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