98 строки
2,5 КиБ
Go
98 строки
2,5 КиБ
Go
//go:build stm32f4 && (stm32f407 || stm32f469)
|
|
|
|
package runtime
|
|
|
|
import (
|
|
"device/stm32"
|
|
"machine"
|
|
)
|
|
|
|
func init() {
|
|
initCLK()
|
|
|
|
machine.InitSerial()
|
|
|
|
initTickTimer(&machine.TIM2)
|
|
}
|
|
|
|
func putchar(c byte) {
|
|
machine.Serial.WriteByte(c)
|
|
}
|
|
|
|
func getchar() byte {
|
|
for machine.Serial.Buffered() == 0 {
|
|
Gosched()
|
|
}
|
|
v, _ := machine.Serial.ReadByte()
|
|
return v
|
|
}
|
|
|
|
func buffered() int {
|
|
return machine.Serial.Buffered()
|
|
}
|
|
|
|
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)
|
|
}
|