I’m trying to set up an isr for a simple pushbutton, not using the metal bsp, but configuring the registers.
This is what I’m doing:
int main(){
int rc;
set_freq_320MHz();
interrupt_enable();
plic_interrupt_enable();
GPIO_REG(GPIO_OUTPUT_EN) |= (1 << variant_pin_map[3].bit_pos);
GPIO_REG(GPIO_INPUT_EN) |= (1 << variant_pin_map[PIN].bit_pos);
unsigned int gpio = variant_pin_map[PIN].bit_pos;
irq_functions[gpio + IRQ_GPIO - 1].active = 1;
irq_functions[gpio + IRQ_GPIO - 1].priority = 7;
irq_functions[gpio + IRQ_GPIO - 1].irq_handler = handler;
PLIC_REG(PLIC_ENABLE_OFFSET) |= (1 << (IRQ_GPIO + gpio));
PLIC_REG(PLIC_PRIORITY_OFFSET + 4 * (IRQ_GPIO + gpio)) = 7;
GPIO_REG(GPIO_FALL_IE) |= (1 << gpio);
while (1)
{
if(taken)
{
GPIO_REG(GPIO_OUTPUT_VAL) ^= (1 << variant_pin_map[3].bit_pos);
taken = 0;
}
wait_timer();
}
return 0;
}
void handler()
{
PLIC_REG(PLIC_ENABLE_OFFSET) &= ~(1 << (IRQ_GPIO + 23));
taken = GPIO_REG(GPIO_FALL_IP);
GPIO_REG(GPIO_FALL_IP) = taken;
PLIC_REG(PLIC_ENABLE_OFFSET) |= (1 << (IRQ_GPIO + 23));
}
The problem is that the GPIO correctly forwards the interrupt to the PLIC (and the plic to the hart) only the first time. I’ve checked every register possible: they are the same before and after the interrupt is correctly handled. The full project is here: Sifive_HiFive_RevB_Projects/src at master · NicolaGiardino/Sifive_HiFive_RevB_Projects · GitHub
This is what I’m doing in the handler:
- Check mcause
- Pass the control to the PLIC handler (Base mode, not vectored)
- Claim the interrupt
- Executing handling function (handler())
- mret