stm32f1_hal/common/uart/
uart_it.rs

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