@@ -9,31 +9,54 @@ use embedded_hal_async::{
9
9
spi:: { SpiBus as AsyncSpiBus , SpiDevice as AsyncSpiDevice } ,
10
10
} ;
11
11
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
+
12
36
use super :: shared:: transaction;
13
37
use super :: DeviceError ;
14
38
15
39
/// [`SpiDevice`] implementation with exclusive access to the bus (not shared).
16
40
///
17
41
/// This is the most straightforward way of obtaining an [`SpiDevice`] from an [`SpiBus`],
18
42
/// 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 > {
20
45
bus : BUS ,
21
- cs : CS ,
46
+ cs : NoPin ,
22
47
delay : D ,
23
48
}
24
49
25
- impl < BUS , CS , D > ExclusiveDevice < BUS , CS , D > {
50
+ impl < BUS , D > ExclusiveDevice < BUS , D > {
26
51
/// Create a new [`ExclusiveDevice`].
27
52
///
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.
30
53
#[ 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
+ } )
37
60
}
38
61
39
62
/// Returns a reference to the underlying bus object.
@@ -49,12 +72,9 @@ impl<BUS, CS, D> ExclusiveDevice<BUS, CS, D> {
49
72
}
50
73
}
51
74
52
- impl < BUS , CS > ExclusiveDevice < BUS , CS , super :: NoDelay > {
75
+ impl < BUS > ExclusiveDevice < BUS , super :: NoDelay > {
53
76
/// Create a new [`ExclusiveDevice`] without support for in-transaction delays.
54
77
///
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
- ///
58
78
/// **Warning**: The returned instance *technically* doesn't comply with the `SpiDevice`
59
79
/// contract, which mandates delay support. It is relatively rare for drivers to use
60
80
/// 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> {
70
90
/// The returned device will panic if you try to execute a transaction
71
91
/// that contains any operations of type [`Operation::DelayNs`].
72
92
#[ 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 > {
78
94
Ok ( Self {
79
95
bus,
80
- cs,
96
+ cs : NoPin ,
81
97
delay : super :: NoDelay ,
82
98
} )
83
99
}
84
100
}
85
101
86
- impl < BUS , CS , D > ErrorType for ExclusiveDevice < BUS , CS , D >
102
+ impl < BUS , D > ErrorType for ExclusiveDevice < BUS , D >
87
103
where
88
104
BUS : ErrorType ,
89
- CS : OutputPin ,
90
105
{
91
- type Error = DeviceError < BUS :: Error , CS :: Error > ;
106
+ type Error = DeviceError < BUS :: Error , Infallible > ;
92
107
}
93
108
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 >
95
110
where
96
111
BUS : SpiBus < Word > ,
97
- CS : OutputPin ,
98
112
D : DelayNs ,
99
113
{
100
114
#[ inline]
@@ -105,10 +119,9 @@ where
105
119
106
120
#[ cfg( feature = "async" ) ]
107
121
#[ 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 >
109
123
where
110
124
BUS : AsyncSpiBus < Word > ,
111
- CS : OutputPin ,
112
125
D : AsyncDelayNs ,
113
126
{
114
127
#[ inline]
@@ -142,11 +155,9 @@ where
142
155
143
156
// On failure, it's important to still flush and deassert CS.
144
157
let flush_res = self . bus . flush ( ) . await ;
145
- let cs_res = self . cs . set_high ( ) ;
146
158
147
159
op_res. map_err ( DeviceError :: Spi ) ?;
148
160
flush_res. map_err ( DeviceError :: Spi ) ?;
149
- cs_res. map_err ( DeviceError :: Cs ) ?;
150
161
151
162
Ok ( ( ) )
152
163
}
0 commit comments