adc_nrfx_saadc: Channel 0 not configured, adc_read() failed with error code -22

I use nRF52832 SAADC to measure battery voltage. But I encounter <err> adc_nrfx_saadc: Channel 0 not configured, adc_read() failed, ret=-22. Do you have suggestion to configure channel 0? What is meaning of error code -22?

00> *** Booting Zephyr OS build v3.3.99-ncs1 ***
00> btInit() e
00> _btReady(0) e
00> Bluetooth initialized
00> _btReady(0) x
00> btInit() x
00> [00:00:00.006,011] <dbg> fs_nvs: nvs_recover_last_ate: Recovering last ate from sector 0
00> [00:00:00.012,542] <inf> fs_nvs: 3 Sectors of 4096 bytes
00> [00:00:00.012,573] <inf> fs_nvs: alloc wra: 0, fe8
00> [00:00:00.012,573] <inf> fs_nvs: data wra: 0, 0
00> [00:00:00.012,603] <err> adc_nrfx_saadc: Selected ADC gain is not valid
00> [00:00:00.012,603] <err> battery: adc_channel_setup() failed, errCode=-22
00> configure POWER_UP pin as output
00> configure LED_G pin as output
00> set POWER_UP pin
00> device_is_ready() ok
00> nrfx_gpiote_input_configure() okay for button
00> val=0
00> button pressed
00> start a timer
00> 12
00> lis2dh12 device is ready!
00> LIS2DH12 ID check ok, id=0x33
00> lis2dh12 ID check pass!
00> _buttonTimerHandler: 3012
00> button released
00> Button pressed at 132376
00> start a timer
00> 4039
00> _buttonTimerHandler: 7039
00> button pressed
00> power up
00> connected() e
00> Connected F0:92:AF:29:DA:F8 (random)
00> btInfo.le.interval=6
00> btInfo.le.latency=0
00> btInfo.le.timeout=400
00> _gCurrentConn=0x200021f8
00> state = connect
00> btNusThreadCreate() e
00> connected() x
00> _basTimerHandler: 30692
00> batteryVoltageEnable(1) e
00> Enabling battery measurement ok
00> [00:00:30.692,657] <err> adc_nrfx_saadc: Channel 0 not configured
00>  adc_read() failed, ret=-22

Procedures to reproduce this issue are as follows.

1. Unzipping custom_nrf52832.zip to C:\ncs\v2.4.0\nrf\boards\arm folder.

2. Unzipping minimal_log_battery.zip to C:\ncs\v2.4.0\nrf\samples folder.

3. cd C:\ncs\v2.4.0\nrf\samples\minimal_log_battery

4. west build -b custom_nrf52832

5. west flash

6. Rebooting nRF52832 device and connecting to nRF Connect Windows APP.

Parents
  • I found the error is because I set gain of struct adc_channel_cfg to ADC_GAIN_128. Why adc_nrfx_channel_setup() limits maximum gain to ADC_GAIN_4?

    static int adc_nrfx_channel_setup(const struct device *dev,
    				  const struct adc_channel_cfg *channel_cfg)
    {
    	nrf_saadc_channel_config_t config = {
    		.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
    		.resistor_n = NRF_SAADC_RESISTOR_DISABLED,
    		.burst      = NRF_SAADC_BURST_DISABLED,
    	};
    	uint8_t channel_id = channel_cfg->channel_id;
    
    	if (channel_id >= SAADC_CH_NUM) {
    		return -EINVAL;
    	}
    
    	switch (channel_cfg->gain) {
    	case ADC_GAIN_1_6:
    		config.gain = NRF_SAADC_GAIN1_6;
    		break;
    	case ADC_GAIN_1_5:
    		config.gain = NRF_SAADC_GAIN1_5;
    		break;
    	case ADC_GAIN_1_4:
    		config.gain = NRF_SAADC_GAIN1_4;
    		break;
    	case ADC_GAIN_1_3:
    		config.gain = NRF_SAADC_GAIN1_3;
    		break;
    	case ADC_GAIN_1_2:
    		config.gain = NRF_SAADC_GAIN1_2;
    		break;
    	case ADC_GAIN_1:
    		config.gain = NRF_SAADC_GAIN1;
    		break;
    	case ADC_GAIN_2:
    		config.gain = NRF_SAADC_GAIN2;
    		break;
    	case ADC_GAIN_4:
    		config.gain = NRF_SAADC_GAIN4;
    		break;
    	default:
    		LOG_ERR("Selected ADC gain is not valid");
    		return -EINVAL;
    	}
    
    	switch (channel_cfg->reference) {
    	case ADC_REF_INTERNAL:
    		config.reference = NRF_SAADC_REFERENCE_INTERNAL;
    		break;
    	case ADC_REF_VDD_1_4:
    		config.reference = NRF_SAADC_REFERENCE_VDD4;
    		break;
    	default:
    		LOG_ERR("Selected ADC reference is not valid");
    		return -EINVAL;
    	}
    
    	switch (channel_cfg->acquisition_time) {
    	case ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 3):
    		config.acq_time = NRF_SAADC_ACQTIME_3US;
    		break;
    	case ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5):
    		config.acq_time = NRF_SAADC_ACQTIME_5US;
    		break;
    	case ADC_ACQ_TIME_DEFAULT:
    	case ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 10):
    		config.acq_time = NRF_SAADC_ACQTIME_10US;
    		break;
    	case ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 15):
    		config.acq_time = NRF_SAADC_ACQTIME_15US;
    		break;
    	case ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20):
    		config.acq_time = NRF_SAADC_ACQTIME_20US;
    		break;
    	case ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 40):
    		config.acq_time = NRF_SAADC_ACQTIME_40US;
    		break;
    	default:
    		LOG_ERR("Selected ADC acquisition time is not valid");
    		return -EINVAL;
    	}
    
    	config.mode = (channel_cfg->differential ?
    		NRF_SAADC_MODE_DIFFERENTIAL : NRF_SAADC_MODE_SINGLE_ENDED);
    
    	/* Keep the channel disabled in hardware (set positive input to
    	 * NRF_SAADC_INPUT_DISABLED) until it is selected to be included
    	 * in a sampling sequence.
    	 */
    
    	nrf_saadc_channel_init(NRF_SAADC, channel_id, &config);
    	nrf_saadc_channel_input_set(NRF_SAADC,
    				    channel_id,
    				    NRF_SAADC_INPUT_DISABLED,
    				    channel_cfg->input_negative);
    
    	/* Store the positive input selection in a dedicated array,
    	 * to get it later when the channel is selected for a sampling
    	 * and to mark the channel as configured (ready to be selected).
    	 */
    	m_data.positive_inputs[channel_id] = channel_cfg->input_positive;
    
    	return 0;
    }

  • Hello,

    I am glad to read that you were able to resolve your initial issue! :) 

    snowuyl said:
    Why adc_nrfx_channel_setup() limits maximum gain to ADC_GAIN_4?

    The possible gain configurations is limited by the SAADC's hardware capabilities.

    Best regards,
    Karl

Reply Children
Related