|
1 | 1 | use super::*; |
2 | | -use crate::common::dma::*; |
| 2 | +use crate::common::{dma::*, os::*}; |
3 | 3 | use embedded_io::{ErrorType, Read, Write}; |
4 | 4 |
|
5 | 5 | // TX ------------------------------------------------------------------------- |
6 | 6 |
|
7 | | -pub struct UartDmaBufTx<U, CH> { |
| 7 | +pub struct UartDmaBufTx<U, CH, T> { |
8 | 8 | _uart: U, |
9 | 9 | w: DmaRingbufTxWriter<u8, CH>, |
| 10 | + timeout: T, |
| 11 | + flush_timeout: T, |
10 | 12 | } |
11 | 13 |
|
12 | | -impl<U, CH> UartDmaBufTx<U, CH> |
| 14 | +impl<U, CH, T> UartDmaBufTx<U, CH, T> |
13 | 15 | where |
14 | 16 | U: UartPeriph, |
15 | 17 | CH: DmaChannel, |
| 18 | + T: Timeout, |
16 | 19 | { |
17 | | - pub fn new(mut uart: U, dma_ch: CH, buf_size: usize) -> (Self, DmaRingbufTxLoader<u8, CH>) { |
| 20 | + pub fn new( |
| 21 | + mut uart: U, |
| 22 | + dma_ch: CH, |
| 23 | + buf_size: usize, |
| 24 | + timeout: T, |
| 25 | + flush_timeout: T, |
| 26 | + ) -> (Self, DmaRingbufTxLoader<u8, CH>) { |
18 | 27 | uart.enable_dma_tx(true); |
19 | 28 | let (w, l) = DmaRingbufTx::new(dma_ch, uart.get_tx_data_reg_addr(), buf_size); |
20 | | - (Self { _uart: uart, w }, l) |
| 29 | + ( |
| 30 | + Self { |
| 31 | + _uart: uart, |
| 32 | + w, |
| 33 | + timeout, |
| 34 | + flush_timeout, |
| 35 | + }, |
| 36 | + l, |
| 37 | + ) |
21 | 38 | } |
22 | 39 | } |
23 | 40 |
|
24 | | -impl<U, CH> ErrorType for UartDmaBufTx<U, CH> |
| 41 | +impl<U, CH, T> ErrorType for UartDmaBufTx<U, CH, T> |
25 | 42 | where |
26 | 43 | U: UartPeriph, |
27 | 44 | CH: DmaChannel, |
| 45 | + T: Timeout, |
28 | 46 | { |
29 | 47 | type Error = Error; |
30 | 48 | } |
31 | 49 |
|
32 | | -impl<U, CH> Write for UartDmaBufTx<U, CH> |
| 50 | +impl<U, CH, T> Write for UartDmaBufTx<U, CH, T> |
33 | 51 | where |
34 | 52 | U: UartPeriph, |
35 | 53 | CH: DmaChannel, |
| 54 | + T: Timeout, |
36 | 55 | { |
37 | 56 | #[inline(always)] |
38 | 57 | fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
39 | | - // TODO block |
40 | | - if let n @ 1.. = self.w.write(buf) { |
41 | | - Ok(n) |
42 | | - } else { |
43 | | - Err(Error::Busy) |
| 58 | + if buf.len() == 0 { |
| 59 | + return Err(Error::Other); |
44 | 60 | } |
| 61 | + |
| 62 | + let mut t = self.timeout.start(); |
| 63 | + loop { |
| 64 | + if let n @ 1.. = self.w.write(buf) { |
| 65 | + return Ok(n); |
| 66 | + } else if t.timeout() { |
| 67 | + break; |
| 68 | + } |
| 69 | + t.interval(); |
| 70 | + } |
| 71 | + Err(Error::Busy) |
45 | 72 | } |
46 | 73 |
|
47 | 74 | fn flush(&mut self) -> Result<(), Self::Error> { |
48 | | - // TODO |
49 | | - Ok(()) |
| 75 | + let mut t = self.flush_timeout.start(); |
| 76 | + loop { |
| 77 | + if !self.w.in_progress() { |
| 78 | + return Ok(()); |
| 79 | + } else if t.timeout() { |
| 80 | + break; |
| 81 | + } |
| 82 | + t.interval(); |
| 83 | + } |
| 84 | + Err(Error::Other) |
50 | 85 | } |
51 | 86 | } |
52 | 87 |
|
53 | 88 | // RX ------------------------------------------------------------------------- |
54 | 89 |
|
55 | | -pub struct UartDmaRx<U, CH> { |
| 90 | +pub struct UartDmaRx<U, CH, T> { |
56 | 91 | _uart: U, |
57 | 92 | ch: DmaCircularBufferRx<u8, CH>, |
| 93 | + timeout: T, |
58 | 94 | } |
59 | 95 |
|
60 | | -impl<U, CH> UartDmaRx<U, CH> |
| 96 | +impl<U, CH, T> UartDmaRx<U, CH, T> |
61 | 97 | where |
62 | 98 | U: UartPeriph, |
63 | 99 | CH: DmaChannel, |
| 100 | + T: Timeout, |
64 | 101 | { |
65 | | - pub fn new(mut uart: U, dma_ch: CH, buf_size: usize) -> Self { |
| 102 | + pub fn new(mut uart: U, dma_ch: CH, buf_size: usize, timeout: T) -> Self { |
66 | 103 | let ch = DmaCircularBufferRx::<u8, CH>::new(dma_ch, uart.get_rx_data_reg_addr(), buf_size); |
67 | 104 | uart.enable_dma_rx(true); |
68 | | - Self { _uart: uart, ch } |
| 105 | + Self { |
| 106 | + _uart: uart, |
| 107 | + ch, |
| 108 | + timeout, |
| 109 | + } |
69 | 110 | } |
70 | 111 | } |
71 | 112 |
|
72 | | -impl<U, CH> ErrorType for UartDmaRx<U, CH> |
| 113 | +impl<U, CH, T> ErrorType for UartDmaRx<U, CH, T> |
73 | 114 | where |
74 | 115 | U: UartPeriph, |
75 | 116 | CH: DmaChannel, |
| 117 | + T: Timeout, |
76 | 118 | { |
77 | 119 | type Error = Error; |
78 | 120 | } |
79 | 121 |
|
80 | | -impl<U, CH> Read for UartDmaRx<U, CH> |
| 122 | +impl<U, CH, T> Read for UartDmaRx<U, CH, T> |
81 | 123 | where |
82 | 124 | U: UartPeriph, |
83 | 125 | CH: DmaChannel, |
| 126 | + T: Timeout, |
84 | 127 | { |
85 | 128 | fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { |
86 | | - // TODO block |
87 | | - if let Some(d) = self.ch.read(buf.len()) { |
88 | | - buf[..d.len()].copy_from_slice(d); |
89 | | - Ok(d.len()) |
90 | | - } else { |
91 | | - Err(Error::Other) |
| 129 | + if buf.len() == 0 { |
| 130 | + return Err(Error::Other); |
| 131 | + } |
| 132 | + |
| 133 | + let mut t = self.timeout.start(); |
| 134 | + loop { |
| 135 | + if let Some(d) = self.ch.read(buf.len()) { |
| 136 | + buf[..d.len()].copy_from_slice(d); |
| 137 | + return Ok(d.len()); |
| 138 | + } else if t.timeout() { |
| 139 | + break; |
| 140 | + } |
| 141 | + t.interval(); |
92 | 142 | } |
| 143 | + Err(Error::Other) |
93 | 144 | } |
94 | 145 | } |
0 commit comments