Skip to content

Adapt to embedded-hal-1.0.0-alpha.1 #43

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 1 commit into from
Nov 7, 2020
Merged
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
@@ -15,7 +15,7 @@ gpio_cdev = ["gpio-cdev"]
default = [ "gpio_cdev", "gpio_sysfs" ]

[dependencies]
embedded-hal = { version = "0.2.3", features = ["unproven"] }
embedded-hal = "=1.0.0-alpha.1"
gpio-cdev = { version = "0.3", optional = true }
sysfs_gpio = { version = "0.5", optional = true }

@@ -24,7 +24,6 @@ nb = "0.1.1"
serial-core = "0.4.0"
serial-unix = "0.4.0"
spidev = "0.4"
void = "1"

[dev-dependencies]
openpty = "0.1.0"
14 changes: 7 additions & 7 deletions src/cdev_pin.rs
Original file line number Diff line number Diff line change
@@ -15,31 +15,31 @@ impl CdevPin {
}
}

impl hal::digital::v2::OutputPin for CdevPin {
impl hal::digital::OutputPin for CdevPin {
type Error = gpio_cdev::errors::Error;

fn set_low(&mut self) -> Result<(), Self::Error> {
fn try_set_low(&mut self) -> Result<(), Self::Error> {
self.0.set_value(0)
}

fn set_high(&mut self) -> Result<(), Self::Error> {
fn try_set_high(&mut self) -> Result<(), Self::Error> {
self.0.set_value(1)
}
}

impl hal::digital::v2::InputPin for CdevPin {
impl hal::digital::InputPin for CdevPin {
type Error = gpio_cdev::errors::Error;

fn is_high(&self) -> Result<bool, Self::Error> {
fn try_is_high(&self) -> Result<bool, Self::Error> {
if !self.1 {
self.0.get_value().map(|val| val != 0)
} else {
self.0.get_value().map(|val| val == 0)
}
}

fn is_low(&self) -> Result<bool, Self::Error> {
self.is_high().map(|val| !val)
fn try_is_low(&self) -> Result<bool, Self::Error> {
self.try_is_high().map(|val| !val)
}
}

77 changes: 49 additions & 28 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -16,19 +16,18 @@ extern crate cast;
extern crate core;
extern crate embedded_hal as hal;
pub extern crate i2cdev;
pub extern crate spidev;
pub extern crate serial_unix;
pub extern crate serial_core;
pub extern crate nb;

pub extern crate serial_core;
pub extern crate serial_unix;
pub extern crate spidev;

#[cfg(feature = "gpio_sysfs")]
pub extern crate sysfs_gpio;

#[cfg(feature = "gpio_cdev")]
pub extern crate gpio_cdev;


use core::convert::Infallible;
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::time::Duration;
@@ -60,65 +59,87 @@ pub use cdev_pin::CdevPin;
/// Sysfs pin re-export
pub use sysfs_pin::SysfsPin;


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

impl hal::blocking::delay::DelayUs<u8> for Delay {
fn delay_us(&mut self, n: u8) {
thread::sleep(Duration::new(0, u32(n) * 1000))
type Error = Infallible;

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

impl hal::blocking::delay::DelayUs<u16> for Delay {
fn delay_us(&mut self, n: u16) {
thread::sleep(Duration::new(0, u32(n) * 1000))
type Error = Infallible;

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

impl hal::blocking::delay::DelayUs<u32> for Delay {
fn delay_us(&mut self, n: u32) {
type Error = Infallible;

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

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

impl hal::blocking::delay::DelayUs<u64> for Delay {
fn delay_us(&mut self, n: u64) {
type Error = Infallible;

fn try_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))
thread::sleep(Duration::new(secs, nsecs));
Ok(())
}
}

impl hal::blocking::delay::DelayMs<u8> for Delay {
fn delay_ms(&mut self, n: u8) {
thread::sleep(Duration::from_millis(u64(n)))
type Error = Infallible;

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

impl hal::blocking::delay::DelayMs<u16> for Delay {
fn delay_ms(&mut self, n: u16) {
thread::sleep(Duration::from_millis(u64(n)))
type Error = Infallible;

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

impl hal::blocking::delay::DelayMs<u32> for Delay {
fn delay_ms(&mut self, n: u32) {
thread::sleep(Duration::from_millis(u64(n)))
type Error = Infallible;

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

impl hal::blocking::delay::DelayMs<u64> for Delay {
fn delay_ms(&mut self, n: u64) {
thread::sleep(Duration::from_millis(n))
type Error = Infallible;

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


/// Newtype around [`i2cdev::linux::LinuxI2CDevice`] that implements the `embedded-hal` traits
///
/// [`i2cdev::linux::LinuxI2CDevice`]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html
@@ -156,7 +177,7 @@ impl I2cdev {
impl hal::blocking::i2c::Read for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;

fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
fn try_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
self.set_address(address)?;
self.inner.read(buffer)
}
@@ -165,7 +186,7 @@ impl hal::blocking::i2c::Read for I2cdev {
impl hal::blocking::i2c::Write for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;

fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
fn try_write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
self.set_address(address)?;
self.inner.write(bytes)
}
@@ -174,7 +195,7 @@ impl hal::blocking::i2c::Write for I2cdev {
impl hal::blocking::i2c::WriteRead for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;

fn write_read(
fn try_write_read(
&mut self,
address: u8,
bytes: &[u8],
@@ -220,7 +241,7 @@ impl Spidev {
impl hal::blocking::spi::Transfer<u8> for Spidev {
type Error = io::Error;

fn transfer<'b>(&mut self, buffer: &'b mut [u8]) -> io::Result<&'b [u8]> {
fn try_transfer<'b>(&mut self, buffer: &'b mut [u8]) -> io::Result<&'b [u8]> {
let tx = buffer.to_owned();
self.0
.transfer(&mut SpidevTransfer::read_write(&tx, buffer))?;
@@ -231,7 +252,7 @@ impl hal::blocking::spi::Transfer<u8> for Spidev {
impl hal::blocking::spi::Write<u8> for Spidev {
type Error = io::Error;

fn write(&mut self, buffer: &[u8]) -> io::Result<()> {
fn try_write(&mut self, buffer: &[u8]) -> io::Result<()> {
self.0.write_all(buffer)
}
}
12 changes: 6 additions & 6 deletions src/serial.rs
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ fn translate_io_errors(err: std::io::Error) -> nb::Error<IoErrorKind> {
impl hal::serial::Read<u8> for Serial {
type Error = IoErrorKind;

fn read(&mut self) -> nb::Result<u8, Self::Error> {
fn try_read(&mut self) -> nb::Result<u8, Self::Error> {
let mut buffer = [0; 1];
let bytes_read = self.0.read(&mut buffer).map_err(translate_io_errors)?;
if bytes_read == 1 {
@@ -47,12 +47,12 @@ impl hal::serial::Read<u8> for Serial {
impl hal::serial::Write<u8> for Serial {
type Error = IoErrorKind;

fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
fn try_write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
self.0.write(&[word]).map_err(translate_io_errors)?;
Ok(())
}

fn flush(&mut self) -> nb::Result<(), Self::Error> {
fn try_flush(&mut self) -> nb::Result<(), Self::Error> {
self.0.flush().map_err(translate_io_errors)
}
}
@@ -76,20 +76,20 @@ mod test {
#[test]
fn test_empty_read() {
let (mut _master, mut serial) = create_pty_and_serial();
assert_eq!(Err(nb::Error::WouldBlock), serial.read());
assert_eq!(Err(nb::Error::WouldBlock), serial.try_read());
}

#[test]
fn test_read() {
let (mut master, mut serial) = create_pty_and_serial();
master.write(&[1]).expect("Write failed");
assert_eq!(Ok(1), serial.read());
assert_eq!(Ok(1), serial.try_read());
}

#[test]
fn test_write() {
let (mut master, mut serial) = create_pty_and_serial();
serial.write(2).expect("Write failed");
serial.try_write(2).expect("Write failed");
let mut buf = [0; 2];
assert_eq!(1, master.read(&mut buf).unwrap());
assert_eq!(buf, [2, 0]);
14 changes: 7 additions & 7 deletions src/sysfs_pin.rs
Original file line number Diff line number Diff line change
@@ -26,31 +26,31 @@ impl SysfsPin {
}
}

impl hal::digital::v2::OutputPin for SysfsPin {
impl hal::digital::OutputPin for SysfsPin {
type Error = sysfs_gpio::Error;

fn set_low(&mut self) -> Result<(), Self::Error> {
fn try_set_low(&mut self) -> Result<(), Self::Error> {
self.0.set_value(0)
}

fn set_high(&mut self) -> Result<(), Self::Error> {
fn try_set_high(&mut self) -> Result<(), Self::Error> {
self.0.set_value(1)
}
}

impl hal::digital::v2::InputPin for SysfsPin {
impl hal::digital::InputPin for SysfsPin {
type Error = sysfs_gpio::Error;

fn is_high(&self) -> Result<bool, Self::Error> {
fn try_is_high(&self) -> Result<bool, Self::Error> {
if !self.0.get_active_low()? {
self.0.get_value().map(|val| val != 0)
} else {
self.0.get_value().map(|val| val == 0)
}
}

fn is_low(&self) -> Result<bool, Self::Error> {
self.is_high().map(|val| !val)
fn try_is_low(&self) -> Result<bool, Self::Error> {
self.try_is_high().map(|val| !val)
}
}

17 changes: 10 additions & 7 deletions src/timer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Timers.
use core::convert::Infallible;
use std::time::{Duration, Instant};

use hal::timer::{CountDown, Periodic};
@@ -27,17 +28,19 @@ impl SysTimer {
}

impl CountDown for SysTimer {
type Error = Infallible;
type Time = Duration;

fn start<T>(&mut self, count: T)
fn try_start<T>(&mut self, count: T) -> Result<(), Self::Error>
where
T: Into<Self::Time>,
{
self.start = Instant::now();
self.duration = count.into();
Ok(())
}

fn wait(&mut self) -> nb::Result<(), void::Void> {
fn try_wait(&mut self) -> nb::Result<(), Self::Error> {
if (Instant::now() - self.start) >= self.duration {
// Restart the timer to fulfill the contract by `Periodic`
self.start = Instant::now();
@@ -60,8 +63,8 @@ mod tests {
fn test_delay() {
let mut timer = SysTimer::new();
let before = Instant::now();
timer.start(Duration::from_millis(100));
nb::block!(timer.wait()).unwrap();
timer.try_start(Duration::from_millis(100)).unwrap();
nb::block!(timer.try_wait()).unwrap();
let after = Instant::now();
let duration_ms = (after - before).as_millis();
assert!(duration_ms >= 100);
@@ -73,13 +76,13 @@ mod tests {
fn test_periodic() {
let mut timer = SysTimer::new();
let before = Instant::now();
timer.start(Duration::from_millis(100));
nb::block!(timer.wait()).unwrap();
timer.try_start(Duration::from_millis(100)).unwrap();
nb::block!(timer.try_wait()).unwrap();
let after1 = Instant::now();
let duration_ms_1 = (after1 - before).as_millis();
assert!(duration_ms_1 >= 100);
assert!(duration_ms_1 < 500);
nb::block!(timer.wait()).unwrap();
nb::block!(timer.try_wait()).unwrap();
let after2 = Instant::now();
let duration_ms_2 = (after2 - after1).as_millis();
assert!(duration_ms_2 >= 100);