Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

machine.UART refactor #3832

Merged
merged 8 commits into from
Jul 15, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/machine/machine_atmega.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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.
Expand Down Expand Up @@ -190,14 +191,16 @@ 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) {
}
uart.dataReg.Set(c) // send char
return nil
}

func (uart *UART) flush() {}

// SPIConfig is used to store config info for SPI.
type SPIConfig struct {
Frequency uint32
Expand Down
4 changes: 3 additions & 1 deletion src/machine/machine_atsamd21.go
Original file line number Diff line number Diff line change
Expand Up @@ -626,14 +626,16 @@ 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) {
}
uart.Bus.DATA.Set(uint16(c))
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) {
Expand Down
4 changes: 3 additions & 1 deletion src/machine/machine_atsamd51.go
Original file line number Diff line number Diff line change
Expand Up @@ -1114,14 +1114,16 @@ 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) {
}
uart.Bus.DATA.Set(uint32(c))
return nil
}

func (uart *UART) flush() {}

func (uart *UART) handleInterrupt(interrupt.Interrupt) {
// should reset IRQ
uart.Receive(byte((uart.Bus.DATA.Get() & 0xFF)))
Expand Down
4 changes: 3 additions & 1 deletion src/machine/machine_esp32.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
4 changes: 3 additions & 1 deletion src/machine/machine_esp32c3.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -502,3 +502,5 @@ func (uart *UART) WriteByte(b byte) error {
uart.Bus.FIFO.Set(uint32(b))
return nil
}

func (uart *UART) flush() {}
6 changes: 4 additions & 2 deletions src/machine/machine_esp8266.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
5 changes: 4 additions & 1 deletion src/machine/machine_fe310.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
5 changes: 4 additions & 1 deletion src/machine/machine_k210.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
4 changes: 3 additions & 1 deletion src/machine/machine_mimxrt1062_uart.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,16 @@ 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) {
}
uart.Bus.CTRL.SetBits(nxp.LPUART_CTRL_TIE)
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.
Expand Down
4 changes: 3 additions & 1 deletion src/machine/machine_nrf.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,16 @@ 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 {
}
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()))
Expand Down
4 changes: 3 additions & 1 deletion src/machine/machine_nxpmk66f18_uart.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -305,3 +305,5 @@ func (u *UART) WriteByte(c byte) error {
u.C2.Set(uartC2TXActive)
return nil
}

func (uart *UART) flush() {}
9 changes: 8 additions & 1 deletion src/machine/machine_rp2040_uart.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,23 @@ 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
uart.Bus.UARTDR.Set(uint32(c))
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
Expand Down
4 changes: 3 additions & 1 deletion src/machine/machine_stm32_uart.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
17 changes: 15 additions & 2 deletions src/machine/uart.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,24 @@ 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)
uart.writeByte(v)
soypat marked this conversation as resolved.
Show resolved Hide resolved
}
uart.flush() // flush() blocks until all data has been transmitted.
return len(data), nil
}

Expand Down