PPI ADC + Timer usage

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

Related