aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/machine
diff options
context:
space:
mode:
authorPatricio Whittingslow <[email protected]>2023-07-15 11:24:53 -0300
committerGitHub <[email protected]>2023-07-15 11:24:53 -0300
commita7b205c26cab4f87d9b2e5e845482cd206ba1daf (patch)
tree5b47320a07339d7da8e7cd7dfae72224f9f3f48c /src/machine
parentc83f712c17b6024d2cc3130db1d7bb0899e7b419 (diff)
downloadtinygo-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
Diffstat (limited to 'src/machine')
-rw-r--r--src/machine/machine_atmega.go7
-rw-r--r--src/machine/machine_atsamd21.go4
-rw-r--r--src/machine/machine_atsamd51.go4
-rw-r--r--src/machine/machine_esp32.go4
-rw-r--r--src/machine/machine_esp32c3.go4
-rw-r--r--src/machine/machine_esp8266.go6
-rw-r--r--src/machine/machine_fe310.go5
-rw-r--r--src/machine/machine_k210.go5
-rw-r--r--src/machine/machine_mimxrt1062_uart.go4
-rw-r--r--src/machine/machine_nrf.go4
-rw-r--r--src/machine/machine_nxpmk66f18_uart.go4
-rw-r--r--src/machine/machine_rp2040_uart.go9
-rw-r--r--src/machine/machine_stm32_uart.go4
-rw-r--r--src/machine/uart.go22
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
}