📄 stm32f_usb.c
字号:
// Disable receiving (only singe direction is possible)
EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_DISABLED);
WriteEpDTB_AddrRx(EpSlot,Offset1);
WriteEpDTB_CountRx(EpSlot,0);
EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_ISO);
EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0);
// Enable EP
EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_VALID);
break;
case EP_INTERRUPT:
EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_INTERRUPT);
EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0);
// Enable EP
EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_NAK);
break;
default: // EP_BULK_DOUB_BUF
// Disable receiving (only singe direction is possible)
EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_DISABLED);
// All buffers are empties
EpInfo[EndPoint].EpIntrFl = 1;
// Clear Tx Software toggle
WriteEpDTB_AddrRx(EpSlot,Offset1);
WriteEpDTB_CountRx(EpSlot,0);
EpCtrlSet_DTOG_RX(pEpCtrlBaseAddr,0);
EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_BULK_SING_BUFF);
EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,1);
// Enable EP
EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_NAK);
}
// Clear Correct Transfer for transmission flag
EpCtrlClr_CTR_TX(pEpCtrlBaseAddr);
}
else
{
RxCount_t RxCount = {0};
// OUT EP
// Disable EP
EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_DISABLED);
// Clear Rx toggle
EpCtrlSet_DTOG_RX(pEpCtrlBaseAddr,0);
// Clear Correct Transfer for reception flag
EpCtrlClr_CTR_RX(pEpCtrlBaseAddr);
// Update EP description table
RxCount.BlSizeField = (MaxPacketSize > 62);
RxCount.NubBlockField = (MaxPacketSize > 62) ? (MaxPacketSize>>5)-1:MaxPacketSizeTmp>>1;
WriteEpDTB_AddrRx(EpSlot,Offset);
WriteEpDTB_CountRx(EpSlot,RxCount.Count);
// Set EP Kind & enable
switch(EpType)
{
case EP_BULK_SING_BUFF:
EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_BULK_SING_BUFF);
EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0);
// Enable EP
EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_VALID);
break;
case EP_CTRL:
EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_CTRL);
EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0);
// Enable EP
EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_NAK);
break;
case EP_ISO:
WriteEpDTB_CountTx(EpSlot,RxCount.Count);
// Disable transmitting (only singe direction is possible)
EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_DISABLED);
WriteEpDTB_AddrTx(EpSlot,Offset1);
EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_ISO);
EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0);
// Enable EP
EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_VALID);
break;
case EP_INTERRUPT:
EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_INTERRUPT);
EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0);
// Enable EP
EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_VALID);
break;
default: // EP_BULK_DOUB_BUF
// All buffers are empties
EpInfo[EndPoint].EpIntrFl = 0;
// Disable transmitting (only singe direction is possible)
EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_DISABLED);
WriteEpDTB_CountTx(EpSlot,RxCount.Count);
WriteEpDTB_AddrTx(EpSlot,Offset1);
EpCtrlSet_DTOG_TX(pEpCtrlBaseAddr,0);
EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_BULK_SING_BUFF);
EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,1);
// Enable EP
EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_VALID);
}
}
}
else
{
pEpCtrlBaseAddr = (pInt32U)&USB_EP0R;
pEpCtrlBaseAddr += EpSlot;
if(EndPoint & 1)
{
// Disable IN EP
EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_DISABLED);
// Clear Correct Transfer for reception flag
EpCtrlClr_CTR_TX(pEpCtrlBaseAddr);
}
else
{
// Disable OUT EP
EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_DISABLED);
// Clear Correct Transfer for reception flag
EpCtrlClr_CTR_RX(pEpCtrlBaseAddr);
}
// release buffer
USB_ReleaseBuffer(EndPoint);
EpInfo[EndPoint].pEpCtrl = NULL;
}
return(USB_OK);
}
/*************************************************************************
* Function Name: USB_SetAdd
* Parameters: Int32U DevAdd - device address between 0 - 127
*
* Return: none
*
* Description: Set device address
*
*************************************************************************/
void USB_SetAdd(Int32U DevAdd)
{
USB_DADDR = DevAdd | 0x80;
}
/*************************************************************************
* Function Name: USB_ConnectRes
* Parameters: Boolean Conn
*
* Return: none
*
* Description: Enable Pull-Up resistor
*
*************************************************************************/
void USB_ConnectRes (Boolean Conn)
{
GPIO_WriteBit(GPIOC,GPIO_Pin_11,((Conn)?Bit_RESET:Bit_SET));
}
/*************************************************************************
* Function Name: USB_Configure
* Parameters: Boolean Configure
*
* Return: none
*
* Description: Configure device
* When Configure != 0 enable all Realize Ep
*
*************************************************************************/
static
void USB_Configure (Boolean Configure)
{
}
/*************************************************************************
* Function Name: USB_Suspend
* Parameters: void
*
* Return: none
*
* Description: Suspend the USB engine
*
*************************************************************************/
static
void USB_Suspend(void)
{
USB_CNTR_bit.FSUSP = 1;
USB_CNTR_bit.LPMODE = 1;
}
#if USB_REMOTE_WAKEUP != 0
/*************************************************************************
* Function Name: USB_WakeUp
* Parameters: none
*
* Return: none
*
* Description: Wake up Usb
*
*************************************************************************/
static
void USB_WakeUp (void)
{
USB_Resume(USB_RESUME_SOFT_EVENT);
}
#endif // USB_REMOTE_WAKEUP != 0
/*************************************************************************
* Function Name: USB_Resume
* Parameters: UsbResumeEvent_t UsbResumeEvent
*
* Return: none
*
* Description: USB Resume implement
*
*************************************************************************/
static
void USB_Resume (UsbResumeEvent_t UsbResumeEvent)
{
Int32U LineStates;
switch(UsbResumeEvent)
{
case USB_RESUME_SOF_EVENT:
if(DlyCnt)
{
// Waiting 8ms (not take more than 10ms) before release signal to host
if(--DlyCnt == 0)
{
USB_CNTR_bit.ESOFM = 0;
USB_CNTR_bit.RESUME = 0;
USB_CNTR_bit.FSUSP = 0; // Must be 0
if(UsbUserFun[UsbUserSuspend] != NULL)
{
UsbUserFun[UsbUserSuspend]((void *)0);
}
}
}
break;
case USB_RESUME_SOFT_EVENT: // resume by USER
USB_CNTR_bit.LPMODE = 0;
DlyCnt = USB_RESUME_DLY;
USB_CNTR_bit.RESUME = 1;
USB_CNTR_bit.ESOFM = 1;
UsbDevSuspendCallback(FALSE);
break;
case USB_RESUME_WAKE_UP_EVENT: // resume by HOST
LineStates = USB_FNR & 0xC000;
if((LineStates == 0x8000) && (LineStates == 0x3000))
{
// noise return to suspend again
USB_Suspend();
}
else if(LineStates)
{
// wake-up
USB_CNTR_bit.LPMODE = 0;
USB_CNTR_bit.FSUSP = 0; // Must be 0
UsbDevSuspendCallback(FALSE);
}
break;
}
}
/*************************************************************************
* Function Name: USB_GetDevStatus
* Parameters: USB_DevStatusReqType_t Type
*
* Return: Boolean
*
* Description: Return USB device status
*
*************************************************************************/
Boolean USB_GetDevStatus (USB_DevStatusReqType_t Type)
{
switch (Type)
{
case USB_DevConnectStatus:
return(TRUE);
case USB_SuspendStatus:
return(USB_CNTR_bit.FSUSP);
case USB_ResetStatus:
return(USB_CNTR_bit.FRES);
}
return(FALSE);
}
/*************************************************************************
* Function Name: USB_SetStallEP
* Parameters: USB_Endpoint_t EndPoint, Boolean Stall
*
* Return: USB_ErrorCodes_t
*
* Description: The endpoint stall/unstall
*
*************************************************************************/
USB_ErrorCodes_t USB_SetStallEP (USB_Endpoint_t EndPoint, Boolean Stall)
{
if( EpInfo[EndPoint].pEpCtrl == NULL)
{
return(USB_EP_NOT_VALID);
}
if(Stall)
{
if(EndPoint & 1)
{
// IN EP
EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_STALL);
}
else
{
// OUT EP
EpCtrlSet_STAT_RX(EpInfo[EndPoint].pEpCtrl,EP_STALL);
}
}
else if(EndPoint & 1)
{
// IN EP
// reset Data Toggle bit
switch(EpInfo[EndPoint].EpType)
{
case EP_BULK_DOUB_BUF:
EpInfo[EndPoint].EpIntrFl = 1;
EpCtrlSet_DTOG_RX(EpInfo[EndPoint].pEpCtrl,0);
case EP_INTERRUPT:
case EP_ISO:
case EP_BULK_SING_BUFF:
EpCtrlSet_DTOG_TX(EpInfo[EndPoint].pEpCtrl,0);
}
EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_NAK);
}
else
{
// OUT EP
// reset Data Toggle bit
switch(EpInfo[EndPoint].EpType)
{
case EP_BULK_DOUB_BUF:
EpInfo[EndPoint].EpIntrFl = 0;
EpCtrlSet_DTOG_TX(EpInfo[EndPoint].pEpCtrl,0);
case EP_INTERRUPT:
case EP_ISO:
case EP_BULK_SING_BUFF:
EpCtrlSet_DTOG_RX(EpInfo[EndPoint].pEpCtrl,0);
}
EpCtrlSet_STAT_RX(EpInfo[EndPoint].pEpCtrl,EP_NAK);
}
return(USB_OK);
}
/*************************************************************************
* Function Name: USB_GetStallEP
* Parameters: USB_Endpoint_t EndPoint, pBoolean pStall
*
* Return: USB_ErrorCodes_t
*
* Description: Get stall state of the endpoint
*
*************************************************************************/
static
USB_ErrorCodes_t USB_GetStallEP (USB_Endpoint_t EndPoint, pBoolean pStall)
{
if(EpInfo[EndPoint].pEpCtrl == NULL)
{
return(USB_EP_NOT_VALID);
}
*pStall = (EndPoint & 1)?
(EpCtrlGet_STAT_TX(EpInfo[EndPoint].pEpCtrl) == EP_STALL): // IN EP
(EpCtrlGet_STAT_RX(EpInfo[EndPoint].pEpCtrl) == EP_STALL); // OUT EP
return (USB_OK);
}
/*************************************************************************
* Function Name: USB_EpValidate
* Parameters: USB_Endpoint_t EndPoint, Boolean State
*
* Return: USB_ErrorCodes_t
*
* Description: Validate/Unvalidate EP buffer
*
*************************************************************************/
USB_ErrorCodes_t USB_EpValidate( USB_Endpoint_t EndPoint, Boolean State)
{
if( EpInfo[EndPoint].pEpCtrl == NULL)
{
return(USB_EP_NOT_VALID);
}
if(EndPoint & 1)
{
// IN EP (Tx)
if (State)
{
// Validate buffer
EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
}
else
{
// Unvalidate buffer
EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_NAK);
EpCtrlClr_CTR_TX(EpInfo[EndPoint].pEpCtrl);
}
}
else
{
// OUT EP (Rx)
if (State)
{
// Validate buffer
EpCtrlSet_STAT_RX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
}
else
{
// Unvalidate buffer
EpCtrlSet_STAT_RX(EpInfo[EndPoint].pEpCtrl,EP_NAK);
EpCtrlClr_CTR_RX(EpInfo[EndPoint].pEpCtrl);
}
}
return(USB_OK);
}
/*************************************************************************
* Function Name: USB_EpWrite
* Parameters: USB_Endpoint_t EndPoint, pInt8U pData, pInt32U pCount
*
* Return: USB_ErrorCodes_t
*
* Description: Endpoint Write (IN)
*
*************************************************************************/
USB_ErrorCodes_t USB_EpWrite (USB_Endpoint_t EndPoint, pInt8U pData,
pInt32U pCount)
{
__usb_epr_bits EpState;
pInt32U pDst;
Int32U ActSize, Temp, Count, CurrSize, SizeHold;
ActSize = *pCount;
*pCount = 0;
if(EpInfo[EndPoint].pEpCtrl == NULL)
{
return(USB_EP_NOT_VALID);
}
EpState = *(__usb_epr_bits *)EpInfo[EndPoint].pEpCtrl;
if(EpState.STATTX == EP_DISABLED)
{
// Fatal error (require restart of the USB)
return(USB_EP_FATAL_ERROR);
}
switch(EpInfo[EndPoint].EpType)
{
case EP_INTERRUPT:
if (EpState.STATTX == EP_STALL)
{
// EP stalled
return(USB_EP_STALLED);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -