ADC full-scale conversion in npm1300 Zephyr drivers

During development we noticed that current measurements coming from npm1300 appear to be much higher than expected despite the results not matching what we were seeing on the nrf power profiler. For example: while powering our board with the nrf ppk2, we logged a peak current of ~250mA on the profiler but were getting current measurements >300mA from npm1300.

Following this issue down to the npm1300 Zephyr drivers, I am struggling to understand where the numbers for full scale conversion are being derived from. The passage from the npm1300 datasheet on current full scale states:

"A value of 01 means the battery is discharging. During a discharge, the full scale current is the weighted sum of registers BCHGISETDISCHARGEMSB and BCHGISETDISCHARGELSB multiplied by 0.836. A value of 11 means the battery is charging. When charging, the full scale current is the weighted sum of registers BCHGISETMSB and BCHGISETLSB multiplied by 1.25."

When comparing this to the calculation of full scale in the zephyr drivers, however, I do not understand the derivation particularly for the 'discharge' case. In the 'charge' case the number accurately tracks to 1/1.25 = 0.8, which when accounting for unit conversion correctly divides by 800. In the 'discharge' case, I am unable to figure out how a division by 893 is derived. I would expect this to be 1/0.836 = 1.196 (which when converting to mA, would mean dividing 1196)

I wanted to verify whether this is the correct value, and if so, how is this value derived?


The function in question, `calc_current` looks as follows:

```

static void calc_current(const struct npm1300_charger_config *const config,
struct npm1300_charger_data *const data, struct sensor_value *valp)
{
int32_t full_scale_ma;
int32_t current;

switch (data->ibat_stat) {
case IBAT_STAT_DISCHARGE:
full_scale_ma = config->dischg_limit_microamp / 893;
break;
case IBAT_STAT_CHARGE_TRICKLE:
/* Fallthrough */
case IBAT_STAT_CHARGE_COOL:
/* Fallthrough */
case IBAT_STAT_CHARGE_NORMAL:
full_scale_ma = -config->current_microamp / 800;
break;
default:
full_scale_ma = 0;
break;
}

current = (data->current * full_scale_ma) / 1024;

valp->val1 = current / 1000;
valp->val2 = (current % 1000) * 1000;
}
Parents
  • Hi there,

    Latest documentation states:

    A value of 01 means the battery is discharging. During a discharge, the full scale current (in Amps) is the battery discharge current limit (as configured in registers BCHGISETDISCHARGEMSB and BCHGISETDISCHARGELSB) multiplied by 1.12.

    full_scale_ma = config->dischg_limit_microamp / 893;

    Which can be rewritten:

    full_scale_ma = config->1000/893 ~ 1.12

    The latest driver version is a bit more clear: 

    		full_scale_ua = -config->dischg_limit_microamp *
    				config->full_scale_discharge_factors[0] /
    				config->full_scale_discharge_factors[1];

    Where the scaling factors are defined here

    		config->full_scale_discharge_factors[0] /
    				config->full_scale_discharge_factors[1];
    = 1.12.

    So the driver should be correct here.

    I think the error is somewhere else in your system. 

    Can you explain how, or share schematics for your system?

    How is the npm and ppk connected?

    regards

    Jared 

  • Hi Jared,

    Thank you for clarifying the ADC calculation.

    Our board uses npm1300 to supply system power from a battery and measure battery current draw to report to the MCU. To connect the power profiler I replaced the battery with the ppk set up as a source meter, supplying power from the profiler instead.
    I cannot share schematics, but other than the npm1300 there is nothing connected to the battery other than one extremely low power IC.

    With this setup, I was periodically reading current from npm1300_charger (via Zephyr's regulator api) and logging the output. While monitoring current draw from the ppk on nRF Power Profiler (sampling at 10 kHz) I was comparing these results to current measurements being read and logged in Zephyr at 1 Hz and 10Hz (I tried different frequencies).
    This set up gave the results I referenced in my initial post.

    Regards,

    Oscar

  • Hi,

    Can you try to set the PPK in ampere mode and connect it between the battery and the nPM1300. What current do you measure now?

    Also, is this on a custom board or are you are using the EK?

    regards
    Jared 

  • Hi Jared,

    Yes, we are using a custom board.
    I connected a battery and ran the ppk in ampere mode, which resulted in the same waveform as in source mode. Logging the current measurements from the npm1300 to compare, I was still seeing anomylous measurements compared to what is being measured by the power profiler.

    However, I dont see us being able to resolve this issue without me being able to share details or schematics. Seeing as my original question regarding ADC full scale conversion has been answered, I will be closing this thread. If I continue to see differences between npm1300 and ppk2, I will open a seperate case as a private issue.

    Thank you for your support,

    Oscar

Reply
  • Hi Jared,

    Yes, we are using a custom board.
    I connected a battery and ran the ppk in ampere mode, which resulted in the same waveform as in source mode. Logging the current measurements from the npm1300 to compare, I was still seeing anomylous measurements compared to what is being measured by the power profiler.

    However, I dont see us being able to resolve this issue without me being able to share details or schematics. Seeing as my original question regarding ADC full scale conversion has been answered, I will be closing this thread. If I continue to see differences between npm1300 and ppk2, I will open a seperate case as a private issue.

    Thank you for your support,

    Oscar

Children
No Data
Related