py32_hal/usart/
ringbuffered.rs1use core::future::poll_fn;
8use core::mem;
9use core::sync::atomic::{compiler_fence, Ordering};
10use core::task::Poll;
11
12use embassy_embedded_hal::SetConfig;
13use embassy_hal_internal::PeripheralRef;
14use embedded_io_async::ReadReady;
15use futures_util::future::{select, Either};
16
17use super::{
18 clear_interrupt_flags, rdr, reconfigure, sr, Config, ConfigError, Error, Info, State, UartRx,
19};
20#[cfg(dma)]
21use crate::dma::ReadableRingBuffer;
22use crate::gpio::{AnyPin, SealedPin as _};
23use crate::mode::Async;
24use crate::time::Hertz;
25use crate::usart::{Regs, Sr};
26
27pub struct RingBufferedUartRx<'d> {
31 info: &'static Info,
32 state: &'static State,
33 kernel_clock: Hertz,
34 rx: Option<PeripheralRef<'d, AnyPin>>,
35 rts: Option<PeripheralRef<'d, AnyPin>>,
36 ring_buf: ReadableRingBuffer<'d, u8>,
37}
38
39impl<'d> SetConfig for RingBufferedUartRx<'d> {
40 type Config = Config;
41 type ConfigError = ConfigError;
42
43 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
44 self.set_config(config)
45 }
46}
47
48impl<'d> UartRx<'d, Async> {
49 pub fn into_ring_buffered(mut self, dma_buf: &'d mut [u8]) -> RingBufferedUartRx<'d> {
53 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
54
55 let opts = Default::default();
56
57 let rx_dma = self.rx_dma.as_mut().unwrap();
59 let request = rx_dma.request;
60 let rx_dma = unsafe { rx_dma.channel.clone_unchecked() };
61
62 let info = self.info;
63 let state = self.state;
64 let kernel_clock = self.kernel_clock;
65 let ring_buf =
66 unsafe { ReadableRingBuffer::new(rx_dma, request, rdr(info.regs), dma_buf, opts) };
67 let rx = unsafe { self.rx.as_ref().map(|x| x.clone_unchecked()) };
68 let rts = unsafe { self.rts.as_ref().map(|x| x.clone_unchecked()) };
69
70 mem::forget(self);
72
73 RingBufferedUartRx {
74 info,
75 state,
76 kernel_clock,
77 rx,
78 rts,
79 ring_buf,
80 }
81 }
82}
83
84impl<'d> RingBufferedUartRx<'d> {
85 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
87 reconfigure(self.info, self.kernel_clock, config)
88 }
89
90 pub fn start_uart(&mut self) {
94 compiler_fence(Ordering::SeqCst);
96 self.ring_buf.start();
97
98 let r = self.info.regs;
99 r.cr1().modify(|w| {
101 w.set_rxneie(false);
103 w.set_peie(w.pce());
105 w.set_idleie(true);
107 });
108 r.cr3().modify(|w| {
109 w.set_eie(true);
111 w.set_dmar(true);
113 });
114 }
115
116 fn stop_uart(&mut self) {
118 self.ring_buf.request_pause();
119
120 let r = self.info.regs;
121 r.cr1().modify(|w| {
123 w.set_rxneie(false);
125 w.set_peie(false);
127 w.set_idleie(false);
129 });
130 r.cr3().modify(|w| {
131 w.set_eie(false);
133 w.set_dmar(false);
135 });
136
137 compiler_fence(Ordering::SeqCst);
138 }
139
140 pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
149 let r = self.info.regs;
150
151 let sr = clear_idle_flag(r);
154 if !r.cr3().read().dmar() {
155 self.start_uart();
156 } else {
157 check_for_errors(sr)?;
158 }
159
160 loop {
161 match self.ring_buf.read(buf) {
162 Ok((0, _)) => {}
163 Ok((len, _)) => {
164 return Ok(len);
165 }
166 Err(_) => {
167 self.stop_uart();
168 return Err(Error::Overrun);
169 }
170 }
171
172 match self.wait_for_data_or_idle().await {
173 Ok(_) => {}
174 Err(err) => {
175 self.stop_uart();
176 return Err(err);
177 }
178 }
179 }
180 }
181
182 async fn wait_for_data_or_idle(&mut self) -> Result<(), Error> {
184 compiler_fence(Ordering::SeqCst);
185
186 let s = self.state;
188 let uart = poll_fn(|cx| {
189 s.rx_waker.register(cx.waker());
190
191 compiler_fence(Ordering::SeqCst);
192
193 let sr = critical_section::with(|_| clear_idle_flag(self.info.regs));
196
197 check_for_errors(sr)?;
198
199 if sr.idle() {
200 Poll::Ready(Ok(()))
202 } else {
203 Poll::Pending
204 }
205 });
206
207 let mut dma_init = false;
208 let dma = poll_fn(|cx| {
210 self.ring_buf.set_waker(cx.waker());
211
212 let status = match dma_init {
213 false => Poll::Pending,
214 true => Poll::Ready(()),
215 };
216
217 dma_init = true;
218 status
219 });
220
221 match select(uart, dma).await {
222 Either::Left((result, _)) => result,
223 Either::Right(((), _)) => Ok(()),
224 }
225 }
226}
227
228impl Drop for RingBufferedUartRx<'_> {
229 fn drop(&mut self) {
230 self.stop_uart();
231 self.rx.as_ref().map(|x| x.set_as_disconnected());
232 self.rts.as_ref().map(|x| x.set_as_disconnected());
233 super::drop_tx_rx(self.info, self.state);
234 }
235}
236
237fn check_for_errors(s: Sr) -> Result<(), Error> {
239 if s.pe() {
240 Err(Error::Parity)
241 } else if s.fe() {
242 Err(Error::Framing)
243 } else if s.ne() {
244 Err(Error::Noise)
245 } else if s.ore() {
246 Err(Error::Overrun)
247 } else {
248 Ok(())
249 }
250}
251
252fn clear_idle_flag(r: Regs) -> Sr {
254 let sr = sr(r).read();
257
258 unsafe { rdr(r).read_volatile() };
260 clear_interrupt_flags(r, sr);
261
262 r.cr1().modify(|w| w.set_idleie(true));
263
264 sr
265}
266
267impl embedded_io_async::ErrorType for RingBufferedUartRx<'_> {
268 type Error = Error;
269}
270
271impl embedded_io_async::Read for RingBufferedUartRx<'_> {
272 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
273 self.read(buf).await
274 }
275}
276
277impl ReadReady for RingBufferedUartRx<'_> {
278 fn read_ready(&mut self) -> Result<bool, Self::Error> {
279 let len = self.ring_buf.len().map_err(|e| match e {
280 crate::dma::ringbuffer::Error::Overrun => Self::Error::Overrun,
281 crate::dma::ringbuffer::Error::DmaUnsynced => {
282 error!(
283 "Ringbuffer error: DmaUNsynced, driver implementation is
284 probably bugged please open an issue"
285 );
286 Self::Error::Overrun
288 }
289 })?;
290 Ok(len > 0)
291 }
292}