mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-09 05:23:40 +00:00
feat(machine/stm32): make HSE crystal frequency selectable.
Define the board's external crystal (HSE) frequency `xtalHz` in the respective `board_*.go` files. Per-topology PLL tables (F1, F4, F7) will compute the register dividers from it. Moving this parameter to the board definition level cleanly isolates board hardware characteristics from general MCU chip configurations, eliminating the need for custom target build tags. Targets using HSE-clocked STM32 chips must define `xtalHz` or fail to build.
This commit is contained in:
committed by
Ron Evans
parent
b8adb803c4
commit
5f02d6b659
@@ -31,8 +31,10 @@ func buffered() int {
|
||||
return machine.Serial.Buffered()
|
||||
}
|
||||
|
||||
// initCLK sets clock to 72MHz using HSE 8MHz crystal w/ PLL X 9 (8MHz x 9 = 72MHz).
|
||||
// initCLK sets clock to 72MHz using the board's HSE crystal (defined by the xtalHz) w/ PLL.
|
||||
func initCLK() {
|
||||
pll := machine.PLLParams72MHz()
|
||||
|
||||
stm32.FLASH.ACR.SetBits(stm32.FLASH_ACR_LATENCY_WS2) // Two wait states, per datasheet
|
||||
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE1_Div2 << stm32.RCC_CFGR_PPRE1_Pos) // prescale PCLK1 = HCLK/2
|
||||
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE2_Div1 << stm32.RCC_CFGR_PPRE2_Pos) // prescale PCLK2 = HCLK/1
|
||||
@@ -49,9 +51,10 @@ func initCLK() {
|
||||
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSIRDY) {
|
||||
}
|
||||
|
||||
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PLLSRC) // set PLL source to HSE
|
||||
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PLLMUL_Mul9 << stm32.RCC_CFGR_PLLMUL_Pos) // multiply by 9
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON) // enable the PLL
|
||||
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PLLSRC) // set PLL source to HSE
|
||||
stm32.RCC.CFGR.SetBits(pll.Prediv << stm32.RCC_CFGR_PLLXTPRE_Pos) // optional HSE /2 prescaler
|
||||
stm32.RCC.CFGR.SetBits(pll.Mul << stm32.RCC_CFGR_PLLMUL_Pos) // PLL multiplier
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON) // enable the PLL
|
||||
|
||||
// wait for the PLLRDY flag
|
||||
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
|
||||
|
||||
@@ -73,7 +73,7 @@ func initCLK() {
|
||||
// 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)
|
||||
stm32.RCC.PLLCFGR.Set(pllCFGR())
|
||||
// Enable main PLL
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON)
|
||||
// Wait till the main PLL is ready
|
||||
|
||||
@@ -8,15 +8,15 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// +----------------------+
|
||||
// | Clock Settings |
|
||||
// +-------------+--------+
|
||||
// | HSE | 12mhz |
|
||||
// | SYSCLK | 168mhz |
|
||||
// | HCLK | 168mhz |
|
||||
// | APB1(PCLK1) | 42mhz |
|
||||
// | APB2(PCLK2) | 84mhz |
|
||||
// +-------------+--------+
|
||||
// +---------------------------------------------+
|
||||
// | Clock Settings |
|
||||
// +-------------+-------------------------------+
|
||||
// | HSE | selectable (xtal_8/12/16_mhz) |
|
||||
// | SYSCLK | 168mhz |
|
||||
// | HCLK | 168mhz |
|
||||
// | APB1(PCLK1) | 42mhz |
|
||||
// | APB2(PCLK2) | 84mhz |
|
||||
// +-------------+-------------------------------+
|
||||
HCLK_FREQ_HZ = 168000000
|
||||
PCLK1_FREQ_HZ = HCLK_FREQ_HZ / 4
|
||||
PCLK2_FREQ_HZ = HCLK_FREQ_HZ / 2
|
||||
@@ -29,11 +29,6 @@ const (
|
||||
PLL_SRC_HSE = 1 << stm32.RCC_PLLCFGR_PLLSRC_Pos // use HSE for PLL and PLLI2S
|
||||
PLL_SRC_HSI = 0 // use HSI for PLL and PLLI2S
|
||||
|
||||
PLL_DIV_M = 6 << stm32.RCC_PLLCFGR_PLLM_Pos
|
||||
PLL_MLT_N = 168 << stm32.RCC_PLLCFGR_PLLN_Pos
|
||||
PLL_DIV_P = ((2 >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP_Pos
|
||||
PLL_DIV_Q = 7 << stm32.RCC_PLLCFGR_PLLQ_Pos
|
||||
|
||||
SYSCLK_SRC_PLL = stm32.RCC_CFGR_SW_PLL << stm32.RCC_CFGR_SW_Pos
|
||||
SYSCLK_STAT_PLL = stm32.RCC_CFGR_SWS_PLL << stm32.RCC_CFGR_SWS_Pos
|
||||
|
||||
@@ -94,7 +89,12 @@ func initOSC() {
|
||||
}
|
||||
|
||||
// set HSE as PLL source and configure clock divisors
|
||||
stm32.RCC.PLLCFGR.Set(PLL_SRC_HSE | PLL_DIV_M | PLL_MLT_N | PLL_DIV_P | PLL_DIV_Q)
|
||||
pll := machine.PLLParams168MHz()
|
||||
stm32.RCC.PLLCFGR.Set(PLL_SRC_HSE |
|
||||
pll.M<<stm32.RCC_PLLCFGR_PLLM_Pos |
|
||||
pll.N<<stm32.RCC_PLLCFGR_PLLN_Pos |
|
||||
((pll.P>>1)-1)<<stm32.RCC_PLLCFGR_PLLP_Pos |
|
||||
pll.Q<<stm32.RCC_PLLCFGR_PLLQ_Pos)
|
||||
|
||||
// enable PLL and wait for it to sync
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON)
|
||||
|
||||
@@ -2,26 +2,28 @@
|
||||
|
||||
package runtime
|
||||
|
||||
import "device/stm32"
|
||||
import (
|
||||
"device/stm32"
|
||||
"machine"
|
||||
)
|
||||
|
||||
/*
|
||||
clock settings
|
||||
|
||||
+-------------+--------+
|
||||
| HSE | 8mhz |
|
||||
| SYSCLK | 168mhz |
|
||||
| HCLK | 168mhz |
|
||||
| APB2(PCLK2) | 84mhz |
|
||||
| APB1(PCLK1) | 42mhz |
|
||||
+-------------+--------+
|
||||
+-------------+--------------------------------+
|
||||
| HSE | selectable (xtal_8/12/16_mhz) |
|
||||
| SYSCLK | 168mhz |
|
||||
| HCLK | 168mhz |
|
||||
| APB2(PCLK2) | 84mhz |
|
||||
| APB1(PCLK1) | 42mhz |
|
||||
+-------------+--------------------------------+
|
||||
*/
|
||||
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_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)
|
||||
)
|
||||
const HSE_STARTUP_TIMEOUT = 0x0500
|
||||
|
||||
// pllCFGR builds the RCC_PLLCFGR value for the current xtal - see RM0090
|
||||
// Reference Manual pg. 95.
|
||||
func pllCFGR() uint32 {
|
||||
pll := machine.PLLParams168MHz()
|
||||
return 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)
|
||||
}
|
||||
|
||||
@@ -2,27 +2,28 @@
|
||||
|
||||
package runtime
|
||||
|
||||
import "device/stm32"
|
||||
import (
|
||||
"device/stm32"
|
||||
"machine"
|
||||
)
|
||||
|
||||
/*
|
||||
clock settings
|
||||
|
||||
+-------------+--------+
|
||||
| HSE | 8mhz |
|
||||
| SYSCLK | 180mhz |
|
||||
| HCLK | 180mhz |
|
||||
| APB2(PCLK2) | 90mhz |
|
||||
| APB1(PCLK1) | 45mhz |
|
||||
+-------------+--------+
|
||||
+-------------+--------------------------------+
|
||||
| HSE | selectable (xtal_8/12/16_mhz) |
|
||||
| SYSCLK | 180mhz |
|
||||
| HCLK | 180mhz |
|
||||
| APB2(PCLK2) | 90mhz |
|
||||
| APB1(PCLK1) | 45mhz |
|
||||
+-------------+--------------------------------+
|
||||
*/
|
||||
const (
|
||||
HSE_STARTUP_TIMEOUT = 0x0500
|
||||
// PLL Options - See RM0386 Reference Manual pg. 148
|
||||
PLL_M = 8 // PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
|
||||
PLL_N = 360
|
||||
PLL_P = 2 // SYSCLK = PLL_VCO / PLL_P
|
||||
PLL_Q = 7 // USB OTS FS, SDIO and RNG Clock = PLL_VCO / PLL_Q
|
||||
PLL_R = 6 // DSI
|
||||
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) | (PLL_R << stm32.RCC_PLLCFGR_PLLR_Pos)
|
||||
)
|
||||
const HSE_STARTUP_TIMEOUT = 0x0500
|
||||
|
||||
// pllCFGR builds the RCC_PLLCFGR value for the current xtal - see RM0386
|
||||
// Reference Manual pg. 148.
|
||||
func pllCFGR() uint32 {
|
||||
pll := machine.PLLParams180MHz()
|
||||
return 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) | (pll.R << stm32.RCC_PLLCFGR_PLLR_Pos)
|
||||
}
|
||||
|
||||
@@ -10,21 +10,15 @@ import (
|
||||
/*
|
||||
clock settings
|
||||
|
||||
+-------------+--------+
|
||||
| HSE | 8mhz |
|
||||
| SYSCLK | 216mhz |
|
||||
| HCLK | 216mhz |
|
||||
| APB1(PCLK1) | 27mhz |
|
||||
| APB2(PCLK2) | 108mhz |
|
||||
+-------------+--------+
|
||||
+-------------+--------------------------------+
|
||||
| HSE | selectable (xtal_8/12/16_mhz) |
|
||||
| SYSCLK | 216mhz |
|
||||
| HCLK | 216mhz |
|
||||
| APB1(PCLK1) | 27mhz |
|
||||
| APB2(PCLK2) | 108mhz |
|
||||
+-------------+--------------------------------+
|
||||
*/
|
||||
const (
|
||||
HSE_STARTUP_TIMEOUT = 0x0500
|
||||
PLL_M = 4
|
||||
PLL_N = 216
|
||||
PLL_P = 2
|
||||
PLL_Q = 9
|
||||
)
|
||||
const HSE_STARTUP_TIMEOUT = 0x0500
|
||||
|
||||
func init() {
|
||||
initCLK()
|
||||
@@ -107,12 +101,13 @@ func initOsc() {
|
||||
}
|
||||
|
||||
// Configure the PLL: HSE as source, use SVD constants for positions.
|
||||
pll := machine.PLLParams216MHz()
|
||||
stm32.RCC.PLLCFGR.Set(
|
||||
(stm32.RCC_PLLCFGR_PLLSRC_HSE << stm32.RCC_PLLCFGR_PLLSRC_Pos) |
|
||||
(PLL_M << stm32.RCC_PLLCFGR_PLLM_Pos) |
|
||||
(PLL_N << stm32.RCC_PLLCFGR_PLLN_Pos) |
|
||||
(((PLL_P >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP_Pos) |
|
||||
(PLL_Q << stm32.RCC_PLLCFGR_PLLQ_Pos))
|
||||
(pll.M << stm32.RCC_PLLCFGR_PLLM_Pos) |
|
||||
(pll.N << stm32.RCC_PLLCFGR_PLLN_Pos) |
|
||||
(((pll.P >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP_Pos) |
|
||||
(pll.Q << stm32.RCC_PLLCFGR_PLLQ_Pos))
|
||||
|
||||
// Enable the PLL, wait until ready
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON)
|
||||
|
||||
Reference in New Issue
Block a user