📄 stm32f_usb.c
字号:
UsbUserFun[EpPhAddr]((void *)UsbDataOutPacket);
}
}
else
{
// IN EP
EpCtrlClr_CTR_TX(EpInfo[EpPhAddr].pEpCtrl);
Status = EpCtrlGet_DTOG_RX(EpInfo[EpPhAddr].pEpCtrl);
if(Status == EpCtrlGet_DTOG_TX(EpInfo[EpPhAddr].pEpCtrl))
{
// The both buffers are drained
++EpInfo[EpPhAddr].EpIntrFl;
}
if(UsbUserFun[EpPhAddr] != NULL)
{
UsbUserFun[EpPhAddr]((void *)UsbDataInPacket);
}
}
}
}
#endif // USB_HIGH_PRIORITY_EVENT > 0
/*************************************************************************
* Function Name: USB_ISR
* Parameters: none
*
* Return: none
*
* Description: USB interrupt subroutine
*
*************************************************************************/
void USB_ISR (void)
{
IntrStatus_t IntrStatus;
Int32U EpPhAddr;
Boolean SetupPacket;
// Get masked interrupt flags
IntrStatus.Status = USB_ISTR;
IntrStatus.Status &= USB_CNTR | 0x1F;
#if USB_DOVR_EVENT > 0
// DMA over / underrun (for speed up retry process)
if(IntrStatus.DOVR)
{
USB_ISTR = ~bmDOVR;
if(UsbUserFun[UsbDovrEvent] != NULL)
{
UsbUserFun[UsbDovrEvent]((void *)Val);
}
}
#endif
#if USB_ERROR_EVENT > 0
// USB engine error interrupt
if(IntrStatus.ERR)
{
USB_ISTR = ~bmERRM;
if(UsbUserFun[UsbErrorEvent] != NULL)
{
UsbUserFun[UsbErrorEvent](NULL);
}
}
#endif
// Device reset
if(IntrStatus.RESET)
{
USB_ISTR = ~bmRESETM;
USB_HwReset();
UsbDevConnectCallback(TRUE);
UsbDevResetCallback();
UsbDevSuspendCallback(FALSE);
}
#if USB_SOF_EVENT > 0
// Frame interrupt
if(IntrStatus.SOF)
{
USB_ISTR = ~bmSOFM;
if(UsbUserFun[UsbUserSofEvent] != NULL)
{
UsbUserFun[UsbUserSofEvent]((void *)NULL);
}
}
#endif
// Wake-up interrupt
if(IntrStatus.WKUP)
{
USB_ISTR = ~(bmSUSPM | bmWKUPM);
USB_Resume(USB_RESUME_WAKE_UP_EVENT);
}
// Device suspend
if(IntrStatus.SUSP)
{
USB_Suspend();
USB_ISTR = ~(bmSUSPM | bmWKUPM);
UsbDevSuspendCallback(TRUE);
}
// Expected Frame interrupt
if(IntrStatus.ESOF)
{
USB_ISTR = ~bmESOFM;
USB_Resume(USB_RESUME_SOF_EVENT);
}
// Low priority EP interrupt
if(IntrStatus.CTR)
{
// find corresponding EP
pInt32U pReg = (pInt32U)&USB_EP0R;
pReg += IntrStatus.EP_ID;
EpPhAddr = ((*pReg & 0xF) << 1) + (IntrStatus.DIR?0:1);
// The ISO and Double buffered endpoints have own interrupt (HIGH_INTR)
if((EpInfo[EpPhAddr].EpType != EP_ISO) &&
(EpInfo[EpPhAddr].EpType != EP_BULK_DOUB_BUF))
{
if(EpPhAddr == CTRL_ENP_OUT)
{
// determinate type of packet (only for control EP)
SetupPacket = EpCtrlGet_SETUP(EpInfo[EpPhAddr].pEpCtrl);
EpCtrlClr_CTR_RX(EpInfo[EpPhAddr].pEpCtrl);
if(UsbUserFun[UsbEp0Out] != NULL)
{
// call appropriate callback function
if(SetupPacket)
{
UsbUserFun[UsbEp0Out]((void *)UsbSetupPacket);
}
else
{
UsbUserFun[UsbEp0Out]((void *)UsbDataOutPacket);
}
}
}
else if (EpPhAddr & 1)
{
// OUT EP
EpCtrlClr_CTR_TX(EpInfo[EpPhAddr].pEpCtrl);
if(UsbUserFun[EpPhAddr] != NULL)
{
UsbUserFun[EpPhAddr]((void *)UsbDataInPacket);
}
}
else
{
// IN EP
EpCtrlClr_CTR_RX(EpInfo[EpPhAddr].pEpCtrl);
if(UsbUserFun[EpPhAddr] != NULL)
{
UsbUserFun[EpPhAddr]((void *)UsbDataOutPacket);
}
}
}
}
}
/*************************************************************************
* Function Name: UsbCtrlEp
* Parameters: void * pArg
*
* Return: none
*
* Description: USB Ctrl EP Callback
*
*************************************************************************/
static inline
void UsbCtrlEp (USB_PacketType_t Packet)
{
Int32U CurrCount;
if(Packet == UsbSetupPacket)
{
// Setup packet
UsbEp0Ctrl.EpStatus.Status = UsbSetupPhase;
UsbEp0Ctrl.pData = EpCtrlDataBuf;
UsbEp0Ctrl.Counter = Ep0MaxSize;
USB_EpRead(CTRL_ENP_OUT,EpCtrlDataBuf,&UsbEp0Ctrl.Counter);
// Copy new setup packet int setup buffer
memcpy((Int8U *)&UsbEp0SetupPacket,EpCtrlDataBuf,sizeof(UsbEp0SetupPacket));
if(UsbEp0Ctrl.Counter != sizeof(UsbSetupPacket_t))
{
UsbEp0SetupPacket.mRequestType.Type = UsbTypeReserved;
}
else
{
// validate OUT/IN EP
USB_EpValidate(CTRL_ENP_OUT,TRUE);
USB_SetStallEP(CTRL_ENP_IN,FALSE);
}
switch(UsbEp0SetupPacket.mRequestType.Type)
{
// Standard
case UsbTypeStandart:
// Decoding standard request
switch (UsbEp0SetupPacket.bRequest)
{
case GET_STATUS:
UsbGetStatus();
break;
case CLEAR_FEATURE:
UsbClearFeature();
break;
case SET_FEATURE:
UsbSetFeature();
break;
case SET_ADDRESS:
UsbSetAddress();
break;
case GET_DESCRIPTOR:
if(UsbEp0SetupPacket.mRequestType.Recipient == UsbRecipientDevice)
{
UsbGetDescriptor();
}
// Only get descriptor for device is standard request
else if ((UsbEp0SetupPacket.mRequestType.Dir == UsbDevice2Host) &&
(UsbUserFun[UsbUserGetDescriptor] != NULL) &&
((Int32U)UsbUserFun[UsbUserGetDescriptor](&UsbEp0Ctrl) == UsbPass))
{
if(UsbEp0Ctrl.Counter >= UsbEp0SetupPacket.wLength.Word)
{
UsbEp0Ctrl.Counter = UsbEp0SetupPacket.wLength.Word;
UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE;
}
else
{
UsbEp0Ctrl.EpStatus.NoZeroLength = FALSE;
}
UsbEp0Ctrl.EpStatus.Status = UsbDataPhase;
}
else
{
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
break;
case SET_DESCRIPTOR:
// Optional (only for configuration and string descriptors)
UsbSetDescriptor();
break;
case GET_CONFIGURATION:
UsbGetConfiguration();
break;
case SET_CONFIGURATION:
UsbSetConfiguration();
break;
case GET_INTERFACE:
UsbGetInterface();
break;
case SET_INTERFACE:
UsbSetInterface();
break;
case SYNCH_FRAME:
UsbSynchFrame();
break;
default:
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
break;
// Class
case UsbTypeClass:
if(UsbUserFun[UsbUserClass] != NULL &&
((Int32U)UsbUserFun[UsbUserClass](&UsbEp0Ctrl) == UsbPass))
{
if(UsbEp0Ctrl.Counter >= UsbEp0SetupPacket.wLength.Word)
{
UsbEp0Ctrl.Counter = UsbEp0SetupPacket.wLength.Word;
UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE;
}
else
{
UsbEp0Ctrl.EpStatus.NoZeroLength = FALSE;
}
UsbEp0Ctrl.EpStatus.Status = UsbDataPhase;
}
else
{
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
break;
// Vendor
case UsbTypeVendor:
if(UsbUserFun[UsbUserVendor] != NULL &&
((Int32U)UsbUserFun[UsbUserVendor](&UsbEp0Ctrl) == UsbPass))
{
if(UsbEp0Ctrl.Counter >= UsbEp0SetupPacket.wLength.Word)
{
UsbEp0Ctrl.Counter = UsbEp0SetupPacket.wLength.Word;
UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE;
}
else
{
UsbEp0Ctrl.EpStatus.NoZeroLength = FALSE;
}
UsbEp0Ctrl.EpStatus.Status = UsbDataPhase;
}
else
{
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
break;
// Other
default:
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
}
switch (UsbEp0Ctrl.EpStatus.Status)
{
case UsbDataPhase:
if (UsbEp0SetupPacket.mRequestType.Dir == UsbHost2Device)
{
if (Packet == UsbDataOutPacket)
{
// Data receiving
CurrCount = Ep0MaxSize;
USB_EpRead(CTRL_ENP_OUT,UsbEp0Ctrl.pData,&CurrCount);
UsbEp0Ctrl.pData += CurrCount;
UsbEp0Ctrl.Counter -= CurrCount;
// Receiving of data complete when all data was received or
// when host send short packet
if ((UsbEp0Ctrl.Counter == 0) ||
(CurrCount < Ep0MaxSize))
{
// Find appropriate callback function depending of current request
// after data was received
switch (UsbEp0SetupPacket.mRequestType.Type)
{
case UsbTypeStandart:
if ((UsbCoreT9Fun != NULL) &&
((Int32U)UsbCoreT9Fun(NULL) == UsbPass))
{
UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
}
else
{
// Stall EP if callback function isn't set, but host
// send this type request or when callback function
// return an error.
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
UsbCoreT9Fun = NULL;
break;
case UsbTypeClass:
if ((UsbUserFun[UsbClassEp0OutPacket] != NULL) &&
((Int32U)UsbUserFun[UsbClassEp0OutPacket](NULL) == UsbPass))
{
UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
}
else
{
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
break;
case UsbTypeVendor:
if ((UsbUserFun[UsbVendorEp0OutPacket] != NULL) &&
((Int32U)UsbUserFun[UsbVendorEp0OutPacket](NULL) == UsbPass))
{
UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
}
else
{
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
break;
default:
UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
}
if(UsbEp0Ctrl.EpStatus.Status == UsbStatusPhase)
{
CurrCount = 0;
USB_EpWrite(CTRL_ENP_IN,NULL,&CurrCount);
UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
}
}
}
else if (UsbEp0Ctrl.Counter == 0)
{
CurrCount = 0;
USB_EpWrite(CTRL_ENP_IN,NULL,&CurrCount);
UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
}
}
else
{
// Data transmit
if (Packet == UsbDataOutPacket)
{
USB_EpValidate(CTRL_ENP_OUT,TRUE);
UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
break;
}
CurrCount = Ep0MaxSize;
if ((UsbEp0Ctrl.Counter == 0) && UsbEp0Ctrl.EpStatus.NoZeroLength)
{
UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
break;
}
else if(UsbEp0Ctrl.Counter < Ep0MaxSize)
{
UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE;
CurrCount = UsbEp0Ctrl.Counter;
}
USB_EpWrite(CTRL_ENP_IN,UsbEp0Ctrl.pData,&CurrCount);
UsbEp0Ctrl.Counter -= CurrCount;
UsbEp0Ctrl.pData += CurrCount;
}
break;
case UsbStatusPhase:
if (UsbEp0SetupPacket.bRequest == SET_ADDRESS)
{
// Device address is set after status phase of set address request
UsbDevCtrl.DevAdd = UsbEp0SetupPacket.wValue.Lo;
USB_SetAdd(UsbDevCtrl.DevAdd);
if(UsbDevCtrl.DevAdd)
{
UsbSetDevState(UsbDevStatusAddress);
}
else
{
// when address is 0 put device int configuration state
UsbSetDevState(UsbDevStatusDefault);
}
}
if (Packet == UsbDataOutPacket)
{
USB_EpValidate(CTRL_ENP_OUT,TRUE);
}
UsbEp0Ctrl.EpStatus.Status = UsbSetupPhase;
break;
default:
// Error
USB_SetStallEP(CTRL_ENP_IN,TRUE);
USB_SetStallEP(CTRL_ENP_OUT,TRUE);
UsbEp0Ctrl.EpStatus.Status = UsbSetupPhase;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -