@@ -9,31 +9,54 @@ 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 ,
34- {
35- cs . set_high ( ) ? ;
36- Ok ( Self { bus , cs , delay } )
54+ pub fn new ( bus : BUS , delay : D ) -> Result < Self , Infallible > {
55+ Ok ( Self {
56+ bus ,
57+ cs : NoPin ,
58+ delay ,
59+ } )
3760 }
3861
3962 /// Returns a reference to the underlying bus object.
@@ -49,12 +72,9 @@ impl<BUS, CS, D> ExclusiveDevice<BUS, CS, D> {
4972 }
5073}
5174
52- impl < BUS , CS > ExclusiveDevice < BUS , CS , super :: NoDelay > {
75+ impl < BUS > ExclusiveDevice < BUS , super :: NoDelay > {
5376 /// Create a new [`ExclusiveDevice`] without support for in-transaction delays.
5477 ///
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- ///
5878 /// **Warning**: The returned instance *technically* doesn't comply with the `SpiDevice`
5979 /// contract, which mandates delay support. It is relatively rare for drivers to use
6080 /// in-transaction delays, so you might still want to use this method because it's more practical.
@@ -70,31 +90,25 @@ impl<BUS, CS> ExclusiveDevice<BUS, CS, super::NoDelay> {
7090 /// The returned device will panic if you try to execute a transaction
7191 /// that contains any operations of type [`Operation::DelayNs`].
7292 #[ inline]
73- pub fn new_no_delay ( bus : BUS , mut cs : CS ) -> Result < Self , CS :: Error >
74- where
75- CS : OutputPin ,
76- {
77- cs. set_high ( ) ?;
93+ pub fn new_no_delay ( bus : BUS ) -> Result < Self , Infallible > {
7894 Ok ( Self {
7995 bus,
80- cs,
96+ cs : NoPin ,
8197 delay : super :: NoDelay ,
8298 } )
8399 }
84100}
85101
86- impl < BUS , CS , D > ErrorType for ExclusiveDevice < BUS , CS , D >
102+ impl < BUS , D > ErrorType for ExclusiveDevice < BUS , D >
87103where
88104 BUS : ErrorType ,
89- CS : OutputPin ,
90105{
91- type Error = DeviceError < BUS :: Error , CS :: Error > ;
106+ type Error = DeviceError < BUS :: Error , Infallible > ;
92107}
93108
94- impl < Word : Copy + ' static , BUS , CS , D > SpiDevice < Word > for ExclusiveDevice < BUS , CS , D >
109+ impl < Word : Copy + ' static , BUS , D > SpiDevice < Word > for ExclusiveDevice < BUS , D >
95110where
96111 BUS : SpiBus < Word > ,
97- CS : OutputPin ,
98112 D : DelayNs ,
99113{
100114 #[ inline]
@@ -105,10 +119,9 @@ where
105119
106120#[ cfg( feature = "async" ) ]
107121#[ cfg_attr( docsrs, doc( cfg( feature = "async" ) ) ) ]
108- impl < Word : Copy + ' static , BUS , CS , D > AsyncSpiDevice < Word > for ExclusiveDevice < BUS , CS , D >
122+ impl < Word : Copy + ' static , BUS , D > AsyncSpiDevice < Word > for ExclusiveDevice < BUS , D >
109123where
110124 BUS : AsyncSpiBus < Word > ,
111- CS : OutputPin ,
112125 D : AsyncDelayNs ,
113126{
114127 #[ inline]
@@ -142,11 +155,9 @@ where
142155
143156 // On failure, it's important to still flush and deassert CS.
144157 let flush_res = self . bus . flush ( ) . await ;
145- let cs_res = self . cs . set_high ( ) ;
146158
147159 op_res. map_err ( DeviceError :: Spi ) ?;
148160 flush_res. map_err ( DeviceError :: Spi ) ?;
149- cs_res. map_err ( DeviceError :: Cs ) ?;
150161
151162 Ok ( ( ) )
152163 }
0 commit comments