mirror of
https://github.com/esphome/esphome.git
synced 2026-10-18 20:22:49 +00:00
Read the device table in place with word-only fields instead of copying an entry
This commit is contained in:
@@ -176,7 +176,7 @@ bool ShellyDimmer::upgrade_firmware_() {
|
||||
uint8_t buffer[BUFFER_SIZE];
|
||||
const uint8_t *p = STM_FIRMWARE;
|
||||
uint32_t offset = 0;
|
||||
uint32_t addr = stm32->dev.fl_start;
|
||||
uint32_t addr = stm32->dev->fl_start;
|
||||
const uint32_t end = addr + STM_FIRMWARE_SIZE_IN_BYTES;
|
||||
|
||||
while (addr < end && offset < STM_FIRMWARE_SIZE_IN_BYTES) {
|
||||
|
||||
@@ -116,25 +116,18 @@ namespace esphome::shelly_dimmer {
|
||||
|
||||
namespace {
|
||||
|
||||
uint32_t read_page_size(const uint32_t *psize) {
|
||||
uint32_t size;
|
||||
progmem_memcpy(&size, psize, sizeof(size));
|
||||
return size;
|
||||
}
|
||||
|
||||
int flash_addr_to_page_ceil(const stm32_unique_ptr &stm, uint32_t addr) {
|
||||
if (!(addr >= stm->dev.fl_start && addr <= stm->dev.fl_end))
|
||||
if (!(addr >= stm->dev->fl_start && addr <= stm->dev->fl_end))
|
||||
return 0;
|
||||
|
||||
int page = 0;
|
||||
addr -= stm->dev.fl_start;
|
||||
const auto *psize = stm->dev.fl_ps;
|
||||
addr -= stm->dev->fl_start;
|
||||
const auto *psize = stm->dev->fl_ps;
|
||||
|
||||
uint32_t size;
|
||||
while (addr >= (size = read_page_size(psize))) {
|
||||
addr -= size;
|
||||
while (addr >= psize[0]) {
|
||||
addr -= psize[0];
|
||||
page++;
|
||||
if (read_page_size(psize + 1))
|
||||
if (psize[1])
|
||||
psize++;
|
||||
}
|
||||
|
||||
@@ -644,16 +637,14 @@ stm32_unique_ptr stm32_init(uart::UARTDevice *stream, const uint8_t flags, const
|
||||
return make_stm32_with_deletor(nullptr);
|
||||
}
|
||||
|
||||
const stm32_dev_t *dev = DEVICES;
|
||||
uint16_t id;
|
||||
while ((id = progmem_read_uint16(&dev->id)) != 0x00 && id != stm->pid)
|
||||
++dev;
|
||||
stm->dev = DEVICES;
|
||||
while (stm->dev->id != 0x00 && stm->dev->id != stm->pid)
|
||||
++stm->dev;
|
||||
|
||||
if (!id) {
|
||||
if (!stm->dev->id) {
|
||||
ESP_LOGD(TAG, "Unknown/unsupported device (Device ID: 0x%03x)", stm->pid);
|
||||
return make_stm32_with_deletor(nullptr);
|
||||
}
|
||||
progmem_memcpy(&stm->dev, dev, sizeof(stm->dev));
|
||||
|
||||
return stm;
|
||||
}
|
||||
@@ -830,10 +821,10 @@ stm32_err_t stm32_erase_memory(const stm32_unique_ptr &stm, uint32_t spage, uint
|
||||
* a tentative of intrusion and will hang.
|
||||
* Erasing the flash page-by-page is the safer way to go.
|
||||
*/
|
||||
if (!(stm->dev.flags & F_NO_ME))
|
||||
if (!(stm->dev->flags & F_NO_ME))
|
||||
return stm32_mass_erase(stm);
|
||||
|
||||
pages = flash_addr_to_page_ceil(stm, stm->dev.fl_end);
|
||||
pages = flash_addr_to_page_ceil(stm, stm->dev->fl_end);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -922,9 +913,9 @@ stm32_err_t stm32_go(const stm32_unique_ptr &stm, const uint32_t address) {
|
||||
}
|
||||
|
||||
stm32_err_t stm32_reset_device(const stm32_unique_ptr &stm) {
|
||||
const auto target_address = stm->dev.ram_start;
|
||||
const auto target_address = stm->dev->ram_start;
|
||||
|
||||
if (stm->dev.flags & F_OBLL) {
|
||||
if (stm->dev->flags & F_OBLL) {
|
||||
/* set the OBL_LAUNCH bit to reset device (see RM0360, 2.5) */
|
||||
return stm32_run_raw_code(stm, target_address, STM_OBL_LAUNCH_CODE, STM_OBL_LAUNCH_CODE_SIZE);
|
||||
} else {
|
||||
|
||||
@@ -72,16 +72,18 @@ using stm32_cmd_t = struct Stm32Cmd {
|
||||
uint8_t crc;
|
||||
};
|
||||
|
||||
// Word-only fields: the table is in PROGMEM and aligned 32-bit loads from flash are safe on ESP8266
|
||||
using stm32_dev_t = struct Stm32Dev { // NOLINT
|
||||
uint16_t id;
|
||||
uint32_t ram_start, ram_end;
|
||||
uint32_t fl_start, fl_end;
|
||||
uint16_t fl_pps; // pages per sector
|
||||
const uint32_t id;
|
||||
const uint32_t ram_start, ram_end;
|
||||
const uint32_t fl_start, fl_end;
|
||||
const uint32_t fl_pps; // pages per sector
|
||||
const uint32_t *fl_ps; // page size
|
||||
uint32_t opt_start, opt_end;
|
||||
uint32_t mem_start, mem_end;
|
||||
uint32_t flags;
|
||||
const uint32_t opt_start, opt_end;
|
||||
const uint32_t mem_start, mem_end;
|
||||
const uint32_t flags;
|
||||
};
|
||||
static_assert(sizeof(stm32_dev_t) == 12 * sizeof(uint32_t), "stm32_dev_t must stay word-only for flash reads");
|
||||
|
||||
using stm32_t = struct Stm32 {
|
||||
uart::UARTDevice *stream;
|
||||
@@ -92,7 +94,7 @@ using stm32_t = struct Stm32 {
|
||||
uint8_t option1, option2;
|
||||
uint16_t pid;
|
||||
stm32_cmd_t *cmd;
|
||||
stm32_dev_t dev; // RAM copy of the PROGMEM DEVICES entry
|
||||
const stm32_dev_t *dev;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user