stm32f1_hal/common/uart/
uart_dma.rs

1use super::*;
2use crate::common::{dma::*, os::*};
3use embedded_io::{ErrorType, Read, Write};
4
5// TX -------------------------------------------------------------------------
6
7pub struct UartDmaBufTx<U, CH, T> {
8    _uart: U,
9    w: DmaRingbufTxWriter<u8, CH>,
10    timeout: T,
11    flush_timeout: T,
12}
13
14impl<U, CH, T> UartDmaBufTx<U, CH, T>
15where
16    U: UartPeriph,
17    CH: DmaChannel,
18    T: Timeout,
19{
20    pub fn new(
21        mut uart: U,
22        dma_ch: CH,
23        buf_size: usize,
24        timeout: T,
25        flush_timeout: T,
26    ) -> (Self, DmaRingbufTxLoader<u8, CH>) {
27        uart.enable_dma_tx(true);
28        let (w, l) = DmaRingbufTx::new(dma_ch, uart.get_tx_data_reg_addr(), buf_size);
29        (
30            Self {
31                _uart: uart,
32                w,
33                timeout,
34                flush_timeout,
35            },
36            l,
37        )
38    }
39}
40
41impl<U, CH, T> ErrorType for UartDmaBufTx<U, CH, T>
42where
43    U: UartPeriph,
44    CH: DmaChannel,
45    T: Timeout,
46{
47    type Error = Error;
48}
49
50impl<U, CH, T> Write for UartDmaBufTx<U, CH, T>
51where
52    U: UartPeriph,
53    CH: DmaChannel,
54    T: Timeout,
55{
56    #[inline(always)]
57    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
58        if buf.is_empty() {
59            return Err(Error::Other);
60        }
61
62        let mut t = self.timeout.start();
63        loop {
64            if let n @ 1.. = self.w.write(buf) {
65                return Ok(n);
66            } else if t.timeout() {
67                break;
68            }
69            t.interval();
70        }
71        Err(Error::Busy)
72    }
73
74    fn flush(&mut self) -> Result<(), Self::Error> {
75        let mut t = self.flush_timeout.start();
76        loop {
77            if !self.w.in_progress() {
78                return Ok(());
79            } else if t.timeout() {
80                break;
81            }
82            t.interval();
83        }
84        Err(Error::Other)
85    }
86}
87
88// RX -------------------------------------------------------------------------
89
90pub struct UartDmaRx<U, CH, T> {
91    _uart: U,
92    ch: DmaCircularBufferRx<u8, CH>,
93    timeout: T,
94}
95
96impl<U, CH, T> UartDmaRx<U, CH, T>
97where
98    U: UartPeriph,
99    CH: DmaChannel,
100    T: Timeout,
101{
102    pub fn new(mut uart: U, dma_ch: CH, buf_size: usize, timeout: T) -> Self {
103        let ch = DmaCircularBufferRx::<u8, CH>::new(dma_ch, uart.get_rx_data_reg_addr(), buf_size);
104        uart.enable_dma_rx(true);
105        Self {
106            _uart: uart,
107            ch,
108            timeout,
109        }
110    }
111}
112
113impl<U, CH, T> ErrorType for UartDmaRx<U, CH, T>
114where
115    U: UartPeriph,
116    CH: DmaChannel,
117    T: Timeout,
118{
119    type Error = Error;
120}
121
122impl<U, CH, T> Read for UartDmaRx<U, CH, T>
123where
124    U: UartPeriph,
125    CH: DmaChannel,
126    T: Timeout,
127{
128    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
129        if buf.is_empty() {
130            return Err(Error::Other);
131        }
132
133        let mut t = self.timeout.start();
134        loop {
135            if let Some(d) = self.ch.read(buf.len()) {
136                buf[..d.len()].copy_from_slice(d);
137                return Ok(d.len());
138            } else if t.timeout() {
139                break;
140            }
141            t.interval();
142        }
143        Err(Error::Other)
144    }
145}