|
| 1 | +//! Portable in-line assembly |
| 2 | +//! |
| 3 | +//! On the RP235x, this is useful to write code portable between ARM and RISC-V cores. |
| 4 | +//! While there's no such choice on the RP2040, providing the same functions helps writing |
| 5 | +//! code that works on both RP2040 and RP235x. |
| 6 | +
|
| 7 | +#[cfg(all(target_arch = "arm", target_os = "none"))] |
| 8 | +mod inner { |
| 9 | + pub use cortex_m::asm::{delay, dsb, nop, sev, wfe, wfi}; |
| 10 | + pub use cortex_m::interrupt::{disable as interrupt_disable, enable as interrupt_enable}; |
| 11 | + |
| 12 | + /// Are interrupts current enabled? |
| 13 | + pub fn interrupts_enabled() -> bool { |
| 14 | + cortex_m::register::primask::read().is_active() |
| 15 | + } |
| 16 | + |
| 17 | + /// Run the closure without interrupts |
| 18 | + /// |
| 19 | + /// No critical-section token because we haven't blocked the second core |
| 20 | + pub fn interrupt_free<T, F>(f: F) -> T |
| 21 | + where |
| 22 | + F: FnOnce() -> T, |
| 23 | + { |
| 24 | + let active = interrupts_enabled(); |
| 25 | + if active { |
| 26 | + interrupt_disable(); |
| 27 | + } |
| 28 | + let t = f(); |
| 29 | + if active { |
| 30 | + unsafe { |
| 31 | + interrupt_enable(); |
| 32 | + } |
| 33 | + } |
| 34 | + t |
| 35 | + } |
| 36 | +} |
| 37 | + |
| 38 | +#[cfg(not(all(any(target_arch = "arm", target_arch = "riscv32"), target_os = "none")))] |
| 39 | +mod inner { |
| 40 | + /// Placeholder function to disable interrupts |
| 41 | + pub fn interrupt_disable() {} |
| 42 | + /// Placeholder function to enable interrupts |
| 43 | + pub fn interrupt_enable() {} |
| 44 | + /// Placeholder function to check if interrupts are enabled |
| 45 | + pub fn interrupts_enabled() -> bool { |
| 46 | + false |
| 47 | + } |
| 48 | + /// Placeholder function to wait for an event |
| 49 | + pub fn wfe() {} |
| 50 | + /// Placeholder function to do nothing |
| 51 | + pub fn nop() {} |
| 52 | + /// Placeholder function to emit a data synchronisation barrier |
| 53 | + pub fn dsb() {} |
| 54 | + /// Placeholder function to run a closure with interrupts disabled |
| 55 | + pub fn interrupt_free<T, F>(f: F) -> T |
| 56 | + where |
| 57 | + F: FnOnce() -> T, |
| 58 | + { |
| 59 | + f() |
| 60 | + } |
| 61 | + /// Placeholder function to wait for some clock cycles |
| 62 | + pub fn delay(_: u32) {} |
| 63 | + /// Placeholder function to emit an event |
| 64 | + pub fn sev() {} |
| 65 | +} |
| 66 | + |
| 67 | +pub use inner::*; |
0 commit comments