Skip to content

Commit c957298

Browse files
committed
Add timeout trait
1 parent 1e77c05 commit c957298

File tree

5 files changed

+84
-30
lines changed

5 files changed

+84
-30
lines changed

examples/f103c8/src/main.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use stm32f1_hal::{
1515
embedded_io,
1616
gpio::{Edge, ExtiPin, PinState},
1717
nvic_scb::PriorityGrouping,
18+
os::RetryTimes,
1819
pac::{self, Interrupt},
1920
prelude::*,
2021
rcc,
@@ -156,7 +157,10 @@ fn uart_poll_init<U: UartPeriphExt>(
156157
tx: uart::Tx<U>,
157158
rx: uart::Rx<U>,
158159
) -> UartPollTask<impl embedded_io::Write, impl embedded_io::Read> {
159-
let (uart_tx, uart_rx) = (tx.into_poll(0, 10_000), rx.into_poll(0, 1_000));
160+
let (uart_tx, uart_rx) = (
161+
tx.into_poll(RetryTimes::new(0), 10_000),
162+
rx.into_poll(RetryTimes::new(0), 1_000),
163+
);
160164
UartPollTask::new(32, uart_tx, uart_rx)
161165
}
162166

src/common/os.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,49 @@ cfg_if::cfg_if! {
1212
pub fn yield_cpu() {
1313
// TODO yield
1414
}
15+
16+
pub trait Timeout {
17+
fn start(&mut self) -> impl TimeoutInstance;
18+
}
19+
20+
pub trait TimeoutInstance {
21+
fn timeout(&mut self) -> bool;
22+
fn interval(&self);
23+
}
24+
25+
pub struct RetryTimes {
26+
retry_times: usize,
27+
}
28+
impl RetryTimes {
29+
pub fn new(retry_times: usize) -> Self {
30+
Self { retry_times }
31+
}
32+
}
33+
impl Timeout for RetryTimes {
34+
#[inline]
35+
fn start(&mut self) -> impl TimeoutInstance {
36+
RetryTimesInstance {
37+
count: 0,
38+
retry_times: self.retry_times,
39+
}
40+
}
41+
}
42+
43+
pub struct RetryTimesInstance {
44+
count: usize,
45+
retry_times: usize,
46+
}
47+
impl TimeoutInstance for RetryTimesInstance {
48+
#[inline]
49+
fn timeout(&mut self) -> bool {
50+
if self.count <= self.retry_times {
51+
self.count = self.count.wrapping_add(1);
52+
false
53+
} else {
54+
true
55+
}
56+
}
57+
58+
#[inline(always)]
59+
fn interval(&self) {}
60+
}

src/common/uart/uart_poll.rs

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
11
//! It doesn't depend on DMA or interrupts, relying instead on continuous polling.
22
33
use super::*;
4-
use crate::common::os;
4+
use crate::common::os::*;
55
use embedded_hal_nb as e_nb;
66
use embedded_io as e_io;
77

88
// TX -------------------------------------------------------------------------
99

10-
pub struct UartPollTx<U> {
10+
pub struct UartPollTx<U, T> {
1111
uart: U,
12-
retry_times: u32,
12+
timeout: T,
1313
flush_retry_times: u32,
1414
}
1515

16-
impl<U: UartPeriph> UartPollTx<U> {
17-
pub fn new(uart: U, retry_times: u32, flush_retry_times: u32) -> Self {
16+
impl<U: UartPeriph, T: Timeout> UartPollTx<U, T> {
17+
pub fn new(uart: U, timeout: T, flush_retry_times: u32) -> Self {
1818
Self {
1919
uart,
20-
retry_times,
20+
timeout,
2121
flush_retry_times,
2222
}
2323
}
2424
}
2525

26-
impl<U: UartPeriph> e_nb::serial::ErrorType for UartPollTx<U> {
26+
impl<U: UartPeriph, T: Timeout> e_nb::serial::ErrorType for UartPollTx<U, T> {
2727
type Error = Error;
2828
}
29-
impl<U: UartPeriph> e_io::ErrorType for UartPollTx<U> {
29+
impl<U: UartPeriph, T: Timeout> e_io::ErrorType for UartPollTx<U, T> {
3030
type Error = Error;
3131
}
3232

3333
// NB Write ----
3434

35-
impl<U: UartPeriph> e_nb::serial::Write<u16> for UartPollTx<U> {
35+
impl<U: UartPeriph, T: Timeout> e_nb::serial::Write<u16> for UartPollTx<U, T> {
3636
#[inline]
3737
fn write(&mut self, word: u16) -> nb::Result<(), Self::Error> {
3838
self.uart.write(word)
@@ -49,18 +49,19 @@ impl<U: UartPeriph> e_nb::serial::Write<u16> for UartPollTx<U> {
4949

5050
// IO Write ----
5151

52-
impl<U: UartPeriph> e_io::Write for UartPollTx<U> {
52+
impl<U: UartPeriph, T: Timeout> e_io::Write for UartPollTx<U, T> {
5353
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
5454
if buf.len() == 0 {
5555
return Err(Error::Other);
5656
}
5757

5858
// try first data
5959
let mut rst = Err(nb::Error::WouldBlock);
60-
for _ in 0..=self.retry_times {
60+
let mut t = self.timeout.start();
61+
while !t.timeout() {
6162
rst = self.uart.write(buf[0] as u16);
6263
if let Err(nb::Error::WouldBlock) = rst {
63-
os::yield_cpu();
64+
t.interval();
6465
} else {
6566
break;
6667
}
@@ -86,40 +87,40 @@ impl<U: UartPeriph> e_io::Write for UartPollTx<U> {
8687
if self.uart.is_tx_empty() && self.uart.is_tx_complete() {
8788
return Ok(());
8889
}
89-
os::yield_cpu();
90+
yield_cpu();
9091
}
9192
Err(Error::Other)
9293
}
9394
}
9495

9596
// RX -------------------------------------------------------------------------
9697

97-
pub struct UartPollRx<U> {
98+
pub struct UartPollRx<U, T> {
9899
uart: U,
99-
retry_times: u32,
100+
timeout: T,
100101
continue_retry_times: u32,
101102
}
102103

103-
impl<U: UartPeriph> UartPollRx<U> {
104-
pub fn new(uart: U, retry_times: u32, continue_retry_times: u32) -> Self {
104+
impl<U: UartPeriph, T: Timeout> UartPollRx<U, T> {
105+
pub fn new(uart: U, timeout: T, continue_retry_times: u32) -> Self {
105106
Self {
106107
uart,
107-
retry_times,
108+
timeout,
108109
continue_retry_times,
109110
}
110111
}
111112
}
112113

113-
impl<U: UartPeriph> e_nb::serial::ErrorType for UartPollRx<U> {
114+
impl<U: UartPeriph, T: Timeout> e_nb::serial::ErrorType for UartPollRx<U, T> {
114115
type Error = Error;
115116
}
116-
impl<U: UartPeriph> e_io::ErrorType for UartPollRx<U> {
117+
impl<U: UartPeriph, T: Timeout> e_io::ErrorType for UartPollRx<U, T> {
117118
type Error = Error;
118119
}
119120

120121
// NB Read ----
121122

122-
impl<U: UartPeriph> e_nb::serial::Read<u16> for UartPollRx<U> {
123+
impl<U: UartPeriph, T: Timeout> e_nb::serial::Read<u16> for UartPollRx<U, T> {
123124
#[inline]
124125
fn read(&mut self) -> nb::Result<u16, Self::Error> {
125126
self.uart.read()
@@ -128,18 +129,19 @@ impl<U: UartPeriph> e_nb::serial::Read<u16> for UartPollRx<U> {
128129

129130
// IO Read ----
130131

131-
impl<U: UartPeriph> e_io::Read for UartPollRx<U> {
132+
impl<U: UartPeriph, T: Timeout> e_io::Read for UartPollRx<U, T> {
132133
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
133134
if buf.len() == 0 {
134135
return Err(Error::Other);
135136
}
136137

137138
// try first data
138139
let mut rst = Err(nb::Error::WouldBlock);
139-
for _ in 0..=self.retry_times {
140+
let mut t = self.timeout.start();
141+
while !t.timeout() {
140142
rst = self.uart.read();
141143
if let Err(nb::Error::WouldBlock) = rst {
142-
os::yield_cpu();
144+
t.interval();
143145
} else {
144146
break;
145147
}
@@ -165,7 +167,7 @@ impl<U: UartPeriph> e_io::Read for UartPollRx<U> {
165167
return Ok(n);
166168
}
167169
retry += 1;
168-
os::yield_cpu();
170+
yield_cpu();
169171
}
170172
}
171173
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ cfg_if::cfg_if! {
2626

2727
pub mod common;
2828

29+
pub use common::os;
2930
pub use common::ringbuf;
3031
pub use common::simplest_heap::Heap;
3132

src/uart/mod.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub use crate::common::uart::*;
1010
use crate::{
1111
Steal,
1212
afio::{RemapMode, uart_remap::*},
13+
common::os::*,
1314
dma::{DmaBindRx, DmaBindTx, DmaRingbufTxLoader},
1415
rcc::{BusClock, Enable, Reset},
1516
};
@@ -66,8 +67,8 @@ impl<U: UartPeriphExt> Tx<U> {
6667
Self { uart }
6768
}
6869

69-
pub fn into_poll(self, retry_times: u32, flush_retry_times: u32) -> UartPollTx<U> {
70-
UartPollTx::<U>::new(self.uart, retry_times, flush_retry_times)
70+
pub fn into_poll<T: Timeout>(self, timeout: T, flush_retry_times: u32) -> UartPollTx<U, T> {
71+
UartPollTx::<U, T>::new(self.uart, timeout, flush_retry_times)
7172
}
7273

7374
pub fn into_interrupt(
@@ -116,8 +117,8 @@ impl<U: UartPeriphExt> Rx<U> {
116117
Self { uart }
117118
}
118119

119-
pub fn into_poll(self, retry_times: u32, continue_retry_times: u32) -> UartPollRx<U> {
120-
UartPollRx::<U>::new(self.uart, retry_times, continue_retry_times)
120+
pub fn into_poll<T: Timeout>(self, timeout: T, continue_retry_times: u32) -> UartPollRx<U, T> {
121+
UartPollRx::<U, T>::new(self.uart, timeout, continue_retry_times)
121122
}
122123

123124
pub fn into_interrupt(

0 commit comments

Comments
 (0)