From 6a5b24335908398fc3906c2c165d0a2e9e2b1125 Mon Sep 17 00:00:00 2001 From: Tomasz Duda Date: Tue, 30 Jan 2024 21:02:02 +0100 Subject: [PATCH] add gpio for zephyr --- esphome/components/nrf52/core_zephyr.cpp | 9 +- esphome/components/nrf52/gpio.h | 2 +- esphome/components/nrf52/gpio_arduino.cpp | 8 +- esphome/components/nrf52/gpio_zephyr.cpp | 102 ++++++++-------------- esphome/core/helpers.h | 1 + 5 files changed, 51 insertions(+), 71 deletions(-) diff --git a/esphome/components/nrf52/core_zephyr.cpp b/esphome/components/nrf52/core_zephyr.cpp index 2d9321f5ea..0b0ad7595b 100644 --- a/esphome/components/nrf52/core_zephyr.cpp +++ b/esphome/components/nrf52/core_zephyr.cpp @@ -1,13 +1,14 @@ #ifdef USE_NRF52 #ifdef USE_ZEPHYR +#include #include namespace esphome { void yield() { ::k_yield(); } -uint32_t millis() { return ::k_ticks_to_ms_floor32(k_uptime_ticks()); } +uint32_t millis() { return k_ticks_to_ms_floor32(k_uptime_ticks()); } void delay(uint32_t ms) { ::k_msleep(ms); } -uint32_t micros() { return ::k_ticks_to_us_floor32(k_uptime_ticks()); } +uint32_t micros() { return k_ticks_to_us_floor32(k_uptime_ticks()); } void arch_init() { // TODO @@ -16,6 +17,10 @@ void arch_feed_wdt() { // TODO } +void arch_restart() { + // TODO +} + void nrf52GetMacAddr(uint8_t *mac) { const uint8_t *src = (const uint8_t *)NRF_FICR->DEVICEADDR; diff --git a/esphome/components/nrf52/gpio.h b/esphome/components/nrf52/gpio.h index 0224670110..9c9d59abd2 100644 --- a/esphome/components/nrf52/gpio.h +++ b/esphome/components/nrf52/gpio.h @@ -26,12 +26,12 @@ class NRF52GPIOPin : public InternalGPIOPin { protected: void attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const override; - uint8_t pin_; bool inverted_; gpio::Flags flags_; #ifdef USE_ZEPHYR const device * gpio_ = nullptr; + bool value_ = false; #endif }; diff --git a/esphome/components/nrf52/gpio_arduino.cpp b/esphome/components/nrf52/gpio_arduino.cpp index ebcb523536..7d6404f5c0 100644 --- a/esphome/components/nrf52/gpio_arduino.cpp +++ b/esphome/components/nrf52/gpio_arduino.cpp @@ -83,7 +83,7 @@ void NRF52GPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpio::Inter void NRF52GPIOPin::setup() { pin_mode(flags_); } void NRF52GPIOPin::pin_mode(gpio::Flags flags) { - pinMode(pin_, flags_to_mode(flags, pin_)); // NOLINT + pinMode(pin_, flags_to_mode(flags, pin_)); } std::string NRF52GPIOPin::dump_summary() const { @@ -93,10 +93,10 @@ std::string NRF52GPIOPin::dump_summary() const { } bool NRF52GPIOPin::digital_read() { - return bool(digitalRead(pin_)) != inverted_; // NOLINT + return bool(digitalRead(pin_)) != inverted_; } void NRF52GPIOPin::digital_write(bool value) { - digitalWrite(pin_, value != inverted_ ? 1 : 0); // NOLINT + digitalWrite(pin_, value != inverted_ ? 1 : 0); } void NRF52GPIOPin::detach_interrupt() const { detachInterrupt(pin_); @@ -109,7 +109,7 @@ void NRF52GPIOPin::detach_interrupt() const { // TODO seems to not work??? bool IRAM_ATTR ISRInternalGPIOPin::digital_read() { auto *arg = reinterpret_cast(arg_); - return bool(digitalRead(arg->pin)) != arg->inverted; // NOLINT + return bool(digitalRead(arg->pin)) != arg->inverted; } } // namespace esphome diff --git a/esphome/components/nrf52/gpio_zephyr.cpp b/esphome/components/nrf52/gpio_zephyr.cpp index b0ba906157..ea8ef8a88e 100644 --- a/esphome/components/nrf52/gpio_zephyr.cpp +++ b/esphome/components/nrf52/gpio_zephyr.cpp @@ -1,11 +1,7 @@ #ifdef USE_NRF52 #ifdef USE_ZEPHYR - #include "gpio.h" #include "esphome/core/log.h" -// #include -// #include -// #include #include namespace esphome { @@ -13,20 +9,29 @@ namespace nrf52 { static const char *const TAG = "nrf52"; -static int flags_to_mode(gpio::Flags flags, uint8_t pin) { - if (flags == gpio::FLAG_INPUT) { // NOLINT(bugprone-branch-clone) - return GPIO_INPUT; - } else if (flags == gpio::FLAG_OUTPUT) { - return GPIO_OUTPUT; - } else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLUP)) { - return GPIO_INPUT | GPIO_PULL_UP; - } else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_PULLDOWN)) { - return GPIO_INPUT | GPIO_PULL_DOWN; - } else if (flags == (gpio::FLAG_OUTPUT | gpio::FLAG_OPEN_DRAIN)) { - return GPIO_OUTPUT | GPIO_OPEN_DRAIN; - } else { - return GPIO_DISCONNECTED; +static int flags_to_mode(gpio::Flags flags, uint8_t pin, bool inverted, bool value) { + int ret = 0; + if (flags & gpio::FLAG_INPUT) { + ret |= GPIO_INPUT; } + if (flags & gpio::FLAG_OUTPUT) { + ret |= GPIO_OUTPUT; + if(value != inverted){ + ret |= GPIO_OUTPUT_INIT_HIGH; + } else { + ret |= GPIO_OUTPUT_INIT_LOW; + } + } + if (flags & gpio::FLAG_PULLUP) { + ret |= GPIO_PULL_UP; + } + if (flags & gpio::FLAG_PULLDOWN) { + ret |= GPIO_PULL_DOWN; + } + if (flags & gpio::FLAG_OPEN_DRAIN) { + ret |= GPIO_OPEN_DRAIN; + } + return ret; } struct ISRPinArg { @@ -34,40 +39,15 @@ struct ISRPinArg { bool inverted; }; -//TODO implement -//TODO test -// void (*irq_cb)(void *); -// void* irq_arg; -// static void pin_irq(void){ -// irq_cb(irq_arg); -// } - ISRInternalGPIOPin NRF52GPIOPin::to_isr() const { - auto *arg = new ISRPinArg{}; // NOLINT(cppcoreguidelines-owning-memory) + auto *arg = new ISRPinArg{}; arg->pin = pin_; arg->inverted = inverted_; return ISRInternalGPIOPin((void *) arg); } void NRF52GPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const { - // uint32_t mode = ISR_DEFERRED; - // switch (type) { - // case gpio::INTERRUPT_RISING_EDGE: - // mode |= inverted_ ? FALLING : RISING; - // break; - // case gpio::INTERRUPT_FALLING_EDGE: - // mode |= inverted_ ? RISING : FALLING; - // break; - // case gpio::INTERRUPT_ANY_EDGE: - // mode |= CHANGE; - // break; - // default: - // return; - // } - - // irq_cb = func; - // irq_arg = arg; - // attachInterrupt(pin_, pin_irq, mode); + // TODO } void NRF52GPIOPin::setup() { @@ -87,21 +67,20 @@ void NRF52GPIOPin::setup() { #error "gpio1 is disabled" #endif } - //TODO why no ready?? - // if (!device_is_ready(gpio)) { + if (device_is_ready(gpio)) { gpio_ = gpio; - // } else { - // ESP_LOGE(TAG, "gpio %u is not ready.", pin_); - // } - gpio_ = gpio; - pin_mode(flags_); + } else { + ESP_LOGE(TAG, "gpio %u is not ready.", pin_); + return; + } + pin_mode(flags_); } void NRF52GPIOPin::pin_mode(gpio::Flags flags) { if(nullptr == gpio_) { return; } - gpio_pin_configure(gpio_, pin_, flags_to_mode(flags, pin_)); + gpio_pin_configure(gpio_, pin_, flags_to_mode(flags, pin_, inverted_, value_)); } std::string NRF52GPIOPin::dump_summary() const { @@ -112,31 +91,26 @@ std::string NRF52GPIOPin::dump_summary() const { bool NRF52GPIOPin::digital_read() { if(nullptr == gpio_) { - //TODO invert ?? return false; } - return bool(gpio_pin_get(gpio_, pin_)) != inverted_; // NOLINT + return bool(gpio_pin_get(gpio_, pin_) != inverted_); } + void NRF52GPIOPin::digital_write(bool value) { + // make sure that value is not ignored since it can be inverted e.g. on switch side + // that way init state should be correct + value_ = value; if(nullptr == gpio_) { return; } - gpio_pin_set(gpio_, pin_, value != inverted_ ? 1 : 0); + gpio_pin_set(gpio_, pin_, value != inverted_ ? 1 : 0 ); } void NRF52GPIOPin::detach_interrupt() const { - // detachInterrupt(pin_); + // TODO } } // namespace nrf52 -// using namespace nrf52; - -// TODO seems to not work??? -// bool IRAM_ATTR ISRInternalGPIOPin::digital_read() { - // auto *arg = reinterpret_cast(arg_); - // return bool(digitalRead(arg->pin)) != arg->inverted; // NOLINT -// } - } // namespace esphome #endif diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 9ca9f4a664..53bb6c79e3 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "esphome/core/optional.h"