/********************************** (C) COPYRIGHT ******************************* * File Name : ch32v20x_it.c * Author : WCH * Version : V1.0.0 * Date : 2022/06/16 * 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. *******************************************************************************/ /********************************************************************* * INCLUDES */ #include "ch32v20x_it.h" #include "eth_driver.h" #include "CONFIG.h" #include "debug.h" #include "fault_diag.h" /********************************************************************* * LOCAL FUNCTIONS */ void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); void BB_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); void ETH_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); void TIM2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); /********************************************************************* * @fn NMI_Handler * * @brief This function handles NMI exception. * * @return None */ void NMI_Handler(void) { } /* 故障诊断现场: .noinit 段 (复位不清零) */ FaultDiag g_fault_diag __attribute__((section(".noinit"))); /********************************************************************* * @fn fault_diag_init * * @brief main 开头调用: 打印上次复位现场 + 重置 + 递增 boot_cnt * * @return none */ void fault_diag_init(void) { if (g_fault_diag.magic == 0xFA57FA57UL) { PRINT("FAULT_DIAG: boot_cnt=%lu mcause=0x%08lx mepc=0x%08lx mtval=0x%08lx marker=0x%08lx\n", (unsigned long)g_fault_diag.boot_cnt, (unsigned long)g_fault_diag.mcause, (unsigned long)g_fault_diag.mepc, (unsigned long)g_fault_diag.mtval, (unsigned long)g_fault_diag.marker); } else if (g_fault_diag.marker != 0) { /* 非 HardFault 复位 (IWDG 超时/卡死/掉电): marker 仍记录执行轨迹 */ PRINT("FAULT_DIAG: no-hardfault boot_cnt=%lu marker=0x%08lx (卡死/看门狗复位)\n", (unsigned long)g_fault_diag.boot_cnt, (unsigned long)g_fault_diag.marker); } /* 重置现场, boot_cnt 保留递增 */ g_fault_diag.magic = 0; g_fault_diag.mcause = 0; g_fault_diag.mepc = 0; g_fault_diag.mtval = 0; g_fault_diag.marker = 0; g_fault_diag.boot_cnt++; } /********************************************************************* * @fn HardFault_Handler * * @brief This function handles Hard Fault exception. * * @return None */ void HardFault_Handler(void) { /* 纯 RAM 写现场 (不依赖 UART/printf): 栈坏/中断禁用也能留痕 */ g_fault_diag.magic = 0xFA57FA57UL; g_fault_diag.mcause = __get_MCAUSE(); g_fault_diag.mepc = __get_MEPC(); g_fault_diag.mtval = __get_MTVAL(); /* 尽力打印 (UART 可用时), 失败不影响 RAM 现场 */ PRINT("HARDFAULT: mcause=0x%08lx mepc=0x%08lx mtval=0x%08lx\n", (unsigned long)g_fault_diag.mcause, (unsigned long)g_fault_diag.mepc, (unsigned long)g_fault_diag.mtval); NVIC_SystemReset(); while(1) { } } /********************************************************************* * @fn BB_IRQHandler * * @brief BB Interrupt for BLE. * * @return None */ void BB_IRQHandler(void) { BB_IRQLibHandler(); } /********************************************************************* * @fn ETH_IRQHandler * * @brief This function handles ETH exception. * * @return none */ void ETH_IRQHandler(void) { WCHNET_ETHIsr(); } void TIM2_IRQHandler( void ) { WCHNET_TimeIsr(WCHNETTIMERPERIOD); TIM_ClearITPendingBit(TIM2, TIM_IT_Update); }