npm1300 problem

hi professor,

    The npm1300 is used for power management  on my borad.When VBAT and VBUS are connected simultaneously, the bulk 2 output power supply varies between 1V and 3.3V.When only VBUS is connected, the bulk 2 output voltage is fixed at 3.3V, which meets my expectations.

    The chip version i am using is CAAACA 2335A1.Does this version of the chip have such characteristics that VBAT must be connected?

Here are the DTS fragments:

&arduino_i2c {
npm1300_ek_pmic: pmic@6b {
compatible = "nordic,npm1300";
reg = <0x6b>;

npm1300_ek_gpio: gpio-controller {
compatible = "nordic,npm1300-gpio";
gpio-controller;
#gpio-cells = <2>;
ngpios = <5>;
};

npm1300_ek_regulators: regulators {
compatible = "nordic,npm1300-regulator";
/* limits are set to min/max allowed values */
npm1300_ek_buck1: BUCK1 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
/delete-property/ regulator-init-microvolt;
};
npm1300_ek_buck2: BUCK2 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <3300000>;
regulator-init-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
/delete-property/ retention-microvolt;
/delete-property/ enable-gpios;
/delete-property/ retention-gpios;
/delete-property/ pwm-gpios;
};

npm1300_ek_ldo1: LDO1 {
/delete-property/ regulator-min-microvolt;
/delete-property/ regulator-max-microvolt;
/delete-property/ regulator-initial-mode;
/delete-property/ enable-gpios;
};

npm1300_ek_ldo2: LDO2 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-init-microvolt = <1800000>;
regulator-initial-mode = <NPM1300_LDSW_MODE_LDO>;
regulator-always-on;
regulator-boot-on;
/delete-property/ enable-gpios;
};
};
npm1300_ek_charger: charger {
compatible = "nordic,npm1300-charger";
term-microvolt = <4200000>;
term-warm-microvolt = <4000000>;
current-microamp = <400000>;
dischg-limit-microamp = <1000000>;
vbus-limit-microamp = <500000>;
thermistor-ohms = <10000>;
thermistor-beta = <3380>;
charging-enable;
vbatlow-charge-enable;
};
npm1300_ek_buttons: buttons {
compatible = "gpio-keys";
pmic_button0: pmic_button_0 {
gpios = < &npm1300_ek_gpio 0 GPIO_ACTIVE_HIGH>;
label = "Pmic button switch 0";
zephyr,code = <INPUT_KEY_0>;
};
};
npm1300_ek_leds: leds {
compatible = "nordic,npm1300-led";
nordic,led0-mode = "host";
nordic,led1-mode = "charging";
nordic,led2-mode = "error";
};
};
};

Parents
  • When VBAT and VBUS are connected simultaneously, the bulk 2 output power supply varies between 1V and 3.3V.

    What are the voltages on VBAT and VBUS when this occur?

  • hi,
    The parts related to npm1300 include the following code and dts.
    static const struct device *regulators = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_regulators));
    static const struct device *charger = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_charger));
    static const struct device *leds = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_leds));
    static const struct device *pmic = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_pmic));

    static float max_charge_current;
    static float term_charge_current;
    static int64_t ref_time;

    static const struct battery_model battery_model = {
    #include "lq_25C.inc"
    };

    /********************thread define*******************************/
    #define PMIC_STACK_SIZE 1024
    #define PMIC_PRIORITY 2  

    K_THREAD_STACK_DEFINE(pmic_stack_area, PMIC_STACK_SIZE);
    struct k_thread pmic_thread_data;
    static int read_sensors(const struct device *charger, float *voltage, float *current, float *temp)
    {
        struct sensor_value value;
        int ret;

        ret = sensor_sample_fetch(charger);
        if (ret < 0) {
            return ret;
        }

        sensor_channel_get(charger, SENSOR_CHAN_GAUGE_VOLTAGE, &value);
        *voltage = (float)value.val1 + ((float)value.val2 / 1000000);

        sensor_channel_get(charger, SENSOR_CHAN_GAUGE_TEMP, &value);
        *temp = (float)value.val1 + ((float)value.val2 / 1000000);

        sensor_channel_get(charger, SENSOR_CHAN_GAUGE_AVG_CURRENT, &value);
        *current = (float)value.val1 + ((float)value.val2 / 1000000);

        return 0;
    }

    int fuel_gauge_init(const struct device *charger)
    {
        struct sensor_value value;
        struct nrf_fuel_gauge_init_parameters parameters = { .model = &battery_model };
        int ret;

        memset(&gBatteryStatus, 0x00,sizeof(gBatteryStatus));
       
        ret = read_sensors(charger, &parameters.v0, &parameters.i0, &parameters.t0);
        if (ret < 0) {
            return ret;
        }

        /* Store charge nominal and termination current, needed for ttf calculation */
        sensor_channel_get(charger, SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT, &value);
        max_charge_current = (float)value.val1 + ((float)value.val2 / 1000000);
        term_charge_current = max_charge_current / 10.f;

        nrf_fuel_gauge_init(&parameters, NULL);

        ref_time = k_uptime_get();

        return 0;
    }

    int fuel_gauge_update(const struct device *charger)
    {
        float voltage;
        float current;
        float temp;
        float soc;
        float tte;
        float ttf;
        float delta;
        int ret;
        struct sensor_value error;
        struct sensor_value status;
        //static int led_set = 0;
        static int buzzer_count = 0;

        ret = read_sensors(charger, &voltage, &current, &temp);
        if (ret < 0) {
            printk("Error: Could not read from charger device\n");
            return ret;
        }

        delta = (float) k_uptime_delta(&ref_time) / 1000.f;

        soc = nrf_fuel_gauge_process(voltage, current, temp, delta, NULL);
        tte = nrf_fuel_gauge_tte_get();
        ttf = nrf_fuel_gauge_ttf_get(-max_charge_current, -term_charge_current);

        sensor_channel_get(charger, SENSOR_CHAN_NPM1300_CHARGER_STATUS, &status);
        sensor_channel_get(charger, SENSOR_CHAN_NPM1300_CHARGER_ERROR, &error);
        printk("V: %.3f, I: %.3f, T: %.2f, ", voltage, current, temp);
        printk("SoC: %.2f, TTE: %.0f, TTF: %.0f\n", soc, tte, ttf);
        printk("Charger Status: %d, Error: %d\n", status.val1, error.val1);
        return 0;
    }
    /**********************************************************
    * function:pmic_thread_run
    *
    * description:pmic thread run
    *      err = k_sem_take(&ble_sem, K_FOREVER);
    * date:k_sched_lock(); k_sched_unlock();
    **********************************************************/
    static void pmic_thread_run(void *p1, void *p2, void *p3)
    {
        if (!device_is_ready(charger))
        {
            printk("Charger device not ready.\n");
            return 0;
        }

        if (fuel_gauge_init(charger) < 0) {
            printk("Could not initialise fuel gauge.\n");
            return 0;
        }

        printk("PMIC device ok\n");
        led_on(leds, 0U);

        while (1)
        {
            fuel_gauge_update(charger);
            k_msleep(PMIC_SLEEP_TIME_MS);
        }
        return;
    }
    /**********************************************************
    * function:pmic_init
    *
    * description:pmic module init
    *      err = k_sem_take(&ble_sem, K_FOREVER);
    * date:k_sched_lock(); k_sched_unlock();
    **********************************************************/
    int pmic_init(void)
    {
        k_tid_t my_tid;

        if (!device_is_ready(leds)) {
            printk("Error: led device is not ready\n");
            return;
        }

        if (!device_is_ready(pmic)) {
            printk("Pmic device not ready.\n");
            return;
        }

        if (!device_is_ready(regulators)) {
            printk("Error: Regulator device is not ready\n");
            return 0;
        }
       
        led_off(leds, 0U);

        my_tid = k_thread_create(&pmic_thread_data, pmic_stack_area,
                                     K_THREAD_STACK_SIZEOF(pmic_stack_area),
                                     pmic_thread_run,
                                     NULL, NULL, NULL,
                                     PMIC_PRIORITY, 0, K_NO_WAIT);
        k_thread_name_set(&pmic_thread_data, "pmic_thread");
        return 0;
    }
Reply
  • hi,
    The parts related to npm1300 include the following code and dts.
    static const struct device *regulators = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_regulators));
    static const struct device *charger = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_charger));
    static const struct device *leds = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_leds));
    static const struct device *pmic = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_pmic));

    static float max_charge_current;
    static float term_charge_current;
    static int64_t ref_time;

    static const struct battery_model battery_model = {
    #include "lq_25C.inc"
    };

    /********************thread define*******************************/
    #define PMIC_STACK_SIZE 1024
    #define PMIC_PRIORITY 2  

    K_THREAD_STACK_DEFINE(pmic_stack_area, PMIC_STACK_SIZE);
    struct k_thread pmic_thread_data;
    static int read_sensors(const struct device *charger, float *voltage, float *current, float *temp)
    {
        struct sensor_value value;
        int ret;

        ret = sensor_sample_fetch(charger);
        if (ret < 0) {
            return ret;
        }

        sensor_channel_get(charger, SENSOR_CHAN_GAUGE_VOLTAGE, &value);
        *voltage = (float)value.val1 + ((float)value.val2 / 1000000);

        sensor_channel_get(charger, SENSOR_CHAN_GAUGE_TEMP, &value);
        *temp = (float)value.val1 + ((float)value.val2 / 1000000);

        sensor_channel_get(charger, SENSOR_CHAN_GAUGE_AVG_CURRENT, &value);
        *current = (float)value.val1 + ((float)value.val2 / 1000000);

        return 0;
    }

    int fuel_gauge_init(const struct device *charger)
    {
        struct sensor_value value;
        struct nrf_fuel_gauge_init_parameters parameters = { .model = &battery_model };
        int ret;

        memset(&gBatteryStatus, 0x00,sizeof(gBatteryStatus));
       
        ret = read_sensors(charger, &parameters.v0, &parameters.i0, &parameters.t0);
        if (ret < 0) {
            return ret;
        }

        /* Store charge nominal and termination current, needed for ttf calculation */
        sensor_channel_get(charger, SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT, &value);
        max_charge_current = (float)value.val1 + ((float)value.val2 / 1000000);
        term_charge_current = max_charge_current / 10.f;

        nrf_fuel_gauge_init(&parameters, NULL);

        ref_time = k_uptime_get();

        return 0;
    }

    int fuel_gauge_update(const struct device *charger)
    {
        float voltage;
        float current;
        float temp;
        float soc;
        float tte;
        float ttf;
        float delta;
        int ret;
        struct sensor_value error;
        struct sensor_value status;
        //static int led_set = 0;
        static int buzzer_count = 0;

        ret = read_sensors(charger, &voltage, &current, &temp);
        if (ret < 0) {
            printk("Error: Could not read from charger device\n");
            return ret;
        }

        delta = (float) k_uptime_delta(&ref_time) / 1000.f;

        soc = nrf_fuel_gauge_process(voltage, current, temp, delta, NULL);
        tte = nrf_fuel_gauge_tte_get();
        ttf = nrf_fuel_gauge_ttf_get(-max_charge_current, -term_charge_current);

        sensor_channel_get(charger, SENSOR_CHAN_NPM1300_CHARGER_STATUS, &status);
        sensor_channel_get(charger, SENSOR_CHAN_NPM1300_CHARGER_ERROR, &error);
        printk("V: %.3f, I: %.3f, T: %.2f, ", voltage, current, temp);
        printk("SoC: %.2f, TTE: %.0f, TTF: %.0f\n", soc, tte, ttf);
        printk("Charger Status: %d, Error: %d\n", status.val1, error.val1);
        return 0;
    }
    /**********************************************************
    * function:pmic_thread_run
    *
    * description:pmic thread run
    *      err = k_sem_take(&ble_sem, K_FOREVER);
    * date:k_sched_lock(); k_sched_unlock();
    **********************************************************/
    static void pmic_thread_run(void *p1, void *p2, void *p3)
    {
        if (!device_is_ready(charger))
        {
            printk("Charger device not ready.\n");
            return 0;
        }

        if (fuel_gauge_init(charger) < 0) {
            printk("Could not initialise fuel gauge.\n");
            return 0;
        }

        printk("PMIC device ok\n");
        led_on(leds, 0U);

        while (1)
        {
            fuel_gauge_update(charger);
            k_msleep(PMIC_SLEEP_TIME_MS);
        }
        return;
    }
    /**********************************************************
    * function:pmic_init
    *
    * description:pmic module init
    *      err = k_sem_take(&ble_sem, K_FOREVER);
    * date:k_sched_lock(); k_sched_unlock();
    **********************************************************/
    int pmic_init(void)
    {
        k_tid_t my_tid;

        if (!device_is_ready(leds)) {
            printk("Error: led device is not ready\n");
            return;
        }

        if (!device_is_ready(pmic)) {
            printk("Pmic device not ready.\n");
            return;
        }

        if (!device_is_ready(regulators)) {
            printk("Error: Regulator device is not ready\n");
            return 0;
        }
       
        led_off(leds, 0U);

        my_tid = k_thread_create(&pmic_thread_data, pmic_stack_area,
                                     K_THREAD_STACK_SIZEOF(pmic_stack_area),
                                     pmic_thread_run,
                                     NULL, NULL, NULL,
                                     PMIC_PRIORITY, 0, K_NO_WAIT);
        k_thread_name_set(&pmic_thread_data, "pmic_thread");
        return 0;
    }
Children
No Data
Related