firmware: add io::Error::Unrecognized variant and use it in drtioaux.

This commit is contained in:
whitequark 2018-05-14 12:06:33 +00:00
parent 504d37b66b
commit bfc8fd0807
4 changed files with 55 additions and 68 deletions

View File

@ -1,8 +1,42 @@
use core::fmt;
use io::{Cursor, Error as IoError};
use io::proto::ProtoRead;
use super::*; use super::*;
use {Error, Result}; pub type Result<T> = result::Result<T, Error>;
use io::Cursor;
use io::proto::ProtoRead; #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Error {
CorruptedPacket,
TimedOut,
NoRoute,
GatewareError,
Io(IoError<!>)
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&Error::CorruptedPacket =>
write!(f, "packet CRC failed"),
&Error::TimedOut =>
write!(f, "timed out waiting for data"),
&Error::NoRoute =>
write!(f, "invalid node number"),
&Error::GatewareError =>
write!(f, "gateware reported error"),
&Error::Io(ref io) =>
write!(f, "I/O error ({})", io)
}
}
}
impl From<IoError<!>> for Error {
fn from(value: IoError<!>) -> Error {
Error::Io(value)
}
}
pub fn reset(linkno: u8) { pub fn reset(linkno: u8) {
let linkno = linkno as usize; let linkno = linkno as usize;
@ -26,8 +60,8 @@ fn has_rx_error(linkno: u8) -> bool {
} }
} }
fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, !> fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>>
where F: FnOnce(&[u8]) -> Result<T, !> where F: FnOnce(&[u8]) -> Result<T>
{ {
let linkidx = linkno as usize; let linkidx = linkno as usize;
unsafe { unsafe {
@ -44,7 +78,7 @@ fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, !>
} }
} }
pub fn recv_link(linkno: u8) -> Result<Option<Packet>, !> { pub fn recv_link(linkno: u8) -> Result<Option<Packet>> {
if has_rx_error(linkno) { if has_rx_error(linkno) {
return Err(Error::GatewareError) return Err(Error::GatewareError)
} }
@ -64,11 +98,11 @@ pub fn recv_link(linkno: u8) -> Result<Option<Packet>, !> {
} }
reader.set_position(0); reader.set_position(0);
Packet::read_from(&mut reader) Ok(Packet::read_from(&mut reader)?)
}) })
} }
pub fn recv_timeout_link(linkno: u8, timeout_ms: Option<u64>) -> Result<Packet, !> { pub fn recv_timeout_link(linkno: u8, timeout_ms: Option<u64>) -> Result<Packet> {
let timeout_ms = timeout_ms.unwrap_or(10); let timeout_ms = timeout_ms.unwrap_or(10);
let limit = board::clock::get_ms() + timeout_ms; let limit = board::clock::get_ms() + timeout_ms;
while board::clock::get_ms() < limit { while board::clock::get_ms() < limit {
@ -80,8 +114,8 @@ pub fn recv_timeout_link(linkno: u8, timeout_ms: Option<u64>) -> Result<Packet,
Err(Error::TimedOut) Err(Error::TimedOut)
} }
fn transmit<F>(linkno: u8, f: F) -> Result<(), !> fn transmit<F>(linkno: u8, f: F) -> Result<()>
where F: FnOnce(&mut [u8]) -> Result<usize, !> where F: FnOnce(&mut [u8]) -> Result<usize>
{ {
let linkno = linkno as usize; let linkno = linkno as usize;
unsafe { unsafe {
@ -95,7 +129,7 @@ fn transmit<F>(linkno: u8, f: F) -> Result<(), !>
} }
} }
pub fn send_link(linkno: u8, packet: &Packet) -> Result<(), !> { pub fn send_link(linkno: u8, packet: &Packet) -> Result<()> {
transmit(linkno, |buffer| { transmit(linkno, |buffer| {
let mut writer = Cursor::new(buffer); let mut writer = Cursor::new(buffer);
@ -116,24 +150,24 @@ pub fn send_link(linkno: u8, packet: &Packet) -> Result<(), !> {
} }
// TODO: routing // TODO: routing
fn get_linkno(nodeno: u8) -> Result<u8, !> { fn get_linkno(nodeno: u8) -> Result<u8> {
if nodeno == 0 || nodeno as usize > board::csr::DRTIO.len() { if nodeno == 0 || nodeno as usize > board::csr::DRTIO.len() {
return Err(Error::NoRoute) return Err(Error::NoRoute)
} }
Ok(nodeno - 1) Ok(nodeno - 1)
} }
pub fn recv(nodeno: u8) -> Result<Option<Packet>, !> { pub fn recv(nodeno: u8) -> Result<Option<Packet>> {
let linkno = get_linkno(nodeno)?; let linkno = get_linkno(nodeno)?;
recv_link(linkno) recv_link(linkno)
} }
pub fn recv_timeout(nodeno: u8, timeout_ms: Option<u64>) -> Result<Packet, !> { pub fn recv_timeout(nodeno: u8, timeout_ms: Option<u64>) -> Result<Packet> {
let linkno = get_linkno(nodeno)?; let linkno = get_linkno(nodeno)?;
recv_timeout_link(linkno, timeout_ms) recv_timeout_link(linkno, timeout_ms)
} }
pub fn send(nodeno: u8, packet: &Packet) -> Result<(), !> { pub fn send(nodeno: u8, packet: &Packet) -> Result<()> {
let linkno = get_linkno(nodeno)?; let linkno = get_linkno(nodeno)?;
send_link(linkno, packet) send_link(linkno, packet)
} }

View File

@ -6,59 +6,9 @@ extern crate crc;
extern crate io; extern crate io;
extern crate board; extern crate board;
use core::slice; use io::{Read, Write, Error, Result};
use core::result;
use core::fmt;
use io::{Read, Write, Error as IoError};
use io::proto::{ProtoRead, ProtoWrite}; use io::proto::{ProtoRead, ProtoWrite};
pub type Result<T, E> = result::Result<T, Error<E>>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Error<T> {
UnknownPacket(u8),
CorruptedPacket,
TimedOut,
NoRoute,
GatewareError,
Io(IoError<T>),
Other(T)
}
impl<T: fmt::Display> fmt::Display for Error<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&Error::UnknownPacket(ty) =>
write!(f, "unknown packet type {:#02x}", ty),
&Error::CorruptedPacket =>
write!(f, "packet CRC failed"),
&Error::TimedOut =>
write!(f, "timed out waiting for data"),
&Error::NoRoute =>
write!(f, "invalid node number"),
&Error::GatewareError =>
write!(f, "gateware reported error"),
&Error::Io(ref io) =>
write!(f, "I/O error ({})", io),
&Error::Other(ref err) =>
write!(f, "{}", err)
}
}
}
impl<T> From<T> for Error<T> {
fn from(value: T) -> Error<T> {
Error::Other(value)
}
}
impl<T> From<IoError<T>> for Error<T> {
fn from(value: IoError<T>) -> Error<T> {
Error::Io(value)
}
}
#[derive(Debug)] #[derive(Debug)]
pub enum Packet { pub enum Packet {
EchoRequest, EchoRequest,
@ -188,7 +138,7 @@ impl Packet {
succeeded: reader.read_bool()? succeeded: reader.read_bool()?
}, },
ty => return Err(Error::UnknownPacket(ty)) _ => return Err(Error::Unrecognized)
}) })
} }

View File

@ -19,6 +19,7 @@ pub type Result<T, E> = result::Result<T, Error<E>>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Error<T> { pub enum Error<T> {
UnexpectedEof, UnexpectedEof,
Unrecognized,
Other(T) Other(T)
} }
@ -27,6 +28,8 @@ impl<T: fmt::Display> fmt::Display for Error<T> {
match self { match self {
&Error::UnexpectedEof => &Error::UnexpectedEof =>
write!(f, "unexpected end of stream"), write!(f, "unexpected end of stream"),
&Error::Unrecognized =>
write!(f, "unrecognized input"),
&Error::Other(ref err) => &Error::Other(ref err) =>
write!(f, "{}", err) write!(f, "{}", err)
} }

View File

@ -27,7 +27,7 @@ fn drtio_reset_phy(reset: bool) {
} }
} }
fn process_aux_packet(packet: drtioaux::Packet) -> drtioaux::Result<(), !> { fn process_aux_packet(packet: drtioaux::Packet) -> drtioaux::hw::Result<()> {
// In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels, // In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels,
// and u16 otherwise; hence the `as _` conversion. // and u16 otherwise; hence the `as _` conversion.
match packet { match packet {