rp/gpio: set up gpio interrupts only once

doing this setup work repeatedly, on every wait, is unnecessary. with
nothing ever disabling the interrupt it is sufficient to enable it once
during device init and never touch it again.
This commit is contained in:
pennae
2023-05-02 08:39:05 +02:00
parent 8fc92fdf62
commit 849011b826
4 changed files with 75 additions and 7 deletions

View File

@ -136,6 +136,13 @@ pub enum InterruptTrigger {
AnyEdge,
}
pub(crate) unsafe fn init() {
let irq = interrupt::IO_IRQ_BANK0::steal();
irq.disable();
irq.set_priority(interrupt::Priority::P3);
irq.enable();
}
#[interrupt]
unsafe fn IO_IRQ_BANK0() {
let cpu = SIO.cpuid().read() as usize;
@ -179,10 +186,6 @@ impl<'d, T: Pin> InputFuture<'d, T> {
pub fn new(pin: impl Peripheral<P = T> + 'd, level: InterruptTrigger) -> Self {
into_ref!(pin);
unsafe {
let irq = interrupt::IO_IRQ_BANK0::steal();
irq.disable();
irq.set_priority(interrupt::Priority::P3);
let pin_group = (pin.pin() % 8) as usize;
// first, clear the INTR register bits. without this INTR will still
// contain reports of previous edges, causing the IRQ to fire early
@ -221,8 +224,6 @@ impl<'d, T: Pin> InputFuture<'d, T> {
w.set_edge_low(pin_group, true);
}
});
irq.enable();
}
Self { pin, level }

View File

@ -157,6 +157,7 @@ pub fn init(_config: config::Config) -> Peripherals {
timer::init();
dma::init();
pio::init();
gpio::init();
}
peripherals

View File

@ -33,7 +33,7 @@ use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
use crate::interrupt::{Interrupt, InterruptExt};
use crate::peripherals::CORE1;
use crate::{interrupt, pac};
use crate::{gpio, interrupt, pac};
const PAUSE_TOKEN: u32 = 0xDEADBEEF;
const RESUME_TOKEN: u32 = !0xDEADBEEF;
@ -68,6 +68,9 @@ fn install_stack_guard(stack_bottom: *mut usize) {
#[inline(always)]
fn core1_setup(stack_bottom: *mut usize) {
install_stack_guard(stack_bottom);
unsafe {
gpio::init();
}
}
/// Data type for a properly aligned stack of N bytes