stm32: add nucleo-l031k6 support

Adds i2c for all L0 series

UART, Blinky (LED) and i2c tested
This commit is contained in:
Kenneth Bell
2021-03-22 18:14:28 -07:00
committed by Ron Evans
parent c246978dd7
commit a30671751f
14 changed files with 389 additions and 95 deletions
+47 -46
View File
@@ -1,4 +1,4 @@
// +build stm32,stm32l0
// +build stm32l0
package runtime
@@ -7,68 +7,48 @@ import (
"machine"
)
/*
timer settings used for tick and sleep.
note: TICK_TIMER_FREQ and SLEEP_TIMER_FREQ are controlled by PLL / clock
settings above, so must be kept in sync if the clock settings are changed.
*/
const (
TICK_RATE = 1000 // 1 KHz
TICK_TIMER_IRQ = stm32.IRQ_TIM7
TICK_TIMER_FREQ = 32000000 // 32 MHz
SLEEP_TIMER_IRQ = stm32.IRQ_TIM3
SLEEP_TIMER_FREQ = 32000000 // 32 MHz
RCC_SYSCLK_DIV1 = 0 // Needs SVD update (should be stm32.RCC_SYSCLK_DIV1)
)
type arrtype = uint16
func init() {
initCLK()
initSleepTimer(&timerInfo{
EnableRegister: &stm32.RCC.APB1ENR,
EnableFlag: stm32.RCC_APB1ENR_TIM3EN,
Device: stm32.TIM3,
})
machine.UART0.Configure(machine.UARTConfig{})
initTickTimer(&timerInfo{
EnableRegister: &stm32.RCC.APB1ENR,
EnableFlag: stm32.RCC_APB1ENR_TIM7EN,
Device: stm32.TIM7,
})
}
const asyncScheduler = false
func putchar(c byte) {
machine.UART0.WriteByte(c)
}
// initCLK sets clock to 32MHz
// SEE: https://github.com/WRansohoff/STM32x0_timer_example/blob/master/src/main.c
func initCLK() {
// Set Power Regulator to enable max performance (1.8V)
stm32.PWR.CR.ReplaceBits(1<<stm32.PWR_CR_VOS_Pos, stm32.PWR_CR_VOS_Msk, 0)
// Set the Flash ACR to use 1 wait-state
// enable the prefetch buffer and pre-read for performance
stm32.FLASH.ACR.SetBits(stm32.Flash_ACR_LATENCY | stm32.Flash_ACR_PRFTEN | stm32.Flash_ACR_PRE_READ)
// Set presaclers so half system clock (PCLKx = HCLK/2)
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE1_Div2 << stm32.RCC_CFGR_PPRE1_Pos)
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE2_Div2 << stm32.RCC_CFGR_PPRE2_Pos)
// Calibration (default 0x10)
stm32.RCC.ICSCR.ReplaceBits(0x10<<stm32.RCC_ICSCR_HSI16TRIM_Pos, stm32.RCC_ICSCR_HSI16TRIM_Msk, 0)
// Enable the HSI16 oscillator, since the L0 series boots to the MSI one.
stm32.RCC.CR.SetBits(stm32.RCC_CR_HSI16ON)
stm32.RCC.CR.ReplaceBits(stm32.RCC_CR_HSI16ON, stm32.RCC_CR_HSI16ON_Msk|stm32.RCC_CR_HSI16DIVEN_Msk, 0)
// Wait for HSI16 to be ready
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSI16RDYF) {
}
// Disable PLL
stm32.RCC.CR.ClearBits(stm32.RCC_CR_PLLON)
// Wait for PLL to be disabled
for stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
}
// Configure the PLL to use HSI16 with a PLLDIV of 2 and PLLMUL of 4.
stm32.RCC.CFGR.SetBits(0x01<<stm32.RCC_CFGR_PLLDIV_Pos | 0x01<<stm32.RCC_CFGR_PLLMUL_Pos)
stm32.RCC.CFGR.ClearBits(0x02<<stm32.RCC_CFGR_PLLDIV_Pos | 0x0E<<stm32.RCC_CFGR_PLLMUL_Pos)
stm32.RCC.CFGR.ClearBits(stm32.RCC_CFGR_PLLSRC)
stm32.RCC.CFGR.ReplaceBits(
(stm32.RCC_CFGR_PLLSRC_HSI16<<stm32.RCC_CFGR_PLLSRC_Pos)|
(stm32.RCC_CFGR_PLLMUL_Mul4<<stm32.RCC_CFGR_PLLMUL_Pos)|
(stm32.RCC_CFGR_PLLDIV_Div2<<stm32.RCC_CFGR_PLLDIV_Pos),
stm32.RCC_CFGR_PLLSRC_Msk|
stm32.RCC_CFGR_PLLMUL_Msk|
stm32.RCC_CFGR_PLLDIV_Msk,
0)
// Enable PLL
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON)
@@ -77,9 +57,30 @@ func initCLK() {
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
}
// Use PLL As System clock
stm32.RCC.CFGR.SetBits(0x3)
// Adjust flash latency
if FlashLatency > getFlashLatency() {
setFlashLatency(FlashLatency)
for getFlashLatency() != FlashLatency {
}
}
// HCLK
stm32.RCC.CFGR.ReplaceBits(RCC_SYSCLK_DIV1, stm32.RCC_CFGR_HPRE_Msk, 0)
// Use PLL As System clock
stm32.RCC.CFGR.ReplaceBits(stm32.RCC_CFGR_SWS_PLL, stm32.RCC_CFGR_SW_Msk, 0)
for stm32.RCC.CFGR.Get()&stm32.RCC_CFGR_SW_Msk != stm32.RCC_CFGR_SWS_PLL {
}
// Set prescalers so half system clock (PCLKx = HCLK/2)
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE1_Div2 << stm32.RCC_CFGR_PPRE1_Pos)
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE2_Div2 << stm32.RCC_CFGR_PPRE2_Pos)
}
const asyncScheduler = false
func getFlashLatency() uint32 {
return stm32.FLASH.ACR.Get() & stm32.Flash_ACR_LATENCY_Msk
}
func setFlashLatency(l uint32) {
stm32.FLASH.ACR.ReplaceBits(l, stm32.Flash_ACR_LATENCY_Msk, 0)
}
+44
View File
@@ -0,0 +1,44 @@
// +build stm32l0x1
package runtime
import (
"device/stm32"
"machine"
)
/*
timer settings used for tick and sleep.
note: TICK_TIMER_FREQ and SLEEP_TIMER_FREQ are controlled by PLL / clock
settings, so must be kept in sync if the clock settings are changed.
*/
const (
TICK_RATE = 1000 // 1 KHz
TICK_TIMER_IRQ = stm32.IRQ_TIM21
TICK_TIMER_FREQ = 32000000 // 32 MHz
SLEEP_TIMER_IRQ = stm32.IRQ_TIM22
SLEEP_TIMER_FREQ = 32000000 // 32 MHz
)
const (
FlashLatency = stm32.Flash_ACR_LATENCY_WS1
)
func init() {
initCLK()
initSleepTimer(&timerInfo{
EnableRegister: &stm32.RCC.APB2ENR,
EnableFlag: stm32.RCC_APB2ENR_TIM22EN,
Device: stm32.TIM22,
})
machine.UART0.Configure(machine.UARTConfig{})
initTickTimer(&timerInfo{
EnableRegister: &stm32.RCC.APB2ENR,
EnableFlag: stm32.RCC_APB2ENR_TIM21EN,
Device: stm32.TIM21,
})
}
+44
View File
@@ -0,0 +1,44 @@
// +build stm32l0x2
package runtime
import (
"device/stm32"
"machine"
)
/*
timer settings used for tick and sleep.
note: TICK_TIMER_FREQ and SLEEP_TIMER_FREQ are controlled by PLL / clock
settings, so must be kept in sync if the clock settings are changed.
*/
const (
TICK_RATE = 1000 // 1 KHz
TICK_TIMER_IRQ = stm32.IRQ_TIM7
TICK_TIMER_FREQ = 32000000 // 32 MHz
SLEEP_TIMER_IRQ = stm32.IRQ_TIM3
SLEEP_TIMER_FREQ = 32000000 // 32 MHz
)
const (
FlashLatency = stm32.Flash_ACR_LATENCY_WS1
)
func init() {
initCLK()
initSleepTimer(&timerInfo{
EnableRegister: &stm32.RCC.APB1ENR,
EnableFlag: stm32.RCC_APB1ENR_TIM3EN,
Device: stm32.TIM3,
})
machine.UART0.Configure(machine.UARTConfig{})
initTickTimer(&timerInfo{
EnableRegister: &stm32.RCC.APB1ENR,
EnableFlag: stm32.RCC_APB1ENR_TIM7EN,
Device: stm32.TIM7,
})
}