1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
use core::{
    ptr::write_volatile,
    task::{RawWaker, RawWakerVTable, Waker},
};

const NVIC_STIR: usize = 0xE000_EF00;

static VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake, drop);

#[repr(transparent)]
pub struct WakeInt(u16);

impl WakeInt {
    pub fn new(int_num: u16) -> Self {
        Self(int_num)
    }

    pub fn wakeup(&self) {
        unsafe { write_volatile(NVIC_STIR as *mut u16, self.0) };
    }

    pub fn to_waker(&self) -> Waker {
        unsafe { Waker::from_raw(self.to_raw_waker()) }
    }

    fn to_raw_waker(&self) -> RawWaker {
        RawWaker::new(self.0 as *const (), &VTABLE)
    }
}

unsafe fn clone(data: *const ()) -> RawWaker {
    WakeInt::new(data as u16).to_raw_waker()
}

unsafe fn wake(data: *const ()) {
    WakeInt::new(data as u16).wakeup();
}