85 строки
1,7 КиБ
Go
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
|
|
}
|