diff --git a/src/machine/board_arduino_uno_q.go b/src/machine/board_arduino_uno_q.go index bf26eadb5..4d11ca217 100644 --- a/src/machine/board_arduino_uno_q.go +++ b/src/machine/board_arduino_uno_q.go @@ -7,54 +7,64 @@ package machine import ( "device/stm32" "runtime/interrupt" + "unsafe" ) const ( // Arduino Pins - A0 = PA0 - A1 = PA1 - A2 = PA4 - A3 = PB1 - A4 = PB11 - A5 = PB12 + A0 = PA4 + A1 = PA5 + A2 = PA6 + A3 = PA7 + A4 = PC1 + A5 = PC0 D0 = PB7 D1 = PB6 - D2 = PA10 - D3 = PB3 - D4 = PB5 - D5 = PB4 - D6 = PB10 - D7 = PA8 - D8 = PA9 - D9 = PC7 - D10 = PB0 - D11 = PA7 - D12 = PA6 - D13 = PA5 - D14 = PB9 - D15 = PB8 + D2 = PB3 + D3 = PB0 + D4 = PA12 + D5 = PA11 + D6 = PB1 + D7 = PB2 + D8 = PB4 + D9 = PB8 + D10 = PB9 + D11 = PB15 + D12 = PB14 + D13 = PB13 + D18 = PC1 + D19 = PC0 + D20 = PB10 + D21 = PB11 ) const ( - LED = LED_BUILTIN - LED_BUILTIN = LED_GREEN - LED_GREEN = PA5 + LED = LED3_R + LED3_R = PH10 + LED3_G = PH11 + LED3_B = PH12 + LED4_R = PH13 + LED4_G = PH14 + LED4_B = PH15 ) const ( - BUTTON = PC13 -) + // Default UART pins (LPUART1 active via ST-LINK virtual COM port) + UART_TX_PIN = PG7 + UART_RX_PIN = PG8 -const ( - // UART pins - // PA2 and PA3 are connected to the ST-Link Virtual Com Port (VCP) - UART_TX_PIN = PA2 - UART_RX_PIN = PA3 + // USART1 pins (Arduino header D1/D0) + UART1_TX_PIN = D1 + UART1_RX_PIN = D0 + + // LPUART1 pins (active via ST-LINK virtual COM port) + UART2_TX_PIN = PG7 + UART2_RX_PIN = PG8 // I2C pins - I2C0_SCL_PIN = PB8 - I2C0_SDA_PIN = PB9 + I2C0_SCL_PIN = D20 + I2C0_SDA_PIN = D21 // SPI pins SPI1_SCK_PIN = PA5 @@ -66,23 +76,31 @@ const ( ) var ( - // USART2 is the hardware serial port connected to the onboard ST-LINK - // debugger to be exposed as virtual COM port over USB. + // USART1 on PB6/PB7 (Arduino header D1/D0). UART1 = &_UART1 _UART1 = UART{ Buffer: NewRingBuffer(), - Bus: stm32.USART2, + Bus: stm32.USART1, TxAltFuncSelector: AF7_USART1_2_3, RxAltFuncSelector: AF7_USART1_2_3, } - DefaultUART = UART1 - // I2C1 is documented, alias to I2C0 as well - I2C1 = &I2C{ - Bus: stm32.I2C1, + // LPUART1 on PG7/PG8 (active via ST-LINK virtual COM port). + UART2 = &_UART2 + _UART2 = UART{ + Buffer: NewRingBuffer(), + Bus: (*stm32.USART_Type)(unsafe.Pointer(stm32.LPUART1)), + TxAltFuncSelector: AF8_UART4_5_LPUART1_SDMMC1, + RxAltFuncSelector: AF8_UART4_5_LPUART1_SDMMC1, + } + DefaultUART = UART2 + + // I2C2 is documented, alias to I2C0 as well + I2C2 = &I2C{ + Bus: stm32.I2C2, AltFuncSelector: AF4_I2C1_2_3_4, } - I2C0 = I2C1 + I2C0 = I2C2 // SPI1 is documented, alias to SPI0 as well SPI1 = &SPI{ @@ -93,5 +111,6 @@ var ( ) func init() { - UART1.Interrupt = interrupt.New(stm32.IRQ_USART2, _UART1.handleInterrupt) + UART1.Interrupt = interrupt.New(stm32.IRQ_USART1, _UART1.handleInterrupt) + UART2.Interrupt = interrupt.New(stm32.IRQ_LPUART1, _UART2.handleInterrupt) } diff --git a/src/machine/machine_stm32u5.go b/src/machine/machine_stm32u5.go index 720e26ca2..19efa18ce 100644 --- a/src/machine/machine_stm32u5.go +++ b/src/machine/machine_stm32u5.go @@ -236,13 +236,16 @@ func (p Pin) enableClock() { 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 - // PWR clock is always enabled on U5 (no dedicated enable bit needed) + 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 diff --git a/src/machine/machine_stm32u585.go b/src/machine/machine_stm32u585.go index f5e568bb3..5492e14e6 100644 --- a/src/machine/machine_stm32u585.go +++ b/src/machine/machine_stm32u585.go @@ -4,6 +4,7 @@ package machine import ( "device/stm32" + "unsafe" ) func CPUFrequency() uint32 { @@ -20,8 +21,23 @@ const APB2_TIM_FREQ = 4e6 // 4MHz (MSI default) // Configure the UART. func (uart *UART) configurePins(config UARTConfig) { + if uart.isLPUART1() { + // LPUART1 is on APB3. Explicitly enable its peripheral clock. + stm32.RCC.APB3ENR.SetBits(stm32.RCC_APB3ENR_LPUART1EN) + _ = stm32.RCC.APB3ENR.Get() // delay for clock stabilization + + // Select PCLK3 as LPUART1 kernel clock source. + stm32.RCC.CCIPR3.ReplaceBits( + stm32.RCC_CCIPR3_LPUART1SEL_PCLK3<