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::{embedded_hal_nb as e_nb, embedded_io as e_io};
5use core::marker::PhantomData;
6
7// TX -------------------------------------------------------------------------
8
9pub struct UartPollTx<U, OS> {
10    uart: U,
11    timeout: MicrosDurationU32,
12    flush_timeout: MicrosDurationU32,
13    _os: PhantomData<OS>,
14}
15
16impl<U: UartPeriph, OS: OsInterface> UartPollTx<U, OS> {
17    pub fn new(uart: U, baudrate: u32, timeout: MicrosDurationU32) -> Self {
18        Self {
19            uart,
20            timeout,
21            flush_timeout: calculate_timeout(baudrate, 4),
22            _os: PhantomData,
23        }
24    }
25}
26
27impl<U: UartPeriph, OS: OsInterface> e_nb::serial::ErrorType for UartPollTx<U, OS> {
28    type Error = Error;
29}
30impl<U: UartPeriph, OS: OsInterface> e_io::ErrorType for UartPollTx<U, OS> {
31    type Error = Error;
32}
33
34// NB Write ----
35
36impl<U: UartPeriph, OS: OsInterface> e_nb::serial::Write<u16> for UartPollTx<U, OS> {
37    #[inline]
38    fn write(&mut self, word: u16) -> nb::Result<(), Self::Error> {
39        self.uart.write(word)
40    }
41
42    #[inline]
43    fn flush(&mut self) -> nb::Result<(), Self::Error> {
44        if self.uart.is_tx_complete() {
45            return Ok(());
46        }
47        Err(nb::Error::WouldBlock)
48    }
49}
50
51// IO Write ----
52
53impl<U: UartPeriph, OS: OsInterface> e_io::Write for UartPollTx<U, OS> {
54    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
55        if buf.is_empty() {
56            return Err(Error::Other);
57        }
58
59        // try first data
60        let mut t = OS::timeout().start_us(self.timeout.to_micros());
61        let rst = loop {
62            let rst = self.uart.write(buf[0] as u16);
63            if let Err(nb::Error::WouldBlock) = rst {
64                if t.timeout() {
65                    break rst;
66                }
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 = OS::timeout().start_us(self.flush_timeout.to_micros());
89        loop {
90            if self.uart.is_tx_complete() {
91                return Ok(());
92            }
93
94            if t.timeout() {
95                break;
96            }
97        }
98        Err(Error::Other)
99    }
100}
101
102// RX -------------------------------------------------------------------------
103
104pub struct UartPollRx<U, OS> {
105    uart: U,
106    timeout: MicrosDurationU32,
107    continue_timeout: MicrosDurationU32,
108    _os: PhantomData<OS>,
109}
110
111impl<U: UartPeriph, OS: OsInterface> UartPollRx<U, OS> {
112    pub fn new(uart: U, baudrate: u32, timeout: MicrosDurationU32) -> Self {
113        Self {
114            uart,
115            timeout,
116            continue_timeout: calculate_timeout(baudrate, 4),
117            _os: PhantomData,
118        }
119    }
120}
121
122impl<U: UartPeriph, OS: OsInterface> e_nb::serial::ErrorType for UartPollRx<U, OS> {
123    type Error = Error;
124}
125impl<U: UartPeriph, OS: OsInterface> e_io::ErrorType for UartPollRx<U, OS> {
126    type Error = Error;
127}
128
129// NB Read ----
130
131impl<U: UartPeriph, OS: OsInterface> e_nb::serial::Read<u16> for UartPollRx<U, OS> {
132    #[inline]
133    fn read(&mut self) -> nb::Result<u16, Self::Error> {
134        self.uart.read()
135    }
136}
137
138// IO Read ----
139
140impl<U: UartPeriph, OS: OsInterface> e_io::Read for UartPollRx<U, OS> {
141    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
142        if buf.is_empty() {
143            return Err(Error::Other);
144        }
145
146        // try first data
147        let mut t = OS::timeout().start_us(self.timeout.to_micros());
148        let rst = loop {
149            let rst = self.uart.read();
150            if let Err(nb::Error::WouldBlock) = rst {
151                if t.timeout() {
152                    break rst;
153                }
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 = OS::timeout().start_us(self.continue_timeout.to_micros());
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                }
179            }
180        }
181        Ok(buf.len())
182    }
183}