Hi all,
I've gotten the saadc example working on my product, reading in values as I would expect. However, I have two problems. First, I want to be able to use multiple input pins after I first initialize the adc. Since the channel choice (`channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7)`) is at the very top of the init code, it seems like I'd have to run the init again with a different NRF_SAADC_INPUT chosen in order to use a different channel. Is this incorrect? If so, how do I simultaneously enable multiple channels.
Second, I've had to build a 5-second delay into my AdcRead function in order to give the ADC enough time to collect sample. If I shorten the delay or return a value immediately, I get an error saying that the ADC is busy. I've inserted my code below for clarity.
My init function looks like:
ret_code_t err_code; nrf_saadc_channel_config_t channelConfig = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN3); err_code = nrf_drv_saadc_init(NULL, saadcCB); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_channel_init(0, &channelConfig); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_buffer_convert(ADCBufferPool[0], SAMPLES_IN_BUFFER); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_buffer_convert(ADCBufferPool[1], SAMPLES_IN_BUFFER); APP_ERROR_CHECK(err_code);
And my AdcRead function looks like:
ret_code_t 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, 400); 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); // enable sampling APP_ERROR_CHECK(err_code); err_code = nrf_drv_ppi_channel_enable(m_ppi_channel); // Wait for sampling to happen BuDelayMs(5000); *val = AdcRetVal; if (err_code != NRF_SUCCESS) { return ADC_CHANNEL_ERROR; } return ADC_SUCCESS;
This is my callback event handler:
uint32_t adcValAccum = 0; uint16_t i; ret_code_t err_code; if (p_event->type == NRF_DRV_SAADC_EVT_DONE) { err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER); APP_ERROR_CHECK(err_code); for (i = 0; i < SAMPLES_IN_BUFFER; i++) { adcValAccum += p_event->data.done.p_buffer[i]; } AdcRetVal = adcValAccum / 5; }