diff options
author | Patricio Whittingslow <[email protected]> | 2023-07-15 11:24:53 -0300 |
---|---|---|
committer | GitHub <[email protected]> | 2023-07-15 11:24:53 -0300 |
commit | a7b205c26cab4f87d9b2e5e845482cd206ba1daf (patch) | |
tree | 5b47320a07339d7da8e7cd7dfae72224f9f3f48c | |
parent | c83f712c17b6024d2cc3130db1d7bb0899e7b419 (diff) | |
download | tinygo-a7b205c26cab4f87d9b2e5e845482cd206ba1daf.tar.gz tinygo-a7b205c26cab4f87d9b2e5e845482cd206ba1daf.zip |
machine.UART refactor (#3832)
* add gosched calls to UART
* add UART.flush() stubs for all supported architectures
* add comment un uart.go on flush functionality
* uart.writeByte as base of UART usage
* fix NXP having duplicate WriteByte
* fix writeByte not returning error on some platforms
* add flush method for fe310 device
* check for error in WriteByte call to writeByte
-rw-r--r-- | src/machine/machine_atmega.go | 7 | ||||
-rw-r--r-- | src/machine/machine_atsamd21.go | 4 | ||||
-rw-r--r-- | src/machine/machine_atsamd51.go | 4 | ||||
-rw-r--r-- | src/machine/machine_esp32.go | 4 | ||||
-rw-r--r-- | src/machine/machine_esp32c3.go | 4 | ||||
-rw-r--r-- | src/machine/machine_esp8266.go | 6 | ||||
-rw-r--r-- | src/machine/machine_fe310.go | 5 | ||||
-rw-r--r-- | src/machine/machine_k210.go | 5 | ||||
-rw-r--r-- | src/machine/machine_mimxrt1062_uart.go | 4 | ||||
-rw-r--r-- | src/machine/machine_nrf.go | 4 | ||||
-rw-r--r-- | src/machine/machine_nxpmk66f18_uart.go | 4 | ||||
-rw-r--r-- | src/machine/machine_rp2040_uart.go | 9 | ||||
-rw-r--r-- | src/machine/machine_stm32_uart.go | 4 | ||||
-rw-r--r-- | src/machine/uart.go | 22 |
14 files changed, 68 insertions, 18 deletions
diff --git a/src/machine/machine_atmega.go b/src/machine/machine_atmega.go index 90977fb87..81a47c0df 100644 --- a/src/machine/machine_atmega.go +++ b/src/machine/machine_atmega.go @@ -97,7 +97,7 @@ func (i2c *I2C) stop() { } // writeByte writes a single byte to the I2C bus. -func (i2c *I2C) writeByte(data byte) { +func (i2c *I2C) writeByte(data byte) error { // Write data to register. avr.TWDR.Set(data) @@ -107,6 +107,7 @@ func (i2c *I2C) writeByte(data byte) { // Wait till data is transmitted. for !avr.TWCR.HasBits(avr.TWCR_TWINT) { } + return nil } // readByte reads a single byte from the I2C bus. @@ -190,7 +191,7 @@ func (uart *UART) handleInterrupt(intr interrupt.Interrupt) { } // WriteByte writes a byte of data to the UART. -func (uart *UART) WriteByte(c byte) error { +func (uart *UART) writeByte(c byte) error { // Wait until UART buffer is not busy. for !uart.statusRegA.HasBits(avr.UCSR0A_UDRE0) { } @@ -198,6 +199,8 @@ func (uart *UART) WriteByte(c byte) error { return nil } +func (uart *UART) flush() {} + // SPIConfig is used to store config info for SPI. type SPIConfig struct { Frequency uint32 diff --git a/src/machine/machine_atsamd21.go b/src/machine/machine_atsamd21.go index 59df853e5..443c7af56 100644 --- a/src/machine/machine_atsamd21.go +++ b/src/machine/machine_atsamd21.go @@ -626,7 +626,7 @@ func (uart *UART) SetBaudRate(br uint32) { } // WriteByte writes a byte of data to the UART. -func (uart *UART) WriteByte(c byte) error { +func (uart *UART) writeByte(c byte) error { // wait until ready to receive for !uart.Bus.INTFLAG.HasBits(sam.SERCOM_USART_INTFLAG_DRE) { } @@ -634,6 +634,8 @@ func (uart *UART) WriteByte(c byte) error { return nil } +func (uart *UART) flush() {} + // handleInterrupt should be called from the appropriate interrupt handler for // this UART instance. func (uart *UART) handleInterrupt(interrupt.Interrupt) { diff --git a/src/machine/machine_atsamd51.go b/src/machine/machine_atsamd51.go index de5491c88..7c4c4d07c 100644 --- a/src/machine/machine_atsamd51.go +++ b/src/machine/machine_atsamd51.go @@ -1114,7 +1114,7 @@ func (uart *UART) SetBaudRate(br uint32) { } // WriteByte writes a byte of data to the UART. -func (uart *UART) WriteByte(c byte) error { +func (uart *UART) writeByte(c byte) error { // wait until ready to receive for !uart.Bus.INTFLAG.HasBits(sam.SERCOM_USART_INT_INTFLAG_DRE) { } @@ -1122,6 +1122,8 @@ func (uart *UART) WriteByte(c byte) error { return nil } +func (uart *UART) flush() {} + func (uart *UART) handleInterrupt(interrupt.Interrupt) { // should reset IRQ uart.Receive(byte((uart.Bus.DATA.Get() & 0xFF))) diff --git a/src/machine/machine_esp32.go b/src/machine/machine_esp32.go index b58cef66a..4491b3dd9 100644 --- a/src/machine/machine_esp32.go +++ b/src/machine/machine_esp32.go @@ -314,7 +314,7 @@ func (uart *UART) Configure(config UARTConfig) { uart.Bus.CLKDIV.Set(peripheralClock / config.BaudRate) } -func (uart *UART) WriteByte(b byte) error { +func (uart *UART) writeByte(b byte) error { for (uart.Bus.STATUS.Get()>>16)&0xff >= 128 { // Read UART_TXFIFO_CNT from the status register, which indicates how // many bytes there are in the transmit buffer. Wait until there are @@ -324,6 +324,8 @@ func (uart *UART) WriteByte(b byte) error { return nil } +func (uart *UART) flush() {} + // Serial Peripheral Interface on the ESP32. type SPI struct { Bus *esp.SPI_Type diff --git a/src/machine/machine_esp32c3.go b/src/machine/machine_esp32c3.go index f1f646fd5..e447e4fe0 100644 --- a/src/machine/machine_esp32c3.go +++ b/src/machine/machine_esp32c3.go @@ -493,7 +493,7 @@ func (uart *UART) enableReceiver() { uart.Bus.SetINT_ENA_RXFIFO_OVF_INT_ENA(1) } -func (uart *UART) WriteByte(b byte) error { +func (uart *UART) writeByte(b byte) error { for (uart.Bus.STATUS.Get()&esp.UART_STATUS_TXFIFO_CNT_Msk)>>esp.UART_STATUS_TXFIFO_CNT_Pos >= 128 { // Read UART_TXFIFO_CNT from the status register, which indicates how // many bytes there are in the transmit buffer. Wait until there are @@ -502,3 +502,5 @@ func (uart *UART) WriteByte(b byte) error { uart.Bus.FIFO.Set(uint32(b)) return nil } + +func (uart *UART) flush() {} diff --git a/src/machine/machine_esp8266.go b/src/machine/machine_esp8266.go index 37ab29a17..4edd4a535 100644 --- a/src/machine/machine_esp8266.go +++ b/src/machine/machine_esp8266.go @@ -181,12 +181,14 @@ func (uart *UART) Configure(config UARTConfig) { esp.UART0.UART_CLKDIV.Set(CPUFrequency() / config.BaudRate) } -// WriteByte writes a single byte to the output buffer. Note that the hardware +// writeByte writes a single byte to the output buffer. Note that the hardware // includes a buffer of 128 bytes which will be used first. -func (uart *UART) WriteByte(c byte) error { +func (uart *UART) writeByte(c byte) error { for (esp.UART0.UART_STATUS.Get()>>16)&0xff >= 128 { // Wait until the TX buffer has room. } esp.UART0.UART_FIFO.Set(uint32(c)) return nil } + +func (uart *UART) flush() {} diff --git a/src/machine/machine_fe310.go b/src/machine/machine_fe310.go index 3a0c45134..85a2c5bd3 100644 --- a/src/machine/machine_fe310.go +++ b/src/machine/machine_fe310.go @@ -111,13 +111,16 @@ func (uart *UART) handleInterrupt(interrupt.Interrupt) { uart.Receive(c) } -func (uart *UART) WriteByte(c byte) { +func (uart *UART) writeByte(c byte) error { for sifive.UART0.TXDATA.Get()&sifive.UART_TXDATA_FULL != 0 { } sifive.UART0.TXDATA.Set(uint32(c)) + return nil } +func (uart *UART) flush() {} + // SPI on the FE310. The normal SPI0 is actually a quad-SPI meant for flash, so it is best // to use SPI1 or SPI2 port for most applications. type SPI struct { diff --git a/src/machine/machine_k210.go b/src/machine/machine_k210.go index 9c63a8f76..e8a304c85 100644 --- a/src/machine/machine_k210.go +++ b/src/machine/machine_k210.go @@ -392,13 +392,16 @@ func (uart *UART) handleInterrupt(interrupt.Interrupt) { uart.Receive(c) } -func (uart *UART) WriteByte(c byte) { +func (uart *UART) writeByte(c byte) error { for uart.Bus.TXDATA.Get()&kendryte.UARTHS_TXDATA_FULL != 0 { } uart.Bus.TXDATA.Set(uint32(c)) + return nil } +func (uart *UART) flush() {} + type SPI struct { Bus *kendryte.SPI_Type } diff --git a/src/machine/machine_mimxrt1062_uart.go b/src/machine/machine_mimxrt1062_uart.go index d24206dfb..6265b8565 100644 --- a/src/machine/machine_mimxrt1062_uart.go +++ b/src/machine/machine_mimxrt1062_uart.go @@ -173,7 +173,7 @@ func (uart *UART) Sync() error { } // WriteByte writes a single byte of data to the UART interface. -func (uart *UART) WriteByte(c byte) error { +func (uart *UART) writeByte(c byte) error { uart.startTransmitting() for !uart.txBuffer.Put(c) { } @@ -181,6 +181,8 @@ func (uart *UART) WriteByte(c byte) error { return nil } +func (uart *UART) flush() {} + // getBaudRateDivisor finds the greatest over-sampling factor (4..32) and // corresponding baud rate divisor (1..8191) that best partition a given baud // rate into equal intervals. diff --git a/src/machine/machine_nrf.go b/src/machine/machine_nrf.go index 83fa57b3e..346a0bb2e 100644 --- a/src/machine/machine_nrf.go +++ b/src/machine/machine_nrf.go @@ -186,7 +186,7 @@ func (uart *UART) SetBaudRate(br uint32) { } // WriteByte writes a byte of data to the UART. -func (uart *UART) WriteByte(c byte) error { +func (uart *UART) writeByte(c byte) error { nrf.UART0.EVENTS_TXDRDY.Set(0) nrf.UART0.TXD.Set(uint32(c)) for nrf.UART0.EVENTS_TXDRDY.Get() == 0 { @@ -194,6 +194,8 @@ func (uart *UART) WriteByte(c byte) error { return nil } +func (uart *UART) flush() {} + func (uart *UART) handleInterrupt(interrupt.Interrupt) { if nrf.UART0.EVENTS_RXDRDY.Get() != 0 { uart.Receive(byte(nrf.UART0.RXD.Get())) diff --git a/src/machine/machine_nxpmk66f18_uart.go b/src/machine/machine_nxpmk66f18_uart.go index d62fc64e0..a14d18f5e 100644 --- a/src/machine/machine_nxpmk66f18_uart.go +++ b/src/machine/machine_nxpmk66f18_uart.go @@ -292,7 +292,7 @@ func (u *UART) handleStatusInterrupt(interrupt.Interrupt) { } // WriteByte writes a byte of data to the UART. -func (u *UART) WriteByte(c byte) error { +func (u *UART) writeByte(c byte) error { if !u.Configured { return ErrNotConfigured } @@ -305,3 +305,5 @@ func (u *UART) WriteByte(c byte) error { u.C2.Set(uartC2TXActive) return nil } + +func (uart *UART) flush() {} diff --git a/src/machine/machine_rp2040_uart.go b/src/machine/machine_rp2040_uart.go index e5e4f77de..1d927df12 100644 --- a/src/machine/machine_rp2040_uart.go +++ b/src/machine/machine_rp2040_uart.go @@ -86,9 +86,10 @@ func (uart *UART) SetBaudRate(br uint32) { } // WriteByte writes a byte of data to the UART. -func (uart *UART) WriteByte(c byte) error { +func (uart *UART) writeByte(c byte) error { // wait until buffer is not full for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_TXFF) { + gosched() } // write data @@ -96,6 +97,12 @@ func (uart *UART) WriteByte(c byte) error { return nil } +func (uart *UART) flush() { + for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_BUSY) { + gosched() + } +} + // SetFormat for number of data bits, stop bits, and parity for the UART. func (uart *UART) SetFormat(databits, stopbits uint8, parity UARTParity) error { var pen, pev uint8 diff --git a/src/machine/machine_stm32_uart.go b/src/machine/machine_stm32_uart.go index 6ae6f0f99..6e8806c87 100644 --- a/src/machine/machine_stm32_uart.go +++ b/src/machine/machine_stm32_uart.go @@ -74,10 +74,12 @@ func (uart *UART) SetBaudRate(br uint32) { } // WriteByte writes a byte of data to the UART. -func (uart *UART) WriteByte(c byte) error { +func (uart *UART) writeByte(c byte) error { uart.txReg.Set(uint32(c)) for !uart.statusReg.HasBits(uart.txEmptyFlag) { } return nil } + +func (uart *UART) flush() {} diff --git a/src/machine/uart.go b/src/machine/uart.go index 37d322332..eeeb7d6a0 100644 --- a/src/machine/uart.go +++ b/src/machine/uart.go @@ -59,11 +59,27 @@ func (uart *UART) Read(data []byte) (n int, err error) { return size, nil } -// Write data to the UART. +// WriteByte writes a byte of data over the UART's Tx. +// This function blocks until the data is finished being sent. +func (uart *UART) WriteByte(c byte) error { + err := uart.writeByte(c) + if err != nil { + return err + } + uart.flush() // flush() blocks until all data has been transmitted. + return nil +} + +// Write data over the UART's Tx. +// This function blocks until the data is finished being sent. func (uart *UART) Write(data []byte) (n int, err error) { - for _, v := range data { - uart.WriteByte(v) + for i, v := range data { + err = uart.writeByte(v) + if err != nil { + return i, err + } } + uart.flush() // flush() blocks until all data has been transmitted. return len(data), nil } |