mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-06 20:13:40 +00:00
60fb4b95fa
Signed-off-by: deadprogram <ron@hybridgroup.com> machine/stm32u585: fix PWR peripheral clock was never enabled On STM32U5, PWR is on AHB3 and requires RCC.AHB3ENR.PWREN - unlike some other STM32 families where PWR is always clocked. Without this, all writes to PWR registers (including IO2SV for VDDIO2) were silently dropped, so GPIOG pins could never drive. Signed-off-by: deadprogram <ron@hybridgroup.com> target: correct I2C pin mapping for Arduino UNO Q Signed-off-by: deadprogram <ron@hybridgroup.com>
581 lines
18 KiB
Go
581 lines
18 KiB
Go
//go:build stm32u5
|
|
|
|
package machine
|
|
|
|
// Peripheral abstraction layer for the stm32u5
|
|
|
|
import (
|
|
"device/stm32"
|
|
"runtime/interrupt"
|
|
"runtime/volatile"
|
|
"unsafe"
|
|
)
|
|
|
|
var deviceIDAddr = []uintptr{0x0BFA0590, 0x0BFA0594, 0x0BFA0598}
|
|
|
|
const (
|
|
AF0_SYSTEM = 0
|
|
AF1_TIM1_2_5_8_LPTIM1 = 1
|
|
AF2_TIM1_2_3_4_5_LPTIM2 = 2
|
|
AF3_SAI1_SPI2_TIM1_8_USART2_OCTOSPI1 = 3
|
|
AF4_I2C1_2_3_4 = 4
|
|
AF5_SPI1_2_3_OCTOSPI1_OCTOSPI2 = 5
|
|
AF6_SPI3_I2C3_DFSDM1_COMP1 = 6
|
|
AF7_USART1_2_3 = 7
|
|
AF8_UART4_5_LPUART1_SDMMC1 = 8
|
|
AF9_FDCAN1_TSC = 9
|
|
AF10_USB_OCTOSPI1_OCTOSPI2 = 10
|
|
AF11_UCPD1 = 11
|
|
AF12_SDMMC1_COMP1_2_TIM1_8_FMC = 12
|
|
AF13_SAI1_2_TIM8 = 13
|
|
AF14_TIM2_8_15_16_17_LPTIM2 = 14
|
|
AF15_EVENTOUT = 15
|
|
)
|
|
|
|
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
|
|
|
|
PD0 = portD + 0
|
|
PD1 = portD + 1
|
|
PD2 = portD + 2
|
|
PD3 = portD + 3
|
|
PD4 = portD + 4
|
|
PD5 = portD + 5
|
|
PD6 = portD + 6
|
|
PD7 = portD + 7
|
|
PD8 = portD + 8
|
|
PD9 = portD + 9
|
|
PD10 = portD + 10
|
|
PD11 = portD + 11
|
|
PD12 = portD + 12
|
|
PD13 = portD + 13
|
|
PD14 = portD + 14
|
|
PD15 = portD + 15
|
|
|
|
PE0 = portE + 0
|
|
PE1 = portE + 1
|
|
PE2 = portE + 2
|
|
PE3 = portE + 3
|
|
PE4 = portE + 4
|
|
PE5 = portE + 5
|
|
PE6 = portE + 6
|
|
PE7 = portE + 7
|
|
PE8 = portE + 8
|
|
PE9 = portE + 9
|
|
PE10 = portE + 10
|
|
PE11 = portE + 11
|
|
PE12 = portE + 12
|
|
PE13 = portE + 13
|
|
PE14 = portE + 14
|
|
PE15 = portE + 15
|
|
|
|
PF0 = portF + 0
|
|
PF1 = portF + 1
|
|
PF2 = portF + 2
|
|
PF3 = portF + 3
|
|
PF4 = portF + 4
|
|
PF5 = portF + 5
|
|
PF6 = portF + 6
|
|
PF7 = portF + 7
|
|
PF8 = portF + 8
|
|
PF9 = portF + 9
|
|
PF10 = portF + 10
|
|
PF11 = portF + 11
|
|
PF12 = portF + 12
|
|
PF13 = portF + 13
|
|
PF14 = portF + 14
|
|
PF15 = portF + 15
|
|
|
|
PG0 = portG + 0
|
|
PG1 = portG + 1
|
|
PG2 = portG + 2
|
|
PG3 = portG + 3
|
|
PG4 = portG + 4
|
|
PG5 = portG + 5
|
|
PG6 = portG + 6
|
|
PG7 = portG + 7
|
|
PG8 = portG + 8
|
|
PG9 = portG + 9
|
|
PG10 = portG + 10
|
|
PG11 = portG + 11
|
|
PG12 = portG + 12
|
|
PG13 = portG + 13
|
|
PG14 = portG + 14
|
|
PG15 = portG + 15
|
|
|
|
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 {
|
|
switch p / 16 {
|
|
case 0:
|
|
return stm32.GPIOA
|
|
case 1:
|
|
return stm32.GPIOB
|
|
case 2:
|
|
return stm32.GPIOC
|
|
case 3:
|
|
return stm32.GPIOD
|
|
case 4:
|
|
return stm32.GPIOE
|
|
case 5:
|
|
return stm32.GPIOF
|
|
case 6:
|
|
return stm32.GPIOG
|
|
case 7:
|
|
return stm32.GPIOH
|
|
case 8:
|
|
return stm32.GPIOI
|
|
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.AHB2ENR1.SetBits(stm32.RCC_AHB2ENR1_GPIOAEN)
|
|
case 1:
|
|
stm32.RCC.AHB2ENR1.SetBits(stm32.RCC_AHB2ENR1_GPIOBEN)
|
|
case 2:
|
|
stm32.RCC.AHB2ENR1.SetBits(stm32.RCC_AHB2ENR1_GPIOCEN)
|
|
case 3:
|
|
stm32.RCC.AHB2ENR1.SetBits(stm32.RCC_AHB2ENR1_GPIODEN)
|
|
case 4:
|
|
stm32.RCC.AHB2ENR1.SetBits(stm32.RCC_AHB2ENR1_GPIOEEN)
|
|
case 5:
|
|
stm32.RCC.AHB2ENR1.SetBits(stm32.RCC_AHB2ENR1_GPIOFEN)
|
|
case 6:
|
|
stm32.RCC.AHB2ENR1.SetBits(stm32.RCC_AHB2ENR1_GPIOGEN)
|
|
case 7:
|
|
stm32.RCC.AHB2ENR1.SetBits(stm32.RCC_AHB2ENR1_GPIOHEN)
|
|
case 8:
|
|
stm32.RCC.AHB2ENR1.SetBits(stm32.RCC_AHB2ENR1_GPIOIEN)
|
|
default:
|
|
panic("machine: unknown port")
|
|
}
|
|
// Dummy read-back to ensure the clock enable takes effect before
|
|
// accessing GPIO registers (2 AHB cycle delay per STM32 reference manual).
|
|
_ = stm32.RCC.AHB2ENR1.Get()
|
|
}
|
|
|
|
// Enable peripheral clock
|
|
func enableAltFuncClock(bus unsafe.Pointer) {
|
|
switch bus {
|
|
case unsafe.Pointer(stm32.PWR): // Power interface clock enable
|
|
stm32.RCC.AHB3ENR.SetBits(stm32.RCC_AHB3ENR_PWREN)
|
|
case unsafe.Pointer(stm32.I2C1): // I2C1 clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_I2C1EN)
|
|
case unsafe.Pointer(stm32.I2C2): // I2C2 clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_I2C2EN)
|
|
case unsafe.Pointer(stm32.I2C3): // I2C3 clock enable
|
|
stm32.RCC.APB3ENR.SetBits(stm32.RCC_APB3ENR_I2C3EN)
|
|
case unsafe.Pointer(stm32.I2C4): // I2C4 clock enable
|
|
stm32.RCC.APB1ENR2.SetBits(stm32.RCC_APB1ENR2_I2C4EN)
|
|
case unsafe.Pointer(stm32.USART1): // USART1 clock enable
|
|
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_USART1EN)
|
|
case unsafe.Pointer(stm32.USART2): // USART2 clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_USART2EN)
|
|
case unsafe.Pointer(stm32.USART3): // USART3 clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_USART3EN)
|
|
case unsafe.Pointer(stm32.UART4): // UART4 clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_UART4EN)
|
|
case unsafe.Pointer(stm32.UART5): // UART5 clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_UART5EN)
|
|
case unsafe.Pointer(stm32.LPUART1): // LPUART1 clock enable
|
|
stm32.RCC.APB3ENR.SetBits(stm32.RCC_APB3ENR_LPUART1EN)
|
|
case unsafe.Pointer(stm32.SPI1): // SPI1 clock enable
|
|
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN)
|
|
case unsafe.Pointer(stm32.SPI2): // SPI2 clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_SPI2EN)
|
|
case unsafe.Pointer(stm32.SPI3): // SPI3 clock enable
|
|
stm32.RCC.APB3ENR.SetBits(stm32.RCC_APB3ENR_SPI3EN)
|
|
case unsafe.Pointer(stm32.WWDG): // Window watchdog clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_WWDGEN)
|
|
case unsafe.Pointer(stm32.TIM1): // TIM1 clock enable
|
|
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM1EN)
|
|
case unsafe.Pointer(stm32.TIM2): // TIM2 clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_TIM2EN)
|
|
case unsafe.Pointer(stm32.TIM3): // TIM3 clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_TIM3EN)
|
|
case unsafe.Pointer(stm32.TIM4): // TIM4 clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_TIM4EN)
|
|
case unsafe.Pointer(stm32.TIM5): // TIM5 clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_TIM5EN)
|
|
case unsafe.Pointer(stm32.TIM6): // TIM6 clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_TIM6EN)
|
|
case unsafe.Pointer(stm32.TIM7): // TIM7 clock enable
|
|
stm32.RCC.APB1ENR1.SetBits(stm32.RCC_APB1ENR1_TIM7EN)
|
|
case unsafe.Pointer(stm32.TIM8): // TIM8 clock enable
|
|
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM8EN)
|
|
case unsafe.Pointer(stm32.TIM15): // TIM15 clock enable
|
|
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM15EN)
|
|
case unsafe.Pointer(stm32.TIM16): // TIM16 clock enable
|
|
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM16EN)
|
|
case unsafe.Pointer(stm32.TIM17): // TIM17 clock enable
|
|
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM17EN)
|
|
case unsafe.Pointer(stm32.SYSCFG): // System configuration controller clock enable
|
|
stm32.RCC.APB3ENR.SetBits(stm32.RCC_APB3ENR_SYSCFGEN)
|
|
case unsafe.Pointer(stm32.FDCAN1): // FDCAN1 clock enable
|
|
stm32.RCC.APB1ENR2.SetBits(stm32.RCC_APB1ENR2_FDCAN1EN)
|
|
}
|
|
}
|
|
|
|
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_EXTI5, func(interrupt.Interrupt) { handlePinInterrupt(5) })
|
|
case 6:
|
|
return interrupt.New(stm32.IRQ_EXTI6, func(interrupt.Interrupt) { handlePinInterrupt(6) })
|
|
case 7:
|
|
return interrupt.New(stm32.IRQ_EXTI7, func(interrupt.Interrupt) { handlePinInterrupt(7) })
|
|
case 8:
|
|
return interrupt.New(stm32.IRQ_EXTI8, func(interrupt.Interrupt) { handlePinInterrupt(8) })
|
|
case 9:
|
|
return interrupt.New(stm32.IRQ_EXTI9, func(interrupt.Interrupt) { handlePinInterrupt(9) })
|
|
case 10:
|
|
return interrupt.New(stm32.IRQ_EXTI10, func(interrupt.Interrupt) { handlePinInterrupt(10) })
|
|
case 11:
|
|
return interrupt.New(stm32.IRQ_EXTI11, func(interrupt.Interrupt) { handlePinInterrupt(11) })
|
|
case 12:
|
|
return interrupt.New(stm32.IRQ_EXTI12, func(interrupt.Interrupt) { handlePinInterrupt(12) })
|
|
case 13:
|
|
return interrupt.New(stm32.IRQ_EXTI13, func(interrupt.Interrupt) { handlePinInterrupt(13) })
|
|
case 14:
|
|
return interrupt.New(stm32.IRQ_EXTI14, func(interrupt.Interrupt) { handlePinInterrupt(14) })
|
|
case 15:
|
|
return interrupt.New(stm32.IRQ_EXTI15, func(interrupt.Interrupt) { handlePinInterrupt(15) })
|
|
}
|
|
|
|
return interrupt.Interrupt{}
|
|
}
|
|
|
|
func handlePinInterrupt(pin uint8) {
|
|
if stm32.EXTI.RPR1.HasBits(1<<pin) || stm32.EXTI.FPR1.HasBits(1<<pin) {
|
|
stm32.EXTI.RPR1.Set(1 << pin)
|
|
stm32.EXTI.FPR1.Set(1 << pin)
|
|
|
|
callback := pinCallbacks[pin]
|
|
if callback != nil {
|
|
callback(interruptPins[pin])
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------- 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_5_8_LPTIM1}, {PE9, AF1_TIM1_2_5_8_LPTIM1}}},
|
|
TimerChannel{Pins: []PinFunction{{PA9, AF1_TIM1_2_5_8_LPTIM1}, {PE11, AF1_TIM1_2_5_8_LPTIM1}}},
|
|
TimerChannel{Pins: []PinFunction{{PA10, AF1_TIM1_2_5_8_LPTIM1}, {PE13, AF1_TIM1_2_5_8_LPTIM1}}},
|
|
TimerChannel{Pins: []PinFunction{{PA11, AF1_TIM1_2_5_8_LPTIM1}, {PE14, AF1_TIM1_2_5_8_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_5_8_LPTIM1}, {PA5, AF1_TIM1_2_5_8_LPTIM1}, {PA15, AF1_TIM1_2_5_8_LPTIM1}}},
|
|
TimerChannel{Pins: []PinFunction{{PA1, AF1_TIM1_2_5_8_LPTIM1}, {PB3, AF1_TIM1_2_5_8_LPTIM1}}},
|
|
TimerChannel{Pins: []PinFunction{{PA2, AF1_TIM1_2_5_8_LPTIM1}, {PB10, AF1_TIM1_2_5_8_LPTIM1}}},
|
|
TimerChannel{Pins: []PinFunction{{PA3, AF1_TIM1_2_5_8_LPTIM1}, {PB11, AF1_TIM1_2_5_8_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{{PA6, AF2_TIM1_2_3_4_5_LPTIM2}, {PB4, AF2_TIM1_2_3_4_5_LPTIM2}, {PC6, AF2_TIM1_2_3_4_5_LPTIM2}, {PE3, AF2_TIM1_2_3_4_5_LPTIM2}}},
|
|
TimerChannel{Pins: []PinFunction{{PA7, AF2_TIM1_2_3_4_5_LPTIM2}, {PB5, AF2_TIM1_2_3_4_5_LPTIM2}, {PC7, AF2_TIM1_2_3_4_5_LPTIM2}, {PE4, AF2_TIM1_2_3_4_5_LPTIM2}}},
|
|
TimerChannel{Pins: []PinFunction{{PB0, AF2_TIM1_2_3_4_5_LPTIM2}, {PC8, AF2_TIM1_2_3_4_5_LPTIM2}, {PE5, AF2_TIM1_2_3_4_5_LPTIM2}}},
|
|
TimerChannel{Pins: []PinFunction{{PB1, AF2_TIM1_2_3_4_5_LPTIM2}, {PC9, AF2_TIM1_2_3_4_5_LPTIM2}, {PE6, AF2_TIM1_2_3_4_5_LPTIM2}}},
|
|
},
|
|
busFreq: APB1_TIM_FREQ,
|
|
}
|
|
|
|
TIM4 = TIM{
|
|
EnableRegister: &stm32.RCC.APB1ENR1,
|
|
EnableFlag: stm32.RCC_APB1ENR1_TIM4EN,
|
|
Device: stm32.TIM4,
|
|
Channels: [4]TimerChannel{
|
|
TimerChannel{Pins: []PinFunction{{PB6, AF2_TIM1_2_3_4_5_LPTIM2}, {PD12, AF2_TIM1_2_3_4_5_LPTIM2}}},
|
|
TimerChannel{Pins: []PinFunction{{PB7, AF2_TIM1_2_3_4_5_LPTIM2}, {PD13, AF2_TIM1_2_3_4_5_LPTIM2}}},
|
|
TimerChannel{Pins: []PinFunction{{PB8, AF2_TIM1_2_3_4_5_LPTIM2}, {PD14, AF2_TIM1_2_3_4_5_LPTIM2}}},
|
|
TimerChannel{Pins: []PinFunction{{PB9, AF2_TIM1_2_3_4_5_LPTIM2}, {PD15, AF2_TIM1_2_3_4_5_LPTIM2}}},
|
|
},
|
|
busFreq: APB1_TIM_FREQ,
|
|
}
|
|
|
|
TIM5 = TIM{
|
|
EnableRegister: &stm32.RCC.APB1ENR1,
|
|
EnableFlag: stm32.RCC_APB1ENR1_TIM5EN,
|
|
Device: stm32.TIM5,
|
|
Channels: [4]TimerChannel{
|
|
TimerChannel{Pins: []PinFunction{{PA0, AF2_TIM1_2_3_4_5_LPTIM2}, {PF6, AF2_TIM1_2_3_4_5_LPTIM2}}},
|
|
TimerChannel{Pins: []PinFunction{{PA1, AF2_TIM1_2_3_4_5_LPTIM2}, {PF7, AF2_TIM1_2_3_4_5_LPTIM2}}},
|
|
TimerChannel{Pins: []PinFunction{{PA2, AF2_TIM1_2_3_4_5_LPTIM2}, {PF8, AF2_TIM1_2_3_4_5_LPTIM2}}},
|
|
TimerChannel{Pins: []PinFunction{{PA3, AF2_TIM1_2_3_4_5_LPTIM2}, {PF9, AF2_TIM1_2_3_4_5_LPTIM2}}},
|
|
},
|
|
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,
|
|
}
|
|
|
|
TIM8 = TIM{
|
|
EnableRegister: &stm32.RCC.APB2ENR,
|
|
EnableFlag: stm32.RCC_APB2ENR_TIM8EN,
|
|
Device: stm32.TIM8,
|
|
Channels: [4]TimerChannel{
|
|
TimerChannel{Pins: []PinFunction{{PC6, AF3_SAI1_SPI2_TIM1_8_USART2_OCTOSPI1}}},
|
|
TimerChannel{Pins: []PinFunction{{PC7, AF3_SAI1_SPI2_TIM1_8_USART2_OCTOSPI1}}},
|
|
TimerChannel{Pins: []PinFunction{{PC8, AF3_SAI1_SPI2_TIM1_8_USART2_OCTOSPI1}}},
|
|
TimerChannel{Pins: []PinFunction{{PC9, AF3_SAI1_SPI2_TIM1_8_USART2_OCTOSPI1}}},
|
|
},
|
|
busFreq: APB2_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_8_15_16_17_LPTIM2}, {PB14, AF14_TIM2_8_15_16_17_LPTIM2}, {PG10, AF14_TIM2_8_15_16_17_LPTIM2}}},
|
|
TimerChannel{Pins: []PinFunction{{PA3, AF14_TIM2_8_15_16_17_LPTIM2}, {PB15, AF14_TIM2_8_15_16_17_LPTIM2}, {PG11, AF14_TIM2_8_15_16_17_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_8_15_16_17_LPTIM2}, {PB8, AF14_TIM2_8_15_16_17_LPTIM2}, {PE0, AF14_TIM2_8_15_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, AF14_TIM2_8_15_16_17_LPTIM2}, {PB9, AF14_TIM2_8_15_16_17_LPTIM2}, {PE1, AF14_TIM2_8_15_16_17_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, 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, TIM6.handleUPInterrupt)
|
|
case &TIM7:
|
|
return interrupt.New(stm32.IRQ_TIM7, TIM7.handleUPInterrupt)
|
|
case &TIM8:
|
|
return interrupt.New(stm32.IRQ_TIM8_UP, TIM8.handleUPInterrupt)
|
|
case &TIM15:
|
|
return interrupt.New(stm32.IRQ_TIM15, TIM15.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 &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, TIM6.handleOCInterrupt)
|
|
case &TIM7:
|
|
return interrupt.New(stm32.IRQ_TIM7, TIM7.handleOCInterrupt)
|
|
case &TIM8:
|
|
return interrupt.New(stm32.IRQ_TIM8_CC, TIM8.handleOCInterrupt)
|
|
case &TIM15:
|
|
return interrupt.New(stm32.IRQ_TIM15, TIM15.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
|
|
type psctype = uint16
|
|
|
|
const (
|
|
ARR_MAX = 0x10000
|
|
PSC_MAX = 0x10000
|
|
)
|
|
|
|
func initRNG() {
|
|
stm32.RCC.AHB2ENR1.SetBits(stm32.RCC_AHB2ENR1_RNGEN)
|
|
stm32.RNG.CR.SetBits(stm32.RNG_CR_RNGEN)
|
|
}
|