Skip to content

WIP: Update embedded-hal to version 1.0.0-alpha.6 #71

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

Merged
merged 5 commits into from
Feb 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ async-tokio = ["gpio-cdev/async-tokio"]
default = [ "gpio_cdev", "gpio_sysfs" ]

[dependencies]
embedded-hal = "=1.0.0-alpha.5"
embedded-hal = "=1.0.0-alpha.6"
gpio-cdev = { version = "0.5.1", optional = true }
sysfs_gpio = { version = "0.6.1", optional = true }

i2cdev = "0.5.1"
nb = "1"
serial-core = "0.4.0"
Expand Down
72 changes: 3 additions & 69 deletions src/delay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,16 @@
//!
//! [`embedded-hal`]: https://docs.rs/embedded-hal

use cast::{u32, u64};
use cast::u64;
use core::convert::Infallible;
use embedded_hal::delay::blocking::{DelayMs, DelayUs};
use embedded_hal::delay::blocking::DelayUs;
use std::thread;
use std::time::Duration;

/// Empty struct that provides delay functionality on top of `thread::sleep`
pub struct Delay;

impl DelayUs<u8> for Delay {
type Error = Infallible;

fn delay_us(&mut self, n: u8) -> Result<(), Self::Error> {
thread::sleep(Duration::new(0, u32(n) * 1000));
Ok(())
}
}

impl DelayUs<u16> for Delay {
type Error = Infallible;

fn delay_us(&mut self, n: u16) -> Result<(), Self::Error> {
thread::sleep(Duration::new(0, u32(n) * 1000));
Ok(())
}
}

impl DelayUs<u32> for Delay {
impl DelayUs for Delay {
type Error = Infallible;

fn delay_us(&mut self, n: u32) -> Result<(), Self::Error> {
Expand All @@ -40,51 +22,3 @@ impl DelayUs<u32> for Delay {
Ok(())
}
}

impl DelayUs<u64> for Delay {
type Error = Infallible;

fn delay_us(&mut self, n: u64) -> Result<(), Self::Error> {
let secs = n / 1_000_000;
let nsecs = ((n % 1_000_000) * 1_000) as u32;

thread::sleep(Duration::new(secs, nsecs));
Ok(())
}
}

impl DelayMs<u8> for Delay {
type Error = Infallible;

fn delay_ms(&mut self, n: u8) -> Result<(), Self::Error> {
thread::sleep(Duration::from_millis(u64(n)));
Ok(())
}
}

impl DelayMs<u16> for Delay {
type Error = Infallible;

fn delay_ms(&mut self, n: u16) -> Result<(), Self::Error> {
thread::sleep(Duration::from_millis(u64(n)));
Ok(())
}
}

impl DelayMs<u32> for Delay {
type Error = Infallible;

fn delay_ms(&mut self, n: u32) -> Result<(), Self::Error> {
thread::sleep(Duration::from_millis(u64(n)));
Ok(())
}
}

impl DelayMs<u64> for Delay {
type Error = Infallible;

fn delay_ms(&mut self, n: u64) -> Result<(), Self::Error> {
thread::sleep(Duration::from_millis(n));
Ok(())
}
}
45 changes: 37 additions & 8 deletions src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,25 @@ mod embedded_hal_impl {
use i2cdev::linux::LinuxI2CMessage;

impl Read for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;
type Error = I2CError;

fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
self.set_address(address)?;
self.inner.read(buffer)
self.inner.read(buffer).map_err(|err| I2CError { err })
}
}

impl Write for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;
type Error = I2CError;

fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
self.set_address(address)?;
self.inner.write(bytes)
self.inner.write(bytes).map_err(|err| I2CError { err })
}
}

impl WriteRead for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;
type Error = I2CError;

fn write_read(
&mut self,
Expand All @@ -90,12 +90,15 @@ mod embedded_hal_impl {
) -> Result<(), Self::Error> {
self.set_address(address)?;
let mut messages = [LinuxI2CMessage::write(bytes), LinuxI2CMessage::read(buffer)];
self.inner.transfer(&mut messages).map(drop)
self.inner
.transfer(&mut messages)
.map(drop)
.map_err(|err| I2CError { err })
}
}

impl Transactional for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;
type Error = I2CError;

fn exec(
&mut self,
Expand All @@ -113,7 +116,33 @@ mod embedded_hal_impl {
.collect();

self.set_address(address)?;
self.inner.transfer(&mut messages).map(drop)
self.inner
.transfer(&mut messages)
.map(drop)
.map_err(|err| I2CError { err })
}
}
}

/// Error type wrapping [LinuxI2CError](i2cdev::linux::LinuxI2CError) to implement [embedded_hal::i2c::ErrorKind]
#[derive(Debug)]
pub struct I2CError {
err: i2cdev::linux::LinuxI2CError,
}

impl From<i2cdev::linux::LinuxI2CError> for I2CError {
fn from(err: i2cdev::linux::LinuxI2CError) -> Self {
Self { err }
}
}

impl embedded_hal::i2c::Error for I2CError {
fn kind(&self) -> embedded_hal::i2c::ErrorKind {
use embedded_hal::i2c::ErrorKind::*;
match &self.err {
// i2cdev::linux::LinuxI2CError::Nix(_) => todo!(),
// i2cdev::linux::LinuxI2CError::Io(_) => todo!(),
_ => Other,
}
}
}
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ mod spi;
mod timer;

pub use crate::delay::Delay;
pub use crate::i2c::I2cdev;
pub use crate::serial::Serial;
pub use crate::spi::Spidev;
pub use crate::i2c::{I2CError, I2cdev};
pub use crate::serial::{Serial, SerialError};
pub use crate::spi::{SPIError, Spidev};
pub use crate::timer::SysTimer;
64 changes: 60 additions & 4 deletions src/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ impl Serial {
}

/// Helper to convert std::io::Error to the nb::Error
fn translate_io_errors(err: std::io::Error) -> nb::Error<IoErrorKind> {
fn translate_io_errors(err: std::io::Error) -> nb::Error<SerialError> {
match err.kind() {
IoErrorKind::WouldBlock | IoErrorKind::TimedOut | IoErrorKind::Interrupted => {
nb::Error::WouldBlock
}
err => nb::Error::Other(err),
err => nb::Error::Other(SerialError { err }),
}
}

impl embedded_hal::serial::nb::Read<u8> for Serial {
type Error = IoErrorKind;
type Error = SerialError;

fn read(&mut self) -> nb::Result<u8, Self::Error> {
let mut buffer = [0; 1];
Expand All @@ -44,7 +44,7 @@ impl embedded_hal::serial::nb::Read<u8> for Serial {
}

impl embedded_hal::serial::nb::Write<u8> for Serial {
type Error = IoErrorKind;
type Error = SerialError;

fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
self.0.write(&[word]).map_err(translate_io_errors)?;
Expand All @@ -56,6 +56,62 @@ impl embedded_hal::serial::nb::Write<u8> for Serial {
}
}

/// Error type wrapping [io::ErrorKind](IoErrorKind) to implement [embedded_hal::serial::ErrorKind]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct SerialError {
err: IoErrorKind,
}

impl embedded_hal::serial::Error for SerialError {
fn kind(&self) -> embedded_hal::serial::ErrorKind {
use embedded_hal::serial::ErrorKind::*;
match &self.err {
// IoErrorKind::NotFound => todo!(),
// IoErrorKind::PermissionDenied => todo!(),
// IoErrorKind::ConnectionRefused => todo!(),
// IoErrorKind::ConnectionReset => todo!(),
// IoErrorKind::HostUnreachable => todo!(),
// IoErrorKind::NetworkUnreachable => todo!(),
// IoErrorKind::ConnectionAborted => todo!(),
// IoErrorKind::NotConnected => todo!(),
// IoErrorKind::AddrInUse => todo!(),
// IoErrorKind::AddrNotAvailable => todo!(),
// IoErrorKind::NetworkDown => todo!(),
// IoErrorKind::BrokenPipe => todo!(),
// IoErrorKind::AlreadyExists => todo!(),
// IoErrorKind::WouldBlock => todo!(),
// IoErrorKind::NotADirectory => todo!(),
// IoErrorKind::IsADirectory => todo!(),
// IoErrorKind::DirectoryNotEmpty => todo!(),
// IoErrorKind::ReadOnlyFilesystem => todo!(),
// IoErrorKind::FilesystemLoop => todo!(),
// IoErrorKind::StaleNetworkFileHandle => todo!(),
// IoErrorKind::InvalidInput => todo!(),
// IoErrorKind::InvalidData => todo!(),
// IoErrorKind::TimedOut => todo!(),
// IoErrorKind::WriteZero => todo!(),
// IoErrorKind::StorageFull => todo!(),
// IoErrorKind::NotSeekable => todo!(),
// IoErrorKind::FilesystemQuotaExceeded => todo!(),
// IoErrorKind::FileTooLarge => todo!(),
// IoErrorKind::ResourceBusy => todo!(),
// IoErrorKind::ExecutableFileBusy => todo!(),
// IoErrorKind::Deadlock => todo!(),
// IoErrorKind::CrossesDevices => todo!(),
// IoErrorKind::TooManyLinks => todo!(),
// IoErrorKind::FilenameTooLong => todo!(),
// IoErrorKind::ArgumentListTooLong => todo!(),
// IoErrorKind::Interrupted => todo!(),
// IoErrorKind::Unsupported => todo!(),
// IoErrorKind::UnexpectedEof => todo!(),
// IoErrorKind::OutOfMemory => todo!(),
// IoErrorKind::Other => todo!(),
// IoErrorKind::Uncategorized => todo!(),
_ => Other,
}
}
}

#[cfg(test)]
mod test {
use std::path::Path;
Expand Down
Loading