mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 06:38:42 +00:00
machine/stm32: add STM32U585 target definition and runtime
Add processor target (cortex-m33), linker script (2048K flash, 768K RAM), and arduino-uno-q board target. Runtime initializes 160MHz clock via PLL1 from HSI16, with PWR Range 1 and EPOD booster. Also add psctype abstraction for timer PSC register width, needed because the U5 SVD defines PSC as a 16-bit register.
This commit is contained in:
@@ -150,7 +150,7 @@ func (t *TIM) setPeriod(period uint64, updatePrescaler bool) error {
|
||||
psc = ceil(top, ARR_MAX)
|
||||
top = top / psc
|
||||
|
||||
t.Device.PSC.Set(uint32(psc - 1))
|
||||
t.Device.PSC.Set(psctype(psc - 1))
|
||||
} else {
|
||||
psc = uint64(t.Device.PSC.Get()) + 1
|
||||
top = top / psc
|
||||
|
||||
@@ -731,6 +731,7 @@ func (t *TIM) enableMainOutput() {
|
||||
}
|
||||
|
||||
type arrtype = uint32
|
||||
type psctype = uint32
|
||||
type arrRegType = volatile.Register32
|
||||
|
||||
const (
|
||||
|
||||
@@ -607,6 +607,7 @@ func (t *TIM) enableMainOutput() {
|
||||
}
|
||||
|
||||
type arrtype = uint32
|
||||
type psctype = uint32
|
||||
type arrRegType = volatile.Register32
|
||||
|
||||
const (
|
||||
|
||||
@@ -712,6 +712,7 @@ func (t *TIM) enableMainOutput() {
|
||||
}
|
||||
|
||||
type arrtype = uint32
|
||||
type psctype = uint32
|
||||
type arrRegType = volatile.Register32
|
||||
|
||||
const (
|
||||
|
||||
@@ -554,6 +554,7 @@ func (t *TIM) enableMainOutput() {
|
||||
}
|
||||
|
||||
type arrtype = uint32
|
||||
type psctype = uint32
|
||||
type arrRegType = volatile.Register32
|
||||
|
||||
const (
|
||||
|
||||
@@ -189,6 +189,7 @@ func (t *TIM) enableMainOutput() {
|
||||
}
|
||||
|
||||
type arrtype = uint32
|
||||
type psctype = uint32
|
||||
type arrRegType = volatile.Register32
|
||||
|
||||
const (
|
||||
|
||||
@@ -246,6 +246,7 @@ func (t *TIM) enableMainOutput() {
|
||||
}
|
||||
|
||||
type arrtype = uint32
|
||||
type psctype = uint32
|
||||
type arrRegType = volatile.Register32
|
||||
|
||||
const (
|
||||
|
||||
@@ -532,6 +532,7 @@ func (t *TIM) enableMainOutput() {
|
||||
}
|
||||
|
||||
type arrtype = uint32
|
||||
type psctype = uint32
|
||||
type arrRegType = volatile.Register32
|
||||
|
||||
const (
|
||||
|
||||
@@ -542,6 +542,7 @@ func (t *TIM) enableMainOutput() {
|
||||
}
|
||||
|
||||
type arrtype = uint32
|
||||
type psctype = uint32
|
||||
type arrRegType = volatile.Register32
|
||||
|
||||
const (
|
||||
|
||||
@@ -433,6 +433,7 @@ func initRNG() {
|
||||
//----------
|
||||
|
||||
type arrtype = uint32
|
||||
type psctype = uint32
|
||||
type arrRegType = volatile.Register32
|
||||
|
||||
const (
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
//go:build stm32u5
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
"machine"
|
||||
)
|
||||
|
||||
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() {
|
||||
// Initialize clock to 160MHz using PLL1 with HSI16 as source.
|
||||
// PLL1 configuration: HSI16 (16MHz) / PLLM(1) * PLLN(10) / PLLR(1) = 160MHz
|
||||
// VCO = 16 * 10 = 160MHz, PLLR = /1 -> 160MHz SYSCLK
|
||||
|
||||
// Enable PWR clock
|
||||
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_CRSEN) // CRS enable not needed but ensures APB1 is clocked
|
||||
_ = stm32.RCC.APB1ENR1.Get()
|
||||
|
||||
// Set voltage scaling to Range 1 for 160MHz operation
|
||||
// On U5, voltage scaling is in PWR.VOSR register
|
||||
// VOS = 11 (Range 1, up to 160MHz)
|
||||
stm32.PWR.VOSR.ReplaceBits(stm32.PWR_VOSR_VOS_Range1, stm32.PWR_VOSR_VOS_Msk, 0)
|
||||
// Wait for VOS ready
|
||||
for !stm32.PWR.VOSR.HasBits(stm32.PWR_VOSR_VOSRDY) {
|
||||
}
|
||||
|
||||
// Enable EPOD booster for high performance (required for Range 1 >100MHz)
|
||||
stm32.PWR.VOSR.SetBits(stm32.PWR_VOSR_BOOSTEN)
|
||||
for !stm32.PWR.VOSR.HasBits(stm32.PWR_VOSR_BOOSTRDY) {
|
||||
}
|
||||
|
||||
// Enable HSI16
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_HSION)
|
||||
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSIRDY) {
|
||||
}
|
||||
|
||||
// Disable PLL1 before configuration
|
||||
stm32.RCC.CR.ClearBits(stm32.RCC_CR_PLL1ON)
|
||||
for stm32.RCC.CR.HasBits(stm32.RCC_CR_PLL1RDY) {
|
||||
}
|
||||
|
||||
// Configure PLL1:
|
||||
// Source = HSI16 (0x2)
|
||||
// PLLM = 0 (divide by 1)
|
||||
// PLL1RGE = 0x3 (input range 8-16MHz)
|
||||
// Enable PLLR output
|
||||
stm32.RCC.PLL1CFGR.Set(
|
||||
(stm32.RCC_PLL1CFGR_PLL1SRC_HSI16 << stm32.RCC_PLL1CFGR_PLL1SRC_Pos) |
|
||||
(stm32.RCC_PLL1CFGR_PLL1M_Div1 << stm32.RCC_PLL1CFGR_PLL1M_Pos) |
|
||||
(stm32.RCC_PLL1CFGR_PLL1RGE_Range2 << stm32.RCC_PLL1CFGR_PLL1RGE_Pos))
|
||||
|
||||
// Enable PLL1R output
|
||||
stm32.RCC.PLL1CFGR.SetBits(1 << stm32.RCC_PLL1CFGR_PLL1REN_Pos)
|
||||
|
||||
// Set PLL1 dividers in PLL1DIVR:
|
||||
// PLL1N = 10 (value - 1 = 9 in register)
|
||||
// PLL1R = 1 (value - 1 = 0 in register)
|
||||
// VCO = HSI16/1 * 10 = 160MHz
|
||||
// PLLR output = 160MHz / 1 = 160MHz
|
||||
stm32.RCC.SetPLL1DIVR_PLL1N(9) // N = 10, register value = N-1 = 9
|
||||
stm32.RCC.SetPLL1DIVR_PLL1R(0) // R = 1, register value = R-1 = 0
|
||||
|
||||
// Enable PLL1
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLL1ON)
|
||||
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_PLL1RDY) {
|
||||
}
|
||||
|
||||
// Set flash latency to 4 wait states (required for 160MHz in Range 1)
|
||||
const FLASH_LATENCY_4 = 4
|
||||
stm32.FLASH.ACR.ReplaceBits(FLASH_LATENCY_4, stm32.Flash_ACR_LATENCY_Msk, 0)
|
||||
for (stm32.FLASH.ACR.Get() & stm32.Flash_ACR_LATENCY_Msk) != FLASH_LATENCY_4 {
|
||||
}
|
||||
|
||||
// Set AHB prescaler to 1 (no division) in CFGR2
|
||||
stm32.RCC.CFGR2.ReplaceBits(stm32.RCC_CFGR2_HPRE_Div1, stm32.RCC_CFGR2_HPRE_Msk, 0)
|
||||
|
||||
// Set APB1 and APB2 prescalers to 1 (no division) in CFGR2
|
||||
stm32.RCC.CFGR2.ReplaceBits(stm32.RCC_CFGR2_PPRE1_Div1, stm32.RCC_CFGR2_PPRE1_Msk, 0)
|
||||
stm32.RCC.CFGR2.ReplaceBits(stm32.RCC_CFGR2_PPRE2_Div1, stm32.RCC_CFGR2_PPRE2_Msk, 0)
|
||||
|
||||
// Switch system clock to PLL1 (SW = 11 = PLL)
|
||||
stm32.RCC.CFGR1.ReplaceBits(stm32.RCC_CFGR1_SW_PLL, stm32.RCC_CFGR1_SW_Msk, 0)
|
||||
for (stm32.RCC.CFGR1.Get() & stm32.RCC_CFGR1_SWS_Msk) != (stm32.RCC_CFGR1_SWS_PLL << stm32.RCC_CFGR1_SWS_Pos) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
//go:build stm32u585
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"machine"
|
||||
)
|
||||
|
||||
func init() {
|
||||
initCLK()
|
||||
|
||||
machine.InitSerial()
|
||||
|
||||
initTickTimer(&machine.TIM16)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"inherits": ["stm32u585"],
|
||||
"build-tags": ["arduino_uno_q"],
|
||||
"serial": "uart",
|
||||
"openocd-interface": "stlink",
|
||||
"openocd-target": "stm32u5x"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"inherits": [
|
||||
"cortex-m33"
|
||||
],
|
||||
"build-tags": [
|
||||
"stm32u585",
|
||||
"stm32u5",
|
||||
"stm32"
|
||||
],
|
||||
"extra-files": [
|
||||
"src/device/stm32/stm32u585.s"
|
||||
],
|
||||
"linkerscript": "targets/stm32u585.ld",
|
||||
"flash-method": "openocd",
|
||||
"openocd-target": "stm32u5x"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH_TEXT (rw) : ORIGIN = 0x08000000, LENGTH = 2048K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 768K
|
||||
}
|
||||
|
||||
_stack_size = 4K;
|
||||
|
||||
INCLUDE "targets/arm.ld"
|
||||
Reference in New Issue
Block a user