mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +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