From 1aa792e64fcdfa787c4e7b13b821ea6f6cf2630e Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Sun, 1 Sep 2024 16:49:51 +0100 Subject: [PATCH] Upgrade powman_test to work on RISC-V and Arm. Interrupt priorities aren't supported yet, but handling a POWMAN timer IRQ from our new default MachineExternal interrupt handler seems to work OK. I also fixed the RISC-V WFE (or "block") instruction. --- rp235x-hal-examples/riscv_examples.txt | 1 + rp235x-hal-examples/rp235x_riscv.x | 45 ++ rp235x-hal-examples/src/bin/powman_test.rs | 59 +-- rp235x-hal/src/arch.rs | 458 ++++++++++++++++++++- 4 files changed, 509 insertions(+), 54 deletions(-) diff --git a/rp235x-hal-examples/riscv_examples.txt b/rp235x-hal-examples/riscv_examples.txt index 9dc23f7b0..adda18eaa 100644 --- a/rp235x-hal-examples/riscv_examples.txt +++ b/rp235x-hal-examples/riscv_examples.txt @@ -17,6 +17,7 @@ pio_dma pio_proc_blink pio_side_set pio_synchronized +powman_test pwm_blink pwm_blink_embedded_hal_1 rom_funcs diff --git a/rp235x-hal-examples/rp235x_riscv.x b/rp235x-hal-examples/rp235x_riscv.x index ac355eab4..aa2ce9d1f 100644 --- a/rp235x-hal-examples/rp235x_riscv.x +++ b/rp235x-hal-examples/rp235x_riscv.x @@ -80,6 +80,51 @@ PROVIDE(__pre_init = default_pre_init); /* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */ PROVIDE(_setup_interrupts = default_setup_interrupts); +PROVIDE(TIMER0_IRQ_0 = DefaultIrqHandler); +PROVIDE(TIMER0_IRQ_1 = DefaultIrqHandler); +PROVIDE(TIMER0_IRQ_2 = DefaultIrqHandler); +PROVIDE(TIMER0_IRQ_3 = DefaultIrqHandler); +PROVIDE(TIMER1_IRQ_0 = DefaultIrqHandler); +PROVIDE(TIMER1_IRQ_1 = DefaultIrqHandler); +PROVIDE(TIMER1_IRQ_2 = DefaultIrqHandler); +PROVIDE(TIMER1_IRQ_3 = DefaultIrqHandler); +PROVIDE(PWM_IRQ_WRAP_0 = DefaultIrqHandler); +PROVIDE(PWM_IRQ_WRAP_1 = DefaultIrqHandler); +PROVIDE(DMA_IRQ_0 = DefaultIrqHandler); +PROVIDE(DMA_IRQ_1 = DefaultIrqHandler); +PROVIDE(DMA_IRQ_2 = DefaultIrqHandler); +PROVIDE(DMA_IRQ_3 = DefaultIrqHandler); +PROVIDE(USBCTRL_IRQ = DefaultIrqHandler); +PROVIDE(PIO0_IRQ_0 = DefaultIrqHandler); +PROVIDE(PIO0_IRQ_1 = DefaultIrqHandler); +PROVIDE(PIO1_IRQ_0 = DefaultIrqHandler); +PROVIDE(PIO1_IRQ_1 = DefaultIrqHandler); +PROVIDE(PIO2_IRQ_0 = DefaultIrqHandler); +PROVIDE(PIO2_IRQ_1 = DefaultIrqHandler); +PROVIDE(IO_IRQ_BANK0 = DefaultIrqHandler); +PROVIDE(IO_IRQ_BANK0_NS = DefaultIrqHandler); +PROVIDE(IO_IRQ_QSPI = DefaultIrqHandler); +PROVIDE(IO_IRQ_QSPI_NS = DefaultIrqHandler); +PROVIDE(SIO_IRQ_FIFO = DefaultIrqHandler); +PROVIDE(SIO_IRQ_BELL = DefaultIrqHandler); +PROVIDE(SIO_IRQ_FIFO_NS = DefaultIrqHandler); +PROVIDE(SIO_IRQ_BELL_NS = DefaultIrqHandler); +PROVIDE(SIO_IRQ_MTIMECMP = DefaultIrqHandler); +PROVIDE(CLOCKS_IRQ = DefaultIrqHandler); +PROVIDE(SPI0_IRQ = DefaultIrqHandler); +PROVIDE(SPI1_IRQ = DefaultIrqHandler); +PROVIDE(UART0_IRQ = DefaultIrqHandler); +PROVIDE(UART1_IRQ = DefaultIrqHandler); +PROVIDE(ADC_IRQ_FIFO = DefaultIrqHandler); +PROVIDE(I2C0_IRQ = DefaultIrqHandler); +PROVIDE(I2C1_IRQ = DefaultIrqHandler); +PROVIDE(OTP_IRQ = DefaultIrqHandler); +PROVIDE(TRNG_IRQ = DefaultIrqHandler); +PROVIDE(PLL_SYS_IRQ = DefaultIrqHandler); +PROVIDE(PLL_USB_IRQ = DefaultIrqHandler); +PROVIDE(POWMAN_IRQ_POW = DefaultIrqHandler); +PROVIDE(POWMAN_IRQ_TIMER = DefaultIrqHandler); + /* # Multi-processing hook function fn _mp_hook() -> bool; diff --git a/rp235x-hal-examples/src/bin/powman_test.rs b/rp235x-hal-examples/src/bin/powman_test.rs index 80a517ee0..84faa5150 100644 --- a/rp235x-hal-examples/src/bin/powman_test.rs +++ b/rp235x-hal-examples/src/bin/powman_test.rs @@ -13,9 +13,6 @@ use rp235x_hal::{ uart::{DataBits, StopBits, UartConfig, UartPeripheral}, }; -use cortex_m_rt::exception; -use pac::interrupt; - // Some traits we need use core::fmt::Write; use hal::fugit::RateExtU32; @@ -67,7 +64,7 @@ impl GlobalUart { /// Entry point to our bare-metal application. /// -/// The `#[hal::entry]` macro ensures the Cortex-M start-up code calls this function +/// The `#[hal::entry]` macro ensures the start-up code calls this function /// as soon as all global variables and the spinlock are initialised. /// /// The function configures the rp235x peripherals, then writes to the UART in @@ -76,11 +73,6 @@ impl GlobalUart { fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); - let mut cp = cortex_m::Peripherals::take().unwrap(); - - // Enable the cycle counter - cp.DCB.enable_trace(); - cp.DWT.enable_cycle_counter(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); @@ -99,6 +91,8 @@ fn main() -> ! { // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); + let mut mtimer = sio.machine_timer; + mtimer.set_enabled(true); // Set the pins to their default state let pins = gpio::Pins::new( @@ -131,29 +125,32 @@ fn main() -> ! { _ = writeln!(&GLOBAL_UART, "AOT time: 0x{:016x}", powman.aot_get_time()); unsafe { - cortex_m::peripheral::NVIC::unmask(pac::Interrupt::POWMAN_IRQ_TIMER); + hal::arch::enable_irq(pac::Interrupt::POWMAN_IRQ_TIMER); + hal::arch::interrupt_enable(); } _ = writeln!(&GLOBAL_UART, "Starting AOT..."); powman.aot_start(); // we don't know what oscillator we're on, so give it time to start whatever it is - cortex_m::asm::delay(150_000); + for _ in 0..150_000 { + hal::arch::nop(); + } print_aot_status(&mut powman); rollover_test(&mut powman); - loop_test(&mut powman); + loop_test(&mut powman, &mtimer); alarm_test(&mut powman); let source = AotClockSource::Xosc(FractionalFrequency::from_hz(12_000_000)); _ = writeln!(&GLOBAL_UART, "Switching AOT to {}", source); powman.aot_set_clock(source).expect("selecting XOSC"); print_aot_status(&mut powman); - loop_test(&mut powman); + loop_test(&mut powman, &mtimer); let source = AotClockSource::Lposc(FractionalFrequency::from_hz(32768)); _ = writeln!(&GLOBAL_UART, "Switching AOT to {}", source); powman.aot_set_clock(source).expect("selecting LPOSC"); print_aot_status(&mut powman); - loop_test(&mut powman); + loop_test(&mut powman, &mtimer); _ = writeln!(&GLOBAL_UART, "Rebooting now"); @@ -202,7 +199,7 @@ fn rollover_test(powman: &mut Powman) { } /// In this function, we see how long it takes to pass a certain number of ticks. -fn loop_test(powman: &mut Powman) { +fn loop_test(powman: &mut Powman, mtimer: &hal::sio::MachineTimer) { let start_loop = 0; let end_loop = 2_000; // 2 seconds _ = writeln!( @@ -214,24 +211,24 @@ fn loop_test(powman: &mut Powman) { powman.aot_set_time(start_loop); powman.aot_start(); - let start_clocks = cortex_m::peripheral::DWT::cycle_count(); + let start_clocks = mtimer.read(); loop { let now = powman.aot_get_time(); if now == end_loop { break; } } - let end_clocks = cortex_m::peripheral::DWT::cycle_count(); - // Compare our AOT against our CPU clock speed + let end_clocks = mtimer.read(); + // Compare our AOT against our Machine Timer let delta_clocks = end_clocks.wrapping_sub(start_clocks) as u64; let delta_ticks = end_loop - start_loop; let cycles_per_tick = delta_clocks / delta_ticks; - // Assume we're running at 150 MHz - let ms_per_tick = (cycles_per_tick as f32 * 1000.0) / 150_000_000.0; + // Assume we're running at 1 MHz MTimer + let ms_per_tick = (cycles_per_tick as f32 * 1000.0) / 1_000_000.0; let percent = ((ms_per_tick - 1.0) / 1.0) * 100.0; _ = writeln!( &GLOBAL_UART, - "Loop complete ... {delta_ticks} ticks in {delta_clocks} CPU clock cycles = {cycles_per_tick} cycles/tick ~= {ms_per_tick} ms/tick ({percent:.3}%)", + "Loop complete ... {delta_ticks} ticks in {delta_clocks} MTimer cycles = {cycles_per_tick} cycles/tick ~= {ms_per_tick} ms/tick ({percent:.3}%)", ) ; } @@ -258,8 +255,9 @@ fn alarm_test(powman: &mut Powman) { &GLOBAL_UART, "Sleeping until alarm (* = wakeup, ! = POWMAN interrupt)...", ); + while !powman.aot_alarm_ringing() { - cortex_m::asm::wfe(); + hal::arch::wfe(); _ = write!(&GLOBAL_UART, "*",); } @@ -278,25 +276,12 @@ fn alarm_test(powman: &mut Powman) { _ = writeln!(&GLOBAL_UART, "Alarm cleared OK"); } -#[interrupt] +#[no_mangle] #[allow(non_snake_case)] fn POWMAN_IRQ_TIMER() { Powman::static_aot_alarm_interrupt_disable(); _ = write!(&GLOBAL_UART, "!"); - cortex_m::asm::sev(); -} - -#[exception] -unsafe fn HardFault(ef: &cortex_m_rt::ExceptionFrame) -> ! { - let _ = writeln!(&GLOBAL_UART, "HARD FAULT:\n{:#?}", ef); - - hal::reboot::reboot( - hal::reboot::RebootKind::BootSel { - msd_disabled: false, - picoboot_disabled: false, - }, - hal::reboot::RebootArch::Normal, - ); + hal::arch::sev(); } #[panic_handler] diff --git a/rp235x-hal/src/arch.rs b/rp235x-hal/src/arch.rs index a87fe9bc6..15ad0c259 100644 --- a/rp235x-hal/src/arch.rs +++ b/rp235x-hal/src/arch.rs @@ -7,7 +7,7 @@ mod inner { pub use cortex_m::asm::{delay, dsb, nop, sev, wfe, wfi}; pub use cortex_m::interrupt::{disable as interrupt_disable, enable as interrupt_enable}; - /// Are interrupts current enabled? + /// Are interrupts currently enabled? pub fn interrupts_enabled() -> bool { cortex_m::register::primask::read().is_active() } @@ -31,14 +31,51 @@ mod inner { } t } + + /// Placeholder function to check if an IRQ is pending + pub fn check_irq_pending(irq: rp235x_pac::Interrupt) -> bool { + cortex_m::peripheral::NVIC::is_pending(irq) + } + + /// Placeholder function to enable an IRQ + /// + /// This function is unsafe because it can break mask-based critical sections. + pub unsafe fn enable_irq(irq: rp235x_pac::Interrupt) { + unsafe { cortex_m::peripheral::NVIC::unmask(irq) } + } + + /// Placeholder function to disable an IRQ + pub fn disable_irq(irq: rp235x_pac::Interrupt) { + cortex_m::peripheral::NVIC::mask(irq) + } + + /// Placeholder function to check if an IRQ is enabled + pub fn is_irq_enabled(irq: rp235x_pac::Interrupt) -> bool { + cortex_m::peripheral::NVIC::is_enabled(irq) + } + + /// Placeholder function to mark an IRQ as pending + pub fn set_pending(irq: rp235x_pac::Interrupt) { + cortex_m::peripheral::NVIC::pend(irq) + } } #[cfg(all(target_arch = "riscv32", target_os = "none"))] mod inner { pub use riscv::asm::{delay, nop, wfi}; - pub use riscv::interrupt::machine::{ - disable as interrupt_disable, enable as interrupt_enable, free as interrupt_free, - }; + pub use riscv::interrupt::machine::{disable as interrupt_disable, free as interrupt_free}; + + /// Enable interrupts + /// + /// Our version is sure to enable Machine External interrupt as well as the + /// global interrupt flag. + #[inline(always)] + pub fn interrupt_enable() { + unsafe { + riscv::register::mie::set_mext(); + riscv::interrupt::machine::enable(); + } + } /// Send Event #[inline(always)] @@ -50,18 +87,10 @@ mod inner { } /// Wait for Event - /// - /// This is the interrupt-safe version of WFI. pub fn wfe() { - let active = interrupts_enabled(); - if active { - interrupt_disable(); - } - wfi(); - if active { - unsafe { - interrupt_enable(); - } + unsafe { + // This is how h3.block is encoded. + core::arch::asm!("slt x0, x0, x0"); } } @@ -73,11 +102,385 @@ mod inner { core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst); } - /// Are interrupts current enabled? + /// Are interrupts currently enabled? #[inline(always)] pub fn interrupts_enabled() -> bool { riscv::register::mstatus::read().mie() } + + pub use crate::xh3irq::{ + check_irq_pending, disable_irq, enable_irq, is_irq_enabled, set_pending, + }; + + #[no_mangle] + #[allow(non_snake_case)] + fn MachineExternal() { + loop { + let Some(irq) = crate::xh3irq::get_next_interrupt() else { + return; + }; + match irq { + rp235x_pac::Interrupt::TIMER0_IRQ_0 => { + extern "Rust" { + fn TIMER0_IRQ_0(); + } + unsafe { + TIMER0_IRQ_0(); + } + } + rp235x_pac::Interrupt::TIMER0_IRQ_1 => { + extern "Rust" { + fn TIMER0_IRQ_1(); + } + unsafe { + TIMER0_IRQ_1(); + } + } + rp235x_pac::Interrupt::TIMER0_IRQ_2 => { + extern "Rust" { + fn TIMER0_IRQ_2(); + } + unsafe { + TIMER0_IRQ_2(); + } + } + rp235x_pac::Interrupt::TIMER0_IRQ_3 => { + extern "Rust" { + fn TIMER0_IRQ_3(); + } + unsafe { + TIMER0_IRQ_3(); + } + } + rp235x_pac::Interrupt::TIMER1_IRQ_0 => { + extern "Rust" { + fn TIMER1_IRQ_0(); + } + unsafe { + TIMER1_IRQ_0(); + } + } + rp235x_pac::Interrupt::TIMER1_IRQ_1 => { + extern "Rust" { + fn TIMER1_IRQ_1(); + } + unsafe { + TIMER1_IRQ_1(); + } + } + rp235x_pac::Interrupt::TIMER1_IRQ_2 => { + extern "Rust" { + fn TIMER1_IRQ_2(); + } + unsafe { + TIMER1_IRQ_2(); + } + } + rp235x_pac::Interrupt::TIMER1_IRQ_3 => { + extern "Rust" { + fn TIMER1_IRQ_3(); + } + unsafe { + TIMER1_IRQ_3(); + } + } + rp235x_pac::Interrupt::PWM_IRQ_WRAP_0 => { + extern "Rust" { + fn PWM_IRQ_WRAP_0(); + } + unsafe { + PWM_IRQ_WRAP_0(); + } + } + rp235x_pac::Interrupt::PWM_IRQ_WRAP_1 => { + extern "Rust" { + fn PWM_IRQ_WRAP_1(); + } + unsafe { + PWM_IRQ_WRAP_1(); + } + } + rp235x_pac::Interrupt::DMA_IRQ_0 => { + extern "Rust" { + fn DMA_IRQ_0(); + } + unsafe { + DMA_IRQ_0(); + } + } + rp235x_pac::Interrupt::DMA_IRQ_1 => { + extern "Rust" { + fn DMA_IRQ_1(); + } + unsafe { + DMA_IRQ_1(); + } + } + rp235x_pac::Interrupt::DMA_IRQ_2 => { + extern "Rust" { + fn DMA_IRQ_2(); + } + unsafe { + DMA_IRQ_2(); + } + } + rp235x_pac::Interrupt::DMA_IRQ_3 => { + extern "Rust" { + fn DMA_IRQ_3(); + } + unsafe { + DMA_IRQ_3(); + } + } + rp235x_pac::Interrupt::USBCTRL_IRQ => { + extern "Rust" { + fn USBCTRL_IRQ(); + } + unsafe { + USBCTRL_IRQ(); + } + } + rp235x_pac::Interrupt::PIO0_IRQ_0 => { + extern "Rust" { + fn PIO0_IRQ_0(); + } + unsafe { + PIO0_IRQ_0(); + } + } + rp235x_pac::Interrupt::PIO0_IRQ_1 => { + extern "Rust" { + fn PIO0_IRQ_1(); + } + unsafe { + PIO0_IRQ_1(); + } + } + rp235x_pac::Interrupt::PIO1_IRQ_0 => { + extern "Rust" { + fn PIO1_IRQ_0(); + } + unsafe { + PIO1_IRQ_0(); + } + } + rp235x_pac::Interrupt::PIO1_IRQ_1 => { + extern "Rust" { + fn PIO1_IRQ_1(); + } + unsafe { + PIO1_IRQ_1(); + } + } + rp235x_pac::Interrupt::PIO2_IRQ_0 => { + extern "Rust" { + fn PIO2_IRQ_0(); + } + unsafe { + PIO2_IRQ_0(); + } + } + rp235x_pac::Interrupt::PIO2_IRQ_1 => { + extern "Rust" { + fn PIO2_IRQ_1(); + } + unsafe { + PIO2_IRQ_1(); + } + } + rp235x_pac::Interrupt::IO_IRQ_BANK0 => { + extern "Rust" { + fn IO_IRQ_BANK0(); + } + unsafe { + IO_IRQ_BANK0(); + } + } + rp235x_pac::Interrupt::IO_IRQ_BANK0_NS => { + extern "Rust" { + fn IO_IRQ_BANK0_NS(); + } + unsafe { + IO_IRQ_BANK0_NS(); + } + } + rp235x_pac::Interrupt::IO_IRQ_QSPI => { + extern "Rust" { + fn IO_IRQ_QSPI(); + } + unsafe { + IO_IRQ_QSPI(); + } + } + rp235x_pac::Interrupt::IO_IRQ_QSPI_NS => { + extern "Rust" { + fn IO_IRQ_QSPI_NS(); + } + unsafe { + IO_IRQ_QSPI_NS(); + } + } + rp235x_pac::Interrupt::SIO_IRQ_FIFO => { + extern "Rust" { + fn SIO_IRQ_FIFO(); + } + unsafe { + SIO_IRQ_FIFO(); + } + } + rp235x_pac::Interrupt::SIO_IRQ_BELL => { + extern "Rust" { + fn SIO_IRQ_BELL(); + } + unsafe { + SIO_IRQ_BELL(); + } + } + rp235x_pac::Interrupt::SIO_IRQ_FIFO_NS => { + extern "Rust" { + fn SIO_IRQ_FIFO_NS(); + } + unsafe { + SIO_IRQ_FIFO_NS(); + } + } + rp235x_pac::Interrupt::SIO_IRQ_BELL_NS => { + extern "Rust" { + fn SIO_IRQ_BELL_NS(); + } + unsafe { + SIO_IRQ_BELL_NS(); + } + } + rp235x_pac::Interrupt::SIO_IRQ_MTIMECMP => { + extern "Rust" { + fn SIO_IRQ_MTIMECMP(); + } + unsafe { + SIO_IRQ_MTIMECMP(); + } + } + rp235x_pac::Interrupt::CLOCKS_IRQ => { + extern "Rust" { + fn CLOCKS_IRQ(); + } + unsafe { + CLOCKS_IRQ(); + } + } + rp235x_pac::Interrupt::SPI0_IRQ => { + extern "Rust" { + fn SPI0_IRQ(); + } + unsafe { + SPI0_IRQ(); + } + } + rp235x_pac::Interrupt::SPI1_IRQ => { + extern "Rust" { + fn SPI1_IRQ(); + } + unsafe { + SPI1_IRQ(); + } + } + rp235x_pac::Interrupt::UART0_IRQ => { + extern "Rust" { + fn UART0_IRQ(); + } + unsafe { + UART0_IRQ(); + } + } + rp235x_pac::Interrupt::UART1_IRQ => { + extern "Rust" { + fn UART1_IRQ(); + } + unsafe { + UART1_IRQ(); + } + } + rp235x_pac::Interrupt::ADC_IRQ_FIFO => { + extern "Rust" { + fn ADC_IRQ_FIFO(); + } + unsafe { + ADC_IRQ_FIFO(); + } + } + rp235x_pac::Interrupt::I2C0_IRQ => { + extern "Rust" { + fn I2C0_IRQ(); + } + unsafe { + I2C0_IRQ(); + } + } + rp235x_pac::Interrupt::I2C1_IRQ => { + extern "Rust" { + fn I2C1_IRQ(); + } + unsafe { + I2C1_IRQ(); + } + } + rp235x_pac::Interrupt::OTP_IRQ => { + extern "Rust" { + fn OTP_IRQ(); + } + unsafe { + OTP_IRQ(); + } + } + rp235x_pac::Interrupt::TRNG_IRQ => { + extern "Rust" { + fn TRNG_IRQ(); + } + unsafe { + TRNG_IRQ(); + } + } + rp235x_pac::Interrupt::PLL_SYS_IRQ => { + extern "Rust" { + fn PLL_SYS_IRQ(); + } + unsafe { + PLL_SYS_IRQ(); + } + } + rp235x_pac::Interrupt::PLL_USB_IRQ => { + extern "Rust" { + fn PLL_USB_IRQ(); + } + unsafe { + PLL_USB_IRQ(); + } + } + rp235x_pac::Interrupt::POWMAN_IRQ_POW => { + extern "Rust" { + fn POWMAN_IRQ_POW(); + } + unsafe { + POWMAN_IRQ_POW(); + } + } + rp235x_pac::Interrupt::POWMAN_IRQ_TIMER => { + extern "Rust" { + fn POWMAN_IRQ_TIMER(); + } + unsafe { + POWMAN_IRQ_TIMER(); + } + } + } + } + } + + #[no_mangle] + #[allow(non_snake_case)] + unsafe fn DefaultIrqHandler() { + panic!(); + } } #[cfg(not(all(any(target_arch = "arm", target_arch = "riscv32"), target_os = "none")))] @@ -87,7 +490,7 @@ mod inner { /// Placeholder function to enable interrupts pub fn interrupt_enable() {} /// Placeholder function to check if interrupts are enabled - pub fn interrupts_enabled() -> bool { + pub fn interrupt_enabled() -> bool { false } /// Placeholder function to wait for an event @@ -107,6 +510,27 @@ mod inner { pub fn delay(_: u32) {} /// Placeholder function to emit an event pub fn sev() {} + + /// Placeholder function to check if an IRQ is pending + pub fn check_irq_pending(irq: rp235x_pac::Interrupt) -> bool { + false + } + + /// Placeholder function to enable an IRQ + /// + /// This function is unsafe because it can break mask-based critical sections. + pub unsafe fn enable_irq(irq: rp235x_pac::Interrupt) {} + + /// Placeholder function to disable an IRQ + pub fn disable_irq(irq: rp235x_pac::Interrupt) {} + + /// Placeholder function to check if an IRQ is enabled + pub fn is_irq_enabled(irq: rp235x_pac::Interrupt) -> bool { + false + } + + /// Placeholder function to mark an IRQ as pending + pub fn set_pending(irq: rp235x_pac::Interrupt) {} } pub use inner::*;