From 7e831d22d14341ca7b746a7b541817fc037c4719 Mon Sep 17 00:00:00 2001 From: Dennis Marttinen Date: Tue, 7 Sep 2021 00:19:53 +0300 Subject: [PATCH] Fix RTC backup register indexing, add target-specific register and boot command According to ST's RM0008 STM32F103xx reference manual section 6.4.5 table 17 the backup registers are 32 bits wide with only the lower 16 bits being used for storing values. In addition to this, the "first" register slot is entirely reserved and there is no backup register zero, meaning that BKP_DR1 starts from an offset of 0x04. This was mostly correctly reflected in backup.c, but the 2-multiplier for the register enum throws everything off by a lot, which results in the boot command check failing to work correctly when using anything but the first backup register. BKP0 has also been removed since as described by RM0008 indexing starts at one (BKP1 is now fully equivalent to the old BKP0). I've also gone ahead and implemented support for specifying the backup register and boot command to use per-target. If not defined, options equivalent to the old behavior are used to not break existing applications. --- src/stm32f103/backup.c | 8 ++++---- src/stm32f103/backup.h | 7 ++++++- src/stm32f103/target_stm32f103.c | 12 +++++++++--- src/stm32l1/target_stm32l1.c | 9 ++++++++- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/stm32f103/backup.c b/src/stm32f103/backup.c index 18a4c20..c120ea7 100644 --- a/src/stm32f103/backup.c +++ b/src/stm32f103/backup.c @@ -29,13 +29,13 @@ void backup_write(enum BackupRegister reg, uint32_t value) { rcc_periph_clock_enable(RCC_BKP); pwr_disable_backup_domain_write_protect(); - RTC_BKP_DR((int)reg*2) = value & 0xFFFFUL; - RTC_BKP_DR((int)reg*2+1) = (value & 0xFFFF0000UL) >> 16; + RTC_BKP_DR((int)reg) = value & 0xFFFFUL; + RTC_BKP_DR((int)reg+1) = (value & 0xFFFF0000UL) >> 16; pwr_enable_backup_domain_write_protect(); } uint32_t backup_read(enum BackupRegister reg) { - uint32_t value = ((uint32_t)RTC_BKP_DR((int)reg*2+1) << 16) - | ((uint32_t)RTC_BKP_DR((int)reg*2) << 0); + uint32_t value = (uint32_t)RTC_BKP_DR((int)reg) + | ((uint32_t)RTC_BKP_DR((int)reg+1) << 16); return value; } diff --git a/src/stm32f103/backup.h b/src/stm32f103/backup.h index c2fe2b0..739dced 100644 --- a/src/stm32f103/backup.h +++ b/src/stm32f103/backup.h @@ -20,11 +20,16 @@ #define BACKUP_H_INCLUDED enum BackupRegister { - BKP0 = 0, BKP1, BKP2, BKP3, BKP4, + BKP5, + BKP6, + BKP7, + BKP8, + BKP9, + BKP10, }; extern void backup_write(enum BackupRegister reg, uint32_t value); diff --git a/src/stm32f103/target_stm32f103.c b/src/stm32f103/target_stm32f103.c index 6948482..ba924b5 100644 --- a/src/stm32f103/target_stm32f103.c +++ b/src/stm32f103/target_stm32f103.c @@ -55,7 +55,13 @@ _Static_assert((FLASH_BASE + FLASH_SIZE_OVERRIDE >= APP_BASE_ADDRESS), "Incompatible flash size"); #endif -static const uint32_t CMD_BOOT = 0x544F4F42UL; +#ifndef REG_BOOT +#define REG_BOOT BKP1 +#endif + +#ifndef CMD_BOOT +#define CMD_BOOT 0x544F4F42UL +#endif void target_clock_setup(void) { #ifdef USE_HSI @@ -160,13 +166,13 @@ const usbd_driver* target_usb_init(void) { bool target_get_force_bootloader(void) { bool force = false; /* Check the RTC backup register */ - uint32_t cmd = backup_read(BKP0); + uint32_t cmd = backup_read(REG_BOOT); if (cmd == CMD_BOOT) { force = true; } /* Clear the RTC backup register */ - backup_write(BKP0, 0); + backup_write(REG_BOOT, 0); #if HAVE_BUTTON /* Wait some time in case the button has some debounce capacitor */ diff --git a/src/stm32l1/target_stm32l1.c b/src/stm32l1/target_stm32l1.c index 57b4825..0e010c5 100644 --- a/src/stm32l1/target_stm32l1.c +++ b/src/stm32l1/target_stm32l1.c @@ -27,8 +27,15 @@ #include "config.h" #include "backup.h" +#ifndef REG_BOOT +#define REG_BOOT BKP1 +#endif + +#ifndef CMD_BOOT +#define CMD_BOOT 0x544F4F42UL +#endif + //#define CMD_FAST_BOOT 0xfa57b007 -static const uint32_t CMD_BOOT = 0x544F4F42UL; void target_clock_setup(void) {