github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/runtime/runtime_stm32f4.go (about) 1 //go:build stm32f4 && (stm32f407 || stm32f469) 2 3 package runtime 4 5 import ( 6 "device/stm32" 7 "machine" 8 ) 9 10 func init() { 11 initCLK() 12 13 machine.InitSerial() 14 15 initTickTimer(&machine.TIM2) 16 } 17 18 func putchar(c byte) { 19 machine.Serial.WriteByte(c) 20 } 21 22 func getchar() byte { 23 for machine.Serial.Buffered() == 0 { 24 Gosched() 25 } 26 v, _ := machine.Serial.ReadByte() 27 return v 28 } 29 30 func buffered() int { 31 return machine.Serial.Buffered() 32 } 33 34 func initCLK() { 35 // Reset clock registers 36 // Set HSION 37 stm32.RCC.CR.SetBits(stm32.RCC_CR_HSION) 38 for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSIRDY) { 39 } 40 41 // Reset CFGR 42 stm32.RCC.CFGR.Set(0x00000000) 43 // Reset HSEON, CSSON and PLLON 44 stm32.RCC.CR.ClearBits(stm32.RCC_CR_HSEON | stm32.RCC_CR_CSSON | stm32.RCC_CR_PLLON) 45 // Reset PLLCFGR 46 stm32.RCC.PLLCFGR.Set(0x24003010) 47 // Reset HSEBYP 48 stm32.RCC.CR.ClearBits(stm32.RCC_CR_HSEBYP) 49 // Disable all interrupts 50 stm32.RCC.CIR.Set(0x00000000) 51 52 // Set up the clock 53 var startupCounter uint32 = 0 54 55 // Enable HSE 56 stm32.RCC.CR.Set(stm32.RCC_CR_HSEON) 57 58 // Wait till HSE is ready and if timeout is reached exit 59 for { 60 startupCounter++ 61 if stm32.RCC.CR.HasBits(stm32.RCC_CR_HSERDY) || (startupCounter == HSE_STARTUP_TIMEOUT) { 62 break 63 } 64 } 65 if stm32.RCC.CR.HasBits(stm32.RCC_CR_HSERDY) { 66 // Enable high performance mode, configure maximum system frequency. 67 stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_PWREN) 68 stm32.PWR.CR.SetBits(0x4000) // PWR_CR_VOS 69 // HCLK = SYSCLK / 1 70 stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_HPRE_Div1 << stm32.RCC_CFGR_HPRE_Pos) 71 // PCLK2 = HCLK / 2 72 stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE2_Div2 << stm32.RCC_CFGR_PPRE2_Pos) 73 // PCLK1 = HCLK / 4 74 stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE1_Div4 << stm32.RCC_CFGR_PPRE1_Pos) 75 // Configure the main PLL 76 stm32.RCC.PLLCFGR.Set(PLL_CFGR) 77 // Enable main PLL 78 stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON) 79 // Wait till the main PLL is ready 80 for (stm32.RCC.CR.Get() & stm32.RCC_CR_PLLRDY) == 0 { 81 } 82 // Configure Flash prefetch, Instruction cache, Data cache and wait state 83 stm32.FLASH.ACR.Set(stm32.FLASH_ACR_ICEN | stm32.FLASH_ACR_DCEN | (5 << stm32.FLASH_ACR_LATENCY_Pos)) 84 // Select the main PLL as system clock source 85 stm32.RCC.CFGR.ClearBits(stm32.RCC_CFGR_SW_Msk) 86 stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_SW_PLL << stm32.RCC_CFGR_SW_Pos) 87 for (stm32.RCC.CFGR.Get() & stm32.RCC_CFGR_SWS_Msk) != (stm32.RCC_CFGR_SWS_PLL << stm32.RCC_CFGR_SWS_Pos) { 88 } 89 90 } else { 91 // If HSE failed to start up, the application will have wrong clock configuration 92 for { 93 } 94 } 95 96 // Enable the CCM RAM clock 97 stm32.RCC.AHB1ENR.SetBits(1 << 20) 98 }