Add stm32g0b1 support (#5150)

* Add STM32G0B1 target support

Introduce support for STM32G0B1 microcontrollers, including target-specific JSON files, linker scripts, and runtime initialization. This update adds hardware support for GPIO, UART, SPI, I2C, timers, and additional board-specific configurations like Nucleo-G0B1RE.

* Update STM32G0 clock initialization to 64MHz and adjust related configurations

Reconfigure STM32G0 to use a 64MHz system clock via PLL with HSI16 as the source. Update flash latency, prescaler settings, and I2C timing values to reflect the new frequency.

* Cleanup

* Cleanup

* Add STM32G0-specific UART implementation

Introduce a new UART implementation for the STM32G0 series with chip-specific setup and configuration methods. Update the generic STM32 UART code to exclude STM32G0.

* Refactor STM32G0 runtime and machine code to utilize chip-specific register access functions

Simplify and standardize register operations with dedicated setter methods in the STM32G0 runtime and machine code and cleanup redundant syntax.

* Remove redundant commented-out APBENR1 register operations in STM32G0 machine code

* Introduce FDCAN support for STM32G0B1 series

Add FDCAN peripheral implementation targeting STM32G0B1, including support for standard, extended identifiers, and bit rate configuration. Update board files to include FDCAN pins, instances, and clock configuration for Nucleo-G0B1RE and Amken Trio boards.
This commit is contained in:
Amken USA
2026-01-06 17:12:02 -05:00
committed by GitHub
parent 9bcca974ba
commit cfd74c2954
23 changed files with 2021 additions and 9 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build baremetal && (nrf || (stm32 && !(stm32f103 || stm32l0x1)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3 || tkey || (tinygo.riscv32 && virt) || rp2040 || rp2350)
//go:build baremetal && (nrf || (stm32 && !(stm32f103 || stm32l0x1 || stm32g0)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3 || tkey || (tinygo.riscv32 && virt) || rp2040 || rp2350)
// If you update the above build constraint, you'll probably also need to update
// src/crypto/rand/rand_baremetal.go.
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build baremetal && !(nrf || (stm32 && !(stm32f103 || stm32l0x1)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3 || tkey || (tinygo.riscv32 && virt) || rp2040 || rp2350)
//go:build baremetal && !(nrf || (stm32 && !(stm32f103 || stm32l0x1 || stm32g0)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3 || tkey || (tinygo.riscv32 && virt) || rp2040 || rp2350)
package runtime
+97
View File
@@ -0,0 +1,97 @@
//go:build stm32g0
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 64MHz using PLL with HSI16 as source
// PLL configuration: HSI16 (16MHz) / PLLM(1) * PLLN(8) / PLLR(2) = 64MHz
// Enable PWR clock
stm32.RCC.SetAPBENR1_PWREN(1)
// Read back to ensure the write is complete (memory barrier)
_ = stm32.RCC.APBENR1.Get()
// Set Power Regulator to enable max performance (Range 1)
// VOS = 01 for Range 1 (high performance, up to 64 MHz)
stm32.PWR.SetCR1_VOS(1)
// Wait for voltage scaling to be ready (VOSF = 0 means ready)
for stm32.PWR.SR2.HasBits(stm32.PWR_SR2_VOSF) {
}
// Enable HSI16
stm32.RCC.SetCR_HSION(1)
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSIRDY) {
}
// Set HSI16 division factor to 1 (no division) - HSIDIV = 000
stm32.RCC.SetCR_HSIDIV(0)
// Disable PLL before configuration
stm32.RCC.SetCR_PLLON(0)
for stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
}
// Configure PLL: HSI16 / 1 * 8 / 2 = 64 MHz
// PLLSRC = HSI16 (2)
// PLLM = 0 (divide by 1)
// PLLN = 8 (multiply by 8) -> VCO = 16 * 8 = 128 MHz
// PLLR = 0 (divide by 2) -> SYSCLK = 128 / 2 = 64 MHz
// PLLREN = 1 (enable R output for SYSCLK)
const (
PLLSRC_HSI16 = 2 // HSI16 as PLL source
PLLM_DIV1 = 0 // /1
PLLN_MUL8 = 8 // *8
PLLR_DIV2 = 0 // /2 (0 = divide by 2)
)
stm32.RCC.PLLCFGR.Set(
(PLLSRC_HSI16 << stm32.RCC_PLLCFGR_PLLSRC_Pos) |
(PLLM_DIV1 << stm32.RCC_PLLCFGR_PLLM_Pos) |
(PLLN_MUL8 << stm32.RCC_PLLCFGR_PLLN_Pos) |
(PLLR_DIV2 << stm32.RCC_PLLCFGR_PLLR_Pos) |
stm32.RCC_PLLCFGR_PLLREN) // Enable PLLR output
// Enable PLL
stm32.RCC.SetCR_PLLON(1)
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
}
// Set flash latency to 2 wait states (required for 64MHz in Range 1)
// Must be set BEFORE switching to higher frequency clock
const FLASH_LATENCY_2 = 2
stm32.FLASH.SetACR_LATENCY(FLASH_LATENCY_2)
for (stm32.FLASH.ACR.Get() & stm32.Flash_ACR_LATENCY_Msk) != FLASH_LATENCY_2 {
}
// Set AHB prescaler to 1 (no division)
stm32.RCC.SetCFGR_HPRE(0)
// Set APB prescaler to 1 (no division)
stm32.RCC.SetCFGR_PPRE(0)
// Switch system clock to PLL (SW = 010)
const RCC_CFGR_SW_PLL = 2
stm32.RCC.SetCFGR_SW(RCC_CFGR_SW_PLL)
// Wait for PLL to be used as system clock (SWS = 010)
for (stm32.RCC.CFGR.Get() & stm32.RCC_CFGR_SWS_Msk) != (RCC_CFGR_SW_PLL << stm32.RCC_CFGR_SWS_Pos) {
}
}
+15
View File
@@ -0,0 +1,15 @@
//go:build stm32g0b1
package runtime
import (
"machine"
)
func init() {
initCLK()
machine.InitSerial()
initTickTimer(&machine.TIM3)
}