This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

saadc - adc does not work from APP_TIMER call. It appears that the adc interrupt is disabled.

Using SDK 15.

adc_read works properly in main loop.

When called from an APP_Timer or from BLE connect event, function hangs. I set a breakpoint at the handler, and breaks fine in main loop, but never breaks from APP_Timer or BLE event call.

void adc_callback(nrf_drv_saadc_evt_t const * p_event)
{

if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
{
g_twi_transaction_complete = true;
nrf_drv_saadc_abort(); //stop the sampling
for (int i = 0; i < SAMPLES_IN_BUFFER; i++)
{
g_adc_reading[i] = p_event->data.done.p_buffer[i];
NRF_LOG_INFO("ADC Sample = %d ", g_adc_reading[i]);
printf("ADC Sample = %d ", g_adc_reading[i]);
}
}
}

void adc_init(void)
{
ret_code_t err_code;
// Config the struct for the channel being used for the adc
nrf_saadc_channel_config_t channel_config =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1);
channel_config.reference = NRF_SAADC_REFERENCE_VDD4;
channel_config.gain = NRF_SAADC_GAIN1_4;
// Initialize the adc driver and set up the callback
err_code = nrf_drv_saadc_init(NULL, adc_callback);
APP_ERROR_CHECK(err_code);
// Initialize the channel configuration
err_code = nrf_drv_saadc_channel_init(0, &channel_config);
APP_ERROR_CHECK(err_code);
}


void adc_read(void)
{
ret_code_t err_code;
// Trigger sampling
// nrf_drv_saadc_abort(); //stop the sampling if running, returns error

g_twi_transaction_complete = false; //this will be set "true" in call back

err_code = sd_nvic_EnableIRQ(ADC_IRQn);
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_sample();
APP_ERROR_CHECK(err_code);

while (!g_twi_transaction_complete)
;

}

Parents
  • I see two things:

    1) You should not need to use nrf_drv_saadc_abort(); Because the SAADC driver will not call the event handler until the SAADC has finished sampling. You can optionally use nrfx_saadc_is_busy() to verify the state of the SAADC. 

    2) You should not need to enable the SAADC interrupts, the calls to nrfx_saadc_init, nrfx_saadc_channel_init, and nrfx_saadc_buffer_convert will do that for you. 

    If you want periodic sampling I suggest you set up an RTC through its driver and use it to trigger the SAADC's TASKS_SAMPLE through PPI. 

Reply
  • I see two things:

    1) You should not need to use nrf_drv_saadc_abort(); Because the SAADC driver will not call the event handler until the SAADC has finished sampling. You can optionally use nrfx_saadc_is_busy() to verify the state of the SAADC. 

    2) You should not need to enable the SAADC interrupts, the calls to nrfx_saadc_init, nrfx_saadc_channel_init, and nrfx_saadc_buffer_convert will do that for you. 

    If you want periodic sampling I suggest you set up an RTC through its driver and use it to trigger the SAADC's TASKS_SAMPLE through PPI. 

Children
No Data
Related