mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	add dfu support
This commit is contained in:
		| @@ -317,9 +317,18 @@ def upload_adafruit_nrfutil(config, port): | ||||
|     from nordicsemi.dfu.dfu_transport_serial import DfuTransportSerial | ||||
|     from nordicsemi.dfu.dfu_transport import DfuEvent | ||||
|     from nordicsemi.dfu.dfu import Dfu | ||||
|     import serial | ||||
|  | ||||
|     idedata = platformio_api.get_idedata(config) | ||||
|     dfu_package = str(Path(idedata.firmware_elf_path).with_suffix(".zip")) | ||||
|     ser = serial.Serial(port, 2400) | ||||
|     time.sleep(DfuTransportSerial.SERIAL_PORT_OPEN_WAIT_TIME) | ||||
|     ser.setDTR(True) | ||||
|     time.sleep(DfuTransportSerial.DTR_RESET_WAIT_TIME) | ||||
|     ser.close() | ||||
|  | ||||
|     time.sleep(2) | ||||
|  | ||||
|     serial_backend = DfuTransportSerial(port) | ||||
|     serial_backend.register_events_callback(DfuEvent.PROGRESS_EVENT, update_progress) | ||||
|     dfu = Dfu(dfu_package, dfu_transport=serial_backend) | ||||
|   | ||||
							
								
								
									
										24
									
								
								esphome/components/dfu/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								esphome/components/dfu/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.const import ( | ||||
|     CONF_ID, | ||||
| ) | ||||
|  | ||||
| dfu_ns = cg.esphome_ns.namespace("dfu") | ||||
| DeviceFirmwareUpdate = dfu_ns.class_("DeviceFirmwareUpdate", cg.Component) | ||||
|  | ||||
| CONFIG_SCHEMA = cv.All( | ||||
|     cv.Schema( | ||||
|         { | ||||
|             cv.GenerateID(): cv.declare_id(DeviceFirmwareUpdate), | ||||
|         } | ||||
|     ).extend(cv.COMPONENT_SCHEMA), | ||||
|     cv.only_on_nrf52, | ||||
| ) | ||||
|  | ||||
|  | ||||
| async def to_code(config): | ||||
|     var = cg.new_Pvariable(config[CONF_ID]) | ||||
|     # week symbol do not work for some reason so use wrap instaed | ||||
|     cg.add_build_flag("-Wl,--wrap=tud_cdc_line_state_cb") | ||||
|     await cg.register_component(var, config) | ||||
							
								
								
									
										49
									
								
								esphome/components/dfu/dfu.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								esphome/components/dfu/dfu.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| #include "dfu.h" | ||||
| #include <Arduino.h> | ||||
| #include <Adafruit_TinyUSB.h>  // for Serial | ||||
|  | ||||
| extern "C" { | ||||
|  | ||||
| volatile bool goto_dfu = false; | ||||
| void __wrap_tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { | ||||
|   (void) rts; | ||||
|  | ||||
|   // DTR = false is counted as disconnected | ||||
|   if (!dtr) { | ||||
|     // touch2400 only with first CDC instance (Serial) | ||||
|     if (itf == 0) { | ||||
|       cdc_line_coding_t coding; | ||||
|       tud_cdc_get_line_coding(&coding); | ||||
|  | ||||
|       if (coding.bit_rate == 2400) { | ||||
|         goto_dfu = true; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| } | ||||
|  | ||||
| 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 | ||||
							
								
								
									
										10
									
								
								esphome/components/dfu/dfu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								esphome/components/dfu/dfu.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| #pragma once | ||||
| #include "esphome/core/component.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace dfu { | ||||
| class DeviceFirmwareUpdate : public Component { | ||||
| 	void loop() override; | ||||
| }; | ||||
| } | ||||
| } | ||||
| @@ -57,6 +57,7 @@ from esphome.const import ( | ||||
|     TYPE_GIT, | ||||
|     TYPE_LOCAL, | ||||
|     VALID_SUBSTITUTIONS_CHARACTERS, | ||||
|     PLATFORM_NRF52, | ||||
| ) | ||||
| from esphome.core import ( | ||||
|     CORE, | ||||
| @@ -595,6 +596,7 @@ def only_with_framework(frameworks): | ||||
| only_on_esp32 = only_on(PLATFORM_ESP32) | ||||
| only_on_esp8266 = only_on(PLATFORM_ESP8266) | ||||
| only_on_rp2040 = only_on(PLATFORM_RP2040) | ||||
| only_on_nrf52 = only_on(PLATFORM_NRF52) | ||||
| only_with_arduino = only_with_framework("arduino") | ||||
| only_with_esp_idf = only_with_framework("esp-idf") | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user