stm32f1_hal/common/uart/
uart_poll.rs

1//! It doesn't depend on DMA or interrupts, relying instead on continuous polling.
2
3use super::*;
4use crate::common::os::*;
5use embedded_hal_nb as e_nb;
6use embedded_io as e_io;
7
8// TX -------------------------------------------------------------------------
9
10pub struct UartPollTx<U, T> {
11    uart: U,
12    timeout: T,
13    flush_timeout: T,
14}
15
16impl<U: UartPeriph, T: Timeout> UartPollTx<U, T> {
17    pub fn new(uart: U, timeout: T, flush_timeout: T) -> Self {
18        Self {
19            uart,
20            timeout,
21            flush_timeout,
22        }
23    }
24}
25
26impl<U: UartPeriph, T: Timeout> e_nb::serial::ErrorType for UartPollTx<U, T> {
27    type Error = Error;
28}
29impl<U: UartPeriph, T: Timeout> e_io::ErrorType for UartPollTx<U, T> {
30    type Error = Error;
31}
32
33// NB Write ----
34
35impl<U: UartPeriph, T: Timeout> e_nb::serial::Write<u16> for UartPollTx<U, T> {
36    #[inline]
37    fn write(&mut self, word: u16) -> nb::Result<(), Self::Error> {
38        self.uart.write(word)
39    }
40
41    #[inline]
42    fn flush(&mut self) -> nb::Result<(), Self::Error> {
43        if self.uart.is_tx_empty() && self.uart.is_tx_complete() {
44            return Ok(());
45        }
46        Err(nb::Error::WouldBlock)
47    }
48}
49
50// IO Write ----
51
52impl<U: UartPeriph, T: Timeout> e_io::Write for UartPollTx<U, T> {
53    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
54        if buf.is_empty() {
55            return Err(Error::Other);
56        }
57
58        // try first data
59        let mut t = self.timeout.start();
60        let rst = loop {
61            let rst = self.uart.write(buf[0] as u16);
62            if let Err(nb::Error::WouldBlock) = rst {
63                if t.timeout() {
64                    break rst;
65                }
66                t.interval();
67            } else {
68                break rst;
69            }
70        };
71
72        match rst {
73            Ok(()) => (),
74            Err(nb::Error::WouldBlock) => return Err(Error::Busy),
75            Err(nb::Error::Other(_)) => return Err(Error::Other),
76        }
77
78        // write rest data
79        for (i, &data) in buf[1..buf.len()].iter().enumerate() {
80            if self.uart.write(data as u16).is_err() {
81                return Ok(i + 1);
82            }
83        }
84        Ok(buf.len())
85    }
86
87    fn flush(&mut self) -> Result<(), Self::Error> {
88        let mut t = self.flush_timeout.start();
89        loop {
90            if self.uart.is_tx_empty() && self.uart.is_tx_complete() {
91                return Ok(());
92            }
93
94            if t.timeout() {
95                break;
96            }
97            t.interval();
98        }
99        Err(Error::Other)
100    }
101}
102
103// RX -------------------------------------------------------------------------
104
105pub struct UartPollRx<U, T> {
106    uart: U,
107    timeout: T,
108    continue_timeout: T,
109}
110
111impl<U: UartPeriph, T: Timeout> UartPollRx<U, T> {
112    pub fn new(uart: U, timeout: T, continue_timeout: T) -> Self {
113        Self {
114            uart,
115            timeout,
116            continue_timeout,
117        }
118    }
119}
120
121impl<U: UartPeriph, T: Timeout> e_nb::serial::ErrorType for UartPollRx<U, T> {
122    type Error = Error;
123}
124impl<U: UartPeriph, T: Timeout> e_io::ErrorType for UartPollRx<U, T> {
125    type Error = Error;
126}
127
128// NB Read ----
129
130impl<U: UartPeriph, T: Timeout> e_nb::serial::Read<u16> for UartPollRx<U, T> {
131    #[inline]
132    fn read(&mut self) -> nb::Result<u16, Self::Error> {
133        self.uart.read()
134    }
135}
136
137// IO Read ----
138
139impl<U: UartPeriph, T: Timeout> e_io::Read for UartPollRx<U, T> {
140    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
141        if buf.is_empty() {
142            return Err(Error::Other);
143        }
144
145        // try first data
146        let mut t = self.timeout.start();
147        let rst = loop {
148            let rst = self.uart.read();
149            if let Err(nb::Error::WouldBlock) = rst {
150                if t.timeout() {
151                    break rst;
152                }
153                t.interval();
154            } else {
155                break rst;
156            }
157        };
158
159        match rst {
160            Ok(data) => buf[0] = data as u8,
161            _ => return Err(Error::Other),
162        }
163
164        let mut t = self.continue_timeout.start();
165        let mut n = 1;
166        while n < buf.len() {
167            match self.uart.read() {
168                Ok(data) => {
169                    buf[n] = data as u8;
170                    n += 1;
171                    t.restart();
172                }
173                Err(nb::Error::Other(_)) => return Ok(n),
174                Err(nb::Error::WouldBlock) => {
175                    if t.timeout() {
176                        return Ok(n);
177                    }
178                    t.interval();
179                }
180            }
181        }
182        Ok(buf.len())
183    }
184}