From fdbb59a77981a14ed29232245cf5ca8f2e1ac139 Mon Sep 17 00:00:00 2001
From: CNLohr <lohr85@gmail.com>
Date: Thu, 11 May 2023 02:14:07 -0400
Subject: [PATCH] Update with deeper notes about HPE.

---
 examples/exti_pin_change_isr/Makefile         |  2 +-
 .../exti_pin_change_isr/exti_pin_change_isr.c | 60 +++++++++++++------
 2 files changed, 42 insertions(+), 20 deletions(-)

diff --git a/examples/exti_pin_change_isr/Makefile b/examples/exti_pin_change_isr/Makefile
index 68e79e2..d911c13 100644
--- a/examples/exti_pin_change_isr/Makefile
+++ b/examples/exti_pin_change_isr/Makefile
@@ -3,7 +3,7 @@ all : flash
 TARGET:=exti_pin_change_isr
 
 test : flash
-	../../minichlink/minichlink -X ECLK 1:0:0:1:63
+	../../minichlink/minichlink -X ECLK:1:0:0:1:63
 
 include ../../ch32v003fun/ch32v003fun.mk
 
diff --git a/examples/exti_pin_change_isr/exti_pin_change_isr.c b/examples/exti_pin_change_isr/exti_pin_change_isr.c
index 1e937e7..8628842 100644
--- a/examples/exti_pin_change_isr/exti_pin_change_isr.c
+++ b/examples/exti_pin_change_isr/exti_pin_change_isr.c
@@ -6,16 +6,35 @@
 
 #define APB_CLOCK SYSTEM_CORE_CLOCK
 
-volatile uint32_t count;
-
-// This code uses fast interrupts, but be warned, in this mode your hardware stack 
-// is only 2 interrupt calls deep!!!
-//
-// When you execute code here, from RAM, the latency is between 310 and 480ns.
-// From RAM is using  __attribute__((section(".srodata")));
-// Flash starts at 340ns but seems about the same otherwise, bar the fact it prevents
-// any other apps from running.
-void EXTI7_0_IRQHandler( void ) __attribute__((naked));
+/*
+ This code uses fast interrupts, but be warned, in this mode your hardware stack 
+ is only 2 interrupt calls deep!!!
+
+ When you execute code here, from RAM, the latency is between 310 and 480ns.
+ From RAM is using  __attribute__((section(".srodata")));
+
+Chart is in Cycles Spent @ 48MHz
+
+|   __attribute__ |  HPE ON  |  HPE OFF |
+| ((interrupt))   |   29  |   28  |
+| ((section(".srodata"))) and ((interrupt)) | 28 | 23 |
+| ((naked)) | 23 | 21 |
+| ((section(".srodata"))) and ((naked)) | 15 | 16| 
+
+  These were done with an empty (nop) loop in main.
+
+  HPE ON  = 0x804 = 3
+  HPE OFF = 0x804 = 0
+
+  Bog-standard interrupt test with variance. I.e.
+	__attribute__((interrupt)) with cursed code in main loop.
+
+  Variance tests: 27-30 cycles
+  
+  Which will manifest as interurpt jitter.
+*/
+
+void EXTI7_0_IRQHandler( void ) __attribute__((interrupt));
 void EXTI7_0_IRQHandler( void ) 
 {
 	// Flash just a little blip.
@@ -24,9 +43,6 @@ void EXTI7_0_IRQHandler( void )
 
 	// Acknowledge the interrupt
 	EXTI->INTFR = 1<<3;
-
-	// Return out of function.
-	asm volatile( "mret" );
 }
 
 int main()
@@ -50,12 +66,20 @@ int main()
 	// This is how we set (INTSYSCR) to enable hardware interrupt nesting
 	// and hardware stack. BUT this means we can only stack intterrupts 2 deep.
 	//
+	// This feature is called "HPE"
+	//
 	// Note: If you don't do this, you will need to set your functions to be
 	// __attribute__((interrupt)) instead of  __attribute__((naked))  with an
 	// mret.
+	//
+	// PLEASE BE CAREFUL WHEN DOING THIS THOUGH.  There are a number of things
+	// you should know with HPE.  The issue is that HPE doesn't preserve s0,
+	// and s1. You should review the following material before using HPE.
+	//   https://github.com/cnlohr/ch32v003fun/issues/90
+	//   https://www.reddit.com/r/RISCV/comments/126262j/notes_on_wch_fast_interrupts/
+	//   https://www.eevblog.com/forum/microcontrollers/bizarre-problem-on-ch32v003-with-systick-isr-corrupting-uart-tx-data
 	asm volatile( "addi t1,x0, 3\ncsrrw x0, 0x804, t1\n" : : :  "t1" );
 
-
 	// Configure the IO as an interrupt.
 	AFIO->EXTICR = 3<<(3*2); //PORTD.3 (3 out front says PORTD, 3 in back says 3)
 	EXTI->INTENR = 1<<3; // Enable EXT3
@@ -66,11 +90,9 @@ int main()
 
 	while(1)
 	{
-		// PC1 constantly toggles, but do realy cursed instructons ;)
-		// this is so we have something we can "break" from
-		GPIOC->BSHR = 1;
-		if( ((uint32_t*)count++) )
-			GPIOC->BSHR = (1<<16);
+		//GPIOC->BSHR = 1;
+		//if( ((uint32_t*)count++) )
+		//	GPIOC->BSHR = (1<<16);
 		if( count == 100 ) count = 0;
 	}
 }
-- 
GitLab