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.config_validation as cv | ||||
| from esphome.components import output | ||||
| from esphome.const import ( | ||||
|     CONF_ID, | ||||
| ) | ||||
|  | ||||
| from esphome.core import CORE | ||||
| from esphome.components.nrf52 import add_zephyr_prj_conf_option | ||||
|  | ||||
| dfu_ns = cg.esphome_ns.namespace("dfu") | ||||
| DeviceFirmwareUpdate = dfu_ns.class_("DeviceFirmwareUpdate", cg.Component) | ||||
|  | ||||
| CONF_RESET_OUTPUT = "reset_output" | ||||
|  | ||||
| CONFIG_SCHEMA = cv.All( | ||||
|     cv.Schema( | ||||
|         { | ||||
|             cv.GenerateID(): cv.declare_id(DeviceFirmwareUpdate), | ||||
|             cv.Required(CONF_RESET_OUTPUT): cv.use_id(output.BinaryOutput), | ||||
|         } | ||||
|     ).extend(cv.COMPONENT_SCHEMA), | ||||
|     cv.only_on_nrf52, | ||||
| @@ -19,6 +26,11 @@ CONFIG_SCHEMA = cv.All( | ||||
|  | ||||
| async def to_code(config): | ||||
|     var = cg.new_Pvariable(config[CONF_ID]) | ||||
|     reset_output = await cg.get_variable(config[CONF_RESET_OUTPUT]) | ||||
|     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) | ||||
|   | ||||
| @@ -1,10 +1,57 @@ | ||||
| #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 <Adafruit_TinyUSB.h>  // for Serial | ||||
| #include <Adafruit_TinyUSB.h> | ||||
| #endif | ||||
|  | ||||
| extern "C" { | ||||
| namespace esphome { | ||||
| namespace dfu { | ||||
|  | ||||
| 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) rts; | ||||
|  | ||||
| @@ -22,28 +69,4 @@ void __wrap_tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { | ||||
|   } | ||||
| } | ||||
| } | ||||
|  | ||||
| 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 | ||||
| #endif | ||||
|   | ||||
| @@ -1,10 +1,23 @@ | ||||
| #pragma once | ||||
| #include "esphome/core/defines.h" | ||||
| #include "esphome/core/component.h" | ||||
| #ifdef USE_OUTPUT | ||||
| #include "esphome/components/output/binary_output.h" | ||||
| #endif | ||||
|  | ||||
| namespace esphome { | ||||
| namespace dfu { | ||||
| class DeviceFirmwareUpdate : public Component { | ||||
|  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