@@ -74,7 +74,22 @@ pub enum SdCardDeviceError {
74
74
Cs ,
75
75
}
76
76
77
- impl < BUS , CS > SdCardDevice for ( & RefCell < BUS > , CS )
77
+ /// A wrapper around a SPI bus and a CS pin, using a `RefCell`.
78
+ ///
79
+ /// This allows sharing the bus within the same thread.
80
+ pub struct RefCellSdCardDevice < ' a , BUS , CS > {
81
+ bus : & ' a RefCell < BUS > ,
82
+ cs : CS ,
83
+ }
84
+
85
+ impl < ' a , BUS , CS > RefCellSdCardDevice < ' a , BUS , CS > {
86
+ /// Create a new `RefCellSdCardDevice`.
87
+ pub fn new ( bus : & ' a RefCell < BUS > , cs : CS ) -> Self {
88
+ Self { bus, cs }
89
+ }
90
+ }
91
+
92
+ impl < BUS , CS > SdCardDevice for RefCellSdCardDevice < ' _ , BUS , CS >
78
93
where
79
94
BUS : SpiBus ,
80
95
CS : OutputPin ,
@@ -83,75 +98,106 @@ where
83
98
& mut self ,
84
99
operations : & mut [ Operation < ' _ , u8 > ] ,
85
100
) -> Result < ( ) , SdCardDeviceError > {
86
- let ( bus, cs) = self ;
87
- let mut bus = bus. borrow_mut ( ) ;
88
- bus_transaction ( & mut * bus, cs, operations)
101
+ let mut bus = self . bus . borrow_mut ( ) ;
102
+ bus_transaction ( & mut * bus, & mut self . cs , operations)
89
103
}
90
104
91
105
fn send_clock_pulses ( & mut self ) -> Result < ( ) , SdCardDeviceError > {
92
- let ( bus, cs) = self ;
93
- let mut bus = bus. borrow_mut ( ) ;
94
- send_clock_pulses ( & mut * bus, cs)
106
+ let mut bus = self . bus . borrow_mut ( ) ;
107
+ send_clock_pulses ( & mut * bus, & mut self . cs )
95
108
}
96
109
}
97
110
98
111
#[ cfg( feature = "embassy-sync-06" ) ]
99
- impl < CS , BUS , M > SdCardDevice for ( & embassy_sync_06:: blocking_mutex :: Mutex < M , RefCell < BUS > > , CS )
100
- where
101
- CS : OutputPin ,
102
- BUS : SpiBus ,
103
- M : embassy_sync_06 :: blocking_mutex :: raw :: RawMutex ,
104
- {
105
- fn transaction (
106
- & mut self ,
107
- operations : & mut [ Operation < ' _ , u8 > ] ,
108
- ) -> Result < ( ) , SdCardDeviceError > {
109
- let ( bus , cs ) = self ;
110
- bus . lock ( |bus| {
111
- let mut bus = bus . borrow_mut ( ) ;
112
- bus_transaction ( & mut * bus , cs , operations )
113
- } )
112
+ mod embassy_sync_06 {
113
+ use core :: cell :: RefCell ;
114
+
115
+ use :: embassy_sync_06 :: blocking_mutex ;
116
+
117
+ use super :: * ;
118
+
119
+ /// A wrapper around a SPI bus and a CS pin, using an `embassy-sync` blocking mutex.
120
+ ///
121
+ /// This allows sharing the bus with according to the `embassy-sync` mutex model.
122
+ /// See [`blocking_mutex::Mutex`] for more details.
123
+
124
+ pub struct EmbassyMutexSdCardDevice < ' a , BUS , CS , M > {
125
+ bus : & ' a blocking_mutex :: Mutex < M , RefCell < BUS > > ,
126
+ cs : CS ,
114
127
}
115
128
116
- fn send_clock_pulses ( & mut self ) -> Result < ( ) , SdCardDeviceError > {
117
- let ( bus, cs) = self ;
118
- bus. lock ( |bus| {
119
- let mut bus = bus. borrow_mut ( ) ;
120
- send_clock_pulses ( & mut * bus, cs)
121
- } )
129
+ impl < ' a , BUS , CS , M > EmbassyMutexSdCardDevice < ' a , BUS , CS , M > {
130
+ /// Create a new `EmbassyMutexSdCardDevice`.
131
+ pub fn new ( bus : & ' a blocking_mutex:: Mutex < M , RefCell < BUS > > , cs : CS ) -> Self {
132
+ Self { bus, cs }
133
+ }
134
+ }
135
+
136
+ impl < CS , BUS , M > SdCardDevice for EmbassyMutexSdCardDevice < ' _ , BUS , CS , M >
137
+ where
138
+ CS : OutputPin ,
139
+ BUS : SpiBus ,
140
+ M : blocking_mutex:: raw:: RawMutex ,
141
+ {
142
+ fn transaction (
143
+ & mut self ,
144
+ operations : & mut [ Operation < ' _ , u8 > ] ,
145
+ ) -> Result < ( ) , SdCardDeviceError > {
146
+ self . bus . lock ( |bus| {
147
+ let mut bus = bus. borrow_mut ( ) ;
148
+ bus_transaction ( & mut * bus, & mut self . cs , operations)
149
+ } )
150
+ }
151
+
152
+ fn send_clock_pulses ( & mut self ) -> Result < ( ) , SdCardDeviceError > {
153
+ self . bus . lock ( |bus| {
154
+ let mut bus = bus. borrow_mut ( ) ;
155
+ send_clock_pulses ( & mut * bus, & mut self . cs )
156
+ } )
157
+ }
122
158
}
123
159
}
124
160
125
- // `ExclusiveDevice` represents exclusive access to the bus so there's no need to send the dummy
126
- // byte after deasserting the CS pin. We can delegate the implementation to the `embedded_hal` trait.
161
+ #[ cfg( feature = "embassy-sync-06" ) ]
162
+ pub use embassy_sync_06:: * ;
163
+
127
164
#[ cfg( feature = "embedded-hal-bus-03" ) ]
128
- impl < CS , BUS , D > SdCardDevice for embedded_hal_bus_03:: spi:: ExclusiveDevice < BUS , CS , D >
129
- where
130
- BUS : SpiBus ,
131
- CS : OutputPin ,
132
- D : embedded_hal:: delay:: DelayNs ,
133
- {
134
- fn transaction (
135
- & mut self ,
136
- operations : & mut [ Operation < ' _ , u8 > ] ,
137
- ) -> Result < ( ) , SdCardDeviceError > {
138
- <Self as embedded_hal:: spi:: SpiDevice >:: transaction ( self , operations)
139
- . map_err ( |_| SdCardDeviceError :: Spi )
140
- }
165
+ mod embedded_hal_bus_03 {
166
+ use :: embedded_hal_bus_03:: spi:: ExclusiveDevice ;
167
+ use embedded_hal:: spi:: SpiDevice ;
141
168
142
- fn send_clock_pulses ( & mut self ) -> Result < ( ) , SdCardDeviceError > {
143
- let bus = self . bus_mut ( ) ;
169
+ use super :: * ;
144
170
145
- // There's no way to access the CS pin here so we can't set it high. Most likely it is already high so this is probably fine(?)
171
+ // `ExclusiveDevice` represents exclusive access to the bus so there's no need to send the dummy
172
+ // byte after deasserting the CS pin. We can delegate the implementation to the `embedded_hal` trait.
146
173
147
- let send_res = bus. write ( & [ 0xFF ; 10 ] ) ;
174
+ impl < CS , BUS , D > SdCardDevice for ExclusiveDevice < BUS , CS , D >
175
+ where
176
+ BUS : SpiBus ,
177
+ CS : OutputPin ,
178
+ D : embedded_hal:: delay:: DelayNs ,
179
+ {
180
+ fn transaction (
181
+ & mut self ,
182
+ operations : & mut [ Operation < ' _ , u8 > ] ,
183
+ ) -> Result < ( ) , SdCardDeviceError > {
184
+ <Self as SpiDevice >:: transaction ( self , operations) . map_err ( |_| SdCardDeviceError :: Spi )
185
+ }
186
+
187
+ fn send_clock_pulses ( & mut self ) -> Result < ( ) , SdCardDeviceError > {
188
+ let bus = self . bus_mut ( ) ;
189
+
190
+ // There's no way to access the CS pin here so we can't set it high. Most likely it is already high so this is probably fine(?)
148
191
149
- // On failure, it's important to still flush.
150
- let flush_res = bus. flush ( ) . map_err ( |_| SdCardDeviceError :: Spi ) ;
192
+ let send_res = bus. write ( & [ 0xFF ; 10 ] ) ;
151
193
152
- send_res. map_err ( |_| SdCardDeviceError :: Spi ) ?;
153
- flush_res. map_err ( |_| SdCardDeviceError :: Spi ) ?;
154
- Ok ( ( ) )
194
+ // On failure, it's important to still flush.
195
+ let flush_res = bus. flush ( ) . map_err ( |_| SdCardDeviceError :: Spi ) ;
196
+
197
+ send_res. map_err ( |_| SdCardDeviceError :: Spi ) ?;
198
+ flush_res. map_err ( |_| SdCardDeviceError :: Spi ) ?;
199
+ Ok ( ( ) )
200
+ }
155
201
}
156
202
}
157
203
0 commit comments