Skip to content

Commit

Permalink
nRF42: SAADC double buffering
Browse files Browse the repository at this point in the history
- Double-buffer SAADC data
- Make default sample duration take 5us instead of 3us
- Set MAXCNT to 16 initially
  • Loading branch information
TMRh20 committed Nov 4, 2024
1 parent f3ab825 commit 6285868
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/AutoAnalogAudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,13 +267,13 @@ class AutoAnalog
int8_t gain;

/**
* Enable I2S on nRF52
* Enable I2S and/or SAADC on nRF52
* By default this is disabled (analog output using PWM)
*
* @code
* aaAudio.begin(1,1,3);
* @endcode
* @param Set to 1 for I2S DAC, 2 for I2S ADC, 3 for both
* @param Set to 1 for I2S DAC, 2 for I2S ADC, 3 for both, 4 for SAADC only, 5 for SAADC + PWM Output, 6 for SAADC + I2S Output
*/
uint8_t useI2S;

Expand Down
30 changes: 20 additions & 10 deletions src/NRF52840/AutoAnalogAudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,29 +324,39 @@ void AutoAnalog::getADC(uint32_t samples){

while(NRF_SAADC->EVENTS_END == 0){ }

if(!adcWhichBuf){
NRF_SAADC->RESULT.PTR = (uint32_t)adcBuf1;
}else{
NRF_SAADC->RESULT.PTR = (uint32_t)adcBuf0;
}
NRF_SAADC->RESULT.MAXCNT = samples;
NRF_SAADC->EVENTS_END = 0;
NRF_SAADC->TASKS_START = 1;

if(adcBitsPerSample == 16){
if(!adcWhichBuf){
for(uint32_t i=0; i<samples; i++){
adcBuffer16[i] = adcBuf0[i] << 2;
}
NRF_SAADC->RESULT.PTR = (uint32_t)adcBuf1;
}else{
for(uint32_t i=0; i<samples; i++){
adcBuffer16[i] = adcBuf1[i] << 2;
}
NRF_SAADC->RESULT.PTR = (uint32_t)adcBuf0;
}
}else
if(adcBitsPerSample == 8){
for(uint32_t i=0; i<samples; i++){
adcBuffer[i] = adcBuf0[i] >> 6;
if(!adcWhichBuf){
for(uint32_t i=0; i<samples; i++){
adcBuffer[i] = adcBuf0[i] >> 6;
}
}else{
for(uint32_t i=0; i<samples; i++){
adcBuffer[i] = adcBuf1[i] >> 6;
}
}
}
adcWhichBuf = !adcWhichBuf;

NRF_SAADC->RESULT.MAXCNT = samples;
NRF_SAADC->EVENTS_END = 0;
NRF_SAADC->TASKS_START = 1;


}

Expand Down Expand Up @@ -622,13 +632,13 @@ if(useI2S >= 4 && useI2S <= 6){
NRF_SAADC->CH[0].PSELP = dinPin << SAADC_CH_PSELP_PSELP_Pos;
NRF_SAADC->CH[0].PSELN = dinPin << SAADC_CH_PSELN_PSELN_Pos;
NRF_SAADC->CH[0].CONFIG = (SAADC_CH_CONFIG_RESP_VDD1_2 << SAADC_CH_CONFIG_RESP_Pos ) | SAADC_CH_CONFIG_GAIN_Gain4 << SAADC_CH_CONFIG_GAIN_Pos |
SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos | SAADC_CH_CONFIG_TACQ_3us << SAADC_CH_CONFIG_TACQ_Pos |
SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos | SAADC_CH_CONFIG_TACQ_5us << SAADC_CH_CONFIG_TACQ_Pos |
SAADC_CH_CONFIG_MODE_Diff << SAADC_CH_CONFIG_MODE_Pos | SAADC_CH_CONFIG_BURST_Disabled << SAADC_CH_CONFIG_BURST_Pos;
NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_14bit << SAADC_RESOLUTION_VAL_Pos;
NRF_SAADC->OVERSAMPLE = SAADC_OVERSAMPLE_OVERSAMPLE_Over2x << SAADC_OVERSAMPLE_OVERSAMPLE_Pos;
NRF_SAADC->SAMPLERATE = 16000000 / 16000 / 2 | SAADC_SAMPLERATE_MODE_Timers << SAADC_SAMPLERATE_MODE_Pos;
NRF_SAADC->RESULT.PTR = (uint32_t)adcBuf0;
NRF_SAADC->RESULT.MAXCNT = MAX_BUFFER_SIZE;
NRF_SAADC->RESULT.MAXCNT = 16;
NRF_SAADC->ENABLE = true;

NRF_SAADC->TASKS_CALIBRATEOFFSET = true;
Expand Down

0 comments on commit 6285868

Please sign in to comment.