33use embedded_hal:: delay:: DelayUs ;
44use embedded_hal:: digital:: OutputPin ;
55use 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+ } ;
611
712use super :: DeviceError ;
813
@@ -21,6 +26,16 @@ impl<BUS, CS, D> ExclusiveDevice<BUS, CS, D> {
2126 pub fn new ( bus : BUS , cs : CS , delay : D ) -> Self {
2227 Self { bus, cs, delay }
2328 }
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+ }
2439}
2540
2641impl < BUS , CS > ExclusiveDevice < BUS , CS , super :: NoDelay > {
7994 Ok ( ( ) )
8095 }
8196}
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