Zephyr shell ADC reading: Channel 0 not configured

Hi there,

I use the ADC in my firmware, which works well, but I also want to use it from the shell.

I enabled the CONFIG_ADC_SHELL Kconfig option, which made the "adc" command available in the shell, but I get the following error:

$ adc adc@40007000 read 0
E: Channel 0 not configured

The relevant devicetree nodes:

&adc {
    status = "okay";
    #address-cells = <1>;
    #size-cells = <0>;

    channel@0 {
        reg = <0>;
        zephyr,gain = "ADC_GAIN_1_6";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,input-positive = <NRF_SAADC_AIN2>; // TS_ADC
        zephyr,resolution = <12>;
    };

    channel@1 {
        reg = <1>;
        zephyr,gain = "ADC_GAIN_1_4";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,input-positive = <NRF_SAADC_AIN3>; // VBAT_ADC
        zephyr,resolution = <12>;
    };
};

Thanks in advance!

- Laci

  • Hi Laci

    I see the same on my side. Most likely the shell module will not initialize the ADC driver for you, and you have to do this in the application.

    Could you try this and see if it works better? 

    You could use the battery sample for reference in order to see how ADC initialization is handled.

    Best regards
    Torbjørn 

  • Hi Torbjørn,

    I actually initialize the ADC in my application:

    #include <zephyr/drivers/gpio.h>
    #include <zephyr/sys/util.h>
    
    #define DT_SPEC_AND_COMMA(node_id, prop, idx) \
        ADC_DT_SPEC_GET_BY_IDX(node_id, idx),
    const struct adc_dt_spec adc_channels[] = {
        DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels, DT_SPEC_AND_COMMA)
    };
    
    void InitCharger(void) {
        for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
            if (!device_is_ready(adc_channels[i].dev)) {
                printk("ADC controller device %s not ready\n", adc_channels[i].dev->name);
                return;
            }
            int err;
            err = adc_channel_setup_dt(&adc_channels[i]);
            if (err < 0) {
                printk("Could not setup channel #%d (%d)\n", i, err);
                return;
            }
        }
    }

    Afterward, I can read ADC values with adc_sequence_init_dt() followed by adc_read() in my application, so I'd expect the ADC shell module to read the ADC as well.

  • Hi Laci

    It seems you need to configure the ADC channel through the shell before you can read it. One of the developers shared a snippet showing how they have configured the ADC shell in the past, you can use that for reference:

    adc adc@e000 acq_time 40 us
    adc adc@e000 resolution 10
    adc adc@e000 reference INTERNAL
    adc adc@e000 gain GAIN_1_6
    adc adc@e000 channel id 4
    adc adc@e000 channel negative 0
    adc adc@e000 channel positive 5
    adc adc@e000 channel id 5
    adc adc@e000 channel negative 0
    adc adc@e000 channel positive 6
    adc adc@e000 channel id 0
    adc adc@e000 channel negative 0
    adc adc@e000 channel positive 1
    adc adc@e000 channel id 1
    adc adc@e000 channel negative 0
    adc adc@e000 channel positive 2

    Best regards
    Torbjørn

Related