Using vbat_mon pin p1.10 in NRF54L15 as ADC and trying to read the voltages

I am implementing the code for nrf54l15 nordic MCU to:

Use vbat_mon pin p1.10 in NRF54L15 as ADC and trying to read the voltages, but physically i am not able to read/get the correct voltages across 

VBAT_MEAS_SW and VBAT_MON which is having volatge divider circuit in the schematics. instead i am able to read as 0 V at both pins.

I am using the dts board file code as below

zephyr,user
{ io-channels = <&adc 0>;
};

aliases {
vbatmon = &vbat_mon;
vbatadcnode = &vbatadc_node;
};

&adc {
    #address-cells = <1>;
    #size-cells = <0>;
    status = "okay";
    vbatadc_node: channel@0 {
        reg = <0>;                    /* Use ADC channel 0 */
        zephyr,gain = "ADC_GAIN_1_6"; /* Gain 1/6 to measure up to VDD range */
        zephyr,reference = "ADC_REF_INTERNAL"; /* Internal 0.6V reference */
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,input-positive = <NRF_SAADC_AIN3>;  /* P1.10 maps to AIN3 */
        zephyr,resolution = <12>;  /* 12-bit resolution */
    };
};

using the kconfig options as below

CONFIG_ADC=y
CONFIG_NRFX_SAADC=y

I implemented the below code:

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/devicetree.h>
#include <zephyr/logging/log.h>
#include <stdio.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/dt-bindings/gpio/gpio.h>
#include <zephyr/dt-bindings/adc/nrf-saadc.h>
#include <zephyr/devicetree/gpio.h>
#include <zephyr/toolchain/common.h>
#include <zephyr/sys/__assert.h>
#include "tca9535_config.h"
#include "tca9535.h"
#include "VoltMon.h"

LOG_MODULE_REGISTER(vbat_mon, LOG_LEVEL_INF);
/*
 * Use DT_PATH(zephyr_user) to get the node,
 * and 0 to specify the first channel in its 'io-channels' list.
 */
static const struct adc_dt_spec vbat_adc_channel = ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), 0);

static int16_t sample_buffer;

void measure_vbat_voltage(void)
{
    int err;
    struct adc_sequence sequence = {
        .channels = BIT(vbat_adc_channel.channel_id), // Use the specific channel ID retrieved by the macro
        .buffer = &sample_buffer,
        /* buffer size in bytes, not number of samples */
        .buffer_size = sizeof(sample_buffer),
        .calibrate = true, // Calibration is recommended
        .oversampling = 0, // Set oversampling rate if needed (0 for default/off)
        .resolution = vbat_adc_channel.resolution, // Use resolution from DT spec
       
    };

    // Follow the steps in the linked guide to initialize and read ADC data
    if (!adc_is_ready_dt(&vbat_adc_channel)) {
        printk("ADC controller device %s not ready", vbat_adc_channel.dev->name);
        return;
    }

    err = adc_channel_setup_dt(&vbat_adc_channel);
    if (err < 0) {
        printk("Could not setup ADC channel (%d)", err);
        return;
    }

    //Enable the VBAT_MEAS_SW  PIN before reading the voltage
    TCA9535_Set_PORT0_PORT1(VBAT_MEAS_SW_PORT0_EN); // Enable measurement path
    k_sleep(K_MSEC(10)); // Allow stabilization

    while (1)
    {
        err = adc_read(vbat_adc_channel.dev, &sequence);
        if (err)
        {
            LOG_ERR("ADC read failed (%d)", err);
        }
        else
        {
            /* Convert raw ADC value to voltage */
            float vbat = ((float)sample_buffer / (1 << vbat_adc_channel.resolution)) * 0.6f * 6; // internal ref * gain factor
            LOG_INF("VBAT raw: %d, voltage: %.2f V", sample_buffer, vbat);
        }
        k_sleep(K_SECONDS(1));
    }

    //Disable the VBAT_MEAS_SW  PIN after reading the voltage
    TCA9535_Set_PORT0_PORT1(VBAT_MEAS_SW_PORT0_DISABLE);
}

please provide inputs if any of the above implementation is incorrect ?
I must ensure that exact volatges are read across those pins on board physically


Related