summaryrefslogtreecommitdiff
path: root/ports/stm32/powerctrlboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'ports/stm32/powerctrlboot.c')
-rw-r--r--ports/stm32/powerctrlboot.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/ports/stm32/powerctrlboot.c b/ports/stm32/powerctrlboot.c
index 4ecd83e2c..555457c58 100644
--- a/ports/stm32/powerctrlboot.c
+++ b/ports/stm32/powerctrlboot.c
@@ -104,6 +104,77 @@ void SystemClock_Config(void) {
powerctrl_config_systick();
}
+#elif defined(STM32G0)
+
+void SystemClock_Config(void) {
+ // Enable power control peripheral
+ __HAL_RCC_PWR_CLK_ENABLE();
+
+ // Set flash latency to 2 because SYSCLK > 48MHz
+ FLASH->ACR = (FLASH->ACR & ~0x7) | 0x2;
+
+ #if MICROPY_HW_CLK_USE_HSI
+ // Enable the 16MHz internal oscillator and the PLL to get a 64MHz SYSCLK
+ RCC->CR |= RCC_CR_HSION;
+ while ((RCC->CR & RCC_CR_HSIRDY) == 0) {
+ // Wait for HSI to be ready
+ }
+
+ // Use the PLL to get a 64MHz SYSCLK
+ #define PLLM (HSI_VALUE / 16000000) // input is 8MHz
+ #define PLLN (8) // 8*16MHz = 128MHz
+ #define PLLP (2) // f_P = 64MHz
+ #define PLLQ (2) // f_Q = 64MHz
+ #define PLLR (2) // f_R = 64MHz
+ RCC->PLLCFGR =
+ (PLLP - 1) << RCC_PLLCFGR_PLLP_Pos | RCC_PLLCFGR_PLLPEN
+ | (PLLQ - 1) << RCC_PLLCFGR_PLLQ_Pos | RCC_PLLCFGR_PLLQEN
+ | (PLLR - 1) << RCC_PLLCFGR_PLLR_Pos | RCC_PLLCFGR_PLLREN
+ | PLLN << RCC_PLLCFGR_PLLN_Pos
+ | (PLLM - 1) << RCC_PLLCFGR_PLLM_Pos
+ | RCC_PLLCFGR_PLLSRC_HSI;
+
+ #else
+ #error System clock not specified
+ #endif
+
+ RCC->CR |= RCC_CR_PLLON; // Turn PLL on
+ while ((RCC->CR & RCC_CR_PLLRDY) == 0) {
+ // Wait for PLL to lock
+ }
+ const uint32_t sysclk_src = 2; // 2 = PLLRCLK
+
+ // Select SYSCLK source
+ RCC->CFGR |= sysclk_src << RCC_CFGR_SW_Pos;
+ while (((RCC->CFGR >> RCC_CFGR_SWS_Pos) & 0x7) != sysclk_src) {
+ // Wait for SYSCLK source to change
+ }
+
+ SystemCoreClockUpdate();
+ powerctrl_config_systick();
+
+ #if MICROPY_HW_ENABLE_RNG || MICROPY_HW_ENABLE_USB
+ // Enable the 48MHz internal oscillator
+ RCC->CRRCR |= RCC_CRRCR_HSI48ON;
+ RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
+ SYSCFG->CFGR3 |= SYSCFG_CFGR3_ENREF_HSI48;
+ while (!(RCC->CRRCR & RCC_CRRCR_HSI48RDY)) {
+ // Wait for HSI48 to be ready
+ }
+
+ // Select RC48 as HSI48 for USB and RNG
+ RCC->CCIPR |= RCC_CCIPR_HSI48SEL;
+
+ #if MICROPY_HW_ENABLE_USB
+ // Synchronise HSI48 with 1kHz USB SoF
+ __HAL_RCC_CRS_CLK_ENABLE();
+ CRS->CR = 0x20 << CRS_CR_TRIM_Pos;
+ CRS->CFGR = 2 << CRS_CFGR_SYNCSRC_Pos | 0x22 << CRS_CFGR_FELIM_Pos
+ | __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000) << CRS_CFGR_RELOAD_Pos;
+ #endif
+ #endif
+}
+
#elif defined(STM32L0)
void SystemClock_Config(void) {