nPM1300 is not charging - is NTC to GND the reason?

I´m testing the nPM1300 in a custom circuit with Zephyr on an nRF52 / nRF53 attached to it. It looks like the IC isn´t charging a battery. For testing I use the nPM1300-EK sample from Zephyr as the base and modify it for my setup with an nRF52-DK nRF52832.

#include <dt-bindings/regulator/npm1300.h>
#include <zephyr/dt-bindings/input/input-event-codes.h>

&i2c0 {
	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";

			npm1300_ek_buck1: BUCK1 {
				regulator-init-microvolt = <2700000>;
			};

			npm1300_ek_buck2: BUCK2 {
				regulator-init-microvolt = <1800000>;
			};

			npm1300_ek_ldo1: LDO1 {
				regulator-min-microvolt = <1000000>;
				regulator-max-microvolt = <3300000>;
				regulator-initial-mode = <NPM1300_LDSW_MODE_LDO>;
				enable-gpios = <&npm1300_ek_gpio 2 GPIO_ACTIVE_LOW>;
			};

			npm1300_ek_ldo2: LDO2 {
				regulator-min-microvolt = <1000000>;
				regulator-max-microvolt = <3300000>;
				regulator-initial-mode = <NPM1300_LDSW_MODE_LDSW>;
				enable-gpios = <&npm1300_ek_gpio 2 GPIO_ACTIVE_LOW>;
			};
		};

		npm1300_ek_charger: charger {
			compatible = "nordic,npm1300-charger";
			term-microvolt = <4150000>;
			term-warm-microvolt = <4000000>;
			current-microamp = <150000>;
			dischg-limit-microamp = <1000000>;
			vbus-limit-microamp = <500000>;
			thermistor-ohms = <10000>;
			thermistor-beta = <3380>;
			charging-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 = "error";
			nordic,led1-mode = "charging";
			nordic,led2-mode = "host";
		};
	};
};

&i2c0_default {
	group1 {
		bias-pull-up;
	};
};
 

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/i2c.h>

#include <zephyr/drivers/regulator.h>
#include <zephyr/drivers/sensor/npm1300_charger.h>
#include <zephyr/dt-bindings/regulator/npm1300.h>
#include <zephyr/dt-bindings/regulator/npm1300.h>

LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);

static const struct device* buck1 = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_buck1));
static const struct device* buck2 = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_buck2));
static const struct device* ldo1 = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_ldo1));
static const struct device* ldo2 = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_ldo2));
static const struct device* charger = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_charger));

int main(void)
{
	int32_t Voltage;

	if(device_is_ready(buck2) == false)
    {
		LOG_ERR("Regulator device is not ready!");
		return -ENODEV;
	}

	if (!device_is_ready(charger)) {
		printk("Charger device not ready.\n");
		return 0;
	}

	if(regulator_is_enabled(ldo1) == false)
    {
		LOG_INF("Enable LDO1...");
		regulator_enable(ldo1);
		if(regulator_is_enabled(ldo1) == false)
		{
			LOG_INF("LDO1 not enabled!");
			regulator_enable(ldo1);
			regulator_set_voltage(ldo1, 3300000, 3300000);
		}
		else
		{
			LOG_INF("LDO1 enabled!");
		}
	}
	else
	{
		LOG_INF("LDO1 enabled!");
	}

	if(regulator_is_enabled(ldo2) == false)
    {
		LOG_INF("LDO2 not enabled!");
	}
	else
	{
		LOG_INF("LDO2 enabled!");
	}

	regulator_get_voltage(buck1, &Voltage);
	LOG_INF("BUCK1 Voltage: %i", Voltage);
	regulator_get_voltage(buck2, &Voltage);
	LOG_INF("BUCK2 Voltage: %i", Voltage);

	regulator_set_voltage(buck2, 1800000, 1800000);

	struct sensor_value volt;
	struct sensor_value current;
	struct sensor_value temp;
	struct sensor_value error;
	struct sensor_value status;

	sensor_sample_fetch(charger);
	sensor_channel_get(charger, SENSOR_CHAN_GAUGE_VOLTAGE, &volt);
	sensor_channel_get(charger, SENSOR_CHAN_GAUGE_AVG_CURRENT, &current);
	sensor_channel_get(charger, SENSOR_CHAN_GAUGE_TEMP, &temp);
	sensor_channel_get(charger, SENSOR_CHAN_NPM1300_CHARGER_STATUS, &status);
	sensor_channel_get(charger, SENSOR_CHAN_NPM1300_CHARGER_ERROR, &error);

	printk("V: %d.%03d ", volt.val1, volt.val2 / 1000);

	printk("I: %s%d.%04d ", ((current.val1 < 0) || (current.val2 < 0)) ? "-" : "",
	       abs(current.val1), abs(current.val2) / 100);

	printk("T: %d.%02d\n", temp.val1, temp.val2 / 10000);

	printk("Charger Status: %d, Error: %d\n", status.val1, error.val1);

    while(true)
    {
        k_msleep(1000);
    }

    return 0;
}

And I get the following output:

*** Booting Zephyr OS build v3.3.99-ncs1-1 ***
V: 3.994 I: 0.0000 T: -273.-14
Charger Status: 0, Error: 0

If we bridge the NTC on the nPM1300-EK the firmware outputs 0 as charger status too. But why? The documentation says:

"If a thermistor is not used, the NTC pin must be tied directly to ground or through a resistor. The functionality must be disabled in register BCHGDISABLESET. This does not impact Charger thermal regulation because the two temperature measurements are independent of each other."

so pulling NTC to ground shouldn´t be a problem. Or do we have to change it in the device tree and / or firmware to disable it?

Here you can find the schematics for my test board if needed.

5100.Schematics Initial Order.pdf

Parents
  • Update:
    We found the issue. The nPM1300 driver is not handling the missing NTC correctly. This issue also explains why it´s required to add values for the NTC. This looks like an issue in all Zephyr versions.

    To fix it "npm1300_charger_init" in "sensor/npm1300_charger/npm1300_charger.c" must be expanded with

    ret = reg_write(dev, CHGR_BASE, 0x06, 2U);
    if (ret != 0) {
    	return ret;
    }

    We will create an issue in the Zephyr project to tackle this issue.

Reply
  • Update:
    We found the issue. The nPM1300 driver is not handling the missing NTC correctly. This issue also explains why it´s required to add values for the NTC. This looks like an issue in all Zephyr versions.

    To fix it "npm1300_charger_init" in "sensor/npm1300_charger/npm1300_charger.c" must be expanded with

    ret = reg_write(dev, CHGR_BASE, 0x06, 2U);
    if (ret != 0) {
    	return ret;
    }

    We will create an issue in the Zephyr project to tackle this issue.

Children
Related