diff --git a/src/runtime/runtime_stm32f4.go b/src/runtime/runtime_stm32f4.go new file mode 100644 index 00000000..6ce44303 --- /dev/null +++ b/src/runtime/runtime_stm32f4.go @@ -0,0 +1,88 @@ +//go:build stm32f4 && (stm32f407 || stm32f469) +// +build stm32f4 +// +build stm32f407 stm32f469 + +package runtime + +import ( + "device/stm32" + "machine" +) + +func init() { + initCLK() + + machine.Serial.Configure(machine.UARTConfig{}) + + initTickTimer(&machine.TIM2) +} + +func putchar(c byte) { + machine.Serial.WriteByte(c) +} + +func initCLK() { + // Reset clock registers + // Set HSION + stm32.RCC.CR.SetBits(stm32.RCC_CR_HSION) + for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSIRDY) { + } + + // Reset CFGR + stm32.RCC.CFGR.Set(0x00000000) + // Reset HSEON, CSSON and PLLON + stm32.RCC.CR.ClearBits(stm32.RCC_CR_HSEON | stm32.RCC_CR_CSSON | stm32.RCC_CR_PLLON) + // Reset PLLCFGR + stm32.RCC.PLLCFGR.Set(0x24003010) + // Reset HSEBYP + stm32.RCC.CR.ClearBits(stm32.RCC_CR_HSEBYP) + // Disable all interrupts + stm32.RCC.CIR.Set(0x00000000) + + // Set up the clock + var startupCounter uint32 = 0 + + // Enable HSE + stm32.RCC.CR.Set(stm32.RCC_CR_HSEON) + + // Wait till HSE is ready and if timeout is reached exit + for { + startupCounter++ + if stm32.RCC.CR.HasBits(stm32.RCC_CR_HSERDY) || (startupCounter == HSE_STARTUP_TIMEOUT) { + break + } + } + if stm32.RCC.CR.HasBits(stm32.RCC_CR_HSERDY) { + // Enable high performance mode, configure maximum system frequency. + stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_PWREN) + stm32.PWR.CR.SetBits(0x4000) // PWR_CR_VOS + // HCLK = SYSCLK / 1 + stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_HPRE_Div1 << stm32.RCC_CFGR_HPRE_Pos) + // PCLK2 = HCLK / 2 + stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE2_Div2 << stm32.RCC_CFGR_PPRE2_Pos) + // PCLK1 = HCLK / 4 + stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE1_Div4 << stm32.RCC_CFGR_PPRE1_Pos) + // Configure the main PLL + stm32.RCC.PLLCFGR.Set(PLL_CFGR) + // Enable main PLL + stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON) + // Wait till the main PLL is ready + for (stm32.RCC.CR.Get() & stm32.RCC_CR_PLLRDY) == 0 { + } + // Configure Flash prefetch, Instruction cache, Data cache and wait state + stm32.FLASH.ACR.Set(stm32.FLASH_ACR_ICEN | stm32.FLASH_ACR_DCEN | (5 << stm32.FLASH_ACR_LATENCY_Pos)) + // Select the main PLL as system clock source + stm32.RCC.CFGR.ClearBits(stm32.RCC_CFGR_SW_Msk) + stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_SW_PLL << stm32.RCC_CFGR_SW_Pos) + for (stm32.RCC.CFGR.Get() & stm32.RCC_CFGR_SWS_Msk) != (stm32.RCC_CFGR_SWS_PLL << stm32.RCC_CFGR_SWS_Pos) { + } + + } else { + // If HSE failed to start up, the application will have wrong clock configuration + for { + } + } + + // Enable the CCM RAM clock + stm32.RCC.AHB1ENR.SetBits(1 << 20) +} diff --git a/src/runtime/runtime_stm32f407.go b/src/runtime/runtime_stm32f407.go index 27ecd955..643f67f8 100644 --- a/src/runtime/runtime_stm32f407.go +++ b/src/runtime/runtime_stm32f407.go @@ -1,11 +1,9 @@ -// +build stm32,stm32f407 +//go:build stm32f4 && stm32f407 +// +build stm32f4,stm32f407 package runtime -import ( - "device/stm32" - "machine" -) +import "device/stm32" /* clock settings @@ -20,88 +18,10 @@ import ( const ( HSE_STARTUP_TIMEOUT = 0x0500 // PLL Options - See RM0090 Reference Manual pg. 95 - PLL_M = 8 // PLL_VCO = (HSE_VALUE or HSI_VLAUE / PLL_M) * PLL_N - PLL_N = 336 - PLL_P = 2 // SYSCLK = PLL_VCO / PLL_P - PLL_Q = 7 // USB OTS FS, SDIO and RNG Clock = PLL_VCO / PLL_Q + PLL_M = 8 // PLL_VCO = (HSE_VALUE or HSI_VLAUE / PLL_M) * PLL_N + PLL_N = 336 + PLL_P = 2 // SYSCLK = PLL_VCO / PLL_P + PLL_Q = 7 // USB OTS FS, SDIO and RNG Clock = PLL_VCO / PLL_Q + PLL_CFGR = PLL_M | (PLL_N << stm32.RCC_PLLCFGR_PLLN_Pos) | (((PLL_P >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP_Pos) | + (1 << stm32.RCC_PLLCFGR_PLLSRC_Pos) | (PLL_Q << stm32.RCC_PLLCFGR_PLLQ_Pos) ) - -func init() { - initCLK() - - machine.Serial.Configure(machine.UARTConfig{}) - - initTickTimer(&machine.TIM2) -} - -func putchar(c byte) { - machine.Serial.WriteByte(c) -} - -func initCLK() { - // Reset clock registers - // Set HSION - stm32.RCC.CR.SetBits(stm32.RCC_CR_HSION) - for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSIRDY) { - } - - // Reset CFGR - stm32.RCC.CFGR.Set(0x00000000) - // Reset HSEON, CSSON and PLLON - stm32.RCC.CR.ClearBits(stm32.RCC_CR_HSEON | stm32.RCC_CR_CSSON | stm32.RCC_CR_PLLON) - // Reset PLLCFGR - stm32.RCC.PLLCFGR.Set(0x24003010) - // Reset HSEBYP - stm32.RCC.CR.ClearBits(stm32.RCC_CR_HSEBYP) - // Disable all interrupts - stm32.RCC.CIR.Set(0x00000000) - - // Set up the clock - var startupCounter uint32 = 0 - - // Enable HSE - stm32.RCC.CR.Set(stm32.RCC_CR_HSEON) - - // Wait till HSE is ready and if timeout is reached exit - for { - startupCounter++ - if stm32.RCC.CR.HasBits(stm32.RCC_CR_HSERDY) || (startupCounter == HSE_STARTUP_TIMEOUT) { - break - } - } - if stm32.RCC.CR.HasBits(stm32.RCC_CR_HSERDY) { - // Enable high performance mode, System frequency up to 168MHz - stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_PWREN) - stm32.PWR.CR.SetBits(0x4000) // PWR_CR_VOS - // HCLK = SYSCLK / 1 - stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_HPRE_Div1 << stm32.RCC_CFGR_HPRE_Pos) - // PCLK2 = HCLK / 2 - stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE2_Div2 << stm32.RCC_CFGR_PPRE2_Pos) - // PCLK1 = HCLK / 4 - stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE1_Div4 << stm32.RCC_CFGR_PPRE1_Pos) - // Configure the main PLL - // PLL Options - See RM0090 Reference Manual pg. 95 - stm32.RCC.PLLCFGR.Set(PLL_M | (PLL_N << 6) | (((PLL_P >> 1) - 1) << 16) | - (1 << stm32.RCC_PLLCFGR_PLLSRC_Pos) | (PLL_Q << 24)) - // Enable main PLL - stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON) - // Wait till the main PLL is ready - for (stm32.RCC.CR.Get() & stm32.RCC_CR_PLLRDY) == 0 { - } - // Configure Flash prefetch, Instruction cache, Data cache and wait state - stm32.FLASH.ACR.Set(stm32.FLASH_ACR_ICEN | stm32.FLASH_ACR_DCEN | (5 << stm32.FLASH_ACR_LATENCY_Pos)) - // Select the main PLL as system clock source - stm32.RCC.CFGR.ClearBits(stm32.RCC_CFGR_SW_Msk) - stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_SW_PLL << stm32.RCC_CFGR_SW_Pos) - for (stm32.RCC.CFGR.Get() & stm32.RCC_CFGR_SWS_Msk) != (stm32.RCC_CFGR_SWS_PLL << stm32.RCC_CFGR_SWS_Pos) { - } - - } else { - // If HSE failed to start up, the application will have wrong clock configuration - for { - } - } - - // Enable the CCM RAM clock - stm32.RCC.AHB1ENR.SetBits(1 << 20) -}