Page 1 of 1

IRQs not working on ARM (Raspberry Pi 2 B)

Posted: Sun Feb 14, 2016 10:52 pm
by TyrelHaveman
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: Select all

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: Select all

.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: Select all

#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?

Re: IRQs not working on ARM (Raspberry Pi 2 B)

Posted: Mon Feb 15, 2016 11:13 am
by Nutterts
It's been way to long since I played around with my Raspberry Pi 2B to really help you. You code looks fine to me. But did you switch to interrupt mode and set a stack before enabling interrupts?

I don't remember where I got it from, it's not mine, but I used this assembly snippet:

Code: Select all

mrs r0, cpsr
bic r0, $0b11111111
orr r0, $0b11010010
msr cpsr, r0
mov sp, $0x4000
bic r0, $0b11111111
orr r0, $0b11010011
msr cpsr, r0

Re: IRQs not working on ARM (Raspberry Pi 2 B)

Posted: Mon Feb 15, 2016 11:23 am
by TyrelHaveman
Nutterts wrote:But did you switch to interrupt mode and set a stack before enabling interrupts?
Thanks for responding. Yes, I did do that:

Code: Select all

// Set stack pointer to 0x7000 for IRQ mode
// switch to IRQ mode
mov r0, #(0x12 | 0x80 | 0x40)
msr cpsr_c, r0

// set stack
mov sp, #0x7000

// go back to supervisor mode
mov r0, #(0x13 | 0x80 | 0x40)
msr cpsr_c, r0
It's perhaps a little more efficient than the code you showed but otherwise appears to be the same.

Re: IRQs not working on ARM (Raspberry Pi 2 B)

Posted: Mon Feb 15, 2016 11:36 am
by Nutterts
Yeah that looks even better. Wish I could help ya.

Re: IRQs not working on ARM (Raspberry Pi 2 B)

Posted: Mon Feb 15, 2016 1:27 pm
by Gigasoft
And what does the interrupt handler look like?