diff --git a/src/machine/machine_stm32_f7_uart.go b/src/machine/machine_stm32_f7_uart.go deleted file mode 100644 index d1de87a2..00000000 --- a/src/machine/machine_stm32_f7_uart.go +++ /dev/null @@ -1,62 +0,0 @@ -// +build stm32f7 - -package machine - -// Peripheral abstraction layer for UARTs on the stm32 family. - -import ( - "device/stm32" - "runtime/interrupt" - "unsafe" -) - -// Configure the UART. -func (uart UART) Configure(config UARTConfig) { - // Default baud rate to 115200. - if config.BaudRate == 0 { - config.BaudRate = 115200 - } - - // Set the GPIO pins to defaults if they're not set - if config.TX == 0 && config.RX == 0 { - config.TX = UART_TX_PIN - config.RX = UART_RX_PIN - } - - // Enable USART clock - enableAltFuncClock(unsafe.Pointer(uart.Bus)) - - uart.configurePins(config) - - // Set baud rate - uart.SetBaudRate(config.BaudRate) - - // Enable USART port, tx, rx and rx interrupts - uart.Bus.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE) - - // Enable RX IRQ - uart.Interrupt.SetPriority(0xc0) - uart.Interrupt.Enable() -} - -// handleInterrupt should be called from the appropriate interrupt handler for -// this UART instance. -func (uart *UART) handleInterrupt(interrupt.Interrupt) { - uart.Receive(byte((uart.Bus.RDR.Get() & 0xFF))) -} - -// SetBaudRate sets the communication speed for the UART. Defer to chip-specific -// routines for calculation -func (uart UART) SetBaudRate(br uint32) { - divider := uart.getBaudRateDivisor(br) - uart.Bus.BRR.Set(divider) -} - -// WriteByte writes a byte of data to the UART. -func (uart UART) WriteByte(c byte) error { - uart.Bus.TDR.Set(uint32(c)) - - for !uart.Bus.ISR.HasBits(stm32.USART_ISR_TXE) { - } - return nil -} diff --git a/src/machine/machine_stm32_l5_uart.go b/src/machine/machine_stm32_l5_uart.go deleted file mode 100644 index ffae11c5..00000000 --- a/src/machine/machine_stm32_l5_uart.go +++ /dev/null @@ -1,62 +0,0 @@ -// +build stm32,stm32l5x2 - -package machine - -// Peripheral abstraction layer for UARTs on the stm32 family. - -import ( - "device/stm32" - "runtime/interrupt" - "unsafe" -) - -// Configure the UART. -func (uart UART) Configure(config UARTConfig) { - // Default baud rate to 115200. - if config.BaudRate == 0 { - config.BaudRate = 115200 - } - - // Set the GPIO pins to defaults if they're not set - if config.TX == 0 && config.RX == 0 { - config.TX = UART_TX_PIN - config.RX = UART_RX_PIN - } - - // Enable USART clock - enableAltFuncClock(unsafe.Pointer(uart.Bus)) - - uart.configurePins(config) - - // Set baud rate - uart.SetBaudRate(config.BaudRate) - - // Enable USART port, tx, rx and rx interrupts - uart.Bus.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE) - - // Enable RX IRQ - uart.Interrupt.SetPriority(0xc0) - uart.Interrupt.Enable() -} - -// handleInterrupt should be called from the appropriate interrupt handler for -// this UART instance. -func (uart *UART) handleInterrupt(interrupt.Interrupt) { - uart.Receive(byte((uart.Bus.RDR.Get() & 0xFF))) -} - -// SetBaudRate sets the communication speed for the UART. Defer to chip-specific -// routines for calculation -func (uart UART) SetBaudRate(br uint32) { - divider := uart.getBaudRateDivisor(br) - uart.Bus.BRR.Set(divider) -} - -// WriteByte writes a byte of data to the UART. -func (uart UART) WriteByte(c byte) error { - uart.Bus.TDR.Set(uint32(c)) - - for !uart.Bus.ISR.HasBits(stm32.USART_ISR_TXE) { - } - return nil -} diff --git a/src/machine/machine_stm32_uart.go b/src/machine/machine_stm32_uart.go index 84bc1093..a3a99cd1 100644 --- a/src/machine/machine_stm32_uart.go +++ b/src/machine/machine_stm32_uart.go @@ -1,4 +1,4 @@ -// +build stm32,!stm32f7,!stm32l5x2,!stm32l0 +// +build stm32,!stm32l0 package machine @@ -7,11 +7,26 @@ package machine import ( "device/stm32" "runtime/interrupt" + "runtime/volatile" "unsafe" ) +// UART representation +type UART struct { + Buffer *RingBuffer + Bus *stm32.USART_Type + Interrupt interrupt.Interrupt + AltFuncSelector stm32.AltFunc + + // Registers specific to the chip + rxReg *volatile.Register32 + txReg *volatile.Register32 + statusReg *volatile.Register32 + txEmptyFlag uint32 +} + // Configure the UART. -func (uart UART) Configure(config UARTConfig) { +func (uart *UART) Configure(config UARTConfig) { // Default baud rate to 115200. if config.BaudRate == 0 { config.BaudRate = 115200 @@ -23,6 +38,11 @@ func (uart UART) Configure(config UARTConfig) { config.RX = UART_RX_PIN } + // STM32 families have different, but compatible, registers for + // basic UART functions. For each family populate the registers + // into `uart`. + uart.setRegisters() + // Enable USART clock enableAltFuncClock(unsafe.Pointer(uart.Bus)) @@ -42,21 +62,21 @@ func (uart UART) Configure(config UARTConfig) { // handleInterrupt should be called from the appropriate interrupt handler for // this UART instance. func (uart *UART) handleInterrupt(interrupt.Interrupt) { - uart.Receive(byte((uart.Bus.DR.Get() & 0xFF))) + uart.Receive(byte((uart.rxReg.Get() & 0xFF))) } // SetBaudRate sets the communication speed for the UART. Defer to chip-specific // routines for calculation -func (uart UART) SetBaudRate(br uint32) { +func (uart *UART) SetBaudRate(br uint32) { divider := uart.getBaudRateDivisor(br) uart.Bus.BRR.Set(divider) } // WriteByte writes a byte of data to the UART. -func (uart UART) WriteByte(c byte) error { - uart.Bus.DR.Set(uint32(c)) +func (uart *UART) WriteByte(c byte) error { + uart.txReg.Set(uint32(c)) - for !uart.Bus.SR.HasBits(stm32.USART_SR_TXE) { + for !uart.statusReg.HasBits(uart.txEmptyFlag) { } return nil } diff --git a/src/machine/machine_stm32f103.go b/src/machine/machine_stm32f103.go index 4d422733..2de299c5 100644 --- a/src/machine/machine_stm32f103.go +++ b/src/machine/machine_stm32f103.go @@ -6,7 +6,6 @@ package machine import ( "device/stm32" - "runtime/interrupt" "unsafe" ) @@ -103,17 +102,10 @@ func enableAltFuncClock(bus unsafe.Pointer) { } } -//---------- UART related types and code - -// UART representation -type UART struct { - Buffer *RingBuffer - Bus *stm32.USART_Type - Interrupt interrupt.Interrupt -} +//---------- UART related code // Configure the TX and RX pins -func (uart UART) configurePins(config UARTConfig) { +func (uart *UART) configurePins(config UARTConfig) { // pins switch config.TX { @@ -133,7 +125,7 @@ func (uart UART) configurePins(config UARTConfig) { } // Determine the divisor for USARTs to get the given baudrate -func (uart UART) getBaudRateDivisor(br uint32) uint32 { +func (uart *UART) getBaudRateDivisor(br uint32) uint32 { // Note: PCLK2 (from APB2) used for USART1 and PCLK1 for USART2, 3, 4, 5 var divider uint32 @@ -147,6 +139,14 @@ func (uart UART) getBaudRateDivisor(br uint32) uint32 { return divider } +// Register names vary by ST processor, these are for STM F103xx +func (uart *UART) setRegisters() { + uart.rxReg = &uart.Bus.DR + uart.txReg = &uart.Bus.DR + uart.statusReg = &uart.Bus.SR + uart.txEmptyFlag = stm32.USART_SR_TXE +} + //---------- SPI related types and code type SPI struct { diff --git a/src/machine/machine_stm32f405.go b/src/machine/machine_stm32f405.go index de11e792..eb54c2af 100644 --- a/src/machine/machine_stm32f405.go +++ b/src/machine/machine_stm32f405.go @@ -7,7 +7,6 @@ package machine import ( "device/stm32" "math/bits" - "runtime/interrupt" ) func CPUFrequency() uint32 { @@ -36,20 +35,13 @@ const ( // -- UART --------------------------------------------------------------------- -type UART struct { - Buffer *RingBuffer - Bus *stm32.USART_Type - Interrupt interrupt.Interrupt - AltFuncSelector uint8 -} - -func (uart UART) configurePins(config UARTConfig) { +func (uart *UART) configurePins(config UARTConfig) { // enable the alternate functions on the TX and RX pins config.TX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTTX}, uart.AltFuncSelector) config.RX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTRX}, uart.AltFuncSelector) } -func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 { +func (uart *UART) getBaudRateDivisor(baudRate uint32) uint32 { var clock uint32 switch uart.Bus { case stm32.USART1, stm32.USART6: @@ -60,6 +52,14 @@ func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 { return clock / baudRate } +// Register names vary by ST processor, these are for STM F405 +func (uart *UART) setRegisters() { + uart.rxReg = &uart.Bus.DR + uart.txReg = &uart.Bus.DR + uart.statusReg = &uart.Bus.SR + uart.txEmptyFlag = stm32.USART_SR_TXE +} + // -- SPI ---------------------------------------------------------------------- type SPI struct { diff --git a/src/machine/machine_stm32f407.go b/src/machine/machine_stm32f407.go index ae1ba0c8..a0d9e190 100644 --- a/src/machine/machine_stm32f407.go +++ b/src/machine/machine_stm32f407.go @@ -6,7 +6,6 @@ package machine import ( "device/stm32" - "runtime/interrupt" ) func CPUFrequency() uint32 { @@ -33,18 +32,10 @@ const ( AF15_EVENTOUT = 15 ) -//---------- UART related types and code - -// UART representation -type UART struct { - Buffer *RingBuffer - Bus *stm32.USART_Type - Interrupt interrupt.Interrupt - AltFuncSelector uint8 -} +//---------- UART related code // Configure the UART. -func (uart UART) configurePins(config UARTConfig) { +func (uart *UART) configurePins(config UARTConfig) { // enable the alternate functions on the TX and RX pins config.TX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTTX}, uart.AltFuncSelector) config.RX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTRX}, uart.AltFuncSelector) @@ -52,7 +43,7 @@ func (uart UART) configurePins(config UARTConfig) { // UART baudrate calc based on the bus and clockspeed // NOTE: keep this in sync with the runtime/runtime_stm32f407.go clock init code -func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 { +func (uart *UART) getBaudRateDivisor(baudRate uint32) uint32 { var clock uint32 switch uart.Bus { case stm32.USART1, stm32.USART6: @@ -63,6 +54,14 @@ func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 { return clock / baudRate } +// Register names vary by ST processor, these are for STM F407 +func (uart *UART) setRegisters() { + uart.rxReg = &uart.Bus.DR + uart.txReg = &uart.Bus.DR + uart.statusReg = &uart.Bus.SR + uart.txEmptyFlag = stm32.USART_SR_TXE +} + //---------- SPI related types and code // SPI on the STM32Fxxx using MODER / alternate function pins diff --git a/src/machine/machine_stm32f7x2.go b/src/machine/machine_stm32f7x2.go index 7ebca01e..2724c6e4 100644 --- a/src/machine/machine_stm32f7x2.go +++ b/src/machine/machine_stm32f7x2.go @@ -6,25 +6,16 @@ package machine import ( "device/stm32" - "runtime/interrupt" ) func CPUFrequency() uint32 { return 216000000 } -//---------- UART related types and code - -// UART representation -type UART struct { - Buffer *RingBuffer - Bus *stm32.USART_Type - Interrupt interrupt.Interrupt - AltFuncSelector uint8 -} +//---------- UART related code // Configure the UART. -func (uart UART) configurePins(config UARTConfig) { +func (uart *UART) configurePins(config UARTConfig) { // enable the alternate functions on the TX and RX pins config.TX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTTX}, uart.AltFuncSelector) config.RX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTRX}, uart.AltFuncSelector) @@ -32,7 +23,7 @@ func (uart UART) configurePins(config UARTConfig) { // UART baudrate calc based on the bus and clockspeed // NOTE: keep this in sync with the runtime/runtime_stm32f7x2.go clock init code -func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 { +func (uart *UART) getBaudRateDivisor(baudRate uint32) uint32 { var clock uint32 switch uart.Bus { case stm32.USART1, stm32.USART6: @@ -42,3 +33,11 @@ func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 { } return clock / baudRate } + +// Register names vary by ST processor, these are for STM F7x2 +func (uart *UART) setRegisters() { + uart.rxReg = &uart.Bus.RDR + uart.txReg = &uart.Bus.TDR + uart.statusReg = &uart.Bus.ISR + uart.txEmptyFlag = stm32.USART_ISR_TXE +} diff --git a/src/machine/machine_stm32l5x2.go b/src/machine/machine_stm32l5x2.go index 16344620..898be952 100644 --- a/src/machine/machine_stm32l5x2.go +++ b/src/machine/machine_stm32l5x2.go @@ -6,25 +6,16 @@ package machine import ( "device/stm32" - "runtime/interrupt" ) func CPUFrequency() uint32 { return 110000000 } -//---------- UART related types and code - -// UART representation -type UART struct { - Buffer *RingBuffer - Bus *stm32.USART_Type - Interrupt interrupt.Interrupt - AltFuncSelector stm32.AltFunc -} +//---------- UART related code // Configure the UART. -func (uart UART) configurePins(config UARTConfig) { +func (uart *UART) configurePins(config UARTConfig) { if config.RX.getPort() == stm32.GPIOG || config.TX.getPort() == stm32.GPIOG { // Enable VDDIO2 power supply, which is an independant power supply for the PGx pins stm32.PWR.CR2.SetBits(stm32.PWR_CR2_IOSV) @@ -37,6 +28,14 @@ func (uart UART) configurePins(config UARTConfig) { // UART baudrate calc based on the bus and clockspeed // NOTE: keep this in sync with the runtime/runtime_stm32l5x2.go clock init code -func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 { +func (uart *UART) getBaudRateDivisor(baudRate uint32) uint32 { return 256 * (CPUFrequency() / baudRate) } + +// Register names vary by ST processor, these are for STM L5 +func (uart *UART) setRegisters() { + uart.rxReg = &uart.Bus.RDR + uart.txReg = &uart.Bus.TDR + uart.statusReg = &uart.Bus.ISR + uart.txEmptyFlag = stm32.USART_ISR_TXE +}