Skip to content

Commit 9ecaddd

Browse files
soypatdeadprogram
authored andcommitted
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
1 parent 97fea1c commit 9ecaddd

14 files changed

+68
-18
lines changed

src/machine/machine_atmega.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func (i2c *I2C) stop() {
9797
}
9898

9999
// writeByte writes a single byte to the I2C bus.
100-
func (i2c *I2C) writeByte(data byte) {
100+
func (i2c *I2C) writeByte(data byte) error {
101101
// Write data to register.
102102
avr.TWDR.Set(data)
103103

@@ -107,6 +107,7 @@ func (i2c *I2C) writeByte(data byte) {
107107
// Wait till data is transmitted.
108108
for !avr.TWCR.HasBits(avr.TWCR_TWINT) {
109109
}
110+
return nil
110111
}
111112

112113
// readByte reads a single byte from the I2C bus.
@@ -190,14 +191,16 @@ func (uart *UART) handleInterrupt(intr interrupt.Interrupt) {
190191
}
191192

192193
// WriteByte writes a byte of data to the UART.
193-
func (uart *UART) WriteByte(c byte) error {
194+
func (uart *UART) writeByte(c byte) error {
194195
// Wait until UART buffer is not busy.
195196
for !uart.statusRegA.HasBits(avr.UCSR0A_UDRE0) {
196197
}
197198
uart.dataReg.Set(c) // send char
198199
return nil
199200
}
200201

202+
func (uart *UART) flush() {}
203+
201204
// SPIConfig is used to store config info for SPI.
202205
type SPIConfig struct {
203206
Frequency uint32

src/machine/machine_atsamd21.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -626,14 +626,16 @@ func (uart *UART) SetBaudRate(br uint32) {
626626
}
627627

628628
// WriteByte writes a byte of data to the UART.
629-
func (uart *UART) WriteByte(c byte) error {
629+
func (uart *UART) writeByte(c byte) error {
630630
// wait until ready to receive
631631
for !uart.Bus.INTFLAG.HasBits(sam.SERCOM_USART_INTFLAG_DRE) {
632632
}
633633
uart.Bus.DATA.Set(uint16(c))
634634
return nil
635635
}
636636

637+
func (uart *UART) flush() {}
638+
637639
// handleInterrupt should be called from the appropriate interrupt handler for
638640
// this UART instance.
639641
func (uart *UART) handleInterrupt(interrupt.Interrupt) {

src/machine/machine_atsamd51.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -1114,14 +1114,16 @@ func (uart *UART) SetBaudRate(br uint32) {
11141114
}
11151115

11161116
// WriteByte writes a byte of data to the UART.
1117-
func (uart *UART) WriteByte(c byte) error {
1117+
func (uart *UART) writeByte(c byte) error {
11181118
// wait until ready to receive
11191119
for !uart.Bus.INTFLAG.HasBits(sam.SERCOM_USART_INT_INTFLAG_DRE) {
11201120
}
11211121
uart.Bus.DATA.Set(uint32(c))
11221122
return nil
11231123
}
11241124

1125+
func (uart *UART) flush() {}
1126+
11251127
func (uart *UART) handleInterrupt(interrupt.Interrupt) {
11261128
// should reset IRQ
11271129
uart.Receive(byte((uart.Bus.DATA.Get() & 0xFF)))

src/machine/machine_esp32.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ func (uart *UART) Configure(config UARTConfig) {
314314
uart.Bus.CLKDIV.Set(peripheralClock / config.BaudRate)
315315
}
316316

317-
func (uart *UART) WriteByte(b byte) error {
317+
func (uart *UART) writeByte(b byte) error {
318318
for (uart.Bus.STATUS.Get()>>16)&0xff >= 128 {
319319
// Read UART_TXFIFO_CNT from the status register, which indicates how
320320
// many bytes there are in the transmit buffer. Wait until there are
@@ -324,6 +324,8 @@ func (uart *UART) WriteByte(b byte) error {
324324
return nil
325325
}
326326

327+
func (uart *UART) flush() {}
328+
327329
// Serial Peripheral Interface on the ESP32.
328330
type SPI struct {
329331
Bus *esp.SPI_Type

src/machine/machine_esp32c3.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ func (uart *UART) enableReceiver() {
493493
uart.Bus.SetINT_ENA_RXFIFO_OVF_INT_ENA(1)
494494
}
495495

496-
func (uart *UART) WriteByte(b byte) error {
496+
func (uart *UART) writeByte(b byte) error {
497497
for (uart.Bus.STATUS.Get()&esp.UART_STATUS_TXFIFO_CNT_Msk)>>esp.UART_STATUS_TXFIFO_CNT_Pos >= 128 {
498498
// Read UART_TXFIFO_CNT from the status register, which indicates how
499499
// many bytes there are in the transmit buffer. Wait until there are
@@ -502,3 +502,5 @@ func (uart *UART) WriteByte(b byte) error {
502502
uart.Bus.FIFO.Set(uint32(b))
503503
return nil
504504
}
505+
506+
func (uart *UART) flush() {}

src/machine/machine_esp8266.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,14 @@ func (uart *UART) Configure(config UARTConfig) {
181181
esp.UART0.UART_CLKDIV.Set(CPUFrequency() / config.BaudRate)
182182
}
183183

184-
// WriteByte writes a single byte to the output buffer. Note that the hardware
184+
// writeByte writes a single byte to the output buffer. Note that the hardware
185185
// includes a buffer of 128 bytes which will be used first.
186-
func (uart *UART) WriteByte(c byte) error {
186+
func (uart *UART) writeByte(c byte) error {
187187
for (esp.UART0.UART_STATUS.Get()>>16)&0xff >= 128 {
188188
// Wait until the TX buffer has room.
189189
}
190190
esp.UART0.UART_FIFO.Set(uint32(c))
191191
return nil
192192
}
193+
194+
func (uart *UART) flush() {}

src/machine/machine_fe310.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,16 @@ func (uart *UART) handleInterrupt(interrupt.Interrupt) {
111111
uart.Receive(c)
112112
}
113113

114-
func (uart *UART) WriteByte(c byte) {
114+
func (uart *UART) writeByte(c byte) error {
115115
for sifive.UART0.TXDATA.Get()&sifive.UART_TXDATA_FULL != 0 {
116116
}
117117

118118
sifive.UART0.TXDATA.Set(uint32(c))
119+
return nil
119120
}
120121

122+
func (uart *UART) flush() {}
123+
121124
// SPI on the FE310. The normal SPI0 is actually a quad-SPI meant for flash, so it is best
122125
// to use SPI1 or SPI2 port for most applications.
123126
type SPI struct {

src/machine/machine_k210.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -392,13 +392,16 @@ func (uart *UART) handleInterrupt(interrupt.Interrupt) {
392392
uart.Receive(c)
393393
}
394394

395-
func (uart *UART) WriteByte(c byte) {
395+
func (uart *UART) writeByte(c byte) error {
396396
for uart.Bus.TXDATA.Get()&kendryte.UARTHS_TXDATA_FULL != 0 {
397397
}
398398

399399
uart.Bus.TXDATA.Set(uint32(c))
400+
return nil
400401
}
401402

403+
func (uart *UART) flush() {}
404+
402405
type SPI struct {
403406
Bus *kendryte.SPI_Type
404407
}

src/machine/machine_mimxrt1062_uart.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,16 @@ func (uart *UART) Sync() error {
173173
}
174174

175175
// WriteByte writes a single byte of data to the UART interface.
176-
func (uart *UART) WriteByte(c byte) error {
176+
func (uart *UART) writeByte(c byte) error {
177177
uart.startTransmitting()
178178
for !uart.txBuffer.Put(c) {
179179
}
180180
uart.Bus.CTRL.SetBits(nxp.LPUART_CTRL_TIE)
181181
return nil
182182
}
183183

184+
func (uart *UART) flush() {}
185+
184186
// getBaudRateDivisor finds the greatest over-sampling factor (4..32) and
185187
// corresponding baud rate divisor (1..8191) that best partition a given baud
186188
// rate into equal intervals.

src/machine/machine_nrf.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,16 @@ func (uart *UART) SetBaudRate(br uint32) {
186186
}
187187

188188
// WriteByte writes a byte of data to the UART.
189-
func (uart *UART) WriteByte(c byte) error {
189+
func (uart *UART) writeByte(c byte) error {
190190
nrf.UART0.EVENTS_TXDRDY.Set(0)
191191
nrf.UART0.TXD.Set(uint32(c))
192192
for nrf.UART0.EVENTS_TXDRDY.Get() == 0 {
193193
}
194194
return nil
195195
}
196196

197+
func (uart *UART) flush() {}
198+
197199
func (uart *UART) handleInterrupt(interrupt.Interrupt) {
198200
if nrf.UART0.EVENTS_RXDRDY.Get() != 0 {
199201
uart.Receive(byte(nrf.UART0.RXD.Get()))

src/machine/machine_nxpmk66f18_uart.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ func (u *UART) handleStatusInterrupt(interrupt.Interrupt) {
292292
}
293293

294294
// WriteByte writes a byte of data to the UART.
295-
func (u *UART) WriteByte(c byte) error {
295+
func (u *UART) writeByte(c byte) error {
296296
if !u.Configured {
297297
return ErrNotConfigured
298298
}
@@ -305,3 +305,5 @@ func (u *UART) WriteByte(c byte) error {
305305
u.C2.Set(uartC2TXActive)
306306
return nil
307307
}
308+
309+
func (uart *UART) flush() {}

src/machine/machine_rp2040_uart.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,23 @@ func (uart *UART) SetBaudRate(br uint32) {
8686
}
8787

8888
// WriteByte writes a byte of data to the UART.
89-
func (uart *UART) WriteByte(c byte) error {
89+
func (uart *UART) writeByte(c byte) error {
9090
// wait until buffer is not full
9191
for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_TXFF) {
92+
gosched()
9293
}
9394

9495
// write data
9596
uart.Bus.UARTDR.Set(uint32(c))
9697
return nil
9798
}
9899

100+
func (uart *UART) flush() {
101+
for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_BUSY) {
102+
gosched()
103+
}
104+
}
105+
99106
// SetFormat for number of data bits, stop bits, and parity for the UART.
100107
func (uart *UART) SetFormat(databits, stopbits uint8, parity UARTParity) error {
101108
var pen, pev uint8

src/machine/machine_stm32_uart.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,12 @@ func (uart *UART) SetBaudRate(br uint32) {
7474
}
7575

7676
// WriteByte writes a byte of data to the UART.
77-
func (uart *UART) WriteByte(c byte) error {
77+
func (uart *UART) writeByte(c byte) error {
7878
uart.txReg.Set(uint32(c))
7979

8080
for !uart.statusReg.HasBits(uart.txEmptyFlag) {
8181
}
8282
return nil
8383
}
84+
85+
func (uart *UART) flush() {}

src/machine/uart.go

+19-3
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,27 @@ func (uart *UART) Read(data []byte) (n int, err error) {
5959
return size, nil
6060
}
6161

62-
// Write data to the UART.
62+
// WriteByte writes a byte of data over the UART's Tx.
63+
// This function blocks until the data is finished being sent.
64+
func (uart *UART) WriteByte(c byte) error {
65+
err := uart.writeByte(c)
66+
if err != nil {
67+
return err
68+
}
69+
uart.flush() // flush() blocks until all data has been transmitted.
70+
return nil
71+
}
72+
73+
// Write data over the UART's Tx.
74+
// This function blocks until the data is finished being sent.
6375
func (uart *UART) Write(data []byte) (n int, err error) {
64-
for _, v := range data {
65-
uart.WriteByte(v)
76+
for i, v := range data {
77+
err = uart.writeByte(v)
78+
if err != nil {
79+
return i, err
80+
}
6681
}
82+
uart.flush() // flush() blocks until all data has been transmitted.
6783
return len(data), nil
6884
}
6985

0 commit comments

Comments
 (0)