Mapping GPIO pins to ADC channel

Elijahg
Posts: 12
Joined: Sat Dec 08, 2018 3:30 am

Mapping GPIO pins to ADC channel

Postby Elijahg » Mon Mar 11, 2019 12:47 am

Hi guys,

I've searched and examined headers for quite some time but am yet to come up with an answer. Is there a function or macro that will map a gpio_num_t to adc1_channel_t? There is an adc1_pad_get_io_num function which converts adc1_channel_t to gpio_num_t (i.e. ADC channel to GPIO pin), but since the ADC channel isn't really used for anything except internally; it seems a bit pointless and an oversight not to have the inverse. At the moment I have to manually look up the channel for each pin, there appears to be no way programatically. Also, it surely would make sense for the adc1 functions to take a GPIO pin number rather than a specific ADC channel, or at least be overloaded to do both?

Thanks
-Eli

PhracturedBlue
Posts: 1
Joined: Sun Feb 27, 2022 3:48 am

Re: Mapping GPIO pins to ADC channel

Postby PhracturedBlue » Sun Feb 27, 2022 3:55 am

I know this is a very old topic, but I ran into the issue of wanting to convert a given GPIO pin # to the corresponding ADC without having to create a mapping for each of the ESP32 variants.

I came up with the following CPP macros to achieve this:

Code: Select all

#define _ADC_TO_GPIO(x) x ## _GPIO_NUM
#define ADC_TO_GPIO(x) _ADC_TO_GPIO(x)
#define _GPIO_TO_ADC1(x) ADC1_GPIO ## x ##_CHANNEL
#define GPIO_TO_ADC1(x) _GPIO_TO_ADC1(x)
#define _GPIO_TO_ADC2(x) ADC2_GPIO ## x ##_CHANNEL
#define GPIO_TO_ADC2(x) _GPIO_TO_ADC2(x)

// Use some convoluted macro-magic to find the corresponding ADC for a specified GPIO
// Because ADCx_CHANNELx is n Enum, we can't use macro checks to verify which mapping is correct
//  Instead:
//    (1)  map GPIO->ADCx_GPIOy_CHANNEL : This will either result in an enum or an undefined macro
//    (2)  map (1) -> ADCx_CHANNEL_y_GPIO_NUM :
//         If (1) mapped to an enum, this will map back to a GPIO #
//         If (1) did NOT map to an enum, this will map to an empty value
//    (3)  compare (2) to the original GPIO which will only succeed if (1) mapped properly
#if (ADC_TO_GPIO(GPIO_TO_ADC1(CONFIG_BUTTON_INTR_PIN)) == CONFIG_BUTTON_INTR_PIN)
#if (ADC_TO_GPIO(GPIO_TO_ADC1(CONFIG_GPIO_PIN)) == CONFIG_GPIO_PIN)
    #define CONFIG_ADC_CHAN GPIO_TO_ADC1(CONFIG_GPIO_PIN)
#elif (ADC_TO_GPIO(GPIO_TO_ADC2(CONFIG_GPIO_PIN)) == CONFIG_GPIO_PIN)
    #define CONFIG_ADC_CHAN GPIO_TO_ADC2(CONFIG_GPIO_PIN)
#else
    #error "No ADC found for CONFIG_GPIO_PIN" 
    #define CONFIG_BUTTON_ADC_CHAN 0
#endif
With the above code, a CONFIG_GPIO_PIN can be defined as part of Kconfig, and this code will set CONFIG_ADC_CHAN to the equivalent ADC channel if one exists. If not, it will raise a compile-time error

Who is online

Users browsing this forum: No registered users and 431 guests