23#include <idfxx/intr_alloc>
25#include <driver/gpio.h>
66 input = GPIO_MODE_INPUT,
83 cap_0 = GPIO_DRIVE_CAP_0,
84 cap_1 = GPIO_DRIVE_CAP_1,
85 cap_2 = GPIO_DRIVE_CAP_2,
87 cap_3 = GPIO_DRIVE_CAP_3,
100#if SOC_GPIO_SUPPORT_PIN_HYS_FILTER
103#if SOC_GPIO_SUPPORT_PIN_HYS_CTRL_BY_EFUSE
104 efuse = GPIO_HYS_CTRL_EFUSE,
111 class unique_isr_handle;
167 other._num = GPIO_NUM_NC;
176 if (
this != &other) {
177 if (_num != GPIO_NUM_NC) {
182 other._num = GPIO_NUM_NC;
194 if (_num != GPIO_NUM_NC) {
220#if SOC_GPIO_SUPPORT_PIN_HYS_FILTER
228 : _num(GPIO_NUM_NC) {}
237#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
248 [[nodiscard]]
static constexpr gpio nc() {
return gpio{GPIO_NUM_NC}; }
251 [[nodiscard]]
static constexpr gpio max() {
return gpio{
static_cast<gpio_num_t
>(GPIO_NUM_MAX - 1)}; }
263 return _num != GPIO_NUM_NC && _num >= 0 && _num < GPIO_NUM_MAX && GPIO_IS_VALID_GPIO(_num);
267 [[nodiscard]]
constexpr bool is_output_capable()
const {
return GPIO_IS_VALID_OUTPUT_GPIO(_num); }
273 [[nodiscard]]
constexpr int num()
const {
return static_cast<int>(_num); }
276 [[nodiscard]]
constexpr gpio_num_t
idf_num()
const {
return _num; }
289 gpio_reset_pin(_num);
293#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
348 return guarded([&] {
return gpio_set_direction(_num,
static_cast<gpio_mode_t
>(
mode)); });
356 return guarded([&] {
return gpio_input_enable(_num); });
366 return guarded([&] {
return gpio_set_pull_mode(_num,
static_cast<gpio_pull_mode_t
>(
mode)); });
374 return guarded([&] {
return gpio_pullup_en(_num); });
382 return guarded([&] {
return gpio_pullup_dis(_num); });
390 return guarded([&] {
return gpio_pulldown_en(_num); });
398 return guarded([&] {
return gpio_pulldown_dis(_num); });
406 void set_level(
bool level) { gpio_set_level(_num, level ? 1 : 0); }
412 [[nodiscard]]
bool get_level()
const {
return gpio_get_level(_num) != 0; }
415#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
435 return guarded([&] {
return gpio_set_drive_capability(_num,
static_cast<gpio_drive_cap_t
>(strength)); });
446 gpio_drive_cap_t cap;
447 auto err = gpio_get_drive_capability(_num, &cap);
448 return wrap(err).transform([cap]() {
return static_cast<drive_cap>(cap); });
452#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
482#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
575#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
601 return guarded(gpio_set_intr_type, _num,
static_cast<gpio_int_type_t
>(
intr_type));
617#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
639 return guarded(gpio_wakeup_enable, _num,
static_cast<gpio_int_type_t
>(
intr_type));
649#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
706#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
750 return guarded(gpio_sleep_set_direction, _num,
static_cast<gpio_mode_t
>(
mode));
760 return guarded(gpio_sleep_set_pull_mode, _num,
static_cast<gpio_pull_mode_t
>(pull));
767 template<
typename F,
typename... Args>
768 result<void> guarded(F&& f, Args&&... args)
const {
772 return wrap(std::invoke(std::forward<F>(f), std::forward<Args>(args)...));
797template<
typename... Gpios>
801#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
823template<
typename... Gpios>
834struct gpio_constant {
835 static_assert(N == GPIO_NUM_NC || (SOC_GPIO_VALID_GPIO_MASK & (1ULL << N)),
"Invalid GPIO number");
836 static constexpr gpio value{
static_cast<gpio_num_t
>(N)};
850#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 0))
853#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 1))
856#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 2))
859#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 3))
862#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 4))
865#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 5))
868#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 6))
871#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 7))
874#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 8))
877#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 9))
880#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 10))
883#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 11))
886#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 12))
889#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 13))
892#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 14))
895#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 15))
898#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 16))
901#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 17))
904#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 18))
907#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 19))
910#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 20))
913#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 21))
916#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 22))
919#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 23))
922#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 24))
925#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 25))
928#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 26))
931#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 27))
934#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 28))
937#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 29))
940#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 30))
943#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 31))
946#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 32))
949#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 33))
952#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 34))
955#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 35))
958#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 36))
961#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 37))
964#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 38))
967#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 39))
970#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 40))
973#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 41))
976#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 42))
979#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 43))
982#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 44))
985#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 45))
988#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 46))
991#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 47))
994#if (SOC_GPIO_VALID_GPIO_MASK & (1ULL << 48))
1011 return "GPIO_" + std::to_string(g.
num());
1018#include "sdkconfig.h"
1019#ifdef CONFIG_IDFXX_STD_FORMAT
1025struct formatter<
idfxx::gpio> {
1026 constexpr auto parse(format_parse_context& ctx) {
return ctx.begin(); }
1028 template<
typename FormatContext>
1029 auto format(
idfxx::gpio g, FormatContext& ctx)
const {
1031 return std::copy(s.begin(), s.end(), ctx.out());
Type-safe set of flags from a scoped enum.
Handle to a registered ISR handler.
RAII handle for ISR registration that removes the handler on destruction.
unique_isr_handle & operator=(unique_isr_handle &&other) noexcept
Move assignment operator.
unique_isr_handle() noexcept
Constructs an empty unique_isr_handle.
unique_isr_handle(unique_isr_handle &&other) noexcept
Move constructor.
~unique_isr_handle()
Destructor.
unique_isr_handle & operator=(const unique_isr_handle &)=delete
unique_isr_handle(const unique_isr_handle &)=delete
unique_isr_handle(isr_handle handle) noexcept
Constructs from an isr_handle, taking ownership.
isr_handle release() noexcept
Releases ownership of the handle without removing the ISR.
static result< gpio > make(int num)
Creates a validated GPIO pin.
static void uninstall_isr_service()
Uninstalls the GPIO ISR service, freeing related resources.
result< void > try_set_intr_type(enum intr_type intr_type)
Sets the interrupt trigger type.
void set_drive_capability(enum drive_cap strength)
Sets the gpio drive capability.
result< void > try_pulldown_disable()
Disables the internal pull-down resistor.
static result< void > try_install_isr_service(flags< intr_flag > intr_flags={})
Installs the GPIO ISR service for per-gpio interrupt handlers.
void intr_enable()
Enables interrupts for this gpio.
result< void > try_sleep_set_direction(enum mode mode)
Sets GPIO direction at sleep.
result< void > try_wakeup_enable(enum intr_type intr_type)
Enables GPIO wake-up from light sleep.
result< void > try_set_pull_mode(enum pull_mode mode)
Sets the pull resistor mode.
result< void > try_wakeup_disable()
Disables GPIO wake-up.
result< void > try_sleep_sel_enable()
Enables SLP_SEL to change GPIO status automatically in light sleep.
void pulldown_enable()
Enables the internal pull-down resistor.
constexpr bool is_digital_io_pin_capable() const
Returns true if this gpio is a valid digital I/O pin.
void input_enable()
Enables input on this gpio.
static void deep_sleep_hold_disable()
Disables hold for all digital GPIOs during deep sleep.
void sleep_set_direction(enum mode mode)
Sets GPIO direction at sleep.
void set_level(bool level)
Sets the output level.
constexpr int num() const
Returns the underlying GPIO pin number.
void set_intr_type(enum intr_type intr_type)
Sets the interrupt trigger type.
result< drive_cap > try_get_drive_capability() const
Gets the current drive capability.
result< void > try_set_direction(enum mode mode)
Sets the GPIO direction mode.
void sleep_sel_disable()
Disables SLP_SEL to change GPIO status automatically in light sleep.
result< void > try_pullup_enable()
Enables the internal pull-up resistor.
gpio & operator=(const gpio &)=default
void wakeup_disable()
Disables GPIO wake-up.
result< void > try_intr_disable()
Disables interrupts for this gpio.
friend struct gpio_constant
result< void > try_isr_handler_remove(isr_handle handle)
Removes a specific ISR handler.
static void install_isr_service(flags< intr_flag > intr_alloc_flags={})
Installs the GPIO ISR service for per-gpio interrupt handlers.
result< void > try_set_drive_capability(enum drive_cap strength)
Sets the gpio drive capability.
void set_pull_mode(enum pull_mode mode)
Sets the pull resistor mode.
void pulldown_disable()
Disables the internal pull-down resistor.
static constexpr gpio max()
Returns a GPIO for the highest valid pin number.
gpio & operator=(gpio &&)=default
void sleep_set_pull_mode(enum pull_mode pull)
Sets pull resistor mode at sleep.
result< void > try_input_enable()
Enables input on this gpio.
static constexpr gpio nc()
Returns a GPIO representing "not connected".
result< void > try_hold_disable()
Disables gpio hold function.
void reset()
Resets the gpio to default state.
@ disable
GPIO mode : disable input and output.
@ output
GPIO mode : output only mode.
@ input
GPIO mode : input only.
@ input_output_od
GPIO mode : output and input with open-drain mode.
@ input_output
GPIO mode : output and input mode.
@ output_od
GPIO mode : output only with open-drain mode.
isr_handle isr_handler_add(std::move_only_function< void() const > handler)
Adds an ISR handler for this gpio.
constexpr gpio_num_t idf_num() const
Returns the underlying ESP-IDF GPIO number.
gpio(const gpio &)=default
constexpr gpio()
Constructs a GPIO representing "not connected".
pull_mode
Pull resistor configuration.
@ pullup_pulldown
Pin pull up + pull down.
constexpr bool operator==(const gpio &other) const =default
result< void > try_hold_enable()
Enables gpio hold function.
void intr_disable()
Disables interrupts for this gpio.
void hold_enable()
Enables gpio hold function.
gpio(int num)
Constructs a validated GPIO pin.
result< isr_handle > try_isr_handler_add(std::move_only_function< void() const > handler)
Adds an ISR handler for this gpio.
void isr_handler_remove_all()
Removes all ISR handlers for this gpio.
result< void > try_sleep_set_pull_mode(enum pull_mode pull)
Sets pull resistor mode at sleep.
constexpr bool is_output_capable() const
Returns true if this gpio supports output mode.
isr_handle isr_handler_add(void(*fn)(void *), void *arg)
Adds an ISR handler for this gpio.
drive_cap
Pin drive capability (output strength).
@ cap_0
Pin drive capability: weak.
@ cap_default
Pin drive capability: medium.
@ cap_1
Pin drive capability: stronger.
@ cap_2
Pin drive capability: medium.
@ cap_3
Pin drive capability: strongest.
constexpr bool is_connected() const
Returns true if this is a valid GPIO pin.
void hold_disable()
Disables gpio hold function.
result< void > try_pullup_disable()
Disables the internal pull-up resistor.
result< isr_handle > try_isr_handler_add(void(*fn)(void *), void *arg)
Adds an ISR handler for this gpio.
result< void > try_intr_enable()
Enables interrupts for this gpio.
void set_direction(enum mode mode)
Sets the GPIO direction mode.
void wakeup_enable(enum intr_type intr_type)
Enables GPIO wake-up from light sleep.
result< void > try_pulldown_enable()
Enables the internal pull-down resistor.
bool get_level() const
Reads the current input level.
void sleep_sel_enable()
Enables SLP_SEL to change GPIO status automatically in light sleep.
result< void > try_isr_handler_remove_all()
Removes all ISR handlers for this gpio.
enum drive_cap get_drive_capability() const
Gets the current drive capability.
result< void > try_sleep_sel_disable()
Disables SLP_SEL to change GPIO status automatically in light sleep.
hys_ctrl_mode
Hysteresis control mode.
@ soft_enable
Pin input hysteresis enable by software.
@ soft_disable
Pin input hysteresis disable by software.
void pullup_enable()
Enables the internal pull-up resistor.
void pullup_disable()
Disables the internal pull-up resistor.
intr_type
Interrupt trigger type.
@ disable
Disable GPIO interrupt.
@ low_level
GPIO interrupt type : input low level trigger.
@ high_level
GPIO interrupt type : input high level trigger.
@ anyedge
GPIO interrupt type : both rising and falling edge.
@ negedge
GPIO interrupt type : falling edge.
@ posedge
GPIO interrupt type : rising edge.
static void deep_sleep_hold_enable()
Enables hold for all digital GPIOs during deep sleep.
void isr_handler_remove(isr_handle handle)
Removes a specific ISR handler.
std::string to_string(core_id c)
Returns a string representation of a CPU core identifier.
void configure_gpios(const gpio::config &cfg, std::vector< gpio > gpios)
Configures multiple GPIOs with the same settings.
result< void > try_configure_gpios(const gpio::config &cfg, std::vector< gpio > gpios)
Configures multiple GPIOs with the same settings.
constexpr std::unexpected< std::error_code > error(E e) noexcept
Creates an unexpected error from an error code enum.
T unwrap(result< T > result)
Throws a std::system_error if the result is an error.
@ invalid_state
Invalid state.
std::expected< T, std::error_code > result
result type wrapping a value or error code.
result< void > wrap(esp_err_t e)
Wraps an esp_err_t into a result<void>.
Configuration parameters for idfxx::gpio_config.