Skip to content

Commit e7fd628

Browse files
bors[bot]caemor
andauthored
71: WIP: Update embedded-hal to version 1.0.0-alpha.6 r=eldruin a=caemor The delay update is pretty straightforward. The error update is more difficult: The current implementation creates a new struct including a single element: the upstream linux error, and implement the e-h error trait for it. I've got two issues with this. Is creating a new struct the best way to do this? For matching the e-h trait kind: Currently I just matched everything to `Other` because I couldn't find any good matches when taking a quick glance. Is there something that should be matched? The creation of a central error enum for linux e-h would be an other alternative way to solve this. Co-authored-by: Caemor <[email protected]> Co-authored-by: Chris <[email protected]>
2 parents ecaedd6 + 3b10f16 commit e7fd628

File tree

6 files changed

+194
-97
lines changed

6 files changed

+194
-97
lines changed

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,9 @@ async-tokio = ["gpio-cdev/async-tokio"]
2020
default = [ "gpio_cdev", "gpio_sysfs" ]
2121

2222
[dependencies]
23-
embedded-hal = "=1.0.0-alpha.5"
23+
embedded-hal = "=1.0.0-alpha.6"
2424
gpio-cdev = { version = "0.5.1", optional = true }
2525
sysfs_gpio = { version = "0.6.1", optional = true }
26-
2726
i2cdev = "0.5.1"
2827
nb = "1"
2928
serial-core = "0.4.0"

src/delay.rs

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,16 @@
22
//!
33
//! [`embedded-hal`]: https://docs.rs/embedded-hal
44
5-
use cast::{u32, u64};
5+
use cast::u64;
66
use core::convert::Infallible;
7-
use embedded_hal::delay::blocking::{DelayMs, DelayUs};
7+
use embedded_hal::delay::blocking::DelayUs;
88
use std::thread;
99
use std::time::Duration;
1010

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

14-
impl DelayUs<u8> for Delay {
15-
type Error = Infallible;
16-
17-
fn delay_us(&mut self, n: u8) -> Result<(), Self::Error> {
18-
thread::sleep(Duration::new(0, u32(n) * 1000));
19-
Ok(())
20-
}
21-
}
22-
23-
impl DelayUs<u16> for Delay {
24-
type Error = Infallible;
25-
26-
fn delay_us(&mut self, n: u16) -> Result<(), Self::Error> {
27-
thread::sleep(Duration::new(0, u32(n) * 1000));
28-
Ok(())
29-
}
30-
}
31-
32-
impl DelayUs<u32> for Delay {
14+
impl DelayUs for Delay {
3315
type Error = Infallible;
3416

3517
fn delay_us(&mut self, n: u32) -> Result<(), Self::Error> {
@@ -40,51 +22,3 @@ impl DelayUs<u32> for Delay {
4022
Ok(())
4123
}
4224
}
43-
44-
impl DelayUs<u64> for Delay {
45-
type Error = Infallible;
46-
47-
fn delay_us(&mut self, n: u64) -> Result<(), Self::Error> {
48-
let secs = n / 1_000_000;
49-
let nsecs = ((n % 1_000_000) * 1_000) as u32;
50-
51-
thread::sleep(Duration::new(secs, nsecs));
52-
Ok(())
53-
}
54-
}
55-
56-
impl DelayMs<u8> for Delay {
57-
type Error = Infallible;
58-
59-
fn delay_ms(&mut self, n: u8) -> Result<(), Self::Error> {
60-
thread::sleep(Duration::from_millis(u64(n)));
61-
Ok(())
62-
}
63-
}
64-
65-
impl DelayMs<u16> for Delay {
66-
type Error = Infallible;
67-
68-
fn delay_ms(&mut self, n: u16) -> Result<(), Self::Error> {
69-
thread::sleep(Duration::from_millis(u64(n)));
70-
Ok(())
71-
}
72-
}
73-
74-
impl DelayMs<u32> for Delay {
75-
type Error = Infallible;
76-
77-
fn delay_ms(&mut self, n: u32) -> Result<(), Self::Error> {
78-
thread::sleep(Duration::from_millis(u64(n)));
79-
Ok(())
80-
}
81-
}
82-
83-
impl DelayMs<u64> for Delay {
84-
type Error = Infallible;
85-
86-
fn delay_ms(&mut self, n: u64) -> Result<(), Self::Error> {
87-
thread::sleep(Duration::from_millis(n));
88-
Ok(())
89-
}
90-
}

src/i2c.rs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,25 +62,25 @@ mod embedded_hal_impl {
6262
use i2cdev::linux::LinuxI2CMessage;
6363

6464
impl Read for I2cdev {
65-
type Error = i2cdev::linux::LinuxI2CError;
65+
type Error = I2CError;
6666

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

7373
impl Write for I2cdev {
74-
type Error = i2cdev::linux::LinuxI2CError;
74+
type Error = I2CError;
7575

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

8282
impl WriteRead for I2cdev {
83-
type Error = i2cdev::linux::LinuxI2CError;
83+
type Error = I2CError;
8484

8585
fn write_read(
8686
&mut self,
@@ -90,12 +90,15 @@ mod embedded_hal_impl {
9090
) -> Result<(), Self::Error> {
9191
self.set_address(address)?;
9292
let mut messages = [LinuxI2CMessage::write(bytes), LinuxI2CMessage::read(buffer)];
93-
self.inner.transfer(&mut messages).map(drop)
93+
self.inner
94+
.transfer(&mut messages)
95+
.map(drop)
96+
.map_err(|err| I2CError { err })
9497
}
9598
}
9699

97100
impl Transactional for I2cdev {
98-
type Error = i2cdev::linux::LinuxI2CError;
101+
type Error = I2CError;
99102

100103
fn exec(
101104
&mut self,
@@ -113,7 +116,33 @@ mod embedded_hal_impl {
113116
.collect();
114117

115118
self.set_address(address)?;
116-
self.inner.transfer(&mut messages).map(drop)
119+
self.inner
120+
.transfer(&mut messages)
121+
.map(drop)
122+
.map_err(|err| I2CError { err })
123+
}
124+
}
125+
}
126+
127+
/// Error type wrapping [LinuxI2CError](i2cdev::linux::LinuxI2CError) to implement [embedded_hal::i2c::ErrorKind]
128+
#[derive(Debug)]
129+
pub struct I2CError {
130+
err: i2cdev::linux::LinuxI2CError,
131+
}
132+
133+
impl From<i2cdev::linux::LinuxI2CError> for I2CError {
134+
fn from(err: i2cdev::linux::LinuxI2CError) -> Self {
135+
Self { err }
136+
}
137+
}
138+
139+
impl embedded_hal::i2c::Error for I2CError {
140+
fn kind(&self) -> embedded_hal::i2c::ErrorKind {
141+
use embedded_hal::i2c::ErrorKind::*;
142+
match &self.err {
143+
// i2cdev::linux::LinuxI2CError::Nix(_) => todo!(),
144+
// i2cdev::linux::LinuxI2CError::Io(_) => todo!(),
145+
_ => Other,
117146
}
118147
}
119148
}

src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ mod spi;
4646
mod timer;
4747

4848
pub use crate::delay::Delay;
49-
pub use crate::i2c::I2cdev;
50-
pub use crate::serial::Serial;
51-
pub use crate::spi::Spidev;
49+
pub use crate::i2c::{I2CError, I2cdev};
50+
pub use crate::serial::{Serial, SerialError};
51+
pub use crate::spi::{SPIError, Spidev};
5252
pub use crate::timer::SysTimer;

src/serial.rs

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@ impl Serial {
2020
}
2121

2222
/// Helper to convert std::io::Error to the nb::Error
23-
fn translate_io_errors(err: std::io::Error) -> nb::Error<IoErrorKind> {
23+
fn translate_io_errors(err: std::io::Error) -> nb::Error<SerialError> {
2424
match err.kind() {
2525
IoErrorKind::WouldBlock | IoErrorKind::TimedOut | IoErrorKind::Interrupted => {
2626
nb::Error::WouldBlock
2727
}
28-
err => nb::Error::Other(err),
28+
err => nb::Error::Other(SerialError { err }),
2929
}
3030
}
3131

3232
impl embedded_hal::serial::nb::Read<u8> for Serial {
33-
type Error = IoErrorKind;
33+
type Error = SerialError;
3434

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

4646
impl embedded_hal::serial::nb::Write<u8> for Serial {
47-
type Error = IoErrorKind;
47+
type Error = SerialError;
4848

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

59+
/// Error type wrapping [io::ErrorKind](IoErrorKind) to implement [embedded_hal::serial::ErrorKind]
60+
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
61+
pub struct SerialError {
62+
err: IoErrorKind,
63+
}
64+
65+
impl embedded_hal::serial::Error for SerialError {
66+
fn kind(&self) -> embedded_hal::serial::ErrorKind {
67+
use embedded_hal::serial::ErrorKind::*;
68+
match &self.err {
69+
// IoErrorKind::NotFound => todo!(),
70+
// IoErrorKind::PermissionDenied => todo!(),
71+
// IoErrorKind::ConnectionRefused => todo!(),
72+
// IoErrorKind::ConnectionReset => todo!(),
73+
// IoErrorKind::HostUnreachable => todo!(),
74+
// IoErrorKind::NetworkUnreachable => todo!(),
75+
// IoErrorKind::ConnectionAborted => todo!(),
76+
// IoErrorKind::NotConnected => todo!(),
77+
// IoErrorKind::AddrInUse => todo!(),
78+
// IoErrorKind::AddrNotAvailable => todo!(),
79+
// IoErrorKind::NetworkDown => todo!(),
80+
// IoErrorKind::BrokenPipe => todo!(),
81+
// IoErrorKind::AlreadyExists => todo!(),
82+
// IoErrorKind::WouldBlock => todo!(),
83+
// IoErrorKind::NotADirectory => todo!(),
84+
// IoErrorKind::IsADirectory => todo!(),
85+
// IoErrorKind::DirectoryNotEmpty => todo!(),
86+
// IoErrorKind::ReadOnlyFilesystem => todo!(),
87+
// IoErrorKind::FilesystemLoop => todo!(),
88+
// IoErrorKind::StaleNetworkFileHandle => todo!(),
89+
// IoErrorKind::InvalidInput => todo!(),
90+
// IoErrorKind::InvalidData => todo!(),
91+
// IoErrorKind::TimedOut => todo!(),
92+
// IoErrorKind::WriteZero => todo!(),
93+
// IoErrorKind::StorageFull => todo!(),
94+
// IoErrorKind::NotSeekable => todo!(),
95+
// IoErrorKind::FilesystemQuotaExceeded => todo!(),
96+
// IoErrorKind::FileTooLarge => todo!(),
97+
// IoErrorKind::ResourceBusy => todo!(),
98+
// IoErrorKind::ExecutableFileBusy => todo!(),
99+
// IoErrorKind::Deadlock => todo!(),
100+
// IoErrorKind::CrossesDevices => todo!(),
101+
// IoErrorKind::TooManyLinks => todo!(),
102+
// IoErrorKind::FilenameTooLong => todo!(),
103+
// IoErrorKind::ArgumentListTooLong => todo!(),
104+
// IoErrorKind::Interrupted => todo!(),
105+
// IoErrorKind::Unsupported => todo!(),
106+
// IoErrorKind::UnexpectedEof => todo!(),
107+
// IoErrorKind::OutOfMemory => todo!(),
108+
// IoErrorKind::Other => todo!(),
109+
// IoErrorKind::Uncategorized => todo!(),
110+
_ => Other,
111+
}
112+
}
113+
}
114+
59115
#[cfg(test)]
60116
mod test {
61117
use std::path::Path;

0 commit comments

Comments
 (0)