2020-12-31 03:14:56 +00:00
|
|
|
//! Interrupt management
|
|
|
|
//!
|
|
|
|
//! This module implements an API for managing interrupts compatible with
|
|
|
|
//! nrf_softdevice::interrupt. Intended for switching between the two at compile-time.
|
|
|
|
|
|
|
|
use core::sync::atomic::{compiler_fence, Ordering};
|
|
|
|
|
|
|
|
use crate::pac::NVIC_PRIO_BITS;
|
|
|
|
|
|
|
|
// Re-exports
|
|
|
|
pub use crate::pac::Interrupt;
|
|
|
|
pub use crate::pac::Interrupt::*; // needed for cortex-m-rt #[interrupt]
|
|
|
|
pub use cortex_m::interrupt::{CriticalSection, Mutex};
|
|
|
|
pub use embassy::interrupt::{declare, take, OwnedInterrupt};
|
|
|
|
|
|
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
|
|
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
|
|
|
#[repr(u8)]
|
|
|
|
pub enum Priority {
|
|
|
|
Level0 = 0,
|
|
|
|
Level1 = 1,
|
|
|
|
Level2 = 2,
|
|
|
|
Level3 = 3,
|
|
|
|
Level4 = 4,
|
|
|
|
Level5 = 5,
|
|
|
|
Level6 = 6,
|
|
|
|
Level7 = 7,
|
2021-01-05 23:18:24 +00:00
|
|
|
Level8 = 8,
|
|
|
|
Level9 = 9,
|
|
|
|
Level10 = 10,
|
|
|
|
Level11 = 11,
|
|
|
|
Level12 = 12,
|
|
|
|
Level13 = 13,
|
|
|
|
Level14 = 14,
|
2021-01-05 23:24:27 +00:00
|
|
|
Level15 = 15,
|
2020-12-31 03:14:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl From<u8> for Priority {
|
|
|
|
fn from(priority: u8) -> Self {
|
|
|
|
match priority >> (8 - NVIC_PRIO_BITS) {
|
|
|
|
0 => Self::Level0,
|
|
|
|
1 => Self::Level1,
|
|
|
|
2 => Self::Level2,
|
|
|
|
3 => Self::Level3,
|
|
|
|
4 => Self::Level4,
|
|
|
|
5 => Self::Level5,
|
|
|
|
6 => Self::Level6,
|
|
|
|
7 => Self::Level7,
|
2021-01-05 23:38:46 +00:00
|
|
|
8 => Self::Level8,
|
|
|
|
9 => Self::Level9,
|
|
|
|
10 => Self::Level10,
|
|
|
|
11 => Self::Level11,
|
|
|
|
12 => Self::Level12,
|
|
|
|
13 => Self::Level13,
|
|
|
|
14 => Self::Level14,
|
|
|
|
15 => Self::Level15,
|
2020-12-31 03:14:56 +00:00
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Priority> for u8 {
|
|
|
|
fn from(p: Priority) -> Self {
|
|
|
|
(p as u8) << (8 - NVIC_PRIO_BITS)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn free<F, R>(f: F) -> R
|
|
|
|
where
|
|
|
|
F: FnOnce(&CriticalSection) -> R,
|
|
|
|
{
|
|
|
|
unsafe {
|
|
|
|
// TODO: assert that we're in privileged level
|
|
|
|
// Needed because disabling irqs in non-privileged level is a noop, which would break safety.
|
|
|
|
|
|
|
|
let primask: u32;
|
|
|
|
asm!("mrs {}, PRIMASK", out(reg) primask);
|
|
|
|
|
|
|
|
asm!("cpsid i");
|
|
|
|
|
|
|
|
// Prevent compiler from reordering operations inside/outside the critical section.
|
|
|
|
compiler_fence(Ordering::SeqCst);
|
|
|
|
|
|
|
|
let r = f(&CriticalSection::new());
|
|
|
|
|
|
|
|
compiler_fence(Ordering::SeqCst);
|
|
|
|
|
|
|
|
if primask & 1 == 0 {
|
|
|
|
asm!("cpsie i");
|
|
|
|
}
|
|
|
|
|
|
|
|
r
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-16 00:38:36 +00:00
|
|
|
#[cfg(feature = "stm32f401")]
|
|
|
|
mod irqs {
|
|
|
|
use super::*;
|
|
|
|
declare!(PVD);
|
|
|
|
declare!(TAMP_STAMP);
|
|
|
|
declare!(RTC_WKUP);
|
|
|
|
declare!(FLASH);
|
|
|
|
declare!(RCC);
|
|
|
|
declare!(EXTI0);
|
|
|
|
declare!(EXTI1);
|
|
|
|
declare!(EXTI2);
|
|
|
|
declare!(EXTI3);
|
|
|
|
declare!(EXTI4);
|
|
|
|
declare!(DMA1_STREAM0);
|
|
|
|
declare!(DMA1_STREAM1);
|
|
|
|
declare!(DMA1_STREAM2);
|
|
|
|
declare!(DMA1_STREAM3);
|
|
|
|
declare!(DMA1_STREAM4);
|
|
|
|
declare!(DMA1_STREAM5);
|
|
|
|
declare!(DMA1_STREAM6);
|
|
|
|
declare!(ADC);
|
|
|
|
declare!(EXTI9_5);
|
|
|
|
declare!(TIM1_BRK_TIM9);
|
|
|
|
declare!(TIM1_UP_TIM10);
|
|
|
|
declare!(TIM1_TRG_COM_TIM11);
|
|
|
|
declare!(TIM1_CC);
|
|
|
|
declare!(TIM2);
|
|
|
|
declare!(TIM3);
|
|
|
|
declare!(TIM4);
|
|
|
|
declare!(I2C1_EV);
|
|
|
|
declare!(I2C1_ER);
|
|
|
|
declare!(I2C2_EV);
|
|
|
|
declare!(I2C2_ER);
|
|
|
|
declare!(SPI1);
|
|
|
|
declare!(SPI2);
|
|
|
|
declare!(USART1);
|
|
|
|
declare!(USART2);
|
|
|
|
declare!(EXTI15_10);
|
|
|
|
declare!(RTC_ALARM);
|
|
|
|
declare!(OTG_FS_WKUP);
|
|
|
|
declare!(DMA1_STREAM7);
|
|
|
|
declare!(SDIO);
|
|
|
|
declare!(TIM5);
|
|
|
|
declare!(SPI3);
|
|
|
|
declare!(DMA2_STREAM0);
|
|
|
|
declare!(DMA2_STREAM1);
|
|
|
|
declare!(DMA2_STREAM2);
|
|
|
|
declare!(DMA2_STREAM3);
|
|
|
|
declare!(DMA2_STREAM4);
|
|
|
|
declare!(OTG_FS);
|
|
|
|
declare!(DMA2_STREAM5);
|
|
|
|
declare!(DMA2_STREAM6);
|
|
|
|
declare!(DMA2_STREAM7);
|
|
|
|
declare!(USART6);
|
|
|
|
declare!(I2C3_EV);
|
|
|
|
declare!(I2C3_ER);
|
|
|
|
declare!(FPU);
|
|
|
|
declare!(SPI4);
|
|
|
|
}
|
|
|
|
|
2020-12-31 03:14:56 +00:00
|
|
|
#[cfg(feature = "stm32f405")]
|
|
|
|
mod irqs {
|
|
|
|
use super::*;
|
|
|
|
declare!(WWDG);
|
|
|
|
declare!(PVD);
|
|
|
|
declare!(TAMP_STAMP);
|
|
|
|
declare!(RTC_WKUP);
|
|
|
|
// declare!(FLASH);
|
|
|
|
declare!(RCC);
|
|
|
|
declare!(EXTI0);
|
|
|
|
declare!(EXTI1);
|
|
|
|
declare!(EXTI2);
|
|
|
|
declare!(EXTI3);
|
|
|
|
declare!(EXTI4);
|
|
|
|
declare!(DMA1_STREAM0);
|
|
|
|
declare!(DMA1_STREAM1);
|
|
|
|
declare!(DMA1_STREAM2);
|
|
|
|
declare!(DMA1_STREAM3);
|
|
|
|
declare!(DMA1_STREAM4);
|
|
|
|
declare!(DMA1_STREAM5);
|
|
|
|
declare!(DMA1_STREAM6);
|
|
|
|
declare!(ADC);
|
|
|
|
declare!(CAN1_TX);
|
|
|
|
declare!(CAN1_RX0);
|
|
|
|
declare!(CAN1_RX1);
|
|
|
|
declare!(CAN1_SCE);
|
|
|
|
declare!(EXTI9_5);
|
|
|
|
declare!(TIM1_BRK_TIM9);
|
|
|
|
declare!(TIM1_UP_TIM10);
|
|
|
|
declare!(TIM1_TRG_COM_TIM11);
|
|
|
|
declare!(TIM1_CC);
|
|
|
|
declare!(TIM2);
|
|
|
|
declare!(TIM3);
|
|
|
|
declare!(TIM4);
|
|
|
|
declare!(I2C1_EV);
|
|
|
|
declare!(I2C1_ER);
|
|
|
|
declare!(I2C2_EV);
|
|
|
|
declare!(I2C2_ER);
|
|
|
|
declare!(SPI1);
|
|
|
|
declare!(SPI2);
|
|
|
|
declare!(USART1);
|
|
|
|
declare!(USART2);
|
|
|
|
declare!(USART3);
|
|
|
|
declare!(EXTI15_10);
|
|
|
|
declare!(RTC_ALARM);
|
|
|
|
declare!(OTG_FS_WKUP);
|
|
|
|
declare!(TIM8_BRK_TIM12);
|
|
|
|
declare!(TIM8_UP_TIM13);
|
|
|
|
declare!(TIM8_TRG_COM_TIM14);
|
|
|
|
declare!(TIM8_CC);
|
|
|
|
declare!(DMA1_STREAM7);
|
|
|
|
// declare!(FMC);
|
|
|
|
declare!(SDIO);
|
|
|
|
declare!(TIM5);
|
|
|
|
declare!(SPI3);
|
|
|
|
declare!(UART4);
|
|
|
|
declare!(UART5);
|
|
|
|
declare!(TIM6_DAC);
|
|
|
|
declare!(TIM7);
|
|
|
|
declare!(DMA2_STREAM0);
|
|
|
|
declare!(DMA2_STREAM1);
|
|
|
|
declare!(DMA2_STREAM2);
|
|
|
|
declare!(DMA2_STREAM3);
|
|
|
|
declare!(DMA2_STREAM4);
|
|
|
|
declare!(ETH);
|
|
|
|
declare!(ETH_WKUP);
|
|
|
|
declare!(CAN2_TX);
|
|
|
|
declare!(CAN2_RX0);
|
|
|
|
declare!(CAN2_RX1);
|
|
|
|
declare!(CAN2_SCE);
|
|
|
|
declare!(OTG_FS);
|
|
|
|
declare!(DMA2_STREAM5);
|
|
|
|
declare!(DMA2_STREAM6);
|
|
|
|
declare!(DMA2_STREAM7);
|
|
|
|
declare!(USART6);
|
|
|
|
declare!(I2C3_EV);
|
|
|
|
declare!(I2C3_ER);
|
|
|
|
declare!(OTG_HS_EP1_OUT);
|
|
|
|
declare!(OTG_HS_EP1_IN);
|
|
|
|
declare!(OTG_HS_WKUP);
|
|
|
|
declare!(OTG_HS);
|
|
|
|
declare!(DCMI);
|
|
|
|
declare!(CRYP);
|
|
|
|
declare!(HASH_RNG);
|
|
|
|
declare!(FPU);
|
|
|
|
// declare!(UART7);
|
|
|
|
// declare!(UART8);
|
|
|
|
// declare!(SPI4);
|
|
|
|
// declare!(SPI5);
|
|
|
|
// declare!(SPI6);
|
|
|
|
// declare!(SAI1);
|
|
|
|
declare!(LCD_TFT);
|
|
|
|
declare!(LCD_TFT_1);
|
|
|
|
// declare!(DMA2D);
|
|
|
|
}
|
|
|
|
|
2021-01-21 17:59:56 +00:00
|
|
|
#[cfg(feature = "stm32f411")]
|
|
|
|
mod irqs {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
declare!(WWDG);
|
|
|
|
declare!(PVD);
|
|
|
|
declare!(TAMP_STAMP);
|
|
|
|
declare!(RTC_WKUP);
|
|
|
|
declare!(FLASH);
|
|
|
|
declare!(RCC);
|
|
|
|
declare!(EXTI0);
|
|
|
|
declare!(EXTI1);
|
|
|
|
declare!(EXTI2);
|
|
|
|
declare!(EXTI3);
|
|
|
|
declare!(EXTI4);
|
|
|
|
declare!(DMA1_STREAM0);
|
|
|
|
declare!(DMA1_STREAM1);
|
|
|
|
declare!(DMA1_STREAM2);
|
|
|
|
declare!(DMA1_STREAM3);
|
|
|
|
declare!(DMA1_STREAM4);
|
|
|
|
declare!(DMA1_STREAM5);
|
|
|
|
declare!(DMA1_STREAM6);
|
|
|
|
declare!(ADC);
|
|
|
|
declare!(EXTI9_5);
|
|
|
|
declare!(TIM1_BRK_TIM9);
|
|
|
|
declare!(TIM1_UP_TIM10);
|
|
|
|
declare!(TIM1_TRG_COM_TIM11);
|
|
|
|
declare!(TIM1_CC);
|
|
|
|
declare!(TIM2);
|
|
|
|
declare!(TIM3);
|
|
|
|
declare!(TIM4);
|
|
|
|
declare!(I2C1_EV);
|
|
|
|
declare!(I2C1_ER);
|
|
|
|
declare!(I2C2_EV);
|
|
|
|
declare!(I2C2_ER);
|
|
|
|
declare!(SPI1);
|
|
|
|
declare!(SPI2);
|
|
|
|
declare!(USART1);
|
|
|
|
declare!(USART2);
|
|
|
|
declare!(EXTI15_10);
|
|
|
|
declare!(RTC_ALARM);
|
|
|
|
declare!(OTG_FS_WKUP);
|
|
|
|
declare!(DMA1_STREAM7);
|
|
|
|
declare!(SDIO);
|
|
|
|
declare!(TIM5);
|
|
|
|
declare!(SPI3);
|
|
|
|
declare!(DMA2_STREAM0);
|
|
|
|
declare!(DMA2_STREAM1);
|
|
|
|
declare!(DMA2_STREAM2);
|
|
|
|
declare!(DMA2_STREAM3);
|
|
|
|
declare!(DMA2_STREAM4);
|
|
|
|
declare!(OTG_FS);
|
|
|
|
declare!(DMA2_STREAM5);
|
|
|
|
declare!(DMA2_STREAM6);
|
|
|
|
declare!(DMA2_STREAM7);
|
|
|
|
declare!(USART6);
|
|
|
|
declare!(I2C3_EV);
|
|
|
|
declare!(I2C3_ER);
|
|
|
|
declare!(FPU);
|
|
|
|
declare!(SPI4);
|
|
|
|
declare!(SPI5);
|
|
|
|
}
|
|
|
|
|
2020-12-31 03:14:56 +00:00
|
|
|
pub use irqs::*;
|