tinygo/src/machine/uart.go
Ron Evans ef2ac09561
nrf: implement UART interface
Signed-off-by: Ron Evans <ron@hybridgroup.com>
2018-10-02 17:08:31 +02:00

85 строки
1,7 КиБ
Go

// +build avr nrf
package machine
import "errors"
type UARTConfig struct {
BaudRate uint32
}
type UART struct {
}
// Read from the RX buffer.
func (uart UART) Read(data []byte) (n int, err error) {
// check if RX buffer is empty
size := uart.Buffered()
if size == 0 {
return 0, nil
}
// Make sure we do not read more from buffer than the data slice can hold.
if len(data) < size {
size = len(data)
}
// only read number of bytes used from buffer
for i := 0; i < size; i++ {
v, _ := uart.ReadByte()
data[i] = v
}
return size, nil
}
// Write data to the UART.
func (uart UART) Write(data []byte) (n int, err error) {
for _, v := range data {
uart.WriteByte(v)
}
return len(data), nil
}
// ReadByte reads a single byte from the RX buffer.
// If there is no data in the buffer, returns an error.
func (uart UART) ReadByte() (byte, error) {
// check if RX buffer is empty
if uart.Buffered() == 0 {
return 0, errors.New("Buffer empty")
}
return bufferGet(), nil
}
// Buffered returns the number of bytes currently stored in the RX buffer.
func (uart UART) Buffered() int {
return int(bufferUsed())
}
const bufferSize = 64
// Minimal ring buffer implementation inspired by post at
// https://www.embeddedrelated.com/showthread/comp.arch.embedded/77084-1.php
//go:volatile
type volatileByte byte
var rxbuffer [bufferSize]volatileByte
var head volatileByte
var tail volatileByte
func bufferUsed() uint8 { return uint8(head - tail) }
func bufferPut(val byte) {
if bufferUsed() != bufferSize {
head++
rxbuffer[head%bufferSize] = volatileByte(val)
}
}
func bufferGet() byte {
if bufferUsed() != 0 {
tail++
return byte(rxbuffer[tail%bufferSize])
}
return 0
}