Skip to content

Commit

Permalink
Fix RTC backup register indexing, add target-specific register and bo…
Browse files Browse the repository at this point in the history
…ot 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.
  • Loading branch information
twelho committed Sep 6, 2021
1 parent 087b7c7 commit 7e831d2
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 9 deletions.
8 changes: 4 additions & 4 deletions src/stm32f103/backup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
7 changes: 6 additions & 1 deletion src/stm32f103/backup.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
12 changes: 9 additions & 3 deletions src/stm32f103/target_stm32f103.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down
9 changes: 8 additions & 1 deletion src/stm32l1/target_stm32l1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {

Expand Down

0 comments on commit 7e831d2

Please sign in to comment.