Skip to content

Commit fc75b7d

Browse files
committed
Improve UART module by systick timeout
1 parent 43567a1 commit fc75b7d

File tree

5 files changed

+193
-126
lines changed

5 files changed

+193
-126
lines changed

examples/f103c8/src/main.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,8 @@ fn uart_poll_init<U: UartPeriphExt>(
154154
tx: uart::Tx<U>,
155155
rx: uart::Rx<U>,
156156
) -> UartPollTask<impl embedded_io::Write, impl embedded_io::Read> {
157-
let (uart_tx, uart_rx) = (
158-
tx.into_poll(RetryTimes::new(0), 10_000),
159-
rx.into_poll(RetryTimes::new(0), 1_000),
160-
);
157+
let uart_rx = rx.into_poll(RetryTimes::new(0), RetryTimes::new(1_000));
158+
let uart_tx = tx.into_poll(RetryTimes::new(0), RetryTimes::new(10_000));
161159
UartPollTask::new(32, uart_tx, uart_rx)
162160
}
163161

@@ -167,8 +165,9 @@ fn uart_interrupt_init<U: UartPeriphExt + 'static>(
167165
interrupt_callback: &hal::interrupt::Callback,
168166
mcu: &mut Mcu,
169167
) -> UartPollTask<impl embedded_io::Write + 'static, impl embedded_io::Read + 'static> {
170-
let (tx, mut tx_it) = tx.into_interrupt(64, 0, 10_000);
171-
let (rx, mut rx_it) = rx.into_interrupt(64, 0);
168+
let (rx, mut rx_it) = rx.into_interrupt(64, SysTickTimeout::new(100));
169+
let (tx, mut tx_it) =
170+
tx.into_interrupt(64, SysTickTimeout::new(0), SysTickTimeout::new(20_000));
172171
interrupt_callback.set(mcu, move || {
173172
rx_it.handler();
174173
tx_it.handler();
@@ -184,9 +183,14 @@ fn uart_dma_init<'r, U: UartPeriphExt + 'static>(
184183
dma_rx: impl DmaBindRx<U> + 'r,
185184
mcu: &mut Mcu,
186185
) -> UartPollTask<impl embedded_io::Write + 'static, impl embedded_io::Read + 'r> {
187-
let uart_rx = rx.into_dma_circle(dma_rx, 64);
186+
let uart_rx = rx.into_dma_circle(dma_rx, 64, SysTickTimeout::new(100));
188187
dma_tx.set_interrupt(DmaEvent::TransferComplete, true);
189-
let (uart_tx, mut tx_it) = tx.into_dma_ringbuf(dma_tx, 32);
188+
let (uart_tx, mut tx_it) = tx.into_dma_ringbuf(
189+
dma_tx,
190+
32,
191+
SysTickTimeout::new(0),
192+
SysTickTimeout::new(20_000),
193+
);
190194
interrupt_callback.set(mcu, move || {
191195
tx_it.interrupt_reload();
192196
});

src/common/uart/uart_dma.rs

Lines changed: 77 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,145 @@
11
use super::*;
2-
use crate::common::dma::*;
2+
use crate::common::{dma::*, os::*};
33
use embedded_io::{ErrorType, Read, Write};
44

55
// TX -------------------------------------------------------------------------
66

7-
pub struct UartDmaBufTx<U, CH> {
7+
pub struct UartDmaBufTx<U, CH, T> {
88
_uart: U,
99
w: DmaRingbufTxWriter<u8, CH>,
10+
timeout: T,
11+
flush_timeout: T,
1012
}
1113

12-
impl<U, CH> UartDmaBufTx<U, CH>
14+
impl<U, CH, T> UartDmaBufTx<U, CH, T>
1315
where
1416
U: UartPeriph,
1517
CH: DmaChannel,
18+
T: Timeout,
1619
{
17-
pub fn new(mut uart: U, dma_ch: CH, buf_size: usize) -> (Self, DmaRingbufTxLoader<u8, CH>) {
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>) {
1827
uart.enable_dma_tx(true);
1928
let (w, l) = DmaRingbufTx::new(dma_ch, uart.get_tx_data_reg_addr(), buf_size);
20-
(Self { _uart: uart, w }, l)
29+
(
30+
Self {
31+
_uart: uart,
32+
w,
33+
timeout,
34+
flush_timeout,
35+
},
36+
l,
37+
)
2138
}
2239
}
2340

24-
impl<U, CH> ErrorType for UartDmaBufTx<U, CH>
41+
impl<U, CH, T> ErrorType for UartDmaBufTx<U, CH, T>
2542
where
2643
U: UartPeriph,
2744
CH: DmaChannel,
45+
T: Timeout,
2846
{
2947
type Error = Error;
3048
}
3149

32-
impl<U, CH> Write for UartDmaBufTx<U, CH>
50+
impl<U, CH, T> Write for UartDmaBufTx<U, CH, T>
3351
where
3452
U: UartPeriph,
3553
CH: DmaChannel,
54+
T: Timeout,
3655
{
3756
#[inline(always)]
3857
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
39-
// TODO block
40-
if let n @ 1.. = self.w.write(buf) {
41-
Ok(n)
42-
} else {
43-
Err(Error::Busy)
58+
if buf.len() == 0 {
59+
return Err(Error::Other);
4460
}
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)
4572
}
4673

4774
fn flush(&mut self) -> Result<(), Self::Error> {
48-
// TODO
49-
Ok(())
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)
5085
}
5186
}
5287

5388
// RX -------------------------------------------------------------------------
5489

55-
pub struct UartDmaRx<U, CH> {
90+
pub struct UartDmaRx<U, CH, T> {
5691
_uart: U,
5792
ch: DmaCircularBufferRx<u8, CH>,
93+
timeout: T,
5894
}
5995

60-
impl<U, CH> UartDmaRx<U, CH>
96+
impl<U, CH, T> UartDmaRx<U, CH, T>
6197
where
6298
U: UartPeriph,
6399
CH: DmaChannel,
100+
T: Timeout,
64101
{
65-
pub fn new(mut uart: U, dma_ch: CH, buf_size: usize) -> Self {
102+
pub fn new(mut uart: U, dma_ch: CH, buf_size: usize, timeout: T) -> Self {
66103
let ch = DmaCircularBufferRx::<u8, CH>::new(dma_ch, uart.get_rx_data_reg_addr(), buf_size);
67104
uart.enable_dma_rx(true);
68-
Self { _uart: uart, ch }
105+
Self {
106+
_uart: uart,
107+
ch,
108+
timeout,
109+
}
69110
}
70111
}
71112

72-
impl<U, CH> ErrorType for UartDmaRx<U, CH>
113+
impl<U, CH, T> ErrorType for UartDmaRx<U, CH, T>
73114
where
74115
U: UartPeriph,
75116
CH: DmaChannel,
117+
T: Timeout,
76118
{
77119
type Error = Error;
78120
}
79121

80-
impl<U, CH> Read for UartDmaRx<U, CH>
122+
impl<U, CH, T> Read for UartDmaRx<U, CH, T>
81123
where
82124
U: UartPeriph,
83125
CH: DmaChannel,
126+
T: Timeout,
84127
{
85128
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
86-
// TODO block
87-
if let Some(d) = self.ch.read(buf.len()) {
88-
buf[..d.len()].copy_from_slice(d);
89-
Ok(d.len())
90-
} else {
91-
Err(Error::Other)
129+
if buf.len() == 0 {
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();
92142
}
143+
Err(Error::Other)
93144
}
94145
}

0 commit comments

Comments
 (0)