Skip to content

Commit 64ba1c3

Browse files
committed
Require infallible chipselect pins
1 parent 04b4f18 commit 64ba1c3

File tree

6 files changed

+38
-59
lines changed

6 files changed

+38
-59
lines changed

embedded-hal-bus/src/spi/critical_section.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use core::cell::RefCell;
2+
use core::convert::Infallible;
23
use critical_section::Mutex;
34
use embedded_hal::delay::DelayNs;
45
use embedded_hal::digital::OutputPin;
56
use embedded_hal::spi::{ErrorType, Operation, SpiBus, SpiDevice};
67

7-
use super::DeviceError;
88
use crate::spi::shared::transaction;
99

1010
/// `critical-section`-based shared bus [`SpiDevice`] implementation.
@@ -61,15 +61,15 @@ impl<'a, BUS, CS> CriticalSectionDevice<'a, BUS, CS, super::NoDelay> {
6161
impl<'a, BUS, CS, D> ErrorType for CriticalSectionDevice<'a, BUS, CS, D>
6262
where
6363
BUS: ErrorType,
64-
CS: OutputPin,
64+
CS: OutputPin<Error = Infallible>,
6565
{
66-
type Error = DeviceError<BUS::Error, CS::Error>;
66+
type Error = BUS::Error;
6767
}
6868

6969
impl<'a, Word: Copy + 'static, BUS, CS, D> SpiDevice<Word> for CriticalSectionDevice<'a, BUS, CS, D>
7070
where
7171
BUS: SpiBus<Word>,
72-
CS: OutputPin,
72+
CS: OutputPin<Error = Infallible>,
7373
D: DelayNs,
7474
{
7575
#[inline]

embedded-hal-bus/src/spi/exclusive.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! SPI bus sharing mechanisms.
22
3+
use core::convert::Infallible;
4+
35
use embedded_hal::delay::DelayNs;
46
use embedded_hal::digital::OutputPin;
57
use embedded_hal::spi::{ErrorType, Operation, SpiBus, SpiDevice};
@@ -10,7 +12,6 @@ use embedded_hal_async::{
1012
};
1113

1214
use super::shared::transaction;
13-
use super::DeviceError;
1415

1516
/// [`SpiDevice`] implementation with exclusive access to the bus (not shared).
1617
///
@@ -72,15 +73,15 @@ impl<BUS, CS> ExclusiveDevice<BUS, CS, super::NoDelay> {
7273
impl<BUS, CS, D> ErrorType for ExclusiveDevice<BUS, CS, D>
7374
where
7475
BUS: ErrorType,
75-
CS: OutputPin,
76+
CS: OutputPin<Error = Infallible>,
7677
{
77-
type Error = DeviceError<BUS::Error, CS::Error>;
78+
type Error = BUS::Error;
7879
}
7980

8081
impl<Word: Copy + 'static, BUS, CS, D> SpiDevice<Word> for ExclusiveDevice<BUS, CS, D>
8182
where
8283
BUS: SpiBus<Word>,
83-
CS: OutputPin,
84+
CS: OutputPin<Error = Infallible>,
8485
D: DelayNs,
8586
{
8687
#[inline]
@@ -94,15 +95,17 @@ where
9495
impl<Word: Copy + 'static, BUS, CS, D> AsyncSpiDevice<Word> for ExclusiveDevice<BUS, CS, D>
9596
where
9697
BUS: AsyncSpiBus<Word>,
97-
CS: OutputPin,
98+
CS: OutputPin<Error = Infallible>,
9899
D: AsyncDelayNs,
99100
{
100101
#[inline]
101102
async fn transaction(
102103
&mut self,
103104
operations: &mut [Operation<'_, Word>],
104105
) -> Result<(), Self::Error> {
105-
self.cs.set_low().map_err(DeviceError::Cs)?;
106+
use crate::spi::shared::into_ok;
107+
108+
into_ok(self.cs.set_low());
106109

107110
let op_res = 'ops: {
108111
for op in operations {
@@ -128,12 +131,8 @@ where
128131

129132
// On failure, it's important to still flush and deassert CS.
130133
let flush_res = self.bus.flush().await;
131-
let cs_res = self.cs.set_high();
132-
133-
op_res.map_err(DeviceError::Spi)?;
134-
flush_res.map_err(DeviceError::Spi)?;
135-
cs_res.map_err(DeviceError::Cs)?;
134+
into_ok(self.cs.set_high());
136135

137-
Ok(())
136+
op_res.and(flush_res)
138137
}
139138
}

embedded-hal-bus/src/spi/mod.rs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! `SpiDevice` implementations.
22
33
use core::fmt::Debug;
4-
use embedded_hal::spi::{Error, ErrorKind};
54

65
mod exclusive;
76
pub use exclusive::*;
@@ -19,30 +18,6 @@ pub use self::critical_section::*;
1918
#[cfg(feature = "defmt-03")]
2019
use crate::defmt;
2120

22-
/// Error type for [`ExclusiveDevice`] operations.
23-
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
24-
#[cfg_attr(feature = "defmt-03", derive(defmt::Format))]
25-
pub enum DeviceError<BUS, CS> {
26-
/// An inner SPI bus operation failed.
27-
Spi(BUS),
28-
/// Asserting or deasserting CS failed.
29-
Cs(CS),
30-
}
31-
32-
impl<BUS, CS> Error for DeviceError<BUS, CS>
33-
where
34-
BUS: Error + Debug,
35-
CS: Debug,
36-
{
37-
#[inline]
38-
fn kind(&self) -> ErrorKind {
39-
match self {
40-
Self::Spi(e) => e.kind(),
41-
Self::Cs(_) => ErrorKind::ChipSelectFault,
42-
}
43-
}
44-
}
45-
4621
/// Dummy [`DelayNs`](embedded_hal::delay::DelayNs) implementation that panics on use.
4722
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
4823
#[cfg_attr(feature = "defmt-03", derive(defmt::Format))]

embedded-hal-bus/src/spi/mutex.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
use core::convert::Infallible;
2+
13
use embedded_hal::delay::DelayNs;
24
use embedded_hal::digital::OutputPin;
35
use embedded_hal::spi::{ErrorType, Operation, SpiBus, SpiDevice};
46
use std::sync::Mutex;
57

6-
use super::DeviceError;
78
use crate::spi::shared::transaction;
89

910
/// `std` `Mutex`-based shared bus [`SpiDevice`] implementation.
@@ -59,15 +60,15 @@ impl<'a, BUS, CS> MutexDevice<'a, BUS, CS, super::NoDelay> {
5960
impl<'a, BUS, CS, D> ErrorType for MutexDevice<'a, BUS, CS, D>
6061
where
6162
BUS: ErrorType,
62-
CS: OutputPin,
63+
CS: OutputPin<Error = Infallible>,
6364
{
64-
type Error = DeviceError<BUS::Error, CS::Error>;
65+
type Error = BUS::Error;
6566
}
6667

6768
impl<'a, Word: Copy + 'static, BUS, CS, D> SpiDevice<Word> for MutexDevice<'a, BUS, CS, D>
6869
where
6970
BUS: SpiBus<Word>,
70-
CS: OutputPin,
71+
CS: OutputPin<Error = Infallible>,
7172
D: DelayNs,
7273
{
7374
#[inline]

embedded-hal-bus/src/spi/refcell.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use core::cell::RefCell;
2+
use core::convert::Infallible;
23
use embedded_hal::delay::DelayNs;
34
use embedded_hal::digital::OutputPin;
45
use embedded_hal::spi::{ErrorType, Operation, SpiBus, SpiDevice};
56

6-
use super::DeviceError;
77
use crate::spi::shared::transaction;
88

99
/// `RefCell`-based shared bus [`SpiDevice`] implementation.
@@ -58,15 +58,15 @@ impl<'a, BUS, CS> RefCellDevice<'a, BUS, CS, super::NoDelay> {
5858
impl<'a, BUS, CS, D> ErrorType for RefCellDevice<'a, BUS, CS, D>
5959
where
6060
BUS: ErrorType,
61-
CS: OutputPin,
61+
CS: OutputPin<Error = Infallible>,
6262
{
63-
type Error = DeviceError<BUS::Error, CS::Error>;
63+
type Error = BUS::Error;
6464
}
6565

6666
impl<'a, Word: Copy + 'static, BUS, CS, D> SpiDevice<Word> for RefCellDevice<'a, BUS, CS, D>
6767
where
6868
BUS: SpiBus<Word>,
69-
CS: OutputPin,
69+
CS: OutputPin<Error = Infallible>,
7070
D: DelayNs,
7171
{
7272
#[inline]

embedded-hal-bus/src/spi/shared.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1+
use core::convert::Infallible;
2+
13
use embedded_hal::delay::DelayNs;
24
use embedded_hal::digital::OutputPin;
35
use embedded_hal::spi::{ErrorType, Operation, SpiBus};
46

5-
use crate::spi::DeviceError;
6-
77
/// Common implementation to perform a transaction against the device.
88
#[inline]
99
pub fn transaction<Word, BUS, CS, D>(
1010
operations: &mut [Operation<Word>],
1111
bus: &mut BUS,
1212
delay: &mut D,
1313
cs: &mut CS,
14-
) -> Result<(), DeviceError<BUS::Error, CS::Error>>
14+
) -> Result<(), BUS::Error>
1515
where
1616
BUS: SpiBus<Word> + ErrorType,
17-
CS: OutputPin,
17+
CS: OutputPin<Error = Infallible>,
1818
D: DelayNs,
1919
Word: Copy,
2020
{
21-
cs.set_low().map_err(DeviceError::Cs)?;
21+
into_ok(cs.set_low());
2222

2323
let op_res = operations.iter_mut().try_for_each(|op| match op {
2424
Operation::Read(buf) => bus.read(buf),
@@ -34,11 +34,15 @@ where
3434

3535
// On failure, it's important to still flush and deassert CS.
3636
let flush_res = bus.flush();
37-
let cs_res = cs.set_high();
37+
into_ok(cs.set_high());
3838

39-
op_res.map_err(DeviceError::Spi)?;
40-
flush_res.map_err(DeviceError::Spi)?;
41-
cs_res.map_err(DeviceError::Cs)?;
39+
op_res.and(flush_res)
40+
}
4241

43-
Ok(())
42+
/// see https://github.com/rust-lang/rust/issues/61695
43+
pub(crate) fn into_ok<T>(res: Result<T, Infallible>) -> T {
44+
match res {
45+
Ok(t) => t,
46+
Err(infallible) => match infallible {},
47+
}
4448
}

0 commit comments

Comments
 (0)