Skip to content
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

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

Merged
merged 1 commit into from
Nov 7, 2020
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 @@ -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 }

Expand All @@ -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"
Expand Down
14 changes: 7 additions & 7 deletions src/cdev_pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand Down
77 changes: 49 additions & 28 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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],
Expand Down Expand Up @@ -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))?;
Expand All @@ -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)
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
}
}
Expand All @@ -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]);
Expand Down
14 changes: 7 additions & 7 deletions src/sysfs_pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand Down
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};
Expand Down Expand Up @@ -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();
Expand All @@ -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);
Expand All @@ -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);
Expand Down