Hi everyone,
I am currently working on a project where I need to sample the SAADC continuously on 5 channels: channels 4,5,6,7 and VDD, which on my board is channel 9. I am using timer 2 that is PPI'd into my SAADC and everything works perfectly IF I don't sample the VDD Channel.
As soon as I add a call to nrf_drv_saadc_channel_init for my VDD channel, the SAADC won't trigger anymore and won't go into it's callback function. When I remove the VDD channel init, everything works again, the callback function is being called, and my values get correctly read from the SAADC.
Here's is a snippet of my code:
enum adc_channel{
in_1,
in_2,
in_3,
in_4,
vdd,
num_adc_channels
};
#define NUM_SAMPLES 1 /*< Number of samples per ADC capture. >*/
#define SAMPLES_IN_BUFFER num_adc_channels*NUM_SAMPLES /*< Number of samples in SAADC buffer. >*/
void saadc_sampling_event_init(void)
{
ret_code_t err_code;
// PPI Driver init
err_code = nrf_drv_ppi_init();
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
APP_ERROR_CHECK(err_code);
// Timer & SAADC interconnection via PPI
uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer_adc,
NRF_TIMER_CC_CHANNEL2);
uint32_t saadc_sample_task_addr = nrf_drv_saadc_sample_task_get();
err_code = nrf_drv_ppi_channel_assign(m_ppi_channel, /* setup ppi channel so that timer compare event is triggering sample task in SAADC */
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)
{
#ifdef WATTZA_DEBUG
m_adc_evt_counter+=1;
#endif
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);
for (int i = 0; i < num_adc_channels; i++)
{
switch (i){
case(in_1):
in_1_val = p_event->data.done.p_buffer[i];
break;
case(in_2):
in_2_val = p_event->data.done.p_buffer[i];
break;
case(in_3):
in_3_val = p_event->data.done.p_buffer[i];
break;
case(in_4):
in_4_val = p_event->data.done.p_buffer[i];
break;
case(vdd):
vdd_val = p_event->data.done.p_buffer[i];
break;
}
}
}
void saadc_init(void)
{
ret_code_t err_code;
// SAADC Channel configuration
// VDD Level Channel Config
nrf_saadc_channel_config_t vdd_ch_conf =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD);
vdd_ch_conf.resistor_n = NRF_SAADC_RESISTOR_PULLDOWN;
vdd_ch_conf.reference = NRF_SAADC_REFERENCE_VDD4;
vdd_ch_conf.gain = NRF_SAADC_GAIN1_4;
// in 1 Channel Config
nrf_saadc_channel_config_t in_1_ch_conf =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4);
in_1_ch_conf.resistor_n = NRF_SAADC_RESISTOR_PULLDOWN;
in_1_ch_conf.reference = NRF_SAADC_REFERENCE_VDD4;
in_1_ch_conf.gain = NRF_SAADC_GAIN1_4;
// in 2 Channel Config
nrf_saadc_channel_config_t in_2_ch_conf =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN5);
in_2_ch_conf.resistor_n = NRF_SAADC_RESISTOR_PULLDOWN;
in_2_ch_conf.reference = NRF_SAADC_REFERENCE_VDD4;
in_2_ch_conf.gain = NRF_SAADC_GAIN1_4;
// in 3 Channel Config
nrf_saadc_channel_config_t in_3_ch_conf =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN6);
in_3_ch_conf.resistor_n = NRF_SAADC_RESISTOR_PULLDOWN;
in_3_ch_conf.reference = NRF_SAADC_REFERENCE_VDD4;
in_3_ch_conf.gain = NRF_SAADC_GAIN1_4;
// in 4 Channel Config
nrf_saadc_channel_config_t in_4_ch_conf =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7);
in_4_ch_conf.resistor_n = NRF_SAADC_RESISTOR_PULLDOWN;
in_4_ch_conf.reference = NRF_SAADC_REFERENCE_VDD4;
in_4_ch_conf.gain = NRF_SAADC_GAIN1_4;
// SAADC Initialization
err_code = nrf_drv_saadc_init(NULL, saadc_callback);
APP_ERROR_CHECK(err_code);
// ADC Channels initialization
err_code = nrf_drv_saadc_channel_init(in_1_CH, &in_1_ch_conf);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_channel_init(in_2_CH, &in_2_ch_conf);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_channel_init(in_3_CH, &in_3_ch_conf);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_channel_init(in_4_CH, &in_4_ch_conf);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_channel_init(NRF_SAADC_INPUT_VDD, &vdd_ch_conf);
APP_ERROR_CHECK(err_code);
// Non-blocking mode - Buffer initialization
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);
}
Let me know if you need any more info!
Cheers,
Yacin