Improve wait for interrupt routines

This commit is contained in:
Stanislaw Kaushanski 2022-04-28 19:20:32 +02:00
parent 02ce96eed8
commit 5f44f8df98
2 changed files with 13 additions and 15 deletions

Binary file not shown.

View File

@ -45,36 +45,34 @@ void configure_irq(size_t irq_num, function_ptr_t handler, unsigned char prio=1)
} }
void wait_for_spn1_interrupt() { 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) { while(spn1_hw_interrupt) {
set_csr(mie, MIP_MEIP); // Enable interrupts and immediately enter wfi.
asm("wfi"); asm volatile ("csrrs x0, mie, %0; wfi; nop" : : "r"(MIP_MEIP));
clear_csr(mie, MIP_MEIP); // Disable interrupts again before examine the flag value.
asm("nop"); asm volatile ("csrrc x0, mie, %0; nop; nop" : : "r"(MIP_MEIP));
} }
spn1_hw_interrupt=true; spn1_hw_interrupt=true;
set_csr(mie, MIP_MEIP); set_csr(mie, MIP_MEIP);
} }
void wait_for_spn2_interrupt() { 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) { while(spn2_hw_interrupt) {
set_csr(mie, MIP_MEIP); asm volatile ("csrrs x0, mie, %0; wfi; nop" : : "r"(MIP_MEIP));
asm("wfi"); asm volatile ("csrrc x0, mie, %0; nop; nop" : : "r"(MIP_MEIP));
clear_csr(mie, MIP_MEIP);
asm("nop");
} }
spn2_hw_interrupt=true; spn2_hw_interrupt=true;
set_csr(mie, MIP_MEIP); set_csr(mie, MIP_MEIP);
} }
void wait_for_spn_interrupts() { 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) { while(spn1_hw_interrupt || spn2_hw_interrupt) {
set_csr(mie, MIP_MEIP); asm volatile ("csrrs x0, mie, %0; wfi; nop" : : "r"(MIP_MEIP));
asm("wfi"); asm volatile ("csrrc x0, mie, %0; nop; nop" : : "r"(MIP_MEIP));
asm("nop");
clear_csr(mie, MIP_MEIP);
} }
spn1_hw_interrupt=true; spn1_hw_interrupt=true;
spn2_hw_interrupt=true; spn2_hw_interrupt=true;