Skip to content

Commit c586d64

Browse files
committed
Extract SPI into separate module
1 parent 96c712e commit c586d64

File tree

3 files changed

+110
-101
lines changed

3 files changed

+110
-101
lines changed

src/lib.rs

Lines changed: 9 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,6 @@ pub use sysfs_gpio;
2323

2424
#[cfg(feature = "gpio_cdev")]
2525
pub use gpio_cdev;
26-
27-
use std::io::{self, Write};
28-
use std::ops;
29-
use std::path::Path;
30-
31-
use spidev::SpidevTransfer;
32-
33-
mod serial;
34-
mod timer;
35-
36-
pub use serial::Serial;
37-
pub use timer::SysTimer;
38-
3926
#[cfg(feature = "gpio_sysfs")]
4027
/// Sysfs Pin wrapper module
4128
mod sysfs_pin;
@@ -47,94 +34,19 @@ mod cdev_pin;
4734
#[cfg(feature = "gpio_cdev")]
4835
/// Cdev pin re-export
4936
pub use cdev_pin::CdevPin;
37+
5038
#[cfg(feature = "gpio_sysfs")]
5139
/// Sysfs pin re-export
5240
pub use sysfs_pin::SysfsPin;
5341

5442
mod delay;
55-
pub use crate::delay::Delay;
56-
5743
mod i2c;
58-
pub use crate::i2c::I2cdev;
59-
60-
/// Newtype around [`spidev::Spidev`] that implements the `embedded-hal` traits
61-
///
62-
/// [`spidev::Spidev`]: https://docs.rs/spidev/0.4.0/spidev/struct.Spidev.html
63-
pub struct Spidev(pub spidev::Spidev);
64-
65-
impl Spidev {
66-
/// See [`spidev::Spidev::open`][0] for details.
67-
///
68-
/// [0]: https://docs.rs/spidev/0.4.0/spidev/struct.Spidev.html#method.open
69-
pub fn open<P>(path: P) -> io::Result<Self>
70-
where
71-
P: AsRef<Path>,
72-
{
73-
spidev::Spidev::open(path).map(Spidev)
74-
}
75-
}
76-
77-
impl embedded_hal::blocking::spi::Transfer<u8> for Spidev {
78-
type Error = io::Error;
79-
80-
fn try_transfer<'b>(&mut self, buffer: &'b mut [u8]) -> io::Result<&'b [u8]> {
81-
let tx = buffer.to_owned();
82-
self.0
83-
.transfer(&mut SpidevTransfer::read_write(&tx, buffer))?;
84-
Ok(buffer)
85-
}
86-
}
87-
88-
impl embedded_hal::blocking::spi::Write<u8> for Spidev {
89-
type Error = io::Error;
90-
91-
fn try_write(&mut self, buffer: &[u8]) -> io::Result<()> {
92-
self.0.write_all(buffer)
93-
}
94-
}
95-
96-
pub use embedded_hal::blocking::spi::Operation as SpiOperation;
97-
98-
/// Transactional implementation batches SPI operations into a single transaction
99-
impl embedded_hal::blocking::spi::Transactional<u8> for Spidev {
100-
type Error = io::Error;
101-
102-
fn try_exec<'a>(&mut self, operations: &mut [SpiOperation<'a, u8>]) -> Result<(), Self::Error> {
103-
// Map types from generic to linux objects
104-
let mut messages: Vec<_> = operations
105-
.iter_mut()
106-
.map(|a| {
107-
match a {
108-
SpiOperation::Write(w) => SpidevTransfer::write(w),
109-
SpiOperation::Transfer(r) => {
110-
// Clone read to write pointer
111-
// SPIdev is okay with having w == r but this is tricky to achieve in safe rust
112-
let w = unsafe {
113-
let p = r.as_ptr();
114-
std::slice::from_raw_parts(p, r.len())
115-
};
116-
117-
SpidevTransfer::read_write(w, r)
118-
}
119-
}
120-
})
121-
.collect();
122-
123-
// Execute transfer
124-
self.0.transfer_multiple(&mut messages)
125-
}
126-
}
127-
128-
impl ops::Deref for Spidev {
129-
type Target = spidev::Spidev;
130-
131-
fn deref(&self) -> &Self::Target {
132-
&self.0
133-
}
134-
}
44+
mod serial;
45+
mod spi;
46+
mod timer;
13547

136-
impl ops::DerefMut for Spidev {
137-
fn deref_mut(&mut self) -> &mut Self::Target {
138-
&mut self.0
139-
}
140-
}
48+
pub use crate::delay::Delay;
49+
pub use crate::i2c::I2cdev;
50+
pub use crate::serial::Serial;
51+
pub use crate::spi::{SpiOperation, Spidev};
52+
pub use crate::timer::SysTimer;

src/serial.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
//! Implementation of [`Serial`](https://docs.rs/embedded-hal/0.2.1/embedded_hal/serial/index.html)
22
3-
use std::io::{ErrorKind as IoErrorKind, Read, Write};
4-
use std::path::Path;
5-
63
use nb;
7-
84
use serial_core;
95
use serial_unix::TTYPort;
6+
use std::io::{ErrorKind as IoErrorKind, Read, Write};
7+
use std::path::Path;
108

119
/// Newtype around [`serial_unix::TTYPort`] that implements
1210
/// the `embedded-hal` traits.

src/spi.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
//! Implementation of [`embedded-hal`] SPI traits
2+
//!
3+
//! [`embedded-hal`]: https://docs.rs/embedded-hal
4+
//!
5+
6+
pub use embedded_hal::blocking::spi::Operation as SpiOperation;
7+
use std::io;
8+
use std::ops;
9+
use std::path::Path;
10+
11+
/// Newtype around [`spidev::Spidev`] that implements the `embedded-hal` traits
12+
///
13+
/// [`spidev::Spidev`]: https://docs.rs/spidev/0.4.0/spidev/struct.Spidev.html
14+
pub struct Spidev(pub spidev::Spidev);
15+
16+
impl Spidev {
17+
/// See [`spidev::Spidev::open`][0] for details.
18+
///
19+
/// [0]: https://docs.rs/spidev/0.4.0/spidev/struct.Spidev.html#method.open
20+
pub fn open<P>(path: P) -> io::Result<Self>
21+
where
22+
P: AsRef<Path>,
23+
{
24+
spidev::Spidev::open(path).map(Spidev)
25+
}
26+
}
27+
28+
impl ops::Deref for Spidev {
29+
type Target = spidev::Spidev;
30+
31+
fn deref(&self) -> &Self::Target {
32+
&self.0
33+
}
34+
}
35+
36+
impl ops::DerefMut for Spidev {
37+
fn deref_mut(&mut self) -> &mut Self::Target {
38+
&mut self.0
39+
}
40+
}
41+
42+
mod embedded_hal_impl {
43+
use super::*;
44+
use embedded_hal::blocking::spi::{Transactional, Transfer, Write};
45+
use spidev::SpidevTransfer;
46+
use std::io::Write as _;
47+
48+
impl Transfer<u8> for Spidev {
49+
type Error = io::Error;
50+
51+
fn try_transfer<'b>(&mut self, buffer: &'b mut [u8]) -> io::Result<&'b [u8]> {
52+
let tx = buffer.to_owned();
53+
self.0
54+
.transfer(&mut SpidevTransfer::read_write(&tx, buffer))?;
55+
Ok(buffer)
56+
}
57+
}
58+
59+
impl Write<u8> for Spidev {
60+
type Error = io::Error;
61+
62+
fn try_write(&mut self, buffer: &[u8]) -> io::Result<()> {
63+
self.0.write_all(buffer)
64+
}
65+
}
66+
67+
/// Transactional implementation batches SPI operations into a single transaction
68+
impl Transactional<u8> for Spidev {
69+
type Error = io::Error;
70+
71+
fn try_exec<'a>(
72+
&mut self,
73+
operations: &mut [SpiOperation<'a, u8>],
74+
) -> Result<(), Self::Error> {
75+
// Map types from generic to linux objects
76+
let mut messages: Vec<_> = operations
77+
.iter_mut()
78+
.map(|a| {
79+
match a {
80+
SpiOperation::Write(w) => SpidevTransfer::write(w),
81+
SpiOperation::Transfer(r) => {
82+
// Clone read to write pointer
83+
// SPIdev is okay with having w == r but this is tricky to achieve in safe rust
84+
let w = unsafe {
85+
let p = r.as_ptr();
86+
std::slice::from_raw_parts(p, r.len())
87+
};
88+
89+
SpidevTransfer::read_write(w, r)
90+
}
91+
}
92+
})
93+
.collect();
94+
95+
// Execute transfer
96+
self.0.transfer_multiple(&mut messages)
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)