stm32f1_hal/common/uart/
uart_it.rs

1//! UART interrupt implementation
2
3use super::*;
4use crate::common::{
5    embedded_io::{ErrorType, Read, Write},
6    ringbuf::*,
7};
8
9// TX -------------------------------------------------------------------------
10
11pub 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
83// TX interrupt -----------------
84
85pub 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
120// RX -------------------------------------------------------------------------
121
122pub 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
181// RX interrupt -----------------
182
183pub struct UartInterruptRxHandler<U, OS: OsInterface> {
184    uart: U,
185    w: Producer<u8>,
186    notifier: OS::Notifier,
187    // count: [u32; 10],
188}
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            // count: [0; 10],
202        }
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        // match self.uart.read() {
212        //     Ok(data) => match self.w.push(data as u8) {
213        //         Ok(()) => self.count[0] = self.count[0].saturating_add(1),
214        //         Err(_) => self.count[1] = self.count[1].saturating_add(1),
215        //     },
216        //     Err(nb::Error::WouldBlock) => self.count[2] = self.count[2].saturating_add(1),
217        //     Err(nb::Error::Other(e)) => match e {
218        //         Error::Overrun => self.count[3] = self.count[3].saturating_add(1),
219        //         Error::Other => self.count[4] = self.count[4].saturating_add(1),
220        //         Error::Noise => self.count[5] = self.count[5].saturating_add(1),
221        //         Error::FrameFormat => self.count[6] = self.count[6].saturating_add(1),
222        //         Error::Parity => self.count[7] = self.count[7].saturating_add(1),
223        //         Error::Busy => self.count[8] = self.count[8].saturating_add(1),
224        //     },
225        // }
226    }
227}