Quote:
TLDR:Interrupts are being enabled and the ARM timer is generating interrupts. My interrupt handler is callable. But the interrupts are not calling my interrupt handler.
Hey guys,
I've been having trouble getting IRQs to work on my Raspberry Pi 2 B.
I set the IRQ vector (#6) at the start of memory to 0xe59ff018, which is
ldr pc, [pc, #24], which is a common way to do it on ARM to make it load the address 24 bytes ahead of the next instruction into the pc, to cause it to run. So I have the address of my interrupt handler stored there.
I can confirm that this instruction and the address are correct by calling it like this:
Code:
typedef void (*fptr)(void);
fptr v = (fptr)24;
(*v)();
This definitely results in my handler getting called (I'm outputting Morse code on an LED to tell me what's going on).
So you would think that if I enable interrupts and something to cause an interrupt, that would get called.
Here's the function for enabling interrupts:
Code:
.global enable_interrupts
enable_interrupts:
mrs r0, cpsr
bic r0, r0, #0x80
msr cpsr_c, r0
mov pc, lr
Here's the code to enable the ARM timer and it interrupts (note that my mmio_write function is adding the base 0x3F000000 for Raspi 2 to addresses):
Code:
#define PIC_BASE 0xB200
#define PIC_ENABLE_BASIC_IRQ PIC_BASE+(4*6)
#define IRQ_ARM_TIMER_BIT 0
#define ARM_TIMER_BASE 0xB400
#define ARM_TIMER_LOAD ARM_TIMER_BASE
#define ARM_TIMER_CTRL ARM_TIMER_BASE+(4*2)
#define ARM_TIMER_CTRL_32BIT (1<<1)
#define ARM_TIMER_CTRL_ENABLE (1<<7)
#define ARM_TIMER_CTRL_IRQ_ENABLE (1<<5)
#define ARM_TIMER_CTRL_PRESCALE_256 (2<<2)
enable_interrupts();
mmio_write(PIC_ENABLE_BASIC_IRQ, 1 << IRQ_ARM_TIMER_BIT);
mmio_write(ARM_TIMER_LOAD, 0x400);
send(led, "GO");
mmio_write(ARM_TIMER_CTRL, ARM_TIMER_CTRL_32BIT | ARM_TIMER_CTRL_ENABLE | ARM_TIMER_CTRL_IRQ_ENABLE | ARM_TIMER_CTRL_PRESCALE_256);
while (1) {
sendText(led, "SOS");
}
I know that the mmio_write is working because I use it for the LED. In addition, the timer DOES get enabled here in the last mmio_write. I can tell that because something does happen: the machine stops running after a little while (the timer isn't running very often). If I comment out that last call to mmio_write, then it keeps sending my "SOS" over and over forever.
So, in summary: Interrupts are being enabled and the ARM timer is generating interrupts. My interrupt handler is callable. But the interrupts are not calling my interrupt handler.
Any thoughts on why this might be?