diff --git a/bootloader/DroneCAN/DroneCAN.c b/bootloader/DroneCAN/DroneCAN.c index 0c05afe2..7e7100cf 100644 --- a/bootloader/DroneCAN/DroneCAN.c +++ b/bootloader/DroneCAN/DroneCAN.c @@ -142,7 +142,7 @@ static uint32_t millis32(void) default settings, based on public/assets/eeprom_default.bin in AM32 configurator */ static const uint8_t default_settings[] = { - 0x01, 0x02, 0x01, 0x01, 0x23, 0x4e, 0x45, 0x4f, 0x45, 0x53, 0x43, 0x20, 0x66, 0x30, 0x35, 0x31, + 0x01, 0x02, BOOTLOADER_VERSION, 0x01, 0x23, 0x4e, 0x45, 0x4f, 0x45, 0x53, 0x43, 0x20, 0x66, 0x30, 0x35, 0x31, 0x20, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x18, 0x64, 0x37, 0x0e, 0x00, 0x00, 0x05, 0x00, 0x80, 0x80, 0x80, 0x32, 0x00, 0x32, 0x00, 0x00, 0x0f, 0x0a, 0x0a, 0x8d, 0x66, 0x06, 0x00, 0x00 }; diff --git a/bootloader/main.c b/bootloader/main.c index 8c170f37..95cdd39c 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -69,6 +69,10 @@ #endif #endif +#ifndef EEPROM_MAX_SIZE +#define EEPROM_MAX_SIZE 1024 // must be multiple of 256 +#endif + #ifdef USE_PA2 #define input_pin GPIO_PIN(2) #define input_port GPIOA @@ -424,6 +428,16 @@ static void decodeInput() return; } + if (address == EEPROM_START_ADD && payload_buffer_size > 2) { + /* + if the configuration client is writing the eeprom area + then replace the bootloader version byte in the buffer + with the right version. This makes the update_EEPROM() + less likely to need to erase any flash + */ + payLoadBuffer[2] = BOOTLOADER_VERSION; + } + if (!save_flash_nolib((uint8_t*)payLoadBuffer, payload_buffer_size,address)) { send_BAD_ACK(); } else { @@ -737,14 +751,35 @@ static void receiveBuffer() #ifdef UPDATE_EEPROM_ENABLE static void update_EEPROM() { - read_flash_bin(rxBuffer , EEPROM_START_ADD , 48); - if (BOOTLOADER_VERSION != rxBuffer[2]) { - if (rxBuffer[2] == 0xFF || rxBuffer[2] == 0x00){ - return; - } - rxBuffer[2] = BOOTLOADER_VERSION; - save_flash_nolib(rxBuffer, 48, EEPROM_START_ADD); - } + if (!bl_was_software_reset()) { + // we only update the bootloader version on a software reset to reduce the chances + // of a brownout or spark causing a eeprom write that corrupts the settings + return; + } + const uint8_t *eeprom = (const uint8_t *)EEPROM_START_ADD; + if (BOOTLOADER_VERSION != eeprom[2]) { + if (eeprom[2] == 0xFF || eeprom[2] == 0x00) { + return; + } + + // update only the bootloader version, preserve all other bytes up to EEPROM_MAX_SIZE + uint8_t data[EEPROM_MAX_SIZE]; + memcpy(data, eeprom, EEPROM_MAX_SIZE); + data[2] = BOOTLOADER_VERSION; + + // flash in 256 byte chunks as save_flash_nolib may not support larger chunks + uint32_t remaining = EEPROM_MAX_SIZE; + uint32_t addr = EEPROM_START_ADD; + const uint8_t *p = &data[0]; + + while (remaining > 0) { + const uint32_t chunk = 256; + save_flash_nolib(p, chunk, addr); + p += chunk; + addr += chunk; + remaining -= chunk; + } + } } #endif // UPDATE_EEPROM_ENABLE