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 if let Op::ReadWriteDone(status) = node.operation.get() {
108 node.txbuffer.take().map(|write_buffer| {
109 let read_buffer = node.rxbuffer.take();
110 self.read_write_done(write_buffer, read_buffer, status);
111 });
112 }
113 });
114 }
115 }
116
117 fn do_next_op_async(&self) {
125 self.deferred_call.set();
126 }
127}
128
129impl<'a, Spi: hil::spi::SpiMaster<'a>> DeferredCallClient for MuxSpiMaster<'a, Spi> {
130 fn handle_deferred_call(&self) {
131 self.do_next_op();
132 }
133
134 fn register(&'static self) {
135 self.deferred_call.register(self);
136 }
137}
138
139#[derive(Copy, Clone, PartialEq)]
140enum Op {
141 Idle,
142 ReadWriteBytes,
143 ReadWriteDone(Result<usize, ErrorCode>),
144}
145
146struct SpiConfiguration<'a, Spi: hil::spi::SpiMaster<'a>> {
149 chip_select: Spi::ChipSelect,
150 polarity: hil::spi::ClockPolarity,
151 phase: hil::spi::ClockPhase,
152 rate: u32,
153}
154
155impl<'a, Spi: hil::spi::SpiMaster<'a>> Copy for SpiConfiguration<'a, Spi> {}
159impl<'a, Spi: hil::spi::SpiMaster<'a>> Clone for SpiConfiguration<'a, Spi> {
160 fn clone(&self) -> SpiConfiguration<'a, Spi> {
161 *self
162 }
163}
164
165pub struct VirtualSpiMasterDevice<'a, Spi: hil::spi::SpiMaster<'a>> {
166 mux: &'a MuxSpiMaster<'a, Spi>,
167 configuration: Cell<SpiConfiguration<'a, Spi>>,
168 txbuffer: MapCell<SubSliceMut<'static, u8>>,
169 rxbuffer: MapCell<SubSliceMut<'static, u8>>,
170 operation: Cell<Op>,
171 next: ListLink<'a, VirtualSpiMasterDevice<'a, Spi>>,
172 client: OptionalCell<&'a dyn hil::spi::SpiMasterClient>,
173}
174
175impl<'a, Spi: hil::spi::SpiMaster<'a>> VirtualSpiMasterDevice<'a, Spi> {
176 pub fn new(
177 mux: &'a MuxSpiMaster<'a, Spi>,
178 chip_select: Spi::ChipSelect,
179 ) -> VirtualSpiMasterDevice<'a, Spi> {
180 VirtualSpiMasterDevice {
181 mux,
182 configuration: Cell::new(SpiConfiguration {
183 chip_select,
184 polarity: hil::spi::ClockPolarity::IdleLow,
185 phase: hil::spi::ClockPhase::SampleLeading,
186 rate: 100_000,
187 }),
188 txbuffer: MapCell::empty(),
189 rxbuffer: MapCell::empty(),
190 operation: Cell::new(Op::Idle),
191 next: ListLink::empty(),
192 client: OptionalCell::empty(),
193 }
194 }
195
196 pub fn setup(&'a self) {
198 self.mux.devices.push_head(self);
199 }
200}
201
202impl<'a, Spi: hil::spi::SpiMaster<'a>> hil::spi::SpiMasterClient
203 for VirtualSpiMasterDevice<'a, Spi>
204{
205 fn read_write_done(
206 &self,
207 write_buffer: SubSliceMut<'static, u8>,
208 read_buffer: Option<SubSliceMut<'static, u8>>,
209 status: Result<usize, ErrorCode>,
210 ) {
211 self.client.map(move |client| {
212 client.read_write_done(write_buffer, read_buffer, status);
213 });
214 }
215}
216
217impl<'a, Spi: hil::spi::SpiMaster<'a>> ListNode<'a, VirtualSpiMasterDevice<'a, Spi>>
218 for VirtualSpiMasterDevice<'a, Spi>
219{
220 fn next(&'a self) -> &'a ListLink<'a, VirtualSpiMasterDevice<'a, Spi>> {
221 &self.next
222 }
223}
224
225impl<'a, Spi: hil::spi::SpiMaster<'a>> hil::spi::SpiMasterDevice<'a>
226 for VirtualSpiMasterDevice<'a, Spi>
227{
228 fn set_client(&self, client: &'a dyn SpiMasterClient) {
229 self.client.set(client);
230 }
231
232 fn configure(
233 &self,
234 cpol: hil::spi::ClockPolarity,
235 cpal: hil::spi::ClockPhase,
236 rate: u32,
237 ) -> Result<(), ErrorCode> {
238 if self.operation.get() == Op::Idle {
239 let mut configuration = self.configuration.get();
240 configuration.polarity = cpol;
241 configuration.phase = cpal;
242 configuration.rate = rate;
243 self.configuration.set(configuration);
244 Ok(())
245 } else {
246 Err(ErrorCode::BUSY)
247 }
248 }
249
250 fn read_write_bytes(
251 &self,
252 write_buffer: SubSliceMut<'static, u8>,
253 mut read_buffer: Option<SubSliceMut<'static, u8>>,
254 ) -> Result<
255 (),
256 (
257 ErrorCode,
258 SubSliceMut<'static, u8>,
259 Option<SubSliceMut<'static, u8>>,
260 ),
261 > {
262 if self.operation.get() == Op::Idle {
263 self.txbuffer.replace(write_buffer);
264 if let Some(rb) = read_buffer.take() {
265 self.rxbuffer.put(rb);
266 }
267 self.operation.set(Op::ReadWriteBytes);
268 self.mux.do_next_op();
269 Ok(())
270 } else {
271 Err((ErrorCode::BUSY, write_buffer, read_buffer))
272 }
273 }
274
275 fn set_polarity(&self, cpol: hil::spi::ClockPolarity) -> Result<(), ErrorCode> {
276 if self.operation.get() == Op::Idle {
277 let mut configuration = self.configuration.get();
278 configuration.polarity = cpol;
279 self.configuration.set(configuration);
280 Ok(())
281 } else {
282 Err(ErrorCode::BUSY)
283 }
284 }
285
286 fn set_phase(&self, cpal: hil::spi::ClockPhase) -> Result<(), ErrorCode> {
287 if self.operation.get() == Op::Idle {
288 let mut configuration = self.configuration.get();
289 configuration.phase = cpal;
290 self.configuration.set(configuration);
291 Ok(())
292 } else {
293 Err(ErrorCode::BUSY)
294 }
295 }
296
297 fn set_rate(&self, rate: u32) -> Result<(), ErrorCode> {
298 if self.operation.get() == Op::Idle {
299 let mut configuration = self.configuration.get();
300 configuration.rate = rate;
301 self.configuration.set(configuration);
302 Ok(())
303 } else {
304 Err(ErrorCode::BUSY)
305 }
306 }
307
308 fn get_polarity(&self) -> hil::spi::ClockPolarity {
309 self.configuration.get().polarity
310 }
311
312 fn get_phase(&self) -> hil::spi::ClockPhase {
313 self.configuration.get().phase
314 }
315
316 fn get_rate(&self) -> u32 {
317 self.configuration.get().rate
318 }
319}
320
321pub struct SpiSlaveDevice<'a, Spi: hil::spi::SpiSlave<'a>> {
322 spi: &'a Spi,
323 client: OptionalCell<&'a dyn hil::spi::SpiSlaveClient>,
324}
325
326impl<'a, Spi: hil::spi::SpiSlave<'a>> SpiSlaveDevice<'a, Spi> {
327 pub const fn new(spi: &'a Spi) -> SpiSlaveDevice<'a, Spi> {
328 SpiSlaveDevice {
329 spi,
330 client: OptionalCell::empty(),
331 }
332 }
333}
334
335impl<'a, Spi: hil::spi::SpiSlave<'a>> hil::spi::SpiSlaveClient for SpiSlaveDevice<'a, Spi> {
336 fn read_write_done(
337 &self,
338 write_buffer: Option<&'static mut [u8]>,
339 read_buffer: Option<&'static mut [u8]>,
340 len: usize,
341 status: Result<(), ErrorCode>,
342 ) {
343 self.client.map(move |client| {
344 client.read_write_done(write_buffer, read_buffer, len, status);
345 });
346 }
347
348 fn chip_selected(&self) {
349 self.client.map(move |client| {
350 client.chip_selected();
351 });
352 }
353}
354
355impl<'a, Spi: hil::spi::SpiSlave<'a>> hil::spi::SpiSlaveDevice<'a> for SpiSlaveDevice<'a, Spi> {
356 fn set_client(&self, client: &'a dyn hil::spi::SpiSlaveClient) {
357 self.client.set(client);
358 }
359
360 fn configure(
361 &self,
362 cpol: hil::spi::ClockPolarity,
363 cpal: hil::spi::ClockPhase,
364 ) -> Result<(), ErrorCode> {
365 self.spi.set_polarity(cpol)?;
366 self.spi.set_phase(cpal)
367 }
368
369 fn read_write_bytes(
370 &self,
371 write_buffer: Option<&'static mut [u8]>,
372 read_buffer: Option<&'static mut [u8]>,
373 len: usize,
374 ) -> Result<
375 (),
376 (
377 ErrorCode,
378 Option<&'static mut [u8]>,
379 Option<&'static mut [u8]>,
380 ),
381 > {
382 self.spi.read_write_bytes(write_buffer, read_buffer, len)
383 }
384
385 fn set_polarity(&self, cpol: hil::spi::ClockPolarity) -> Result<(), ErrorCode> {
386 self.spi.set_polarity(cpol)
387 }
388
389 fn set_phase(&self, cpal: hil::spi::ClockPhase) -> Result<(), ErrorCode> {
390 self.spi.set_phase(cpal)
391 }
392
393 fn get_polarity(&self) -> hil::spi::ClockPolarity {
394 self.spi.get_polarity()
395 }
396
397 fn get_phase(&self) -> hil::spi::ClockPhase {
398 self.spi.get_phase()
399 }
400}