35#ifndef _DRIVERS_ESP32GPIO_HXX_
36#define _DRIVERS_ESP32GPIO_HXX_
44#include <driver/gpio.h>
45#include <esp_rom_gpio.h>
47#include <soc/gpio_struct.h>
49#if defined(CONFIG_IDF_TARGET_ESP32C3)
53#define IS_GPIO_OUTPUT(pin) (GPIO_IS_VALID_OUTPUT_GPIO(pin) && \
54 GPIO.enable.data & BIT(pin & 25))
59#define IS_GPIO_OUTPUT(pin) (GPIO_IS_VALID_OUTPUT_GPIO(pin) && \
60 (pin < 32) ? GPIO.enable & BIT(pin & 31) : \
61 GPIO.enable1.data & BIT(pin & 31))
64template <
class Defs,
bool SAFE_VALUE,
bool INVERT>
struct GpioOutputPin;
65template <
class Defs,
bool PUEN,
bool PDEN>
struct GpioInputPin;
74template <gpio_num_t PIN_NUM,
bool INVERTED = false>
78#if CONFIG_IDF_TARGET_ESP32S3
79 static_assert(PIN_NUM >= 0 && PIN_NUM <= 48,
"Valid pin range is 0..48.");
80 static_assert(!(PIN_NUM >= 22 && PIN_NUM <= 25)
81 ,
"Pin does not exist");
82 static_assert(!(PIN_NUM >= 26 && PIN_NUM <= 32)
83 ,
"Pin is reserved for flash usage.");
84#if defined(CONFIG_SPIRAM_MODE_OCT) || defined(CONFIG_ESPTOOLPY_OCT_FLASH)
85 static_assert(!(PIN_NUM >= 33 && PIN_NUM <= 37),
86 "Pin is not available when Octal SPI mode is enabled.");
88#elif CONFIG_IDF_TARGET_ESP32S2
89 static_assert(PIN_NUM >= 0 && PIN_NUM <= 46,
"Valid pin range is 0..46.");
90 static_assert(!(PIN_NUM >= 22 && PIN_NUM <= 25)
91 ,
"Pin does not exist");
92 static_assert(!(PIN_NUM >= 26 && PIN_NUM <= 32)
93 ,
"Pin is reserved for flash usage.");
94#elif CONFIG_IDF_TARGET_ESP32C3
95 static_assert(PIN_NUM >= 0 && PIN_NUM <= 21,
"Valid pin range is 0..21.");
98 static_assert(!(PIN_NUM >= 11 && PIN_NUM <= 17)
99 ,
"Pin is reserved for flash usage.");
101 static_assert(PIN_NUM >= 0 && PIN_NUM <= 39,
"Valid pin range is 0..39.");
102 static_assert(PIN_NUM != 24,
"Pin does not exist");
103 static_assert(!(PIN_NUM >= 28 && PIN_NUM <= 31),
"Pin does not exist");
109#if defined(ESP32_PICO)
110 static_assert(!(PIN_NUM >= 6 && PIN_NUM <= 8)
111 ,
"Pin is reserved for flash usage.");
112 static_assert(PIN_NUM != 11 && PIN_NUM != 16 && PIN_NUM != 17
113 ,
"Pin is reserved for flash usage.");
115 static_assert(!(PIN_NUM >= 6 && PIN_NUM <= 11)
116 ,
"Pin is reserved for flash usage.");
117#if defined(BOARD_HAS_PSRAM) || defined(CONFIG_SPIRAM_SUPPORT)
118 static_assert(PIN_NUM != 16 && PIN_NUM != 17
119 ,
"Pin is reserved for PSRAM usage.");
131 LOG(
VERBOSE,
"Esp32Gpio(%d) write %s", PIN_NUM,
132 new_state == Value::SET ?
"CLR" :
"SET");
133 ESP_ERROR_CHECK(gpio_set_level(PIN_NUM, new_state == Value::CLR));
137 LOG(
VERBOSE,
"Esp32Gpio(%d) write %s", PIN_NUM,
138 new_state == Value::SET ?
"SET" :
"CLR");
139 ESP_ERROR_CHECK(gpio_set_level(PIN_NUM, new_state));
147 return (
Value)gpio_get_level(PIN_NUM);
165 if (dir == Direction::DOUTPUT)
167 HASSERT(GPIO_IS_VALID_OUTPUT_GPIO(PIN_NUM));
171 gpio_set_direction(PIN_NUM, GPIO_MODE_INPUT_OUTPUT));
172 LOG(
VERBOSE,
"Esp32Gpio(%d) configured as OUTPUT", PIN_NUM);
176 ESP_ERROR_CHECK(gpio_set_direction(PIN_NUM, GPIO_MODE_INPUT));
177 LOG(
VERBOSE,
"Esp32Gpio(%d) configured as INPUT", PIN_NUM);
187 return Direction::DOUTPUT;
189 return Direction::DINPUT;
192 template <
class Defs,
bool SAFE_VALUE,
bool INVERT>
friend struct GpioOutputPin;
193 template <
class Defs,
bool PUEN,
bool PDEN>
friend struct GpioInputPin;
203template <gpio_num_t PIN_NUM,
bool INVERTED>
211template <
class Defs,
bool SAFE_VALUE,
bool INVERT = false>
217#if CONFIG_IDF_TARGET_ESP32S2
218 static_assert(PIN_NUM != 46,
"Pin 46 can not be used for output.");
219#elif CONFIG_IDF_TARGET_ESP32
220 static_assert(PIN_NUM < 34,
"Pins 34 and above can not be used as output.");
227 "[Esp32Gpio] Configuring output pin %d, default value: %d",
228 PIN_NUM, SAFE_VALUE);
229 esp_rom_gpio_pad_select_gpio(PIN_NUM);
231 memset(&cfg, 0,
sizeof(gpio_config_t));
232 cfg.pin_bit_mask = BIT64(PIN_NUM);
235 cfg.mode = GPIO_MODE_INPUT_OUTPUT;
236 ESP_ERROR_CHECK(gpio_config(&cfg));
237 ESP_ERROR_CHECK(gpio_set_level(PIN_NUM, SAFE_VALUE));
243 ESP_ERROR_CHECK(gpio_set_level(PIN_NUM, SAFE_VALUE));
254 static void set(
bool value)
305template <
class Defs,
bool PUEN,
bool PDEN>
struct GpioInputPin :
public Defs
309#if CONFIG_IDF_TARGET_ESP32S2
311 static_assert(!PUEN || (PUEN && (PIN_NUM != 45 && PIN_NUM != 46)),
312 "GPIO 45 and 46 typically have built-in pull-down "
313 "resistors, enabling pull-up is not possible.");
315 static_assert(!PDEN || (PDEN && PIN_NUM != 0),
316 "GPIO 0 typically has a built-in pull-up resistors, "
317 "enabling pull-down is not possible.");
318#elif CONFIG_IDF_TARGET_ESP32S3
320 static_assert(!PDEN || (PDEN && PIN_NUM != 0),
321 "GPIO 0 typically has a built-in pull-up resistors, "
322 "enabling pull-down is not possible.");
323#elif CONFIG_IDF_TARGET_ESP32C3
325 static_assert(!PDEN || (PDEN && PIN_NUM != 9),
326 "GPIO 9 typically has a built-in pull-up resistors, "
327 "enabling pull-down is not possible.");
330 static_assert(!PUEN ||
331 (PUEN && (PIN_NUM != 2 && PIN_NUM != 4 && PIN_NUM != 12)),
332 "GPIO 2, 4, 12 typically have built-in pull-down resistors, "
333 "enabling pull-up is not possible.");
335 static_assert(!PDEN ||
336 (PDEN && (PIN_NUM != 0 && PIN_NUM != 5 && PIN_NUM == 15)),
337 "GPIO 0, 5, 15 typically have built-in pull-up resistors, "
338 "enabling pull-down is not possible.");
341 static void hw_init()
343 LOG(
VERBOSE,
"[Esp32Gpio] Configuring input pin %d, PUEN: %d, PDEN: %d",
344 PIN_NUM, PUEN, PDEN);
345 esp_rom_gpio_pad_select_gpio(PIN_NUM);
347 memset(&cfg, 0,
sizeof(gpio_config_t));
348 cfg.pin_bit_mask = BIT64(PIN_NUM);
351 cfg.mode = GPIO_MODE_INPUT;
354 cfg.pull_up_en = GPIO_PULLUP_ENABLE;
358 cfg.pull_down_en = GPIO_PULLDOWN_ENABLE;
360 ESP_ERROR_CHECK(gpio_config(&cfg));
558#define GPIO_PIN(NAME, BaseClass, NUM) \
561 static const gpio_num_t PIN_NUM = (gpio_num_t)NUM; \
564 static gpio_num_t pin() \
569 typedef BaseClass<NAME##Defs> NAME##_Pin
#define IS_GPIO_OUTPUT(pin)
Helper macro to test if a pin has been configured for output.
Defines a GPIO output pin.
void clr() const override
Sets output to LOW.
void set() const override
Sets output to HIGH.
void set_direction(Direction dir) const override
Sets the direction of the connected GPIO pin.
static const Esp32Gpio instance_
Static instance variable that can be used for libraries expecting a generic Gpio pointer.
Direction direction() const override
Gets the GPIO direction.
void write(Value new_state) const override
Sets the output state of the connected GPIO pin.
Value read() const override
Reads the current state of the connected GPIO pin.
OS-independent abstraction for GPIO.
virtual void write(Value new_state) const =0
Writes a GPIO output pin (set or clear to a specific state).
Value
Defines the options for GPIO level.
Direction
Defines the options for GPIO direction.
virtual Value read() const =0
Retrieves the current Value of a GPIO input pin.
#define LOG(level, message...)
Conditionally write a message to the logging output.
static const int VERBOSE
Loglevel that is usually not printed, reporting debugging information.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Parametric GPIO output class.
static constexpr const Gpio * instance()
static void toggle()
Toggles the state of the pin to the opposite of what it is currently.
static void hw_init()
Initializes the hardware pin.
static void set(bool value)
Sets the output pin.
static void hw_set_to_safe()
Sets the hardware pin to a safe value.
Defines a GPIO output pin, initialized to be an output pin with high level.
Defines a GPIO output pin, initialized to be an output pin with high level.
Defines a GPIO output pin, initialized to be an output pin with low level.
Defines a GPIO output pin, initialized to be an output pin with low level.