aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-rp/src/uart/buffered.rs87
1 files changed, 35 insertions, 52 deletions
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs
index 9164794b1..6465a20c6 100644
--- a/embassy-rp/src/uart/buffered.rs
+++ b/embassy-rp/src/uart/buffered.rs
@@ -49,15 +49,6 @@ fn init<'d, T: Instance + 'd>(
49 rx_buffer: &'d mut [u8], 49 rx_buffer: &'d mut [u8],
50 config: Config, 50 config: Config,
51) { 51) {
52 let regs = T::regs();
53 unsafe {
54 regs.uartimsc().modify(|w| {
55 w.set_rxim(true);
56 w.set_rtim(true);
57 w.set_txim(true);
58 });
59 }
60
61 super::Uart::<'d, T, Async>::init(tx, rx, rts, cts, config); 52 super::Uart::<'d, T, Async>::init(tx, rx, rts, cts, config);
62 53
63 let state = T::state(); 54 let state = T::state();
@@ -168,6 +159,8 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
168 159
169 fn read<'a>(buf: &'a mut [u8]) -> impl Future<Output = Result<usize, Error>> + 'a { 160 fn read<'a>(buf: &'a mut [u8]) -> impl Future<Output = Result<usize, Error>> + 'a {
170 poll_fn(move |cx| { 161 poll_fn(move |cx| {
162 unsafe { T::Interrupt::steal() }.pend();
163
171 let state = T::state(); 164 let state = T::state();
172 let mut rx_reader = unsafe { state.rx_buf.reader() }; 165 let mut rx_reader = unsafe { state.rx_buf.reader() };
173 let n = rx_reader.pop(|data| { 166 let n = rx_reader.pop(|data| {
@@ -186,6 +179,8 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
186 179
187 fn fill_buf<'a>() -> impl Future<Output = Result<&'a [u8], Error>> { 180 fn fill_buf<'a>() -> impl Future<Output = Result<&'a [u8], Error>> {
188 poll_fn(move |cx| { 181 poll_fn(move |cx| {
182 unsafe { T::Interrupt::steal() }.pend();
183
189 let state = T::state(); 184 let state = T::state();
190 let mut rx_reader = unsafe { state.rx_buf.reader() }; 185 let mut rx_reader = unsafe { state.rx_buf.reader() };
191 let (p, n) = rx_reader.pop_buf(); 186 let (p, n) = rx_reader.pop_buf();
@@ -310,40 +305,31 @@ pub(crate) unsafe fn on_interrupt<T: Instance>(_: *mut ()) {
310 let s = T::state(); 305 let s = T::state();
311 306
312 unsafe { 307 unsafe {
313 // RX
314
315 let ris = r.uartris().read(); 308 let ris = r.uartris().read();
316 // Clear interrupt flags 309 let mut mis = r.uartimsc().read();
317 r.uarticr().write(|w| {
318 w.set_rxic(true);
319 w.set_rtic(true);
320 });
321 310
322 if ris.peris() { 311 // Errors
323 warn!("Parity error");
324 r.uarticr().write(|w| {
325 w.set_peic(true);
326 });
327 }
328 if ris.feris() { 312 if ris.feris() {
329 warn!("Framing error"); 313 warn!("Framing error");
330 r.uarticr().write(|w| { 314 }
331 w.set_feic(true); 315 if ris.peris() {
332 }); 316 warn!("Parity error");
333 } 317 }
334 if ris.beris() { 318 if ris.beris() {
335 warn!("Break error"); 319 warn!("Break error");
336 r.uarticr().write(|w| {
337 w.set_beic(true);
338 });
339 } 320 }
340 if ris.oeris() { 321 if ris.oeris() {
341 warn!("Overrun error"); 322 warn!("Overrun error");
342 r.uarticr().write(|w| {
343 w.set_oeic(true);
344 });
345 } 323 }
324 // Clear any error flags
325 r.uarticr().write(|w| {
326 w.set_feic(true);
327 w.set_peic(true);
328 w.set_beic(true);
329 w.set_oeic(true);
330 });
346 331
332 // RX
347 let mut rx_writer = s.rx_buf.writer(); 333 let mut rx_writer = s.rx_buf.writer();
348 let rx_buf = rx_writer.push_slice(); 334 let rx_buf = rx_writer.push_slice();
349 let mut n_read = 0; 335 let mut n_read = 0;
@@ -358,33 +344,30 @@ pub(crate) unsafe fn on_interrupt<T: Instance>(_: *mut ()) {
358 rx_writer.push_done(n_read); 344 rx_writer.push_done(n_read);
359 s.rx_waker.wake(); 345 s.rx_waker.wake();
360 } 346 }
347 // Disable any further RX interrupts when the buffer becomes full.
348 mis.set_rxim(!s.rx_buf.is_full());
349 mis.set_rtim(!s.rx_buf.is_full());
361 350
362 // TX 351 // TX
363 let mut tx_reader = s.tx_buf.reader(); 352 let mut tx_reader = s.tx_buf.reader();
364 let tx_buf = tx_reader.pop_slice(); 353 let tx_buf = tx_reader.pop_slice();
365 if tx_buf.len() == 0 { 354 let mut n_written = 0;
366 // Disable interrupt until we have something to transmit again 355 for tx_byte in tx_buf.iter_mut() {
367 r.uartimsc().modify(|w| { 356 if r.uartfr().read().txff() {
368 w.set_txim(false); 357 break;
369 });
370 } else {
371 r.uartimsc().modify(|w| {
372 w.set_txim(true);
373 });
374
375 let mut n_written = 0;
376 for tx_byte in tx_buf.iter_mut() {
377 if r.uartfr().read().txff() {
378 break;
379 }
380 r.uartdr().write(|w| w.set_data(*tx_byte));
381 n_written += 1;
382 }
383 if n_written > 0 {
384 tx_reader.pop_done(n_written);
385 s.tx_waker.wake();
386 } 358 }
359 r.uartdr().write(|w| w.set_data(*tx_byte));
360 n_written += 1;
387 } 361 }
362 if n_written > 0 {
363 tx_reader.pop_done(n_written);
364 s.tx_waker.wake();
365 }
366 // Disable the TX interrupt when we do not have more data to send.
367 mis.set_txim(!s.tx_buf.is_empty());
368
369 // Update interrupt mask.
370 r.uartimsc().write_value(mis);
388 } 371 }
389} 372}
390 373