Skip to content

Commit 5259b32

Browse files
bors[bot]eldruin
andauthored
77: Adapt to embedded-hal-1.0.0-alpha.7 r=posborne a=eldruin For the iterator methods I just collected the results. I have not looked into really using an iterating interface but merging this would be a first step and if there is interest we can look into that later on. Fixes rust-embedded#76 Co-authored-by: Diego Barrios Romero <[email protected]>
2 parents 62966e9 + 70012b4 commit 5259b32

File tree

9 files changed

+142
-38
lines changed

9 files changed

+142
-38
lines changed

Cargo.toml

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

2222
[dependencies]
23-
embedded-hal = "=1.0.0-alpha.6"
23+
embedded-hal = "=1.0.0-alpha.7"
2424
gpio-cdev = { version = "0.5.1", optional = true }
2525
sysfs_gpio = { version = "0.6.1", optional = true }
2626
i2cdev = "0.5.1"

examples/transactional-i2c.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use embedded_hal::i2c::blocking::{Operation as I2cOperation, Transactional};
1+
use embedded_hal::i2c::blocking::{I2c, Operation as I2cOperation};
22
use linux_embedded_hal::I2cdev;
33

44
const ADDR: u8 = 0x12;
@@ -9,7 +9,7 @@ struct Driver<I2C> {
99

1010
impl<I2C> Driver<I2C>
1111
where
12-
I2C: Transactional,
12+
I2C: I2c,
1313
{
1414
pub fn new(i2c: I2C) -> Self {
1515
Driver { i2c }
@@ -21,7 +21,7 @@ where
2121
I2cOperation::Write(&[0xAB]),
2222
I2cOperation::Read(&mut read_buffer),
2323
];
24-
self.i2c.exec(ADDR, &mut ops).and(Ok(read_buffer[0]))
24+
self.i2c.transaction(ADDR, &mut ops).and(Ok(read_buffer[0]))
2525
}
2626
}
2727

src/cdev_pin.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,11 @@ fn state_to_value(state: embedded_hal::digital::PinState, is_active_low: bool) -
5353
}
5454
}
5555

56-
impl embedded_hal::digital::blocking::OutputPin for CdevPin {
56+
impl embedded_hal::digital::ErrorType for CdevPin {
5757
type Error = gpio_cdev::errors::Error;
58+
}
5859

60+
impl embedded_hal::digital::blocking::OutputPin for CdevPin {
5961
fn set_low(&mut self) -> Result<(), Self::Error> {
6062
self.0.set_value(state_to_value(
6163
embedded_hal::digital::PinState::Low,
@@ -72,8 +74,6 @@ impl embedded_hal::digital::blocking::OutputPin for CdevPin {
7274
}
7375

7476
impl embedded_hal::digital::blocking::InputPin for CdevPin {
75-
type Error = gpio_cdev::errors::Error;
76-
7777
fn is_high(&self) -> Result<bool, Self::Error> {
7878
self.0.get_value().map(|val| {
7979
val == state_to_value(

src/i2c.rs

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,32 +57,32 @@ impl ops::DerefMut for I2cdev {
5757

5858
mod embedded_hal_impl {
5959
use super::*;
60-
use embedded_hal::i2c::blocking::{
61-
Operation as I2cOperation, Read, Transactional, Write, WriteRead,
62-
};
60+
use embedded_hal::i2c::blocking::{I2c, Operation as I2cOperation};
61+
use embedded_hal::i2c::ErrorType;
6362
use i2cdev::core::{I2CDevice, I2CMessage, I2CTransfer};
6463
use i2cdev::linux::LinuxI2CMessage;
65-
66-
impl Read for I2cdev {
64+
impl ErrorType for I2cdev {
6765
type Error = I2CError;
66+
}
6867

68+
impl I2c for I2cdev {
6969
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
7070
self.set_address(address)?;
7171
self.inner.read(buffer).map_err(|err| I2CError { err })
7272
}
73-
}
74-
75-
impl Write for I2cdev {
76-
type Error = I2CError;
7773

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

84-
impl WriteRead for I2cdev {
85-
type Error = I2CError;
79+
fn write_iter<B>(&mut self, address: u8, bytes: B) -> Result<(), Self::Error>
80+
where
81+
B: IntoIterator<Item = u8>,
82+
{
83+
let bytes: Vec<_> = bytes.into_iter().collect();
84+
self.write(address, &bytes)
85+
}
8686

8787
fn write_read(
8888
&mut self,
@@ -97,12 +97,24 @@ mod embedded_hal_impl {
9797
.map(drop)
9898
.map_err(|err| I2CError { err })
9999
}
100-
}
101100

102-
impl Transactional for I2cdev {
103-
type Error = I2CError;
101+
fn write_iter_read<B>(
102+
&mut self,
103+
address: u8,
104+
bytes: B,
105+
buffer: &mut [u8],
106+
) -> Result<(), Self::Error>
107+
where
108+
B: IntoIterator<Item = u8>,
109+
{
110+
let bytes: Vec<_> = bytes.into_iter().collect();
111+
self.transaction(
112+
address,
113+
&mut [I2cOperation::Write(&bytes), I2cOperation::Read(buffer)],
114+
)
115+
}
104116

105-
fn exec(
117+
fn transaction(
106118
&mut self,
107119
address: u8,
108120
operations: &mut [I2cOperation],
@@ -123,6 +135,14 @@ mod embedded_hal_impl {
123135
.map(drop)
124136
.map_err(|err| I2CError { err })
125137
}
138+
139+
fn transaction_iter<'a, O>(&mut self, address: u8, operations: O) -> Result<(), Self::Error>
140+
where
141+
O: IntoIterator<Item = I2cOperation<'a>>,
142+
{
143+
let mut ops: Vec<_> = operations.into_iter().collect();
144+
self.transaction(address, &mut ops)
145+
}
126146
}
127147
}
128148

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,4 @@ pub use crate::delay::Delay;
4949
pub use crate::i2c::{I2CError, I2cdev};
5050
pub use crate::serial::{Serial, SerialError};
5151
pub use crate::spi::{SPIError, Spidev};
52-
pub use crate::timer::SysTimer;
52+
pub use crate::timer::{CountDown, Periodic, SysTimer};

src/serial.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@ fn translate_io_errors(err: std::io::Error) -> nb::Error<SerialError> {
2929
}
3030
}
3131

32-
impl embedded_hal::serial::nb::Read<u8> for Serial {
32+
impl embedded_hal::serial::ErrorType for Serial {
3333
type Error = SerialError;
34+
}
3435

36+
impl embedded_hal::serial::nb::Read<u8> for Serial {
3537
fn read(&mut self) -> nb::Result<u8, Self::Error> {
3638
let mut buffer = [0; 1];
3739
let bytes_read = self.0.read(&mut buffer).map_err(translate_io_errors)?;
@@ -44,8 +46,6 @@ impl embedded_hal::serial::nb::Read<u8> for Serial {
4446
}
4547

4648
impl embedded_hal::serial::nb::Write<u8> for Serial {
47-
type Error = SerialError;
48-
4949
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
5050
self.0.write(&[word]).map_err(translate_io_errors)?;
5151
Ok(())

src/spi.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,15 @@ mod embedded_hal_impl {
4343
use embedded_hal::spi::blocking::{
4444
Operation as SpiOperation, Transactional, Transfer, TransferInplace, Write,
4545
};
46+
use embedded_hal::spi::ErrorType;
4647
use spidev::SpidevTransfer;
4748
use std::io::Write as _;
4849

49-
impl Transfer<u8> for Spidev {
50+
impl ErrorType for Spidev {
5051
type Error = SPIError;
52+
}
5153

54+
impl Transfer<u8> for Spidev {
5255
fn transfer<'b>(&mut self, read: &'b mut [u8], write: &[u8]) -> Result<(), Self::Error> {
5356
self.0
5457
.transfer(&mut SpidevTransfer::read_write(&write, read))
@@ -57,8 +60,6 @@ mod embedded_hal_impl {
5760
}
5861

5962
impl TransferInplace<u8> for Spidev {
60-
type Error = SPIError;
61-
6263
fn transfer_inplace<'b>(&mut self, buffer: &'b mut [u8]) -> Result<(), Self::Error> {
6364
let tx = buffer.to_owned();
6465
self.0
@@ -68,17 +69,13 @@ mod embedded_hal_impl {
6869
}
6970

7071
impl Write<u8> for Spidev {
71-
type Error = SPIError;
72-
7372
fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
7473
self.0.write_all(buffer).map_err(|err| SPIError { err })
7574
}
7675
}
7776

7877
/// Transactional implementation batches SPI operations into a single transaction
7978
impl Transactional<u8> for Spidev {
80-
type Error = SPIError;
81-
8279
fn exec<'a>(&mut self, operations: &mut [SpiOperation<'a, u8>]) -> Result<(), Self::Error> {
8380
// Map types from generic to linux objects
8481
let mut messages: Vec<_> = operations

src/sysfs_pin.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ impl SysfsPin {
2828
}
2929
}
3030

31-
impl embedded_hal::digital::blocking::OutputPin for SysfsPin {
31+
impl embedded_hal::digital::ErrorType for SysfsPin {
3232
type Error = sysfs_gpio::Error;
33+
}
3334

35+
impl embedded_hal::digital::blocking::OutputPin for SysfsPin {
3436
fn set_low(&mut self) -> Result<(), Self::Error> {
3537
if self.0.get_active_low()? {
3638
self.0.set_value(1)
@@ -49,8 +51,6 @@ impl embedded_hal::digital::blocking::OutputPin for SysfsPin {
4951
}
5052

5153
impl embedded_hal::digital::blocking::InputPin for SysfsPin {
52-
type Error = sysfs_gpio::Error;
53-
5454
fn is_high(&self) -> Result<bool, Self::Error> {
5555
if !self.0.get_active_low()? {
5656
self.0.get_value().map(|val| val != 0)

src/timer.rs

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,94 @@
55
use core::convert::Infallible;
66
use std::time::{Duration, Instant};
77

8-
use embedded_hal::timer::{nb::CountDown, Periodic};
8+
/// Marker trait that indicates that a timer is periodic
9+
pub trait Periodic {}
10+
11+
/// A count down timer
12+
///
13+
/// Note that this is borrowed from `embedded-hal` 0.2.x and will be in use until the `1.x` version provides one.
14+
///
15+
/// # Contract
16+
///
17+
/// - `self.start(count); block!(self.wait());` MUST block for AT LEAST the time specified by
18+
/// `count`.
19+
///
20+
/// *Note* that the implementer doesn't necessarily have to be a *downcounting* timer; it could also
21+
/// be an *upcounting* timer as long as the above contract is upheld.
22+
///
23+
/// # Examples
24+
///
25+
/// You can use this timer to create delays
26+
///
27+
/// ```
28+
/// use std::time::Duration;
29+
/// use nb::block;
30+
/// use linux_embedded_hal::{CountDown, SysTimer};
31+
///
32+
/// fn main() {
33+
/// let mut led: Led = {
34+
/// // ..
35+
/// # Led
36+
/// };
37+
/// let mut timer = SysTimer::new();
38+
///
39+
/// Led.on();
40+
/// timer.start(Duration::from_millis(1000)).unwrap();
41+
/// block!(timer.wait()); // blocks for 1 second
42+
/// Led.off();
43+
/// }
44+
///
45+
/// # use core::convert::Infallible;
46+
/// # struct Seconds(u32);
47+
/// # trait U32Ext { fn s(self) -> Seconds; }
48+
/// # impl U32Ext for u32 { fn s(self) -> Seconds { Seconds(self) } }
49+
/// # struct Led;
50+
/// # impl Led {
51+
/// # pub fn off(&mut self) {}
52+
/// # pub fn on(&mut self) {}
53+
/// # }
54+
/// ```
55+
pub trait CountDown {
56+
/// An enumeration of `CountDown` errors.
57+
///
58+
/// For infallible implementations, will be `Infallible`
59+
type Error: core::fmt::Debug;
60+
61+
/// The unit of time used by this timer
62+
type Time;
63+
64+
/// Starts a new count down
65+
fn start<T>(&mut self, count: T) -> Result<(), Self::Error>
66+
where
67+
T: Into<Self::Time>;
68+
69+
/// Non-blockingly "waits" until the count down finishes
70+
///
71+
/// # Contract
72+
///
73+
/// - If `Self: Periodic`, the timer will start a new count down right after the last one
74+
/// finishes.
75+
/// - Otherwise the behavior of calling `wait` after the last call returned `Ok` is UNSPECIFIED.
76+
/// Implementers are suggested to panic on this scenario to signal a programmer error.
77+
fn wait(&mut self) -> nb::Result<(), Self::Error>;
78+
}
79+
80+
impl<T: CountDown> CountDown for &mut T {
81+
type Error = T::Error;
82+
83+
type Time = T::Time;
84+
85+
fn start<TIME>(&mut self, count: TIME) -> Result<(), Self::Error>
86+
where
87+
TIME: Into<Self::Time>,
88+
{
89+
T::start(self, count)
90+
}
91+
92+
fn wait(&mut self) -> nb::Result<(), Self::Error> {
93+
T::wait(self)
94+
}
95+
}
996

1097
/// A periodic timer based on [`std::time::Instant`][instant], which is a
1198
/// monotonically nondecreasing clock.

0 commit comments

Comments
 (0)