Hello.
I'd like to implement low level interrupts with only cortex-m-rt crate for studying purposes. The program should detect rising/falling edge on pa0 and turn led off. I tried to use example from cortex-m-rt-0.6.13/src/lib.rs line 268 and replaced vector table (__INTERRUPTS) for interrupts with my own, but without much success. Here's my full program. Also I commented out __INTERRUPTS from cortex-m-rt/src/lib.rs file to remove duplicates. I tried to search for examples, but wasn't able to find any. Thank you for help.
Program:
Summary
#![no_std]
#![no_main]
use cortex_m_rt::entry;
use panic_reset as _;
#[entry]
fn main() -> ! {
let nvic: u32 = 0xe000_e100; // NVIC base address. PM0056 page 128
let nvic_iser = nvic as *mut u32; // NVIC_ISER register. nvic + 0x00 (offset).
let nvic_ipr6 = (nvic + 0x0300 + 6) as *mut u8; // NVIC_IPR6 register. nvic + 0x0300 (offset) + 6 (six for exti0)
unsafe {
*nvic_ipr6 = 0x0f; // Setup interrupt priority for sixth vector.
*nvic_iser = 1; // Enabling interrupt
}
let exti = 0x4001_0400; // EXTI base address. RM0008 page 51
let exti_imr = exti as *mut u32; // EXTI_IMR register. exti + 0x00 (offset)
let exti_emr = (exti + 0x04) as *mut u32; // EXTI_EMR register. exti + 0x04 (offset)
unsafe {
*exti_imr &= ! 0x0000_0001; // Masking interrupt request for line 0
*exti_emr &= ! 0x0000_0001; // Masking event request for line 0
}
let rcc = 0x4002_1000; // RCC base address. RM0008 page 50
let apb2enr = (rcc + 0x18) as *mut u32; // APB2ENR register. rcc + 0x18 (offset)
let gpioa = 0x4001_0800; // GPIOA base address;
let gpioa_crl = gpioa as *mut u32; // GPIO_CRL register. gpioa + 0x00 (offset)
unsafe {
*apb2enr |= 0x0000_0015; // Enable afio, gpioa, gpioc clocking
*gpioa_crl &= !0x0000_000f;
*gpioa_crl |= 0x0000_0004; // Setup PA0 as input floating
}
let afio = 0x4001_0000; // AFIO base address. RM0008 page 51.
let afio_exticr1 = (afio + 0x08) as *mut u32; // AFIO_EXTICR1 register. afio + 0x08 (offset)
unsafe {
*afio_exticr1 &= !0x0000_0000;
*afio_exticr1 |= 0x0000_0000; // Select PA0 as source input for EXTI0
}
let exti_rtsr = (exti + 0x08) as *mut u32; // EXTI_RTSR register. exti + 0x08 (offset)
let exti_ftsr = (exti + 0x0c) as *mut u32; // EXTI_RTSR register. exti + 0x0c (offset)
unsafe {
*exti_rtsr |= 0x0000_0001; // Enable rising trigger interrupt for input line 0
*exti_ftsr |= 0x0000_0001; // Enable falling trigger interrupt for input line 0
*exti_imr |= 0x0000_0001; // Unmasking interrupt request for line 0
}
let gpioc_crh = 0x4001_1004 as *mut u32; // GPIOC_CRH register
unsafe {
*gpioc_crh &= !0x00F0_0000;
*gpioc_crh |= 0x0020_0000; // Setup PC13 as output
};
loop {
}
}
pub union Vector {
handler: fn(),
reserved: usize,
}
//declare handler function for default interrupts
fn default_handler() {
}
// decalre handler function for exti0 interrupt
fn exti0() {
let bsrr = 0x4001_1010 as *mut u32; // GPIOC_BSRR register
unsafe {
*bsrr = 0x2000; // Set PC13 high
}
}
// Replacing vector table from cortex-m-rt v0.6.13 file line 709
#[link_section = ".vector_table.interrupts"]
#[no_mangle]
pub static __INTERRUPTS: [Vector; 60] = [
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: exti0 },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
Vector { handler: default_handler },
];