diff options
author | Kenneth Bell <[email protected]> | 2021-03-22 18:14:28 -0700 |
---|---|---|
committer | Ron Evans <[email protected]> | 2021-04-07 17:20:19 +0200 |
commit | a30671751faabf29a5658c90b01a84500b9ade5d (patch) | |
tree | b72727cc666cb57cb93154c80bcaf27a51b6a159 | |
parent | c246978dd7844192c414c0d95428d1d7e9a6f6a6 (diff) | |
download | tinygo-a30671751faabf29a5658c90b01a84500b9ade5d.tar.gz tinygo-a30671751faabf29a5658c90b01a84500b9ade5d.zip |
stm32: add nucleo-l031k6 support
Adds i2c for all L0 series
UART, Blinky (LED) and i2c tested
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/machine/board_lgt92.go | 15 | ||||
-rw-r--r-- | src/machine/board_nucleol031k6.go | 92 | ||||
-rw-r--r-- | src/machine/i2c.go | 2 | ||||
-rw-r--r-- | src/machine/machine_stm32_i2c_revb.go | 2 | ||||
-rw-r--r-- | src/machine/machine_stm32l0.go | 55 | ||||
-rw-r--r-- | src/machine/machine_stm32l0x1.go | 52 | ||||
-rw-r--r-- | src/machine/machine_stm32l0x2.go | 54 | ||||
-rw-r--r-- | src/runtime/runtime_stm32l0.go | 91 | ||||
-rw-r--r-- | src/runtime/runtime_stm32l0x1.go | 44 | ||||
-rw-r--r-- | src/runtime/runtime_stm32l0x2.go | 44 | ||||
-rw-r--r-- | targets/cortex-m0.json | 8 | ||||
-rw-r--r-- | targets/nucleo-l031k6.json | 11 | ||||
-rw-r--r-- | targets/stm32l031k6.ld | 10 |
14 files changed, 388 insertions, 94 deletions
@@ -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 diff --git a/src/machine/board_lgt92.go b/src/machine/board_lgt92.go index ee6129b7f..c95de360b 100644 --- a/src/machine/board_lgt92.go +++ b/src/machine/board_lgt92.go @@ -41,13 +41,17 @@ const ( // LORA RFM95 Radio RFM95_DIO0_PIN = PC13 - //TinyGo UART is MCU LPUSART1 + // TinyGo UART is MCU LPUSART1 UART_RX_PIN = PA13 UART_TX_PIN = PA14 - //TinyGo UART1 is MCU USART1 + // 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, diff --git a/src/machine/board_nucleol031k6.go b/src/machine/board_nucleol031k6.go new file mode 100644 index 000000000..d5fddebf4 --- /dev/null +++ b/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) +} diff --git a/src/machine/i2c.go b/src/machine/i2c.go index 310173614..60204f48d 100644 --- a/src/machine/i2c.go +++ b/src/machine/i2c.go @@ -1,4 +1,4 @@ -// +build atmega nrf sam stm32,!stm32l0 fe310 k210 +// +build atmega nrf sam stm32 fe310 k210 package machine diff --git a/src/machine/machine_stm32_i2c_revb.go b/src/machine/machine_stm32_i2c_revb.go index 63e9205f1..aca962400 100644 --- a/src/machine/machine_stm32_i2c_revb.go +++ b/src/machine/machine_stm32_i2c_revb.go @@ -1,4 +1,4 @@ -// +build stm32l5 stm32f7 stm32l4 +// +build stm32l5 stm32f7 stm32l4 stm32l0 package machine diff --git a/src/machine/machine_stm32l0.go b/src/machine/machine_stm32l0.go index c37d6a027..886c3985a 100644 --- a/src/machine/machine_stm32l0.go +++ b/src/machine/machine_stm32l0.go @@ -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 +} diff --git a/src/machine/machine_stm32l0x1.go b/src/machine/machine_stm32l0x1.go new file mode 100644 index 000000000..3fad050a6 --- /dev/null +++ b/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) + } +} diff --git a/src/machine/machine_stm32l0x2.go b/src/machine/machine_stm32l0x2.go new file mode 100644 index 000000000..71c7cd4a0 --- /dev/null +++ b/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) + } +} diff --git a/src/runtime/runtime_stm32l0.go b/src/runtime/runtime_stm32l0.go index db14a520f..c7045087b 100644 --- a/src/runtime/runtime_stm32l0.go +++ b/src/runtime/runtime_stm32l0.go @@ -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) { } + // 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.SetBits(0x3) + 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) +} diff --git a/src/runtime/runtime_stm32l0x1.go b/src/runtime/runtime_stm32l0x1.go new file mode 100644 index 000000000..1d48388e8 --- /dev/null +++ b/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, + }) +} diff --git a/src/runtime/runtime_stm32l0x2.go b/src/runtime/runtime_stm32l0x2.go new file mode 100644 index 000000000..6eccf0eb6 --- /dev/null +++ b/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, + }) +} diff --git a/targets/cortex-m0.json b/targets/cortex-m0.json new file mode 100644 index 000000000..8cbbe2850 --- /dev/null +++ b/targets/cortex-m0.json @@ -0,0 +1,8 @@ +{ + "inherits": ["cortex-m"], + "llvm-target": "armv6m-none-eabi", + "cflags": [ + "--target=armv6m-none-eabi", + "-Qunused-arguments" + ] +} diff --git a/targets/nucleo-l031k6.json b/targets/nucleo-l031k6.json new file mode 100644 index 000000000..928dd43dc --- /dev/null +++ b/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" +}
\ No newline at end of file diff --git a/targets/stm32l031k6.ld b/targets/stm32l031k6.ld new file mode 100644 index 000000000..f9995bc02 --- /dev/null +++ b/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"
\ No newline at end of file |