📄 xsudc.c
字号:
XllpUdcClearInterrupt (pUdcHandle, INT_ENDPOINT_0, PACKET_COMPL_INT);
// Update statistics
++pUdcHandle->interruptStat.EpIntCount[INT_ENDPOINT_0];
}
// Check if this is Endpoint 0 FIFO error interrupt
if (statusISR0 & XLLP_UDC_UDCISR0_IR0_1)
{
PostDisplayProgress(ERR_L_XSUDC, ERR_S_XSUDC_MAIN_INT, 2);
// Clear the Endpoint 0 Interrupt
XllpUdcClearInterrupt (pUdcHandle, INT_ENDPOINT_0, FIFO_ERROR_INT);
}
// Process the pending interrupts from the Endpoints in active configuration
while (pUdcHandle->listOfActiveEndpoints[i].udcEndpointNum > 0)
{
udcEndpointNum = pUdcHandle->listOfActiveEndpoints[i].udcEndpointNum;
// Get Endpoint's packet complete interrupt status
XllpUdcGetStatusInterrupt (pUdcHandle,
udcEndpointNum,
PACKET_COMPL_INT,
&packetComplIntStatus);
if (packetComplIntStatus)
{
// Determine the direction of the Endpoint
if (pRegs->UDCCRZ[udcEndpointNum] & XLLP_UDC_UDCCRZ_ED)
{
// This is IN Endpoint
PostDisplayProgress(ERR_L_XSUDC, ERR_S_XSUDC_MAIN_INT, 3);
XllpUdcFillFifo (pUdcHandle, udcEndpointNum, XLLP_TRUE);
}
else
{
// This is OUT Endpoint
PostDisplayProgress(ERR_L_XSUDC, ERR_S_XSUDC_MAIN_INT, 4);
XllpUdcUnloadFifo (pUdcHandle, udcEndpointNum);
}
// Clear the Interrupt
XllpUdcClearInterrupt (pUdcHandle, udcEndpointNum, PACKET_COMPL_INT);
// Update statistics
++pUdcHandle->interruptStat.EpIntCount[udcEndpointNum];
}
// Get Endpoint's FIFO error interrupt status
XllpUdcGetStatusInterrupt (pUdcHandle,
udcEndpointNum,
FIFO_ERROR_INT,
&fifoErrorIntStatus);
if (fifoErrorIntStatus)
{
// If this is IN Endpoint, the FIFO underrun happened,
// The UDC will issue NAK to the host for Bulk and Interrupt transfers,
// and sends zero-length packet for Iso
// if this is OUT Endpoint, the FIFO overrun happened,
// The UDC will issue NAK to the host for Bulk and Interrupt OUT tokens.
PostDisplayProgress(ERR_L_XSUDC, ERR_S_XSUDC_MAIN_INT, 5);
// Clear the Endpoint FIFO Interrupt
XllpUdcClearInterrupt (pUdcHandle, udcEndpointNum, FIFO_ERROR_INT);
}
++i;
}
}
XLLP_STATUS_T XllpUdcRegisterFirstLevelInterrupt(P_XLLP_UDC_T pUdcHandle)
{
UINT32 error = FALSE;
// Register the UDC interrupt handler
error = XsIcRegisterHandler (XSIC_USB_SGNL, (XsIcL1IntHandlerFnPT)XsUdcInterruptHandler,
(void*)pUdcHandle);
if (error)
{
LOGERRORX(error, ERR_L_XSUDC, ERR_S_XSUDC_INT_HANDLER, 1, ERR_T_ILLPARAM, 0, 0, 0);
}
return error;
}
XLLP_STATUS_T XllpUdcUnRegisterFirstLevelInterrupt(void)
{
UINT32 error = FALSE;
// Register the UDC interrupt handler
error = XsIcUnRegisterHandler (XSIC_USB_SGNL);
if (error)
{
LOGERRORX(error, ERR_L_XSUDC, ERR_S_XSUDC_INT_HANDLER, 2, ERR_T_ILLPARAM, 0, 0, 0);
}
return error;
}
XLLP_STATUS_T XllpUdcEnableFirstLevelInterrupt(void)
{
UINT32 error = FALSE;
// Enable first level UDC interrupt
error = XsIcEnableIrqDeviceInt (XSIC_USB_SGNL);
if (error)
{
LOGERRORX(error, ERR_L_XSUDC, ERR_S_XSUDC_ENABLE_INT, 1, ERR_T_NO_HANDLER, 0, 0, 0);
}
return error;
}
XLLP_STATUS_T XllpUdcDisableFirstLevelInterrupt(void)
{
UINT32 error = FALSE;
// Enable first level UDC interrupt
error = XsIcDisableIrqDeviceInt (XSIC_USB_SGNL);
if (error)
{
LOGERRORX(error, ERR_L_XSUDC, ERR_S_XSUDC_ENABLE_INT, 2, ERR_T_NO_HANDLER, 0, 0, 0);
}
return error;
}
/******************************************************************************
Function Name:
XsUdcSend
Description:
This function is used to transfer the data via the USB Endpoint
Global Register Modified:
None.
Input Arguments:
P_XLLP_UDC_T pUdcHandle - pointer to the UDC's handle
XLLP_UDC_USB_EP_T usbEndpointNum - the USB endpoint number
P_XLLP_UINT32_T pTxBuff - pointer to the transmit buffer
XLLP_UINT32_T xferLength - length of the transfer
Output Arguments:
P_XLLP_UINT32_T pXferCompleteFlag - notifies the caller that transfer was completed or failed
Return Value:
None
*******************************************************************************/
void XsUdcSend (P_XLLP_UDC_T pUdcHandle,
XLLP_UDC_USB_EP_T usbEndpointNum,
P_XLLP_UINT32_T pTxBuff,
XLLP_UINT32_T xferLength,
P_XLLP_UINT32_T pXferCompleteFlag)
{
XLLP_UDC_EP_T udcEndpointNum, i = 0;
XLLP_VUINT32_T statusTxComplete = 0;
// Get the UDC endpoint number that is correspond to the USB Endpoint number
// from the list of active endpoints
while (pUdcHandle->listOfActiveEndpoints[i].usbEndpointNum > 0)
{
if (pUdcHandle->listOfActiveEndpoints[i].usbEndpointNum == usbEndpointNum)
{
udcEndpointNum = pUdcHandle->listOfActiveEndpoints[i].udcEndpointNum;
break;
}
++i;
}
if (pUdcHandle->enableDma == XLLP_TRUE)
{
// Disable endpoint's packet complete interrupt
XllpUdcDisableInterrupt (pUdcHandle,
udcEndpointNum,
PACKET_COMPL_INT);
// Disable endpoint's FIFO error interrupt
XllpUdcDisableInterrupt (pUdcHandle,
udcEndpointNum,
FIFO_ERROR_INT);
// Initilize the UDC's endpoint xfer structure and setup DMA
XsUdcSetupInEndpointDma (pUdcHandle, udcEndpointNum, pTxBuff, xferLength);
}
else
{
// Initilize the UDC's endpoint xfer structure
XsUdcSetupInEndpoint (pUdcHandle, udcEndpointNum, pTxBuff, xferLength);
// Load Endpoint's FIFO with the first packet
XllpUdcFillFifo (pUdcHandle, udcEndpointNum, XLLP_TRUE);
// Enable endpoint's packet complete interrupt
XllpUdcEnableInterrupt (pUdcHandle,
udcEndpointNum,
PACKET_COMPL_INT);
// Enable endpoint's FIFO error interrupt
XllpUdcEnableInterrupt (pUdcHandle,
udcEndpointNum,
FIFO_ERROR_INT);
}
// Wait for data to be sent
while (!statusTxComplete)
statusTxComplete=pUdcHandle->EpXferTable[udcEndpointNum].TxXferComplete;
// Disable endpoint's packet complete interrupt
XllpUdcDisableInterrupt (pUdcHandle,
udcEndpointNum,
PACKET_COMPL_INT);
// Notify caller that transfer was completed or failed
*pXferCompleteFlag = pUdcHandle->EpXferTable[udcEndpointNum].TxXferComplete;
pUdcHandle->EpXferTable[udcEndpointNum].TxXferComplete = XLLP_FALSE;
}
/******************************************************************************
Function Name:
XsUdcRead
Description:
This function is used to receive the data from the USB Endpoint
Global Register Modified:
None.
Input Arguments:
P_XLLP_UDC_T pUdcHandle - pointer to the UDC's handle
XLLP_UDC_USB_EP_T usbEndpointNum - the USB Endpoint number
P_XLLP_UINT32_T pRxBuff - pointer to the receive buffer
Output Arguments:
P_XLLP_UINT32_T pNumBytes - total number of bytes being received
Return Value:
None
*******************************************************************************/
void XsUdcRead (P_XLLP_UDC_T pUdcHandle,
XLLP_UDC_USB_EP_T usbEndpointNum,
P_XLLP_UINT32_T pRxBuff,
P_XLLP_UINT32_T pNumBytes)
{
UINT32 udcEndpointNum, i = 0;
// Get the UDC endpoint number that is correspond to the USB Endpoint number
// from the list of active endpoints
while (pUdcHandle->listOfActiveEndpoints[i].usbEndpointNum > 0)
{
if (pUdcHandle->listOfActiveEndpoints[i].usbEndpointNum == usbEndpointNum)
{
udcEndpointNum = pUdcHandle->listOfActiveEndpoints[i].udcEndpointNum;
break;
}
++i;
}
// Reset OUT Endpoint and get ready for the transfer
XllpUdcSetupOutEndpoint (pUdcHandle, udcEndpointNum);
do
{
if (pUdcHandle->EpXferTable[udcEndpointNum].RxXferComplete == XLLP_TRUE)
{
memcpy (pRxBuff, pUdcHandle->EpXferTable[udcEndpointNum].pDataEp,
pUdcHandle->EpXferTable[udcEndpointNum].xferDataCounter);
*pNumBytes = pUdcHandle->EpXferTable[udcEndpointNum].xferDataCounter;
// Disable endpoint's packet complete interrupt
XllpUdcDisableInterrupt (pUdcHandle,
udcEndpointNum,
PACKET_COMPL_INT);
// Disable endpoint's FIFO error interrupt
XllpUdcDisableInterrupt (pUdcHandle,
udcEndpointNum,
FIFO_ERROR_INT);
break;
}
else if (pUdcHandle->EpXferTable[udcEndpointNum].RxBlockXferComplete == XLLP_TRUE)
{
// We need to notify upper layer to request more memory,
// the transfer has not been completed yet
memcpy (pRxBuff, pUdcHandle->EpXferTable[udcEndpointNum].pDataEp,
pUdcHandle->EpXferTable[udcEndpointNum].xferDataCounter);
*pNumBytes = pUdcHandle->EpXferTable[udcEndpointNum].xferDataCounter;
break;
}
}while (1);
}
UINT32 XsUdcHWSetup (void)
{
UINT32 status = FALSE;
UINT32 error = FALSE;
status = XllpUdcHWSetup (&UsbDeviceController);
if (status)
{
LOGERROR(error, ERR_L_XSUDC, ERR_S_XSUDC_HWSETUP, ERR_T_NODEVICE, 0, 0, 0);
}
return error;
}
UINT32 XsUdcHWShutdown (void)
{
P_XLLP_UDC_T pUdcHandle = &UsbDeviceController;
volatile P_XLLP_UDC_REGISTERS_T pRegs = (P_XLLP_UDC_REGISTERS_T)pUdcHandle->pRegsBase;
XLLP_UINT32_T i;
UINT32 status = FALSE;
UINT32 error = FALSE;
status = XllpUdcHWShutdown (pUdcHandle);
if (status)
{
LOGERROR(error, ERR_L_XSUDC, ERR_S_XSUDC_SHUT, ERR_T_NODEVICE, 0, 0, 0);
}
// Free memory allocated for temp. Rx buffers
for (i = 1; i < XLLP_UDC_MAX_EP_NUM; ++i)
{
// Check if this is OUT endpoint
if (!(pRegs->UDCCRZ[i] & XLLP_UDC_UDCCRZ_ED))
{
// Free alocated memory
if (pUdcHandle->EpXferTable[i].pDataEp != NULL)
free((PVOID)pUdcHandle->EpXferTable[i].pDataEp);
}
}
// Clear Endpoints' Xfer table
memset (&pUdcHandle->EpXferTable[0], 0, (sizeof(XLLP_UDC_XFER_T) * XLLP_UDC_MAX_EP_NUM));
return error;
}
void XsUdcSWInit (void)
{
XllpUdcSWInit (&UsbDeviceController, (P_XLLP_UDC_REGISTERS_T)XLLP_UDC_REGISTERS_BASE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -