/********************************** (C) COPYRIGHT ******************************* * File Name : usb_istr.c * Author : WCH * Version : V1.0.1 * Date : 2022/12/28 * Description : ISTR events 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 "usb_istr.h" #include "../driver/inc/usb_lib.h" #include "usb_prop.h" #include "usb_pwr.h" uint16_t Ep0RxBlks; /* Private variables */ __IO uint16_t wIstr; __IO uint8_t bIntPackSOF = 0; __IO uint32_t esof_counter =0; __IO uint32_t wCNTR=0; /* function pointers to non-control endpoints service routines */ void (*pEpInt_IN[7])(void) ={ EP1_IN_Callback, EP2_IN_Callback, EP3_IN_Callback, EP4_IN_Callback, EP5_IN_Callback, EP6_IN_Callback, EP7_IN_Callback, }; void (*pEpInt_OUT[7])(void) ={ EP1_OUT_Callback, EP2_OUT_Callback, EP3_OUT_Callback, EP4_OUT_Callback, EP5_OUT_Callback, EP6_OUT_Callback, EP7_OUT_Callback, }; /******************************************************************************* * @fn USB_Istr * * @brief ISTR events interrupt service routine * * @return None. */ void USB_Istr(void) { uint32_t i=0; __IO uint32_t EP[8]; if ((*_pEPRxCount(0) & 0xFC00 )!= Ep0RxBlks) { *_pEPRxCount(0) |= (Ep0RxBlks & 0xFC00); } wIstr = _GetISTR(); #if (IMR_MSK & ISTR_SOF) if (wIstr & ISTR_SOF & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_SOF); bIntPackSOF++; #ifdef SOF_CALLBACK SOF_Callback(); #endif } #endif #if (IMR_MSK & ISTR_CTR) if (wIstr & ISTR_CTR & wInterrupt_Mask) { CTR_LP(); #ifdef CTR_CALLBACK CTR_Callback(); #endif } #endif #if (IMR_MSK & ISTR_RESET) if (wIstr & ISTR_RESET & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_RESET); Device_Property.Reset(); #ifdef RESET_CALLBACK RESET_Callback(); #endif } #endif #if (IMR_MSK & ISTR_DOVR) if (wIstr & ISTR_DOVR & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_DOVR); #ifdef DOVR_CALLBACK DOVR_Callback(); #endif } #endif #if (IMR_MSK & ISTR_ERR) if (wIstr & ISTR_ERR & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_ERR); #ifdef ERR_CALLBACK ERR_Callback(); #endif } #endif #if (IMR_MSK & ISTR_WKUP) if (wIstr & ISTR_WKUP & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_WKUP); Resume(RESUME_EXTERNAL); #ifdef WKUP_CALLBACK WKUP_Callback(); #endif } #endif #if (IMR_MSK & ISTR_SUSP) if (wIstr & ISTR_SUSP & wInterrupt_Mask) { if (fSuspendEnabled) { Suspend(); } else { Resume(RESUME_LATER); } _SetISTR((uint16_t)CLR_SUSP); #ifdef SUSP_CALLBACK SUSP_Callback(); #endif } #endif #if (IMR_MSK & ISTR_ESOF) if (wIstr & ISTR_ESOF & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_ESOF); if ((_GetFNR()&FNR_RXDP)!=0) { esof_counter ++; if ((esof_counter >3)&&((_GetCNTR()&CNTR_FSUSP)==0)) { wCNTR = _GetCNTR(); for (i=0;i<8;i++) EP[i] = _GetENDPOINT(i); wCNTR|=CNTR_FRES; _SetCNTR(wCNTR); wCNTR&=~CNTR_FRES; _SetCNTR(wCNTR); while((_GetISTR()&ISTR_RESET) == 0); _SetISTR((uint16_t)CLR_RESET); for (i=0;i<8;i++) _SetENDPOINT(i, EP[i]); esof_counter = 0; } } else { esof_counter = 0; } Resume(RESUME_ESOF); #ifdef ESOF_CALLBACK ESOF_Callback(); #endif } #endif } /* USB_Istr */