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

Dual channel ADC capture missing samples from one channel

Dear All,

I am trying to implement a simple data recorder on nRF52840 DK that digitizes signals over SAADC and writes them onto the SD card. The program is working fine for just one input channel, but when I try to extend it to use two SAADC channels I either miss all samples from Channel 0 or all from Channel 1. Which channel is missing in a run, seems to be random. Here's the jist of the code:

#define sampling_rate (2*20000)


// -------------------------------------------------------------------------------------------------------
void adc_handler(nrfx_saadc_evt_t const * p_event)
{
  if (NRFX_SAADC_EVT_DONE == p_event->type)
  {
    // copy 'p_event->data.done.size' from 'p_event->data.done.p_buffer' to FIFO
	// ...

    // set next buffer for continuity
    nrfx_saadc_buffer_convert(...);
  }
  
  // ...
}


// =======================================================================================================
int main(void)
{
  // initialize ADC
  nrfx_saadc_config_t const adc_config=
  {
    .resolution= NRF_SAADC_RESOLUTION_12BIT,    
    .oversample= NRF_SAADC_OVERSAMPLE_DISABLED, 
    .interrupt_priority= 2,
    .low_power_mode= false
  };

  nrfx_saadc_init(&adc_config, adc_handler);

  // initalize channels
  nrf_saadc_channel_config_t const adc_channel_config0=
  {
    .resistor_p= NRF_SAADC_RESISTOR_DISABLED,
    .resistor_n= NRF_SAADC_RESISTOR_DISABLED,
    .gain= NRF_SAADC_GAIN1,
    .reference= NRF_SAADC_REFERENCE_INTERNAL,
    .acq_time= NRF_SAADC_ACQTIME_20US,
    .mode= NRF_SAADC_MODE_SINGLE_ENDED,
    .burst= NRF_SAADC_BURST_DISABLED,
    .pin_p= NRF_SAADC_INPUT_AIN0,     // AIN0: P0.02, see https://infocenter.nordicsemi.com/topic/ps_nrf52840/pin.html?cp=4_0_0_6_0_0#aqfn73
    .pin_n= NRF_SAADC_INPUT_DISABLED
  };

  nrf_saadc_channel_config_t const adc_channel_config1=
  {
    .resistor_p= NRF_SAADC_RESISTOR_DISABLED,
    .resistor_n= NRF_SAADC_RESISTOR_DISABLED,
    .gain= NRF_SAADC_GAIN1,
    .reference= NRF_SAADC_REFERENCE_INTERNAL,
    .acq_time= NRF_SAADC_ACQTIME_20US,
    .mode= NRF_SAADC_MODE_SINGLE_ENDED,
    .burst= NRF_SAADC_BURST_DISABLED,
    .pin_p= NRF_SAADC_INPUT_AIN7,     // AIN7: P0.31, see https://infocenter.nordicsemi.com/topic/ps_nrf52840/pin.html?cp=4_0_0_6_0_0#aqfn73
    .pin_n= NRF_SAADC_INPUT_DISABLED
  };

  nrfx_saadc_channel_init(0, &adc_channel_config0);
  nrfx_saadc_channel_init(1, &adc_channel_config1);

  // calibrate ADC
  nrfx_saadc_calibrate_offset();
  // wait until ready ...
  
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  // set up 20 ksps (per channel) sampling rate
  uint32_t adc_cc= (16000000ul / ((uint32_t) sampling_rate));
  NRF_SAADC->SAMPLERATE = (SAADC_SAMPLERATE_MODE_Timers << SAADC_SAMPLERATE_MODE_Pos) | (adc_cc << SAADC_SAMPLERATE_CC_Pos);


  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
start_sampling:

  // set first ADC buffer
  nrfx_saadc_buffer_convert(...);
    
  // start ADC sampling
  nrfx_saadc_sample();

  // when ADC has started, set second buffer
  while (!nrfx_saadc_is_busy());
  nrfx_saadc_buffer_convert(...);

  while (!button_pressed)
  {
    // write data from FIFO to SD card
  }

  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
stop_sampling:

  // stop sampling
  nrfx_saadc_abort();
}

Ideally, I would like to have the data of the two channels in an interleaved format (1x 12-bit sample from Ch0 stored as uint16, then 1x 12-bit sample from Ch1 stored as uint16, and so on). Can you spot any errors there? (In the real code, I have error checks after every function call. They don't indicate any errors.)

Thanks!
Tamas

Parents Reply Children
No Data
Related