From 769759619398e63fbe07445fc3b7f9aea51161b8 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Mon, 15 Jan 2024 16:03:44 +0100 Subject: [PATCH] AT-SAME51: reset clock before staging --- hal/same51.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/hal/same51.c b/hal/same51.c index 992e9b819..6abf0edb2 100644 --- a/hal/same51.c +++ b/hal/same51.c @@ -75,7 +75,10 @@ * Generic clock generator */ #define GCLK_BASE (0x40001C00) +#define GCLK_CTRLA *((volatile uint32_t *)(GCLK_BASE + 0x00)) #define GCLK_SYNCBUSY *((volatile uint32_t *)(GCLK_BASE + 0x04)) +#define CTRLA_SWRST (1 << 0) +#define SYNCBUSY_SWRST (1 << 0) #define SYNCBUSY_GENCTRL(x) (1 << (2 + x)) #define GCLK_IS_BUSY(x) ((GCLK_SYNCBUSY & (SYNCBUSY_GENCTRL(x))) != 0) @@ -132,6 +135,14 @@ #define NVMCTRL_STATUS *((volatile uint16_t *)(NVMCTRL_BASE + 0x12)) #define NVMCTRL_ADDR *((volatile uint32_t *)(NVMCTRL_BASE + 0x14)) #define NVMCTRL_SEESTAT *((volatile uint32_t *)(NVMCTRL_BASE + 0x2c)) + + +/* Extra NVMCTRL options (unused: leaving default values) */ +#define NVMCTRLA_DISABLE_CACHES (0xC000) +#define NVMCTRLA_RWS_MASK (0x0F00) +#define NVMCTRLA_RWS_SHIFT 8 +#define NVMCTRLA_AUTOWS (1 << 2) + #define NVMCMD_KEY ((0xA5) << 8) #define NVMCMD_ERASE_PAGE (0x00) #define NVMCMD_ERASE_BLOCK (0x02) @@ -271,6 +282,8 @@ void hal_init(void) WDT_CTRL &= (~WDT_EN); /* Run the bootloader with interrupts off */ __asm__ volatile ("cpsid i"); + + /* Initialize clock */ clock_init(); /* enable all the AHB clocks */ @@ -285,6 +298,7 @@ void hal_init(void) /* enable all the APBD clocks */ MCLK_APBDMASK = 0x2U; + #ifdef DUALBANK_SWAP fork_bootloader(); #endif @@ -352,7 +366,6 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len) void RAMFUNCTION hal_flash_dualbank_swap(void) { - hal_flash_unlock(); NVMCTRLB = NVMCMD_BKSWRST | NVMCMD_KEY; @@ -366,6 +379,11 @@ void RAMFUNCTION hal_flash_dualbank_swap(void) void RAMFUNCTION hal_prepare_boot(void) { + /* Reset clock controller */ + GCLK_CTRLA |= CTRLA_SWRST; + /* Wait until reset is complete */ + while ((GCLK_SYNCBUSY & SYNCBUSY_SWRST) != 0) + ; }