diff --git a/src/machine/board_bluepill.go b/src/machine/board_bluepill.go index 7ec73147..39c7d421 100644 --- a/src/machine/board_bluepill.go +++ b/src/machine/board_bluepill.go @@ -2,6 +2,8 @@ package machine +import "device/stm32" + // https://wiki.stm32duino.com/index.php?title=File:Bluepillpinout.gif const ( PA0 = portA + 0 @@ -47,10 +49,28 @@ const ( // UART pins const ( - UART_TX_PIN = PA9 - UART_RX_PIN = PA10 + UART_TX_PIN = PA9 + UART_RX_PIN = PA10 + UART_ALT_TX_PIN = PB6 + UART_ALT_RX_PIN = PB7 ) +var ( + // USART1 is the first hardware serial port on the STM32. + // Both UART0 and UART1 refer to USART1. + UART0 = UART{ + Buffer: NewRingBuffer(), + Bus: stm32.USART1, + IRQVal: stm32.IRQ_USART1, + } + UART1 = &UART0 +) + +//go:export USART1_IRQHandler +func handleUART1() { + UART1.Receive(byte((UART1.Bus.DR.Get() & 0xFF))) +} + // SPI pins const ( SPI0_SCK_PIN = PA5 diff --git a/src/machine/machine_stm32f103xx.go b/src/machine/machine_stm32f103xx.go index 44fa8742..ecded417 100644 --- a/src/machine/machine_stm32f103xx.go +++ b/src/machine/machine_stm32f103xx.go @@ -110,15 +110,10 @@ func (p Pin) Get() bool { // UART type UART struct { Buffer *RingBuffer + Bus *stm32.USART_Type + IRQVal uint32 } -var ( - // USART1 is the first hardware serial port on the STM32. - // Both UART0 and UART1 refer to USART1. - UART0 = UART{Buffer: NewRingBuffer()} - UART1 = &UART0 -) - // Configure the UART. func (uart UART) Configure(config UARTConfig) { // Default baud rate to 115200. @@ -128,53 +123,63 @@ func (uart UART) Configure(config UARTConfig) { // pins switch config.TX { - case PB6: - // use alternate TX/RX pins PB6/PB7 via AFIO mapping + case UART_ALT_TX_PIN: + // use alternate TX/RX pins via AFIO mapping stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_AFIOEN) - stm32.AFIO.MAPR.SetBits(stm32.AFIO_MAPR_USART1_REMAP) - PB6.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull}) - PB7.Configure(PinConfig{Mode: PinInputModeFloating}) + if uart.Bus == stm32.USART1 { + stm32.AFIO.MAPR.SetBits(stm32.AFIO_MAPR_USART1_REMAP) + } else if uart.Bus == stm32.USART2 { + stm32.AFIO.MAPR.SetBits(stm32.AFIO_MAPR_USART2_REMAP) + } + UART_ALT_TX_PIN.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull}) + UART_ALT_RX_PIN.Configure(PinConfig{Mode: PinInputModeFloating}) default: // use standard TX/RX pins PA9 and PA10 UART_TX_PIN.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull}) UART_RX_PIN.Configure(PinConfig{Mode: PinInputModeFloating}) } - // Enable USART1 clock - stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_USART1EN) + // Enable USART clock + if uart.Bus == stm32.USART1 { + stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_USART1EN) + } else if uart.Bus == stm32.USART2 { + stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN) + } // Set baud rate uart.SetBaudRate(config.BaudRate) - // Enable USART1 port. - stm32.USART1.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE) + // Enable USART port + uart.Bus.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE) - // Enable RX IRQ. - arm.SetPriority(stm32.IRQ_USART1, 0xc0) - arm.EnableIRQ(stm32.IRQ_USART1) + // Enable RX IRQ + arm.SetPriority(uart.IRQVal, 0xc0) + arm.EnableIRQ(uart.IRQVal) } // SetBaudRate sets the communication speed for the UART. func (uart UART) SetBaudRate(br uint32) { - // first divide by PCLK2 prescaler (div 1) and then desired baudrate - divider := CPU_FREQUENCY / br - stm32.USART1.BRR.Set(divider) + // Note: PCLK2 (from APB2) used for USART1 and PCLK1 for USART2, 3, 4, 5 + var divider uint32 + if uart.Bus == stm32.USART1 { + // first divide by PCLK2 prescaler (div 1) and then desired baudrate + divider = CPU_FREQUENCY / br + } else { + // first divide by PCLK1 prescaler (div 2) and then desired baudrate + divider = CPU_FREQUENCY / 2 / br + } + uart.Bus.BRR.Set(divider) } // WriteByte writes a byte of data to the UART. func (uart UART) WriteByte(c byte) error { - stm32.USART1.DR.Set(uint32(c)) + uart.Bus.DR.Set(uint32(c)) - for !stm32.USART1.SR.HasBits(stm32.USART_SR_TXE) { + for !uart.Bus.SR.HasBits(stm32.USART_SR_TXE) { } return nil } -//go:export USART1_IRQHandler -func handleUART1() { - UART1.Receive(byte((stm32.USART1.DR.Get() & 0xFF))) -} - // SPI on the STM32. type SPI struct { Bus *stm32.SPI_Type