From 9cb6ab52fc2b86956e5f74a8630a3aaf79411f29 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Fri, 13 Dec 2024 11:23:25 +0100 Subject: [PATCH] feat: vos0, system clock at 480 MHz --- include/registers.h | 12 ++++++---- src/main.c | 53 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/include/registers.h b/include/registers.h index ccaf2ac..a2719ad 100644 --- a/include/registers.h +++ b/include/registers.h @@ -13,8 +13,10 @@ inline void __attribute__((always_inline)) reg_write_bits_pos(volatile uint32_t *reg, uint32_t data, uint8_t pos, uint32_t mask) { - *reg &= ~(mask << pos); - *reg |= (data & mask) << pos; + uint32_t val = *reg; + val &= ~(mask << pos); + val |= (data & mask) << pos; + *reg = val; } /** @@ -25,8 +27,10 @@ reg_write_bits_pos(volatile uint32_t *reg, uint32_t data, uint8_t pos, */ inline void __attribute__((always_inline)) reg_write_bits(volatile uint32_t *reg, uint32_t data, uint32_t mask) { - *reg &= ~(mask); - *reg |= (data & mask); + uint32_t val = *reg; + val &= ~(mask); + val |= (data & mask); + *reg = val; } /** diff --git a/src/main.c b/src/main.c index 8c71d1f..bba1bf0 100644 --- a/src/main.c +++ b/src/main.c @@ -275,11 +275,54 @@ void main() clocks_pll_enable(CLOCK_PLL2); clocks_pll_wait_ready(CLOCK_PLL2, 300); - /* clocks_pll_configure(CLOCK_PLL1, 1, 25, PLL_SOURCE_HSE, 200, 2, 2, 2); */ - /* clocks_pll_enable(CLOCK_PLL1); */ - /* clocks_pll_wait_ready(CLOCK_PLL1, 300); */ - - /* clocks_system_clock_source(CLOCK_SOURCE_PLL_1_P_CK, 1, 1, 1, 300); */ + // 1. Set pwr configuration + reg_write_bits(&PWR->CR3, + (1 << PWR_CR3_SMPSEN_Pos) | (0 << PWR_CR3_LDOEN_Msk) | + (0 << PWR_CR3_BYPASS_Msk), + PWR_CR3_LDOEN_Msk | PWR_CR3_SMPSEN_Msk | PWR_CR3_BYPASS_Msk); + + // 2. Verify pwr configuration. If not working, stay here looping! + // NOTE: this probably means you need to power cycle the board. The + // configuration can be written only when the chip has just been connected. + while (!(PWR->CR3 & PWR_CR3_SMPSEN) || (PWR->CR3 & PWR_CR3_LDOEN) || (PWR->CR3 & PWR_CR3_BYPASS)); + + // 3. Change VOS + // 3.1. Check current configuration (VOS 3) + while (!(PWR->CSR1 & PWR_CSR1_ACTVOSRDY)); + + // 3.2. VOS 1 transition + reg_write_bits(&PWR->D3CR, (11 << PWR_D3CR_VOS_Pos), PWR_D3CR_VOS_Msk); + while (!(PWR->CSR1 & PWR_D3CR_VOSRDY)); + + // 3.3. VOS 0 transition + reg_set_bits(&SYSCFG->PWRCR, SYSCFG_PWRCR_ODEN); + while (!(PWR->CSR1 & PWR_D3CR_VOSRDY)); + + // 25 MHz / 10 -> 2.5 MHz * 384 = 960 MHz (FVCO) + // PLL1_P = 960 / 2 => 480 MHz + clocks_pll_configure(CLOCK_PLL1, 0, 10, PLL_SOURCE_HSE, 384, 2, 0, 0); + clocks_pll_enable(CLOCK_PLL1); + clocks_pll_wait_ready(CLOCK_PLL1, 300); + + // Flash setup + /* uint32_t sysck_freq_hz = 480000000; // 480 MHz */ + /* uint32_t d1cpre_freq_hz = sysck_freq_hz / 1; // 480 Mhz */ + /* uint32_t rcc_hclk = d1cpre_freq_hz / 2; // 240 MHz */ + + // 240 MHz means wait states = 4, progr delay = 2 + reg_write_bits(&FLASH->ACR, + (2 << FLASH_ACR_WRHIGHFREQ_Pos) | (4 << FLASH_ACR_LATENCY_Pos), + FLASH_ACR_WRHIGHFREQ_Msk | FLASH_ACR_LATENCY_Msk); + while (((FLASH->ACR & FLASH_ACR_LATENCY_Msk) >> FLASH_ACR_LATENCY_Pos) != 4); + + // D1CPRE = sysck / 1 => 480 MHz, HPRE = sysck / 2 => 240 MHz + reg_write_bits(&RCC->D1CFGR, + (0 << RCC_D1CFGR_D1CPRE_Pos) | (1 << RCC_D1CFGR_HPRE_Pos) | + (0 << RCC_D1CFGR_D1CPRE_Pos), + RCC_D1CFGR_D1CPRE_Msk | RCC_D1CFGR_HPRE_Msk | RCC_D1CFGR_D1CPRE_Msk); + + // Sysck = PLL1_P + clocks_system_clock_source(CLOCK_SOURCE_PLL_1_P_CK, 1, 1, 1, 300); fmc_t fmc; init_fmc(&fmc); -- 2.48.1