SAADC - Scan mode connects inputs to VDD_GPIO?

Hello!

We are using a custom nRF9160 board with 3 differential ADC channels. The differential voltage is measured across two resistors, with the center voltage (normally OpAmp driven) at 1,66 V.

I'm sampling three ADC channels in differential mode and noticed weird results and verified with a scope: Taking a sample with more than one channel enabled results in nRF9160 connecting the ADC-inputs to what appears to be VDD-ish for a period that seems to be TACQ*2. Sampling is triggered by PPI, currently at 1 kHz, and this phenomenon happens at every sample. (Changing the PPI frequency changes the spike positions as well.

Changing to single-ended measurement makes no difference but the problem doesn't show on scope with only one channel enabled.

Do I have something wrong with my SAADC configuration?

UPDATE 2022-10-24: Issue is related to CONFIG_BOOTLOADER_MCUBOOT and pin P0.14, which seems to configured as output and connecting to VDD_GPIO when it is sampling ADC

// SAADC Channel configuration
#define ADC_CONFIG_DIFF (SAADC_CH_CONFIG_GAIN_Gain1     << SAADC_CH_CONFIG_GAIN_Pos) | \
                        (SAADC_CH_CONFIG_MODE_Diff        << 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_10us        << SAADC_CH_CONFIG_TACQ_Pos)

static void init_adc(void) {
  NRF_SAADC_NS->TASKS_CALIBRATEOFFSET = 1;
  
  NRF_SAADC_NS->RESOLUTION = SAADC_RESOLUTION_VAL_12bit;
  
  // Set sampling rate to be controlled by "SAMPLE", call.
  NRF_SAADC_NS->SAMPLERATE = SAADC_SAMPLERATE_MODE_Task;

  //Set the EasyDMA buffer
  active_buffer = 0;
  NRF_SAADC_NS->RESULT.PTR = (uint32_t) &m_sample_buffer_0;
  NRF_SAADC_NS->RESULT.MAXCNT = ADC_TOTAL_BUFFER_LEN;

  // Enable interrupt for buffer full
  NRF_SAADC_NS->INTENSET = SAADC_INTENSET_END_Set << SAADC_INTENSET_END_Pos;
  NRF_SAADC_NS->INTEN |= SAADC_INTEN_END_Enabled << SAADC_INTEN_END_Pos;
  NRF_SAADC_NS->EVENTS_END = 0;
  
// Configure SAADC Channels 
  NRF_SAADC_NS->CH[0].CONFIG = ADC_CONFIG_DIFF;
  NRF_SAADC_NS->CH[0].PSELP = SAADC_CH_PSELP_PSELP_AnalogInput0 << SAADC_CH_PSELP_PSELP_Pos;
  NRF_SAADC_NS->CH[0].PSELN = SAADC_CH_PSELN_PSELN_AnalogInput1 << SAADC_CH_PSELN_PSELN_Pos;


  NRF_SAADC_NS->CH[1].CONFIG = ADC_CONFIG_DIFF;
  NRF_SAADC_NS->CH[1].PSELP = SAADC_CH_PSELP_PSELP_AnalogInput2 << SAADC_CH_PSELP_PSELP_Pos;
  NRF_SAADC_NS->CH[1].PSELN = SAADC_CH_PSELN_PSELN_AnalogInput3 << SAADC_CH_PSELN_PSELN_Pos;


  NRF_SAADC_NS->CH[2].CONFIG = ADC_CONFIG_DIFF;
  NRF_SAADC_NS->CH[2].PSELP = SAADC_CH_PSELP_PSELP_AnalogInput4 << SAADC_CH_PSELP_PSELP_Pos;
  NRF_SAADC_NS->CH[2].PSELN = SAADC_CH_PSELN_PSELN_AnalogInput5 << SAADC_CH_PSELN_PSELN_Pos;

  
  NVIC_EnableIRQ( SAADC_IRQn );
  NVIC_SetPriority( SAADC_IRQn, 1UL );
  IRQ_DIRECT_CONNECT(SAADC_IRQn, 0, SAADC_IRQHandler, 0);
  NRF_SAADC_NS->ENABLE = 1;
}

Scope images (OpAmp off, resulting in ~0,7 V average at the OpAmp output)

Parents
  • Hi,

    Could you add this to your overlay file? It's just to check whether these pins being defined in the pinctrl node is causing issues despite the uart1 node being disabled. If you get an error when building, try some other unused pins for the RTS and CTS.

    &pinctrl {
        uart1_default: uart1_default {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 0, 1)>,
    				<NRF_PSEL(UART_RTS, 1, 10)>;
    		};
    		group2 {
    			psels = <NRF_PSEL(UART_RX, 0, 0)>,
    				<NRF_PSEL(UART_CTS, 1, 11)>;
    			bias-pull-up;
    		};
    	};
    
    	uart1_sleep: uart1_sleep {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 0, 1)>,
    				<NRF_PSEL(UART_RX, 0, 0)>,
    				<NRF_PSEL(UART_RTS, 1, 10)>,
    				<NRF_PSEL(UART_CTS, 1, 11)>;
    			low-power-enable;
    		};
    	};
    };

Reply
  • Hi,

    Could you add this to your overlay file? It's just to check whether these pins being defined in the pinctrl node is causing issues despite the uart1 node being disabled. If you get an error when building, try some other unused pins for the RTS and CTS.

    &pinctrl {
        uart1_default: uart1_default {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 0, 1)>,
    				<NRF_PSEL(UART_RTS, 1, 10)>;
    		};
    		group2 {
    			psels = <NRF_PSEL(UART_RX, 0, 0)>,
    				<NRF_PSEL(UART_CTS, 1, 11)>;
    			bias-pull-up;
    		};
    	};
    
    	uart1_sleep: uart1_sleep {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 0, 1)>,
    				<NRF_PSEL(UART_RX, 0, 0)>,
    				<NRF_PSEL(UART_RTS, 1, 10)>,
    				<NRF_PSEL(UART_CTS, 1, 11)>;
    			low-power-enable;
    		};
    	};
    };

Children
  • Hi, adding that to the project overlay file, no effect for any PIN_CNF's for 10, 11, 14 or 15

    Overlay is included in the build and the other changes (gpio inputs/outputs, aliases and I2C devices) are used in the binary.
    However, when I tried changing the pins in nrf9160_nrf9160_common-pinctrl.dtsi it worked as expected, 10=output, 11=input with pull-up, 14 and 15 were inputs with everything disabled.

    Is it possible the overlay isn't working as we're building for nonsecure while the TFM configuration is done for the secure target?

  • Hm, are you doing pristine builds? Try deleting the build configuration / build folder and have the change only in the overlay. I assume you are targeting the nrf9160dk_nrf9160_ns board, so the overlay name is correct. Can you try putting the overlay in the project folder, next to prj.conf?

    And when you change the uart1 pins in pinctrl, does the SAADC work properly with the P0.14 and P0.15 pins? So we can confirm that it was causing issues, despite uart1 being disabled?

  • Yeah, pristine build in all cases. Build configuration was always the same, though.
    I created a new build configuration, and tried moving the overlay to the project root folder (same as prj.conf). Previously it was in <project_root>/boards.

    No change, P0.14 is still output, P0.10 and P0.11 unchanged.

    If I change the entry in nrf9160_nrf9160_common-pinctrl.dtsi I no longer see the P14 VDD_GPIO spikes using the oscilloscope. So yes, to answer your question is is the P0.14 and P0.15, related to uart1 that is causing my SAADC issues.

Related