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 Reply Children
  • I'm sorry, there's an issue with my description.When VBAT is connected, the bulk 2 voltage is fixed and outputs 3.3v, regardless of whether VBUS is connected or not. When only VBUS is connected,the bulk 2 output power supply varies between 1V and 3.3V. The schematic is detailed in the following image.

  • Thank you for the update.

    The issue you're experiencing could be because the device is drawing more current than what the USB host can provide. The current limit for VBUS is set at 500mA. If the device draws more than this, the system's voltage (VSYS) will drop.

    Vsys can also drop if the USB host can only deliver, for example, 100mA, and the device draws more than this. Even if the VBUS current limit is set to 500mA.

    The overlay looks OK and works as expected when we are testing it.

  • hi,

    My device uses a very low current, less than 1mA.

  • 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;
    }
Related