📄 str91x_usb.c
字号:
}
// Validate buffer
EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
break;
case EP_CTRL:
if(EpState.STAT_TX == 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)(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot) +\
(Int32U)__segment_begin("USB_PACKET_MEMORY"));
for (Count = 0; Count < SizeHold; ++Count)
{
Temp = *pData++;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 8;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 16;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 24;
}
}
}
*pDst++ = Temp;
}
// Validate buffer
EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
break;
case EP_ISO:
if(EpState.DTOG_TX)
{
// Tx Buffer
pDst = (pInt32U)(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot) +\
(Int32U)__segment_begin("USB_PACKET_MEMORY"));
// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpInfo[EndPoint].MaxSize,ActSize);
for (Count = 0; Count < SizeHold; ++Count)
{
Temp = *pData++;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 8;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 16;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 24;
}
}
}
*pDst++ = Temp;
}
WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,SizeHold);
}
else
{
// Rx Buffer
pDst = (pInt32U)(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot) +\
(Int32U)__segment_begin("USB_PACKET_MEMORY"));
// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpInfo[EndPoint].MaxSize,ActSize);
for (Count = 0; Count < SizeHold; ++Count)
{
Temp = *pData++;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 8;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 16;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 24;
}
}
}
*pDst++ = Temp;
}
WriteEpDTB_CountRx(EpInfo[EndPoint].EpSlot,SizeHold);
}
break;
case EP_BULK_SING_BUFF:
if (EpState.STAT_TX == EP_STALL)
{
// EP stalled
return(USB_EP_STALLED);
}
else if(EpState.STAT_TX == 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)(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot) +\
(Int32U)__segment_begin("USB_PACKET_MEMORY"));
for (Count = 0; Count < SizeHold; ++Count)
{
Temp = *pData++;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 8;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 16;
if (++Count < SizeHold)
{
Temp |= (*pData++) << 24;
}
}
}
*pDst++ = Temp;
}
// Validate buffer
EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
break;
case EP_BULK_DOUB_BUF:
// Double buffered
if (EpState.STAT_TX == 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.DTOG_RX == 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.DTOG_RX)
{
// Tx Buffer
pDst = (pInt32U)(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot) +\
(Int32U)__segment_begin("USB_PACKET_MEMORY"));
WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,CurrSize);
}
else
{
// Rx Buffer
pDst = (pInt32U)(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot) +\
(Int32U)__segment_begin("USB_PACKET_MEMORY"));
WriteEpDTB_CountRx(EpInfo[EndPoint].EpSlot,CurrSize);
}
for (Count = 0; Count < CurrSize; ++Count)
{
Temp = *pData++;
if (++Count < CurrSize)
{
Temp |= (*pData++) << 8;
if (++Count < CurrSize)
{
Temp |= (*pData++) << 16;
if (++Count < CurrSize)
{
Temp |= (*pData++) << 24;
}
}
}
*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.DTOG_RX ^= 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.STAT_RX == EP_DISABLED)
{
return(USB_EP_FATAL_ERROR);
}
switch (EpInfo[EndPoint].EpType)
{
case EP_CTRL:
if(EpState.STAT_RX == EP_VALID)
{
// Data is not received yet.
return(UB_EP_SETUP_UNDERRUN);
}
// Get received bytes number
EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot);
WriteEpDTB_CountRx(EpInfo[EndPoint].EpSlot,EpCount & ~0x3FF);
EpCount &= 0x3FF;
// Get address of the USB packet buffer for corresponding EP
pSrc = (pInt32U)(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot)+\
(Int32U)__segment_begin("USB_PACKET_MEMORY"));
// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpCount,ActSize);
for(Count = 0; Count < SizeHold; ++Count)
{
Temp = *pSrc++;
*pData++ = Temp;
// fix overwrite problem with odd number of bytes
if(++Count <= SizeHold)
{
*pData++ = Temp>>8;
if(++Count <= SizeHold)
{
*pData++ = Temp>>16;
if(++Count <= SizeHold)
{
*pData++ = Temp>>24;
}
}
}
}
*pCount = ActSize;
if(EpCtrlGet_SETUP(EpInfo[EndPoint].pEpCtrl))
{
return(UB_EP_SETUP_OVERWRITE);
}
break;
case EP_ISO:
if(EpState.DTOG_RX)
{
EpCount = ReadEpDTB_CountTx(EpInfo[EndPoint].EpSlot) & 0x3FF;
pSrc = (pInt32U)(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot)+\
(Int32U)__segment_begin("USB_PACKET_MEMORY"));
}
else
{
EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot) & 0x3FF;
pSrc = (pInt32U)(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot)+\
(Int32U)__segment_begin("USB_PACKET_MEMORY"));
}
// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpCount,ActSize);
for(Count = 0; Count < SizeHold; ++Count)
{
Temp = *pSrc++;
*pData++ = Temp;
// fix overwrite problem with odd number of bytes
if(++Count <= SizeHold)
{
*pData++ = Temp>>8;
if(++Count <= SizeHold)
{
*pData++ = Temp>>16;
if(++Count <= SizeHold)
{
*pData++ = Temp>>24;
}
}
}
}
break;
case EP_INTERRUPT:
if (EpState.STAT_RX == EP_STALL)
{
return(USB_EP_STALLED);
}
else if (EpState.STAT_RX == EP_VALID)
{
return(UB_EP_SETUP_UNDERRUN);
}
EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot);
WriteEpDTB_CountRx(EpInfo[EndPoint].EpSlot,EpCount & ~0x3FF);
EpCount &= 0x3FF;
pSrc = (pInt32U)(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot)+\
(Int32U)__segment_begin("USB_PACKET_MEMORY"));
// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpCount,ActSize);
for(Count = 0; Count < SizeHold; ++Count)
{
Temp = *pSrc++;
*pData++ = Temp;
// fix overwrite problem with odd number of bytes
if(++Count <= SizeHold)
{
*pData++ = Temp>>8;
if(++Count <= SizeHold)
{
*pData++ = Temp>>16;
if(++Count <= SizeHold)
{
*pData++ = Temp>>24;
}
}
}
}
break;
case EP_BULK_SING_BUFF:
// Single buffer
if (EpState.STAT_RX == EP_STALL)
{
return(USB_EP_STALLED);
}
else if (EpState.STAT_RX == EP_VALID)
{
return(UB_EP_SETUP_UNDERRUN);
}
EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot);
WriteEpDTB_CountRx(EpInfo[EndPoint].EpSlot,EpCount & ~0x3FF);
EpCount &= 0x3FF;
pSrc = (pInt32U)(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot)+\
(Int32U)__segment_begin("USB_PACKET_MEMORY"));
// Get smaller of the user buffer and the received data.
SizeHold = MIN(EpCount,ActSize);
for(Count = 0; Count < SizeHold; ++Count)
{
Temp = *pSrc++;
*pData++ = Temp;
// fix overwrite problem with odd number of bytes
if(++Count <= SizeHold)
{
*pData++ = Temp>>8;
if(++Count <= SizeHold)
{
*pData++ = Temp>>16;
if(++Count <= SizeHold)
{
*pData++ = Temp>>24;
}
}
}
}
break;
case EP_BULK_DOUB_BUF:
if (EpState.STAT_RX == EP_STALL)
{
return(USB_EP_STALLED);
}
SizeHold = 0;
do
{
if(!EpInfo[EndPoint].EpIntrFl)
{
// Buffers are empties
break;
}
if(!EpState.DTOG_TX)
{
EpCount = ReadEpDTB_CountTx(EpInfo[EndPoint].EpSlot);
WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,EpCount & ~0x3FF);
EpCount &= 0x3FF;
pSrc = (pInt32U)(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot)+\
(Int32U)__segment_begin("USB_PACKET_MEMORY"));
}
else
{
EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot);
WriteEpDTB_CountRx(EpInfo[EndPoint].EpSlot,EpCount & ~0x3FF);
EpCount &= 0x3FF;
pSrc = (pInt32U)(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot)+\
(Int32U)__segment_begin("USB_PACKET_MEMORY"));
}
// Get smaller of the rest of the user buffer and the received data.
CurrSize = MIN(EpCount,(ActSize-SizeHold));
for(Count = 0; Count < CurrSize; ++Count)
{
Temp = *pSrc++;
*pData++ = Temp;
// fix overwrite problem with odd number of bytes
if(++Count <= CurrSize)
{
*pData++ = Temp>>8;
if(++Count <= CurrSize)
{
*pData++ = Temp>>16;
if(++Count <= CurrSize)
{
*pData++ = Temp>>24;
}
}
}
}
EpCtrlToggle_DTOG_TX(EpInfo[EndPoint].pEpCtrl);
EpState.DTOG_TX ^= 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -