|
@@ -576,7 +576,7 @@ static uint32_t sector_number_to_id(uint32_t sector_number)
|
|
|
return SECTOR_NUMBER_TO_ID_ERROR;
|
|
return SECTOR_NUMBER_TO_ID_ERROR;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-bool platform_erase_flash_sector(uint32_t sector)
|
|
|
|
|
|
|
+static bool erase_flash_sector(uint32_t sector)
|
|
|
{
|
|
{
|
|
|
fmc_unlock();
|
|
fmc_unlock();
|
|
|
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
|
|
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
|
|
@@ -597,27 +597,14 @@ bool platform_erase_flash_sector(uint32_t sector)
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-bool platform_write_flash(uint32_t offset, uint32_t length, uint8_t buffer[PLATFORM_FLASH_WRITE_BUFFER_SIZE])
|
|
|
|
|
|
|
+static bool write_flash(uint32_t offset, uint32_t length, uint8_t buffer[PLATFORM_FLASH_WRITE_BUFFER_SIZE])
|
|
|
{
|
|
{
|
|
|
- if (offset == 0)
|
|
|
|
|
- {
|
|
|
|
|
- if (buffer[3] != 0x20 || buffer[7] != 0x08)
|
|
|
|
|
- {
|
|
|
|
|
- logmsg("Invalid firmware file, starts with: ", bytearray(buffer, 16));
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- dbgmsg("Writing flash at firmware offset ", offset, " data ", bytearray(buffer, 4));
|
|
|
|
|
- assert(offset % PLATFORM_FLASH_WRITE_BUFFER_SIZE == 0);
|
|
|
|
|
- //assert(offset >= PLATFORM_BOOTLOADER_SIZE);
|
|
|
|
|
|
|
|
|
|
fmc_unlock();
|
|
fmc_unlock();
|
|
|
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
|
|
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
|
|
|
fmc_state_enum status;
|
|
fmc_state_enum status;
|
|
|
uint32_t *buf32 = (uint32_t*)buffer;
|
|
uint32_t *buf32 = (uint32_t*)buffer;
|
|
|
- uint32_t memory_address = FLASH_BASE + PLATFORM_BOOTLOADER_SIZE + offset;
|
|
|
|
|
|
|
+ uint32_t memory_address = FLASH_BASE + offset;
|
|
|
uint32_t num_words = length / 4;
|
|
uint32_t num_words = length / 4;
|
|
|
if (length % 4 == 0)
|
|
if (length % 4 == 0)
|
|
|
{
|
|
{
|
|
@@ -638,7 +625,7 @@ bool platform_write_flash(uint32_t offset, uint32_t length, uint8_t buffer[PLATF
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
fmc_lock();
|
|
fmc_lock();
|
|
|
- memory_address = FLASH_BASE + PLATFORM_BOOTLOADER_SIZE + offset;
|
|
|
|
|
|
|
+ memory_address = FLASH_BASE + offset;
|
|
|
for (int i = 0; i < num_words; i++)
|
|
for (int i = 0; i < num_words; i++)
|
|
|
{
|
|
{
|
|
|
uint32_t expected = buf32[i];
|
|
uint32_t expected = buf32[i];
|
|
@@ -654,6 +641,160 @@ bool platform_write_flash(uint32_t offset, uint32_t length, uint8_t buffer[PLATF
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// the size of the main code without the bootloader
|
|
|
|
|
+static uint32_t firmware_size(FsFile &file)
|
|
|
|
|
+{
|
|
|
|
|
+ uint32_t fwsize = file.size();
|
|
|
|
|
+ if (fwsize <= PLATFORM_BOOTLOADER_SIZE )
|
|
|
|
|
+ {
|
|
|
|
|
+ logmsg("Firmware file size too small: ", fwsize, " bootloader fits in the first : ", PLATFORM_BOOTLOADER_SIZE, " bytes");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return fwsize - PLATFORM_BOOTLOADER_SIZE;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+bool platform_firmware_erase(FsFile &file)
|
|
|
|
|
+{
|
|
|
|
|
+ uint32_t bootloader_sector_index = 0;
|
|
|
|
|
+ uint32_t bootloader_sector_byte_count = 0;
|
|
|
|
|
+ const uint32_t map_length = sizeof(platform_flash_sector_map)/sizeof(platform_flash_sector_map[0]);
|
|
|
|
|
+ // Find at which sector the bootloader ends so it isn't overwritten
|
|
|
|
|
+ for(;;)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (bootloader_sector_index < map_length)
|
|
|
|
|
+ {
|
|
|
|
|
+ bootloader_sector_byte_count += platform_flash_sector_map[bootloader_sector_index];
|
|
|
|
|
+ if (bootloader_sector_byte_count < PLATFORM_BOOTLOADER_SIZE)
|
|
|
|
|
+ {
|
|
|
|
|
+ bootloader_sector_index++;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ logmsg("Bootloader does not fit in flash");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // find the last sector the mainline firmware ends
|
|
|
|
|
+ uint32_t fwsize = firmware_size(file);
|
|
|
|
|
+ uint32_t firmware_sector_start = bootloader_sector_index + 1;
|
|
|
|
|
+ uint32_t last_sector_index = firmware_sector_start;
|
|
|
|
|
+ uint32_t last_sector_byte_count = 0;
|
|
|
|
|
+ for(;;)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (last_sector_index < map_length)
|
|
|
|
|
+ {
|
|
|
|
|
+ last_sector_byte_count += platform_flash_sector_map[last_sector_index];
|
|
|
|
|
+ if (fwsize > last_sector_byte_count)
|
|
|
|
|
+ {
|
|
|
|
|
+ last_sector_index++;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ logmsg("Firmware too large: ", (int) fwsize,
|
|
|
|
|
+ " space left after the bootloader ", last_sector_byte_count,
|
|
|
|
|
+ " total flash size ", (int)PLATFORM_FLASH_TOTAL_SIZE);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Erase the sectors the mainline firmware will be written to
|
|
|
|
|
+ for (int i = firmware_sector_start; i <= last_sector_index; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (i % 2 == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ LED_ON();
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ LED_OFF();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!erase_flash_sector(i))
|
|
|
|
|
+ {
|
|
|
|
|
+ logmsg("Flash failed to erase sector ", i);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ LED_OFF();
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+bool platform_firmware_program(FsFile &file)
|
|
|
|
|
+{
|
|
|
|
|
+ // write the mainline firmware to flash
|
|
|
|
|
+ int32_t bytes_read = 0;
|
|
|
|
|
+ uint32_t address_offset = PLATFORM_BOOTLOADER_SIZE;
|
|
|
|
|
+
|
|
|
|
|
+ // Make sure the buffer is aligned to word boundary
|
|
|
|
|
+ static uint32_t buffer32[PLATFORM_FLASH_WRITE_BUFFER_SIZE / 4];
|
|
|
|
|
+ uint8_t *buffer = (uint8_t*)buffer32;
|
|
|
|
|
+
|
|
|
|
|
+ if (!file.seek(PLATFORM_BOOTLOADER_SIZE))
|
|
|
|
|
+ {
|
|
|
|
|
+ logmsg("Seek failed");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ dbgmsg("Writing flash at firmware offset ", address_offset, " data ", bytearray(buffer, 4));
|
|
|
|
|
+
|
|
|
|
|
+ for(;;)
|
|
|
|
|
+ {
|
|
|
|
|
+ if ((address_offset - PLATFORM_BOOTLOADER_SIZE) / PLATFORM_FLASH_WRITE_BUFFER_SIZE % 2)
|
|
|
|
|
+ {
|
|
|
|
|
+ LED_ON();
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ LED_OFF();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ bytes_read = file.read(buffer, PLATFORM_FLASH_WRITE_BUFFER_SIZE);
|
|
|
|
|
+ if ( bytes_read < 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ logmsg("Firmware file read failed, error code ", (int) bytes_read);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!write_flash(address_offset, bytes_read, buffer))
|
|
|
|
|
+ {
|
|
|
|
|
+ logmsg("Failed to write flash at offset: ", address_offset, " bytes read: ",(int) bytes_read);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // check the mainline firmware is valid
|
|
|
|
|
+ if (address_offset == PLATFORM_BOOTLOADER_SIZE)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (buffer[3] != 0x20 || buffer[7] != 0x08)
|
|
|
|
|
+ {
|
|
|
|
|
+ logmsg("Invalid firmware file, starts with: ", bytearray(buffer, 16));
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (bytes_read < PLATFORM_FLASH_WRITE_BUFFER_SIZE)
|
|
|
|
|
+ {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ address_offset += bytes_read;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ LED_OFF();
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void platform_boot_to_main_firmware()
|
|
void platform_boot_to_main_firmware()
|
|
|
{
|
|
{
|
|
|
uint32_t *mainprogram_start = (uint32_t*)(0x08000000 + PLATFORM_BOOTLOADER_SIZE);
|
|
uint32_t *mainprogram_start = (uint32_t*)(0x08000000 + PLATFORM_BOOTLOADER_SIZE);
|