stm32: add minimal stm32wlex5 / lorae5 target
credit to ofauchon
Этот коммит содержится в:
родитель
339301b709
коммит
62d4a6a77f
17 изменённых файлов: 582 добавлений и 6 удалений
2
Makefile
2
Makefile
|
@ -430,6 +430,8 @@ ifneq ($(STM32), 0)
|
|||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=stm32f4disco-1 examples/pwm
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=lorae5 examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
endif
|
||||
ifneq ($(AVR), 0)
|
||||
$(TINYGO) build -size short -o test.hex -target=atmega1284p examples/serial
|
||||
|
|
|
@ -107,6 +107,7 @@ The following 72 microcontroller boards are currently supported:
|
|||
* [Raytac MDBT50Q-RX Dongle (with TinyUF2 bootloader)](https://www.adafruit.com/product/5199)
|
||||
* [Seeed Wio Terminal](https://www.seeedstudio.com/Wio-Terminal-p-4509.html)
|
||||
* [Seeed Seeeduino XIAO](https://www.seeedstudio.com/Seeeduino-XIAO-Arduino-Microcontroller-SAMD21-Cortex-M0+-p-4426.html)
|
||||
* [Seeed LoRa-E5 Development Kit](https://www.seeedstudio.com/LoRa-E5-Dev-Kit-p-4868.html)
|
||||
* [Seeed Sipeed MAix BiT](https://www.seeedstudio.com/Sipeed-MAix-BiT-for-RISC-V-AI-IoT-p-2872.html)
|
||||
* [SiFIve HiFive1](https://www.sifive.com/boards/hifive1)
|
||||
* [ST Micro "Nucleo" F103RB](https://www.st.com/en/evaluation-tools/nucleo-f103rb.html)
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 3a0b0829b70bf930c74fb69d887bee28005e7d99
|
||||
Subproject commit 5f417214efe79598eadd38f68b4432384ca57456
|
54
src/machine/board_lorae5.go
Обычный файл
54
src/machine/board_lorae5.go
Обычный файл
|
@ -0,0 +1,54 @@
|
|||
//go:build lorae5
|
||||
// +build lorae5
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
const (
|
||||
LED1 = PB5
|
||||
LED = LED1 // Default LED
|
||||
)
|
||||
|
||||
// SubGhz (SPI3)
|
||||
const (
|
||||
SPI0_NSS_PIN = PA4
|
||||
SPI0_SCK_PIN = PA5
|
||||
SPI0_SDO_PIN = PA6
|
||||
SPI0_SDI_PIN = PA7
|
||||
)
|
||||
|
||||
// UARTS
|
||||
const (
|
||||
//MCU USART1
|
||||
UART1_TX_PIN = PB6
|
||||
UART1_RX_PIN = PB7
|
||||
|
||||
//MCU USART2
|
||||
UART2_TX_PIN = PA2
|
||||
UART2_RX_PIN = PA3
|
||||
|
||||
// DEFAULT USART
|
||||
UART_TX_PIN = UART1_TX_PIN
|
||||
UART_RX_PIN = UART1_RX_PIN
|
||||
)
|
||||
|
||||
var (
|
||||
// Console UART
|
||||
UART0 = &_UART0
|
||||
_UART0 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: stm32.USART1,
|
||||
TxAltFuncSelector: AF7_USART1_2,
|
||||
RxAltFuncSelector: AF7_USART1_2,
|
||||
}
|
||||
DefaultUART = UART0
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Enable UARTs Interrupts
|
||||
UART0.Interrupt = interrupt.New(stm32.IRQ_USART1, _UART0.handleInterrupt)
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
// +build atmega nrf sam stm32 fe310 k210 rp2040
|
||||
//go:build atmega || nrf || sam || (stm32 && !stm32wle5) || fe310 || k210 || rp2040
|
||||
// +build atmega nrf sam stm32,!stm32wle5 fe310 k210 rp2040
|
||||
|
||||
package machine
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// +build stm32,!stm32f1,!stm32l5
|
||||
//go:build stm32 && !stm32f1 && !stm32l5 && !stm32wle5
|
||||
// +build stm32,!stm32f1,!stm32l5,!stm32wle5
|
||||
|
||||
package machine
|
||||
|
||||
|
|
27
src/machine/machine_stm32_exti_syscfg_noenable.go
Обычный файл
27
src/machine/machine_stm32_exti_syscfg_noenable.go
Обычный файл
|
@ -0,0 +1,27 @@
|
|||
//go:build stm32wle5
|
||||
// +build stm32wle5
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
"runtime/volatile"
|
||||
)
|
||||
|
||||
func getEXTIConfigRegister(pin uint8) *volatile.Register32 {
|
||||
switch (pin & 0xf) / 4 {
|
||||
case 0:
|
||||
return &stm32.SYSCFG.EXTICR1
|
||||
case 1:
|
||||
return &stm32.SYSCFG.EXTICR2
|
||||
case 2:
|
||||
return &stm32.SYSCFG.EXTICR3
|
||||
case 3:
|
||||
return &stm32.SYSCFG.EXTICR4
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func enableEXTIConfigRegisters() {
|
||||
// No registers to enable
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
// +build stm32,!stm32l4,!stm32l5
|
||||
//go:build stm32 && !stm32l4 && !stm32l5 && !stm32wle5
|
||||
// +build stm32,!stm32l4,!stm32l5,!stm32wle5
|
||||
|
||||
package machine
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build stm32l4 || stm32l5
|
||||
// +build stm32l4 stm32l5
|
||||
|
||||
package machine
|
||||
|
|
87
src/machine/machine_stm32_gpio_revb_mp.go
Обычный файл
87
src/machine/machine_stm32_gpio_revb_mp.go
Обычный файл
|
@ -0,0 +1,87 @@
|
|||
//go:build stm32wle5
|
||||
// +build stm32wle5
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
)
|
||||
|
||||
//
|
||||
// This variant of the GPIO input interrupt logic is for
|
||||
// multi-core chips with a larger number of interrupt
|
||||
// channels (more than fits in a single register).
|
||||
//
|
||||
// This logic is currently used by the single-core stm32wle5
|
||||
// due to a patch in stm32-rs project that has renamed the
|
||||
// registers to match the dual-core names. This renaming is
|
||||
// being discussed and may change in future.
|
||||
//
|
||||
|
||||
//
|
||||
// STM32 allows one interrupt source per pin number, with
|
||||
// the same pin number in different ports sharing a single
|
||||
// interrupt source (so PA0, PB0, PC0 all share). Only a
|
||||
// single physical pin can be connected to each interrupt
|
||||
// line.
|
||||
//
|
||||
// To call interrupt callbacks, we record here for each
|
||||
// pin number the callback and the actual associated pin.
|
||||
//
|
||||
|
||||
// Callbacks for pin interrupt events
|
||||
var pinCallbacks [16]func(Pin)
|
||||
|
||||
// The pin currently associated with interrupt callback
|
||||
// for a given slot.
|
||||
var interruptPins [16]Pin
|
||||
|
||||
// SetInterrupt sets an interrupt to be executed when a particular pin changes
|
||||
// state. The pin should already be configured as an input, including a pull up
|
||||
// or down if no external pull is provided.
|
||||
//
|
||||
// This call will replace a previously set callback on this pin. You can pass a
|
||||
// nil func to unset the pin change interrupt. If you do so, the change
|
||||
// parameter is ignored and can be set to any value (such as 0).
|
||||
func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error {
|
||||
port := uint32(uint8(p) / 16)
|
||||
pin := uint8(p) % 16
|
||||
|
||||
enableEXTIConfigRegisters()
|
||||
|
||||
if callback == nil {
|
||||
stm32.EXTI.C1IMR1.ClearBits(1 << pin)
|
||||
pinCallbacks[pin] = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
if pinCallbacks[pin] != nil {
|
||||
// The pin was already configured.
|
||||
// To properly re-configure a pin, unset it first and set a new
|
||||
// configuration.
|
||||
return ErrNoPinChangeChannel
|
||||
}
|
||||
|
||||
// Set the callback now (before the interrupt is enabled) to avoid
|
||||
// possible race condition
|
||||
pinCallbacks[pin] = callback
|
||||
interruptPins[pin] = p
|
||||
|
||||
crReg := getEXTIConfigRegister(pin)
|
||||
shift := (pin & 0x3) * 4
|
||||
crReg.ReplaceBits(port, 0xf, shift)
|
||||
|
||||
if (change & PinRising) != 0 {
|
||||
stm32.EXTI.RTSR1.SetBits(1 << pin)
|
||||
}
|
||||
if (change & PinFalling) != 0 {
|
||||
stm32.EXTI.FTSR1.SetBits(1 << pin)
|
||||
}
|
||||
stm32.EXTI.C1IMR1.SetBits(1 << pin)
|
||||
|
||||
intr := p.registerInterrupt()
|
||||
intr.SetPriority(0)
|
||||
intr.Enable()
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
// +build stm32,!stm32f7x2,!stm32l5x2
|
||||
//go:build stm32 && !stm32f7x2 && !stm32l5x2 && !stm32wle5
|
||||
// +build stm32,!stm32f7x2,!stm32l5x2,!stm32wle5
|
||||
|
||||
package machine
|
||||
|
||||
|
|
343
src/machine/machine_stm32wle5.go
Обычный файл
343
src/machine/machine_stm32wle5.go
Обычный файл
|
@ -0,0 +1,343 @@
|
|||
//go:build stm32wle5
|
||||
// +build stm32wle5
|
||||
|
||||
package machine
|
||||
|
||||
// Peripheral abstraction layer for the stm32wle5
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
"runtime/interrupt"
|
||||
"runtime/volatile"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
AF0_SYSTEM = 0
|
||||
AF1_TIM1_2_LPTIM1 = 1
|
||||
AF2_TIM1_2 = 2
|
||||
AF3_SPIS2_TIM1_LPTIM3 = 3
|
||||
AF4_I2C1_2_3 = 4
|
||||
AF5_SPI1_SPI2S2 = 5
|
||||
AF6_RF = 6
|
||||
AF7_USART1_2 = 7
|
||||
AF8_LPUART1 = 8
|
||||
AF12_COMP1_2_TIM1 = 12
|
||||
AF13_DEBUG = 13
|
||||
AF14_TIM2_16_17_LPTIM2 = 14
|
||||
AF15_EVENTOUT = 15
|
||||
)
|
||||
|
||||
func CPUFrequency() uint32 {
|
||||
return 4e6
|
||||
}
|
||||
|
||||
const APB1_TIM_FREQ = 4e6
|
||||
const APB2_TIM_FREQ = 4e6
|
||||
|
||||
const (
|
||||
PA0 = portA + 0
|
||||
PA1 = portA + 1
|
||||
PA2 = portA + 2
|
||||
PA3 = portA + 3
|
||||
PA4 = portA + 4
|
||||
PA5 = portA + 5
|
||||
PA6 = portA + 6
|
||||
PA7 = portA + 7
|
||||
PA8 = portA + 8
|
||||
PA9 = portA + 9
|
||||
PA10 = portA + 10
|
||||
PA11 = portA + 11
|
||||
PA12 = portA + 12
|
||||
PA13 = portA + 13
|
||||
PA14 = portA + 14
|
||||
PA15 = portA + 15
|
||||
|
||||
PB0 = portB + 0
|
||||
PB1 = portB + 1
|
||||
PB2 = portB + 2
|
||||
PB3 = portB + 3
|
||||
PB4 = portB + 4
|
||||
PB5 = portB + 5
|
||||
PB6 = portB + 6
|
||||
PB7 = portB + 7
|
||||
PB8 = portB + 8
|
||||
PB9 = portB + 9
|
||||
PB10 = portB + 10
|
||||
PB11 = portB + 11
|
||||
PB12 = portB + 12
|
||||
PB13 = portB + 13
|
||||
PB14 = portB + 14
|
||||
PB15 = portB + 15
|
||||
|
||||
PC0 = portC + 0
|
||||
PC1 = portC + 1
|
||||
PC2 = portC + 2
|
||||
PC3 = portC + 3
|
||||
PC4 = portC + 4
|
||||
PC5 = portC + 5
|
||||
PC6 = portC + 6
|
||||
PC7 = portC + 7
|
||||
PC8 = portC + 8
|
||||
PC9 = portC + 9
|
||||
PC10 = portC + 10
|
||||
PC11 = portC + 11
|
||||
PC12 = portC + 12
|
||||
PC13 = portC + 13
|
||||
PC14 = portC + 14
|
||||
PC15 = portC + 15
|
||||
|
||||
PH3 = portH + 3
|
||||
)
|
||||
|
||||
func (p Pin) getPort() *stm32.GPIO_Type {
|
||||
switch p / 16 {
|
||||
case 0:
|
||||
return stm32.GPIOA
|
||||
case 1:
|
||||
return stm32.GPIOB
|
||||
case 2:
|
||||
return stm32.GPIOC
|
||||
case 7:
|
||||
return stm32.GPIOH
|
||||
default:
|
||||
panic("machine: unknown port")
|
||||
}
|
||||
}
|
||||
|
||||
// enableClock enables the clock for this desired GPIO port.
|
||||
func (p Pin) enableClock() {
|
||||
switch p / 16 {
|
||||
case 0:
|
||||
stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_GPIOAEN)
|
||||
case 1:
|
||||
stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_GPIOBEN)
|
||||
case 2:
|
||||
stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_GPIOCEN)
|
||||
case 7:
|
||||
stm32.RCC.AHB2ENR.SetBits(stm32.RCC_AHB2ENR_GPIOHEN)
|
||||
default:
|
||||
panic("machine: unknown port")
|
||||
}
|
||||
}
|
||||
|
||||
// Enable peripheral clock
|
||||
func enableAltFuncClock(bus unsafe.Pointer) {
|
||||
switch bus {
|
||||
// APB1ENR1
|
||||
case unsafe.Pointer(stm32.LPTIM1): // LPTIM1 clock enable
|
||||
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_LPTIM1EN)
|
||||
case unsafe.Pointer(stm32.DAC): // DAC clock enable
|
||||
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_DAC1EN)
|
||||
case unsafe.Pointer(stm32.I2C3): // I2C3 clock enable
|
||||
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_I2C3EN)
|
||||
case unsafe.Pointer(stm32.I2C2): // I2C2 clock enable
|
||||
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_I2C2EN)
|
||||
case unsafe.Pointer(stm32.I2C1): // I2C1 clock enable
|
||||
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_I2C1EN)
|
||||
case unsafe.Pointer(stm32.USART2): // USART2 clock enable
|
||||
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_USART2EN)
|
||||
case unsafe.Pointer(stm32.SPI2): // SPI2S2 clock enable
|
||||
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_SPI2S2EN)
|
||||
case unsafe.Pointer(stm32.WWDG): // Window watchdog clock enable
|
||||
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_WWDGEN)
|
||||
case unsafe.Pointer(stm32.TIM2): // TIM2 clock enable
|
||||
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_TIM2EN)
|
||||
// APB1ENR2
|
||||
case unsafe.Pointer(stm32.LPTIM3): // LPTIM3 clock enable
|
||||
stm32.RCC.APB1ENR2.SetBits(stm32.RCC_APB1ENR2_LPTIM3EN)
|
||||
case unsafe.Pointer(stm32.LPTIM2): // LPTIM2 clock enable
|
||||
stm32.RCC.APB1ENR2.SetBits(stm32.RCC_APB1ENR2_LPTIM2EN)
|
||||
case unsafe.Pointer(stm32.LPUART): // LPUART clock enable
|
||||
stm32.RCC.APB1ENR2.SetBits(stm32.RCC_APB1ENR2_LPUART1EN)
|
||||
//APB2ENR
|
||||
case unsafe.Pointer(stm32.TIM17): // TIM17 clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM17EN)
|
||||
case unsafe.Pointer(stm32.TIM16): // TIM16 clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM16EN)
|
||||
case unsafe.Pointer(stm32.USART1): // USART1 clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_USART1EN)
|
||||
case unsafe.Pointer(stm32.SPI1): // SPI1 clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN)
|
||||
case unsafe.Pointer(stm32.TIM1): // TIM1 clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM1EN)
|
||||
case unsafe.Pointer(stm32.ADC): // ADC clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_ADCEN)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func handlePinInterrupt(pin uint8) {
|
||||
if stm32.EXTI.PR1.HasBits(1 << pin) {
|
||||
// Writing 1 to the pending register clears the
|
||||
// pending flag for that bit
|
||||
stm32.EXTI.PR1.Set(1 << pin)
|
||||
|
||||
callback := pinCallbacks[pin]
|
||||
if callback != nil {
|
||||
callback(interruptPins[pin])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p Pin) registerInterrupt() interrupt.Interrupt {
|
||||
pin := uint8(p) % 16
|
||||
|
||||
switch pin {
|
||||
case 0:
|
||||
return interrupt.New(stm32.IRQ_EXTI0, func(interrupt.Interrupt) { handlePinInterrupt(0) })
|
||||
case 1:
|
||||
return interrupt.New(stm32.IRQ_EXTI1, func(interrupt.Interrupt) { handlePinInterrupt(1) })
|
||||
case 2:
|
||||
return interrupt.New(stm32.IRQ_EXTI2, func(interrupt.Interrupt) { handlePinInterrupt(2) })
|
||||
case 3:
|
||||
return interrupt.New(stm32.IRQ_EXTI3, func(interrupt.Interrupt) { handlePinInterrupt(3) })
|
||||
case 4:
|
||||
return interrupt.New(stm32.IRQ_EXTI4, func(interrupt.Interrupt) { handlePinInterrupt(4) })
|
||||
case 5:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(5) })
|
||||
case 6:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(6) })
|
||||
case 7:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(7) })
|
||||
case 8:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(8) })
|
||||
case 9:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(9) })
|
||||
case 10:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(10) })
|
||||
case 11:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(11) })
|
||||
case 12:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(12) })
|
||||
case 13:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(13) })
|
||||
case 14:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(14) })
|
||||
case 15:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(15) })
|
||||
}
|
||||
|
||||
return interrupt.Interrupt{}
|
||||
}
|
||||
|
||||
//---------- UART related code
|
||||
|
||||
// Configure the UART.
|
||||
func (uart UART) configurePins(config UARTConfig) {
|
||||
// enable the alternate functions on the TX and RX pins
|
||||
config.TX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTTX}, uart.TxAltFuncSelector)
|
||||
config.RX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTRX}, uart.RxAltFuncSelector)
|
||||
}
|
||||
|
||||
// UART baudrate calc based on the bus and clockspeed
|
||||
// NOTE: keep this in sync with the runtime/runtime_stm32wle5.go clock init code
|
||||
func (uart *UART) getBaudRateDivisor(baudRate uint32) uint32 {
|
||||
var br uint32
|
||||
uartClock := CPUFrequency() // No Prescaler configuration
|
||||
br = uint32((uartClock + baudRate/2) / baudRate)
|
||||
return (br)
|
||||
}
|
||||
|
||||
// Register names vary by ST processor, these are for STM L5
|
||||
func (uart *UART) setRegisters() {
|
||||
uart.rxReg = &uart.Bus.RDR
|
||||
uart.txReg = &uart.Bus.TDR
|
||||
uart.statusReg = &uart.Bus.ISR
|
||||
uart.txEmptyFlag = stm32.USART_ISR_TXFNF //(TXFNF == TXE == bit 7, but depends alternate RM0461/1094)
|
||||
}
|
||||
|
||||
//---------- Timer related code
|
||||
|
||||
var (
|
||||
TIM1 = TIM{
|
||||
EnableRegister: &stm32.RCC.APB2ENR,
|
||||
EnableFlag: stm32.RCC_APB2ENR_TIM1EN,
|
||||
Device: stm32.TIM1,
|
||||
Channels: [4]TimerChannel{
|
||||
TimerChannel{Pins: []PinFunction{{PA8, AF1_TIM1_2_LPTIM1}}},
|
||||
TimerChannel{Pins: []PinFunction{{PA9, AF1_TIM1_2_LPTIM1}}},
|
||||
TimerChannel{Pins: []PinFunction{{PA10, AF1_TIM1_2_LPTIM1}}},
|
||||
TimerChannel{Pins: []PinFunction{{PA11, AF1_TIM1_2_LPTIM1}}},
|
||||
},
|
||||
busFreq: APB2_TIM_FREQ,
|
||||
}
|
||||
TIM2 = TIM{
|
||||
EnableRegister: &stm32.RCC.APB1ENR1,
|
||||
EnableFlag: stm32.RCC_APB1ENR1_TIM2EN,
|
||||
Device: stm32.TIM2,
|
||||
Channels: [4]TimerChannel{
|
||||
TimerChannel{Pins: []PinFunction{{PA0, AF1_TIM1_2_LPTIM1}, {PA5, AF1_TIM1_2_LPTIM1}, {PA15, AF1_TIM1_2_LPTIM1}}},
|
||||
TimerChannel{Pins: []PinFunction{{PA1, AF1_TIM1_2_LPTIM1}, {PB3, AF1_TIM1_2_LPTIM1}}},
|
||||
TimerChannel{Pins: []PinFunction{{PA2, AF1_TIM1_2_LPTIM1}, {PB10, AF1_TIM1_2_LPTIM1}}},
|
||||
TimerChannel{Pins: []PinFunction{{PA3, AF1_TIM1_2_LPTIM1}, {PB11, AF1_TIM1_2_LPTIM1}}},
|
||||
},
|
||||
busFreq: APB1_TIM_FREQ,
|
||||
}
|
||||
TIM16 = TIM{
|
||||
EnableRegister: &stm32.RCC.APB2ENR,
|
||||
EnableFlag: stm32.RCC_APB2ENR_TIM16EN,
|
||||
Device: stm32.TIM16,
|
||||
Channels: [4]TimerChannel{
|
||||
TimerChannel{Pins: []PinFunction{{PA6, AF14_TIM2_16_17_LPTIM2}}},
|
||||
TimerChannel{Pins: []PinFunction{}},
|
||||
TimerChannel{Pins: []PinFunction{}},
|
||||
TimerChannel{Pins: []PinFunction{}},
|
||||
},
|
||||
busFreq: APB2_TIM_FREQ,
|
||||
}
|
||||
TIM17 = TIM{
|
||||
EnableRegister: &stm32.RCC.APB2ENR,
|
||||
EnableFlag: stm32.RCC_APB2ENR_TIM17EN,
|
||||
Device: stm32.TIM17,
|
||||
Channels: [4]TimerChannel{
|
||||
TimerChannel{Pins: []PinFunction{{PA7, AF1_TIM1_2_LPTIM1}, {PB9, AF1_TIM1_2_LPTIM1}}},
|
||||
TimerChannel{Pins: []PinFunction{}},
|
||||
TimerChannel{Pins: []PinFunction{}},
|
||||
TimerChannel{Pins: []PinFunction{}},
|
||||
},
|
||||
busFreq: APB2_TIM_FREQ,
|
||||
}
|
||||
)
|
||||
|
||||
func (t *TIM) registerUPInterrupt() interrupt.Interrupt {
|
||||
switch t {
|
||||
case &TIM1:
|
||||
return interrupt.New(stm32.IRQ_TIM1_UP, TIM1.handleUPInterrupt)
|
||||
case &TIM2:
|
||||
return interrupt.New(stm32.IRQ_TIM2, TIM2.handleUPInterrupt)
|
||||
case &TIM16:
|
||||
return interrupt.New(stm32.IRQ_TIM16, TIM16.handleUPInterrupt)
|
||||
case &TIM17:
|
||||
return interrupt.New(stm32.IRQ_TIM17, TIM17.handleUPInterrupt)
|
||||
}
|
||||
|
||||
return interrupt.Interrupt{}
|
||||
}
|
||||
|
||||
func (t *TIM) registerOCInterrupt() interrupt.Interrupt {
|
||||
switch t {
|
||||
case &TIM1:
|
||||
return interrupt.New(stm32.IRQ_TIM1_CC, TIM1.handleOCInterrupt)
|
||||
case &TIM2:
|
||||
return interrupt.New(stm32.IRQ_TIM2, TIM2.handleOCInterrupt)
|
||||
case &TIM16:
|
||||
return interrupt.New(stm32.IRQ_TIM16, TIM16.handleOCInterrupt)
|
||||
case &TIM17:
|
||||
return interrupt.New(stm32.IRQ_TIM17, TIM17.handleOCInterrupt)
|
||||
}
|
||||
|
||||
return interrupt.Interrupt{}
|
||||
}
|
||||
|
||||
func (t *TIM) enableMainOutput() {
|
||||
t.Device.BDTR.SetBits(stm32.TIM_BDTR_MOE)
|
||||
}
|
||||
|
||||
type arrtype = uint32
|
||||
type arrRegType = volatile.Register32
|
||||
|
||||
const (
|
||||
ARR_MAX = 0x10000
|
||||
PSC_MAX = 0x10000
|
||||
)
|
|
@ -1,4 +1,5 @@
|
|||
// +build !baremetal stm32,!stm32f7x2,!stm32l5x2 fe310 k210 atmega
|
||||
//go:build !baremetal || (stm32 && !stm32f7x2 && !stm32l5x2 && !stm32wle5) || fe310 || k210 || atmega
|
||||
// +build !baremetal stm32,!stm32f7x2,!stm32l5x2,!stm32wle5 fe310 k210 atmega
|
||||
|
||||
package machine
|
||||
|
||||
|
|
26
src/runtime/runtime_stm32wle5.go
Обычный файл
26
src/runtime/runtime_stm32wle5.go
Обычный файл
|
@ -0,0 +1,26 @@
|
|||
//go:build stm32wle5
|
||||
// +build stm32wle5
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"machine"
|
||||
)
|
||||
|
||||
type arrtype = uint32
|
||||
|
||||
func init() {
|
||||
// Currently the clock is not configured, which means
|
||||
// the MCU runs at default reset clock speed (4Mhz).
|
||||
// Code to initialize RCC and PLL can go here.
|
||||
|
||||
// UART init
|
||||
machine.Serial.Configure(machine.UARTConfig{})
|
||||
|
||||
// Timers init
|
||||
initTickTimer(&machine.TIM1)
|
||||
}
|
||||
|
||||
func putchar(c byte) {
|
||||
machine.Serial.WriteByte(c)
|
||||
}
|
12
targets/lorae5.json
Обычный файл
12
targets/lorae5.json
Обычный файл
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"inherits": [
|
||||
"stm32wle5"
|
||||
],
|
||||
"build-tags": [
|
||||
"lorae5"
|
||||
],
|
||||
"serial": "uart",
|
||||
"flash-method": "openocd",
|
||||
"openocd-interface": "stlink-v2",
|
||||
"openocd-target": "stm32wlx"
|
||||
}
|
8
targets/stm32wle5.json
Обычный файл
8
targets/stm32wle5.json
Обычный файл
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"inherits": ["cortex-m4"],
|
||||
"build-tags": ["stm32wle5", "stm32"],
|
||||
"extra-files": [
|
||||
"src/device/stm32/stm32wle5.s"
|
||||
],
|
||||
"linkerscript": "targets/stm32wle5.ld"
|
||||
}
|
10
targets/stm32wle5.ld
Обычный файл
10
targets/stm32wle5.ld
Обычный файл
|
@ -0,0 +1,10 @@
|
|||
|
||||
MEMORY
|
||||
{
|
||||
FLASH_TEXT (rw) : ORIGIN = 0x08000000, LENGTH = 256K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||
}
|
||||
|
||||
_stack_size = 4K;
|
||||
|
||||
INCLUDE "targets/arm.ld"
|
Загрузка…
Создание таблицы
Сослаться в новой задаче