1use crate::{
2 async_hal::interrupts::{Binding, Handler, InterruptSource},
3 sercom::{
4 uart::{
5 Capability, DataReg, Duplex, Error, Flags, Receive, Rx, RxDuplex, SingleOwner,
6 Transmit, Tx, TxDuplex, Uart, ValidConfig,
7 },
8 Sercom,
9 },
10 typelevel::NoneT,
11};
12use atsamd_hal_macros::hal_macro_helper;
13use core::{marker::PhantomData, task::Poll};
14use num_traits::AsPrimitive;
15
16pub struct InterruptHandler<S: Sercom> {
18 _private: (),
19 _sercom: PhantomData<S>,
20}
21
22impl<S: Sercom> crate::typelevel::Sealed for InterruptHandler<S> {}
23
24impl<S: Sercom> Handler<S::Interrupt> for InterruptHandler<S> {
25 #[inline]
26 #[hal_macro_helper]
27 unsafe fn on_interrupt() {
28 unsafe {
29 let mut peripherals = crate::pac::Peripherals::steal();
30
31 #[hal_cfg(any("sercom0-d11", "sercom0-d21"))]
32 let uart = S::reg_block(&mut peripherals).usart();
33 #[hal_cfg("sercom0-d5x")]
34 let uart = S::reg_block(&mut peripherals).usart_int();
35
36 let flags_pending = Flags::from_bits_retain(uart.intflag().read().bits());
37 let enabled_flags = Flags::from_bits_retain(uart.intenset().read().bits());
38 uart.intenclr().write(|w| w.bits(flags_pending.bits()));
39
40 if (Flags::RX & enabled_flags).intersects(flags_pending) {
43 S::rx_waker().wake();
44 }
45
46 if (Flags::TX & enabled_flags).intersects(flags_pending) {
47 S::tx_waker().wake();
48 }
49 }
50 }
51}
52
53impl<C, D, S> Uart<C, D, NoneT, NoneT>
54where
55 C: ValidConfig<Sercom = S>,
56 D: SingleOwner,
57 S: Sercom,
58{
59 #[inline]
63 pub fn into_future<I>(self, _interrupts: I) -> UartFuture<C, D>
64 where
65 I: Binding<S::Interrupt, InterruptHandler<S>>,
66 {
67 S::Interrupt::unpend();
68 unsafe { S::Interrupt::enable() };
69
70 UartFuture { uart: self }
71 }
72}
73
74pub struct UartFuture<C, D, R = NoneT, T = NoneT>
78where
79 C: ValidConfig,
80 D: Capability,
81{
82 uart: Uart<C, D, R, T>,
83}
84
85pub type UartFutureDuplex<C> = UartFuture<C, Duplex>;
87
88pub type UartFutureRx<C> = UartFuture<C, Rx>;
90
91pub type UartFutureRxDuplex<C> = UartFuture<C, RxDuplex>;
93
94pub type UartFutureTx<C> = UartFuture<C, Tx>;
96
97pub type UartFutureTxDuplex<C> = UartFuture<C, TxDuplex>;
99
100impl<C, R, T> UartFuture<C, Duplex, R, T>
101where
102 C: ValidConfig,
103{
104 #[inline]
106 #[allow(clippy::type_complexity)]
107 pub fn split(
108 self,
109 ) -> (
110 UartFuture<C, RxDuplex, R, NoneT>,
111 UartFuture<C, TxDuplex, NoneT, T>,
112 ) {
113 let config = unsafe { core::ptr::read(&self.uart.config) };
114 (
115 UartFuture {
116 uart: Uart {
117 config: self.uart.config,
118 capability: PhantomData,
119 rx_channel: self.uart.rx_channel,
120 tx_channel: NoneT,
121 },
122 },
123 UartFuture {
124 uart: Uart {
125 config,
126 capability: PhantomData,
127 rx_channel: NoneT,
128 tx_channel: self.uart.tx_channel,
129 },
130 },
131 )
132 }
133
134 #[inline]
137 pub fn join(
138 rx: UartFuture<C, RxDuplex, R, NoneT>,
139 tx: UartFuture<C, TxDuplex, NoneT, T>,
140 ) -> Self {
141 Self {
142 uart: Uart {
143 config: rx.uart.config,
144 capability: PhantomData,
145 rx_channel: rx.uart.rx_channel,
146 tx_channel: tx.uart.tx_channel,
147 },
148 }
149 }
150}
151
152impl<C, D> UartFuture<C, D, NoneT, NoneT>
153where
154 C: ValidConfig,
155 D: SingleOwner,
156{
157 pub fn free(self) -> Uart<C, D> {
159 self.uart
160 }
161}
162
163impl<C, D, R, T> embedded_io::ErrorType for UartFuture<C, D, R, T>
164where
165 C: ValidConfig,
166 D: Capability,
167{
168 type Error = Error;
169}
170
171impl<C, D, S, R, T> UartFuture<C, D, R, T>
172where
173 C: ValidConfig<Sercom = S>,
174 D: Capability,
175 S: Sercom,
176{
177 #[inline]
178 async fn wait_flags(&mut self, flags_to_wait: Flags) {
179 let flags_to_wait = flags_to_wait & Flags::from_bits_retain(D::FLAG_MASK);
180
181 core::future::poll_fn(|cx| {
182 {
184 let maybe_pending = self.uart.config.as_ref().registers.read_flags();
185 if flags_to_wait.intersects(maybe_pending) {
186 return Poll::Ready(());
187 }
188 }
189
190 if flags_to_wait.intersects(Flags::RX) {
191 self.uart.disable_interrupts(Flags::RX);
192 S::rx_waker().register(cx.waker());
193 }
194 if flags_to_wait.intersects(Flags::TX) {
195 self.uart.disable_interrupts(Flags::RX);
196 S::tx_waker().register(cx.waker());
197 }
198 self.uart.enable_interrupts(flags_to_wait);
199 let maybe_pending = self.uart.config.as_ref().registers.read_flags();
200
201 if !flags_to_wait.intersects(maybe_pending) {
202 Poll::Pending
203 } else {
204 Poll::Ready(())
205 }
206 })
207 .await;
208 }
209}
210
211impl<C, D, S, R, T> UartFuture<C, D, R, T>
212where
213 C: ValidConfig<Sercom = S>,
214 D: Receive,
215 S: Sercom,
216 DataReg: AsPrimitive<C::Word>,
217{
218 #[cfg(feature = "dma")]
220 #[inline]
221 pub fn with_rx_dma_channel<Chan: crate::dmac::AnyChannel<Status = crate::dmac::ReadyFuture>>(
222 self,
223 rx_channel: Chan,
224 ) -> UartFuture<C, D, Chan, T> {
225 UartFuture {
226 uart: Uart {
227 config: self.uart.config,
228 capability: PhantomData,
229 rx_channel,
230 tx_channel: self.uart.tx_channel,
231 },
232 }
233 }
234
235 #[inline]
237 pub async fn read_word(&mut self) -> Result<C::Word, Error> {
238 self.wait_flags(Flags::RXC).await;
239 self.uart.read_status().check_bus_error()?;
240 Ok(unsafe { self.uart.read_data().as_() })
241 }
242}
243
244impl<C, D, S, T> UartFuture<C, D, NoneT, T>
245where
246 C: ValidConfig<Sercom = S>,
247 D: Receive,
248 S: Sercom,
249 DataReg: AsPrimitive<C::Word>,
250{
251 #[inline]
257 pub async fn read(&mut self, buffer: &mut [C::Word]) -> Result<(), (Error, usize)> {
258 for (i, word) in buffer.iter_mut().enumerate() {
259 match self.read_word().await {
260 Ok(w) => {
261 *word = w;
262 }
263 Err(e) => {
264 return Err((e, i));
265 }
266 }
267 }
268 Ok(())
269 }
270}
271
272impl<C, D, S, R> embedded_io_async::Read for UartFuture<C, D, NoneT, R>
273where
274 C: ValidConfig<Sercom = S, Word = u8>,
275 D: Receive,
276 S: Sercom,
277{
278 #[inline]
279 async fn read(&mut self, buffer: &mut [u8]) -> Result<usize, Self::Error> {
280 self.read(buffer).await.map_err(|(e, _)| e)?;
281 Ok(buffer.len())
282 }
283}
284
285impl<C, D, S, R, T> UartFuture<C, D, R, T>
286where
287 C: ValidConfig<Sercom = S>,
288 D: Transmit,
289 S: Sercom,
290{
291 #[cfg(feature = "dma")]
293 #[inline]
294 pub fn with_tx_dma_channel<Chan: crate::dmac::AnyChannel<Status = crate::dmac::ReadyFuture>>(
295 self,
296 tx_channel: Chan,
297 ) -> UartFuture<C, D, R, Chan> {
298 UartFuture {
299 uart: Uart {
300 config: self.uart.config,
301 capability: PhantomData,
302 rx_channel: self.uart.rx_channel,
303 tx_channel,
304 },
305 }
306 }
307
308 #[inline]
310 pub async fn write_word(&mut self, word: C::Word) {
311 self.wait_flags(Flags::DRE).await;
312 unsafe { self.uart.write_data(word.as_()) };
313 }
314}
315
316impl<C, D, S, R> UartFuture<C, D, R, NoneT>
317where
318 C: ValidConfig<Sercom = S>,
319 D: Transmit,
320 S: Sercom,
321{
322 #[inline]
325 pub async fn write(&mut self, buffer: &[C::Word]) {
326 for word in buffer {
327 self.write_word(*word).await;
328 }
329 }
330}
331
332impl<C, D, S, R> embedded_io_async::Write for UartFuture<C, D, R, NoneT>
333where
334 C: ValidConfig<Sercom = S, Word = u8>,
335 D: Transmit,
336 S: Sercom,
337{
338 #[inline]
339 async fn write(&mut self, buffer: &[u8]) -> Result<usize, Self::Error> {
340 self.write(buffer).await;
341 Ok(buffer.len())
342 }
343}
344
345impl<C, D, R, T, S> AsRef<Uart<C, D, R, T>> for UartFuture<C, D, R, T>
346where
347 C: ValidConfig<Sercom = S>,
348 D: Capability,
349 S: Sercom,
350{
351 fn as_ref(&self) -> &Uart<C, D, R, T> {
352 &self.uart
353 }
354}
355
356impl<C, D, R, T, S> AsMut<Uart<C, D, R, T>> for UartFuture<C, D, R, T>
357where
358 C: ValidConfig<Sercom = S>,
359 D: Capability,
360 S: Sercom,
361{
362 fn as_mut(&mut self) -> &mut Uart<C, D, R, T> {
363 &mut self.uart
364 }
365}
366
367#[cfg(feature = "dma")]
368mod dma {
369 use super::*;
370 use crate::{
371 dmac::{AnyChannel, Beat, Channel, ReadyFuture},
372 sercom::dma::{
373 async_dma::{read_dma, write_dma},
374 SharedSliceBuffer,
375 },
376 };
377
378 pub type UartFutureDuplexDma<C, R, T> =
384 UartFuture<C, Duplex, Channel<R, ReadyFuture>, Channel<T, ReadyFuture>>;
385
386 pub type UartFutureRxDma<C, R> = UartFuture<C, Rx, Channel<R, ReadyFuture>, NoneT>;
390
391 pub type UartFutureRxDuplexDma<C, R> = UartFuture<C, RxDuplex, Channel<R, ReadyFuture>, NoneT>;
396
397 pub type UartFutureTxDma<C, T> = UartFuture<C, Tx, NoneT, Channel<T, ReadyFuture>>;
401
402 pub type UartFutureTxDuplexDma<C, T> = UartFuture<C, TxDuplex, NoneT, Channel<T, ReadyFuture>>;
407
408 impl<C, D, R, T> UartFuture<C, D, R, T>
409 where
410 C: ValidConfig,
411 D: Capability,
412 R: AnyChannel<Status = ReadyFuture>,
413 {
414 pub fn take_rx_channel(self) -> (UartFuture<C, D, NoneT, T>, R) {
417 let (uart, channel) = self.uart.take_rx_channel();
418 (UartFuture { uart }, channel)
419 }
420 }
421
422 impl<C, D, R, T> UartFuture<C, D, R, T>
423 where
424 C: ValidConfig,
425 D: Capability,
426 T: AnyChannel<Status = ReadyFuture>,
427 {
428 pub fn take_tx_channel(self) -> (UartFuture<C, D, R, NoneT>, T) {
431 let (uart, channel) = self.uart.take_tx_channel();
432 (UartFuture { uart }, channel)
433 }
434 }
435
436 impl<C, D, S, R, T> UartFuture<C, D, R, T>
437 where
438 C: ValidConfig<Sercom = S>,
439 C::Word: Beat,
440 D: Receive,
441 S: Sercom + 'static,
442 DataReg: AsPrimitive<C::Word>,
443 R: AnyChannel<Status = ReadyFuture>,
444 {
445 #[inline]
448 pub async fn read(&mut self, mut words: &mut [C::Word]) -> Result<(), Error> {
449 let uart_ptr = self.uart.sercom_ptr();
452
453 read_dma::<_, _, S>(&mut self.uart.rx_channel, uart_ptr, &mut words).await?;
454 Ok(())
455 }
456 }
457
458 impl<C, D, S, R, T> embedded_io_async::Read for UartFuture<C, D, R, T>
459 where
460 C: ValidConfig<Sercom = S, Word = u8>,
461 D: Receive,
462 S: Sercom + 'static,
463 DataReg: AsPrimitive<C::Word>,
464 R: AnyChannel<Status = ReadyFuture>,
465 {
466 #[inline]
467 async fn read(&mut self, words: &mut [u8]) -> Result<usize, Error> {
468 self.read(words).await?;
469 Ok(words.len())
470 }
471 }
472
473 impl<C, D, S, R, T> UartFuture<C, D, R, T>
474 where
475 C: ValidConfig<Sercom = S>,
476 C::Word: Beat,
477 D: Transmit,
478 S: Sercom + 'static,
479 T: AnyChannel<Status = ReadyFuture>,
480 {
481 #[inline]
483 pub async fn write(&mut self, words: &[C::Word]) -> Result<(), Error> {
484 let uart_ptr = self.uart.sercom_ptr();
487
488 let mut words = SharedSliceBuffer::from_slice(words);
489 write_dma::<_, _, S>(&mut self.uart.tx_channel, uart_ptr, &mut words).await?;
490 self.wait_flags(Flags::TXC).await;
491 Ok(())
492 }
493 }
494
495 impl<C, D, S, R, T> embedded_io_async::Write for UartFuture<C, D, R, T>
496 where
497 C: ValidConfig<Sercom = S, Word = u8>,
498 D: Transmit,
499 S: Sercom + 'static,
500 T: AnyChannel<Status = ReadyFuture>,
501 {
502 #[inline]
503 async fn write(&mut self, words: &[u8]) -> Result<usize, Error> {
504 self.write(words).await?;
505 Ok(words.len())
506 }
507 }
508}
509
510#[cfg(feature = "dma")]
511pub use dma::*;