@@ -9,31 +9,52 @@ 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 ,
54
+ pub fn new ( bus : BUS , delay : D ) -> Result < Self , Infallible >
55
+
34
56
{
35
- cs. set_high ( ) ?;
36
- Ok ( Self { bus, cs, delay } )
57
+ Ok ( Self { bus, cs : NoPin , delay } )
37
58
}
38
59
39
60
/// Returns a reference to the underlying bus object.
@@ -49,12 +70,9 @@ impl<BUS, CS, D> ExclusiveDevice<BUS, CS, D> {
49
70
}
50
71
}
51
72
52
- impl < BUS , CS > ExclusiveDevice < BUS , CS , super :: NoDelay > {
73
+ impl < BUS > ExclusiveDevice < BUS , super :: NoDelay > {
53
74
/// 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
+ ///
58
76
/// **Warning**: The returned instance *technically* doesn't comply with the `SpiDevice`
59
77
/// contract, which mandates delay support. It is relatively rare for drivers to use
60
78
/// 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> {
70
88
/// The returned device will panic if you try to execute a transaction
71
89
/// that contains any operations of type [`Operation::DelayNs`].
72
90
#[ 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 >
76
92
{
77
- cs. set_high ( ) ?;
78
93
Ok ( Self {
79
94
bus,
80
- cs,
95
+ cs : NoPin ,
81
96
delay : super :: NoDelay ,
82
97
} )
83
98
}
84
99
}
85
100
86
- impl < BUS , CS , D > ErrorType for ExclusiveDevice < BUS , CS , D >
101
+ impl < BUS , D > ErrorType for ExclusiveDevice < BUS , D >
87
102
where
88
103
BUS : ErrorType ,
89
- CS : OutputPin ,
90
104
{
91
- type Error = DeviceError < BUS :: Error , CS :: Error > ;
105
+ type Error = DeviceError < BUS :: Error , Infallible > ;
92
106
}
93
107
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 >
95
109
where
96
110
BUS : SpiBus < Word > ,
97
- CS : OutputPin ,
98
111
D : DelayNs ,
99
112
{
100
113
#[ inline]
@@ -105,10 +118,9 @@ where
105
118
106
119
#[ cfg( feature = "async" ) ]
107
120
#[ 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 >
109
122
where
110
123
BUS : AsyncSpiBus < Word > ,
111
- CS : OutputPin ,
112
124
D : AsyncDelayNs ,
113
125
{
114
126
#[ inline]
@@ -142,11 +154,9 @@ where
142
154
143
155
// On failure, it's important to still flush and deassert CS.
144
156
let flush_res = self . bus . flush ( ) . await ;
145
- let cs_res = self . cs . set_high ( ) ;
146
157
147
158
op_res. map_err ( DeviceError :: Spi ) ?;
148
159
flush_res. map_err ( DeviceError :: Spi ) ?;
149
- cs_res. map_err ( DeviceError :: Cs ) ?;
150
160
151
161
Ok ( ( ) )
152
162
}
0 commit comments