github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/runtime/runtime_stm32l4.go (about) 1 //go:build stm32 && stm32l4 2 3 package runtime 4 5 import ( 6 "device/stm32" 7 "machine" 8 ) 9 10 const ( 11 PWR_CR1_VOS_0 = 1 << stm32.PWR_CR1_VOS_Pos 12 PWR_CR1_VOS_1 = 2 << stm32.PWR_CR1_VOS_Pos 13 PWR_REGULATOR_VOLTAGE_SCALE1 = PWR_CR1_VOS_0 14 PWR_REGULATOR_VOLTAGE_SCALE2 = PWR_CR1_VOS_1 15 16 FLASH_LATENCY_0 = 0 17 FLASH_LATENCY_1 = 1 18 FLASH_LATENCY_2 = 2 19 FLASH_LATENCY_3 = 3 20 FLASH_LATENCY_4 = 4 21 22 RCC_PLLP_DIV2 = 2 23 RCC_PLLP_DIV7 = 7 24 RCC_PLLQ_DIV2 = 2 25 RCC_PLLR_DIV2 = 2 26 27 RCC_CFGR_SWS_MSI = 0x0 28 RCC_CFGR_SWS_PLL = 0xC 29 30 RCC_PLLSOURCE_MSI = 1 31 32 RCC_PLL_SYSCLK = stm32.RCC_PLLCFGR_PLLREN 33 ) 34 35 type arrtype = uint32 36 37 func init() { 38 initCLK() 39 40 machine.InitSerial() 41 42 initTickTimer(&machine.TIM15) 43 } 44 45 func putchar(c byte) { 46 machine.Serial.WriteByte(c) 47 } 48 49 func getchar() byte { 50 for machine.Serial.Buffered() == 0 { 51 Gosched() 52 } 53 v, _ := machine.Serial.ReadByte() 54 return v 55 } 56 57 func buffered() int { 58 return machine.Serial.Buffered() 59 } 60 61 func initCLK() { 62 // PWR_CLK_ENABLE 63 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_PWREN) 64 _ = stm32.RCC.APB1ENR1.Get() 65 66 // Disable Backup domain protection 67 if !stm32.PWR.CR1.HasBits(stm32.PWR_CR1_DBP) { 68 stm32.PWR.CR1.SetBits(stm32.PWR_CR1_DBP) 69 for !stm32.PWR.CR1.HasBits(stm32.PWR_CR1_DBP) { 70 } 71 } 72 73 // Set LSE Drive to LOW 74 stm32.RCC.BDCR.ReplaceBits(0, stm32.RCC_BDCR_LSEDRV_Msk, 0) 75 76 // Initialize the High-Speed External Oscillator 77 initOsc() 78 79 // PWR_VOLTAGESCALING_CONFIG 80 stm32.PWR.CR1.ReplaceBits(0, stm32.PWR_CR1_VOS_Msk, 0) 81 _ = stm32.PWR.CR1.Get() 82 83 // Set flash wait states (min 5 latency units) based on clock 84 if (stm32.FLASH.ACR.Get() & 0xF) < 5 { 85 stm32.FLASH.ACR.ReplaceBits(5, 0xF, 0) 86 } 87 88 // Ensure HCLK does not exceed max during transition 89 stm32.RCC.CFGR.ReplaceBits(8<<stm32.RCC_CFGR_HPRE_Pos, stm32.RCC_CFGR_HPRE_Msk, 0) 90 91 // Set SYSCLK source and wait 92 // (3 = RCC_SYSCLKSOURCE_PLLCLK, 2=RCC_CFGR_SWS_Pos) 93 stm32.RCC.CFGR.ReplaceBits(3, stm32.RCC_CFGR_SW_Msk, 0) 94 for stm32.RCC.CFGR.Get()&(3<<2) != (3 << 2) { 95 } 96 97 // Set HCLK 98 // (0 = RCC_SYSCLKSOURCE_PLLCLK) 99 stm32.RCC.CFGR.ReplaceBits(0, stm32.RCC_CFGR_HPRE_Msk, 0) 100 101 // Set flash wait states (max 5 latency units) based on clock 102 if (stm32.FLASH.ACR.Get() & 0xF) > 5 { 103 stm32.FLASH.ACR.ReplaceBits(5, 0xF, 0) 104 } 105 106 // Set APB1 and APB2 clocks (0 = DIV1) 107 stm32.RCC.CFGR.ReplaceBits(0, stm32.RCC_CFGR_PPRE1_Msk, 0) 108 stm32.RCC.CFGR.ReplaceBits(0, stm32.RCC_CFGR_PPRE2_Msk, 0) 109 } 110 111 func initOsc() { 112 sysclkSource := stm32.RCC.CFGR.Get() & stm32.RCC_CFGR_SWS_Msk 113 pllConfig := stm32.RCC.PLLCFGR.Get() & stm32.RCC_PLLCFGR_PLLSRC_Msk 114 115 // Enable MSI, adjusting flash latency 116 if sysclkSource == RCC_CFGR_SWS_MSI || 117 (sysclkSource == RCC_CFGR_SWS_PLL && pllConfig == RCC_PLLSOURCE_MSI) { 118 if MSIRANGE > getMSIRange() { 119 setFlashLatencyFromMSIRange(MSIRANGE) 120 121 setMSIFreq(MSIRANGE, 0) 122 } else { 123 setMSIFreq(MSIRANGE, 0) 124 125 if sysclkSource == RCC_CFGR_SWS_MSI { 126 setFlashLatencyFromMSIRange(MSIRANGE) 127 } 128 } 129 } else { 130 stm32.RCC.CR.SetBits(stm32.RCC_CR_MSION) 131 for !stm32.RCC.CR.HasBits(stm32.RCC_CR_MSIRDY) { 132 } 133 134 setMSIFreq(MSIRANGE, 0) 135 } 136 137 // Enable LSE, wait until ready 138 stm32.RCC.BDCR.SetBits(stm32.RCC_BDCR_LSEON) 139 for !stm32.RCC.BDCR.HasBits(stm32.RCC_BDCR_LSEON) { 140 } 141 142 // Disable the PLL, wait until disabled 143 stm32.RCC.CR.ClearBits(stm32.RCC_CR_PLLON) 144 for stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) { 145 } 146 147 // Configure the PLL 148 stm32.RCC.PLLCFGR.ReplaceBits( 149 (1)| // 1 = RCC_PLLSOURCE_MSI 150 (PLL_M-1)<<stm32.RCC_PLLCFGR_PLLM_Pos| 151 (PLL_N<<stm32.RCC_PLLCFGR_PLLN_Pos)| 152 (((PLL_Q>>1)-1)<<stm32.RCC_PLLCFGR_PLLQ_Pos)| 153 (((PLL_R>>1)-1)<<stm32.RCC_PLLCFGR_PLLR_Pos)| 154 (PLL_P<<stm32.RCC_PLLCFGR_PLLP_Pos), 155 stm32.RCC_PLLCFGR_PLLSRC_Msk|stm32.RCC_PLLCFGR_PLLM_Msk| 156 stm32.RCC_PLLCFGR_PLLN_Msk|stm32.RCC_PLLCFGR_PLLP_Msk| 157 stm32.RCC_PLLCFGR_PLLR_Msk|stm32.RCC_PLLCFGR_PLLP_Msk, 158 0) 159 160 // Enable the PLL and PLL System Clock Output, wait until ready 161 stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON) 162 stm32.RCC.PLLCFGR.SetBits(stm32.RCC_PLLCFGR_PLLREN) // = RCC_PLL_SYSCLK 163 for !stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) { 164 } 165 166 // Enable system clock output 167 stm32.RCC.PLLCFGR.SetBits(RCC_PLL_SYSCLK) 168 } 169 170 func getMSIRange() uint32 { 171 if stm32.RCC.CR.HasBits(stm32.RCC_CR_MSIRGSEL) { 172 return (stm32.RCC.CR.Get() & stm32.RCC_CR_MSIRANGE_Msk) >> stm32.RCC_CR_MSIRANGE_Pos 173 } 174 175 return (stm32.RCC.CSR.Get() & stm32.RCC_CSR_MSISRANGE_Msk) >> stm32.RCC_CSR_MSISRANGE_Pos 176 } 177 178 func setMSIFreq(r uint32, calibration uint32) { 179 stm32.RCC.CR.SetBits(stm32.RCC_CR_MSIRGSEL) 180 stm32.RCC.CR.ReplaceBits(r<<stm32.RCC_CR_MSIRANGE_Pos, stm32.RCC_CR_MSIRANGE_Msk, 0) 181 182 stm32.RCC.ICSCR.ReplaceBits(calibration<<stm32.RCC_ICSCR_MSITRIM_Pos, stm32.RCC_ICSCR_MSITRIM_Msk, 0) 183 } 184 185 func setFlashLatencyFromMSIRange(r uint32) { 186 var vos uint32 187 if pwrIsClkEnabled() { 188 vos = pwrExGetVoltageRange() 189 } else { 190 pwrClkEnable() 191 vos = pwrExGetVoltageRange() 192 pwrClkDisable() 193 } 194 195 latency := uint32(FLASH_LATENCY_0) 196 if vos == PWR_REGULATOR_VOLTAGE_SCALE1 { 197 if r > stm32.RCC_CR_MSIRANGE_Range16M { 198 if r > stm32.RCC_CR_MSIRANGE_Range32M { 199 latency = FLASH_LATENCY_2 200 } else { 201 latency = FLASH_LATENCY_1 202 } 203 } 204 } else if r > stm32.RCC_CR_MSIRANGE_Range16M { 205 latency = FLASH_LATENCY_3 206 } else { 207 if r == stm32.RCC_CR_MSIRANGE_Range16M { 208 latency = FLASH_LATENCY_2 209 } else if r == stm32.RCC_CR_MSIRANGE_Range8M { 210 latency = FLASH_LATENCY_1 211 } 212 } 213 214 stm32.FLASH.ACR.ReplaceBits(latency, stm32.Flash_ACR_LATENCY_Msk, 0) 215 } 216 217 func pwrIsClkEnabled() bool { 218 return stm32.RCC.APB1ENR1.HasBits(stm32.RCC_APB1ENR1_PWREN) 219 } 220 221 func pwrClkEnable() { 222 stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_PWREN) 223 } 224 func pwrClkDisable() { 225 stm32.RCC.APB1ENR1.ClearBits(stm32.RCC_APB1ENR1_PWREN) 226 } 227 228 func pwrExGetVoltageRange() uint32 { 229 return stm32.PWR.CR1.Get() & stm32.PWR_CR1_VOS_Msk 230 }