247 lines
6.1 KiB
C
247 lines
6.1 KiB
C
/********************************** (C) COPYRIGHT *******************************
|
|
* File Name : ch32v30x_it.c
|
|
* Author : WCH
|
|
* Version : V1.0.0
|
|
* Date : 2024/03/05
|
|
* Description : Main Interrupt Service Routines.
|
|
*********************************************************************************
|
|
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
|
* Attention: This software (modified or not) and binary are used for
|
|
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
|
*******************************************************************************/
|
|
#include "ch32v30x_it.h"
|
|
#include <stdarg.h>
|
|
|
|
void NMI_Handler (void) __attribute__ ((interrupt ("WCH-Interrupt-fast")));
|
|
void HardFault_Handler (void) __attribute__ ((interrupt ("WCH-Interrupt-fast")));
|
|
|
|
/*********************************************************************
|
|
* @fn NMI_Handler
|
|
*
|
|
* @brief This function handles NMI exception.
|
|
*
|
|
* @return none
|
|
*/
|
|
void NMI_Handler (void) {
|
|
while (1) {
|
|
}
|
|
}
|
|
|
|
typedef struct {
|
|
uint32_t ra;
|
|
uint32_t t0;
|
|
uint32_t t1;
|
|
uint32_t t2;
|
|
uint32_t s0;
|
|
uint32_t s1;
|
|
uint32_t a0;
|
|
uint32_t a1;
|
|
uint32_t a2;
|
|
uint32_t a3;
|
|
uint32_t a4;
|
|
uint32_t a5;
|
|
uint32_t a6;
|
|
uint32_t a7;
|
|
uint32_t s2;
|
|
uint32_t s3;
|
|
uint32_t s4;
|
|
uint32_t s5;
|
|
uint32_t s6;
|
|
uint32_t s7;
|
|
uint32_t s8;
|
|
uint32_t s9;
|
|
uint32_t s10;
|
|
uint32_t s11;
|
|
uint32_t t3;
|
|
uint32_t t4;
|
|
uint32_t t5;
|
|
uint32_t t6;
|
|
} HardFaultRegs;
|
|
|
|
// Minimal printf over UART
|
|
void uart_printf (const char *fmt) {
|
|
while (*fmt) {
|
|
USART_SendData (USART1, *fmt);
|
|
while (USART_GetFlagStatus (USART1, USART_FLAG_TXE) == RESET);
|
|
|
|
fmt++;
|
|
}
|
|
}
|
|
|
|
static void print_hex32 (unsigned long val) {
|
|
const char hex[] = "0123456789ABCDEF";
|
|
USART_SendData (USART1, '0');
|
|
while (USART_GetFlagStatus (USART1, USART_FLAG_TXE) == RESET);
|
|
USART_SendData (USART1, 'x');
|
|
while (USART_GetFlagStatus (USART1, USART_FLAG_TXE) == RESET);
|
|
for (int i = 7; i >= 0; i--) {
|
|
USART_SendData (USART1, hex[(val >> (i * 4)) & 0xF]);
|
|
while (USART_GetFlagStatus (USART1, USART_FLAG_TXE) == RESET);
|
|
}
|
|
}
|
|
|
|
volatile HardFaultRegs hardfault_regs; // visible in debugger
|
|
|
|
/*********************************************************************
|
|
* @fn HardFault_Handler
|
|
*
|
|
* @brief This function handles Hard Fault exception.
|
|
*
|
|
* @return none
|
|
*/
|
|
void HardFault_Handler (void) {
|
|
|
|
uint32_t *sp;
|
|
__asm volatile ("mv %0, sp"
|
|
: "=r"(sp)); // get current stack pointer
|
|
|
|
// Copy the stacked registers to the volatile struct
|
|
hardfault_regs.ra = sp[0];
|
|
hardfault_regs.t0 = sp[1];
|
|
hardfault_regs.t1 = sp[2];
|
|
hardfault_regs.t2 = sp[3];
|
|
hardfault_regs.s0 = sp[4];
|
|
hardfault_regs.s1 = sp[5];
|
|
hardfault_regs.a0 = sp[6];
|
|
hardfault_regs.a1 = sp[7];
|
|
hardfault_regs.a2 = sp[8];
|
|
hardfault_regs.a3 = sp[9];
|
|
hardfault_regs.a4 = sp[10];
|
|
hardfault_regs.a5 = sp[11];
|
|
hardfault_regs.a6 = sp[12];
|
|
hardfault_regs.a7 = sp[13];
|
|
hardfault_regs.s2 = sp[14];
|
|
hardfault_regs.s3 = sp[15];
|
|
hardfault_regs.s4 = sp[16];
|
|
hardfault_regs.s5 = sp[17];
|
|
hardfault_regs.s6 = sp[18];
|
|
hardfault_regs.s7 = sp[19];
|
|
hardfault_regs.s8 = sp[20];
|
|
hardfault_regs.s9 = sp[21];
|
|
hardfault_regs.s10 = sp[22];
|
|
hardfault_regs.s11 = sp[23];
|
|
hardfault_regs.t3 = sp[24];
|
|
hardfault_regs.t4 = sp[25];
|
|
hardfault_regs.t5 = sp[26];
|
|
hardfault_regs.t6 = sp[27];
|
|
|
|
// Print all registers
|
|
uart_printf ("HardFault! Registers:\n");
|
|
|
|
uart_printf ("RA: ");
|
|
print_hex32 (hardfault_regs.ra);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("T0: ");
|
|
print_hex32 (hardfault_regs.t0);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("T1: ");
|
|
print_hex32 (hardfault_regs.t1);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("T2: ");
|
|
print_hex32 (hardfault_regs.t2);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("S0: ");
|
|
print_hex32 (hardfault_regs.s0);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("S1: ");
|
|
print_hex32 (hardfault_regs.s1);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("A0: ");
|
|
print_hex32 (hardfault_regs.a0);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("A1: ");
|
|
print_hex32 (hardfault_regs.a1);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("A2: ");
|
|
print_hex32 (hardfault_regs.a2);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("A3: ");
|
|
print_hex32 (hardfault_regs.a3);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("A4: ");
|
|
print_hex32 (hardfault_regs.a4);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("A5: ");
|
|
print_hex32 (hardfault_regs.a5);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("A6: ");
|
|
print_hex32 (hardfault_regs.a6);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("A7: ");
|
|
print_hex32 (hardfault_regs.a7);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("S2: ");
|
|
print_hex32 (hardfault_regs.s2);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("S3: ");
|
|
print_hex32 (hardfault_regs.s3);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("S4: ");
|
|
print_hex32 (hardfault_regs.s4);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("S5: ");
|
|
print_hex32 (hardfault_regs.s5);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("S6: ");
|
|
print_hex32 (hardfault_regs.s6);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("S7: ");
|
|
print_hex32 (hardfault_regs.s7);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("S8: ");
|
|
print_hex32 (hardfault_regs.s8);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("S9: ");
|
|
print_hex32 (hardfault_regs.s9);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("S10: ");
|
|
print_hex32 (hardfault_regs.s10);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("S11: ");
|
|
print_hex32 (hardfault_regs.s11);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("T3: ");
|
|
print_hex32 (hardfault_regs.t3);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("T4: ");
|
|
print_hex32 (hardfault_regs.t4);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("T5: ");
|
|
print_hex32 (hardfault_regs.t5);
|
|
uart_printf ("\n");
|
|
|
|
uart_printf ("T6: ");
|
|
print_hex32 (hardfault_regs.t6);
|
|
uart_printf ("\n");
|
|
Delay_Ms (1000);
|
|
NVIC_SystemReset();
|
|
while (1) {
|
|
}
|
|
}
|