I reference the sample at https://academy.nordicsemi.com/courses/nrf-connect-sdk-intermediate/lessons/lesson-6-analog-to-digital-converter-adc/topic/exercise-3-interfacing-with-adc-using-nrfx-drivers-and-timer-ppi/
My question is:
1. How to manually trigger timer to start SAADC sampling?
When I call method "nrfx_timer_enable(&timer_instance);", the PPI starts just once, another call of this function doesn't work, event if I called method "nrfx_timer_reconfigure(&timer_instance, &timer_config);"
2. How to use mutiple ADC channels with PPI?
/* STEP 4.1 - Define the buffer size for the SAADC */ #define SAADC_BUFFER_SIZE 65 /* STEP 4.2 - Declare the buffers for the SAADC */ static int16_t saadc_sample_buffer[2][SAADC_BUFFER_SIZE*2]; static nrfx_saadc_channel_t m_multiple_channels[] = { NRFX_SAADC_DEFAULT_CHANNEL_SE(NRF_SAADC_INPUT_AIN1, 0), NRFX_SAADC_DEFAULT_CHANNEL_SE(NRF_SAADC_INPUT_AIN6, 3) }; m_multiple_channels[0].channel_config.gain = NRF_SAADC_GAIN1_6; m_multiple_channels[1].channel_config.gain = NRF_SAADC_GAIN1_5; err = nrfx_saadc_channels_config(&m_multiple_channels, 2); if (err != NRFX_SUCCESS) { LOG_ERR("nrfx_saadc_channels_config error: %08x", err); return; } /* STEP 4.8 - Configure channel 0 in advanced mode with event handler * (non-blocking mode) */ uint32_t mask = nrfx_saadc_channels_configured_get(); nrfx_saadc_adv_config_t saadc_adv_config = NRFX_SAADC_DEFAULT_ADV_CONFIG; err = nrfx_saadc_advanced_mode_set(mask, NRF_SAADC_RESOLUTION_14BIT, &saadc_adv_config, saadc_event_handler); if (err != NRFX_SUCCESS) { LOG_ERR("nrfx_saadc_advanced_mode_set error: %08x", err); return; } /* STEP 4.9 - Configure two buffers to make use of double-buffering feature of * SAADC */ err = nrfx_saadc_buffer_set(saadc_sample_buffer[0], SAADC_BUFFER_SIZE * 2); if (err != NRFX_SUCCESS) { LOG_ERR("nrfx_saadc_buffer_set error: %08x", err); return; } err = nrfx_saadc_buffer_set(saadc_sample_buffer[1], SAADC_BUFFER_SIZE * 2); if (err != NRFX_SUCCESS) { LOG_ERR("nrfx_saadc_buffer_set error: %08x", err); return; }
void saadc_event_handler(nrfx_saadc_evt_t const *p_event) { nrfx_err_t err; switch (p_event->type) { case NRFX_SAADC_EVT_READY: /* STEP 5.1 - Buffer is ready, timer (and sampling) can be started. */ // nrfx_timer_enable(&timer_instance); break; case NRFX_SAADC_EVT_BUF_REQ: /* STEP 5.2 - Set up the next available buffer. Alternate between buffer 0 * and 1 */ err = nrfx_saadc_buffer_set( saadc_sample_buffer[(saadc_current_buffer++) % 2], SAADC_BUFFER_SIZE); // err = nrfx_saadc_buffer_set(saadc_sample_buffer[((saadc_current_buffer // == 0 )? saadc_current_buffer++ : 0)], SAADC_BUFFER_SIZE); if (err != NRFX_SUCCESS) { LOG_ERR("nrfx_saadc_buffer_set error: %08x", err); return; } break; case NRFX_SAADC_EVT_DONE: /* STEP 5.3 - Buffer has been filled. Do something with the data and * proceed */ int64_t average = 0; int16_t max = INT16_MIN; int16_t min = INT16_MAX; int16_t current_value; LOG_INF("size: %d", p_event->data.done.size); for (int i = 0; i < p_event->data.done.size; i++) { current_value = ((int16_t *)(p_event->data.done.p_buffer))[i]; LOG_INF("value1: %d, value2: %d", current_value, ((int16_t *)(p_event->data.done.p_buffer))[i++]); average += current_value; if (current_value > max) { max = current_value; } if (current_value < min) { min = current_value; } } average = average / p_event->data.done.size; LOG_INF("SAADC buffer at 0x%x filled with %d samples", (uint32_t)p_event->data.done.p_buffer, p_event->data.done.size); LOG_INF("AVG=%d, MIN=%d, MAX=%d", (int16_t)average, min, max); break; default: LOG_INF("Unhandled SAADC evt %d", p_event->type); break; } }