/** * @brief STR events interrupt service routine. * @param None. * @retval None. */ void SdkEvalVCIntServRoutine(void) { 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); SdkEvalVCResume(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) { SdkEvalVCSuspend(); } else { /* if not possible then resume after xx ms */ SdkEvalVCResume(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) { _SetISTR((uint16_t)CLR_ESOF); /* resume handling timing is made with ESOFs */ SdkEvalVCResume(RESUME_ESOF); /* request without change of the machine state */ #ifdef ESOF_CALLBACK ESOF_Callback(); #endif } #endif }
/******************************************************************************* * 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_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) { /* 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); /*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 } /* USB_Istr */
/* overloaded ISR routine, this is the main usb ISR */ void usb_lpIRQHandler(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 }
/******************************************************************************* * 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; /* 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(); /* 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 */ wEPVal = _GetENDPOINT(ENDP0); if ((wEPVal & EP_CTR_TX) != 0) { _ClearEP_CTR_TX(ENDP0); In0_Process(); /* before terminate set Tx & Rx status */ _SetEPRxStatus(ENDP0, SaveRState); _SetEPTxStatus(ENDP0, SaveTState); return; } else if ((wEPVal &EP_SETUP) != 0) { _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 = _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(...) */ }
/******************************************************************************* * 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 } }