diff --git a/src/machine/board_arduino_uno_q.go b/src/machine/board_arduino_uno_q.go new file mode 100644 index 000000000..8c2412cdf --- /dev/null +++ b/src/machine/board_arduino_uno_q.go @@ -0,0 +1,73 @@ +package tmp +//go:build arduino_uno_q + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} UART1.Interrupt = interrupt.New(stm32.IRQ_USART2, _UART1.handleInterrupt)func init() {) DefaultUART = UART1 } RxAltFuncSelector: AF7_USART1_2_3, TxAltFuncSelector: AF7_USART1_2_3, Bus: stm32.USART2, Buffer: NewRingBuffer(), _UART1 = UART{ UART1 = &_UART1 // debugger to be exposed as virtual COM port over USB. // USART2 is the hardware serial port connected to the onboard ST-LINKvar () UART_RX_PIN = PA3 UART_TX_PIN = PA2 // PA2 and PA3 are connected to the ST-Link Virtual Com Port (VCP) // UART pinsconst () BUTTON = PC13const () LED_GREEN = PA5 LED_BUILTIN = LED_GREEN LED = LED_BUILTINconst () D15 = PB8 D14 = PB9 D13 = PA5 D12 = PA6 D11 = PA7 D10 = PB0 D9 = PC7 D8 = PA9 D7 = PA8 D6 = PB10 D5 = PB4 D4 = PB5 D3 = PB3 D2 = PA10 D1 = PB6 D0 = PB7 A5 = PB12 A4 = PB11 A3 = PB1 A2 = PA4 A1 = PA1 A0 = PA0 // Arduino Pinsconst () "runtime/interrupt" "device/stm32"import (package machine// Arduino UNO Q board with STM32U585 processor. \ No newline at end of file diff --git a/src/machine/machine_stm32_exti_exti.go b/src/machine/machine_stm32_exti_exti.go index 874a04383..b332bfb07 100644 --- a/src/machine/machine_stm32_exti_exti.go +++ b/src/machine/machine_stm32_exti_exti.go @@ -1,4 +1,4 @@ -//go:build stm32l5 +//go:build stm32l5 || stm32u5 package machine diff --git a/src/machine/machine_stm32_exti_syscfg.go b/src/machine/machine_stm32_exti_syscfg.go index 51e1e1a57..4eaa6c4ca 100644 --- a/src/machine/machine_stm32_exti_syscfg.go +++ b/src/machine/machine_stm32_exti_syscfg.go @@ -1,4 +1,4 @@ -//go:build stm32 && !stm32f1 && !stm32l5 && !stm32wlx && !stm32g0 +//go:build stm32 && !stm32f1 && !stm32l5 && !stm32wlx && !stm32g0 && !stm32u5 package machine diff --git a/src/machine/machine_stm32_gpio_reva.go b/src/machine/machine_stm32_gpio_reva.go index d7eaad0ac..27839c491 100644 --- a/src/machine/machine_stm32_gpio_reva.go +++ b/src/machine/machine_stm32_gpio_reva.go @@ -1,4 +1,4 @@ -//go:build stm32 && !stm32l4 && !stm32l5 && !stm32wlx && !stm32g0 +//go:build stm32 && !stm32l4 && !stm32l5 && !stm32wlx && !stm32g0 && !stm32u5 package machine diff --git a/src/machine/machine_stm32_gpio_revb.go b/src/machine/machine_stm32_gpio_revb.go index 49094c730..38278f3e3 100644 --- a/src/machine/machine_stm32_gpio_revb.go +++ b/src/machine/machine_stm32_gpio_revb.go @@ -1,4 +1,4 @@ -//go:build stm32l4 || stm32l5 +//go:build stm32l4 || stm32l5 || stm32u5 package machine diff --git a/src/machine/machine_stm32u5.go b/src/machine/machine_stm32u5.go new file mode 100644 index 000000000..720e26ca2 --- /dev/null +++ b/src/machine/machine_stm32u5.go @@ -0,0 +1,577 @@ +//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") + } +} + +// Enable peripheral clock +func enableAltFuncClock(bus unsafe.Pointer) { + switch bus { + case unsafe.Pointer(stm32.PWR): // Power interface clock enable + // PWR clock is always enabled on U5 (no dedicated enable bit needed) + 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<