?? stm32f_usb.c
字號:
}
else if(EpState.STATTX == EP_VALID)
{
// Data sending in progress
return(USB_OK);
}
// Get is smaller of user buffer and received data.
SizeHold = MIN(EpInfo[EndPoint].MaxSize,ActSize);
WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,SizeHold);
pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
for (Count = 0; Count < SizeHold; ++Count)
{
Temp = *pData++;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 8;
}
*pDst++ = Temp;
}
// Validate buffer
EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
break;
case EP_CTRL:
if(EpState.STATTX == EP_VALID)
{
// Data sending in progress
return(USB_OK);
}
// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpInfo[EndPoint].MaxSize,ActSize);
WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,SizeHold);
pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
for (Count = 0; Count < SizeHold; ++Count)
{
Temp = *pData++;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 8;
}
*pDst++ = Temp;
}
// Validate buffer
EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
break;
case EP_ISO:
if(EpState.DTOGTX)
{
// Tx Buffer
pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpInfo[EndPoint].MaxSize,SizeHold);
for (Count = 0; Count < SizeHold; ++Count)
{
Temp = *pData++;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 8;
}
*pDst++ = Temp;
}
WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,SizeHold);
}
else
{
// Rx Buffer
pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpInfo[EndPoint].MaxSize,SizeHold);
for (Count = 0; Count < SizeHold; ++Count)
{
Temp = *pData++;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 8;
}
*pDst++ = Temp;
}
WriteEpDTB_CountRx(EpInfo[EndPoint].EpSlot,SizeHold);
}
break;
case EP_BULK_SING_BUFF:
if (EpState.STATTX == EP_STALL)
{
// EP stalled
return(USB_EP_STALLED);
}
else if(EpState.STATTX == EP_VALID)
{
// Data sending in progress
return(USB_OK);
}
/// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpInfo[EndPoint].MaxSize,ActSize);
WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,SizeHold);
pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
for (Count = 0; Count < SizeHold; ++Count)
{
Temp = *pData++;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 8;
}
*pDst++ = Temp;
}
// Validate buffer
EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
break;
case EP_BULK_DOUB_BUF:
// Double buffered
if (EpState.STATTX == EP_STALL)
{
// EP stalled
return(USB_EP_STALLED);
}
SizeHold = 0;
do
{
// Check for a pending TX interrupt
if(!EpCtrlGet_CTR_TX(EpInfo[EndPoint].pEpCtrl) &&
!EpInfo[EndPoint].EpIntrFl &&
(EpState.DTOGRX == EpCtrlGet_DTOG_TX(EpInfo[EndPoint].pEpCtrl)))
{
// All buffers are filled
break;
}
// Get smaller of the rest of the user buffer and the received data.
CurrSize = MIN(EpInfo[EndPoint].MaxSize,(ActSize-SizeHold));
if(!EpState.DTOGRX)
{
// Tx Buffer
pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,CurrSize);
}
else
{
// Rx Buffer
pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
WriteEpDTB_CountRx(EpInfo[EndPoint].EpSlot,CurrSize);
}
for (Count = 0; Count < CurrSize; ++Count)
{
Temp = *pData++;
if (++Count < CurrSize)
{
Temp |= (*pData++) << 8;
}
*pDst++ = Temp;
}
EpInfo[EndPoint].EpIntrFl = 0;
// Clear for pending TX interrupt
EpCtrlClr_CTR_TX(EpInfo[EndPoint].pEpCtrl);
EpCtrlToggle_DTOG_RX(EpInfo[EndPoint].pEpCtrl);
// Update RX toggle status
EpState.DTOGRX ^= 1;
EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
SizeHold += CurrSize;
} while(SizeHold < ActSize);
break;
default:
// Fatal error (require restart of the USB)
return(USB_EP_FATAL_ERROR);
}
*pCount = SizeHold;
return(USB_OK);
}
/*************************************************************************
* Function Name: USB_EpRead
* Parameters: USB_Endpoint_t EndPoint, pInt8U pData, pInt32U pCount
*
* Return: USB_ErrorCodes_t
*
* Description: Endpoint Read (OUT)
*
*************************************************************************/
USB_ErrorCodes_t USB_EpRead (USB_Endpoint_t EndPoint, pInt8U pData,
pInt32U pCount)
{
volatile pInt32U pSrc;
Int32U ActSize = *pCount, EpCount;
__usb_epr_bits EpState;
Int32U Temp;
Int32U CurrSize,SizeHold;
Int32U Count;
*pCount = 0;
if(EpInfo[EndPoint].pEpCtrl == NULL)
{
return(USB_EP_NOT_VALID);
}
EpState = *(__usb_epr_bits *)EpInfo[EndPoint].pEpCtrl;
if(EpState.STATRX == EP_DISABLED)
{
return(USB_EP_FATAL_ERROR);
}
switch (EpInfo[EndPoint].EpType)
{
case EP_CTRL:
if(EpState.STATRX == EP_VALID)
{
// Data is not received yet.
return(UB_EP_SETUP_UNDERRUN);
}
// Get received bytes number
EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot) & 0x3FF;
// Get address of the USB packet buffer for corresponding EP
pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpCount,ActSize);
for(Count = 0; Count < SizeHold; ++Count)
{
Temp = *pSrc++;
*pData++ = Temp;
if(++Count <= SizeHold) // fix overwrite problem with odd number of bytes
{
*pData++ = Temp>>8;
}
}
*pCount = SizeHold;
if(EpCtrlGet_SETUP(EpInfo[EndPoint].pEpCtrl))
{
return(UB_EP_SETUP_OVERWRITE);
}
break;
case EP_ISO:
if(EpState.DTOGRX)
{
EpCount = ReadEpDTB_CountTx(EpInfo[EndPoint].EpSlot) & 0x3FF;
pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
}
else
{
EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot) & 0x3FF;
pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
}
// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpCount,ActSize);
for(Count = 0; Count < SizeHold; ++Count)
{
Temp = *pSrc++;
*pData++ = Temp;
if(++Count <= SizeHold) // fix overwrite problem with odd number of bytes
{
*pData++ = Temp>>8;
}
}
break;
case EP_INTERRUPT:
if (EpState.STATRX == EP_STALL)
{
return(USB_EP_STALLED);
}
else if (EpState.STATRX == EP_VALID)
{
return(UB_EP_SETUP_UNDERRUN);
}
EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot) & 0x3FF;
pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpCount,ActSize);
for(Count = 0; Count < SizeHold; ++Count)
{
Temp = *pSrc++;
*pData++ = Temp;
if(++Count <= SizeHold) // fix overwrite problem with odd number of bytes
{
*pData++ = Temp>>8;
}
}
break;
case EP_BULK_SING_BUFF:
// Single buffer
if (EpState.STATRX == EP_STALL)
{
return(USB_EP_STALLED);
}
else if (EpState.STATRX == EP_VALID)
{
return(UB_EP_SETUP_UNDERRUN);
}
EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot) & 0x3FF;
pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpCount,ActSize);
for(Count = 0; Count < SizeHold; ++Count)
{
Temp = *pSrc++;
*pData++ = Temp;
if(++Count <= SizeHold) // fix overwrite problem with odd number of bytes
{
*pData++ = Temp>>8;
}
}
break;
case EP_BULK_DOUB_BUF:
if (EpState.STATRX == EP_STALL)
{
return(USB_EP_STALLED);
}
SizeHold = 0;
do
{
if(!EpInfo[EndPoint].EpIntrFl)
{
// Buffers are empties
break;
}
if(!EpState.DTOGTX)
{
EpCount = ReadEpDTB_CountTx(EpInfo[EndPoint].EpSlot) & 0x3FF;
pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
}
else
{
EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot) & 0x3FF;
pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
}
// the buffer size must be enough bigger to get all available data from
// the EP in other case remaining data will be lost
if(EpCount > (ActSize-SizeHold))
{
*pCount = SizeHold;
return (USB_BUF_OVERFLOW);
}
CurrSize = EpCount;
for(Count = 0; Count < CurrSize; ++Count)
{
Temp = *pSrc++;
*pData++ = Temp;
if(++Count <= CurrSize) // fix overwrite problem with odd number of bytes
{
*pData++ = Temp>>8;
}
}
EpCtrlToggle_DTOG_TX(EpInfo[EndPoint].pEpCtrl);
EpState.DTOGTX ^= 1;
SizeHold += CurrSize;
--EpInfo[EndPoint].EpIntrFl;
} while(SizeHold < ActSize);
break;
default:
return(USB_EP_FATAL_ERROR);
}
*pCount = SizeHold;
return (USB_OK);
}
/*************************************************************************
* Function Name: USB_EpLogToPhysAdd
* Parameters: Int8U EpLogAdd
*
* Return: USB_Endpoint_t
*
* Description: Convert the logical to physical address
*
*************************************************************************/
USB_Endpoint_t USB_EpLogToPhysAdd (Int8U EpLogAdd)
{
USB_Endpoint_t Address = (USB_Endpoint_t)((EpLogAdd & 0x0F)<<1);
if(EpLogAdd & 0x80)
{
++Address;
}
return(Address);
}
#if USB_SOF_EVENT > 0
/*************************************************************************
* Function Name: USB_GetFrameNumb
* Parameters: none
*
* Return: Int32U
*
* Description: Return current value of SOF number
*
*************************************************************************/
Int32U USB_GetFrameNumb (void)
{
return(USB_FNR_bit.FN);
}
#endif // USB_SOF_EVENT > 0
#if USB_HIGH_PRIORITY_EVENT > 0
/*************************************************************************
* Function Name: USB_HIGH_ISR
* Parameters: none
*
* Return: none
*
* Description: High priority USB interrupt subroutine
*
*************************************************************************/
void USB_HIGH_ISR (void)
{
IntrStatus_t IntrStatus;
Int32U EpPhAddr;
Int32U Status;
IntrStatus.Status = USB_ISTR;
IntrStatus.Status &= USB_CNTR | 0x1F;
// Get masked interrupt flags
if(IntrStatus.CTR)
{
// find corresponding EP
pInt32U pReg = (pInt32U)&USB_EP0R;
pReg += IntrStatus.EP_ID;
EpPhAddr = ((*pReg & 0xF) << 1) + (IntrStatus.DIR?0:1);
if(EpInfo[EpPhAddr].EpType == EP_BULK_DOUB_BUF)
{
EpInfo[EpPhAddr].EpIntrFl = 1;
}
if(IntrStatus.DIR == 1)
{
// OUT EP
EpCtrlClr_CTR_RX(EpInfo[EpPhAddr].pEpCtrl);
Status = EpCtrlGet_DTOG_TX(EpInfo[EpPhAddr].pEpCtrl);
if(Status == EpCtrlGet_DTOG_RX(EpInfo[EpPhAddr].pEpCtrl))
{
// The both buffers are filled
++EpInfo[EpPhAddr].EpIntrFl;
}
// Some times USB engine receive second packet
// after resetting of interrupt flag and before testing of
// toggle bits
if(EpCtrlGet_CTR_RX(EpInfo[EpPhAddr].pEpCtrl))
{
// Now both buffers are filled.
EpCtrlClr_CTR_RX(EpInfo[EpPhAddr].pEpCtrl);
EpInfo[EpPhAddr].EpIntrFl = 2;
}
if(UsbUserFun[EpPhAddr] != NULL)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -