mirror of
https://github.com/esphome/esphome.git
synced 2025-10-29 22:24:26 +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