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