From 21a9fdf45a0ed588151fdc2f13ba3e68ce47f11d Mon Sep 17 00:00:00 2001 From: d00f <8052722+DrDoof@users.noreply.github.com> Date: Tue, 8 Sep 2026 01:06:57 +0200 Subject: [PATCH 1/4] Do not enter Idle mode from the external interrupt 2 handler isr_ext2() ends with PCON |= 1. On the DW8051 any enabled interrupt request ends idle, so the handler sleeps until the next request arrives, the system tick at the latest, and only then returns. Everything at the same priority waits with it, and the instruction after the idle is RETI, so the sleep buys nothing. The handler still clears its flag, which is what it has to do. The other four uses of PCON |= 1 are in task context and are left alone. --- rtlplayground.c | 1 - 1 file changed, 1 deletion(-) diff --git a/rtlplayground.c b/rtlplayground.c index 700df0b8..f4228e27 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -516,7 +516,6 @@ void isr_ext1(void) __interrupt(2) void isr_ext2(void) __interrupt(8) { EXIF &= 0xef; // Clear IRQ flag (bit 7) in EXIF - PCON |= 1; // Enter Idle mode until interrupt occurs } /* From eab8c901cf7aa71ee798a891392bf780a3354e80 Mon Sep 17 00:00:00 2001 From: d00f <8052722+DrDoof@users.noreply.github.com> Date: Tue, 8 Sep 2026 22:43:06 +0200 Subject: [PATCH 2/4] Fix the EXIF bit numbers in the ext2 and ext3 handler comments 0xef clears bit 4 (IE2) and 0xdf clears bit 5 (IE3). The comments said 7 and 6. --- rtlplayground.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtlplayground.c b/rtlplayground.c index f4228e27..ee5cd1fc 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -515,7 +515,7 @@ void isr_ext1(void) __interrupt(2) */ void isr_ext2(void) __interrupt(8) { - EXIF &= 0xef; // Clear IRQ flag (bit 7) in EXIF + EXIF &= 0xef; // Clear IRQ flag IE2 (bit 4) in EXIF } /* @@ -524,7 +524,7 @@ void isr_ext2(void) __interrupt(8) */ void isr_ext3(void) __interrupt(9) { - EXIF &= 0xdf; // Clear IRQ flag (bit 6) in EXIF + EXIF &= 0xdf; // Clear IRQ flag IE3 (bit 5) in EXIF } // Timer2: handles system tick. From c012dda029281100c4b4971374f882468b768605 Mon Sep 17 00:00:00 2001 From: d00f <8052722+DrDoof@users.noreply.github.com> Date: Tue, 8 Sep 2026 23:01:28 +0200 Subject: [PATCH 3/4] Do not enter Idle mode from the external interrupt 2 handler isr_ext2() ends with PCON |= 1, putting the core to sleep from inside an interrupt handler. The DW8051 leaves idle when any enabled interrupt is activated, so the core does not stay down for long. It naps until the next enabled interrupt request turns up, with the 200 Hz system tick putting a ceiling of 5 ms on that, and then carries on. The sleep buys nothing either way, because the instruction after it is the return. While it lasts the handler holds the priority latch, so everything at its level or below waits, and that includes the tick, the console and the NIC receive interrupt. The handler still clears its flag, which is what it has to do. The two wrong comments next to the masks go as well: 0xef clears bit 4 and 0xdf clears bit 5, not 7 and 6, and the masks already say that without help. --- rtlplayground.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtlplayground.c b/rtlplayground.c index ee5cd1fc..f129a64b 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -515,7 +515,7 @@ void isr_ext1(void) __interrupt(2) */ void isr_ext2(void) __interrupt(8) { - EXIF &= 0xef; // Clear IRQ flag IE2 (bit 4) in EXIF + EXIF &= 0xef; } /* @@ -524,7 +524,7 @@ void isr_ext2(void) __interrupt(8) */ void isr_ext3(void) __interrupt(9) { - EXIF &= 0xdf; // Clear IRQ flag IE3 (bit 5) in EXIF + EXIF &= 0xdf; } // Timer2: handles system tick. From 247b2302128a0d02ba9f2c8683c62d4ac70cb22a Mon Sep 17 00:00:00 2001 From: d00f <8052722+DrDoof@users.noreply.github.com> Date: Tue, 8 Sep 2026 23:35:27 +0200 Subject: [PATCH 4/4] Do not enter Idle mode from the external interrupt 2 handler isr_ext2() ends with PCON |= 1, putting the core to sleep from inside an interrupt handler. The DW8051 leaves idle when any enabled interrupt is activated, so the core does not stay down for long. It naps until the next enabled interrupt request turns up, with the 200 Hz system tick putting a ceiling of 5 ms on that, and then carries on. The sleep buys nothing either way, because the instruction after it is the return. While it lasts the handler holds the priority latch, so everything at its level or below waits, and that includes the tick, the console and the NIC receive interrupt. The handler still clears its flag, which is what it has to do. The bit numbers beside the two masks were wrong: 0xef clears bit 4 and 0xdf clears bit 5, not 7 and 6. --- rtlplayground.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtlplayground.c b/rtlplayground.c index f129a64b..bbca65b3 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -515,7 +515,7 @@ void isr_ext1(void) __interrupt(2) */ void isr_ext2(void) __interrupt(8) { - EXIF &= 0xef; + EXIF &= 0xef; // Clear IRQ flag (bit 4) in EXIF } /* @@ -524,7 +524,7 @@ void isr_ext2(void) __interrupt(8) */ void isr_ext3(void) __interrupt(9) { - EXIF &= 0xdf; + EXIF &= 0xdf; // Clear IRQ flag (bit 5) in EXIF } // Timer2: handles system tick.