use crate::{Error, Uart};
use embedded_io::{ErrorKind, ErrorType, Read, ReadReady, Write, WriteReady};
impl ErrorType for Uart<'_> {
type Error = Error;
}
impl embedded_io::Error for Error {
fn kind(&self) -> ErrorKind {
match self {
Self::Break | Self::Overrun => ErrorKind::Other,
Self::Framing | Self::Parity => ErrorKind::InvalidData,
Self::InvalidParameter => ErrorKind::InvalidInput,
}
}
}
impl Write for Uart<'_> {
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
let mut bytes_written = 0;
if !buf.is_empty() {
while self.is_tx_fifo_full() {}
for byte in buf {
self.write_word(*byte);
bytes_written += 1;
if self.is_tx_fifo_full() {
break;
}
}
}
Ok(bytes_written)
}
fn flush(&mut self) -> Result<(), Self::Error> {
while self.is_busy() {}
Ok(())
}
}
impl WriteReady for Uart<'_> {
fn write_ready(&mut self) -> Result<bool, Self::Error> {
Ok(!self.is_tx_fifo_full())
}
}
impl Read for Uart<'_> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
if buf.is_empty() {
Ok(0)
} else {
loop {
if let Some(byte) = self.read_word()? {
buf[0] = byte;
return Ok(1);
}
}
}
}
}
impl ReadReady for Uart<'_> {
fn read_ready(&mut self) -> Result<bool, Self::Error> {
Ok(!self.is_rx_fifo_empty())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::FakePL011Registers;
#[test]
fn error_kind() {
assert_eq!(ErrorKind::Other, embedded_io::Error::kind(&Error::Break));
assert_eq!(
ErrorKind::InvalidData,
embedded_io::Error::kind(&Error::Framing)
);
assert_eq!(
ErrorKind::InvalidInput,
embedded_io::Error::kind(&Error::InvalidParameter)
);
}
#[test]
fn embeddedio_write_empty() {
let mut regs = FakePL011Registers::new();
let mut uart = regs.uart_for_test();
assert_eq!(Ok(0), Write::write(&mut uart, &[]));
assert_eq!(Ok(()), Write::flush(&mut uart));
}
#[test]
fn embeddedio_write() {
let mut regs = FakePL011Registers::new();
let mut uart = regs.uart_for_test();
assert_eq!(Ok(2), Write::write(&mut uart, &[1, 2]));
assert_eq!(Ok(()), Write::write_all(&mut uart, &[1, 2]));
assert_eq!(Ok(()), Write::flush(&mut uart));
}
#[test]
fn embeddedio_write_fifo_full() {
let mut regs = FakePL011Registers::new();
{
let mut uart = regs.uart_for_test();
assert_eq!(Ok(true), uart.write_ready());
}
{
regs.reg_write(0x018, 1 << 5);
let mut uart = regs.uart_for_test();
assert_eq!(Ok(false), uart.write_ready());
}
}
#[test]
fn embeddedio_read_empty() {
let mut regs = FakePL011Registers::new();
let mut uart = regs.uart_for_test();
let mut data = [];
assert_eq!(Ok(0), Read::read(&mut uart, &mut data));
}
#[test]
fn embeddedio_read() {
let mut regs = FakePL011Registers::new();
let mut uart = regs.uart_for_test();
let mut data = [0u8; 2];
assert_eq!(Ok(1), Read::read(&mut uart, &mut data));
assert_eq!(data, [0, 0]);
assert_eq!(Ok(()), Read::read_exact(&mut uart, &mut data));
assert_eq!(data, [0, 0]);
}
#[test]
fn embeddedio_read_fifo_empty() {
let mut regs = FakePL011Registers::new();
{
let mut uart = regs.uart_for_test();
assert_eq!(Ok(true), uart.read_ready());
}
{
regs.reg_write(0x018, 1 << 4);
let mut uart = regs.uart_for_test();
assert_eq!(Ok(false), uart.read_ready());
}
}
}