3
3
use embedded_hal:: delay:: DelayUs ;
4
4
use embedded_hal:: digital:: OutputPin ;
5
5
use embedded_hal:: spi:: { ErrorType , Operation , SpiBus , SpiDevice } ;
6
+ #[ cfg( feature = "async" ) ]
7
+ use embedded_hal_async:: {
8
+ delay:: DelayUs as AsyncDelayUs ,
9
+ spi:: { SpiBus as AsyncSpiBus , SpiDevice as AsyncSpiDevice } ,
10
+ } ;
6
11
7
12
use super :: DeviceError ;
8
13
@@ -21,6 +26,16 @@ impl<BUS, CS, D> ExclusiveDevice<BUS, CS, D> {
21
26
pub fn new ( bus : BUS , cs : CS , delay : D ) -> Self {
22
27
Self { bus, cs, delay }
23
28
}
29
+
30
+ /// Returns a reference to the underlying bus object.
31
+ pub fn bus ( & self ) -> & BUS {
32
+ & self . bus
33
+ }
34
+
35
+ /// Returns a mutable reference to the underlying bus object.
36
+ pub fn bus_mut ( & mut self ) -> & mut BUS {
37
+ & mut self . bus
38
+ }
24
39
}
25
40
26
41
impl < BUS , CS > ExclusiveDevice < BUS , CS , super :: NoDelay > {
79
94
Ok ( ( ) )
80
95
}
81
96
}
97
+
98
+ #[ cfg( feature = "async" ) ]
99
+ #[ cfg_attr( docsrs, doc( cfg( feature = "async" ) ) ) ]
100
+ impl < Word : Copy + ' static , BUS , CS , D > AsyncSpiDevice < Word > for ExclusiveDevice < BUS , CS , D >
101
+ where
102
+ BUS : AsyncSpiBus < Word > ,
103
+ CS : OutputPin ,
104
+ D : AsyncDelayUs ,
105
+ {
106
+ async fn transaction (
107
+ & mut self ,
108
+ operations : & mut [ Operation < ' _ , Word > ] ,
109
+ ) -> Result < ( ) , Self :: Error > {
110
+ self . cs . set_low ( ) . map_err ( DeviceError :: Cs ) ?;
111
+
112
+ let op_res = ' ops: {
113
+ for op in operations {
114
+ let res = match op {
115
+ Operation :: Read ( buf) => self . bus . read ( buf) . await ,
116
+ Operation :: Write ( buf) => self . bus . write ( buf) . await ,
117
+ Operation :: Transfer ( read, write) => self . bus . transfer ( read, write) . await ,
118
+ Operation :: TransferInPlace ( buf) => self . bus . transfer_in_place ( buf) . await ,
119
+ Operation :: DelayUs ( us) => match self . bus . flush ( ) . await {
120
+ Err ( e) => Err ( e) ,
121
+ Ok ( ( ) ) => {
122
+ self . delay . delay_us ( * us) . await ;
123
+ Ok ( ( ) )
124
+ }
125
+ } ,
126
+ } ;
127
+ if let Err ( e) = res {
128
+ break ' ops Err ( e) ;
129
+ }
130
+ }
131
+ Ok ( ( ) )
132
+ } ;
133
+
134
+ // On failure, it's important to still flush and deassert CS.
135
+ let flush_res = self . bus . flush ( ) . await ;
136
+ let cs_res = self . cs . set_high ( ) ;
137
+
138
+ op_res. map_err ( DeviceError :: Spi ) ?;
139
+ flush_res. map_err ( DeviceError :: Spi ) ?;
140
+ cs_res. map_err ( DeviceError :: Cs ) ?;
141
+
142
+ Ok ( ( ) )
143
+ }
144
+ }
0 commit comments