|
13 | 13 | #![deny(missing_docs)]
|
14 | 14 |
|
15 | 15 | extern crate cast;
|
16 |
| -extern crate core; |
17 | 16 | extern crate embedded_hal as hal;
|
18 | 17 | pub extern crate i2cdev;
|
19 |
| -pub extern crate spidev; |
20 |
| -pub extern crate serial_unix; |
21 |
| -pub extern crate serial_core; |
22 | 18 | pub extern crate nb;
|
23 |
| - |
| 19 | +pub extern crate serial_core; |
| 20 | +pub extern crate serial_unix; |
| 21 | +pub extern crate spidev; |
24 | 22 |
|
25 | 23 | #[cfg(feature = "gpio_sysfs")]
|
26 | 24 | pub extern crate sysfs_gpio;
|
27 | 25 |
|
28 | 26 | #[cfg(feature = "gpio_cdev")]
|
29 | 27 | pub extern crate gpio_cdev;
|
30 | 28 |
|
31 |
| - |
32 | 29 | use std::io::{self, Write};
|
33 | 30 | use std::path::{Path, PathBuf};
|
34 | 31 | use std::time::Duration;
|
@@ -60,7 +57,6 @@ pub use cdev_pin::CdevPin;
|
60 | 57 | /// Sysfs pin re-export
|
61 | 58 | pub use sysfs_pin::SysfsPin;
|
62 | 59 |
|
63 |
| - |
64 | 60 | /// Empty struct that provides delay functionality on top of `thread::sleep`
|
65 | 61 | pub struct Delay;
|
66 | 62 |
|
@@ -118,7 +114,6 @@ impl hal::blocking::delay::DelayMs<u64> for Delay {
|
118 | 114 | }
|
119 | 115 | }
|
120 | 116 |
|
121 |
| - |
122 | 117 | /// Newtype around [`i2cdev::linux::LinuxI2CDevice`] that implements the `embedded-hal` traits
|
123 | 118 | ///
|
124 | 119 | /// [`i2cdev::linux::LinuxI2CDevice`]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html
|
@@ -236,6 +231,39 @@ impl hal::blocking::spi::Write<u8> for Spidev {
|
236 | 231 | }
|
237 | 232 | }
|
238 | 233 |
|
| 234 | +pub use hal::blocking::spi::Operation as SpiOperation; |
| 235 | + |
| 236 | +impl hal::blocking::spi::Transactional<u8> for Spidev { |
| 237 | + type Error = io::Error; |
| 238 | + |
| 239 | + fn exec<'a>(&mut self, operations: &mut [SpiOperation<'a, u8>]) -> Result<(), Self::Error> { |
| 240 | + // Map types from generic to linux objects |
| 241 | + let mut messages: Vec<_> = operations |
| 242 | + .iter_mut() |
| 243 | + .map(|a| { |
| 244 | + match a { |
| 245 | + SpiOperation::Write(w) => SpidevTransfer::write(w), |
| 246 | + SpiOperation::Transfer(r) => { |
| 247 | + // Clone read to write pointer |
| 248 | + // SPIdev is okay with having w == r but this is tricky to achieve in safe rust |
| 249 | + let w = unsafe { |
| 250 | + let p = r.as_ptr(); |
| 251 | + std::slice::from_raw_parts(p, r.len()) |
| 252 | + }; |
| 253 | + |
| 254 | + SpidevTransfer::read_write(w, r) |
| 255 | + } |
| 256 | + } |
| 257 | + }) |
| 258 | + .collect(); |
| 259 | + |
| 260 | + // Execute transfer |
| 261 | + self.0.transfer_multiple(&mut messages)?; |
| 262 | + |
| 263 | + Ok(()) |
| 264 | + } |
| 265 | +} |
| 266 | + |
239 | 267 | impl ops::Deref for Spidev {
|
240 | 268 | type Target = spidev::Spidev;
|
241 | 269 |
|
|
0 commit comments