@@ -9,31 +9,52 @@ use embedded_hal_async::{
99 spi:: { SpiBus as AsyncSpiBus , SpiDevice as AsyncSpiDevice } ,
1010} ;
1111
12+ use core:: convert:: Infallible ;
13+ use embedded_hal:: digital:: ErrorType as NoPinErrorType ;
14+
15+ /// A dummy pin that does nothing.
16+ /// This can be used for devices that do not require a Chip Select (CS) pin.
17+ #[ derive( Debug , Default , Copy , Clone ) ]
18+ pub struct NoPin ;
19+
20+ // Implement `ErrorType` for NoPin (Explicitly Using `digital::ErrorType`)
21+ impl NoPinErrorType for NoPin {
22+ type Error = Infallible ;
23+ }
24+
25+ // Implement `OutputPin`
26+ impl OutputPin for NoPin {
27+ fn set_low ( & mut self ) -> Result < ( ) , Infallible > {
28+ Ok ( ( ) )
29+ }
30+
31+ fn set_high ( & mut self ) -> Result < ( ) , Infallible > {
32+ Ok ( ( ) )
33+ }
34+ }
35+
1236use super :: shared:: transaction;
1337use super :: DeviceError ;
1438
1539/// [`SpiDevice`] implementation with exclusive access to the bus (not shared).
1640///
1741/// This is the most straightforward way of obtaining an [`SpiDevice`] from an [`SpiBus`],
1842/// ideal for when no sharing is required (only one SPI device is present on the bus).
19- pub struct ExclusiveDevice < BUS , CS , D > {
43+ /// As this is meant for exclusive access, it doesn't require a Chip Select (CS) pin.
44+ pub struct ExclusiveDevice < BUS , D > {
2045 bus : BUS ,
21- cs : CS ,
46+ cs : NoPin ,
2247 delay : D ,
2348}
2449
25- impl < BUS , CS , D > ExclusiveDevice < BUS , CS , D > {
50+ impl < BUS , D > ExclusiveDevice < BUS , D > {
2651 /// Create a new [`ExclusiveDevice`].
2752 ///
28- /// This sets the `cs` pin high, and returns an error if that fails. It is recommended
29- /// to set the pin high the moment it's configured as an output, to avoid glitches.
3053 #[ inline]
31- pub fn new ( bus : BUS , mut cs : CS , delay : D ) -> Result < Self , CS :: Error >
32- where
33- CS : OutputPin ,
54+ pub fn new ( bus : BUS , delay : D ) -> Result < Self , Infallible >
55+
3456 {
35- cs. set_high ( ) ?;
36- Ok ( Self { bus, cs, delay } )
57+ Ok ( Self { bus, cs : NoPin , delay } )
3758 }
3859
3960 /// Returns a reference to the underlying bus object.
@@ -49,12 +70,9 @@ impl<BUS, CS, D> ExclusiveDevice<BUS, CS, D> {
4970 }
5071}
5172
52- impl < BUS , CS > ExclusiveDevice < BUS , CS , super :: NoDelay > {
73+ impl < BUS > ExclusiveDevice < BUS , super :: NoDelay > {
5374 /// Create a new [`ExclusiveDevice`] without support for in-transaction delays.
54- ///
55- /// This sets the `cs` pin high, and returns an error if that fails. It is recommended
56- /// to set the pin high the moment it's configured as an output, to avoid glitches.
57- ///
75+ ///
5876 /// **Warning**: The returned instance *technically* doesn't comply with the `SpiDevice`
5977 /// contract, which mandates delay support. It is relatively rare for drivers to use
6078 /// in-transaction delays, so you might still want to use this method because it's more practical.
@@ -70,31 +88,26 @@ impl<BUS, CS> ExclusiveDevice<BUS, CS, super::NoDelay> {
7088 /// The returned device will panic if you try to execute a transaction
7189 /// that contains any operations of type [`Operation::DelayNs`].
7290 #[ inline]
73- pub fn new_no_delay ( bus : BUS , mut cs : CS ) -> Result < Self , CS :: Error >
74- where
75- CS : OutputPin ,
91+ pub fn new_no_delay ( bus : BUS ) -> Result < Self , Infallible >
7692 {
77- cs. set_high ( ) ?;
7893 Ok ( Self {
7994 bus,
80- cs,
95+ cs : NoPin ,
8196 delay : super :: NoDelay ,
8297 } )
8398 }
8499}
85100
86- impl < BUS , CS , D > ErrorType for ExclusiveDevice < BUS , CS , D >
101+ impl < BUS , D > ErrorType for ExclusiveDevice < BUS , D >
87102where
88103 BUS : ErrorType ,
89- CS : OutputPin ,
90104{
91- type Error = DeviceError < BUS :: Error , CS :: Error > ;
105+ type Error = DeviceError < BUS :: Error , Infallible > ;
92106}
93107
94- impl < Word : Copy + ' static , BUS , CS , D > SpiDevice < Word > for ExclusiveDevice < BUS , CS , D >
108+ impl < Word : Copy + ' static , BUS , D > SpiDevice < Word > for ExclusiveDevice < BUS , D >
95109where
96110 BUS : SpiBus < Word > ,
97- CS : OutputPin ,
98111 D : DelayNs ,
99112{
100113 #[ inline]
@@ -105,10 +118,9 @@ where
105118
106119#[ cfg( feature = "async" ) ]
107120#[ cfg_attr( docsrs, doc( cfg( feature = "async" ) ) ) ]
108- impl < Word : Copy + ' static , BUS , CS , D > AsyncSpiDevice < Word > for ExclusiveDevice < BUS , CS , D >
121+ impl < Word : Copy + ' static , BUS , D > AsyncSpiDevice < Word > for ExclusiveDevice < BUS , D >
109122where
110123 BUS : AsyncSpiBus < Word > ,
111- CS : OutputPin ,
112124 D : AsyncDelayNs ,
113125{
114126 #[ inline]
@@ -142,11 +154,9 @@ where
142154
143155 // On failure, it's important to still flush and deassert CS.
144156 let flush_res = self . bus . flush ( ) . await ;
145- let cs_res = self . cs . set_high ( ) ;
146157
147158 op_res. map_err ( DeviceError :: Spi ) ?;
148159 flush_res. map_err ( DeviceError :: Spi ) ?;
149- cs_res. map_err ( DeviceError :: Cs ) ?;
150160
151161 Ok ( ( ) )
152162 }
0 commit comments