Commit e4909f3a authored by Christos Gentsos's avatar Christos Gentsos

Flash: make btldr check/reset the copy FW flag in user flash space

parent 79fccc98
......@@ -35,7 +35,8 @@ SEARCH_DIR(.)
/* Memory Spaces Definitions */
MEMORY
{
bootloader (rx) : ORIGIN = 0x00000000, LENGTH = 0x00002000
bootloader (rx) : ORIGIN = 0x00000000, LENGTH = 0x00001f00
user_flash (rx) : ORIGIN = 0x00001f00, LENGTH = 0x00000100
fw_storage (rx) : ORIGIN = 0x00022000, LENGTH = 0x0001c000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
......@@ -111,6 +112,14 @@ SECTIONS
_emockbl = .;
} > bootloader
.user_flash :
{
. = ALIGN(4);
user_flash = .;
LONG(0xBEC0ABCD)
. = ALIGN(4);
} > user_flash
.relocate : AT (_etext)
{
. = ALIGN(4);
......
......@@ -35,7 +35,7 @@ SEARCH_DIR(.)
/* Memory Spaces Definitions */
MEMORY
{
bootloader (rx) : ORIGIN = 0x00000000, LENGTH = 0x00002000
bootloader (rx) : ORIGIN = 0x00000000, LENGTH = 0x00001f00
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
......@@ -97,6 +97,8 @@ SECTIONS
. = ALIGN(4);
_etext = .;
user_flash = LENGTH(bootloader);
.relocate : AT (_etext)
{
. = ALIGN(4);
......
......@@ -3,6 +3,15 @@
#define FLASH_ROW_SIZE 256
typedef struct {
uint32_t copy_fw;
uint8_t user_data[252];
} user_flash_t;
extern user_flash_t user_flash;
void flash_erase_row(uint32_t *dst);
void flash_write_words(uint32_t *dst, uint32_t *src, uint32_t n_words);
......
......@@ -42,11 +42,11 @@ static addr_space_t regs = {.n_addrs = N_REGS,
.i2c_reg_w_callback = (fp_t[N_REGS]){},
.i2c_reg_r_callback = (fp_t[N_REGS]){}};
#define N_EXT_REGS 4
#define N_EXT_REGS 6
static addr_space_t ext_regs = {.n_addrs = N_EXT_REGS,
.i2c_reg_addrs = (uint8_t[N_EXT_REGS]){1, 2, 3, 4},
.i2c_reg_lengths = (uint8_t[N_EXT_REGS]){2, 8, 2, 1},
.i2c_reg_addrs = (uint8_t[N_EXT_REGS]){1, 2, 3, 4, 5, 6},
.i2c_reg_lengths = (uint8_t[N_EXT_REGS]){2, 8, 2, 1, 1, 1},
.i2c_reg_pointers = (uint8_t*[N_EXT_REGS]){},
.i2c_reg_w_callback = (fp_t[N_REGS]){},
.i2c_reg_r_callback = (fp_t[N_REGS]){}};
......@@ -288,14 +288,18 @@ void written_fw_checksum()
}
void print_checksum_and_goto_bootloader()
void print_checksum()
{
if (fw_local_checksum == *(uint16_t *)(&ext_regs.i2c_reg_pointers[2][0])) {
debug("locally computed checksum %u is correct!", fw_local_checksum);
} else {
debug("locally computed checksum %u differs from %u!", fw_local_checksum, *(uint16_t *)(&ext_regs.i2c_reg_pointers[2][0]));
}
}
void uc_reset()
{
usbdc_detach();
usbdc_stop();
usbdc_deinit();
......@@ -304,6 +308,26 @@ void print_checksum_and_goto_bootloader()
}
void boot_new_fw()
{
uint8_t *char_user_flash = (uint8_t *)&user_flash;
user_flash_t *tmp_user_flash = (user_flash_t *)fw_write_buf;
/* backup existing user data */
for (uint8_t i = 0; i < 8; ++i)
fw_write_buf[i] = char_user_flash[i];
/* set 0xBEC0ABCD copy FW code */
tmp_user_flash->copy_fw = 0xbec0abcd;
/* copy modified block back to the flash */
flash_write_row((uint32_t *)&user_flash, (uint32_t *)fw_write_buf);
/* reset the uC */
uc_reset();
}
void setup_I2C_slave(void)
{
init_addr_space(&regs);
......@@ -312,7 +336,9 @@ void setup_I2C_slave(void)
regs.i2c_reg_pointers[3][1] = 0xad;
ext_regs.i2c_reg_w_callback[1] = &written_fw_block;
ext_regs.i2c_reg_w_callback[2] = &written_fw_checksum;
ext_regs.i2c_reg_w_callback[3] = &print_checksum_and_goto_bootloader;
ext_regs.i2c_reg_w_callback[3] = &print_checksum;
ext_regs.i2c_reg_w_callback[4] = &boot_new_fw;
ext_regs.i2c_reg_w_callback[5] = &uc_reset;
fw_write_addr = (uint32_t *)0x22000;
fw_write_buf = (uint8_t *)malloc(FLASH_ROW_SIZE);
hri_sercomi2cs_clear_CTRLB_SMEN_bit(SERCOM3);
......
......@@ -4,6 +4,8 @@
#define SECOND_APP_START_ADDRESS 0x2000
static uint8_t tmp_buf[256];
void jump_to_secondary()
{
uint32_t app_start_address;
......@@ -21,7 +23,23 @@ void jump_to_secondary()
int main(void)
{
flash_copy((uint32_t*)0x2000, (uint32_t*)0x22000, 0x1e000);
if (user_flash.copy_fw == 0xBEC0ABCD) {
flash_copy((uint32_t*)0x2000, (uint32_t*)0x22000, 0x1e000);
uint8_t *char_user_flash = (uint8_t *)&user_flash;
user_flash_t *tmp_user_flash = (user_flash_t *)tmp_buf;
/* backup existing user data */
for (uint8_t i = 0; i < 8; ++i)
tmp_buf[i] = char_user_flash[i];
/* reset copy FW code */
tmp_user_flash->copy_fw = 0;
/* copy modified block back to the flash */
flash_write_row((uint32_t *)&user_flash, (uint32_t *)tmp_buf);
}
jump_to_secondary();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment