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

nRF52 reading AIN0 to AIN4 ... AIN4 fails

EDIT I think there is somewhere in KEIL or nrf libraries a bad pointer type alignement .

The correct pointer is given as uint_32_t (NRF_SAADC->RESULT.PTR = (uint32_t)&adcr;) but the result buffer uint32_t adcr[] is composed in this way :

ADCR[0] -> 2_high_byte=AIN1 value ---- 2_low_bytes=AIN0 value

ADCR[1] -> 2_high_byte=AIN3 value ---- 2_low_bytes=AIN2 value

ADCR[2] -> 2_low_bytes=AIN4 value

It's an uint_16_t type result .

So if I use 32 bit cast to a 16 bit buffer , I find the correct values in uint_16_t adcr[].

I don't know if it's a Keil or libraries issue , but with this workaround I'm able to read all 5 Analog input .

Maurizio


Hello , I'trying to read 5 analog channels AIN0 to AIN4 with nRF52 on BMD300 module . With the same configuration for each channel I'm able to read in buffer ADCR[] chanells 0,1,2 and 3 , but I read always 0(zero) on channel 4 . What's wrong ?

BMD300 module + S212 0.9.1 + SDK 11

Thanks

static void adc_init(void)
{
NRF_COMP->ENABLE= 0;
NRF_LPCOMP->ENABLE = 0;
	
// Start HFCLK from crystal oscillator, this will give the SAADC higher accuracy LFCLKSTART
  
NRF_CLOCK->TASKS_HFCLKSTART = 1;
 while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
 NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;

 // Configure SAADC singled-ended channel, Internal reference (0.6V) and 1/6 gain.

    NRF_SAADC->CH[0].CONFIG = (SAADC_CH_CONFIG_GAIN_Gain1_6    << SAADC_CH_CONFIG_GAIN_Pos) |
                            (SAADC_CH_CONFIG_MODE_SE         << SAADC_CH_CONFIG_MODE_Pos) |
                            (SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) |
                            (SAADC_CH_CONFIG_RESN_Bypass     << SAADC_CH_CONFIG_RESN_Pos) |
                            (SAADC_CH_CONFIG_RESP_Bypass     << SAADC_CH_CONFIG_RESP_Pos) |
                            (SAADC_CH_CONFIG_TACQ_20us       << SAADC_CH_CONFIG_TACQ_Pos);
  
	NRF_SAADC->CH[1].CONFIG = (SAADC_CH_CONFIG_GAIN_Gain1_6    << SAADC_CH_CONFIG_GAIN_Pos) |
                            (SAADC_CH_CONFIG_MODE_SE         << SAADC_CH_CONFIG_MODE_Pos) |
                            (SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) |
                            (SAADC_CH_CONFIG_RESN_Bypass     << SAADC_CH_CONFIG_RESN_Pos) |
                            (SAADC_CH_CONFIG_RESP_Bypass     << SAADC_CH_CONFIG_RESP_Pos) |
                            (SAADC_CH_CONFIG_TACQ_20us       << SAADC_CH_CONFIG_TACQ_Pos);
	
	NRF_SAADC->CH[2].CONFIG = (SAADC_CH_CONFIG_GAIN_Gain1_6    << SAADC_CH_CONFIG_GAIN_Pos) |
                            (SAADC_CH_CONFIG_MODE_SE         << SAADC_CH_CONFIG_MODE_Pos) |
                            (SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) |
                            (SAADC_CH_CONFIG_RESN_Bypass     << SAADC_CH_CONFIG_RESN_Pos) |
                            (SAADC_CH_CONFIG_RESP_Bypass     << SAADC_CH_CONFIG_RESP_Pos) |
                            (SAADC_CH_CONFIG_TACQ_20us       << SAADC_CH_CONFIG_TACQ_Pos);
	
	NRF_SAADC->CH[3].CONFIG = (SAADC_CH_CONFIG_GAIN_Gain1_6    << SAADC_CH_CONFIG_GAIN_Pos) |
                            (SAADC_CH_CONFIG_MODE_SE         << SAADC_CH_CONFIG_MODE_Pos) |
                            (SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) |
                            (SAADC_CH_CONFIG_RESN_Bypass     << SAADC_CH_CONFIG_RESN_Pos) |
                            (SAADC_CH_CONFIG_RESP_Bypass     << SAADC_CH_CONFIG_RESP_Pos) |
                            (SAADC_CH_CONFIG_TACQ_20us       << SAADC_CH_CONFIG_TACQ_Pos);
														
	NRF_SAADC->CH[4].CONFIG = (SAADC_CH_CONFIG_GAIN_Gain1_6    << SAADC_CH_CONFIG_GAIN_Pos) |
                            (SAADC_CH_CONFIG_MODE_SE         << SAADC_CH_CONFIG_MODE_Pos) |
                            (SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) |
                            (SAADC_CH_CONFIG_RESN_Bypass     << SAADC_CH_CONFIG_RESN_Pos) |
                            (SAADC_CH_CONFIG_RESP_Bypass     << SAADC_CH_CONFIG_RESP_Pos) |
                            (SAADC_CH_CONFIG_TACQ_20us       << SAADC_CH_CONFIG_TACQ_Pos);
														
// Configure the SAADC resolution.
NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_12bit << SAADC_RESOLUTION_VAL_Pos;

// Configure result to be put in RAM at the location of "result" variable.
NRF_SAADC->RESULT.MAXCNT = 5;
NRF_SAADC->RESULT.PTR = (uint32_t)&adcr;

// No automatic sampling, will trigger with TASKS_SAMPLE.
NRF_SAADC->SAMPLERATE = SAADC_SAMPLERATE_MODE_Task << SAADC_SAMPLERATE_MODE_Pos;

// Enable SAADC (would capture analog pins if they were used in CH[0].PSELP)
NRF_SAADC->ENABLE = SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos;

 
NRF_SAADC->CH[0].PSELP = SAADC_CH_PSELP_PSELP_AnalogInput0 << SAADC_CH_PSELP_PSELP_Pos; // Collego POS a ANALOG INPUT 0
NRF_SAADC->CH[0].PSELN = SAADC_CH_PSELN_PSELN_NC << SAADC_CH_PSELN_PSELN_Pos;           // Collego NEG a GND (Single ended)
  
NRF_SAADC->CH[1].PSELP = SAADC_CH_PSELP_PSELP_AnalogInput1 << SAADC_CH_PSELP_PSELP_Pos; // Collego POS a ANALOG INPUT 1
NRF_SAADC->CH[1].PSELN = SAADC_CH_PSELN_PSELN_NC << SAADC_CH_PSELN_PSELN_Pos;           // Collego NEG a GND (Single ended)

NRF_SAADC->CH[2].PSELP = SAADC_CH_PSELP_PSELP_AnalogInput2 << SAADC_CH_PSELP_PSELP_Pos; // Collego POS a ANALOG INPUT 2
NRF_SAADC->CH[2].PSELN = SAADC_CH_PSELN_PSELN_NC << SAADC_CH_PSELN_PSELN_Pos;           // Collego NEG a GND (Single ended)
	
NRF_SAADC->CH[3].PSELP = SAADC_CH_PSELP_PSELP_AnalogInput3 << SAADC_CH_PSELP_PSELP_Pos; // Collego POS a ANALOG INPUT 3
NRF_SAADC->CH[3].PSELN = SAADC_CH_PSELN_PSELN_NC << SAADC_CH_PSELN_PSELN_Pos;           // Collego NEG a GND (Single ended)

NRF_SAADC->CH[4].PSELP = SAADC_CH_PSELP_PSELP_AnalogInput4 << SAADC_CH_PSELP_PSELP_Pos; // Collego POS a ANALOG INPUT 4
NRF_SAADC->CH[4].PSELN = SAADC_CH_PSELN_PSELN_NC << SAADC_CH_PSELN_PSELN_Pos;           // Collego NEG a GND (Single ended)
  	
}
Related