nrf52832 saadc multi channel reading

hello,

I tried to read adc sampling value from (NRF_SAADC_INPUT_AIN0~NRF_SAADC_INPUT_AIN4) with pip mode.

Here are my code as followings

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "nrf.h"
#include "nrf_drv_saadc.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_timer.h"
#include "boards.h"
#include "app_error.h"
#include "nrf_delay.h"
#include "app_util_platform.h"
#include "nrf_pwr_mgmt.h"

#include "nrf_gpio.h"
#include "nrf_nvmc.h"
#include "nrf_drv_gpiote.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#define SAMPLES_IN_BUFFER 5
#define ADC_CHANNEL_COUNT 5
volatile uint8_t state = 1;

// definition for GPIO
#define VIN_SENS            NRF_SAADC_INPUT_AIN0                                                  /**< LED1 GPIO */
#define CURR_CHG            NRF_SAADC_INPUT_AIN1                                                  /**< LED2 GPIO */
#define BAT_SENS            NRF_SAADC_INPUT_AIN2                                                  /**< HEATER CONTROL GPIO */
#define CURR_DCHG           NRF_SAADC_INPUT_AIN3                                                  /**< EMERGENCY CONTROL GPIO */
#define BAT_TEMP            NRF_SAADC_INPUT_AIN4                                                  /**< EMERGENCY CONTROL #2 GPIO */
#define ACC_ON              29
#define CHG_OFF             31
#define B_BOX_OFF           12
#define BMS_LED1            25                                                 /**< LED1 GPIO */
#define BMS_LED2            26                                                  /**< LED2 GPIO */


static const nrf_drv_timer_t m_timer = NRF_DRV_TIMER_INSTANCE(0);
static nrf_saadc_value_t     m_buffer_pool[10][SAMPLES_IN_BUFFER];
static nrf_ppi_channel_t     m_ppi_channel;
static uint32_t              m_adc_evt_counter;
int16_t vin_sens_val=0, curr_chg_val=0, bat_sens_val=0, curr_dchg_val=0, bat_temp_val=0;


void box_gpio_init(void)
{
  ret_code_t err_code;

  nrf_gpio_cfg_output(BMS_LED1);
  nrf_gpio_cfg_output(BMS_LED2);
  nrf_gpio_cfg_output(CHG_OFF);
  nrf_gpio_cfg_output(B_BOX_OFF);
  nrf_gpio_cfg_input(ACC_ON,NRF_GPIO_PIN_PULLUP);

  nrf_gpio_pin_set(BMS_LED1);
  nrf_gpio_pin_set(BMS_LED2);

  nrf_gpio_pin_set(CHG_OFF);
  nrf_gpio_pin_clear(CHG_OFF);

  nrf_gpio_pin_set(B_BOX_OFF);
  nrf_gpio_pin_clear(B_BOX_OFF);
  
}


void timer_handler(nrf_timer_event_t event_type, void * p_context)
{

}


void saadc_sampling_event_init(void)
{
    ret_code_t err_code;

    err_code = nrf_drv_ppi_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
    err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, timer_handler);
    APP_ERROR_CHECK(err_code);

    /* setup m_timer for compare event every 400ms */
    uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 250);
    nrf_drv_timer_extended_compare(&m_timer,
                                   NRF_TIMER_CC_CHANNEL0,
                                   ticks,
                                   NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                   false);
    nrf_drv_timer_enable(&m_timer);

    uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,
                                                                                NRF_TIMER_CC_CHANNEL0);
    uint32_t saadc_sample_task_addr   = nrf_drv_saadc_sample_task_get();

    /* setup ppi channel so that timer compare event is triggering sample task in SAADC */
    err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(m_ppi_channel,
                                          timer_compare_event_addr,
                                          saadc_sample_task_addr);
    APP_ERROR_CHECK(err_code);
}


void saadc_sampling_event_enable(void)
{
    ret_code_t err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);

    APP_ERROR_CHECK(err_code);
}


void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        ret_code_t err_code;

        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);

        int i;
        NRF_LOG_INFO("ADC event number: %d", (int)m_adc_evt_counter);

        for (i = 0; i < SAMPLES_IN_BUFFER; i++)
        {
            //NRF_LOG_INFO("%d", p_event->data.done.p_buffer[i]);
            switch(i%5)
            {
              case 0: 
                vin_sens_val = p_event->data.done.p_buffer[i];
                break;

              case 1: 
                curr_chg_val = p_event->data.done.p_buffer[i];
                break;

              case 2: 
                bat_sens_val = p_event->data.done.p_buffer[i];
                break;

              case 3: 
                curr_dchg_val = p_event->data.done.p_buffer[i];
                break;

              case 4: 
                bat_temp_val = p_event->data.done.p_buffer[i];
                break;
              default: break;
            }
        }
        m_adc_evt_counter++;

        NRF_LOG_INFO("%d %d %d %d %d", vin_sens_val, curr_chg_val, bat_sens_val, curr_dchg_val, bat_temp_val);

        nrf_gpio_pin_toggle(CHG_OFF);
    }
}

void saadc_init(void)
{
    ret_code_t err_code;
    nrf_saadc_channel_config_t channel_config_vin_sens =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(VIN_SENS);

    channel_config_vin_sens.mode       = NRF_SAADC_MODE_SINGLE_ENDED;
    channel_config_vin_sens.acq_time = NRF_SAADC_ACQTIME_20US;

    nrf_saadc_channel_config_t channel_config_curr_chg =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(CURR_CHG);

    channel_config_curr_chg.mode       = NRF_SAADC_MODE_SINGLE_ENDED;
    channel_config_curr_chg.acq_time = NRF_SAADC_ACQTIME_20US;

    nrf_saadc_channel_config_t channel_config_bat_sens =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(BAT_SENS);

    channel_config_bat_sens.acq_time = NRF_SAADC_ACQTIME_20US;
    channel_config_bat_sens.mode       = NRF_SAADC_MODE_SINGLE_ENDED;

    nrf_saadc_channel_config_t channel_config_curr_dchg =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(CURR_DCHG);

    channel_config_curr_dchg.acq_time = NRF_SAADC_ACQTIME_20US;
    channel_config_curr_dchg.mode       = NRF_SAADC_MODE_SINGLE_ENDED;
    
    nrf_saadc_channel_config_t channel_config_bat_temp =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(BAT_TEMP);

    channel_config_bat_temp.acq_time = NRF_SAADC_ACQTIME_20US;
    channel_config_bat_temp.mode       = NRF_SAADC_MODE_SINGLE_ENDED;

    err_code = nrf_drv_saadc_init(NULL, saadc_callback);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_channel_init(0, &channel_config_vin_sens);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_channel_init(1, &channel_config_curr_chg);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_channel_init(2, &channel_config_bat_sens);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_channel_init(3, &channel_config_curr_dchg);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_channel_init(4, &channel_config_bat_temp);
    APP_ERROR_CHECK(err_code);

  
    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);
}


/**
 * @brief Function for main application entry.
 */
int main(void)
{
    box_gpio_init();
    uint32_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();

    ret_code_t ret_code = nrf_pwr_mgmt_init();
    APP_ERROR_CHECK(ret_code);

    saadc_init();
    saadc_sampling_event_init();
    saadc_sampling_event_enable();
    NRF_LOG_INFO("SAADC HAL simple example started.");

    while (1)
    {
        nrf_pwr_mgmt_run();
        NRF_LOG_FLUSH();
    }
}


/** @} */

If I have no any voltage into adc input channel, I had a result as following

<info> app: 80 80 81 71 85

If I have only voltage into ch0 as adc input channel, I had a result as following

<info> app: 670 266 152 101 102

If I have only voltage into ch1 as adc input channel, I had a result as following

<info> app: 80 673 255 133 111

If I have only voltage into ch2 as adc input channel, I had a result as following

<info> app: 67 72 668 256 145

If I have only voltage into ch3 as adc input channel, I had a result as following

<info> app: 70 73 74 671 281

If I have only voltage into ch4 as adc input channel, I had a result as following

<info> app: 90 89 86 78 669

It seems to be effected to other channel.

How can I solve this problem?

Related