diff --git a/raven_spn/raven_spn b/raven_spn/raven_spn index c363555..33efa25 100755 Binary files a/raven_spn/raven_spn and b/raven_spn/raven_spn differ diff --git a/raven_spn/src/init.h b/raven_spn/src/init.h index 0e10921..1982cf5 100644 --- a/raven_spn/src/init.h +++ b/raven_spn/src/init.h @@ -45,36 +45,34 @@ void configure_irq(size_t irq_num, function_ptr_t handler, unsigned char prio=1) } void wait_for_spn1_interrupt() { - clear_csr(mie, MIP_MEIP); + // This is a time critical part. It must be ensured that no interrupt is processed between flag checking and wfi. + // Disable interrupts and wait a few more clocks for the instruction to take effect before checking the flag. + asm volatile ("csrrc x0, mie, %0; nop; nop" : : "r"(MIP_MEIP)); while(spn1_hw_interrupt) { - set_csr(mie, MIP_MEIP); - asm("wfi"); - clear_csr(mie, MIP_MEIP); - asm("nop"); + // Enable interrupts and immediately enter wfi. + asm volatile ("csrrs x0, mie, %0; wfi; nop" : : "r"(MIP_MEIP)); + // Disable interrupts again before examine the flag value. + asm volatile ("csrrc x0, mie, %0; nop; nop" : : "r"(MIP_MEIP)); } spn1_hw_interrupt=true; set_csr(mie, MIP_MEIP); } void wait_for_spn2_interrupt() { - clear_csr(mie, MIP_MEIP); + asm volatile ("csrrc x0, mie, %0; nop; nop" : : "r"(MIP_MEIP)); while(spn2_hw_interrupt) { - set_csr(mie, MIP_MEIP); - asm("wfi"); - clear_csr(mie, MIP_MEIP); - asm("nop"); + asm volatile ("csrrs x0, mie, %0; wfi; nop" : : "r"(MIP_MEIP)); + asm volatile ("csrrc x0, mie, %0; nop; nop" : : "r"(MIP_MEIP)); } spn2_hw_interrupt=true; set_csr(mie, MIP_MEIP); } void wait_for_spn_interrupts() { - clear_csr(mie, MIP_MEIP); + asm volatile ("csrrc x0, mie, %0; nop; nop" : : "r"(MIP_MEIP)); while(spn1_hw_interrupt || spn2_hw_interrupt) { - set_csr(mie, MIP_MEIP); - asm("wfi"); - asm("nop"); - clear_csr(mie, MIP_MEIP); + asm volatile ("csrrs x0, mie, %0; wfi; nop" : : "r"(MIP_MEIP)); + asm volatile ("csrrc x0, mie, %0; nop; nop" : : "r"(MIP_MEIP)); } spn1_hw_interrupt=true; spn2_hw_interrupt=true;