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;
}
}