github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/runtime/runtime_stm32f7x2.go (about) 1 //go:build stm32 && stm32f7x2 2 3 package runtime 4 5 import ( 6 "device/stm32" 7 "machine" 8 ) 9 10 /* 11 clock settings 12 13 +-------------+--------+ 14 | HSE | 8mhz | 15 | SYSCLK | 216mhz | 16 | HCLK | 216mhz | 17 | APB1(PCLK1) | 27mhz | 18 | APB2(PCLK2) | 108mhz | 19 +-------------+--------+ 20 */ 21 const ( 22 HSE_STARTUP_TIMEOUT = 0x0500 23 PLL_M = 4 24 PLL_N = 216 25 PLL_P = 2 26 PLL_Q = 2 27 ) 28 29 func init() { 30 initCLK() 31 32 machine.InitSerial() 33 34 initTickTimer(&machine.TIM3) 35 } 36 37 func putchar(c byte) { 38 machine.Serial.WriteByte(c) 39 } 40 41 func getchar() byte { 42 for machine.Serial.Buffered() == 0 { 43 Gosched() 44 } 45 v, _ := machine.Serial.ReadByte() 46 return v 47 } 48 49 func buffered() int { 50 return machine.Serial.Buffered() 51 } 52 53 func initCLK() { 54 // PWR_CLK_ENABLE 55 stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_PWREN) 56 _ = stm32.RCC.APB1ENR.Get() 57 58 // PWR_VOLTAGESCALING_CONFIG 59 stm32.PWR.CR1.ReplaceBits(0x3<<stm32.PWR_CR1_VOS_Pos, stm32.PWR_CR1_VOS_Msk, 0) 60 _ = stm32.PWR.CR1.Get() 61 62 // Initialize the High-Speed External Oscillator 63 initOsc() 64 65 // Set flash wait states (min 7 latency units) based on clock 66 if (stm32.FLASH.ACR.Get() & stm32.FLASH_ACR_LATENCY_Msk) < 7 { 67 stm32.FLASH.ACR.ReplaceBits(7, stm32.FLASH_ACR_LATENCY_Msk, 0) 68 } 69 70 // HCLK (0x1C00 = DIV_16, 0x0 = RCC_SYSCLK_DIV1) - ensure timers remain 71 // within spec as the SYSCLK source changes. 72 stm32.RCC.CFGR.ReplaceBits(0x00001C00, stm32.RCC_CFGR_PPRE1_Msk, 0) 73 stm32.RCC.CFGR.ReplaceBits(0x00001C00<<3, stm32.RCC_CFGR_PPRE2_Msk, 0) 74 stm32.RCC.CFGR.ReplaceBits(0, stm32.RCC_CFGR_HPRE_Msk, 0) 75 76 // Set SYSCLK source and wait 77 // (2 = PLLCLK, 3 = RCC_CFGR_SW mask, 3 << 3 = RCC_CFGR_SWS mask) 78 stm32.RCC.CFGR.ReplaceBits(2, 3, 0) 79 for stm32.RCC.CFGR.Get()&(3<<2) != (2 << 2) { 80 } 81 82 // Set flash wait states (max 7 latency units) based on clock 83 if (stm32.FLASH.ACR.Get() & stm32.FLASH_ACR_LATENCY_Msk) > 7 { 84 stm32.FLASH.ACR.ReplaceBits(7, stm32.FLASH_ACR_LATENCY_Msk, 0) 85 } 86 87 // Set APB1 and APB2 clocks (0x1800 = DIV8, 0x1000 = DIV2) 88 stm32.RCC.CFGR.ReplaceBits(0x1800, stm32.RCC_CFGR_PPRE1_Msk, 0) 89 stm32.RCC.CFGR.ReplaceBits(0x1000<<3, stm32.RCC_CFGR_PPRE2_Msk, 0) 90 } 91 92 func initOsc() { 93 // Enable HSE, wait until ready 94 stm32.RCC.CR.SetBits(stm32.RCC_CR_HSEON) 95 for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSERDY) { 96 } 97 98 // Disable the PLL, wait until disabled 99 stm32.RCC.CR.ClearBits(stm32.RCC_CR_PLLON) 100 for stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) { 101 } 102 103 // Configure the PLL 104 stm32.RCC.PLLCFGR.Set(0x20000000 | 105 (1 << stm32.RCC_PLLCFGR_PLLSRC_Pos) | // 1 = HSE 106 PLL_M | 107 (PLL_N << stm32.RCC_PLLCFGR_PLLN_Pos) | 108 (((PLL_P >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP_Pos) | 109 (PLL_Q << stm32.RCC_PLLCFGR_PLLQ_Pos)) 110 111 // Enable the PLL, wait until ready 112 stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON) 113 for !stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) { 114 } 115 }