1use core::cell::Cell;
8use kernel::collections::list::{List, ListLink, ListNode};
9use kernel::deferred_call::{DeferredCall, DeferredCallClient};
10use kernel::hil;
11use kernel::hil::spi::SpiMasterClient;
12use kernel::utilities::cells::{MapCell, OptionalCell};
13use kernel::utilities::leasable_buffer::SubSliceMut;
14use kernel::ErrorCode;
15
16pub struct MuxSpiMaster<'a, Spi: hil::spi::SpiMaster<'a>> {
19 spi: &'a Spi,
20 devices: List<'a, VirtualSpiMasterDevice<'a, Spi>>,
21 inflight: OptionalCell<&'a VirtualSpiMasterDevice<'a, Spi>>,
22 deferred_call: DeferredCall,
23}
24
25impl<'a, Spi: hil::spi::SpiMaster<'a>> hil::spi::SpiMasterClient for MuxSpiMaster<'a, Spi> {
26 fn read_write_done(
27 &self,
28 write_buffer: SubSliceMut<'static, u8>,
29 read_buffer: Option<SubSliceMut<'static, u8>>,
30 status: Result<usize, ErrorCode>,
31 ) {
32 let dev = self.inflight.take();
33 self.do_next_op();
38 dev.map(move |device| {
39 device.read_write_done(write_buffer, read_buffer, status);
40 });
41 }
42}
43
44impl<'a, Spi: hil::spi::SpiMaster<'a>> MuxSpiMaster<'a, Spi> {
45 pub fn new(spi: &'a Spi) -> Self {
46 Self {
47 spi,
48 devices: List::new(),
49 inflight: OptionalCell::empty(),
50 deferred_call: DeferredCall::new(),
51 }
52 }
53
54 fn do_next_op(&self) {
55 if self.inflight.is_none() {
56 let mnode = self
57 .devices
58 .iter()
59 .find(|node| node.operation.get() != Op::Idle);
60 mnode.map(|node| {
61 let configuration = node.configuration.get();
62 let cs = configuration.chip_select;
63 let _ = self.spi.specify_chip_select(cs);
64
65 let op = node.operation.get();
66 node.operation.set(Op::Idle);
68 match op {
69 Op::ReadWriteBytes => {
70 self.inflight.set(node);
73 node.txbuffer.take().map(|txbuffer| {
74 let rresult = self.spi.set_rate(configuration.rate);
75 let polresult = self.spi.set_polarity(configuration.polarity);
76 let phaseresult = self.spi.set_phase(configuration.phase);
77 if rresult.is_err() || polresult.is_err() || phaseresult.is_err() {
78 node.txbuffer.replace(txbuffer);
79 node.operation.set(Op::ReadWriteDone(Err(ErrorCode::INVAL)));
80 self.do_next_op_async();
81 } else {
82 let rxbuffer = node.rxbuffer.take();
83 if let Err((e, write_buffer, read_buffer)) =
84 self.spi.read_write_bytes(txbuffer, rxbuffer)
85 {
86 node.txbuffer.replace(write_buffer);
87 read_buffer.map(|buffer| {
88 node.rxbuffer.replace(buffer);
89 });
90 node.operation.set(Op::ReadWriteDone(Err(e)));
91 self.do_next_op_async();
92 }
93 }
94 });
95 }
96 Op::ReadWriteDone(status) => {
97 node.txbuffer.take().map(|write_buffer| {
98 let read_buffer = node.rxbuffer.take();
99 self.read_write_done(write_buffer, read_buffer, status);
100 });
101 }
102 Op::Idle => {} }
104 });
105 } else {
106 self.inflight.map(|node| {
107 match node.operation.get() {
108 Op::ReadWriteDone(status) => {
110 node.txbuffer.take().map(|write_buffer| {
111 let read_buffer = node.rxbuffer.take();
112 self.read_write_done(write_buffer, read_buffer, status);
113 });
114 }
115 _ => {} }
117 });
118 }
119 }
120
121 fn do_next_op_async(&self) {
129 self.deferred_call.set();
130 }
131}
132
133impl<'a, Spi: hil::spi::SpiMaster<'a>> DeferredCallClient for MuxSpiMaster<'a, Spi> {
134 fn handle_deferred_call(&self) {
135 self.do_next_op();
136 }
137
138 fn register(&'static self) {
139 self.deferred_call.register(self);
140 }
141}
142
143#[derive(Copy, Clone, PartialEq)]
144enum Op {
145 Idle,
146 ReadWriteBytes,
147 ReadWriteDone(Result<usize, ErrorCode>),
148}
149
150struct SpiConfiguration<'a, Spi: hil::spi::SpiMaster<'a>> {
153 chip_select: Spi::ChipSelect,
154 polarity: hil::spi::ClockPolarity,
155 phase: hil::spi::ClockPhase,
156 rate: u32,
157}
158
159impl<'a, Spi: hil::spi::SpiMaster<'a>> Copy for SpiConfiguration<'a, Spi> {}
163impl<'a, Spi: hil::spi::SpiMaster<'a>> Clone for SpiConfiguration<'a, Spi> {
164 fn clone(&self) -> SpiConfiguration<'a, Spi> {
165 *self
166 }
167}
168
169pub struct VirtualSpiMasterDevice<'a, Spi: hil::spi::SpiMaster<'a>> {
170 mux: &'a MuxSpiMaster<'a, Spi>,
171 configuration: Cell<SpiConfiguration<'a, Spi>>,
172 txbuffer: MapCell<SubSliceMut<'static, u8>>,
173 rxbuffer: MapCell<SubSliceMut<'static, u8>>,
174 operation: Cell<Op>,
175 next: ListLink<'a, VirtualSpiMasterDevice<'a, Spi>>,
176 client: OptionalCell<&'a dyn hil::spi::SpiMasterClient>,
177}
178
179impl<'a, Spi: hil::spi::SpiMaster<'a>> VirtualSpiMasterDevice<'a, Spi> {
180 pub fn new(
181 mux: &'a MuxSpiMaster<'a, Spi>,
182 chip_select: Spi::ChipSelect,
183 ) -> VirtualSpiMasterDevice<'a, Spi> {
184 VirtualSpiMasterDevice {
185 mux,
186 configuration: Cell::new(SpiConfiguration {
187 chip_select,
188 polarity: hil::spi::ClockPolarity::IdleLow,
189 phase: hil::spi::ClockPhase::SampleLeading,
190 rate: 100_000,
191 }),
192 txbuffer: MapCell::empty(),
193 rxbuffer: MapCell::empty(),
194 operation: Cell::new(Op::Idle),
195 next: ListLink::empty(),
196 client: OptionalCell::empty(),
197 }
198 }
199
200 pub fn setup(&'a self) {
202 self.mux.devices.push_head(self);
203 }
204}
205
206impl<'a, Spi: hil::spi::SpiMaster<'a>> hil::spi::SpiMasterClient
207 for VirtualSpiMasterDevice<'a, Spi>
208{
209 fn read_write_done(
210 &self,
211 write_buffer: SubSliceMut<'static, u8>,
212 read_buffer: Option<SubSliceMut<'static, u8>>,
213 status: Result<usize, ErrorCode>,
214 ) {
215 self.client.map(move |client| {
216 client.read_write_done(write_buffer, read_buffer, status);
217 });
218 }
219}
220
221impl<'a, Spi: hil::spi::SpiMaster<'a>> ListNode<'a, VirtualSpiMasterDevice<'a, Spi>>
222 for VirtualSpiMasterDevice<'a, Spi>
223{
224 fn next(&'a self) -> &'a ListLink<'a, VirtualSpiMasterDevice<'a, Spi>> {
225 &self.next
226 }
227}
228
229impl<'a, Spi: hil::spi::SpiMaster<'a>> hil::spi::SpiMasterDevice<'a>
230 for VirtualSpiMasterDevice<'a, Spi>
231{
232 fn set_client(&self, client: &'a dyn SpiMasterClient) {
233 self.client.set(client);
234 }
235
236 fn configure(
237 &self,
238 cpol: hil::spi::ClockPolarity,
239 cpal: hil::spi::ClockPhase,
240 rate: u32,
241 ) -> Result<(), ErrorCode> {
242 if self.operation.get() == Op::Idle {
243 let mut configuration = self.configuration.get();
244 configuration.polarity = cpol;
245 configuration.phase = cpal;
246 configuration.rate = rate;
247 self.configuration.set(configuration);
248 Ok(())
249 } else {
250 Err(ErrorCode::BUSY)
251 }
252 }
253
254 fn read_write_bytes(
255 &self,
256 write_buffer: SubSliceMut<'static, u8>,
257 mut read_buffer: Option<SubSliceMut<'static, u8>>,
258 ) -> Result<
259 (),
260 (
261 ErrorCode,
262 SubSliceMut<'static, u8>,
263 Option<SubSliceMut<'static, u8>>,
264 ),
265 > {
266 if self.operation.get() == Op::Idle {
267 self.txbuffer.replace(write_buffer);
268 if let Some(rb) = read_buffer.take() {
269 self.rxbuffer.put(rb);
270 }
271 self.operation.set(Op::ReadWriteBytes);
272 self.mux.do_next_op();
273 Ok(())
274 } else {
275 Err((ErrorCode::BUSY, write_buffer, read_buffer))
276 }
277 }
278
279 fn set_polarity(&self, cpol: hil::spi::ClockPolarity) -> Result<(), ErrorCode> {
280 if self.operation.get() == Op::Idle {
281 let mut configuration = self.configuration.get();
282 configuration.polarity = cpol;
283 self.configuration.set(configuration);
284 Ok(())
285 } else {
286 Err(ErrorCode::BUSY)
287 }
288 }
289
290 fn set_phase(&self, cpal: hil::spi::ClockPhase) -> Result<(), ErrorCode> {
291 if self.operation.get() == Op::Idle {
292 let mut configuration = self.configuration.get();
293 configuration.phase = cpal;
294 self.configuration.set(configuration);
295 Ok(())
296 } else {
297 Err(ErrorCode::BUSY)
298 }
299 }
300
301 fn set_rate(&self, rate: u32) -> Result<(), ErrorCode> {
302 if self.operation.get() == Op::Idle {
303 let mut configuration = self.configuration.get();
304 configuration.rate = rate;
305 self.configuration.set(configuration);
306 Ok(())
307 } else {
308 Err(ErrorCode::BUSY)
309 }
310 }
311
312 fn get_polarity(&self) -> hil::spi::ClockPolarity {
313 self.configuration.get().polarity
314 }
315
316 fn get_phase(&self) -> hil::spi::ClockPhase {
317 self.configuration.get().phase
318 }
319
320 fn get_rate(&self) -> u32 {
321 self.configuration.get().rate
322 }
323}
324
325pub struct SpiSlaveDevice<'a, Spi: hil::spi::SpiSlave<'a>> {
326 spi: &'a Spi,
327 client: OptionalCell<&'a dyn hil::spi::SpiSlaveClient>,
328}
329
330impl<'a, Spi: hil::spi::SpiSlave<'a>> SpiSlaveDevice<'a, Spi> {
331 pub const fn new(spi: &'a Spi) -> SpiSlaveDevice<'a, Spi> {
332 SpiSlaveDevice {
333 spi,
334 client: OptionalCell::empty(),
335 }
336 }
337}
338
339impl<'a, Spi: hil::spi::SpiSlave<'a>> hil::spi::SpiSlaveClient for SpiSlaveDevice<'a, Spi> {
340 fn read_write_done(
341 &self,
342 write_buffer: Option<&'static mut [u8]>,
343 read_buffer: Option<&'static mut [u8]>,
344 len: usize,
345 status: Result<(), ErrorCode>,
346 ) {
347 self.client.map(move |client| {
348 client.read_write_done(write_buffer, read_buffer, len, status);
349 });
350 }
351
352 fn chip_selected(&self) {
353 self.client.map(move |client| {
354 client.chip_selected();
355 });
356 }
357}
358
359impl<'a, Spi: hil::spi::SpiSlave<'a>> hil::spi::SpiSlaveDevice<'a> for SpiSlaveDevice<'a, Spi> {
360 fn set_client(&self, client: &'a dyn hil::spi::SpiSlaveClient) {
361 self.client.set(client);
362 }
363
364 fn configure(
365 &self,
366 cpol: hil::spi::ClockPolarity,
367 cpal: hil::spi::ClockPhase,
368 ) -> Result<(), ErrorCode> {
369 self.spi.set_polarity(cpol)?;
370 self.spi.set_phase(cpal)
371 }
372
373 fn read_write_bytes(
374 &self,
375 write_buffer: Option<&'static mut [u8]>,
376 read_buffer: Option<&'static mut [u8]>,
377 len: usize,
378 ) -> Result<
379 (),
380 (
381 ErrorCode,
382 Option<&'static mut [u8]>,
383 Option<&'static mut [u8]>,
384 ),
385 > {
386 self.spi.read_write_bytes(write_buffer, read_buffer, len)
387 }
388
389 fn set_polarity(&self, cpol: hil::spi::ClockPolarity) -> Result<(), ErrorCode> {
390 self.spi.set_polarity(cpol)
391 }
392
393 fn set_phase(&self, cpal: hil::spi::ClockPhase) -> Result<(), ErrorCode> {
394 self.spi.set_phase(cpal)
395 }
396
397 fn get_polarity(&self) -> hil::spi::ClockPolarity {
398 self.spi.get_polarity()
399 }
400
401 fn get_phase(&self) -> hil::spi::ClockPhase {
402 self.spi.get_phase()
403 }
404}