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