mirror of
https://github.com/esphome/esphome.git
synced 2025-03-13 14:18:14 +00:00
rollback
This commit is contained in:
parent
34285e7f7c
commit
5241102215
@ -1,100 +0,0 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.zephyr import zephyr_set_core_data, zephyr_to_code
|
||||
from esphome.components.zephyr.const import (
|
||||
BOOTLOADER_MCUBOOT,
|
||||
KEY_BOOTLOADER,
|
||||
KEY_ZEPHYR,
|
||||
)
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_BOARD,
|
||||
CONF_FRAMEWORK,
|
||||
CONF_PLATFORM_VERSION,
|
||||
CONF_TYPE,
|
||||
KEY_CORE,
|
||||
KEY_TARGET_FRAMEWORK,
|
||||
KEY_TARGET_PLATFORM,
|
||||
PLATFORM_NRF52,
|
||||
)
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
|
||||
from .boards_zephyr import BOARDS_ZEPHYR
|
||||
from .const import BOOTLOADER_ADAFRUIT
|
||||
|
||||
# force import gpio to register pin schema
|
||||
from .gpio import nrf52_pin_to_code # noqa
|
||||
|
||||
AUTO_LOAD = ["zephyr"]
|
||||
|
||||
|
||||
def set_core_data(config):
|
||||
zephyr_set_core_data(config)
|
||||
CORE.data[KEY_CORE][KEY_TARGET_PLATFORM] = PLATFORM_NRF52
|
||||
CORE.data[KEY_CORE][KEY_TARGET_FRAMEWORK] = KEY_ZEPHYR
|
||||
return config
|
||||
|
||||
|
||||
BOOTLOADERS = [
|
||||
BOOTLOADER_ADAFRUIT,
|
||||
BOOTLOADER_MCUBOOT,
|
||||
]
|
||||
|
||||
|
||||
def _detect_bootloader(value):
|
||||
value = value.copy()
|
||||
bootloader = None
|
||||
|
||||
if (
|
||||
value[CONF_BOARD] in BOARDS_ZEPHYR
|
||||
and KEY_BOOTLOADER in BOARDS_ZEPHYR[value[CONF_BOARD]]
|
||||
):
|
||||
bootloader = BOARDS_ZEPHYR[value[CONF_BOARD]][KEY_BOOTLOADER]
|
||||
|
||||
if KEY_BOOTLOADER not in value:
|
||||
if bootloader is None:
|
||||
bootloader = BOOTLOADER_MCUBOOT
|
||||
value[KEY_BOOTLOADER] = bootloader
|
||||
elif bootloader is not None and bootloader != value[KEY_BOOTLOADER]:
|
||||
raise cv.Invalid(
|
||||
f"{value[CONF_FRAMEWORK][CONF_TYPE]} does not support '{bootloader}' bootloader for {value[CONF_BOARD]}"
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_BOARD): cv.string_strict,
|
||||
cv.Optional(KEY_BOOTLOADER): cv.one_of(*BOOTLOADERS, lower=True),
|
||||
}
|
||||
),
|
||||
_detect_bootloader,
|
||||
set_core_data,
|
||||
)
|
||||
|
||||
|
||||
@coroutine_with_priority(1000)
|
||||
async def to_code(config):
|
||||
cg.add_platformio_option("board", config[CONF_BOARD])
|
||||
cg.add_build_flag("-DUSE_NRF52")
|
||||
cg.add_define("ESPHOME_BOARD", config[CONF_BOARD])
|
||||
cg.add_define("ESPHOME_VARIANT", "NRF52")
|
||||
conf = {CONF_PLATFORM_VERSION: "platformio/nordicnrf52@10.3.0"}
|
||||
cg.add_platformio_option(CONF_FRAMEWORK, CORE.data[KEY_CORE][KEY_TARGET_FRAMEWORK])
|
||||
cg.add_platformio_option("platform", conf[CONF_PLATFORM_VERSION])
|
||||
cg.add_platformio_option(
|
||||
"platform_packages",
|
||||
[
|
||||
"platformio/framework-zephyr@https://github.com/tomaszduda23/framework-sdk-nrf",
|
||||
"platformio/toolchain-gccarmnoneeabi@https://github.com/tomaszduda23/toolchain-sdk-ng",
|
||||
],
|
||||
)
|
||||
|
||||
if config[KEY_BOOTLOADER] == BOOTLOADER_ADAFRUIT:
|
||||
# make sure that firmware.zip is created
|
||||
# for Adafruit_nRF52_Bootloader
|
||||
cg.add_platformio_option("board_upload.protocol", "nrfutil")
|
||||
cg.add_platformio_option("board_upload.use_1200bps_touch", "true")
|
||||
cg.add_platformio_option("board_upload.require_upload_port", "true")
|
||||
cg.add_platformio_option("board_upload.wait_for_upload_port", "true")
|
||||
zephyr_to_code(conf)
|
@ -1,7 +0,0 @@
|
||||
from esphome.components.zephyr.const import KEY_BOOTLOADER
|
||||
|
||||
from .const import BOOTLOADER_ADAFRUIT
|
||||
|
||||
BOARDS_ZEPHYR = {
|
||||
"adafruit_itsybitsy_nrf52840": {KEY_BOOTLOADER: BOOTLOADER_ADAFRUIT},
|
||||
}
|
@ -1 +0,0 @@
|
||||
BOOTLOADER_ADAFRUIT = "adafruit"
|
@ -1,53 +0,0 @@
|
||||
#ifdef USE_ZEPHYR
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/drivers/watchdog.h>
|
||||
#include <zephyr/sys/reboot.h>
|
||||
|
||||
namespace esphome {
|
||||
|
||||
static int wdt_channel_id = -EINVAL;
|
||||
const device *wdt = nullptr;
|
||||
|
||||
void yield() { ::k_yield(); }
|
||||
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()); }
|
||||
|
||||
void arch_init() {
|
||||
wdt = DEVICE_DT_GET(DT_ALIAS(watchdog0));
|
||||
|
||||
if (device_is_ready(wdt)) {
|
||||
static wdt_timeout_cfg wdt_config{};
|
||||
wdt_config.flags = WDT_FLAG_RESET_SOC;
|
||||
wdt_config.window.max = 2000;
|
||||
wdt_channel_id = wdt_install_timeout(wdt, &wdt_config);
|
||||
if (wdt_channel_id >= 0) {
|
||||
wdt_setup(wdt, WDT_OPT_PAUSE_HALTED_BY_DBG | WDT_OPT_PAUSE_IN_SLEEP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void arch_feed_wdt() {
|
||||
if (wdt_channel_id >= 0) {
|
||||
wdt_feed(wdt, wdt_channel_id);
|
||||
}
|
||||
}
|
||||
|
||||
void arch_restart() { sys_reboot(SYS_REBOOT_COLD); }
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
void setup();
|
||||
void loop();
|
||||
|
||||
int main() {
|
||||
setup();
|
||||
while (1) {
|
||||
loop();
|
||||
esphome::yield();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,120 +0,0 @@
|
||||
#ifdef USE_ZEPHYR
|
||||
#include "gpio.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace zephyr {
|
||||
|
||||
static const char *const TAG = "zephyr";
|
||||
|
||||
static int flags_to_mode(gpio::Flags flags, 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 {
|
||||
uint8_t pin;
|
||||
bool inverted;
|
||||
};
|
||||
|
||||
ISRInternalGPIOPin ZephyrGPIOPin::to_isr() const {
|
||||
auto *arg = new ISRPinArg{};
|
||||
arg->pin = pin_;
|
||||
arg->inverted = inverted_;
|
||||
return ISRInternalGPIOPin((void *) arg);
|
||||
}
|
||||
|
||||
void ZephyrGPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void ZephyrGPIOPin::setup() {
|
||||
const struct device *gpio = nullptr;
|
||||
if (pin_ < 32) {
|
||||
#define GPIO0 DT_NODELABEL(gpio0)
|
||||
#if DT_NODE_HAS_STATUS(GPIO0, okay)
|
||||
gpio = DEVICE_DT_GET(GPIO0);
|
||||
#else
|
||||
#error "gpio0 is disabled"
|
||||
#endif
|
||||
} else {
|
||||
#define GPIO1 DT_NODELABEL(gpio1)
|
||||
#if DT_NODE_HAS_STATUS(GPIO1, okay)
|
||||
gpio = DEVICE_DT_GET(GPIO1);
|
||||
#else
|
||||
#error "gpio1 is disabled"
|
||||
#endif
|
||||
}
|
||||
if (device_is_ready(gpio)) {
|
||||
gpio_ = gpio;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "gpio %u is not ready.", pin_);
|
||||
return;
|
||||
}
|
||||
pin_mode(flags_);
|
||||
}
|
||||
|
||||
void ZephyrGPIOPin::pin_mode(gpio::Flags flags) {
|
||||
if (nullptr == gpio_) {
|
||||
return;
|
||||
}
|
||||
gpio_pin_configure(gpio_, pin_ % 32, flags_to_mode(flags, inverted_, value_));
|
||||
}
|
||||
|
||||
std::string ZephyrGPIOPin::dump_summary() const {
|
||||
char buffer[32];
|
||||
snprintf(buffer, sizeof(buffer), "GPIO%u", pin_);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool ZephyrGPIOPin::digital_read() {
|
||||
if (nullptr == gpio_) {
|
||||
return false;
|
||||
}
|
||||
return bool(gpio_pin_get(gpio_, pin_ % 32) != inverted_);
|
||||
}
|
||||
|
||||
void ZephyrGPIOPin::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_ % 32, value != inverted_ ? 1 : 0);
|
||||
}
|
||||
void ZephyrGPIOPin::detach_interrupt() const {
|
||||
// TODO
|
||||
}
|
||||
|
||||
} // namespace zephyr
|
||||
|
||||
bool IRAM_ATTR ISRInternalGPIOPin::digital_read() {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
#endif
|
@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_ZEPHYR
|
||||
#include "esphome/core/hal.h"
|
||||
struct device;
|
||||
namespace esphome {
|
||||
namespace zephyr {
|
||||
|
||||
class ZephyrGPIOPin : public InternalGPIOPin {
|
||||
public:
|
||||
void set_pin(uint8_t pin) { pin_ = pin; }
|
||||
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { flags_ = flags; }
|
||||
|
||||
void setup() override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
std::string dump_summary() const override;
|
||||
void detach_interrupt() const override;
|
||||
ISRInternalGPIOPin to_isr() const override;
|
||||
uint8_t get_pin() const override { return pin_; }
|
||||
bool is_inverted() const override { return inverted_; }
|
||||
|
||||
protected:
|
||||
void attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const override;
|
||||
uint8_t pin_;
|
||||
bool inverted_;
|
||||
gpio::Flags flags_;
|
||||
const device *gpio_ = nullptr;
|
||||
bool value_ = false;
|
||||
};
|
||||
|
||||
} // namespace zephyr
|
||||
} // namespace esphome
|
||||
|
||||
#endif // USE_ZEPHYR
|
@ -1,4 +0,0 @@
|
||||
Import("env")
|
||||
|
||||
board_config = env.BoardConfig()
|
||||
board_config.update("frameworks", ["arduino", "zephyr"])
|
@ -1,155 +0,0 @@
|
||||
#ifdef USE_ZEPHYR
|
||||
|
||||
#include "esphome/core/preferences.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <zephyr/settings/settings.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace zephyr {
|
||||
|
||||
static const char *const TAG = "zephyr.preferences";
|
||||
|
||||
#define ESPHOME_SETTINGS_KEY "esphome"
|
||||
|
||||
class ZephyrPreferenceBackend : public ESPPreferenceBackend {
|
||||
public:
|
||||
ZephyrPreferenceBackend(uint32_t type) { this->type_ = type; }
|
||||
ZephyrPreferenceBackend(uint32_t type, std::vector<uint8_t> &&data) : data(std::move(data)) { this->type_ = type; }
|
||||
|
||||
bool save(const uint8_t *data, size_t len) override {
|
||||
this->data.resize(len);
|
||||
std::memcpy(this->data.data(), data, len);
|
||||
ESP_LOGVV(TAG, "save key: %u, len: %d", type_, len);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool load(uint8_t *data, size_t len) override {
|
||||
if (len != this->data.size()) {
|
||||
ESP_LOGE(TAG, "size of setting key %s changed, from: %u, to: %u", get_key().c_str(), this->data.size(), len);
|
||||
return false;
|
||||
}
|
||||
std::memcpy(data, this->data.data(), len);
|
||||
ESP_LOGVV(TAG, "load key: %u, len: %d", type_, len);
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint32_t get_type() const { return type_; }
|
||||
const std::string get_key() const { return str_sprintf(ESPHOME_SETTINGS_KEY "/%" PRIx32, type_); }
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
|
||||
protected:
|
||||
uint32_t type_ = 0;
|
||||
};
|
||||
|
||||
class ZephyrPreferences : public ESPPreferences {
|
||||
public:
|
||||
void open() {
|
||||
int err = settings_subsys_init();
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "Failed to initialize settings subsystem, err: %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
static struct settings_handler settings_cb = {
|
||||
.name = ESPHOME_SETTINGS_KEY,
|
||||
.h_set = load_setting_,
|
||||
.h_export = export_settings_,
|
||||
};
|
||||
|
||||
err = settings_register(&settings_cb);
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "setting_register failed, err, %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
err = settings_load_subtree(ESPHOME_SETTINGS_KEY);
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "Cannot load settings, err: %d", err);
|
||||
return;
|
||||
}
|
||||
ESP_LOGD(TAG, "Loaded %u settings.", backends_.size());
|
||||
}
|
||||
|
||||
ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash) override {
|
||||
return make_preference(length, type);
|
||||
}
|
||||
|
||||
ESPPreferenceObject make_preference(size_t length, uint32_t type) override {
|
||||
for (auto backend : backends_) {
|
||||
if (backend->get_type() == type) {
|
||||
return ESPPreferenceObject(backend);
|
||||
}
|
||||
}
|
||||
printf("type %u size %u\n", type, backends_.size());
|
||||
auto *pref = new ZephyrPreferenceBackend(type);
|
||||
ESP_LOGD(TAG, "Add new setting %s.", pref->get_key().c_str());
|
||||
backends_.push_back(pref);
|
||||
return ESPPreferenceObject(pref);
|
||||
}
|
||||
|
||||
bool sync() override {
|
||||
ESP_LOGD(TAG, "Save settings");
|
||||
int err = settings_save();
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "Cannot save settings, err: %d", err);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool reset() override {
|
||||
ESP_LOGD(TAG, "Reset settings");
|
||||
for (auto backend : backends_) {
|
||||
// save empty delete data
|
||||
backend->data.clear();
|
||||
}
|
||||
sync();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<ZephyrPreferenceBackend *> backends_;
|
||||
|
||||
static int load_setting_(const char *name, size_t len, settings_read_cb read_cb, void *cb_arg) {
|
||||
auto type = parse_hex<uint32_t>(name);
|
||||
if (!type.has_value()) {
|
||||
std::string full_name(ESPHOME_SETTINGS_KEY);
|
||||
full_name += "/";
|
||||
full_name += name;
|
||||
// Delete unusable keys. Otherwise it will stay in flash forever.
|
||||
settings_delete(full_name.c_str());
|
||||
return 1;
|
||||
}
|
||||
std::vector<uint8_t> data(len);
|
||||
int err = read_cb(cb_arg, data.data(), len);
|
||||
|
||||
ESP_LOGD(TAG, "load setting, name: %s(%u), len %u, err %u", name, *type, len, err);
|
||||
auto *pref = new ZephyrPreferenceBackend(*type, std::move(data));
|
||||
static_cast<ZephyrPreferences *>(global_preferences)->backends_.push_back(pref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int export_settings_(int (*cb)(const char *name, const void *value, size_t val_len)) {
|
||||
for (auto backend : static_cast<ZephyrPreferences *>(global_preferences)->backends_) {
|
||||
auto name = backend->get_key();
|
||||
int err = cb(name.c_str(), backend->data.data(), backend->data.size());
|
||||
ESP_LOGD(TAG, "save in flash, name %s, len %u, err %d", name.c_str(), backend->data.size(), err);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
void setup_preferences() {
|
||||
auto *prefs = new ZephyrPreferences();
|
||||
global_preferences = prefs;
|
||||
prefs->open();
|
||||
}
|
||||
|
||||
} // namespace zephyr
|
||||
|
||||
ESPPreferences *global_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
#endif
|
@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_ZEPHYR
|
||||
|
||||
namespace esphome {
|
||||
namespace zephyr {
|
||||
|
||||
void setup_preferences();
|
||||
|
||||
} // namespace zephyr
|
||||
} // namespace esphome
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user