/******************************************************************************* * Function Name : USB_Istr * Description : ISTR events interrupt service routine * Input : None. * Output : None. * Return : None. *******************************************************************************/ void USB_Istr(void) { wIstr = _GetISTR(); #if (IMR_MSK & ISTR_CTR) if (wIstr & ISTR_CTR & wInterrupt_Mask) { /* servicing of the endpoint correct transfer interrupt */ /* clear of the CTR flag into the sub */ 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) { /* check if SUSPEND is possible */ if (fSuspendEnabled) { Suspend(); } else { /* if not possible then resume after xx ms */ Resume(RESUME_LATER); } /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ _SetISTR((uint16_t)CLR_SUSP); #ifdef SUSP_CALLBACK SUSP_Callback(); #endif } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #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_ESOF) if (wIstr & ISTR_ESOF & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_ESOF); /* resume handling timing is made with ESOFs */ Resume(RESUME_ESOF); /* request without change of the machine state */ #ifdef ESOF_CALLBACK ESOF_Callback(); #endif } #endif } /* USB_Istr */
/******************************************************************************* * Function Name : USB_Istr * Description : ISTR events interrupt service routine * Input : None. * Output : None. * Return : None. *******************************************************************************/ void USB_Istr(void) { uint32_t i=0; __IO uint32_t EP[8]; 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) { /* servicing of the endpoint correct transfer interrupt */ /* clear of the CTR flag into the sub */ 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) { /* check if SUSPEND is possible */ if (fSuspendEnabled) { Suspend(); } else { /* if not possible then resume after xx ms */ Resume(RESUME_LATER); } /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ _SetISTR((uint16_t)CLR_SUSP); #ifdef SUSP_CALLBACK SUSP_Callback(); #endif } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_ESOF) if (wIstr & ISTR_ESOF & wInterrupt_Mask) { /* clear ESOF flag in ISTR */ _SetISTR((uint16_t)CLR_ESOF); if ((_GetFNR()&FNR_RXDP)!=0) { /* increment ESOF counter */ esof_counter ++; /* test if we enter in ESOF more than 3 times with FSUSP =0 and RXDP =1=>> possible missing SUSP flag*/ if ((esof_counter >3)&&((_GetCNTR()&CNTR_FSUSP)==0)) { /* this a sequence to apply a force RESET*/ /*Store CNTR value */ wCNTR = _GetCNTR(); /*Store endpoints registers status */ for (i=0;i<8;i++) EP[i] = _GetENDPOINT(i); /*apply FRES */ wCNTR|=CNTR_FRES; _SetCNTR(wCNTR); /*clear FRES*/ wCNTR&=~CNTR_FRES; _SetCNTR(wCNTR); /*disable ESOF interrupt*/ //wCNTR &= ~CNTR_ESOFM; //_SetCNTR(wCNTR); /*poll for RESET flag in ISTR*/ while((_GetISTR()&ISTR_RESET) == 0); /* clear RESET flag in ISTR */ _SetISTR((uint16_t)CLR_RESET); /*restore Enpoints*/ for (i=0;i<8;i++) _SetENDPOINT(i, EP[i]); esof_counter = 0; } } else { esof_counter = 0; } /* resume handling timing is made with ESOFs */ Resume(RESUME_ESOF); /* request without change of the machine state */ #ifdef ESOF_CALLBACK ESOF_Callback(); #endif } #endif /*disable ESOF interrupt*/ wCNTR = _GetCNTR(); wCNTR &= ~CNTR_ESOFM; _SetCNTR(wCNTR); } /* USB_Istr */
/******************************************************************************* * Function Name : Suspend * Description : sets suspend mode operating conditions * Input : None. * Output : None. * Return : USB_SUCCESS. *******************************************************************************/ void Suspend(void) { uint32_t i =0; uint16_t wCNTR; uint32_t tmpreg = 0; __IO uint32_t savePWR_CR=0; /* suspend preparation */ /* ... */ /*Store CNTR value */ wCNTR = _GetCNTR(); /* This a sequence to apply a force RESET to handle a robustness case */ /*Store endpoints registers status */ for (i=0;i<8;i++) EP[i] = _GetENDPOINT(i); /* unmask RESET flag */ wCNTR|=CNTR_RESETM; _SetCNTR(wCNTR); /*apply FRES */ wCNTR|=CNTR_FRES; _SetCNTR(wCNTR); /*clear FRES*/ wCNTR&=~CNTR_FRES; _SetCNTR(wCNTR); /*poll for RESET flag in ISTR*/ while((_GetISTR()&ISTR_RESET) == 0); /* clear RESET flag in ISTR */ _SetISTR((uint16_t)CLR_RESET); /*restore Enpoints*/ for (i=0;i<8;i++) _SetENDPOINT(i, EP[i]); /* Now it is safe to enter macrocell in suspend mode */ wCNTR |= CNTR_FSUSP; _SetCNTR(wCNTR); /* force low-power mode in the macrocell */ wCNTR = _GetCNTR(); wCNTR |= CNTR_LPMODE; _SetCNTR(wCNTR); /*prepare entry in low power mode (STOP mode)*/ /* Select the regulator state in STOP mode*/ savePWR_CR = PWR->CR; tmpreg = PWR->CR; /* Clear PDDS and LPDS bits */ tmpreg &= ((uint32_t)0xFFFFFFFC); /* Set LPDS bit according to PWR_Regulator value */ tmpreg |= PWR_Regulator_LowPower; /* Store the new value */ PWR->CR = tmpreg; /* Set SLEEPDEEP bit of Cortex System Control Register */ #if defined (STM32F30X) || defined (STM32F37X) SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; #else SCB->SCR |= SCB_SCR_SLEEPDEEP; #endif /* enter system in STOP mode, only when wakeup flag in not set */ if((_GetISTR()&ISTR_WKUP)==0) { __WFI(); /* Reset SLEEPDEEP bit of Cortex System Control Register */ #if defined (STM32F30X) || defined (STM32F37X) SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); #else SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); #endif } else { /* Clear Wakeup flag */ _SetISTR(CLR_WKUP); /* clear FSUSP to abort entry in suspend mode */ wCNTR = _GetCNTR(); wCNTR&=~CNTR_FSUSP; _SetCNTR(wCNTR); /*restore sleep mode configuration */ /* restore Power regulator config in sleep mode*/ PWR->CR = savePWR_CR; /* Reset SLEEPDEEP bit of Cortex System Control Register */ #if defined (STM32F30X) || defined (STM32F37X) SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); #else SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); #endif } }
/******************************************************************************* * Function Name : CTR_LP. * Description : Low priority Endpoint Correct Transfer interrupt's service * routine. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void CTR_LP(void) { u32 wEPVal; /* stay in loop while pending ints */ while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) { _SetISTR((u16)CLR_CTR); /* clear CTR flag */ /* extract highest priority endpoint number */ EPindex = (u8)(wIstr & ISTR_EP_ID); if (EPindex == 0) { /* Decode and service control endpoint interrupt */ /* calling related service routine */ /* (Setup0_Process, In0_Process, Out0_Process) */ /* save RX & TX status */ /* and set both to NAK */ SaveRState = _GetEPRxStatus(ENDP0); SaveTState = _GetEPTxStatus(ENDP0); _SetEPRxStatus(ENDP0, EP_RX_NAK); _SetEPTxStatus(ENDP0, EP_TX_NAK); /* DIR bit = origin of the interrupt */ if ((wIstr & ISTR_DIR) == 0) { /* DIR = 0 */ /* DIR = 0 => IN int */ /* DIR = 0 implies that (EP_CTR_TX = 1) always */ _ClearEP_CTR_TX(ENDP0); In0_Process(); /* check if SETUP arrived during IN processing */ wEPVal = _GetENDPOINT(ENDP0); if ((wEPVal & (EP_CTR_RX | EP_SETUP)) != 0) { _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */ Setup0_Process(); } } else { /* DIR = 1 */ /* DIR = 1 & CTR_RX => SETUP or OUT int */ /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ wEPVal = _GetENDPOINT(ENDP0); if ((wEPVal & EP_CTR_TX) != 0) { _ClearEP_CTR_TX(ENDP0); In0_Process(); } if ((wEPVal &EP_SETUP) != 0) { _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */ Setup0_Process(); } else if ((wEPVal & EP_CTR_RX) != 0) { _ClearEP_CTR_RX(ENDP0); Out0_Process(); } } /* before terminate set Tx & Rx status */ _SetEPRxStatus(ENDP0, SaveRState); _SetEPTxStatus(ENDP0, SaveTState); }/* if(EPindex == 0) */ else { /* Decode and service non control endpoints interrupt */ /* process related endpoint register */ wEPVal = _GetENDPOINT(EPindex); if ((wEPVal & EP_CTR_RX) != 0) { /* clear int flag */ _ClearEP_CTR_RX(EPindex); /* call OUT service function */ (*pEpInt_OUT[EPindex-1])(); } /* if((wEPVal & EP_CTR_RX) */ if ((wEPVal & EP_CTR_TX) != 0) { /* clear int flag */ _ClearEP_CTR_TX(EPindex); /* call IN service function */ (*pEpInt_IN[EPindex-1])(); } /* if((wEPVal & EP_CTR_TX) != 0) */ }/* if(EPindex == 0) else */ }/* while(...) */ }
void USB_LP_CAN1_RX0_IRQHandler(void) { wIstr = _GetISTR(); /* go nuts with the preproc switches since this is an ISTR and must be FAST */ #if (ISR_MSK & ISTR_RESET) if (wIstr & ISTR_RESET & wInterrupt_Mask) { _SetISTR((u16)CLR_RESET); Device_Property.Reset(); } #endif #if (ISR_MSK & ISTR_DOVR) if (wIstr & ISTR_DOVR & wInterrupt_Mask) { _SetISTR((u16)CLR_DOVR); } #endif #if (ISR_MSK & ISTR_ERR) if (wIstr & ISTR_ERR & wInterrupt_Mask) { _SetISTR((u16)CLR_ERR); } #endif #if (ISR_MSK & ISTR_WKUP) if (wIstr & ISTR_WKUP & wInterrupt_Mask) { _SetISTR((u16)CLR_WKUP); usbResume(RESUME_EXTERNAL); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (ISR_MSK & ISTR_SUSP) if (wIstr & ISTR_SUSP & wInterrupt_Mask) { /* check if SUSPEND is possible */ if (F_SUSPEND_ENABLED) { usbSuspend(); } else { /* if not possible then resume after xx ms */ usbResume(RESUME_LATER); } /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ _SetISTR((u16)CLR_SUSP); } #endif #if (ISR_MSK & ISTR_SOF) if (wIstr & ISTR_SOF & wInterrupt_Mask) { _SetISTR((u16)CLR_SOF); bIntPackSOF++; } #endif #if (ISR_MSK & ISTR_ESOF) if (wIstr & ISTR_ESOF & wInterrupt_Mask) { _SetISTR((u16)CLR_ESOF); /* resume handling timing is made with ESOFs */ usbResume(RESUME_ESOF); /* request without change of the machine state */ } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (ISR_MSK & ISTR_CTR) if (wIstr & ISTR_CTR & wInterrupt_Mask) { /* servicing of the endpoint correct transfer interrupt */ /* clear of the CTR flag into the sub */ CTR_LP(); /* low priority ISR defined in the usb core lib */ } #endif }
void USB_Istr(void) { uint16_t wIstr = _GetISTR(); if (wIstr & ISTR_RESET) { _SetISTR((uint16_t)CLR_RESET); if (stm32_usbd_callback.on_reset != NULL) { stm32_usbd_callback.on_reset(stm32_usbd_callback.param); } } if (wIstr & ISTR_DOVR) { _SetISTR((uint16_t)CLR_DOVR); } if (wIstr & ISTR_ERR) { _SetISTR((uint16_t)CLR_ERR); if (stm32_usbd_callback.on_error != NULL) { stm32_usbd_callback.on_error(stm32_usbd_callback.param, USBERR_ERROR); } } if (wIstr & ISTR_WKUP) { _SetISTR((uint16_t)CLR_WKUP); if (stm32_usbd_callback.on_wakeup != NULL) { stm32_usbd_callback.on_wakeup(stm32_usbd_callback.param); } } if (wIstr & ISTR_SUSP) { if (stm32_usbd_callback.on_suspend != NULL) { stm32_usbd_callback.on_suspend(stm32_usbd_callback.param); } _SetISTR((uint16_t)CLR_SUSP); } if (wIstr & ISTR_SOF) { _SetISTR((uint16_t)CLR_SOF); if (stm32_usbd_callback.on_sof != NULL) { stm32_usbd_callback.on_sof(stm32_usbd_callback.param); } } if (wIstr & ISTR_ESOF) { _SetISTR((uint16_t)CLR_ESOF); if (stm32_usbd_callback.on_error != NULL) { stm32_usbd_callback.on_error(stm32_usbd_callback.param, USBERR_SOF_TO); } } if (wIstr & ISTR_CTR) { CTR_LP(); } }
/** * @brief ISTR events interrupt service routine * @param None * @retval None */ void USB_Istr(void) { __IO uint16_t wIstr = 0; wIstr = _GetISTR(); #if (IMR_MSK & ISTR_CTR) if (wIstr & ISTR_CTR & wInterrupt_Mask) { /* servicing of the endpoint correct transfer interrupt */ /* clear of the CTR flag into the sub */ CTR(); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_RESET) if (wIstr & ISTR_RESET & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_RESET); USBD_DCD_INT_fops->Reset(&USB_Device_dev); DCD_EP_SetAddress(&USB_Device_dev, 0); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_DOVR) if (wIstr & ISTR_DOVR & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_DOVR); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_ERR) if (wIstr & ISTR_ERR & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_ERR); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_WKUP) if (wIstr & ISTR_WKUP & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_WKUP); USBD_DCD_INT_fops->Resume(&USB_Device_dev); /* Handle Resume state machine */ Resume(RESUME_EXTERNAL); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_SUSP) if (wIstr & ISTR_SUSP & wInterrupt_Mask) { /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ _SetISTR((uint16_t)CLR_SUSP); /* choose to enter system in low power mode or not in user suspend callback */ USBD_DCD_INT_fops->Suspend(&USB_Device_dev); Suspend(); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_SOF) if (wIstr & ISTR_SOF & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_SOF); USBD_DCD_INT_fops->SOF(&USB_Device_dev); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_ESOF) if (wIstr & ISTR_ESOF & wInterrupt_Mask) { /* clear ESOF flag in ISTR */ _SetISTR((uint16_t)CLR_ESOF); /* resume handling timing is made with ESOFs */ Resume(RESUME_ESOF); /* request without change of the machine state */ } #endif } /* USB_Istr */
/******************************************************************************* * Function Name : USB_Istr * Description : ISTR events interrupt service routine * Input : None. * Output : None. * Return : None. *******************************************************************************/ void USB_Istr(void) { wIstr = _GetISTR(); #if (IMR_MSK & ISTR_RESET) //如果设置了USB中断 if (wIstr & ISTR_RESET & wInterrupt_Mask) { //ISTR 程式只能清0,无法写1, //用要清除的位为0,其他位写为1 _SetISTR((u16)CLR_RESET); Device_Property.Reset(); #ifdef RESET_CALLBACK RESET_Callback(); #endif } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_DOVR) if (wIstr & ISTR_DOVR & wInterrupt_Mask) { _SetISTR((u16)CLR_DOVR); #ifdef DOVR_CALLBACK DOVR_Callback(); #endif } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_ERR) if (wIstr & ISTR_ERR & wInterrupt_Mask) { _SetISTR((u16)CLR_ERR); #ifdef ERR_CALLBACK ERR_Callback(); #endif } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_WKUP) if (wIstr & ISTR_WKUP & wInterrupt_Mask) { _SetISTR((u16)CLR_WKUP); Resume(RESUME_EXTERNAL); #ifdef WKUP_CALLBACK WKUP_Callback(); #endif } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_SUSP) if (wIstr & ISTR_SUSP & wInterrupt_Mask)//USB掛起 { /* check if SUSPEND is possible */ if (fSuspendEnabled) //usb掛起全能 { Suspend(); //直接硬件掛起 } else { //软件掛起 /* if not possible then resume after xx ms */ Resume(RESUME_LATER); // 枚举掛起 } /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ _SetISTR((u16)CLR_SUSP); #ifdef SUSP_CALLBACK SUSP_Callback(); #endif } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_SOF) //帧首标志 //1ms enter one time if (wIstr & ISTR_SOF & wInterrupt_Mask) { _SetISTR((u16)CLR_SOF); bIntPackSOF++; //帧指针加一 #ifdef SOF_CALLBACK SOF_Callback(); #endif } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_ESOF) if (wIstr & ISTR_ESOF & wInterrupt_Mask) { _SetISTR((u16)CLR_ESOF); //帧期望标志 /* resume handling timing is made with ESOFs */ Resume(RESUME_ESOF); /* request without change of the machine state */ #ifdef ESOF_CALLBACK ESOF_Callback(); #endif } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_CTR) if (wIstr & ISTR_CTR & wInterrupt_Mask) { /* servicing of the endpoint correct transfer interrupt */ /* clear of the CTR flag into the sub */ CTR_LP(); #ifdef CTR_CALLBACK CTR_Callback(); #endif } #endif } /* USB_Istr */
/** * @brief ISTR events interrupt service routine * @param None * @retval None */ void USB_Istr(void) { __IO uint16_t wIstr = 0; wIstr = _GetISTR(); #if (IMR_MSK & ISTR_CTR) if (wIstr & ISTR_CTR & wInterrupt_Mask) { /* servicing of the endpoint correct transfer interrupt */ /* clear of the CTR flag into the sub */ CTR(); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_RESET) if (wIstr & ISTR_RESET & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_RESET); USBD_DCD_INT_fops->Reset(&USB_Device_dev); DCD_EP_SetAddress(&USB_Device_dev, 0); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_DOVR) if (wIstr & ISTR_DOVR & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_DOVR); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_ERR) if (wIstr & ISTR_ERR & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_ERR); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_WKUP) if (wIstr & ISTR_WKUP & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_WKUP); USBD_DCD_INT_fops->Resume(&USB_Device_dev); /* Handle Resume state machine */ Resume(RESUME_EXTERNAL); #ifdef LPM_ENABLED /* clear L1 remote wakeup flag */ L1_remote_wakeup = 0; #endif } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_SUSP) if (wIstr & ISTR_SUSP & wInterrupt_Mask) { /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ _SetISTR((uint16_t)CLR_SUSP); /* process library core layer suspend routine*/ USBD_DCD_INT_fops->Suspend(&USB_Device_dev); /* enter macrocell in suspend and system in low power mode when USB_DEVICE_LOW_PWR_MGMT_SUPPORT defined in usb_conf.h */ Suspend(); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_SOF) if (wIstr & ISTR_SOF & wInterrupt_Mask) { _SetISTR((uint16_t)CLR_SOF); USBD_DCD_INT_fops->SOF(&USB_Device_dev); } #endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ #if (IMR_MSK & ISTR_ESOF) if (wIstr & ISTR_ESOF & wInterrupt_Mask) { /* clear ESOF flag in ISTR */ _SetISTR((uint16_t)CLR_ESOF); /* resume handling timing is made with ESOFs */ Resume(RESUME_ESOF); /* request without change of the machine state */ } #endif #ifdef LPM_ENABLED #if (IMR_MSK & ISTR_L1REQ) if (wIstr & ISTR_L1REQ & wInterrupt_Mask) { /* clear L1REQ flag in ISTR */ _SetISTR((uint16_t)CLR_L1REQ); /* read BESL field which coressponds to HIRD parameter in LPM spec*/ /* In your application depending on BESL value, you can choose the right low power mode during L1 state, allowing wakeup time within the request time from host.*/ BESL = (_GetLPMCSR()&LPMCSR_BESL) >>4 ; /* read REMWAKE bit which corresponding to bRemoteWake bit in LPM request*/ /* if this bit is set then L1 remote wakeup is possible */ L1_remote_wakeup = (_GetLPMCSR()&LPMCSR_REMWAKE) >>3; /* process library core layer suspend routine*/ USBD_DCD_INT_fops->Suspend(&USB_Device_dev); /* enter macrocell in suspend and system in low power mode (STOP mode) when USB_DEVICE_LOW_PWR_MGMT_SUPPORT defined in usb_conf.h.*/ /* Please note that in this example we enter in STOP mode during L1 state independently from value read in BESL (even for BESL= 0 which corresponds to 50us delay) because STM32F072 can wakeup system from STOP mode in less than 50 us */ Suspend(); }
/******************************************************************************* * Function Name : CTR_LP. * Description : Low priority Endpoint Correct Transfer interrupt's service * routine. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void CTR_LP(void) { u32 wEPVal = 0; // wIstr = *ISTR; /* stay in loop while pending ints */ while (((wIstr = (*ISTR)) & ISTR_CTR) != 0) //正确传输 { _SetISTR((u16)CLR_CTR); /* clear CTR flag 清正确传输中断*/ /* extract highest priority endpoint number */ EPindex = (u8)(wIstr & ISTR_EP_ID);//ISTR_EP_ID (0x000F) 这个只读,所以与0X000F& if (EPindex == 0) //如果是端点0 { /* Decode and service control endpoint interrupt */ /* calling related service routine */ /* (Setup0_Process, In0_Process, Out0_Process) */ /* save RX & TX status */ /* and set both to NAK */ SaveRState = _GetEPRxStatus(ENDP0); SaveTState = _GetEPTxStatus(ENDP0); _SetEPRxStatus(ENDP0, EP_RX_NAK); //当一次正确的OUT或SETUP数据传输完成后(CTR_RX=1), _SetEPTxStatus(ENDP0, EP_TX_NAK); //硬件会自动设置此位为NAK状态, //使应用程序有足够的时间在处理完当前传输的数据后, //响应下一个数据分组。 /* DIR bit = origin of the interrupt */ if ((wIstr & ISTR_DIR) == 0) //0x0010 如果是输入 { /* DIR = 0 */ /* DIR = 0 => IN int */ /* DIR = 0 implies that (EP_CTR_TX = 1) always */ _ClearEP_CTR_TX(ENDP0); In0_Process(); /* before terminate set Tx & Rx status */ _SetEPRxStatus(ENDP0, SaveRState); _SetEPTxStatus(ENDP0, SaveTState); return; } else //输出 { /* DIR = 1 */ /* DIR = 1 & CTR_RX => SETUP or OUT int */ /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ //EP0的值 wEPVal =(u16)(*((volatile unsigned *)(0x40005C00L) + ENDP0)); if ((wEPVal & EP_CTR_TX) != 0) //硬件在一个正确的IN分组传输完成后置位 { _ClearEP_CTR_TX(ENDP0); In0_Process(); /* before terminate set Tx & Rx status */ _SetEPRxStatus(ENDP0, SaveRState); //SaveTState=EP_TX_STALL; 在In0_Process() _SetEPTxStatus(ENDP0, SaveTState); //SaveTState=EP_TX_STALL; 在In0_Process() return; } //控制传输由3个阶段组成,首先是主机发送SETUP分组的SETUP阶段, //然后是主机发送零个或多个数据的数据阶段,最后是状态阶段,由与数据阶段方向相反的数据分组构成 //据SETUP分组的相应字段决定后面的传输是IN还是OUT。 else if ((wEPVal &EP_SETUP) != 0) //在USB模块收到一个正确的SETUP分组后由硬件置位 { _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */ Setup0_Process(); /* before terminate set Tx & Rx status */ _SetEPRxStatus(ENDP0, SaveRState); _SetEPTxStatus(ENDP0, SaveTState); return; } else if ((wEPVal & EP_CTR_RX) != 0) { _ClearEP_CTR_RX(ENDP0); Out0_Process(); /* before terminate set Tx & Rx status */ _SetEPRxStatus(ENDP0, SaveRState); _SetEPTxStatus(ENDP0, SaveTState); return; } } }/* if(EPindex == 0) */ else { /* Decode and service non control endpoints interrupt */ /* process related endpoint register */ wEPVal = (u16)(*((volatile unsigned *)(0x40005C00L) + EPindex)); if ((wEPVal & EP_CTR_RX) != 0) { /* clear int flag */ _ClearEP_CTR_RX(EPindex); /* call OUT service function */ (*pEpInt_OUT[EPindex-1])(); } /* if((wEPVal & EP_CTR_RX) */ if ((wEPVal & EP_CTR_TX) != 0) { /* clear int flag */ _ClearEP_CTR_TX(EPindex); /* call IN service function */ // (*pEpInt_IN[EPindex-1])(); } /* if((wEPVal & EP_CTR_TX) != 0) */ }/* if(EPindex == 0) else */ }/* while(...) */ }