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, W> {
8    _uart: U,
9    w: DmaRingbufTxWriter<u8, CH>,
10    timeout: W,
11    flush_timeout: W,
12}
13
14impl<U, CH, W> UartDmaBufTx<U, CH, W>
15where
16    U: UartPeriph,
17    CH: DmaChannel,
18    W: Waiter,
19{
20    pub fn new(
21        mut uart: U,
22        dma_ch: CH,
23        buf_size: usize,
24        timeout: W,
25        flush_timeout: W,
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, W> ErrorType for UartDmaBufTx<U, CH, W>
42where
43    U: UartPeriph,
44    CH: DmaChannel,
45    W: Waiter,
46{
47    type Error = Error;
48}
49
50impl<U, CH, W> Write for UartDmaBufTx<U, CH, W>
51where
52    U: UartPeriph,
53    CH: DmaChannel,
54    W: Waiter,
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        }
70        Err(Error::Busy)
71    }
72
73    fn flush(&mut self) -> Result<(), Self::Error> {
74        let mut t = self.flush_timeout.start();
75        loop {
76            if !self.w.in_progress() {
77                return Ok(());
78            } else if t.timeout() {
79                break;
80            }
81        }
82        Err(Error::Other)
83    }
84}
85
86// RX -------------------------------------------------------------------------
87
88pub struct UartDmaRx<U, CH, W> {
89    _uart: U,
90    ch: DmaCircularBufferRx<u8, CH>,
91    timeout: W,
92}
93
94impl<U, CH, W> UartDmaRx<U, CH, W>
95where
96    U: UartPeriph,
97    CH: DmaChannel,
98    W: Waiter,
99{
100    pub fn new(mut uart: U, dma_ch: CH, buf_size: usize, timeout: W) -> Self {
101        let ch = DmaCircularBufferRx::<u8, CH>::new(dma_ch, uart.get_rx_data_reg_addr(), buf_size);
102        uart.enable_dma_rx(true);
103        Self {
104            _uart: uart,
105            ch,
106            timeout,
107        }
108    }
109}
110
111impl<U, CH, W> ErrorType for UartDmaRx<U, CH, W>
112where
113    U: UartPeriph,
114    CH: DmaChannel,
115    W: Waiter,
116{
117    type Error = Error;
118}
119
120impl<U, CH, W> Read for UartDmaRx<U, CH, W>
121where
122    U: UartPeriph,
123    CH: DmaChannel,
124    W: Waiter,
125{
126    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
127        if buf.is_empty() {
128            return Err(Error::Other);
129        }
130
131        let mut t = self.timeout.start();
132        loop {
133            if let Some(d) = self.ch.read(buf.len()) {
134                buf[..d.len()].copy_from_slice(d);
135                return Ok(d.len());
136            } else if t.timeout() {
137                break;
138            }
139        }
140        Err(Error::Other)
141    }
142}