Commit f3bde1bb authored by Adam Wujek's avatar Adam Wujek

i2c: check write byte at firmware reset

Compare the written byte against magic number. If not match refuse
to change a firmware mode. The check is done for bootloader and
main mode.
Signed-off-by: 's avatarAdam Wujek <dev_public@wujek.eu>
parent f5f3995e
......@@ -29,7 +29,7 @@ static uint16_t fw_checksum;
static uint16_t fw_local_checksum;
static uint8_t fw_block[8];
static uint8_t dummy_byte;
static uint8_t reset_byte;
static uint8_t fw_type = FW_BOOTLOADER;
enum {
......@@ -86,7 +86,7 @@ static cmd_t cmds_cmds[] = (cmd_t[]){
{0xD3, (int8_t *)&cmd_data_lengths[cmd_0xD3], (uint8_t *)&fw_checksum, (fp_t)NULL, (fp_t)&written_fw_checksum, (fp_t)NULL, QUERY_WR | QUERY_RD, 0},
{0xD4, (int8_t *)&cmd_data_lengths[cmd_0xD4], (uint8_t *)&fw_local_checksum, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD, 0},
{0xD5, (int8_t *)&cmd_data_lengths[cmd_0xD5], (uint8_t *)&fw_type, &get_fw_type, (fp_t)&boot_new_fw, (fp_t)NULL, QUERY_WR | QUERY_RD, 0},
{0xD6, (int8_t *)&cmd_data_lengths[cmd_0xD6], (uint8_t *)&dummy_byte, (fp_t)NULL, (fp_t)&uc_reset, (fp_t)NULL, QUERY_WR, 0}
{0xD6, (int8_t *)&cmd_data_lengths[cmd_0xD6], (uint8_t *)&reset_byte, (fp_t)NULL, (fp_t)&uc_reset, (fp_t)NULL, QUERY_WR, 0}
};
cmd_space_t cmds = {
......@@ -152,6 +152,12 @@ void written_fw_checksum()
void uc_reset()
{
/* Check magic */
if (reset_byte != UC_RESET_MAGIC) {
/* Wrong magic, abort */
return;
}
NVIC_SystemReset();
}
......@@ -181,6 +187,8 @@ void boot_new_fw()
/* copy modified block back to the flash */
flash_write_row((uint32_t *)&user_flash, (uint32_t *)fw_write_buf);
/* reset the uC */
/* Set a proper Magic for uC reset */
reset_byte = UC_RESET_MAGIC;
/* Reset the uC */
uc_reset();
}
......@@ -27,6 +27,7 @@ typedef void(*fp_t)(void);
#define FW_MAIN 2
/* Defines of Magic numbers */
#define UC_RESET_MAGIC 0x5A
#define BOOT_NEW_FW_MAGIC 0xAD
// QUERY command returned data format
......
......@@ -626,7 +626,8 @@ UC_RESET
| Transaction type: **Byte write**
| Data length: **1**
Writing any byte to this command triggers a uC reset.
Writing 0x5A byte to this register triggers a uC reset.
Other writes are silently ignored.
.. _UPTIME_SECS:
......
......@@ -76,7 +76,7 @@ extern uint32_t seconds_up;
uint32_t TMR_ERROR_CNT;
static uint8_t dummy_byte;
static uint8_t reset_byte;
static uint8_t fw_type;
static uint8_t capablity;
......@@ -221,7 +221,7 @@ static const cmd_t cmds_cmds[] = (cmd_t[]){
{0x9E, (int8_t *)&cmd_data_lengths[cmd_0x9E], (uint8_t *)&MFR_SER, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0xAE, (int8_t *)&cmd_data_lengths[cmd_0xAE], (uint8_t *)&IC_DEVICE_REV, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0xD5, (int8_t *)&cmd_data_lengths[cmd_0xD5], (uint8_t *)&fw_type, &get_fw_type, &boot_new_fw, (fp_t)NULL, QUERY_WR | QUERY_RD, 0},
{0xD6, (int8_t *)&cmd_data_lengths[cmd_0xD6], (uint8_t *)&dummy_byte, (fp_t)NULL, &uc_reset, (fp_t)NULL, QUERY_WR, 0},
{0xD6, (int8_t *)&cmd_data_lengths[cmd_0xD6], (uint8_t *)&reset_byte, (fp_t)NULL, &uc_reset, (fp_t)NULL, QUERY_WR, 0},
{0xD7, (int8_t *)&cmd_data_lengths[cmd_0xD7], (uint8_t *)&seconds_up, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD, 0},
{0xD8, (int8_t *)&cmd_data_lengths[cmd_0xD8], (uint8_t *)&TMR_ERROR_CNT, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_WR | QUERY_RD, 0},
{0xD9, (int8_t *)&cmd_data_lengths[cmd_0xD9], (uint8_t *)&use_pec_tmp, (fp_t)NULL, &set_pec, (fp_t)NULL, QUERY_WR | QUERY_RD, 1},
......@@ -239,6 +239,12 @@ static uint32_t fw_write_buf[FLASH_ROW_SIZE/4];
void uc_reset()
{
/* Check magic */
if (reset_byte != UC_RESET_MAGIC) {
/* Wrong magic, abort */
return;
}
#ifdef USB_ENABLE
usbdc_detach();
usbdc_stop();
......@@ -273,7 +279,9 @@ void boot_new_fw()
/* copy modified block back to the flash */
flash_write_row((uint32_t *)&user_flash, (uint32_t *)fw_write_buf);
/* reset the uC */
/* Set a proper Magic for uC reset */
reset_byte = UC_RESET_MAGIC;
/* Reset the uC */
uc_reset();
}
......
......@@ -126,8 +126,8 @@ void user_interaction()
check_res_print_error(res);
break;
case 'r':
// write value doesn't matter, use whatever
res = i2c_m_sync_blk_cmd_write(&I2C_0, ADDR_UC_RESET, &tmp_byte, 1);
// write magic for the reset
res = i2c_m_sync_blk_cmd_write(&I2C_0, ADDR_UC_RESET, &tmp_byte, 0x5A);
if (!oneline)
check_res_print_error(res);
if (!oneline)
......
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