ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
gpio_pin.h
Go to the documentation of this file.
1#pragma once
2#include <algorithm>
3#include <concepts>
4#include <cstdint>
5#include <type_traits>
6
9#include "esphome/core/log.h"
10
11namespace esphome {
12
14inline constexpr size_t GPIO_SUMMARY_MAX_LEN = 48;
15
16#ifdef USE_ESP8266
17#define LOG_PIN(prefix, pin) log_pin(TAG, F(prefix), pin)
18#else
19#define LOG_PIN(prefix, pin) log_pin(TAG, prefix, pin)
20#endif
21
22// put GPIO flags in a namespace to not pollute esphome namespace
23namespace gpio {
24
25enum Flags : uint8_t {
26 // Can't name these just INPUT because of Arduino defines :(
27 FLAG_NONE = 0x00,
28 FLAG_INPUT = 0x01,
33 FLAG_HOLD = 0x20,
34};
35
37 public:
38 constexpr FlagsHelper(Flags val) : val_(val) {}
39 constexpr operator Flags() const { return val_; }
40
41 protected:
43};
44constexpr FlagsHelper operator&(Flags lhs, Flags rhs) {
45 return static_cast<Flags>(static_cast<uint8_t>(lhs) & static_cast<uint8_t>(rhs));
46}
47constexpr FlagsHelper operator|(Flags lhs, Flags rhs) {
48 return static_cast<Flags>(static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
49}
50
58
59} // namespace gpio
60
61class GPIOPin {
62 public:
63 virtual void setup() = 0;
64
65 virtual void pin_mode(gpio::Flags flags) = 0;
66
72 virtual gpio::Flags get_flags() const = 0;
73
74 virtual bool digital_read() = 0;
75
76 virtual void digital_write(bool value) = 0;
77
83 virtual size_t dump_summary(char *buffer, size_t len) const;
84
87 virtual bool is_internal() { return false; }
88#ifdef USE_GPIO_HOLD
89 bool get_hold() const { return this->get_flags() & gpio::FLAG_HOLD; }
90 virtual bool is_held() const { return false; }
91#else
92 bool get_hold() const { return false; }
93 bool is_held() const { return false; }
94#endif
95};
96
99 public:
101 ISRInternalGPIOPin(void *arg) : arg_(arg) {}
102 bool digital_read();
103 void digital_write(bool value);
104 void clear_interrupt();
106
107 protected:
108 void *arg_{nullptr};
109};
110
111// What callers of the InternalGPIOPin alias (bound in esphome/core/gpio.h) rely on beyond
112// GPIOPin. The class must be final so calls to the GPIOPin virtuals through the alias are direct.
113// int is arbitrary: any T * exercises the public attach_interrupt<T> template.
114template<typename T>
115concept InternalGPIOPinContract = std::derived_from<T, GPIOPin> && std::is_final_v<T> &&
116 requires(const T pin, void (*func)(int *), int *arg, gpio::InterruptType type) {
117 { pin.get_pin() } -> std::same_as<uint8_t>;
118 { pin.is_inverted() } -> std::same_as<bool>;
119 { pin.to_isr() } -> std::same_as<ISRInternalGPIOPin>;
120 { pin.detach_interrupt() } -> std::same_as<void>;
121 { pin.attach_interrupt(func, arg, type) } -> std::same_as<void>;
122};
123
124// Inline default implementation for GPIOPin::dump_summary.
125// Writes an empty summary; subclasses override to provide pin details.
126inline size_t GPIOPin::dump_summary(char *buffer, size_t len) const {
127 if (len > 0)
128 buffer[0] = '\0';
129 return 0;
130}
131
132// Inline helper for log_pin - allows compiler to inline into log_pin in gpio.cpp
133inline void log_pin_with_prefix(const char *tag, const char *prefix, GPIOPin *pin) {
135 size_t len = pin->dump_summary(buffer, sizeof(buffer));
136 len = std::min(len, sizeof(buffer) - 1);
137 esp_log_printf_(ESPHOME_LOG_LEVEL_CONFIG, tag, __LINE__, "%s%.*s", prefix, (int) len, buffer);
138}
139
140// log_pin function declarations - implementation in gpio.cpp
141#ifdef USE_ESP8266
142void log_pin(const char *tag, const __FlashStringHelper *prefix, GPIOPin *pin);
143#else
144void log_pin(const char *tag, const char *prefix, GPIOPin *pin);
145#endif
146
147} // namespace esphome
virtual void pin_mode(gpio::Flags flags)=0
virtual void setup()=0
bool is_held() const
Definition gpio_pin.h:93
virtual void digital_write(bool value)=0
virtual bool is_internal()
Only the platform pin class behind the InternalGPIOPin alias may return true: callers static_cast to ...
Definition gpio_pin.h:87
virtual gpio::Flags get_flags() const =0
Retrieve GPIO pin flags.
virtual bool digital_read()=0
bool get_hold() const
Definition gpio_pin.h:89
virtual bool is_held() const
Definition gpio_pin.h:90
virtual size_t dump_summary(char *buffer, size_t len) const
Write a summary of this pin to the provided buffer.
Definition gpio_pin.h:126
Copy of GPIOPin that is safe to use from ISRs (with no virtual functions)
Definition gpio_pin.h:98
void digital_write(bool value)
Definition gpio.cpp:227
void pin_mode(gpio::Flags flags)
Definition gpio.cpp:239
constexpr FlagsHelper(Flags val)
Definition gpio_pin.h:38
uint16_t flags
uint8_t type
uint32_t buffer
Definition gif.cpp:50
mopeka_std_values val[3]
@ INTERRUPT_FALLING_EDGE
Definition gpio_pin.h:53
@ INTERRUPT_RISING_EDGE
Definition gpio_pin.h:52
@ INTERRUPT_HIGH_LEVEL
Definition gpio_pin.h:56
@ INTERRUPT_LOW_LEVEL
Definition gpio_pin.h:55
@ INTERRUPT_ANY_EDGE
Definition gpio_pin.h:54
constexpr FlagsHelper operator|(Flags lhs, Flags rhs)
Definition gpio_pin.h:47
constexpr FlagsHelper operator&(Flags lhs, Flags rhs)
Definition gpio_pin.h:44
void HOT esp_log_printf_(int level, const char *tag, int line, const char *format,...)
Definition log.cpp:21
const void size_t len
Definition hal.h:68
void log_pin_with_prefix(const char *tag, const char *prefix, GPIOPin *pin)
Definition gpio_pin.h:133
constexpr size_t GPIO_SUMMARY_MAX_LEN
Maximum buffer size for dump_summary output.
Definition gpio_pin.h:14
void log_pin(const char *tag, const __FlashStringHelper *prefix, GPIOPin *pin)
Definition gpio.cpp:7