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, W> {
11    uart: U,
12    timeout: W,
13    flush_timeout: W,
14}
15
16impl<U: UartPeriph, W: Waiter> UartPollTx<U, W> {
17    pub fn new(uart: U, timeout: W, flush_timeout: W) -> Self {
18        Self {
19            uart,
20            timeout,
21            flush_timeout,
22        }
23    }
24}
25
26impl<U: UartPeriph, W: Waiter> e_nb::serial::ErrorType for UartPollTx<U, W> {
27    type Error = Error;
28}
29impl<U: UartPeriph, W: Waiter> e_io::ErrorType for UartPollTx<U, W> {
30    type Error = Error;
31}
32
33// NB Write ----
34
35impl<U: UartPeriph, W: Waiter> e_nb::serial::Write<u16> for UartPollTx<U, W> {
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, W: Waiter> e_io::Write for UartPollTx<U, W> {
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            } else {
67                break rst;
68            }
69        };
70
71        match rst {
72            Ok(()) => (),
73            Err(nb::Error::WouldBlock) => return Err(Error::Busy),
74            Err(nb::Error::Other(_)) => return Err(Error::Other),
75        }
76
77        // write rest data
78        for (i, &data) in buf[1..buf.len()].iter().enumerate() {
79            if self.uart.write(data as u16).is_err() {
80                return Ok(i + 1);
81            }
82        }
83        Ok(buf.len())
84    }
85
86    fn flush(&mut self) -> Result<(), Self::Error> {
87        let mut t = self.flush_timeout.start();
88        loop {
89            if self.uart.is_tx_empty() && self.uart.is_tx_complete() {
90                return Ok(());
91            }
92
93            if t.timeout() {
94                break;
95            }
96        }
97        Err(Error::Other)
98    }
99}
100
101// RX -------------------------------------------------------------------------
102
103pub struct UartPollRx<U, W> {
104    uart: U,
105    timeout: W,
106    continue_timeout: W,
107}
108
109impl<U: UartPeriph, W: Waiter> UartPollRx<U, W> {
110    pub fn new(uart: U, timeout: W, continue_timeout: W) -> Self {
111        Self {
112            uart,
113            timeout,
114            continue_timeout,
115        }
116    }
117}
118
119impl<U: UartPeriph, W: Waiter> e_nb::serial::ErrorType for UartPollRx<U, W> {
120    type Error = Error;
121}
122impl<U: UartPeriph, W: Waiter> e_io::ErrorType for UartPollRx<U, W> {
123    type Error = Error;
124}
125
126// NB Read ----
127
128impl<U: UartPeriph, W: Waiter> e_nb::serial::Read<u16> for UartPollRx<U, W> {
129    #[inline]
130    fn read(&mut self) -> nb::Result<u16, Self::Error> {
131        self.uart.read()
132    }
133}
134
135// IO Read ----
136
137impl<U: UartPeriph, W: Waiter> e_io::Read for UartPollRx<U, W> {
138    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
139        if buf.is_empty() {
140            return Err(Error::Other);
141        }
142
143        // try first data
144        let mut t = self.timeout.start();
145        let rst = loop {
146            let rst = self.uart.read();
147            if let Err(nb::Error::WouldBlock) = rst {
148                if t.timeout() {
149                    break rst;
150                }
151            } else {
152                break rst;
153            }
154        };
155
156        match rst {
157            Ok(data) => buf[0] = data as u8,
158            _ => return Err(Error::Other),
159        }
160
161        let mut t = self.continue_timeout.start();
162        let mut n = 1;
163        while n < buf.len() {
164            match self.uart.read() {
165                Ok(data) => {
166                    buf[n] = data as u8;
167                    n += 1;
168                    t.restart();
169                }
170                Err(nb::Error::Other(_)) => return Ok(n),
171                Err(nb::Error::WouldBlock) => {
172                    if t.timeout() {
173                        return Ok(n);
174                    }
175                }
176            }
177        }
178        Ok(buf.len())
179    }
180}