Skip to content

Commit

Permalink
Merge #50
Browse files Browse the repository at this point in the history
50: Embedded hal 1.0.0 alpha.3 r=ryankurte a=eldruin

Builds on and superseeds #43 and #48.

Co-authored-by: Diego Barrios Romero <[email protected]>
  • Loading branch information
bors[bot] and eldruin authored Nov 5, 2020
2 parents 25bf2be + 4e55504 commit be456d2
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 59 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- Set default features to build both sysfs and cdev pin types
- Removed `Pin` export, use `CdevPin` or `SysfsPin`
- Adapted to `embedded-hal` `1.0.0-alpha.3` release.
- Updated `nb` to version `1`.

## [v0.3.0] - 2019-11-25

Expand Down Expand Up @@ -41,7 +43,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added

- implementation of the unproven `embedded_hal::::digital::InputPin` trait.
- implementation of the unproven `embedded_hal::::digital::InputPin` trait.

## [v0.2.0] - 2018-05-14

Expand Down
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,15 @@ gpio_cdev = ["gpio-cdev"]
default = [ "gpio_cdev", "gpio_sysfs" ]

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

i2cdev = "0.4.3"
nb = "0.1.1"
nb = "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

0 comments on commit be456d2

Please sign in to comment.