-
-
Save shepmaster/25fe1180a01e315040d11cd7412f5452 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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