rp: Fill and empty FIFOs in buffered uart interrupt

Fixes an issue where only the first byte was transmitted.
Should improve throughput aswell.
This commit is contained in:
Timo Kröger 2022-12-27 10:20:51 +01:00
parent 3afb62d8d6
commit e4f457646f

View File

@ -402,27 +402,45 @@ pub(crate) unsafe fn on_interrupt<T: Instance>(_: *mut ()) {
} }
let mut rx_writer = s.rx_buf.writer(); let mut rx_writer = s.rx_buf.writer();
if !r.uartfr().read().rxfe() { let rx_buf = rx_writer.push_slice();
let val = r.uartdr().read().data(); let mut n_read = 0;
if !rx_writer.push_one(val) { for rx_byte in rx_buf {
warn!("RX buffer full, discard received byte"); if r.uartfr().read().rxfe() {
break;
} }
*rx_byte = r.uartdr().read().data();
n_read += 1;
}
if n_read > 0 {
rx_writer.push_done(n_read);
s.rx_waker.wake(); s.rx_waker.wake();
} }
// TX // TX
let mut tx_reader = s.tx_buf.reader(); let mut tx_reader = s.tx_buf.reader();
if let Some(val) = tx_reader.pop_one() { let tx_buf = tx_reader.pop_slice();
r.uartimsc().modify(|w| { if tx_buf.len() == 0 {
w.set_txim(true);
});
r.uartdr().write(|w| w.set_data(val));
s.tx_waker.wake();
} else {
// Disable interrupt until we have something to transmit again // Disable interrupt until we have something to transmit again
r.uartimsc().modify(|w| { r.uartimsc().modify(|w| {
w.set_txim(false); w.set_txim(false);
}); });
} else {
r.uartimsc().modify(|w| {
w.set_txim(true);
});
let mut n_written = 0;
for tx_byte in tx_buf.iter_mut() {
if r.uartfr().read().txff() {
break;
}
r.uartdr().write(|w| w.set_data(*tx_byte));
n_written += 1;
}
if n_written > 0 {
tx_reader.pop_done(n_written);
s.tx_waker.wake();
}
} }
} }
} }