Skip to content

Commit

Permalink
nRF52: Add SAADC Suport for input
Browse files Browse the repository at this point in the history
- Add support for Successive Approximation Analog to Digital converter of nRF52 devices
  • Loading branch information
TMRh20 committed Nov 4, 2024
1 parent a663d84 commit f3ab825
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/AutoAnalogAudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ class AutoAnalog
int pwrPin;

/**
* Set the Input Pin for PDM
* Set the Input Pin for PDM or SAADC. With SAADC AIN0 is 1, AIN1 is 2 etc.
* By default this is PIN_PDM_DIN
* If PIN_PDM_DIN is not defined, it is set to 35 by default
* Configure this before calling `begin()`
Expand Down
69 changes: 64 additions & 5 deletions src/NRF52840/AutoAnalogAudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ void AutoAnalog::setSampleRate(uint32_t sampRate, bool stereo){
#endif

}

NRF_SAADC->SAMPLERATE = 16000000 / sampRate / 2 | SAADC_SAMPLERATE_MODE_Timers << SAADC_SAMPLERATE_MODE_Pos;


}

Expand Down Expand Up @@ -311,11 +314,42 @@ void AutoAnalog::getADC(uint32_t samples){
NRF_I2S->TASKS_START = 1;
}

}else{
}else
if(useI2S == 0){
while(!adcReady){__WFE();};
aSize = samples;
adcReady = false;
}else{


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

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;
}
}
adcWhichBuf = !adcWhichBuf;

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

}

}

/****************************************************************************/
Expand All @@ -324,7 +358,7 @@ bool whichBuf = 0;

void AutoAnalog::feedDAC(uint8_t dacChannel, uint32_t samples, bool startInterrupts){

if(useI2S == 1 || useI2S == 3){
if(useI2S == 1 || useI2S == 3 || useI2S == 6){

bool started = false;
if(NRF_I2S->ENABLE == 0){
Expand Down Expand Up @@ -479,7 +513,8 @@ if(useI2S == 2 || useI2S == 3){
NRF_I2S->RXD.PTR = (uint32_t)adcBuf0;
NRF_I2S->RXTXD.MAXCNT = 16;// / sizeof(uint32_t);

}else{
}else
if(useI2S == 0){



Expand Down Expand Up @@ -581,7 +616,31 @@ if(useI2S == 2 || useI2S == 3){
nrf_pdm_task_trigger(myPDM,NRF_PDM_TASK_START);

#endif
} // USE_I2S
}else
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_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->ENABLE = true;

NRF_SAADC->TASKS_CALIBRATEOFFSET = true;
while(!NRF_SAADC->EVENTS_CALIBRATEDONE){}

NRF_SAADC->EVENTS_STARTED = 0;
NRF_SAADC->TASKS_START = 1;
while(!NRF_SAADC->EVENTS_STARTED){};
while ( NRF_SAADC->STATUS == ( SAADC_STATUS_STATUS_Busy << SAADC_STATUS_STATUS_Pos ) );
NRF_SAADC->TASKS_SAMPLE = 1;
Serial.println("Config");
} // USE_I2S
}

/****************************************************************************/
Expand All @@ -594,7 +653,7 @@ void AutoAnalog::adcInterrupts(bool enabled){

void AutoAnalog::dacSetup(void){

if(useI2S == 1 || useI2S == 3){
if(useI2S == 1 || useI2S == 3 || useI2S == 6){
// Enable transmission
NRF_I2S->CONFIG.TXEN = (I2S_CONFIG_TXEN_TXEN_ENABLE << I2S_CONFIG_TXEN_TXEN_Pos);

Expand Down

0 comments on commit f3ab825

Please sign in to comment.