diff options
| -rw-r--r-- | embassy/src/lib.rs | 2 | ||||
| -rw-r--r-- | embassy/src/util/signal.rs | 68 |
2 files changed, 70 insertions, 0 deletions
diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs index 4fa37a55c..74c69b541 100644 --- a/embassy/src/lib.rs +++ b/embassy/src/lib.rs | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | #![feature(generic_associated_types)] | 2 | #![feature(generic_associated_types)] |
| 3 | #![feature(const_fn)] | 3 | #![feature(const_fn)] |
| 4 | #![feature(const_fn_fn_ptr_basics)] | 4 | #![feature(const_fn_fn_ptr_basics)] |
| 5 | #![feature(const_in_array_repeat_expressions)] | ||
| 6 | #![feature(const_option)] | ||
| 5 | 7 | ||
| 6 | // This mod MUST go first, so that the others see its macros. | 8 | // This mod MUST go first, so that the others see its macros. |
| 7 | pub(crate) mod fmt; | 9 | pub(crate) mod fmt; |
diff --git a/embassy/src/util/signal.rs b/embassy/src/util/signal.rs index 8e778d1e3..2c9c52f1e 100644 --- a/embassy/src/util/signal.rs +++ b/embassy/src/util/signal.rs | |||
| @@ -1,8 +1,13 @@ | |||
| 1 | use crate::executor; | ||
| 1 | use crate::fmt::panic; | 2 | use crate::fmt::panic; |
| 3 | use crate::interrupt::OwnedInterrupt; | ||
| 2 | use core::cell::UnsafeCell; | 4 | use core::cell::UnsafeCell; |
| 3 | use core::future::Future; | 5 | use core::future::Future; |
| 4 | use core::mem; | 6 | use core::mem; |
| 7 | use core::ptr; | ||
| 5 | use core::task::{Context, Poll, Waker}; | 8 | use core::task::{Context, Poll, Waker}; |
| 9 | use cortex_m::peripheral::NVIC; | ||
| 10 | use cortex_m::peripheral::{scb, SCB}; | ||
| 6 | 11 | ||
| 7 | pub struct Signal<T> { | 12 | pub struct Signal<T> { |
| 8 | state: UnsafeCell<State<T>>, | 13 | state: UnsafeCell<State<T>>, |
| @@ -67,3 +72,66 @@ impl<T: Send> Signal<T> { | |||
| 67 | cortex_m::interrupt::free(|_| matches!(unsafe { &*self.state.get() }, State::Signaled(_))) | 72 | cortex_m::interrupt::free(|_| matches!(unsafe { &*self.state.get() }, State::Signaled(_))) |
| 68 | } | 73 | } |
| 69 | } | 74 | } |
| 75 | |||
| 76 | struct NrWrap(u8); | ||
| 77 | unsafe impl cortex_m::interrupt::Nr for NrWrap { | ||
| 78 | fn nr(&self) -> u8 { | ||
| 79 | self.0 | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | pub struct InterruptFuture<'a, I: OwnedInterrupt> { | ||
| 84 | interrupt: &'a mut I, | ||
| 85 | } | ||
| 86 | |||
| 87 | impl<'a, I: OwnedInterrupt> Drop for InterruptFuture<'a, I> { | ||
| 88 | fn drop(&mut self) { | ||
| 89 | self.interrupt.disable(); | ||
| 90 | self.interrupt.remove_handler(); | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | impl<'a, I: OwnedInterrupt> InterruptFuture<'a, I> { | ||
| 95 | pub fn new(interrupt: &'a mut I) -> Self { | ||
| 96 | interrupt.disable(); | ||
| 97 | interrupt.set_handler(Self::interrupt_handler, ptr::null_mut()); | ||
| 98 | interrupt.unpend(); | ||
| 99 | interrupt.enable(); | ||
| 100 | |||
| 101 | Self { | ||
| 102 | interrupt: interrupt, | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | unsafe fn interrupt_handler(ctx: *mut ()) { | ||
| 107 | let irq = match SCB::vect_active() { | ||
| 108 | scb::VectActive::Interrupt { irqn } => irqn, | ||
| 109 | _ => unreachable!(), | ||
| 110 | }; | ||
| 111 | |||
| 112 | if ctx as *const _ != ptr::null() { | ||
| 113 | executor::raw::wake_task(ptr::NonNull::new_unchecked(ctx)); | ||
| 114 | } | ||
| 115 | |||
| 116 | NVIC::mask(NrWrap(irq)); | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 | impl<'a, I: OwnedInterrupt> Unpin for InterruptFuture<'a, I> {} | ||
| 121 | |||
| 122 | impl<'a, I: OwnedInterrupt> Future for InterruptFuture<'a, I> { | ||
| 123 | type Output = (); | ||
| 124 | |||
| 125 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { | ||
| 126 | let s = unsafe { self.get_unchecked_mut() }; | ||
| 127 | s.interrupt.set_handler( | ||
| 128 | Self::interrupt_handler, | ||
| 129 | executor::raw::task_from_waker(&cx.waker()).cast().as_ptr(), | ||
| 130 | ); | ||
| 131 | if s.interrupt.is_enabled() { | ||
| 132 | Poll::Pending | ||
| 133 | } else { | ||
| 134 | Poll::Ready(()) | ||
| 135 | } | ||
| 136 | } | ||
| 137 | } | ||
