github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_stm32_uart.go (about) 1 //go:build stm32 2 3 package machine 4 5 // Peripheral abstraction layer for UARTs on the stm32 family. 6 7 import ( 8 "device/stm32" 9 "runtime/interrupt" 10 "runtime/volatile" 11 "unsafe" 12 ) 13 14 // UART representation 15 type UART struct { 16 Buffer *RingBuffer 17 Bus *stm32.USART_Type 18 Interrupt interrupt.Interrupt 19 TxAltFuncSelector uint8 20 RxAltFuncSelector uint8 21 22 // Registers specific to the chip 23 rxReg *volatile.Register32 24 txReg *volatile.Register32 25 statusReg *volatile.Register32 26 txEmptyFlag uint32 27 } 28 29 // Configure the UART. 30 func (uart *UART) Configure(config UARTConfig) { 31 // Default baud rate to 115200. 32 if config.BaudRate == 0 { 33 config.BaudRate = 115200 34 } 35 36 // Set the GPIO pins to defaults if they're not set 37 if config.TX == 0 && config.RX == 0 { 38 config.TX = UART_TX_PIN 39 config.RX = UART_RX_PIN 40 } 41 42 // STM32 families have different, but compatible, registers for 43 // basic UART functions. For each family populate the registers 44 // into `uart`. 45 uart.setRegisters() 46 47 // Enable USART clock 48 enableAltFuncClock(unsafe.Pointer(uart.Bus)) 49 50 uart.configurePins(config) 51 52 // Set baud rate 53 uart.SetBaudRate(config.BaudRate) 54 55 // Enable USART port, tx, rx and rx interrupts 56 uart.Bus.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE) 57 58 // Enable RX IRQ 59 uart.Interrupt.SetPriority(0xc0) 60 uart.Interrupt.Enable() 61 } 62 63 // handleInterrupt should be called from the appropriate interrupt handler for 64 // this UART instance. 65 func (uart *UART) handleInterrupt(interrupt.Interrupt) { 66 uart.Receive(byte((uart.rxReg.Get() & 0xFF))) 67 } 68 69 // SetBaudRate sets the communication speed for the UART. Defer to chip-specific 70 // routines for calculation 71 func (uart *UART) SetBaudRate(br uint32) { 72 divider := uart.getBaudRateDivisor(br) 73 uart.Bus.BRR.Set(divider) 74 } 75 76 // WriteByte writes a byte of data to the UART. 77 func (uart *UART) writeByte(c byte) error { 78 uart.txReg.Set(uint32(c)) 79 80 for !uart.statusReg.HasBits(uart.txEmptyFlag) { 81 } 82 return nil 83 } 84 85 func (uart *UART) flush() {}