aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/usart/buffered.rs152
-rw-r--r--examples/stm32f4/src/bin/usart_buffered.rs14
-rw-r--r--examples/stm32l0/src/bin/usart_irq.rs16
3 files changed, 61 insertions, 121 deletions
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs
index 6721c44a1..3e23e7ca1 100644
--- a/embassy-stm32/src/usart/buffered.rs
+++ b/embassy-stm32/src/usart/buffered.rs
@@ -43,9 +43,9 @@ pub struct BufferedUartRx<'d, T: BasicInstance> {
43impl<'d, T: BasicInstance> BufferedUart<'d, T> { 43impl<'d, T: BasicInstance> BufferedUart<'d, T> {
44 pub fn new( 44 pub fn new(
45 peri: impl Peripheral<P = T> + 'd, 45 peri: impl Peripheral<P = T> + 'd,
46 irq: impl Peripheral<P = T::Interrupt> + 'd,
46 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 47 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
47 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 48 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
48 irq: impl Peripheral<P = T::Interrupt> + 'd,
49 tx_buffer: &'d mut [u8], 49 tx_buffer: &'d mut [u8],
50 rx_buffer: &'d mut [u8], 50 rx_buffer: &'d mut [u8],
51 config: Config, 51 config: Config,
@@ -53,14 +53,14 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
53 T::enable(); 53 T::enable();
54 T::reset(); 54 T::reset();
55 55
56 Self::new_inner(peri, rx, tx, irq, tx_buffer, rx_buffer, config) 56 Self::new_inner(peri, irq, rx, tx, tx_buffer, rx_buffer, config)
57 } 57 }
58 58
59 pub fn new_with_rtscts( 59 pub fn new_with_rtscts(
60 peri: impl Peripheral<P = T> + 'd, 60 peri: impl Peripheral<P = T> + 'd,
61 irq: impl Peripheral<P = T::Interrupt> + 'd,
61 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 62 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
62 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 63 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
63 irq: impl Peripheral<P = T::Interrupt> + 'd,
64 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 64 rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
65 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 65 cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
66 tx_buffer: &'d mut [u8], 66 tx_buffer: &'d mut [u8],
@@ -81,15 +81,15 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
81 }); 81 });
82 } 82 }
83 83
84 Self::new_inner(peri, rx, tx, irq, tx_buffer, rx_buffer, config) 84 Self::new_inner(peri, irq, rx, tx, tx_buffer, rx_buffer, config)
85 } 85 }
86 86
87 #[cfg(not(usart_v1))] 87 #[cfg(not(usart_v1))]
88 pub fn new_with_de( 88 pub fn new_with_de(
89 peri: impl Peripheral<P = T> + 'd, 89 peri: impl Peripheral<P = T> + 'd,
90 irq: impl Peripheral<P = T::Interrupt> + 'd,
90 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 91 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
91 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 92 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
92 irq: impl Peripheral<P = T::Interrupt> + 'd,
93 de: impl Peripheral<P = impl DePin<T>> + 'd, 93 de: impl Peripheral<P = impl DePin<T>> + 'd,
94 tx_buffer: &'d mut [u8], 94 tx_buffer: &'d mut [u8],
95 rx_buffer: &'d mut [u8], 95 rx_buffer: &'d mut [u8],
@@ -107,14 +107,14 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
107 }); 107 });
108 } 108 }
109 109
110 Self::new_inner(peri, rx, tx, irq, tx_buffer, rx_buffer, config) 110 Self::new_inner(peri, irq, rx, tx, tx_buffer, rx_buffer, config)
111 } 111 }
112 112
113 fn new_inner( 113 fn new_inner(
114 _peri: impl Peripheral<P = T> + 'd, 114 _peri: impl Peripheral<P = T> + 'd,
115 irq: impl Peripheral<P = T::Interrupt> + 'd,
115 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 116 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
116 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 117 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
117 irq: impl Peripheral<P = T::Interrupt> + 'd,
118 tx_buffer: &'d mut [u8], 118 tx_buffer: &'d mut [u8],
119 rx_buffer: &'d mut [u8], 119 rx_buffer: &'d mut [u8],
120 config: Config, 120 config: Config,
@@ -155,8 +155,8 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
155 } 155 }
156 } 156 }
157 157
158 pub fn split(self) -> (BufferedUartRx<'d, T>, BufferedUartTx<'d, T>) { 158 pub fn split(self) -> (BufferedUartTx<'d, T>, BufferedUartRx<'d, T>) {
159 (self.rx, self.tx) 159 (self.tx, self.rx)
160 } 160 }
161} 161}
162 162
@@ -165,85 +165,46 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> {
165 poll_fn(move |cx| { 165 poll_fn(move |cx| {
166 let state = T::buffered_state(); 166 let state = T::buffered_state();
167 let mut rx_reader = unsafe { state.rx_buf.reader() }; 167 let mut rx_reader = unsafe { state.rx_buf.reader() };
168 let n = rx_reader.pop(|data| { 168 let data = rx_reader.pop_slice();
169 let n = data.len().min(buf.len());
170 buf[..n].copy_from_slice(&data[..n]);
171 n
172 });
173 if n == 0 {
174 state.rx_waker.register(cx.waker());
175 return Poll::Pending;
176 }
177
178 // FIXME:
179 // (Re-)Enable the interrupt to receive more data in case it was
180 // disabled because the buffer was full.
181 // let regs = T::regs();
182 // unsafe {
183 // regs.uartimsc().write_set(|w| {
184 // w.set_rxim(true);
185 // w.set_rtim(true);
186 // });
187 // }
188 169
189 Poll::Ready(Ok(n)) 170 if !data.is_empty() {
190 }) 171 let len = data.len().min(buf.len());
191 .await 172 buf[..len].copy_from_slice(&data[..len]);
192 173
193 // poll_fn(move |cx| { 174 let do_pend = state.rx_buf.is_full();
194 // let state = T::buffered_state(); 175 rx_reader.pop_done(len);
195 176
196 // let mut do_pend = false; 177 if do_pend {
197 // compiler_fence(Ordering::SeqCst); 178 unsafe { T::Interrupt::steal().pend() };
198 179 }
199 // // We have data ready in buffer? Return it.
200 // let data = state.rx_buf.pop_buf();
201 // if !data.is_empty() {
202 // let len = data.len().min(buf.len());
203 // buf[..len].copy_from_slice(&data[..len]);
204
205 // if state.rx_buf.is_full() {
206 // do_pend = true;
207 // }
208 // state.rx_buf.pop(len);
209
210 // return Poll::Ready(Ok(len));
211 // }
212
213 // state.rx_waker.register(cx.waker());
214 180
215 // if do_pend { 181 return Poll::Ready(Ok(len));
216 // inner.pend(); 182 }
217 // }
218 183
219 // Poll::Pending 184 state.rx_waker.register(cx.waker());
220 // }) 185 Poll::Pending
221 // .await 186 })
187 .await
222 } 188 }
223 189
224 fn blocking_read(&self, buf: &mut [u8]) -> Result<usize, Error> { 190 fn blocking_read(&self, buf: &mut [u8]) -> Result<usize, Error> {
225 loop { 191 loop {
226 let state = T::buffered_state(); 192 let state = T::buffered_state();
227 let mut rx_reader = unsafe { state.rx_buf.reader() }; 193 let mut rx_reader = unsafe { state.rx_buf.reader() };
228 let n = rx_reader.pop(|data| { 194 let data = rx_reader.pop_slice();
229 let n = data.len().min(buf.len());
230 buf[..n].copy_from_slice(&data[..n]);
231 n
232 });
233 195
234 if n > 0 { 196 if !data.is_empty() {
235 // FIXME: 197 let len = data.len().min(buf.len());
236 // (Re-)Enable the interrupt to receive more data in case it was 198 buf[..len].copy_from_slice(&data[..len]);
237 // disabled because the buffer was full.
238 // let regs = T::regs();
239 // unsafe {
240 // regs.uartimsc().write_set(|w| {
241 // w.set_rxim(true);
242 // w.set_rtim(true);
243 // });
244 // }
245 199
246 return Ok(n); 200 let do_pend = state.rx_buf.is_full();
201 rx_reader.pop_done(len);
202
203 if do_pend {
204 unsafe { T::Interrupt::steal().pend() };
205 }
206
207 return Ok(len);
247 } 208 }
248 } 209 }
249 } 210 }
@@ -279,22 +240,23 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> {
279 async fn write(&self, buf: &[u8]) -> Result<usize, Error> { 240 async fn write(&self, buf: &[u8]) -> Result<usize, Error> {
280 poll_fn(move |cx| { 241 poll_fn(move |cx| {
281 let state = T::buffered_state(); 242 let state = T::buffered_state();
243 let empty = state.tx_buf.is_empty();
244
282 let mut tx_writer = unsafe { state.tx_buf.writer() }; 245 let mut tx_writer = unsafe { state.tx_buf.writer() };
283 let n = tx_writer.push(|data| { 246 let data = tx_writer.push_slice();
284 let n = data.len().min(buf.len()); 247 if data.is_empty() {
285 data[..n].copy_from_slice(&buf[..n]);
286 n
287 });
288 if n == 0 {
289 state.tx_waker.register(cx.waker()); 248 state.tx_waker.register(cx.waker());
290 return Poll::Pending; 249 return Poll::Pending;
291 } 250 }
292 251
293 // The TX interrupt only triggers when the there was data in the 252 let n = data.len().min(buf.len());
294 // FIFO and the number of bytes drops below a threshold. When the 253 data[..n].copy_from_slice(&buf[..n]);
295 // FIFO was empty we have to manually pend the interrupt to shovel 254 tx_writer.push_done(n);
296 // TX data from the buffer into the FIFO. 255
297 unsafe { T::Interrupt::steal() }.pend(); 256 if empty {
257 unsafe { T::Interrupt::steal() }.pend();
258 }
259
298 Poll::Ready(Ok(n)) 260 Poll::Ready(Ok(n))
299 }) 261 })
300 .await 262 .await
@@ -316,19 +278,19 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> {
316 fn blocking_write(&self, buf: &[u8]) -> Result<usize, Error> { 278 fn blocking_write(&self, buf: &[u8]) -> Result<usize, Error> {
317 loop { 279 loop {
318 let state = T::buffered_state(); 280 let state = T::buffered_state();
281 let empty = state.tx_buf.is_empty();
282
319 let mut tx_writer = unsafe { state.tx_buf.writer() }; 283 let mut tx_writer = unsafe { state.tx_buf.writer() };
320 let n = tx_writer.push(|data| { 284 let data = tx_writer.push_slice();
285 if !data.is_empty() {
321 let n = data.len().min(buf.len()); 286 let n = data.len().min(buf.len());
322 data[..n].copy_from_slice(&buf[..n]); 287 data[..n].copy_from_slice(&buf[..n]);
323 n 288 tx_writer.push_done(n);
324 }); 289
290 if empty {
291 unsafe { T::Interrupt::steal() }.pend();
292 }
325 293
326 if n != 0 {
327 // The TX interrupt only triggers when the there was data in the
328 // FIFO and the number of bytes drops below a threshold. When the
329 // FIFO was empty we have to manually pend the interrupt to shovel
330 // TX data from the buffer into the FIFO.
331 unsafe { T::Interrupt::steal() }.pend();
332 return Ok(n); 294 return Ok(n);
333 } 295 }
334 } 296 }
diff --git a/examples/stm32f4/src/bin/usart_buffered.rs b/examples/stm32f4/src/bin/usart_buffered.rs
index dd171fe13..a93f8baeb 100644
--- a/examples/stm32f4/src/bin/usart_buffered.rs
+++ b/examples/stm32f4/src/bin/usart_buffered.rs
@@ -5,7 +5,7 @@
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::interrupt; 7use embassy_stm32::interrupt;
8use embassy_stm32::usart::{BufferedUart, Config, State}; 8use embassy_stm32::usart::{BufferedUart, Config};
9use embedded_io::asynch::BufRead; 9use embedded_io::asynch::BufRead;
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
@@ -16,20 +16,10 @@ async fn main(_spawner: Spawner) {
16 16
17 let config = Config::default(); 17 let config = Config::default();
18 18
19 let mut state = State::new();
20 let irq = interrupt::take!(USART3); 19 let irq = interrupt::take!(USART3);
21 let mut tx_buf = [0u8; 32]; 20 let mut tx_buf = [0u8; 32];
22 let mut rx_buf = [0u8; 32]; 21 let mut rx_buf = [0u8; 32];
23 let mut buf_usart = BufferedUart::new( 22 let mut buf_usart = BufferedUart::new(p.USART3, irq, p.PD9, p.PD8, &mut tx_buf, &mut rx_buf, config);
24 &mut state,
25 p.USART3,
26 p.PD9,
27 p.PD8,
28 irq,
29 &mut tx_buf,
30 &mut rx_buf,
31 config,
32 );
33 23
34 loop { 24 loop {
35 let buf = buf_usart.fill_buf().await.unwrap(); 25 let buf = buf_usart.fill_buf().await.unwrap();
diff --git a/examples/stm32l0/src/bin/usart_irq.rs b/examples/stm32l0/src/bin/usart_irq.rs
index 8e84cd092..465347004 100644
--- a/examples/stm32l0/src/bin/usart_irq.rs
+++ b/examples/stm32l0/src/bin/usart_irq.rs
@@ -5,7 +5,7 @@
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::interrupt; 7use embassy_stm32::interrupt;
8use embassy_stm32::usart::{BufferedUart, Config, State}; 8use embassy_stm32::usart::{BufferedUart, Config};
9use embedded_io::asynch::{Read, Write}; 9use embedded_io::asynch::{Read, Write};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
@@ -20,20 +20,8 @@ async fn main(_spawner: Spawner) {
20 let mut config = Config::default(); 20 let mut config = Config::default();
21 config.baudrate = 9600; 21 config.baudrate = 9600;
22 22
23 let mut state = State::new();
24 let irq = interrupt::take!(USART2); 23 let irq = interrupt::take!(USART2);
25 let mut usart = unsafe { 24 let mut usart = unsafe { BufferedUart::new(p.USART2, irq, p.PA3, p.PA2, &mut TX_BUFFER, &mut RX_BUFFER, config) };
26 BufferedUart::new(
27 &mut state,
28 p.USART2,
29 p.PA3,
30 p.PA2,
31 irq,
32 &mut TX_BUFFER,
33 &mut RX_BUFFER,
34 config,
35 )
36 };
37 25
38 usart.write_all(b"Hello Embassy World!\r\n").await.unwrap(); 26 usart.write_all(b"Hello Embassy World!\r\n").await.unwrap();
39 info!("wrote Hello, starting echo"); 27 info!("wrote Hello, starting echo");