ESPHome  2024.4.0
gpio.cpp
Go to the documentation of this file.
1 #ifdef USE_RP2040
2 
3 #include "gpio.h"
4 #include "esphome/core/log.h"
5 
6 namespace esphome {
7 namespace rp2040 {
8 
9 static const char *const TAG = "rp2040";
10 
11 static int IRAM_ATTR flags_to_mode(gpio::Flags flags, uint8_t pin) {
12  if (flags == gpio::FLAG_INPUT) { // NOLINT(bugprone-branch-clone)
13  return INPUT;
14  } else if (flags == gpio::FLAG_OUTPUT) {
15  return OUTPUT;
16  } else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLUP)) {
17  return INPUT_PULLUP;
18  } else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLDOWN)) {
19  return INPUT_PULLDOWN;
20  // } else if (flags == (gpio::FLAG_OUTPUT | gpio::FLAG_OPEN_DRAIN)) {
21  // return OpenDrain;
22  } else {
23  return 0;
24  }
25 }
26 
27 struct ISRPinArg {
28  uint8_t pin;
29  bool inverted;
30 };
31 
33  auto *arg = new ISRPinArg{}; // NOLINT(cppcoreguidelines-owning-memory)
34  arg->pin = pin_;
35  arg->inverted = inverted_;
36  return ISRInternalGPIOPin((void *) arg);
37 }
38 
39 void RP2040GPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const {
40  PinStatus arduino_mode = LOW;
41  switch (type) {
43  arduino_mode = inverted_ ? FALLING : RISING;
44  break;
46  arduino_mode = inverted_ ? RISING : FALLING;
47  break;
49  arduino_mode = CHANGE;
50  break;
52  arduino_mode = inverted_ ? HIGH : LOW;
53  break;
55  arduino_mode = inverted_ ? LOW : HIGH;
56  break;
57  }
58 
59  attachInterrupt(pin_, func, arduino_mode, arg);
60 }
62  pinMode(pin_, flags_to_mode(flags, pin_)); // NOLINT
63 }
64 
65 std::string RP2040GPIOPin::dump_summary() const {
66  char buffer[32];
67  snprintf(buffer, sizeof(buffer), "GPIO%u", pin_);
68  return buffer;
69 }
70 
72  return bool(digitalRead(pin_)) != inverted_; // NOLINT
73 }
74 void RP2040GPIOPin::digital_write(bool value) {
75  digitalWrite(pin_, value != inverted_ ? 1 : 0); // NOLINT
76 }
77 void RP2040GPIOPin::detach_interrupt() const { detachInterrupt(pin_); }
78 
79 } // namespace rp2040
80 
81 using namespace rp2040;
82 
83 bool IRAM_ATTR ISRInternalGPIOPin::digital_read() {
84  auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
85  return bool(digitalRead(arg->pin)) != arg->inverted; // NOLINT
86 }
87 void IRAM_ATTR ISRInternalGPIOPin::digital_write(bool value) {
88  auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
89  digitalWrite(arg->pin, value != arg->inverted ? 1 : 0); // NOLINT
90 }
91 void IRAM_ATTR ISRInternalGPIOPin::clear_interrupt() {
92  // TODO: implement
93  // auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
94  // GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1UL << arg->pin);
95 }
96 void IRAM_ATTR ISRInternalGPIOPin::pin_mode(gpio::Flags flags) {
97  auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
98  pinMode(arg->pin, flags_to_mode(flags, arg->pin)); // NOLINT
99 }
100 
101 } // namespace esphome
102 
103 #endif // USE_RP2040
Copy of GPIOPin that is safe to use from ISRs (with no virtual functions)
Definition: gpio.h:66
bool digital_read() override
Definition: gpio.cpp:71
void digital_write(bool value) override
Definition: gpio.cpp:74
void pin_mode(gpio::Flags flags) override
Definition: gpio.cpp:61
ISRInternalGPIOPin to_isr() const override
Definition: gpio.cpp:32
void pin_mode(gpio::Flags flags)
Definition: gpio.cpp:128
uint8_t type
const uint32_t flags
Definition: stm32flash.h:85
void attach_interrupt(void(*func)(void *), void *arg, gpio::InterruptType type) const override
Definition: gpio.cpp:39
InterruptType
Definition: gpio.h:40
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
std::string dump_summary() const override
Definition: gpio.cpp:65
void digital_write(bool value)
Definition: gpio.cpp:121
void detach_interrupt() const override
Definition: gpio.cpp:77