Skip to content

Commit 1362ed6

Browse files
bors[bot]ryankurte
andauthored
Merge #35
35: Add transactional SPI r=ryankurte a=ryankurte Implementation of transactional SPI - replaces #33 - blocked on: - ~rust-embedded/embedded-hal#191 - ~#34 ~Important: remove patch and bump hal version before merging~ Co-authored-by: ryan <[email protected]> Co-authored-by: Ryan <[email protected]>
2 parents dfc0434 + d7d7783 commit 1362ed6

File tree

6 files changed

+73
-37
lines changed

6 files changed

+73
-37
lines changed

Cargo.toml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
[package]
2-
authors = ["Jorge Aparicio <[email protected]>"]
2+
authors = [
3+
"The Embedded Linux Team <[email protected]>",
4+
"Jorge Aparicio <[email protected]>"
5+
]
36
categories = ["embedded", "hardware-support"]
47
description = "Implementation of the `embedded-hal` traits for Linux devices"
58
keywords = ["Linux", "hal"]
69
license = "MIT OR Apache-2.0"
710
name = "linux-embedded-hal"
8-
repository = "https://github.com/japaric/linux-embedded-hal"
11+
repository = "https://github.com/rust-embedded/linux-embedded-hal"
912
version = "0.3.0"
13+
edition = "2018"
1014

1115
[features]
1216
gpio_sysfs = ["sysfs_gpio"]
@@ -32,3 +36,4 @@ openpty = "0.1.0"
3236
# we don't need the `Error` implementation
3337
default-features = false
3438
version = "0.2.2"
39+

src/cdev_pin.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ impl CdevPin {
1515
}
1616
}
1717

18-
impl hal::digital::OutputPin for CdevPin {
18+
impl embedded_hal::digital::OutputPin for CdevPin {
1919
type Error = gpio_cdev::errors::Error;
2020

2121
fn try_set_low(&mut self) -> Result<(), Self::Error> {
@@ -27,7 +27,7 @@ impl hal::digital::OutputPin for CdevPin {
2727
}
2828
}
2929

30-
impl hal::digital::InputPin for CdevPin {
30+
impl embedded_hal::digital::InputPin for CdevPin {
3131
type Error = gpio_cdev::errors::Error;
3232

3333
fn try_is_high(&self) -> Result<bool, Self::Error> {

src/lib.rs

Lines changed: 58 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,19 @@
1212
1313
#![deny(missing_docs)]
1414

15-
extern crate cast;
16-
extern crate core;
17-
extern crate embedded_hal as hal;
18-
pub extern crate i2cdev;
19-
pub extern crate nb;
20-
pub extern crate serial_core;
21-
pub extern crate serial_unix;
22-
pub extern crate spidev;
15+
use cast;
16+
pub use i2cdev;
17+
pub use nb;
18+
pub use serial_core;
19+
pub use serial_unix;
20+
pub use spidev;
2321

2422
#[cfg(feature = "gpio_sysfs")]
25-
pub extern crate sysfs_gpio;
23+
pub use sysfs_gpio;
2624

2725
#[cfg(feature = "gpio_cdev")]
28-
pub extern crate gpio_cdev;
26+
pub use gpio_cdev;
27+
2928

3029
use core::convert::Infallible;
3130
use std::io::{self, Write};
@@ -34,7 +33,7 @@ use std::time::Duration;
3433
use std::{ops, thread};
3534

3635
use cast::{u32, u64};
37-
use hal::blocking::i2c::Operation as I2cOperation;
36+
use embedded_hal::blocking::i2c::Operation as I2cOperation;
3837
use i2cdev::core::{I2CDevice, I2CMessage, I2CTransfer};
3938
use i2cdev::linux::LinuxI2CMessage;
4039
use spidev::SpidevTransfer;
@@ -63,7 +62,7 @@ pub use sysfs_pin::SysfsPin;
6362
/// Empty struct that provides delay functionality on top of `thread::sleep`
6463
pub struct Delay;
6564

66-
impl hal::blocking::delay::DelayUs<u8> for Delay {
65+
impl embedded_hal::blocking::delay::DelayUs<u8> for Delay {
6766
type Error = Infallible;
6867

6968
fn try_delay_us(&mut self, n: u8) -> Result<(), Self::Error> {
@@ -72,7 +71,7 @@ impl hal::blocking::delay::DelayUs<u8> for Delay {
7271
}
7372
}
7473

75-
impl hal::blocking::delay::DelayUs<u16> for Delay {
74+
impl embedded_hal::blocking::delay::DelayUs<u16> for Delay {
7675
type Error = Infallible;
7776

7877
fn try_delay_us(&mut self, n: u16) -> Result<(), Self::Error> {
@@ -81,7 +80,7 @@ impl hal::blocking::delay::DelayUs<u16> for Delay {
8180
}
8281
}
8382

84-
impl hal::blocking::delay::DelayUs<u32> for Delay {
83+
impl embedded_hal::blocking::delay::DelayUs<u32> for Delay {
8584
type Error = Infallible;
8685

8786
fn try_delay_us(&mut self, n: u32) -> Result<(), Self::Error> {
@@ -93,7 +92,7 @@ impl hal::blocking::delay::DelayUs<u32> for Delay {
9392
}
9493
}
9594

96-
impl hal::blocking::delay::DelayUs<u64> for Delay {
95+
impl embedded_hal::blocking::delay::DelayUs<u64> for Delay {
9796
type Error = Infallible;
9897

9998
fn try_delay_us(&mut self, n: u64) -> Result<(), Self::Error> {
@@ -105,7 +104,7 @@ impl hal::blocking::delay::DelayUs<u64> for Delay {
105104
}
106105
}
107106

108-
impl hal::blocking::delay::DelayMs<u8> for Delay {
107+
impl embedded_hal::blocking::delay::DelayMs<u8> for Delay {
109108
type Error = Infallible;
110109

111110
fn try_delay_ms(&mut self, n: u8) -> Result<(), Self::Error> {
@@ -114,7 +113,7 @@ impl hal::blocking::delay::DelayMs<u8> for Delay {
114113
}
115114
}
116115

117-
impl hal::blocking::delay::DelayMs<u16> for Delay {
116+
impl embedded_hal::blocking::delay::DelayMs<u16> for Delay {
118117
type Error = Infallible;
119118

120119
fn try_delay_ms(&mut self, n: u16) -> Result<(), Self::Error> {
@@ -123,7 +122,7 @@ impl hal::blocking::delay::DelayMs<u16> for Delay {
123122
}
124123
}
125124

126-
impl hal::blocking::delay::DelayMs<u32> for Delay {
125+
impl embedded_hal::blocking::delay::DelayMs<u32> for Delay {
127126
type Error = Infallible;
128127

129128
fn try_delay_ms(&mut self, n: u32) -> Result<(), Self::Error> {
@@ -132,7 +131,7 @@ impl hal::blocking::delay::DelayMs<u32> for Delay {
132131
}
133132
}
134133

135-
impl hal::blocking::delay::DelayMs<u64> for Delay {
134+
impl embedded_hal::blocking::delay::DelayMs<u64> for Delay {
136135
type Error = Infallible;
137136

138137
fn try_delay_ms(&mut self, n: u64) -> Result<(), Self::Error> {
@@ -175,7 +174,7 @@ impl I2cdev {
175174
}
176175
}
177176

178-
impl hal::blocking::i2c::Read for I2cdev {
177+
impl embedded_hal::blocking::i2c::Read for I2cdev {
179178
type Error = i2cdev::linux::LinuxI2CError;
180179

181180
fn try_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
@@ -184,7 +183,7 @@ impl hal::blocking::i2c::Read for I2cdev {
184183
}
185184
}
186185

187-
impl hal::blocking::i2c::Write for I2cdev {
186+
impl embedded_hal::blocking::i2c::Write for I2cdev {
188187
type Error = i2cdev::linux::LinuxI2CError;
189188

190189
fn try_write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
@@ -193,7 +192,7 @@ impl hal::blocking::i2c::Write for I2cdev {
193192
}
194193
}
195194

196-
impl hal::blocking::i2c::WriteRead for I2cdev {
195+
impl embedded_hal::blocking::i2c::WriteRead for I2cdev {
197196
type Error = i2cdev::linux::LinuxI2CError;
198197

199198
fn try_write_read(
@@ -203,12 +202,15 @@ impl hal::blocking::i2c::WriteRead for I2cdev {
203202
buffer: &mut [u8],
204203
) -> Result<(), Self::Error> {
205204
self.set_address(address)?;
206-
let mut messages = [LinuxI2CMessage::write(bytes), LinuxI2CMessage::read(buffer)];
205+
let mut messages = [
206+
LinuxI2CMessage::write(bytes),
207+
LinuxI2CMessage::read(buffer),
208+
];
207209
self.inner.transfer(&mut messages).map(drop)
208210
}
209211
}
210212

211-
impl hal::blocking::i2c::Transactional for I2cdev {
213+
impl embedded_hal::blocking::i2c::Transactional for I2cdev {
212214
type Error = i2cdev::linux::LinuxI2CError;
213215

214216
fn try_exec(&mut self, address: u8, operations: &mut [I2cOperation]) -> Result<(), Self::Error>
@@ -259,7 +261,7 @@ impl Spidev {
259261
}
260262
}
261263

262-
impl hal::blocking::spi::Transfer<u8> for Spidev {
264+
impl embedded_hal::blocking::spi::Transfer<u8> for Spidev {
263265
type Error = io::Error;
264266

265267
fn try_transfer<'b>(&mut self, buffer: &'b mut [u8]) -> io::Result<&'b [u8]> {
@@ -270,14 +272,44 @@ impl hal::blocking::spi::Transfer<u8> for Spidev {
270272
}
271273
}
272274

273-
impl hal::blocking::spi::Write<u8> for Spidev {
275+
impl embedded_hal::blocking::spi::Write<u8> for Spidev {
274276
type Error = io::Error;
275277

276278
fn try_write(&mut self, buffer: &[u8]) -> io::Result<()> {
277279
self.0.write_all(buffer)
278280
}
279281
}
280282

283+
pub use embedded_hal::blocking::spi::{Operation as SpiOperation};
284+
285+
/// Transactional implementation batches SPI operations into a single transaction
286+
impl embedded_hal::blocking::spi::Transactional<u8> for Spidev {
287+
type Error = io::Error;
288+
289+
fn try_exec<'a>(&mut self, operations: &mut [SpiOperation<'a, u8>]) -> Result<(), Self::Error> {
290+
291+
// Map types from generic to linux objects
292+
let mut messages: Vec<_> = operations.iter_mut().map(|a| {
293+
match a {
294+
SpiOperation::Write(w) => SpidevTransfer::write(w),
295+
SpiOperation::Transfer(r) => {
296+
// Clone read to write pointer
297+
// SPIdev is okay with having w == r but this is tricky to achieve in safe rust
298+
let w = unsafe {
299+
let p = r.as_ptr();
300+
std::slice::from_raw_parts(p, r.len())
301+
};
302+
303+
SpidevTransfer::read_write(w, r)
304+
},
305+
}
306+
}).collect();
307+
308+
// Execute transfer
309+
self.0.transfer_multiple(&mut messages)
310+
}
311+
}
312+
281313
impl ops::Deref for Spidev {
282314
type Target = spidev::Spidev;
283315

src/serial.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use std::path::Path;
55

66
use nb;
77

8-
use hal;
98
use serial_core;
109
use serial_unix::TTYPort;
1110

@@ -30,7 +29,7 @@ fn translate_io_errors(err: std::io::Error) -> nb::Error<IoErrorKind> {
3029
}
3130
}
3231

33-
impl hal::serial::Read<u8> for Serial {
32+
impl embedded_hal::serial::Read<u8> for Serial {
3433
type Error = IoErrorKind;
3534

3635
fn try_read(&mut self) -> nb::Result<u8, Self::Error> {
@@ -44,7 +43,7 @@ impl hal::serial::Read<u8> for Serial {
4443
}
4544
}
4645

47-
impl hal::serial::Write<u8> for Serial {
46+
impl embedded_hal::serial::Write<u8> for Serial {
4847
type Error = IoErrorKind;
4948

5049
fn try_write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
@@ -61,7 +60,7 @@ impl hal::serial::Write<u8> for Serial {
6160
mod test {
6261
use std::path::Path;
6362

64-
use hal::serial::{Read, Write};
63+
use embedded_hal::serial::{Read, Write};
6564
use std::io::{Read as IoRead, Write as IoWrite};
6665

6766
use super::*;

src/sysfs_pin.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl SysfsPin {
2626
}
2727
}
2828

29-
impl hal::digital::OutputPin for SysfsPin {
29+
impl embedded_hal::digital::OutputPin for SysfsPin {
3030
type Error = sysfs_gpio::Error;
3131

3232
fn try_set_low(&mut self) -> Result<(), Self::Error> {
@@ -38,7 +38,7 @@ impl hal::digital::OutputPin for SysfsPin {
3838
}
3939
}
4040

41-
impl hal::digital::InputPin for SysfsPin {
41+
impl embedded_hal::digital::InputPin for SysfsPin {
4242
type Error = sysfs_gpio::Error;
4343

4444
fn try_is_high(&self) -> Result<bool, Self::Error> {

src/timer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use core::convert::Infallible;
44
use std::time::{Duration, Instant};
55

6-
use hal::timer::{CountDown, Periodic};
6+
use embedded_hal::timer::{CountDown, Periodic};
77

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

0 commit comments

Comments
 (0)