Skip to content

Instantly share code, notes, and snippets.

@shepmaster
Created June 15, 2019 12:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shepmaster/25fe1180a01e315040d11cd7412f5452 to your computer and use it in GitHub Desktop.
Save shepmaster/25fe1180a01e315040d11cd7412f5452 to your computer and use it in GitHub Desktop.
struct SerialTx(u8);
static mut TX_WAKER: Option<Waker> = None;
#[inline(always)]
pub fn tx_empty_interrupt_handler() {
// Safety:
// We are on a single-threaded CPU, so static mutable shoudn't matter.
unsafe {
if let Some(waker) = TX_WAKER.take() {
// Notify our waker to poll the future again
waker.wake();
// We must either read from the buffer or disable the
// interrupt to prevent re-invoking the interrupt
// handler immediately.
disable_serial_tx_empty_interrupt();
}
}
}
fn enable_serial_tx_empty_interrupt() {
set_bit_in(UCSR0B, UDRIE0);
}
fn disable_serial_tx_empty_interrupt() {
unset_bit_in(UCSR0B, UDRIE0);
}
impl Future for SerialTx {
type Output = ();
fn poll(self: Pin<&mut Self>, ctx: &mut Context) -> Poll<Self::Output> {
match serial::try_transmit(self.0) {
Ok(()) => {
Poll::Ready(())
},
Err(()) => {
// Safety:
// We are on a single-threaded CPU, so static mutable shoudn't matter.
unsafe {
TX_WAKER = Some(ctx.waker().clone());
}
enable_serial_tx_empty_interrupt();
Poll::Pending
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment