aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorKenneth Bell <[email protected]>2021-05-09 13:26:29 -0700
committerRon Evans <[email protected]>2021-05-28 00:02:46 +0200
commitac543023017911548cb2e31db014bf200b769497 (patch)
tree418f84320450f9d0d3e1f20f33b7d553b3b9eb55
parentc43a41165a74d067ddc8280157652363f9f141fb (diff)
downloadtinygo-ac543023017911548cb2e31db014bf200b769497.tar.gz
tinygo-ac543023017911548cb2e31db014bf200b769497.zip
stm32f7: add pwm
-rw-r--r--src/examples/pwm/nucleo-f722ze.go11
-rw-r--r--src/machine/machine_stm32_tim.go2
-rw-r--r--src/machine/machine_stm32f7.go422
-rw-r--r--src/machine/machine_stm32f7x2.go6
4 files changed, 438 insertions, 3 deletions
diff --git a/src/examples/pwm/nucleo-f722ze.go b/src/examples/pwm/nucleo-f722ze.go
new file mode 100644
index 000000000..fdd0f67f9
--- /dev/null
+++ b/src/examples/pwm/nucleo-f722ze.go
@@ -0,0 +1,11 @@
+// +build stm32f7
+
+package main
+
+import "machine"
+
+var (
+ pwm = &machine.TIM1
+ pinA = machine.PA8
+ pinB = machine.PA9
+)
diff --git a/src/machine/machine_stm32_tim.go b/src/machine/machine_stm32_tim.go
index bfe241d35..75dc9c84c 100644
--- a/src/machine/machine_stm32_tim.go
+++ b/src/machine/machine_stm32_tim.go
@@ -1,4 +1,4 @@
-// +build stm32f4 stm32l5 stm32l0 stm32l4
+// +build stm32f4 stm32l5 stm32l0 stm32l4 stm32l5 stm32f7
package machine
diff --git a/src/machine/machine_stm32f7.go b/src/machine/machine_stm32f7.go
index a84e19cf2..51235709e 100644
--- a/src/machine/machine_stm32f7.go
+++ b/src/machine/machine_stm32f7.go
@@ -6,9 +6,29 @@ package machine
import (
"device/stm32"
+ "runtime/interrupt"
+ "runtime/volatile"
"unsafe"
)
+// Alternative peripheral pin functions
+const (
+ AF0_SYSTEM = 0
+ AF1_TIM1_2 = 1
+ AF2_TIM3_4_5 = 2
+ AF3_TIM8_9_10_11_LPTIM1 = 3
+ AF4_I2C1_2_3_USART1 = 4
+ AF5_SPI1_2_3_4_5_I2S1_2_3 = 5
+ AF6_SPI2_3_I2S2_3_SAI1_UART4 = 6
+ AF7_SPI2_3_I2S2_3_USART1_2_3_UART5 = 7
+ AF8_SAI2_USART6_UART4_5_7_8_OTG1_FS = 8
+ AF9_CAN1_TIM12_13_14_QUADSPI_FMC_OTG2_HS = 9
+ AF10_SAI2_QUADSPI_SDMMC2_OTG2_HS_OTG1_FS = 10
+ AF11_SDMMC2 = 11
+ AF12_UART7_FMC_SDMMC1_OTG2_FS = 12
+ AF15_EVENTOUT = 15
+)
+
const (
PA0 = portA + 0
PA1 = portA + 1
@@ -129,8 +149,39 @@ const (
PG14 = portG + 14
PG15 = portG + 15
- PH0 = portH + 0
- PH1 = portH + 1
+ PH0 = portH + 0
+ PH1 = portH + 1
+ PH2 = portH + 2
+ PH3 = portH + 3
+ PH4 = portH + 4
+ PH5 = portH + 5
+ PH6 = portH + 6
+ PH7 = portH + 7
+ PH8 = portH + 8
+ PH9 = portH + 9
+ PH10 = portH + 10
+ PH11 = portH + 11
+ PH12 = portH + 12
+ PH13 = portH + 13
+ PH14 = portH + 14
+ PH15 = portH + 15
+
+ PI0 = portI + 0
+ PI1 = portI + 1
+ PI2 = portI + 2
+ PI3 = portI + 3
+ PI4 = portI + 4
+ PI5 = portI + 5
+ PI6 = portI + 6
+ PI7 = portI + 7
+ PI8 = portI + 8
+ PI9 = portI + 9
+ PI10 = portI + 10
+ PI11 = portI + 11
+ PI12 = portI + 12
+ PI13 = portI + 13
+ PI14 = portI + 14
+ PI15 = portI + 15
)
func (p Pin) getPort() *stm32.GPIO_Type {
@@ -257,3 +308,370 @@ func enableAltFuncClock(bus unsafe.Pointer) {
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM1EN)
}
}
+
+//---------- 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},
+ {PE9, AF1_TIM1_2},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PA9, AF1_TIM1_2},
+ {PE11, AF1_TIM1_2},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PA10, AF1_TIM1_2},
+ {PE13, AF1_TIM1_2},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PA11, AF1_TIM1_2},
+ {PE14, AF1_TIM1_2},
+ }},
+ },
+ busFreq: APB2_TIM_FREQ,
+ }
+
+ TIM2 = TIM{
+ EnableRegister: &stm32.RCC.APB1ENR,
+ EnableFlag: stm32.RCC_APB1ENR_TIM2EN,
+ Device: stm32.TIM2,
+ Channels: [4]TimerChannel{
+ TimerChannel{Pins: []PinFunction{
+ {PA0, AF1_TIM1_2},
+ {PA5, AF1_TIM1_2},
+ {PA15, AF1_TIM1_2},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PA1, AF1_TIM1_2},
+ {PB3, AF1_TIM1_2},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PA2, AF1_TIM1_2},
+ {PB10, AF1_TIM1_2},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PA3, AF1_TIM1_2},
+ {PB11, AF1_TIM1_2},
+ }},
+ },
+ busFreq: APB1_TIM_FREQ,
+ }
+
+ TIM3 = TIM{
+ EnableRegister: &stm32.RCC.APB1ENR,
+ EnableFlag: stm32.RCC_APB1ENR_TIM3EN,
+ Device: stm32.TIM3,
+ Channels: [4]TimerChannel{
+ TimerChannel{Pins: []PinFunction{
+ {PA6, AF2_TIM3_4_5},
+ {PB4, AF2_TIM3_4_5},
+ {PC6, AF2_TIM3_4_5},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PA7, AF2_TIM3_4_5},
+ {PB5, AF2_TIM3_4_5},
+ {PC7, AF2_TIM3_4_5},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PB0, AF2_TIM3_4_5},
+ {PC8, AF2_TIM3_4_5},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PB1, AF2_TIM3_4_5},
+ {PC9, AF2_TIM3_4_5},
+ }},
+ },
+ busFreq: APB1_TIM_FREQ,
+ }
+
+ TIM4 = TIM{
+ EnableRegister: &stm32.RCC.APB1ENR,
+ EnableFlag: stm32.RCC_APB1ENR_TIM4EN,
+ Device: stm32.TIM4,
+ Channels: [4]TimerChannel{
+ TimerChannel{Pins: []PinFunction{
+ {PB6, AF2_TIM3_4_5},
+ {PD12, AF2_TIM3_4_5},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PB7, AF2_TIM3_4_5},
+ {PD13, AF2_TIM3_4_5},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PB8, AF2_TIM3_4_5},
+ {PD14, AF2_TIM3_4_5},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PB9, AF2_TIM3_4_5},
+ {PD15, AF2_TIM3_4_5},
+ }},
+ },
+ busFreq: APB1_TIM_FREQ,
+ }
+
+ TIM5 = TIM{
+ EnableRegister: &stm32.RCC.APB1ENR,
+ EnableFlag: stm32.RCC_APB1ENR_TIM5EN,
+ Device: stm32.TIM5,
+ Channels: [4]TimerChannel{
+ TimerChannel{Pins: []PinFunction{
+ {PA0, AF2_TIM3_4_5},
+ {PH10, AF2_TIM3_4_5},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PA1, AF2_TIM3_4_5},
+ {PH11, AF2_TIM3_4_5},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PA2, AF2_TIM3_4_5},
+ {PH12, AF2_TIM3_4_5},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PA3, AF2_TIM3_4_5},
+ {PI0, AF2_TIM3_4_5},
+ }},
+ },
+ busFreq: APB1_TIM_FREQ,
+ }
+
+ TIM6 = TIM{
+ EnableRegister: &stm32.RCC.APB1ENR,
+ EnableFlag: stm32.RCC_APB1ENR_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.APB1ENR,
+ EnableFlag: stm32.RCC_APB1ENR_TIM7EN,
+ Device: stm32.TIM7,
+ Channels: [4]TimerChannel{
+ TimerChannel{Pins: []PinFunction{}},
+ TimerChannel{Pins: []PinFunction{}},
+ TimerChannel{Pins: []PinFunction{}},
+ TimerChannel{Pins: []PinFunction{}},
+ },
+ busFreq: APB1_TIM_FREQ,
+ }
+
+ TIM8 = TIM{
+ EnableRegister: &stm32.RCC.APB2ENR,
+ EnableFlag: stm32.RCC_APB2ENR_TIM8EN,
+ Device: stm32.TIM8,
+ Channels: [4]TimerChannel{
+ TimerChannel{Pins: []PinFunction{
+ {PC6, AF3_TIM8_9_10_11_LPTIM1},
+ {PI5, AF3_TIM8_9_10_11_LPTIM1},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PC7, AF3_TIM8_9_10_11_LPTIM1},
+ {PI6, AF3_TIM8_9_10_11_LPTIM1},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PC8, AF3_TIM8_9_10_11_LPTIM1},
+ {PI7, AF3_TIM8_9_10_11_LPTIM1},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PC9, AF3_TIM8_9_10_11_LPTIM1},
+ {PI2, AF3_TIM8_9_10_11_LPTIM1},
+ }},
+ },
+ busFreq: APB2_TIM_FREQ,
+ }
+
+ TIM9 = TIM{
+ EnableRegister: &stm32.RCC.APB2ENR,
+ EnableFlag: stm32.RCC_APB2ENR_TIM9EN,
+ Device: stm32.TIM9,
+ Channels: [4]TimerChannel{
+ TimerChannel{Pins: []PinFunction{
+ {PA2, AF3_TIM8_9_10_11_LPTIM1},
+ {PE5, AF3_TIM8_9_10_11_LPTIM1},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PA3, AF3_TIM8_9_10_11_LPTIM1},
+ {PE6, AF3_TIM8_9_10_11_LPTIM1},
+ }},
+ TimerChannel{Pins: []PinFunction{}},
+ TimerChannel{Pins: []PinFunction{}},
+ },
+ busFreq: APB2_TIM_FREQ,
+ }
+
+ TIM10 = TIM{
+ EnableRegister: &stm32.RCC.APB2ENR,
+ EnableFlag: stm32.RCC_APB2ENR_TIM10EN,
+ Device: stm32.TIM10,
+ Channels: [4]TimerChannel{
+ TimerChannel{Pins: []PinFunction{
+ {PB8, AF3_TIM8_9_10_11_LPTIM1},
+ {PF6, AF3_TIM8_9_10_11_LPTIM1},
+ }},
+ TimerChannel{Pins: []PinFunction{}},
+ TimerChannel{Pins: []PinFunction{}},
+ TimerChannel{Pins: []PinFunction{}},
+ },
+ busFreq: APB2_TIM_FREQ,
+ }
+
+ TIM11 = TIM{
+ EnableRegister: &stm32.RCC.APB2ENR,
+ EnableFlag: stm32.RCC_APB2ENR_TIM11EN,
+ Device: stm32.TIM11,
+ Channels: [4]TimerChannel{
+ TimerChannel{Pins: []PinFunction{
+ {PB9, AF3_TIM8_9_10_11_LPTIM1},
+ {PF7, AF3_TIM8_9_10_11_LPTIM1},
+ }},
+ TimerChannel{Pins: []PinFunction{}},
+ TimerChannel{Pins: []PinFunction{}},
+ TimerChannel{Pins: []PinFunction{}},
+ },
+ busFreq: APB2_TIM_FREQ,
+ }
+
+ TIM12 = TIM{
+ EnableRegister: &stm32.RCC.APB1ENR,
+ EnableFlag: stm32.RCC_APB1ENR_TIM12EN,
+ Device: stm32.TIM12,
+ Channels: [4]TimerChannel{
+ TimerChannel{Pins: []PinFunction{
+ {PB14, AF9_CAN1_TIM12_13_14_QUADSPI_FMC_OTG2_HS},
+ {PH6, AF9_CAN1_TIM12_13_14_QUADSPI_FMC_OTG2_HS},
+ }},
+ TimerChannel{Pins: []PinFunction{
+ {PB15, AF9_CAN1_TIM12_13_14_QUADSPI_FMC_OTG2_HS},
+ {PH9, AF9_CAN1_TIM12_13_14_QUADSPI_FMC_OTG2_HS},
+ }},
+ TimerChannel{Pins: []PinFunction{}},
+ TimerChannel{Pins: []PinFunction{}},
+ },
+ busFreq: APB1_TIM_FREQ,
+ }
+
+ TIM13 = TIM{
+ EnableRegister: &stm32.RCC.APB1ENR,
+ EnableFlag: stm32.RCC_APB1ENR_TIM13EN,
+ Device: stm32.TIM13,
+ Channels: [4]TimerChannel{
+ TimerChannel{Pins: []PinFunction{
+ {PA6, AF9_CAN1_TIM12_13_14_QUADSPI_FMC_OTG2_HS},
+ {PF8, AF9_CAN1_TIM12_13_14_QUADSPI_FMC_OTG2_HS},
+ }},
+ TimerChannel{Pins: []PinFunction{}},
+ TimerChannel{Pins: []PinFunction{}},
+ TimerChannel{Pins: []PinFunction{}},
+ },
+ busFreq: APB1_TIM_FREQ,
+ }
+
+ TIM14 = TIM{
+ EnableRegister: &stm32.RCC.APB1ENR,
+ EnableFlag: stm32.RCC_APB1ENR_TIM14EN,
+ Device: stm32.TIM14,
+ Channels: [4]TimerChannel{
+ TimerChannel{Pins: []PinFunction{
+ {PA7, AF9_CAN1_TIM12_13_14_QUADSPI_FMC_OTG2_HS},
+ {PF9, AF9_CAN1_TIM12_13_14_QUADSPI_FMC_OTG2_HS},
+ }},
+ TimerChannel{Pins: []PinFunction{}},
+ TimerChannel{Pins: []PinFunction{}},
+ TimerChannel{Pins: []PinFunction{}},
+ },
+ busFreq: APB1_TIM_FREQ,
+ }
+)
+
+func (t *TIM) registerUPInterrupt() interrupt.Interrupt {
+ switch t {
+ case &TIM1:
+ return interrupt.New(stm32.IRQ_TIM1_UP_TIM10, TIM1.handleUPInterrupt)
+ case &TIM2:
+ return interrupt.New(stm32.IRQ_TIM2, TIM2.handleUPInterrupt)
+ case &TIM3:
+ return interrupt.New(stm32.IRQ_TIM3, TIM3.handleUPInterrupt)
+ case &TIM4:
+ return interrupt.New(stm32.IRQ_TIM4, TIM4.handleUPInterrupt)
+ case &TIM5:
+ return interrupt.New(stm32.IRQ_TIM5, TIM5.handleUPInterrupt)
+ case &TIM6:
+ return interrupt.New(stm32.IRQ_TIM6_DAC, TIM6.handleUPInterrupt)
+ case &TIM7:
+ return interrupt.New(stm32.IRQ_TIM7, TIM7.handleUPInterrupt)
+ case &TIM8:
+ return interrupt.New(stm32.IRQ_TIM8_UP_TIM13, TIM8.handleUPInterrupt)
+ case &TIM9:
+ return interrupt.New(stm32.IRQ_TIM1_BRK_TIM9, TIM9.handleUPInterrupt)
+ case &TIM10:
+ return interrupt.New(stm32.IRQ_TIM1_UP_TIM10, TIM10.handleUPInterrupt)
+ case &TIM11:
+ return interrupt.New(stm32.IRQ_TIM1_TRG_COM_TIM11, TIM11.handleUPInterrupt)
+ case &TIM12:
+ return interrupt.New(stm32.IRQ_TIM8_BRK_TIM12, TIM12.handleUPInterrupt)
+ case &TIM13:
+ return interrupt.New(stm32.IRQ_TIM8_UP_TIM13, TIM13.handleUPInterrupt)
+ case &TIM14:
+ return interrupt.New(stm32.IRQ_TIM8_TRG_COM_TIM14, TIM14.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 &TIM4:
+ return interrupt.New(stm32.IRQ_TIM4, TIM4.handleOCInterrupt)
+ case &TIM5:
+ return interrupt.New(stm32.IRQ_TIM5, TIM5.handleOCInterrupt)
+ case &TIM6:
+ return interrupt.New(stm32.IRQ_TIM6_DAC, TIM6.handleOCInterrupt)
+ case &TIM7:
+ return interrupt.New(stm32.IRQ_TIM7, TIM7.handleOCInterrupt)
+ case &TIM8:
+ return interrupt.New(stm32.IRQ_TIM8_CC, TIM8.handleOCInterrupt)
+ case &TIM9:
+ return interrupt.New(stm32.IRQ_TIM1_BRK_TIM9, TIM9.handleOCInterrupt)
+ case &TIM10:
+ return interrupt.New(stm32.IRQ_TIM1_UP_TIM10, TIM10.handleOCInterrupt)
+ case &TIM11:
+ return interrupt.New(stm32.IRQ_TIM1_TRG_COM_TIM11, TIM11.handleOCInterrupt)
+ case &TIM12:
+ return interrupt.New(stm32.IRQ_TIM8_BRK_TIM12, TIM12.handleOCInterrupt)
+ case &TIM13:
+ return interrupt.New(stm32.IRQ_TIM8_UP_TIM13, TIM13.handleOCInterrupt)
+ case &TIM14:
+ return interrupt.New(stm32.IRQ_TIM8_TRG_COM_TIM14, TIM14.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
+)
diff --git a/src/machine/machine_stm32f7x2.go b/src/machine/machine_stm32f7x2.go
index 376161bba..7035c38c5 100644
--- a/src/machine/machine_stm32f7x2.go
+++ b/src/machine/machine_stm32f7x2.go
@@ -12,6 +12,12 @@ func CPUFrequency() uint32 {
return 216000000
}
+// 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 = 54e6 // 54MHz
+const APB2_TIM_FREQ = 216e6 // 216MHz
+
//---------- UART related code
// Configure the UART.