capsules_core/virtualizers/
virtual_uart.rs1use core::cell::Cell;
49use core::cmp;
50
51use kernel::collections::list::{List, ListLink, ListNode};
52use kernel::deferred_call::{DeferredCall, DeferredCallClient};
53use kernel::hil::uart;
54use kernel::utilities::cells::{OptionalCell, TakeCell};
55use kernel::ErrorCode;
56
57pub const RX_BUF_LEN: usize = 64;
58
59pub struct MuxUart<'a> {
60 uart: &'a dyn uart::Uart<'a>,
61 speed: u32,
62 devices: List<'a, UartDevice<'a>>,
63 inflight: OptionalCell<&'a UartDevice<'a>>,
64 buffer: TakeCell<'static, [u8]>,
65 completing_read: Cell<bool>,
66 deferred_call: DeferredCall,
67}
68
69impl uart::TransmitClient for MuxUart<'_> {
70 fn transmitted_buffer(
71 &self,
72 tx_buffer: &'static mut [u8],
73 tx_len: usize,
74 rcode: Result<(), ErrorCode>,
75 ) {
76 self.inflight.map(move |device| {
77 self.inflight.clear();
78 device.transmitted_buffer(tx_buffer, tx_len, rcode);
79 });
80 self.do_next_op();
81 }
82}
83
84impl uart::ReceiveClient for MuxUart<'_> {
85 fn received_buffer(
86 &self,
87 buffer: &'static mut [u8],
88 rx_len: usize,
89 rcode: Result<(), ErrorCode>,
90 error: uart::Error,
91 ) {
92 let mut next_read_len = buffer.len();
97 let mut read_pending = false;
98
99 self.completing_read.set(true);
103
104 self.devices.iter().for_each(|device| {
110 if device.receiver {
111 device.rx_buffer.take().map(|rxbuf| {
112 let state = device.state.get();
113 let position = device.rx_position.get();
115 let remaining = device.rx_len.get() - position;
116 let len = cmp::min(rx_len, remaining);
117 if state == UartDeviceReceiveState::Receiving
118 || state == UartDeviceReceiveState::Aborting
119 {
120 rxbuf[position..(len + position)].copy_from_slice(&buffer[..len]);
122 }
123 device.rx_position.set(position + len);
124 device.rx_buffer.replace(rxbuf);
125 });
126 }
127 });
128 self.devices.iter().for_each(|device| {
134 if device.receiver {
135 device.rx_buffer.take().map(|rxbuf| {
136 let state = device.state.get();
137 let position = device.rx_position.get();
138 let remaining = device.rx_len.get() - position;
139 if remaining == 0 {
143 device.state.set(UartDeviceReceiveState::Idle);
144 device.received_buffer(rxbuf, position, rcode, error);
145 if device.state.get() == UartDeviceReceiveState::Receiving {
147 read_pending = true;
148 next_read_len = cmp::min(next_read_len, device.rx_len.get());
149 }
150 } else if state == UartDeviceReceiveState::Aborting {
151 device.state.set(UartDeviceReceiveState::Idle);
152 device.received_buffer(
153 rxbuf,
154 position,
155 Err(ErrorCode::CANCEL),
156 uart::Error::Aborted,
157 );
158 if device.state.get() == UartDeviceReceiveState::Receiving {
160 read_pending = true;
161 next_read_len = cmp::min(next_read_len, device.rx_len.get());
162 }
163 } else {
164 device.rx_buffer.replace(rxbuf);
165 next_read_len = cmp::min(next_read_len, remaining);
166 read_pending = true;
167 }
168 });
169 }
170 });
171
172 self.buffer.replace(buffer);
177
178 self.completing_read.set(false);
180
181 if read_pending {
185 if let Err((e, buf)) = self.start_receive(next_read_len) {
186 self.buffer.replace(buf);
187
188 self.devices.iter().for_each(|device| {
190 if device.receiver {
191 device.rx_buffer.take().map(|rxbuf| {
192 let state = device.state.get();
193 let position = device.rx_position.get();
194
195 if state == UartDeviceReceiveState::Receiving {
196 device.state.set(UartDeviceReceiveState::Idle);
197
198 device.received_buffer(
199 rxbuf,
200 position,
201 Err(e),
202 uart::Error::Aborted,
203 );
204 }
205 });
206 }
207 });
208 }
209 }
210 }
211}
212
213impl<'a> MuxUart<'a> {
214 pub fn new(uart: &'a dyn uart::Uart<'a>, buffer: &'static mut [u8], speed: u32) -> MuxUart<'a> {
215 MuxUart {
216 uart,
217 speed,
218 devices: List::new(),
219 inflight: OptionalCell::empty(),
220 buffer: TakeCell::new(buffer),
221 completing_read: Cell::new(false),
222 deferred_call: DeferredCall::new(),
223 }
224 }
225
226 pub fn initialize(&self) {
227 let _ = self.uart.configure(uart::Parameters {
228 baud_rate: self.speed,
229 width: uart::Width::Eight,
230 stop_bits: uart::StopBits::One,
231 parity: uart::Parity::None,
232 hw_flow_control: false,
233 });
234 }
235
236 fn do_next_op(&self) {
237 if self.inflight.is_none() {
238 let mnode = self.devices.iter().find(|node| node.operation.is_some());
239 mnode.map(|node| {
240 node.tx_buffer.take().map(|buf| {
241 node.operation.take().map(move |op| match op {
242 Operation::Transmit { len } => match self.uart.transmit_buffer(buf, len) {
243 Ok(()) => {
244 self.inflight.set(node);
245 }
246 Err((ecode, buf)) => {
247 node.tx_client.map(move |client| {
248 node.transmitting.set(false);
249 client.transmitted_buffer(buf, 0, Err(ecode));
250 });
251 }
252 },
253 Operation::TransmitWord { word } => {
254 let rcode = self.uart.transmit_word(word);
255 if rcode != Ok(()) {
256 node.tx_client.map(|client| {
257 node.transmitting.set(false);
258 client.transmitted_word(rcode);
259 });
260 }
261 }
262 });
263 });
264 });
265 }
266 }
267
268 fn start_receive(&self, rx_len: usize) -> Result<bool, (ErrorCode, &'static mut [u8])> {
280 self.buffer.take().map_or_else(
281 || {
282 if self.completing_read.get() {
284 Ok(false)
287 } else {
288 let _ = self.uart.receive_abort();
292 Ok(true)
293 }
294 },
295 |rxbuf| {
296 let len = cmp::min(rx_len, rxbuf.len());
298 self.uart.receive_buffer(rxbuf, len)?;
299 Ok(false)
300 },
301 )
302 }
303
304 fn do_next_op_async(&self) {
312 self.deferred_call.set();
313 }
314}
315
316impl DeferredCallClient for MuxUart<'_> {
317 fn handle_deferred_call(&self) {
318 self.do_next_op();
319 }
320
321 fn register(&'static self) {
322 self.deferred_call.register(self);
323 }
324}
325
326#[derive(Copy, Clone, PartialEq)]
327enum Operation {
328 Transmit { len: usize },
329 TransmitWord { word: u32 },
330}
331
332#[derive(Copy, Clone, PartialEq)]
333enum UartDeviceReceiveState {
334 Idle,
335 Receiving,
336 Aborting,
337}
338
339pub struct UartDevice<'a> {
340 state: Cell<UartDeviceReceiveState>,
341 mux: &'a MuxUart<'a>,
342 receiver: bool, tx_buffer: TakeCell<'static, [u8]>,
344 transmitting: Cell<bool>,
345 rx_buffer: TakeCell<'static, [u8]>,
346 rx_position: Cell<usize>,
347 rx_len: Cell<usize>,
348 operation: OptionalCell<Operation>,
349 next: ListLink<'a, UartDevice<'a>>,
350 rx_client: OptionalCell<&'a dyn uart::ReceiveClient>,
351 tx_client: OptionalCell<&'a dyn uart::TransmitClient>,
352}
353
354impl<'a> UartDevice<'a> {
355 pub fn new(mux: &'a MuxUart<'a>, receiver: bool) -> UartDevice<'a> {
356 UartDevice {
357 state: Cell::new(UartDeviceReceiveState::Idle),
358 mux,
359 receiver,
360 tx_buffer: TakeCell::empty(),
361 transmitting: Cell::new(false),
362 rx_buffer: TakeCell::empty(),
363 rx_position: Cell::new(0),
364 rx_len: Cell::new(0),
365 operation: OptionalCell::empty(),
366 next: ListLink::empty(),
367 rx_client: OptionalCell::empty(),
368 tx_client: OptionalCell::empty(),
369 }
370 }
371
372 pub fn setup(&'a self) {
374 self.mux.devices.push_head(self);
375 }
376}
377
378impl uart::TransmitClient for UartDevice<'_> {
379 fn transmitted_buffer(
380 &self,
381 tx_buffer: &'static mut [u8],
382 tx_len: usize,
383 rcode: Result<(), ErrorCode>,
384 ) {
385 self.tx_client.map(move |client| {
386 self.transmitting.set(false);
387 client.transmitted_buffer(tx_buffer, tx_len, rcode);
388 });
389 }
390
391 fn transmitted_word(&self, rcode: Result<(), ErrorCode>) {
392 self.tx_client.map(move |client| {
393 self.transmitting.set(false);
394 client.transmitted_word(rcode);
395 });
396 }
397}
398impl uart::ReceiveClient for UartDevice<'_> {
399 fn received_buffer(
400 &self,
401 rx_buffer: &'static mut [u8],
402 rx_len: usize,
403 rcode: Result<(), ErrorCode>,
404 error: uart::Error,
405 ) {
406 self.rx_client.map(move |client| {
407 self.state.set(UartDeviceReceiveState::Idle);
408 client.received_buffer(rx_buffer, rx_len, rcode, error);
409 });
410 }
411}
412
413impl<'a> ListNode<'a, UartDevice<'a>> for UartDevice<'a> {
414 fn next(&'a self) -> &'a ListLink<'a, UartDevice<'a>> {
415 &self.next
416 }
417}
418
419impl<'a> uart::Transmit<'a> for UartDevice<'a> {
420 fn set_transmit_client(&self, client: &'a dyn uart::TransmitClient) {
421 self.tx_client.set(client);
422 }
423
424 fn transmit_abort(&self) -> Result<(), ErrorCode> {
425 Err(ErrorCode::FAIL)
426 }
427
428 fn transmit_buffer(
430 &self,
431 tx_data: &'static mut [u8],
432 tx_len: usize,
433 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
434 if tx_len == 0 {
435 Err((ErrorCode::SIZE, tx_data))
436 } else if self.transmitting.get() {
437 Err((ErrorCode::BUSY, tx_data))
438 } else {
439 self.tx_buffer.replace(tx_data);
440 self.transmitting.set(true);
441 self.operation.set(Operation::Transmit { len: tx_len });
442 self.mux.do_next_op_async();
443 Ok(())
444 }
445 }
446
447 fn transmit_word(&self, word: u32) -> Result<(), ErrorCode> {
448 if self.transmitting.get() {
449 Err(ErrorCode::BUSY)
450 } else {
451 self.transmitting.set(true);
452 self.operation.set(Operation::TransmitWord { word });
453 self.mux.do_next_op_async();
454 Ok(())
455 }
456 }
457}
458
459impl<'a> uart::Receive<'a> for UartDevice<'a> {
460 fn set_receive_client(&self, client: &'a dyn uart::ReceiveClient) {
461 self.rx_client.set(client);
462 }
463
464 fn receive_buffer(
466 &self,
467 rx_buffer: &'static mut [u8],
468 rx_len: usize,
469 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
470 if self.rx_buffer.is_some() {
471 Err((ErrorCode::BUSY, rx_buffer))
472 } else if rx_len > rx_buffer.len() {
473 Err((ErrorCode::SIZE, rx_buffer))
474 } else {
475 self.rx_buffer.replace(rx_buffer);
476 self.rx_len.set(rx_len);
477 self.rx_position.set(0);
478 self.state.set(UartDeviceReceiveState::Idle);
479 self.mux.start_receive(rx_len)?;
480 self.state.set(UartDeviceReceiveState::Receiving);
481 Ok(())
482 }
483 }
484
485 fn receive_abort(&self) -> Result<(), ErrorCode> {
488 self.state.set(UartDeviceReceiveState::Aborting);
489 let _ = self.mux.uart.receive_abort();
490 Err(ErrorCode::BUSY)
491 }
492
493 fn receive_word(&self) -> Result<(), ErrorCode> {
494 Err(ErrorCode::FAIL)
495 }
496}