diff --git a/esp32c6/Cargo.toml b/esp32c6/Cargo.toml index 5cbe7c888..909d96542 100644 --- a/esp32c6/Cargo.toml +++ b/esp32c6/Cargo.toml @@ -28,12 +28,14 @@ bench = false test = false [dependencies] -critical-section = { version = "1.1.3", optional = true } -vcell = "0.1.3" -defmt = { version = "0.3.8", optional = true } +critical-section = { version = "1.2.0", optional = true } +defmt = { version = "0.3.8", optional = true } +riscv = "0.12.1" +riscv-peripheral = "0.2.0" +vcell = "0.1.3" [features] -default = [] -rt = [] +default = [] +defmt = ["dep:defmt"] impl-register-debug = [] -defmt = ["dep:defmt"] +rt = [] diff --git a/esp32c6/device.x b/esp32c6/device.x index 740d9f953..0a73aed5b 100644 --- a/esp32c6/device.x +++ b/esp32c6/device.x @@ -1,3 +1,23 @@ +/* Core interrupt sources and trap handlers */ +PROVIDE(UserSoft = DefaultHandler); +PROVIDE(_start_UserSoft_trap = _start_DefaultHandler_trap); +PROVIDE(SupervisorSoft = DefaultHandler); +PROVIDE(_start_SupervisorSoft_trap = _start_DefaultHandler_trap); +PROVIDE(MachineSoft = DefaultHandler); +PROVIDE(_start_MachineSoft_trap = _start_DefaultHandler_trap); +PROVIDE(UserTimer = DefaultHandler); +PROVIDE(_start_UserTimer_trap = _start_DefaultHandler_trap); +PROVIDE(SupervisorTimer = DefaultHandler); +PROVIDE(_start_SupervisorTimer_trap = _start_DefaultHandler_trap); +PROVIDE(MachineTimer = DefaultHandler); +PROVIDE(_start_MachineTimer_trap = _start_DefaultHandler_trap); +PROVIDE(UserExternal = DefaultHandler); +PROVIDE(_start_UserExternal_trap = _start_DefaultHandler_trap); +PROVIDE(SupervisorExternal = DefaultHandler); +PROVIDE(_start_SupervisorExternal_trap = _start_DefaultHandler_trap); +PROVIDE(MachineExternal = DefaultHandler); +PROVIDE(_start_MachineExternal_trap = _start_DefaultHandler_trap); +/* External interrupt sources */ PROVIDE(WIFI_MAC = DefaultHandler); PROVIDE(WIFI_MAC_NMI = DefaultHandler); PROVIDE(WIFI_PWR = DefaultHandler); diff --git a/esp32c6/settings.yaml b/esp32c6/settings.yaml new file mode 100644 index 000000000..4a1cd6740 --- /dev/null +++ b/esp32c6/settings.yaml @@ -0,0 +1,81 @@ +riscv_config: + core_interrupts: + - name: "UserSoft" + value: 0 + description: "User Software Interrupt" + - name: "SupervisorSoft" + value: 1 + description: "Supervisor Software Interrupt" + - name: "MachineSoft" + value: 3 + description: "Machine Software Interrupt" + - name: "UserTimer" + value: 4 + description: "User Timer Interrupt" + - name: "SupervisorTimer" + value: 5 + description: "Supervisor Timer Interrupt" + - name: "MachineTimer" + value: 7 + description: "Machine Timer Interrupt" + - name: "UserExternal" + value: 8 + description: "User External Interrupt" + - name: "SupervisorExternal" + value: 9 + description: "Supervisor External Interrupt" + - name: "MachineExternal" + value: 11 + description: "Machine External Interrupt" + + priorities: + - name: "P1" + value: 1 + description: "Priority level 1" + - name: "P2" + value: 2 + description: "Priority level 2" + - name: "P3" + value: 3 + description: "Priority level 3" + - name: "P4" + value: 4 + description: "Priority level 4" + - name: "P5" + value: 5 + description: "Priority level 5" + - name: "P6" + value: 6 + description: "Priority level 6" + - name: "P7" + value: 7 + description: "Priority level 7" + - name: "P8" + value: 8 + description: "Priority level 8" + - name: "P9" + value: 9 + description: "Priority level 9" + - name: "P10" + value: 10 + description: "Priority level 10" + - name: "P11" + value: 11 + description: "Priority level 11" + - name: "P12" + value: 12 + description: "Priority level 12" + - name: "P13" + value: 13 + description: "Priority level 13" + - name: "P14" + value: 14 + description: "Priority level 14" + - name: "P15" + value: 15 + description: "Priority level 15" + + harts: + - name: "H0" + value: 0 + description: "Hart 0" diff --git a/esp32c6/src/interrupt.rs b/esp32c6/src/interrupt.rs index 0e66a817f..e6ae967af 100644 --- a/esp32c6/src/interrupt.rs +++ b/esp32c6/src/interrupt.rs @@ -1,8 +1,96 @@ -#[doc = r"Enumeration of all the interrupts."] +#[doc = r" Core interrupts. These interrupts are handled by the core itself."] +# [riscv :: pac_enum (unsafe CoreInterruptNumber)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[repr(u16)] -pub enum Interrupt { +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum CoreInterrupt { + #[doc = "0 - User Software Interrupt"] + UserSoft = 0, + #[doc = "1 - Supervisor Software Interrupt"] + SupervisorSoft = 1, + #[doc = "3 - Machine Software Interrupt"] + MachineSoft = 3, + #[doc = "4 - User Timer Interrupt"] + UserTimer = 4, + #[doc = "5 - Supervisor Timer Interrupt"] + SupervisorTimer = 5, + #[doc = "7 - Machine Timer Interrupt"] + MachineTimer = 7, + #[doc = "8 - User External Interrupt"] + UserExternal = 8, + #[doc = "9 - Supervisor External Interrupt"] + SupervisorExternal = 9, + #[doc = "11 - Machine External Interrupt"] + MachineExternal = 11, +} +pub use riscv::interrupt::Exception; +#[doc = r" Priority levels in the device"] +# [riscv :: pac_enum (unsafe PriorityNumber)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Priority { + #[doc = "1 - Priority level 1"] + P1 = 1, + #[doc = "2 - Priority level 2"] + P2 = 2, + #[doc = "3 - Priority level 3"] + P3 = 3, + #[doc = "4 - Priority level 4"] + P4 = 4, + #[doc = "5 - Priority level 5"] + P5 = 5, + #[doc = "6 - Priority level 6"] + P6 = 6, + #[doc = "7 - Priority level 7"] + P7 = 7, + #[doc = "8 - Priority level 8"] + P8 = 8, + #[doc = "9 - Priority level 9"] + P9 = 9, + #[doc = "10 - Priority level 10"] + P10 = 10, + #[doc = "11 - Priority level 11"] + P11 = 11, + #[doc = "12 - Priority level 12"] + P12 = 12, + #[doc = "13 - Priority level 13"] + P13 = 13, + #[doc = "14 - Priority level 14"] + P14 = 14, + #[doc = "15 - Priority level 15"] + P15 = 15, +} +#[doc = r" HARTs in the device"] +# [riscv :: pac_enum (unsafe HartIdNumber)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Hart { + #[doc = "0 - Hart 0"] + H0 = 0, +} +pub use riscv::{ + interrupt::{disable, enable, free, nested}, + ExceptionNumber, HartIdNumber, InterruptNumber, PriorityNumber, +}; +pub type Trap = riscv::interrupt::Trap; +#[doc = r" Retrieves the cause of a trap in the current hart."] +#[doc = r""] +#[doc = r" If the raw cause is not a valid interrupt or exception for the target, it returns an error."] +#[inline] +pub fn try_cause() -> riscv::result::Result { + riscv::interrupt::try_cause() +} +#[doc = r" Retrieves the cause of a trap in the current hart (machine mode)."] +#[doc = r""] +#[doc = r" If the raw cause is not a valid interrupt or exception for the target, it panics."] +#[inline] +pub fn cause() -> Trap { + try_cause().unwrap() +} +#[doc = r" External interrupts. These interrupts are handled by the external peripherals."] +# [riscv :: pac_enum (unsafe ExternalInterruptNumber)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ExternalInterrupt { #[doc = "0 - WIFI_MAC"] WIFI_MAC = 0, #[doc = "1 - WIFI_MAC_NMI"] @@ -158,131 +246,3 @@ pub enum Interrupt { #[doc = "76 - ECC"] ECC = 76, } -#[doc = r" TryFromInterruptError"] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[derive(Debug, Copy, Clone)] -pub struct TryFromInterruptError(()); -impl Interrupt { - #[doc = r" Attempt to convert a given value into an `Interrupt`"] - #[inline] - pub fn try_from(value: u8) -> Result { - match value { - 0 => Ok(Interrupt::WIFI_MAC), - 1 => Ok(Interrupt::WIFI_MAC_NMI), - 2 => Ok(Interrupt::WIFI_PWR), - 3 => Ok(Interrupt::WIFI_BB), - 4 => Ok(Interrupt::BT_MAC), - 5 => Ok(Interrupt::BT_BB), - 6 => Ok(Interrupt::BT_BB_NMI), - 7 => Ok(Interrupt::LP_TIMER), - 8 => Ok(Interrupt::COEX), - 9 => Ok(Interrupt::BLE_TIMER), - 10 => Ok(Interrupt::BLE_SEC), - 11 => Ok(Interrupt::I2C_MASTER), - 12 => Ok(Interrupt::ZB_MAC), - 13 => Ok(Interrupt::PMU), - 14 => Ok(Interrupt::EFUSE), - 15 => Ok(Interrupt::LP_RTC_TIMER), - 16 => Ok(Interrupt::LP_UART), - 17 => Ok(Interrupt::LP_I2C), - 18 => Ok(Interrupt::LP_WDT), - 19 => Ok(Interrupt::LP_PERI_TIMEOUT), - 20 => Ok(Interrupt::LP_APM_M0), - 21 => Ok(Interrupt::LP_APM_M1), - 22 => Ok(Interrupt::FROM_CPU_INTR0), - 23 => Ok(Interrupt::FROM_CPU_INTR1), - 24 => Ok(Interrupt::FROM_CPU_INTR2), - 25 => Ok(Interrupt::FROM_CPU_INTR3), - 26 => Ok(Interrupt::ASSIST_DEBUG), - 27 => Ok(Interrupt::TRACE), - 28 => Ok(Interrupt::CACHE), - 29 => Ok(Interrupt::CPU_PERI_TIMEOUT), - 30 => Ok(Interrupt::GPIO), - 31 => Ok(Interrupt::GPIO_NMI), - 32 => Ok(Interrupt::PAU), - 33 => Ok(Interrupt::HP_PERI_TIMEOUT), - 34 => Ok(Interrupt::MODEM_PERI_TIMEOUT), - 35 => Ok(Interrupt::HP_APM_M0), - 36 => Ok(Interrupt::HP_APM_M1), - 37 => Ok(Interrupt::HP_APM_M2), - 38 => Ok(Interrupt::HP_APM_M3), - 39 => Ok(Interrupt::LP_APM0), - 40 => Ok(Interrupt::MSPI), - 41 => Ok(Interrupt::I2S0), - 42 => Ok(Interrupt::UHCI0), - 43 => Ok(Interrupt::UART0), - 44 => Ok(Interrupt::UART1), - 45 => Ok(Interrupt::LEDC), - 46 => Ok(Interrupt::TWAI0), - 47 => Ok(Interrupt::TWAI1), - 48 => Ok(Interrupt::USB_DEVICE), - 49 => Ok(Interrupt::RMT), - 50 => Ok(Interrupt::I2C_EXT0), - 51 => Ok(Interrupt::TG0_T0_LEVEL), - 52 => Ok(Interrupt::TG0_T1_LEVEL), - 53 => Ok(Interrupt::TG0_WDT_LEVEL), - 54 => Ok(Interrupt::TG1_T0_LEVEL), - 55 => Ok(Interrupt::TG1_T1_LEVEL), - 56 => Ok(Interrupt::TG1_WDT_LEVEL), - 57 => Ok(Interrupt::SYSTIMER_TARGET0), - 58 => Ok(Interrupt::SYSTIMER_TARGET1), - 59 => Ok(Interrupt::SYSTIMER_TARGET2), - 60 => Ok(Interrupt::APB_SARADC), - 61 => Ok(Interrupt::MCPWM0), - 62 => Ok(Interrupt::PCNT), - 63 => Ok(Interrupt::PARL_IO), - 64 => Ok(Interrupt::SLC0), - 65 => Ok(Interrupt::SLC1), - 66 => Ok(Interrupt::DMA_IN_CH0), - 67 => Ok(Interrupt::DMA_IN_CH1), - 68 => Ok(Interrupt::DMA_IN_CH2), - 69 => Ok(Interrupt::DMA_OUT_CH0), - 70 => Ok(Interrupt::DMA_OUT_CH1), - 71 => Ok(Interrupt::DMA_OUT_CH2), - 72 => Ok(Interrupt::SPI2), - 73 => Ok(Interrupt::AES), - 74 => Ok(Interrupt::SHA), - 75 => Ok(Interrupt::RSA), - 76 => Ok(Interrupt::ECC), - _ => Err(TryFromInterruptError(())), - } - } -} -#[cfg(feature = "rt")] -#[macro_export] -#[doc = r" Assigns a handler to an interrupt"] -#[doc = r""] -#[doc = r" This macro takes two arguments: the name of an interrupt and the path to the"] -#[doc = r" function that will be used as the handler of that interrupt. That function"] -#[doc = r" must have signature `fn()`."] -#[doc = r""] -#[doc = r" Optionally, a third argument may be used to declare interrupt local data."] -#[doc = r" The handler will have exclusive access to these *local* variables on each"] -#[doc = r" invocation. If the third argument is used then the signature of the handler"] -#[doc = r" function must be `fn(&mut $NAME::Locals)` where `$NAME` is the first argument"] -#[doc = r" passed to the macro."] -#[doc = r""] -#[doc = r" # Example"] -#[doc = r""] -#[doc = r" ``` ignore"] -#[doc = r" interrupt!(TIM2, periodic);"] -#[doc = r""] -#[doc = r" fn periodic() {"] -#[doc = r#" print!(".");"#] -#[doc = r" }"] -#[doc = r""] -#[doc = r" interrupt!(TIM3, tick, locals: {"] -#[doc = r" tick: bool = false;"] -#[doc = r" });"] -#[doc = r""] -#[doc = r" fn tick(locals: &mut TIM3::Locals) {"] -#[doc = r" locals.tick = !locals.tick;"] -#[doc = r""] -#[doc = r" if locals.tick {"] -#[doc = r#" println!("Tick");"#] -#[doc = r" } else {"] -#[doc = r#" println!("Tock");"#] -#[doc = r" }"] -#[doc = r" }"] -#[doc = r" ```"] -macro_rules ! interrupt { ($ NAME : ident , $ path : path , locals : { $ ($ lvar : ident : $ lty : ty = $ lval : expr ;) * }) => { # [allow (non_snake_case)] mod $ NAME { pub struct Locals { $ (pub $ lvar : $ lty ,) * } } # [allow (non_snake_case)] # [no_mangle] pub extern "C" fn $ NAME () { let _ = $ crate :: interrupt :: Interrupt :: $ NAME ; static mut LOCALS : self :: $ NAME :: Locals = self :: $ NAME :: Locals { $ ($ lvar : $ lval ,) * } ; let f : fn (& mut self :: $ NAME :: Locals) = $ path ; f (unsafe { & mut LOCALS }) ; } } ; ($ NAME : ident , $ path : path) => { # [allow (non_snake_case)] # [no_mangle] pub extern "C" fn $ NAME () { let _ = $ crate :: interrupt :: Interrupt :: $ NAME ; let f : fn () = $ path ; f () ; } } } diff --git a/esp32c6/src/lib.rs b/esp32c6/src/lib.rs index 8dc51588e..ead77a492 100644 --- a/esp32c6/src/lib.rs +++ b/esp32c6/src/lib.rs @@ -11,252 +11,8 @@ pub const NVIC_PRIO_BITS: u8 = 0; use generic::*; #[doc = r"Common register and bit access and modify traits"] pub mod generic; -#[cfg(feature = "rt")] -extern "C" { - fn WIFI_MAC(); - fn WIFI_MAC_NMI(); - fn WIFI_PWR(); - fn WIFI_BB(); - fn BT_MAC(); - fn BT_BB(); - fn BT_BB_NMI(); - fn LP_TIMER(); - fn COEX(); - fn BLE_TIMER(); - fn BLE_SEC(); - fn I2C_MASTER(); - fn ZB_MAC(); - fn PMU(); - fn EFUSE(); - fn LP_RTC_TIMER(); - fn LP_UART(); - fn LP_I2C(); - fn LP_WDT(); - fn LP_PERI_TIMEOUT(); - fn LP_APM_M0(); - fn LP_APM_M1(); - fn FROM_CPU_INTR0(); - fn FROM_CPU_INTR1(); - fn FROM_CPU_INTR2(); - fn FROM_CPU_INTR3(); - fn ASSIST_DEBUG(); - fn TRACE(); - fn CACHE(); - fn CPU_PERI_TIMEOUT(); - fn GPIO(); - fn GPIO_NMI(); - fn PAU(); - fn HP_PERI_TIMEOUT(); - fn MODEM_PERI_TIMEOUT(); - fn HP_APM_M0(); - fn HP_APM_M1(); - fn HP_APM_M2(); - fn HP_APM_M3(); - fn LP_APM0(); - fn MSPI(); - fn I2S0(); - fn UHCI0(); - fn UART0(); - fn UART1(); - fn LEDC(); - fn TWAI0(); - fn TWAI1(); - fn USB_DEVICE(); - fn RMT(); - fn I2C_EXT0(); - fn TG0_T0_LEVEL(); - fn TG0_T1_LEVEL(); - fn TG0_WDT_LEVEL(); - fn TG1_T0_LEVEL(); - fn TG1_T1_LEVEL(); - fn TG1_WDT_LEVEL(); - fn SYSTIMER_TARGET0(); - fn SYSTIMER_TARGET1(); - fn SYSTIMER_TARGET2(); - fn APB_SARADC(); - fn MCPWM0(); - fn PCNT(); - fn PARL_IO(); - fn SLC0(); - fn SLC1(); - fn DMA_IN_CH0(); - fn DMA_IN_CH1(); - fn DMA_IN_CH2(); - fn DMA_OUT_CH0(); - fn DMA_OUT_CH1(); - fn DMA_OUT_CH2(); - fn SPI2(); - fn AES(); - fn SHA(); - fn RSA(); - fn ECC(); -} -#[doc(hidden)] -#[repr(C)] -pub union Vector { - pub _handler: unsafe extern "C" fn(), - pub _reserved: usize, -} -#[cfg(feature = "rt")] -#[doc(hidden)] -#[link_section = ".rwtext"] -#[no_mangle] -pub static __EXTERNAL_INTERRUPTS: [Vector; 77] = [ - Vector { _handler: WIFI_MAC }, - Vector { - _handler: WIFI_MAC_NMI, - }, - Vector { _handler: WIFI_PWR }, - Vector { _handler: WIFI_BB }, - Vector { _handler: BT_MAC }, - Vector { _handler: BT_BB }, - Vector { - _handler: BT_BB_NMI, - }, - Vector { _handler: LP_TIMER }, - Vector { _handler: COEX }, - Vector { - _handler: BLE_TIMER, - }, - Vector { _handler: BLE_SEC }, - Vector { - _handler: I2C_MASTER, - }, - Vector { _handler: ZB_MAC }, - Vector { _handler: PMU }, - Vector { _handler: EFUSE }, - Vector { - _handler: LP_RTC_TIMER, - }, - Vector { _handler: LP_UART }, - Vector { _handler: LP_I2C }, - Vector { _handler: LP_WDT }, - Vector { - _handler: LP_PERI_TIMEOUT, - }, - Vector { - _handler: LP_APM_M0, - }, - Vector { - _handler: LP_APM_M1, - }, - Vector { - _handler: FROM_CPU_INTR0, - }, - Vector { - _handler: FROM_CPU_INTR1, - }, - Vector { - _handler: FROM_CPU_INTR2, - }, - Vector { - _handler: FROM_CPU_INTR3, - }, - Vector { - _handler: ASSIST_DEBUG, - }, - Vector { _handler: TRACE }, - Vector { _handler: CACHE }, - Vector { - _handler: CPU_PERI_TIMEOUT, - }, - Vector { _handler: GPIO }, - Vector { _handler: GPIO_NMI }, - Vector { _handler: PAU }, - Vector { - _handler: HP_PERI_TIMEOUT, - }, - Vector { - _handler: MODEM_PERI_TIMEOUT, - }, - Vector { - _handler: HP_APM_M0, - }, - Vector { - _handler: HP_APM_M1, - }, - Vector { - _handler: HP_APM_M2, - }, - Vector { - _handler: HP_APM_M3, - }, - Vector { _handler: LP_APM0 }, - Vector { _handler: MSPI }, - Vector { _handler: I2S0 }, - Vector { _handler: UHCI0 }, - Vector { _handler: UART0 }, - Vector { _handler: UART1 }, - Vector { _handler: LEDC }, - Vector { _handler: TWAI0 }, - Vector { _handler: TWAI1 }, - Vector { - _handler: USB_DEVICE, - }, - Vector { _handler: RMT }, - Vector { _handler: I2C_EXT0 }, - Vector { - _handler: TG0_T0_LEVEL, - }, - Vector { - _handler: TG0_T1_LEVEL, - }, - Vector { - _handler: TG0_WDT_LEVEL, - }, - Vector { - _handler: TG1_T0_LEVEL, - }, - Vector { - _handler: TG1_T1_LEVEL, - }, - Vector { - _handler: TG1_WDT_LEVEL, - }, - Vector { - _handler: SYSTIMER_TARGET0, - }, - Vector { - _handler: SYSTIMER_TARGET1, - }, - Vector { - _handler: SYSTIMER_TARGET2, - }, - Vector { - _handler: APB_SARADC, - }, - Vector { _handler: MCPWM0 }, - Vector { _handler: PCNT }, - Vector { _handler: PARL_IO }, - Vector { _handler: SLC0 }, - Vector { _handler: SLC1 }, - Vector { - _handler: DMA_IN_CH0, - }, - Vector { - _handler: DMA_IN_CH1, - }, - Vector { - _handler: DMA_IN_CH2, - }, - Vector { - _handler: DMA_OUT_CH0, - }, - Vector { - _handler: DMA_OUT_CH1, - }, - Vector { - _handler: DMA_OUT_CH2, - }, - Vector { _handler: SPI2 }, - Vector { _handler: AES }, - Vector { _handler: SHA }, - Vector { _handler: RSA }, - Vector { _handler: ECC }, -]; -#[doc(hidden)] +#[doc = r" Interrupt numbers, priority levels, and HART IDs."] pub mod interrupt; -pub use self::interrupt::Interrupt; #[doc = "AES (Advanced Encryption Standard) Accelerator"] pub struct AES { _marker: PhantomData<*const ()>, diff --git a/esp32h2/Cargo.toml b/esp32h2/Cargo.toml index f116e9a2e..e7b74e402 100644 --- a/esp32h2/Cargo.toml +++ b/esp32h2/Cargo.toml @@ -28,12 +28,14 @@ bench = false test = false [dependencies] -critical-section = { version = "1.1.3", optional = true } -vcell = "0.1.3" -defmt = { version = "0.3.8", optional = true } +critical-section = { version = "1.2.0", optional = true } +defmt = { version = "0.3.8", optional = true } +riscv = "0.12.1" +riscv-peripheral = "0.2.0" +vcell = "0.1.3" [features] -default = [] -rt = [] +default = [] +defmt = ["dep:defmt"] impl-register-debug = [] -defmt = ["dep:defmt"] +rt = [] diff --git a/esp32h2/device.x b/esp32h2/device.x index d19ce8ed4..91bef3929 100644 --- a/esp32h2/device.x +++ b/esp32h2/device.x @@ -1,3 +1,23 @@ +/* Core interrupt sources and trap handlers */ +PROVIDE(UserSoft = DefaultHandler); +PROVIDE(_start_UserSoft_trap = _start_DefaultHandler_trap); +PROVIDE(SupervisorSoft = DefaultHandler); +PROVIDE(_start_SupervisorSoft_trap = _start_DefaultHandler_trap); +PROVIDE(MachineSoft = DefaultHandler); +PROVIDE(_start_MachineSoft_trap = _start_DefaultHandler_trap); +PROVIDE(UserTimer = DefaultHandler); +PROVIDE(_start_UserTimer_trap = _start_DefaultHandler_trap); +PROVIDE(SupervisorTimer = DefaultHandler); +PROVIDE(_start_SupervisorTimer_trap = _start_DefaultHandler_trap); +PROVIDE(MachineTimer = DefaultHandler); +PROVIDE(_start_MachineTimer_trap = _start_DefaultHandler_trap); +PROVIDE(UserExternal = DefaultHandler); +PROVIDE(_start_UserExternal_trap = _start_DefaultHandler_trap); +PROVIDE(SupervisorExternal = DefaultHandler); +PROVIDE(_start_SupervisorExternal_trap = _start_DefaultHandler_trap); +PROVIDE(MachineExternal = DefaultHandler); +PROVIDE(_start_MachineExternal_trap = _start_DefaultHandler_trap); +/* External interrupt sources */ PROVIDE(PMU = DefaultHandler); PROVIDE(EFUSE = DefaultHandler); PROVIDE(LP_RTC_TIMER = DefaultHandler); diff --git a/esp32h2/settings.yaml b/esp32h2/settings.yaml new file mode 100644 index 000000000..4a1cd6740 --- /dev/null +++ b/esp32h2/settings.yaml @@ -0,0 +1,81 @@ +riscv_config: + core_interrupts: + - name: "UserSoft" + value: 0 + description: "User Software Interrupt" + - name: "SupervisorSoft" + value: 1 + description: "Supervisor Software Interrupt" + - name: "MachineSoft" + value: 3 + description: "Machine Software Interrupt" + - name: "UserTimer" + value: 4 + description: "User Timer Interrupt" + - name: "SupervisorTimer" + value: 5 + description: "Supervisor Timer Interrupt" + - name: "MachineTimer" + value: 7 + description: "Machine Timer Interrupt" + - name: "UserExternal" + value: 8 + description: "User External Interrupt" + - name: "SupervisorExternal" + value: 9 + description: "Supervisor External Interrupt" + - name: "MachineExternal" + value: 11 + description: "Machine External Interrupt" + + priorities: + - name: "P1" + value: 1 + description: "Priority level 1" + - name: "P2" + value: 2 + description: "Priority level 2" + - name: "P3" + value: 3 + description: "Priority level 3" + - name: "P4" + value: 4 + description: "Priority level 4" + - name: "P5" + value: 5 + description: "Priority level 5" + - name: "P6" + value: 6 + description: "Priority level 6" + - name: "P7" + value: 7 + description: "Priority level 7" + - name: "P8" + value: 8 + description: "Priority level 8" + - name: "P9" + value: 9 + description: "Priority level 9" + - name: "P10" + value: 10 + description: "Priority level 10" + - name: "P11" + value: 11 + description: "Priority level 11" + - name: "P12" + value: 12 + description: "Priority level 12" + - name: "P13" + value: 13 + description: "Priority level 13" + - name: "P14" + value: 14 + description: "Priority level 14" + - name: "P15" + value: 15 + description: "Priority level 15" + + harts: + - name: "H0" + value: 0 + description: "Hart 0" diff --git a/esp32h2/src/interrupt.rs b/esp32h2/src/interrupt.rs index 924f3098e..a10b0c203 100644 --- a/esp32h2/src/interrupt.rs +++ b/esp32h2/src/interrupt.rs @@ -1,8 +1,96 @@ -#[doc = r"Enumeration of all the interrupts."] +#[doc = r" Core interrupts. These interrupts are handled by the core itself."] +# [riscv :: pac_enum (unsafe CoreInterruptNumber)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[repr(u16)] -pub enum Interrupt { +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum CoreInterrupt { + #[doc = "0 - User Software Interrupt"] + UserSoft = 0, + #[doc = "1 - Supervisor Software Interrupt"] + SupervisorSoft = 1, + #[doc = "3 - Machine Software Interrupt"] + MachineSoft = 3, + #[doc = "4 - User Timer Interrupt"] + UserTimer = 4, + #[doc = "5 - Supervisor Timer Interrupt"] + SupervisorTimer = 5, + #[doc = "7 - Machine Timer Interrupt"] + MachineTimer = 7, + #[doc = "8 - User External Interrupt"] + UserExternal = 8, + #[doc = "9 - Supervisor External Interrupt"] + SupervisorExternal = 9, + #[doc = "11 - Machine External Interrupt"] + MachineExternal = 11, +} +pub use riscv::interrupt::Exception; +#[doc = r" Priority levels in the device"] +# [riscv :: pac_enum (unsafe PriorityNumber)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Priority { + #[doc = "1 - Priority level 1"] + P1 = 1, + #[doc = "2 - Priority level 2"] + P2 = 2, + #[doc = "3 - Priority level 3"] + P3 = 3, + #[doc = "4 - Priority level 4"] + P4 = 4, + #[doc = "5 - Priority level 5"] + P5 = 5, + #[doc = "6 - Priority level 6"] + P6 = 6, + #[doc = "7 - Priority level 7"] + P7 = 7, + #[doc = "8 - Priority level 8"] + P8 = 8, + #[doc = "9 - Priority level 9"] + P9 = 9, + #[doc = "10 - Priority level 10"] + P10 = 10, + #[doc = "11 - Priority level 11"] + P11 = 11, + #[doc = "12 - Priority level 12"] + P12 = 12, + #[doc = "13 - Priority level 13"] + P13 = 13, + #[doc = "14 - Priority level 14"] + P14 = 14, + #[doc = "15 - Priority level 15"] + P15 = 15, +} +#[doc = r" HARTs in the device"] +# [riscv :: pac_enum (unsafe HartIdNumber)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Hart { + #[doc = "0 - Hart 0"] + H0 = 0, +} +pub use riscv::{ + interrupt::{disable, enable, free, nested}, + ExceptionNumber, HartIdNumber, InterruptNumber, PriorityNumber, +}; +pub type Trap = riscv::interrupt::Trap; +#[doc = r" Retrieves the cause of a trap in the current hart."] +#[doc = r""] +#[doc = r" If the raw cause is not a valid interrupt or exception for the target, it returns an error."] +#[inline] +pub fn try_cause() -> riscv::result::Result { + riscv::interrupt::try_cause() +} +#[doc = r" Retrieves the cause of a trap in the current hart (machine mode)."] +#[doc = r""] +#[doc = r" If the raw cause is not a valid interrupt or exception for the target, it panics."] +#[inline] +pub fn cause() -> Trap { + try_cause().unwrap() +} +#[doc = r" External interrupts. These interrupts are handled by the external peripherals."] +# [riscv :: pac_enum (unsafe ExternalInterruptNumber)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ExternalInterrupt { #[doc = "0 - PMU"] PMU = 0, #[doc = "1 - EFUSE"] @@ -134,119 +222,3 @@ pub enum Interrupt { #[doc = "64 - ECDSA"] ECDSA = 64, } -#[doc = r" TryFromInterruptError"] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[derive(Debug, Copy, Clone)] -pub struct TryFromInterruptError(()); -impl Interrupt { - #[doc = r" Attempt to convert a given value into an `Interrupt`"] - #[inline] - pub fn try_from(value: u8) -> Result { - match value { - 0 => Ok(Interrupt::PMU), - 1 => Ok(Interrupt::EFUSE), - 2 => Ok(Interrupt::LP_RTC_TIMER), - 3 => Ok(Interrupt::LP_BLE_TIMER), - 4 => Ok(Interrupt::LP_WDT), - 5 => Ok(Interrupt::LP_PERI_TIMEOUT), - 6 => Ok(Interrupt::LP_APM_M0), - 7 => Ok(Interrupt::FROM_CPU_INTR0), - 8 => Ok(Interrupt::FROM_CPU_INTR1), - 9 => Ok(Interrupt::FROM_CPU_INTR2), - 10 => Ok(Interrupt::FROM_CPU_INTR3), - 11 => Ok(Interrupt::ASSIST_DEBUG), - 12 => Ok(Interrupt::TRACE), - 13 => Ok(Interrupt::CACHE), - 14 => Ok(Interrupt::CPU_PERI_TIMEOUT), - 15 => Ok(Interrupt::BT_MAC), - 16 => Ok(Interrupt::BT_BB), - 17 => Ok(Interrupt::BT_BB_NMI), - 18 => Ok(Interrupt::COEX), - 19 => Ok(Interrupt::BLE_TIMER), - 20 => Ok(Interrupt::BLE_SEC), - 21 => Ok(Interrupt::ZB_MAC), - 22 => Ok(Interrupt::GPIO), - 23 => Ok(Interrupt::GPIO_NMI), - 24 => Ok(Interrupt::PAU), - 25 => Ok(Interrupt::HP_PERI_TIMEOUT), - 26 => Ok(Interrupt::HP_APM_M0), - 27 => Ok(Interrupt::HP_APM_M1), - 28 => Ok(Interrupt::HP_APM_M2), - 29 => Ok(Interrupt::HP_APM_M3), - 30 => Ok(Interrupt::MSPI), - 31 => Ok(Interrupt::I2S0), - 32 => Ok(Interrupt::UHCI0), - 33 => Ok(Interrupt::UART0), - 34 => Ok(Interrupt::UART1), - 35 => Ok(Interrupt::LEDC), - 36 => Ok(Interrupt::TWAI0), - 37 => Ok(Interrupt::USB_DEVICE), - 38 => Ok(Interrupt::RMT), - 39 => Ok(Interrupt::I2C_EXT0), - 40 => Ok(Interrupt::I2C_EXT1), - 41 => Ok(Interrupt::TG0_T0_LEVEL), - 42 => Ok(Interrupt::TG0_WDT_LEVEL), - 43 => Ok(Interrupt::TG1_T0_LEVEL), - 44 => Ok(Interrupt::TG1_WDT_LEVEL), - 45 => Ok(Interrupt::SYSTIMER_TARGET0), - 46 => Ok(Interrupt::SYSTIMER_TARGET1), - 47 => Ok(Interrupt::SYSTIMER_TARGET2), - 48 => Ok(Interrupt::APB_ADC), - 49 => Ok(Interrupt::MCPWM0), - 50 => Ok(Interrupt::PCNT), - 51 => Ok(Interrupt::PARL_IO_TX), - 52 => Ok(Interrupt::PARL_IO_RX), - 53 => Ok(Interrupt::DMA_IN_CH0), - 54 => Ok(Interrupt::DMA_IN_CH1), - 55 => Ok(Interrupt::DMA_IN_CH2), - 56 => Ok(Interrupt::DMA_OUT_CH0), - 57 => Ok(Interrupt::DMA_OUT_CH1), - 58 => Ok(Interrupt::DMA_OUT_CH2), - 59 => Ok(Interrupt::SPI2), - 60 => Ok(Interrupt::AES), - 61 => Ok(Interrupt::SHA), - 62 => Ok(Interrupt::RSA), - 63 => Ok(Interrupt::ECC), - 64 => Ok(Interrupt::ECDSA), - _ => Err(TryFromInterruptError(())), - } - } -} -#[cfg(feature = "rt")] -#[macro_export] -#[doc = r" Assigns a handler to an interrupt"] -#[doc = r""] -#[doc = r" This macro takes two arguments: the name of an interrupt and the path to the"] -#[doc = r" function that will be used as the handler of that interrupt. That function"] -#[doc = r" must have signature `fn()`."] -#[doc = r""] -#[doc = r" Optionally, a third argument may be used to declare interrupt local data."] -#[doc = r" The handler will have exclusive access to these *local* variables on each"] -#[doc = r" invocation. If the third argument is used then the signature of the handler"] -#[doc = r" function must be `fn(&mut $NAME::Locals)` where `$NAME` is the first argument"] -#[doc = r" passed to the macro."] -#[doc = r""] -#[doc = r" # Example"] -#[doc = r""] -#[doc = r" ``` ignore"] -#[doc = r" interrupt!(TIM2, periodic);"] -#[doc = r""] -#[doc = r" fn periodic() {"] -#[doc = r#" print!(".");"#] -#[doc = r" }"] -#[doc = r""] -#[doc = r" interrupt!(TIM3, tick, locals: {"] -#[doc = r" tick: bool = false;"] -#[doc = r" });"] -#[doc = r""] -#[doc = r" fn tick(locals: &mut TIM3::Locals) {"] -#[doc = r" locals.tick = !locals.tick;"] -#[doc = r""] -#[doc = r" if locals.tick {"] -#[doc = r#" println!("Tick");"#] -#[doc = r" } else {"] -#[doc = r#" println!("Tock");"#] -#[doc = r" }"] -#[doc = r" }"] -#[doc = r" ```"] -macro_rules ! interrupt { ($ NAME : ident , $ path : path , locals : { $ ($ lvar : ident : $ lty : ty = $ lval : expr ;) * }) => { # [allow (non_snake_case)] mod $ NAME { pub struct Locals { $ (pub $ lvar : $ lty ,) * } } # [allow (non_snake_case)] # [no_mangle] pub extern "C" fn $ NAME () { let _ = $ crate :: interrupt :: Interrupt :: $ NAME ; static mut LOCALS : self :: $ NAME :: Locals = self :: $ NAME :: Locals { $ ($ lvar : $ lval ,) * } ; let f : fn (& mut self :: $ NAME :: Locals) = $ path ; f (unsafe { & mut LOCALS }) ; } } ; ($ NAME : ident , $ path : path) => { # [allow (non_snake_case)] # [no_mangle] pub extern "C" fn $ NAME () { let _ = $ crate :: interrupt :: Interrupt :: $ NAME ; let f : fn () = $ path ; f () ; } } } diff --git a/esp32h2/src/lib.rs b/esp32h2/src/lib.rs index 3c147d9c6..748b262ce 100644 --- a/esp32h2/src/lib.rs +++ b/esp32h2/src/lib.rs @@ -11,220 +11,8 @@ pub const NVIC_PRIO_BITS: u8 = 0; use generic::*; #[doc = r"Common register and bit access and modify traits"] pub mod generic; -#[cfg(feature = "rt")] -extern "C" { - fn PMU(); - fn EFUSE(); - fn LP_RTC_TIMER(); - fn LP_BLE_TIMER(); - fn LP_WDT(); - fn LP_PERI_TIMEOUT(); - fn LP_APM_M0(); - fn FROM_CPU_INTR0(); - fn FROM_CPU_INTR1(); - fn FROM_CPU_INTR2(); - fn FROM_CPU_INTR3(); - fn ASSIST_DEBUG(); - fn TRACE(); - fn CACHE(); - fn CPU_PERI_TIMEOUT(); - fn BT_MAC(); - fn BT_BB(); - fn BT_BB_NMI(); - fn COEX(); - fn BLE_TIMER(); - fn BLE_SEC(); - fn ZB_MAC(); - fn GPIO(); - fn GPIO_NMI(); - fn PAU(); - fn HP_PERI_TIMEOUT(); - fn HP_APM_M0(); - fn HP_APM_M1(); - fn HP_APM_M2(); - fn HP_APM_M3(); - fn MSPI(); - fn I2S0(); - fn UHCI0(); - fn UART0(); - fn UART1(); - fn LEDC(); - fn TWAI0(); - fn USB_DEVICE(); - fn RMT(); - fn I2C_EXT0(); - fn I2C_EXT1(); - fn TG0_T0_LEVEL(); - fn TG0_WDT_LEVEL(); - fn TG1_T0_LEVEL(); - fn TG1_WDT_LEVEL(); - fn SYSTIMER_TARGET0(); - fn SYSTIMER_TARGET1(); - fn SYSTIMER_TARGET2(); - fn APB_ADC(); - fn MCPWM0(); - fn PCNT(); - fn PARL_IO_TX(); - fn PARL_IO_RX(); - fn DMA_IN_CH0(); - fn DMA_IN_CH1(); - fn DMA_IN_CH2(); - fn DMA_OUT_CH0(); - fn DMA_OUT_CH1(); - fn DMA_OUT_CH2(); - fn SPI2(); - fn AES(); - fn SHA(); - fn RSA(); - fn ECC(); - fn ECDSA(); -} -#[doc(hidden)] -#[repr(C)] -pub union Vector { - pub _handler: unsafe extern "C" fn(), - pub _reserved: usize, -} -#[cfg(feature = "rt")] -#[doc(hidden)] -#[link_section = ".rwtext"] -#[no_mangle] -pub static __EXTERNAL_INTERRUPTS: [Vector; 65] = [ - Vector { _handler: PMU }, - Vector { _handler: EFUSE }, - Vector { - _handler: LP_RTC_TIMER, - }, - Vector { - _handler: LP_BLE_TIMER, - }, - Vector { _handler: LP_WDT }, - Vector { - _handler: LP_PERI_TIMEOUT, - }, - Vector { - _handler: LP_APM_M0, - }, - Vector { - _handler: FROM_CPU_INTR0, - }, - Vector { - _handler: FROM_CPU_INTR1, - }, - Vector { - _handler: FROM_CPU_INTR2, - }, - Vector { - _handler: FROM_CPU_INTR3, - }, - Vector { - _handler: ASSIST_DEBUG, - }, - Vector { _handler: TRACE }, - Vector { _handler: CACHE }, - Vector { - _handler: CPU_PERI_TIMEOUT, - }, - Vector { _handler: BT_MAC }, - Vector { _handler: BT_BB }, - Vector { - _handler: BT_BB_NMI, - }, - Vector { _handler: COEX }, - Vector { - _handler: BLE_TIMER, - }, - Vector { _handler: BLE_SEC }, - Vector { _handler: ZB_MAC }, - Vector { _handler: GPIO }, - Vector { _handler: GPIO_NMI }, - Vector { _handler: PAU }, - Vector { - _handler: HP_PERI_TIMEOUT, - }, - Vector { - _handler: HP_APM_M0, - }, - Vector { - _handler: HP_APM_M1, - }, - Vector { - _handler: HP_APM_M2, - }, - Vector { - _handler: HP_APM_M3, - }, - Vector { _handler: MSPI }, - Vector { _handler: I2S0 }, - Vector { _handler: UHCI0 }, - Vector { _handler: UART0 }, - Vector { _handler: UART1 }, - Vector { _handler: LEDC }, - Vector { _handler: TWAI0 }, - Vector { - _handler: USB_DEVICE, - }, - Vector { _handler: RMT }, - Vector { _handler: I2C_EXT0 }, - Vector { _handler: I2C_EXT1 }, - Vector { - _handler: TG0_T0_LEVEL, - }, - Vector { - _handler: TG0_WDT_LEVEL, - }, - Vector { - _handler: TG1_T0_LEVEL, - }, - Vector { - _handler: TG1_WDT_LEVEL, - }, - Vector { - _handler: SYSTIMER_TARGET0, - }, - Vector { - _handler: SYSTIMER_TARGET1, - }, - Vector { - _handler: SYSTIMER_TARGET2, - }, - Vector { _handler: APB_ADC }, - Vector { _handler: MCPWM0 }, - Vector { _handler: PCNT }, - Vector { - _handler: PARL_IO_TX, - }, - Vector { - _handler: PARL_IO_RX, - }, - Vector { - _handler: DMA_IN_CH0, - }, - Vector { - _handler: DMA_IN_CH1, - }, - Vector { - _handler: DMA_IN_CH2, - }, - Vector { - _handler: DMA_OUT_CH0, - }, - Vector { - _handler: DMA_OUT_CH1, - }, - Vector { - _handler: DMA_OUT_CH2, - }, - Vector { _handler: SPI2 }, - Vector { _handler: AES }, - Vector { _handler: SHA }, - Vector { _handler: RSA }, - Vector { _handler: ECC }, - Vector { _handler: ECDSA }, -]; -#[doc(hidden)] +#[doc = r" Interrupt numbers, priority levels, and HART IDs."] pub mod interrupt; -pub use self::interrupt::Interrupt; #[doc = "AES (Advanced Encryption Standard) Accelerator"] pub struct AES { _marker: PhantomData<*const ()>,