1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-30 14:43:51 +00:00

add gpio for zephyr

This commit is contained in:
Tomasz Duda
2024-01-30 21:02:02 +01:00
parent 990871fa0e
commit 6a5b243359
5 changed files with 51 additions and 71 deletions

View File

@@ -1,13 +1,14 @@
#ifdef USE_NRF52
#ifdef USE_ZEPHYR
#include <stdlib.h>
#include <zephyr/kernel.h>
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;

View File

@@ -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
};

View File

@@ -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<nrf52::ISRPinArg *>(arg_);
return bool(digitalRead(arg->pin)) != arg->inverted; // NOLINT
return bool(digitalRead(arg->pin)) != arg->inverted;
}
} // namespace esphome

View File

@@ -1,11 +1,7 @@
#ifdef USE_NRF52
#ifdef USE_ZEPHYR
#include "gpio.h"
#include "esphome/core/log.h"
// #include <functional>
// #include <vector>
// #include <device.h>
#include <zephyr/drivers/gpio.h>
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<nrf52::ISRPinArg *>(arg_);
// return bool(digitalRead(arg->pin)) != arg->inverted; // NOLINT
// }
} // namespace esphome
#endif

View File

@@ -7,6 +7,7 @@
#include <string>
#include <type_traits>
#include <vector>
#include <limits>
#include "esphome/core/optional.h"