stm32: add nucleo-l031k6 support
Adds i2c for all L0 series UART, Blinky (LED) and i2c tested
Этот коммит содержится в:
родитель
c246978dd7
коммит
a30671751f
14 изменённых файлов: 389 добавлений и 95 удалений
2
Makefile
2
Makefile
|
@ -352,6 +352,8 @@ ifneq ($(STM32), 0)
|
|||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=nucleo-f722ze examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=nucleo-l031k6 examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=nucleo-l432kc examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=nucleo-l552ze examples/blinky1
|
||||
|
|
|
@ -48,6 +48,10 @@ const (
|
|||
// TinyGo UART1 is MCU USART1
|
||||
UART1_RX_PIN = PB6
|
||||
UART1_TX_PIN = PB7
|
||||
|
||||
// MPU9250 Nine-Axis (Gyro + Accelerometer + Compass)
|
||||
I2C0_SCL_PIN = PA9
|
||||
I2C0_SDA_PIN = PA10
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -68,6 +72,13 @@ var (
|
|||
RxAltFuncSelector: 0,
|
||||
}
|
||||
|
||||
// MPU9250 Nine-Axis (Gyro + Accelerometer + Compass)
|
||||
I2C1 = &I2C{
|
||||
Bus: stm32.I2C1,
|
||||
AltFuncSelector: 6,
|
||||
}
|
||||
I2C0 = I2C1
|
||||
|
||||
// SPI
|
||||
SPI0 = SPI{
|
||||
Bus: stm32.SPI1,
|
||||
|
|
92
src/machine/board_nucleol031k6.go
Обычный файл
92
src/machine/board_nucleol031k6.go
Обычный файл
|
@ -0,0 +1,92 @@
|
|||
// +build nucleol031k6
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
const (
|
||||
LED = LED_BUILTIN
|
||||
LED_BUILTIN = LED_GREEN
|
||||
LED_GREEN = PB3
|
||||
)
|
||||
|
||||
const (
|
||||
// Arduino Pins
|
||||
A0 = PA0 // ADC_IN0
|
||||
A1 = PA1 // ADC_IN1
|
||||
A2 = PA3 // ADC_IN3
|
||||
A3 = PA4 // ADC_IN4
|
||||
A4 = PA5 // ADC_IN5 || I2C1_SDA
|
||||
A5 = PA6 // ADC_IN6 || I2C1_SCL
|
||||
A6 = PA7 // ADC_IN7
|
||||
A7 = PA2 // ADC_IN2
|
||||
|
||||
D0 = PA10 // USART1_TX
|
||||
D1 = PA9 // USART1_RX
|
||||
D2 = PA12
|
||||
D3 = PB0 // TIM2_CH3
|
||||
D4 = PB7
|
||||
D5 = PB6 // TIM16_CH1N
|
||||
D6 = PB1 // TIM14_CH1
|
||||
D9 = PA8 // TIM1_CH1
|
||||
D10 = PA11 // SPI_CS || TIM1_CH4
|
||||
D11 = PB5 // SPI1_MOSI || TIM3_CH2
|
||||
D12 = PB4 // SPI1_MISO
|
||||
D13 = PB3 // SPI1_SCK
|
||||
)
|
||||
|
||||
const (
|
||||
// UART pins
|
||||
// PA2 and PA15 are connected to the ST-Link Virtual Com Port (VCP)
|
||||
UART_TX_PIN = PA2
|
||||
UART_RX_PIN = PA15
|
||||
|
||||
// SPI
|
||||
SPI1_SCK_PIN = PB3
|
||||
SPI1_SDI_PIN = PB5
|
||||
SPI1_SDO_PIN = PB4
|
||||
SPI0_SCK_PIN = SPI1_SCK_PIN
|
||||
SPI0_SDI_PIN = SPI1_SDI_PIN
|
||||
SPI0_SDO_PIN = SPI1_SDO_PIN
|
||||
|
||||
// I2C pins
|
||||
// PB6 and PB7 are mapped to CN4 pin 7 and CN4 pin 8 respectively with the
|
||||
// default solder bridge settings
|
||||
I2C0_SCL_PIN = PB7
|
||||
I2C0_SDA_PIN = PB6
|
||||
I2C0_ALT_FUNC = 1
|
||||
)
|
||||
|
||||
var (
|
||||
// USART2 is the hardware serial port connected to the onboard ST-LINK
|
||||
// debugger to be exposed as virtual COM port over USB on Nucleo boards.
|
||||
// Both UART0 and UART1 refer to USART2.
|
||||
UART0 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: stm32.USART2,
|
||||
TxAltFuncSelector: 4,
|
||||
RxAltFuncSelector: 4,
|
||||
}
|
||||
UART1 = &UART0
|
||||
|
||||
// I2C1 is documented, alias to I2C0 as well
|
||||
I2C1 = &I2C{
|
||||
Bus: stm32.I2C1,
|
||||
AltFuncSelector: 1,
|
||||
}
|
||||
I2C0 = I2C1
|
||||
|
||||
// SPI
|
||||
SPI0 = SPI{
|
||||
Bus: stm32.SPI1,
|
||||
AltFuncSelector: 0,
|
||||
}
|
||||
SPI1 = &SPI0
|
||||
)
|
||||
|
||||
func init() {
|
||||
UART0.Interrupt = interrupt.New(stm32.IRQ_USART2, UART0.handleInterrupt)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build atmega nrf sam stm32,!stm32l0 fe310 k210
|
||||
// +build atmega nrf sam stm32 fe310 k210
|
||||
|
||||
package machine
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build stm32l5 stm32f7 stm32l4
|
||||
// +build stm32l5 stm32f7 stm32l4 stm32l0
|
||||
|
||||
package machine
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ package machine
|
|||
|
||||
import (
|
||||
"device/stm32"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func CPUFrequency() uint32 {
|
||||
|
@ -142,50 +141,6 @@ func (p Pin) enableClock() {
|
|||
}
|
||||
}
|
||||
|
||||
// Enable peripheral clock
|
||||
func enableAltFuncClock(bus unsafe.Pointer) {
|
||||
switch bus {
|
||||
case unsafe.Pointer(stm32.DAC): // DAC interface clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_DACEN)
|
||||
case unsafe.Pointer(stm32.PWR): // Power interface clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_PWREN)
|
||||
case unsafe.Pointer(stm32.I2C3): // I2C3 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_I2C3EN)
|
||||
case unsafe.Pointer(stm32.I2C2): // I2C2 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_I2C2EN)
|
||||
case unsafe.Pointer(stm32.I2C1): // I2C1 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_I2C1EN)
|
||||
case unsafe.Pointer(stm32.USART5): // UART5 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART5EN)
|
||||
case unsafe.Pointer(stm32.USART4): // UART4 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART4EN)
|
||||
case unsafe.Pointer(stm32.USART2): // USART2 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN)
|
||||
case unsafe.Pointer(stm32.SPI2): // SPI2 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_SPI2EN)
|
||||
case unsafe.Pointer(stm32.LPUART1): // LPUART1 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_LPUART1EN)
|
||||
case unsafe.Pointer(stm32.WWDG): // Window watchdog clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_WWDGEN)
|
||||
case unsafe.Pointer(stm32.TIM7): // TIM7 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM7EN)
|
||||
case unsafe.Pointer(stm32.TIM6): // TIM6 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM6EN)
|
||||
case unsafe.Pointer(stm32.TIM3): // TIM3 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM3EN)
|
||||
case unsafe.Pointer(stm32.TIM2): // TIM2 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM2EN)
|
||||
case unsafe.Pointer(stm32.SYSCFG): // System configuration controller clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SYSCFGEN)
|
||||
case unsafe.Pointer(stm32.SPI1): // SPI1 clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN)
|
||||
case unsafe.Pointer(stm32.ADC): // ADC clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_ADCEN)
|
||||
case unsafe.Pointer(stm32.USART1): // USART1 clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_USART1EN)
|
||||
}
|
||||
}
|
||||
|
||||
//---------- UART related types and code
|
||||
|
||||
// Configure the UART.
|
||||
|
@ -285,3 +240,13 @@ func (spi SPI) configurePins(config SPIConfig) {
|
|||
config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector)
|
||||
config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector)
|
||||
}
|
||||
|
||||
//---------- I2C related types and code
|
||||
|
||||
// Gets the value for TIMINGR register
|
||||
func (i2c I2C) getFreqRange() uint32 {
|
||||
// This is a 'magic' value calculated by STM32CubeMX
|
||||
// for 80MHz PCLK1.
|
||||
// TODO: Do calculations based on PCLK1
|
||||
return 0x00303D5B
|
||||
}
|
||||
|
|
52
src/machine/machine_stm32l0x1.go
Обычный файл
52
src/machine/machine_stm32l0x1.go
Обычный файл
|
@ -0,0 +1,52 @@
|
|||
// +build stm32l0x1
|
||||
|
||||
package machine
|
||||
|
||||
// Peripheral abstraction layer for the stm32l0
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Enable peripheral clock
|
||||
func enableAltFuncClock(bus unsafe.Pointer) {
|
||||
switch bus {
|
||||
case unsafe.Pointer(stm32.PWR): // Power interface clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_PWREN)
|
||||
case unsafe.Pointer(stm32.I2C3): // I2C3 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_I2C3EN)
|
||||
case unsafe.Pointer(stm32.I2C2): // I2C2 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_I2C2EN)
|
||||
case unsafe.Pointer(stm32.I2C1): // I2C1 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_I2C1EN)
|
||||
case unsafe.Pointer(stm32.USART5): // UART5 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART5EN)
|
||||
case unsafe.Pointer(stm32.USART4): // UART4 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART4EN)
|
||||
case unsafe.Pointer(stm32.USART2): // USART2 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN)
|
||||
case unsafe.Pointer(stm32.SPI2): // SPI2 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_SPI2EN)
|
||||
case unsafe.Pointer(stm32.LPUART1): // LPUART1 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_LPUART1EN)
|
||||
case unsafe.Pointer(stm32.WWDG): // Window watchdog clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_WWDGEN)
|
||||
case unsafe.Pointer(stm32.TIM7): // TIM7 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM7EN)
|
||||
case unsafe.Pointer(stm32.TIM6): // TIM6 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM6EN)
|
||||
case unsafe.Pointer(stm32.TIM3): // TIM3 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM3EN)
|
||||
case unsafe.Pointer(stm32.TIM2): // TIM2 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM2EN)
|
||||
case unsafe.Pointer(stm32.SYSCFG): // System configuration controller clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SYSCFGEN)
|
||||
case unsafe.Pointer(stm32.SPI1): // SPI1 clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN)
|
||||
case unsafe.Pointer(stm32.ADC): // ADC clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_ADCEN)
|
||||
case unsafe.Pointer(stm32.USART1): // USART1 clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_USART1EN)
|
||||
}
|
||||
}
|
54
src/machine/machine_stm32l0x2.go
Обычный файл
54
src/machine/machine_stm32l0x2.go
Обычный файл
|
@ -0,0 +1,54 @@
|
|||
// +build stm32l0x2
|
||||
|
||||
package machine
|
||||
|
||||
// Peripheral abstraction layer for the stm32l0
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Enable peripheral clock
|
||||
func enableAltFuncClock(bus unsafe.Pointer) {
|
||||
switch bus {
|
||||
case unsafe.Pointer(stm32.DAC): // DAC interface clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_DACEN)
|
||||
case unsafe.Pointer(stm32.PWR): // Power interface clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_PWREN)
|
||||
case unsafe.Pointer(stm32.I2C3): // I2C3 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_I2C3EN)
|
||||
case unsafe.Pointer(stm32.I2C2): // I2C2 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_I2C2EN)
|
||||
case unsafe.Pointer(stm32.I2C1): // I2C1 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_I2C1EN)
|
||||
case unsafe.Pointer(stm32.USART5): // UART5 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART5EN)
|
||||
case unsafe.Pointer(stm32.USART4): // UART4 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART4EN)
|
||||
case unsafe.Pointer(stm32.USART2): // USART2 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN)
|
||||
case unsafe.Pointer(stm32.SPI2): // SPI2 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_SPI2EN)
|
||||
case unsafe.Pointer(stm32.LPUART1): // LPUART1 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_LPUART1EN)
|
||||
case unsafe.Pointer(stm32.WWDG): // Window watchdog clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_WWDGEN)
|
||||
case unsafe.Pointer(stm32.TIM7): // TIM7 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM7EN)
|
||||
case unsafe.Pointer(stm32.TIM6): // TIM6 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM6EN)
|
||||
case unsafe.Pointer(stm32.TIM3): // TIM3 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM3EN)
|
||||
case unsafe.Pointer(stm32.TIM2): // TIM2 clock enable
|
||||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM2EN)
|
||||
case unsafe.Pointer(stm32.SYSCFG): // System configuration controller clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SYSCFGEN)
|
||||
case unsafe.Pointer(stm32.SPI1): // SPI1 clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN)
|
||||
case unsafe.Pointer(stm32.ADC): // ADC clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_ADCEN)
|
||||
case unsafe.Pointer(stm32.USART1): // USART1 clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_USART1EN)
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
}
|
||||
}
|
||||
|
||||
const asyncScheduler = false
|
||||
// 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)
|
||||
}
|
||||
|
||||
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
src/runtime/runtime_stm32l0x1.go
Обычный файл
44
src/runtime/runtime_stm32l0x1.go
Обычный файл
|
@ -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
src/runtime/runtime_stm32l0x2.go
Обычный файл
44
src/runtime/runtime_stm32l0x2.go
Обычный файл
|
@ -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,
|
||||
})
|
||||
}
|
8
targets/cortex-m0.json
Обычный файл
8
targets/cortex-m0.json
Обычный файл
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "armv6m-none-eabi",
|
||||
"cflags": [
|
||||
"--target=armv6m-none-eabi",
|
||||
"-Qunused-arguments"
|
||||
]
|
||||
}
|
11
targets/nucleo-l031k6.json
Обычный файл
11
targets/nucleo-l031k6.json
Обычный файл
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"inherits": ["cortex-m0"],
|
||||
"build-tags": ["nucleol031k6", "stm32l031", "stm32l0x1", "stm32l0", "stm32"],
|
||||
"linkerscript": "targets/stm32l031k6.ld",
|
||||
"extra-files": [
|
||||
"src/device/stm32/stm32l0x1.s"
|
||||
],
|
||||
"flash-method": "openocd",
|
||||
"openocd-interface": "stlink",
|
||||
"openocd-target": "stm32l0"
|
||||
}
|
10
targets/stm32l031k6.ld
Обычный файл
10
targets/stm32l031k6.ld
Обычный файл
|
@ -0,0 +1,10 @@
|
|||
|
||||
MEMORY
|
||||
{
|
||||
FLASH_TEXT (rx) : ORIGIN = 0x08000000, LENGTH = 32K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K
|
||||
}
|
||||
|
||||
_stack_size = 2K;
|
||||
|
||||
INCLUDE "targets/arm.ld"
|
Загрузка…
Создание таблицы
Сослаться в новой задаче