mirror of
https://github.com/esphome/esphome.git
synced 2025-10-31 23:21:54 +00:00
add dfu for zephyr
This commit is contained in:
@@ -1,16 +1,23 @@
|
|||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import output
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from esphome.core import CORE
|
||||||
|
from esphome.components.nrf52 import add_zephyr_prj_conf_option
|
||||||
|
|
||||||
dfu_ns = cg.esphome_ns.namespace("dfu")
|
dfu_ns = cg.esphome_ns.namespace("dfu")
|
||||||
DeviceFirmwareUpdate = dfu_ns.class_("DeviceFirmwareUpdate", cg.Component)
|
DeviceFirmwareUpdate = dfu_ns.class_("DeviceFirmwareUpdate", cg.Component)
|
||||||
|
|
||||||
|
CONF_RESET_OUTPUT = "reset_output"
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.All(
|
CONFIG_SCHEMA = cv.All(
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(DeviceFirmwareUpdate),
|
cv.GenerateID(): cv.declare_id(DeviceFirmwareUpdate),
|
||||||
|
cv.Required(CONF_RESET_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||||
}
|
}
|
||||||
).extend(cv.COMPONENT_SCHEMA),
|
).extend(cv.COMPONENT_SCHEMA),
|
||||||
cv.only_on_nrf52,
|
cv.only_on_nrf52,
|
||||||
@@ -19,6 +26,11 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
var = cg.new_Pvariable(config[CONF_ID])
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
# week symbol do not work for some reason so use wrap instaed
|
reset_output = await cg.get_variable(config[CONF_RESET_OUTPUT])
|
||||||
cg.add_build_flag("-Wl,--wrap=tud_cdc_line_state_cb")
|
cg.add(var.set_reset_output(reset_output))
|
||||||
|
if CORE.using_arduino:
|
||||||
|
# week symbol do not work for some reason so use wrap instaed
|
||||||
|
cg.add_build_flag("-Wl,--wrap=tud_cdc_line_state_cb")
|
||||||
|
elif CORE.using_zephyr:
|
||||||
|
add_zephyr_prj_conf_option("CONFIG_CDC_ACM_DTE_RATE_CALLBACK_SUPPORT", True)
|
||||||
await cg.register_component(var, config)
|
await cg.register_component(var, config)
|
||||||
|
|||||||
@@ -1,10 +1,57 @@
|
|||||||
#include "dfu.h"
|
#include "dfu.h"
|
||||||
|
#ifdef USE_NRF52
|
||||||
|
#include <zephyr/device.h>
|
||||||
|
#include <zephyr/drivers/uart.h>
|
||||||
|
#include <zephyr/drivers/uart/cdc_acm.h>
|
||||||
|
#endif
|
||||||
|
#ifdef USE_ARRUINO
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <Adafruit_TinyUSB.h> // for Serial
|
#include <Adafruit_TinyUSB.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
extern "C" {
|
namespace esphome {
|
||||||
|
namespace dfu {
|
||||||
|
|
||||||
volatile bool goto_dfu = false;
|
volatile bool goto_dfu = false;
|
||||||
|
|
||||||
|
#define DFU_DBL_RESET_MEM 0x20007F7C
|
||||||
|
#define DFU_DBL_RESET_MAGIC 0x5A1AD5 // SALADS
|
||||||
|
uint32_t *dbl_reset_mem = ((uint32_t *) DFU_DBL_RESET_MEM);
|
||||||
|
|
||||||
|
#ifdef USE_NRF52
|
||||||
|
#define DEVICE_AND_COMMA(node_id) DEVICE_DT_GET(node_id),
|
||||||
|
|
||||||
|
const struct device *cdc_dev[] = {DT_FOREACH_STATUS_OKAY(zephyr_cdc_acm_uart, DEVICE_AND_COMMA)};
|
||||||
|
|
||||||
|
static void cdc_dte_rate_callback(const struct device *, uint32_t rate){
|
||||||
|
if (rate == 1200) {
|
||||||
|
goto_dfu = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void DeviceFirmwareUpdate::setup() {
|
||||||
|
#ifdef USE_NRF52
|
||||||
|
for (int idx = 0; idx < ARRAY_SIZE(cdc_dev); idx++) {
|
||||||
|
cdc_acm_dte_rate_callback_set(cdc_dev[idx], cdc_dte_rate_callback);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceFirmwareUpdate::loop() {
|
||||||
|
if (goto_dfu) {
|
||||||
|
goto_dfu = false;
|
||||||
|
(*dbl_reset_mem) = DFU_DBL_RESET_MAGIC;
|
||||||
|
reset_output_->set_state(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dfu
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#ifdef USE_ARRUINO
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
void __wrap_tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
|
void __wrap_tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
|
||||||
(void) rts;
|
(void) rts;
|
||||||
|
|
||||||
@@ -22,28 +69,4 @@ void __wrap_tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
namespace esphome {
|
|
||||||
namespace dfu {
|
|
||||||
|
|
||||||
#define DFU_DBL_RESET_MEM 0x20007F7C
|
|
||||||
#define DFU_DBL_RESET_MAGIC 0x5A1AD5 // SALADS
|
|
||||||
uint32_t *dbl_reset_mem = ((uint32_t *) DFU_DBL_RESET_MEM);
|
|
||||||
|
|
||||||
void DeviceFirmwareUpdate::loop() {
|
|
||||||
if (goto_dfu) {
|
|
||||||
goto_dfu = false;
|
|
||||||
(*dbl_reset_mem) = DFU_DBL_RESET_MAGIC;
|
|
||||||
pinMode(14, OUTPUT);
|
|
||||||
pinMode(16, OUTPUT);
|
|
||||||
digitalWrite(14, 1);
|
|
||||||
digitalWrite(16, 1);
|
|
||||||
|
|
||||||
delay(50);
|
|
||||||
digitalWrite(14, 0);
|
|
||||||
digitalWrite(16, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dfu
|
|
||||||
} // namespace esphome
|
|
||||||
|
|||||||
@@ -1,10 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "esphome/core/defines.h"
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
|
#ifdef USE_OUTPUT
|
||||||
|
#include "esphome/components/output/binary_output.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace dfu {
|
namespace dfu {
|
||||||
class DeviceFirmwareUpdate : public Component {
|
class DeviceFirmwareUpdate : public Component {
|
||||||
void loop() override;
|
public:
|
||||||
|
void setup() override;
|
||||||
|
void loop() override;
|
||||||
|
#ifdef USE_OUTPUT
|
||||||
|
void set_reset_output(output::BinaryOutput *reset_output) { this->reset_output_ = reset_output; }
|
||||||
|
#endif
|
||||||
|
protected:
|
||||||
|
#ifdef USE_OUTPUT
|
||||||
|
output::BinaryOutput *reset_output_;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user