diff options
author | Kenneth Bell <[email protected]> | 2021-05-09 08:02:04 -0700 |
---|---|---|
committer | Ron Evans <[email protected]> | 2021-05-28 00:02:46 +0200 |
commit | c43a41165a74d067ddc8280157652363f9f141fb (patch) | |
tree | 2c2e9b6fed436a59618332ac7df1103db0dc8329 | |
parent | 3145c2747eae7445753300b6b2f831b8b3408803 (diff) | |
download | tinygo-c43a41165a74d067ddc8280157652363f9f141fb.tar.gz tinygo-c43a41165a74d067ddc8280157652363f9f141fb.zip |
stm32l4: add pwm
-rw-r--r-- | src/examples/pwm/nucleo-l432kc.go | 11 | ||||
-rw-r--r-- | src/machine/machine_stm32_tim.go | 2 | ||||
-rw-r--r-- | src/machine/machine_stm32l4.go | 194 | ||||
-rw-r--r-- | src/machine/machine_stm32l4x2.go | 6 |
4 files changed, 212 insertions, 1 deletions
diff --git a/src/examples/pwm/nucleo-l432kc.go b/src/examples/pwm/nucleo-l432kc.go new file mode 100644 index 000000000..09298e814 --- /dev/null +++ b/src/examples/pwm/nucleo-l432kc.go @@ -0,0 +1,11 @@ +// +build stm32l4 + +package main + +import "machine" + +var ( + pwm = &machine.TIM2 + pinA = machine.PA0 + pinB = machine.PB3 +) diff --git a/src/machine/machine_stm32_tim.go b/src/machine/machine_stm32_tim.go index f27cd64d9..bfe241d35 100644 --- a/src/machine/machine_stm32_tim.go +++ b/src/machine/machine_stm32_tim.go @@ -1,4 +1,4 @@ -// +build stm32f4 stm32l5 stm32l0 +// +build stm32f4 stm32l5 stm32l0 stm32l4 package machine diff --git a/src/machine/machine_stm32l4.go b/src/machine/machine_stm32l4.go index 7b52f68a5..c464fa702 100644 --- a/src/machine/machine_stm32l4.go +++ b/src/machine/machine_stm32l4.go @@ -4,12 +4,32 @@ package machine import ( "device/stm32" + "runtime/interrupt" + "runtime/volatile" "unsafe" ) // Peripheral abstraction layer for the stm32l4 const ( + AF0_SYSTEM = 0 + AF1_TIM1_2_LPTIM1 = 1 + AF2_TIM1_2 = 2 + AF3_USART2 = 3 + AF4_I2C1_2_3 = 4 + AF5_SPI1_2 = 5 + AF6_SPI3 = 6 + AF7_USART1_2_3 = 7 + AF8_LPUART1 = 8 + AF9_CAN1_TSC = 9 + AF10_USB_QUADSPI = 10 + AF12_COMP1_2_SWPMI1 = 12 + AF13_SAI1 = 13 + AF14_TIM2_15_16_LPTIM2 = 14 + AF15_EVENTOUT = 15 +) + +const ( PA0 = portA + 0 PA1 = portA + 1 PA2 = portA + 2 @@ -246,3 +266,177 @@ func (spi SPI) configurePins(config SPIConfig) { config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector) config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector) } + +//---------- 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}, + }}, + TimerChannel{Pins: []PinFunction{ + {PA3, AF1_TIM1_2_LPTIM1}, + }}, + }, + busFreq: APB1_TIM_FREQ, + } + + TIM3 = TIM{ + EnableRegister: &stm32.RCC.APB1ENR1, + EnableFlag: stm32.RCC_APB1ENR1_TIM3EN, + Device: stm32.TIM3, + Channels: [4]TimerChannel{ + TimerChannel{Pins: []PinFunction{}}, + TimerChannel{Pins: []PinFunction{}}, + TimerChannel{Pins: []PinFunction{}}, + TimerChannel{Pins: []PinFunction{}}, + }, + busFreq: APB1_TIM_FREQ, + } + + TIM6 = TIM{ + EnableRegister: &stm32.RCC.APB1ENR1, + EnableFlag: stm32.RCC_APB1ENR1_TIM6EN, + Device: stm32.TIM6, + Channels: [4]TimerChannel{ + TimerChannel{Pins: []PinFunction{}}, + TimerChannel{Pins: []PinFunction{}}, + TimerChannel{Pins: []PinFunction{}}, + TimerChannel{Pins: []PinFunction{}}, + }, + busFreq: APB1_TIM_FREQ, + } + + TIM7 = TIM{ + EnableRegister: &stm32.RCC.APB1ENR1, + EnableFlag: stm32.RCC_APB1ENR1_TIM7EN, + Device: stm32.TIM7, + Channels: [4]TimerChannel{ + TimerChannel{Pins: []PinFunction{}}, + TimerChannel{Pins: []PinFunction{}}, + TimerChannel{Pins: []PinFunction{}}, + TimerChannel{Pins: []PinFunction{}}, + }, + busFreq: APB1_TIM_FREQ, + } + + TIM15 = TIM{ + EnableRegister: &stm32.RCC.APB2ENR, + EnableFlag: stm32.RCC_APB2ENR_TIM15EN, + Device: stm32.TIM15, + Channels: [4]TimerChannel{ + TimerChannel{Pins: []PinFunction{ + {PA2, AF14_TIM2_15_16_LPTIM2}, + }}, + TimerChannel{Pins: []PinFunction{ + {PA3, AF14_TIM2_15_16_LPTIM2}, + }}, + TimerChannel{Pins: []PinFunction{}}, + TimerChannel{Pins: []PinFunction{}}, + }, + busFreq: APB2_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_15_16_LPTIM2}, + }}, + 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_TIM16, TIM1.handleUPInterrupt) + case &TIM2: + return interrupt.New(stm32.IRQ_TIM2, TIM2.handleUPInterrupt) + case &TIM3: + return interrupt.New(stm32.IRQ_TIM3, TIM3.handleUPInterrupt) + case &TIM6: + return interrupt.New(stm32.IRQ_TIM6_DACUNDER, TIM6.handleUPInterrupt) + case &TIM7: + return interrupt.New(stm32.IRQ_TIM7, TIM7.handleUPInterrupt) + case &TIM15: + return interrupt.New(stm32.IRQ_TIM1_BRK_TIM15, TIM15.handleUPInterrupt) + case &TIM16: + return interrupt.New(stm32.IRQ_TIM1_UP_TIM16, TIM16.handleUPInterrupt) + } + + return interrupt.Interrupt{} +} + +func (t *TIM) registerOCInterrupt() interrupt.Interrupt { + switch t { + case &TIM1: + return interrupt.New(stm32.IRQ_TIM1_CC, TIM1.handleUPInterrupt) + case &TIM2: + return interrupt.New(stm32.IRQ_TIM2, TIM2.handleOCInterrupt) + case &TIM3: + return interrupt.New(stm32.IRQ_TIM3, TIM3.handleOCInterrupt) + case &TIM6: + return interrupt.New(stm32.IRQ_TIM6_DACUNDER, TIM6.handleOCInterrupt) + case &TIM7: + return interrupt.New(stm32.IRQ_TIM7, TIM7.handleOCInterrupt) + case &TIM15: + return interrupt.New(stm32.IRQ_TIM1_BRK_TIM15, TIM15.handleOCInterrupt) + case &TIM16: + return interrupt.New(stm32.IRQ_TIM1_UP_TIM16, TIM16.handleOCInterrupt) + } + + return interrupt.Interrupt{} +} + +func (t *TIM) enableMainOutput() { + // nothing to do - no BDTR register +} + +type arrtype = uint32 +type arrRegType = volatile.Register32 + +const ( + ARR_MAX = 0x10000 + PSC_MAX = 0x10000 +) diff --git a/src/machine/machine_stm32l4x2.go b/src/machine/machine_stm32l4x2.go index 3e307b211..3feaac28d 100644 --- a/src/machine/machine_stm32l4x2.go +++ b/src/machine/machine_stm32l4x2.go @@ -12,6 +12,12 @@ func CPUFrequency() uint32 { return 80000000 } +// Internal use: configured speed of the APB1 and APB2 timers, this should be kept +// in sync with any changes to runtime package which configures the oscillators +// and clock frequencies +const APB1_TIM_FREQ = 80e6 // 80MHz +const APB2_TIM_FREQ = 80e6 // 80MHz + //---------- UART related code // Configure the UART. |