Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
18 years ago

Interrupts

Hello All,

I have several sources of interrupt, mostly with the same priority. When one occurs and the ISR is entered then all other interrupts of the same (or lower) priority are blocked until that ISR is exited. I'd like to be able to allow other interrupts of the same priority to occur during the ISR. Is there a software method to do this?

Reason: I have a program that runs processing foreground stuff and servicing interrupts as they occur. At some point I want to suspend the foreground processing but need to keep all the interrupts running. I'm doing this by having a serial Rx interrupt that 'sticks' until another character Rx releases it. This works ok except other interrupts are blocked for this period.

I know I could achieve this by altering the priority of the serial interrupt within SOPC builder but that would mean updating the hardware, it would be much easier if I only needed to issue a software update.

Thanks in anticipation.

Banx.

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Banx,

    > I'd like to be able to allow other interrupts of the same priority to occur during the ISR.

    > Is there a software method to do this?

    Interrupt "priority" is purely a software concept -- the controller supports up to

    32 bits -- the order you process them is controlled only by software.

    That said, you can disable the particular interrupt that (as you say) 'sticks' by

    clearing the bit in the ienable control register. After you do this, you can re-enable

    interrupts via PIE. To prevent nesting of the one that 'sticks' your interrupt dispatch

    code can AND the ienable and status register contents -- and use the result to

    determine if you should call the handler. The u-boot code uses this technique. e.g.:<div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    void external_interrupt (struct pt_regs *regs)

    {

    unsigned irqs;

    struct irq_action *act;

    /* evaluate only irqs that are both enabled and pending */

    irqs = rdctl (ctl_ienable) & rdctl (ctl_ipending);

    act = vecs;

    /* Assume (as does the Nios2 HAL) that bit 0 is highest

    * priority. NOTE: There is ALWAYS a handler assigned

    * (the default if no other).

    */

    while (irqs) {

    if (irqs & 1) {

    act->handler (act->arg);

    act->count++;

    }

    irqs >>=1;

    act++;

    }

    }[/b]

    --- Quote End ---

    Regards,

    --Scott
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Scott,

    Thanks for speedy answer.

    Yes, that explained it and I&#39;ve got it working using alt_irq_enable_all() with the appropriate value. Everything works just fine now. I appreciate your help.

    Banx.