Skip to content

Commit b91ba47

Browse files
committed
zephyr: device: uart: Add timeout to 'write' entry
Add a timeout parameter to the 'write' method on the UartIrq interface. The method now returns the number of bytes that were actually written. Signed-off-by: David Brown <[email protected]>
1 parent 8c31b7a commit b91ba47

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

zephyr/src/device/uart.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::error::{Error, Result, to_result_void, to_result};
1111
use crate::printkln;
1212
use crate::sys::sync::Semaphore;
1313
use crate::sync::{Arc, SpinMutex};
14-
use crate::time::{Forever, NoWait, Timeout};
14+
use crate::time::{NoWait, Timeout};
1515

1616
use core::ffi::{c_int, c_uchar, c_void};
1717
use core::ptr;
@@ -278,9 +278,11 @@ impl UartIrq {
278278
/// By making this blocking, we don't need to make an extra copy of the data.
279279
///
280280
/// TODO: Async write.
281-
pub unsafe fn write(&mut self, buf: &[u8]) {
281+
pub unsafe fn write<T>(&mut self, buf: &[u8], timeout: T) -> usize
282+
where T: Into<Timeout>
283+
{
282284
if buf.len() == 0 {
283-
return;
285+
return 0;
284286
}
285287

286288
// Make the data to be written available to the irq handler, and get it going.
@@ -298,9 +300,26 @@ impl UartIrq {
298300

299301
// Wait for the transmission to complete. This shouldn't be racy, as the irq shouldn't be
300302
// giving the semaphore until there is 'write' data, and it has been consumed.
301-
let _ = self.data.write_sem.take(Forever);
303+
let _ = self.data.write_sem.take(timeout);
304+
305+
// Depending on the driver, there might be a race here. This would result in the above
306+
// 'take' returning early, and no actual data being written.
307+
308+
{
309+
let mut inner = self.data.inner.lock().unwrap();
302310

303-
// TODO: Should we check that the write actually finished?
311+
if let Some(write) = inner.write.take() {
312+
// First, make sure that no more interrupts will come in.
313+
unsafe { raw::uart_irq_tx_disable(self.device) };
314+
315+
// The write did not complete, and this represents remaining data to write.
316+
buf.len() - write.len
317+
} else {
318+
// The write completed, the rx irq should be disabled. Just return the whole
319+
// buffer.
320+
buf.len()
321+
}
322+
}
304323
}
305324
}
306325

0 commit comments

Comments
 (0)