1use super::*;
4use crate::common::{
5 embedded_io::{ErrorType, Read, Write},
6 ringbuf::*,
7};
8
9pub struct UartInterruptTx<U, OS: OsInterface> {
12 uart: U,
13 timeout: MicrosDurationU32,
14 flush_timeout: MicrosDurationU32,
15 w: Producer<u8>,
16 waiter: OS::NotifyWaiter,
17}
18
19impl<U, OS> UartInterruptTx<U, OS>
20where
21 U: UartPeriph,
22 OS: OsInterface,
23{
24 pub fn new(
25 uart: [U; 2],
26 buf_size: usize,
27 baudrate: u32,
28 timeout: MicrosDurationU32,
29 ) -> (Self, UartInterruptTxHandler<U, OS>) {
30 let (notifier, waiter) = OS::notify();
31 let [uart, u2] = uart;
32 let (w, r) = RingBuffer::<u8>::new(buf_size);
33 (
34 Self {
35 uart,
36 timeout,
37 flush_timeout: calculate_timeout(baudrate, buf_size + 10),
38 w,
39 waiter,
40 },
41 UartInterruptTxHandler::new(u2, r, notifier),
42 )
43 }
44}
45
46impl<U: UartPeriph, OS: OsInterface> ErrorType for UartInterruptTx<U, OS> {
47 type Error = Error;
48}
49
50impl<U: UartPeriph, OS: OsInterface> Write for UartInterruptTx<U, OS> {
51 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
52 if buf.is_empty() {
53 return Err(Error::Other);
54 }
55
56 self.waiter
57 .wait_with(OS::O, self.timeout, 2, || {
58 if let n @ 1.. = self.w.push_slice(buf) {
59 self.uart.set_interrupt(Event::TxEmpty, true);
60 return Some(n);
61 } else if !self.uart.is_interrupt_enable(Event::TxEmpty) {
62 self.uart.set_interrupt(Event::TxEmpty, true);
63 }
64 None
65 })
66 .ok_or(Error::Busy)
67 }
68
69 fn flush(&mut self) -> Result<(), Self::Error> {
70 self.waiter
71 .wait_with(OS::O, self.flush_timeout, 4, || {
72 if self.uart.is_tx_complete() && self.w.slots() == self.w.buffer().capacity() {
73 return Some(());
74 } else if !self.uart.is_interrupt_enable(Event::TxEmpty) {
75 self.uart.set_interrupt(Event::TxEmpty, true);
76 }
77 None
78 })
79 .ok_or(Error::Other)
80 }
81}
82
83pub struct UartInterruptTxHandler<U, OS: OsInterface> {
86 uart: U,
87 r: Consumer<u8>,
88 notifier: OS::Notifier,
89}
90
91impl<U, OS> UartInterruptTxHandler<U, OS>
92where
93 U: UartPeriph,
94 OS: OsInterface,
95{
96 pub fn new(uart: U, r: Consumer<u8>, notifier: OS::Notifier) -> Self {
97 Self { uart, r, notifier }
98 }
99}
100
101impl<U, OS> UartInterruptTxHandler<U, OS>
102where
103 U: UartPeriph,
104 OS: OsInterface,
105{
106 pub fn handler(&mut self) {
107 if let Some(has_data) = self.uart.write_with(|| {
108 let data = self.r.pop();
109 data.map_or(None, |d| Some(d as u16))
110 }) {
111 if has_data {
112 self.notifier.notify();
113 } else if self.uart.is_interrupt_enable(Event::TxEmpty) {
114 self.uart.set_interrupt(Event::TxEmpty, false);
115 }
116 }
117 }
118}
119
120pub struct UartInterruptRx<U, OS: OsInterface> {
123 uart: U,
124 timeout: MicrosDurationU32,
125 r: Consumer<u8>,
126 waiter: OS::NotifyWaiter,
127}
128
129impl<U, OS> UartInterruptRx<U, OS>
130where
131 U: UartPeriph,
132 OS: OsInterface,
133{
134 pub fn new(
135 uart: [U; 2],
136 buf_size: usize,
137 timeout: MicrosDurationU32,
138 ) -> (Self, UartInterruptRxHandler<U, OS>) {
139 let (notifier, waiter) = OS::notify();
140 let [uart, u2] = uart;
141 let (w, r) = RingBuffer::<u8>::new(buf_size);
142 (
143 Self {
144 uart,
145 timeout,
146 r,
147 waiter,
148 },
149 UartInterruptRxHandler::new(u2, w, notifier),
150 )
151 }
152}
153
154impl<U: UartPeriph, OS: OsInterface> ErrorType for UartInterruptRx<U, OS> {
155 type Error = Error;
156}
157
158impl<U, OS> Read for UartInterruptRx<U, OS>
159where
160 U: UartPeriph,
161 OS: OsInterface,
162{
163 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
164 if buf.is_empty() {
165 return Err(Error::Other);
166 }
167
168 self.waiter
169 .wait_with(OS::O, self.timeout, 2, || {
170 if let n @ 1.. = self.r.pop_slice(buf) {
171 return Some(n);
172 } else if !self.uart.is_interrupt_enable(Event::RxNotEmpty) {
173 self.uart.set_interrupt(Event::RxNotEmpty, true);
174 }
175 None
176 })
177 .ok_or(Error::Other)
178 }
179}
180
181pub struct UartInterruptRxHandler<U, OS: OsInterface> {
184 uart: U,
185 w: Producer<u8>,
186 notifier: OS::Notifier,
187 }
189
190impl<U, OS> UartInterruptRxHandler<U, OS>
191where
192 U: UartPeriph,
193 OS: OsInterface,
194{
195 pub fn new(mut uart: U, w: Producer<u8>, notifier: OS::Notifier) -> Self {
196 uart.set_interrupt(Event::RxNotEmpty, true);
197 Self {
198 uart,
199 w,
200 notifier,
201 }
203 }
204
205 pub fn handler(&mut self) {
206 if let Ok(data) = self.uart.read() {
207 self.w.push(data as u8).ok();
208 self.notifier.notify();
209 }
210
211 }
227}