1use super::*;
2use crate::common::{dma::*, os::*};
3use embedded_io::{ErrorType, Read, Write};
4
5pub struct UartDmaBufTx<U, CH, T> {
8 _uart: U,
9 w: DmaRingbufTxWriter<u8, CH>,
10 timeout: T,
11 flush_timeout: T,
12}
13
14impl<U, CH, T> UartDmaBufTx<U, CH, T>
15where
16 U: UartPeriph,
17 CH: DmaChannel,
18 T: Timeout,
19{
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>) {
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, T> ErrorType for UartDmaBufTx<U, CH, T>
42where
43 U: UartPeriph,
44 CH: DmaChannel,
45 T: Timeout,
46{
47 type Error = Error;
48}
49
50impl<U, CH, T> Write for UartDmaBufTx<U, CH, T>
51where
52 U: UartPeriph,
53 CH: DmaChannel,
54 T: Timeout,
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 t.interval();
70 }
71 Err(Error::Busy)
72 }
73
74 fn flush(&mut self) -> Result<(), Self::Error> {
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)
85 }
86}
87
88pub struct UartDmaRx<U, CH, T> {
91 _uart: U,
92 ch: DmaCircularBufferRx<u8, CH>,
93 timeout: T,
94}
95
96impl<U, CH, T> UartDmaRx<U, CH, T>
97where
98 U: UartPeriph,
99 CH: DmaChannel,
100 T: Timeout,
101{
102 pub fn new(mut uart: U, dma_ch: CH, buf_size: usize, timeout: T) -> Self {
103 let ch = DmaCircularBufferRx::<u8, CH>::new(dma_ch, uart.get_rx_data_reg_addr(), buf_size);
104 uart.enable_dma_rx(true);
105 Self {
106 _uart: uart,
107 ch,
108 timeout,
109 }
110 }
111}
112
113impl<U, CH, T> ErrorType for UartDmaRx<U, CH, T>
114where
115 U: UartPeriph,
116 CH: DmaChannel,
117 T: Timeout,
118{
119 type Error = Error;
120}
121
122impl<U, CH, T> Read for UartDmaRx<U, CH, T>
123where
124 U: UartPeriph,
125 CH: DmaChannel,
126 T: Timeout,
127{
128 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
129 if buf.is_empty() {
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();
142 }
143 Err(Error::Other)
144 }
145}