| 
					
				 | 
			
			
				@@ -10,8 +10,11 @@ extern "C" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const char *g_azplatform_name = "GD32F205 AzulSCSI v1.x"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static volatile uint32_t g_millisecond_counter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static volatile uint32_t g_watchdog_timeout; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static uint32_t g_ns_to_cycles; // Q0.32 fixed point format 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void watchdog_handler(uint32_t *sp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 unsigned long millis() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return g_millisecond_counter; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -33,9 +36,27 @@ void delay_ns(unsigned long ns) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while ((uint32_t)(DWT->CYCCNT - CNT_start) < cycles); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void SysTick_Handler(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void SysTick_Handler_inner(uint32_t *sp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     g_millisecond_counter++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (g_watchdog_timeout > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        g_watchdog_timeout--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (g_watchdog_timeout == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            watchdog_handler(sp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+__attribute__((interrupt, naked)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void SysTick_Handler(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Take note of stack pointer so that we can print debug 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // info in watchdog handler. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    asm("mrs r0, msp\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        "b SysTick_Handler_inner": : : "r0"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // Writes log data to the PB3 SWO pin 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -193,6 +214,8 @@ void azplatform_emergency_log_save() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     crashfile.close(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+extern uint32_t _estack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 __attribute__((noinline)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void show_hardfault(uint32_t *sp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -205,6 +228,7 @@ void show_hardfault(uint32_t *sp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     azlog("Platform: ", g_azplatform_name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     azlog("FW Version: ", g_azlog_firmwareversion); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     azlog("CFSR: ", cfsr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    azlog("SP: ", (uint32_t)sp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     azlog("PC: ", pc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     azlog("LR: ", lr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     azlog("R0: ", sp[0]); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -212,6 +236,15 @@ void show_hardfault(uint32_t *sp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     azlog("R2: ", sp[2]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     azlog("R3: ", sp[3]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint32_t *p = (uint32_t*)((uint32_t)sp & ~3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (int i = 0; i < 8; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (p == &_estack) break; // End of stack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        azlog("STACK ", (uint32_t)p, ":    ", p[0], " ", p[1], " ", p[2], " ", p[3]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        p += 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     azplatform_emergency_log_save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while (1) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -234,7 +267,7 @@ void show_hardfault(uint32_t *sp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-__attribute__((naked)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+__attribute__((naked, interrupt)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void HardFault_Handler(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // Copies stack pointer into first argument 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -242,21 +275,21 @@ void HardFault_Handler(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         "b show_hardfault": : : "r0"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-__attribute__((naked)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+__attribute__((naked, interrupt)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void MemManage_Handler(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     asm("mrs r0, msp\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         "b show_hardfault": : : "r0"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-__attribute__((naked)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+__attribute__((naked, interrupt)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void BusFault_Handler(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     asm("mrs r0, msp\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         "b show_hardfault": : : "r0"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-__attribute__((naked)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+__attribute__((naked, interrupt)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void UsageFault_Handler(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     asm("mrs r0, msp\n" 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -265,6 +298,20 @@ void UsageFault_Handler(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } /* extern "C" */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void watchdog_handler(uint32_t *sp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    azlog("-------------- WATCHDOG TIMEOUT"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    show_hardfault(sp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void azplatform_reset_watchdog(int timeout_ms) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // This uses a software watchdog based on systick timer interrupt. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // It gives us opportunity to collect better debug info than the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // full hardware reset that would be caused by hardware watchdog. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    g_watchdog_timeout = timeout_ms; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /*****************************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /* Driver for GD32 SPI for SdFat library */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /*****************************************/ 
			 |