4#include <zephyr/drivers/gpio.h>
5#include <zephyr/sys/util.h>
13static gpio_flags_t flags_to_mode(
gpio::Flags flags,
bool inverted,
bool value) {
20 if (value != inverted) {
21 ret |= GPIO_OUTPUT_INIT_HIGH;
23 ret |= GPIO_OUTPUT_INIT_LOW;
30 ret |= GPIO_PULL_DOWN;
33 ret |= GPIO_OPEN_DRAIN;
45 return inverted ? GPIO_INT_EDGE_FALLING : GPIO_INT_EDGE_RISING;
47 return inverted ? GPIO_INT_EDGE_RISING : GPIO_INT_EDGE_FALLING;
49 return GPIO_INT_EDGE_BOTH;
51 return inverted ? GPIO_INT_LEVEL_HIGH : GPIO_INT_LEVEL_LOW;
53 return inverted ? GPIO_INT_LEVEL_LOW : GPIO_INT_LEVEL_HIGH;
55 return inverted ? GPIO_INT_EDGE_FALLING : GPIO_INT_EDGE_RISING;
60static void gpio_interrupt_handler(
const device * , gpio_callback *cb,
uint32_t ) {
61 auto *interrupt = CONTAINER_OF(cb, ZephyrGPIOInterrupt, callback);
62 if (interrupt->func !=
nullptr) {
63 interrupt->func(interrupt->arg);
75 auto *arg =
new ISRPinArg{};
76 arg->gpio = this->
gpio_;
77 arg->pin = this->
pin_;
84 if (!device_is_ready(this->
gpio_)) {
85 ESP_LOGE(TAG,
"Cannot attach interrupt: GPIO device not ready");
100 ESP_LOGE(TAG,
"gpio_add_callback failed for pin %u: %d", this->
pin_, ret);
104 ret = gpio_pin_interrupt_configure(this->
gpio_, port_pin, interrupt_type_to_flags(
type, this->
inverted_));
106 ESP_LOGE(TAG,
"gpio_pin_interrupt_configure failed for pin %u: %d", this->
pin_, ret);
111 ESP_LOGD(TAG,
"Interrupt attached to pin %u (type=%d)", this->
pin_, (
int) type);
115 if (!device_is_ready(this->
gpio_)) {
116 ESP_LOGE(TAG,
"gpio %u is not ready.", this->
pin_);
123 if (
nullptr == this->
gpio_) {
129 ESP_LOGE(TAG,
"gpio %u cannot be configured %d.", this->
pin_, ret);
138 if (
nullptr == this->
gpio_) {
148 if (
nullptr == this->
gpio_) {
155 if (this->
gpio_ ==
nullptr) {
160 gpio_pin_interrupt_configure(this->
gpio_, port_pin, GPIO_INT_DISABLE);
170 auto *arg = (zephyr::ISRPinArg *) this->
arg_;
171 if (arg ==
nullptr || arg->gpio ==
nullptr) {
174 return bool(gpio_pin_get(arg->gpio, arg->pin % arg->gpio_size) != arg->inverted);
178 auto *arg = (zephyr::ISRPinArg *) this->
arg_;
179 if (arg ==
nullptr || arg->gpio ==
nullptr) {
182 gpio_pin_set(arg->gpio, arg->pin % arg->gpio_size, value != arg->inverted ? 1 : 0);
Copy of GPIOPin that is safe to use from ISRs (with no virtual functions)
void digital_write(bool value)
void digital_write(bool value) override
void detach_interrupt() const
const char * pin_name_prefix_
bool digital_read() override
size_t dump_summary(char *buffer, size_t len) const override
void attach_interrupt_(void(*func)(void *), void *arg, gpio::InterruptType type) const
ZephyrGPIOInterrupt interrupt_
ISRInternalGPIOPin to_isr() const
void pin_mode(gpio::Flags flags) override
ESPHOME_LOG_TAG(TAG, "zephyr")
struct gpio_callback callback