📄 xsudc.c
字号:
/******************************************************************************
**
** COPYRIGHT (C) 2000, 2001 Intel Corporation.
**
** This software as well as the software described in it is furnished under
** license and may only be used or copied in accordance with the terms of the
** license. The information in this file is furnished for informational use
** only, is subject to change without notice, and should not be construed as
** a commitment by Intel Corporation. Intel Corporation assumes no
** responsibility or liability for any errors or inaccuracies that may appear
** in this document or any software that may be provided in association with
** this document.
** Except as permitted by such license, no part of this document may be
** reproduced, stored in a retrieval system, or transmitted in any form or by
** any means without the express written consent of Intel Corporation.
**
** FILENAME: xsudc.c
**
** PURPOSE: This files contains the POST specific functions for USB Device
** controller (UDC).
**
** LAST MODIFIED: $Modtime: 7/17/03 1:01p $
**
******************************************************************************/
/*
*******************************************************************************
* HEADER FILES
*******************************************************************************
*/
#include <string.h>
#include <stdio.h>
#include "systypes.h"
#include "dm_errors.h"
#include "mallocx.h"
#include "DM_Debug.h"
#include "XsIntCtrlApi.h"
#include "boardControl.h"
#include "xllp_defs.h"
#include "xllp_udc.h"
#include "xllp_udc_os_depend.h"
#define UDC_GLOBALS
#include "xsudc.h"
#include "UsbCableInt.h"
/******************************************************************************
Function Name:
XllpUdcParseConfigDescriptor
Description:
This function parses the USB Configurations descriptor and fills out the user's
the Endpoints Configuration table.
Global Register Modified:
None
Input Arguments:
P_XLLP_INT8_T pConfigDescriptor - a pointer to the USB Configuration Descriptor
P_XLLP_UDC_EP_CONFIG_TABLE_T pEndpointsConfigTable - a pointer to the Endpoints
Configuration Table.
Output Arguments:
None
Return Value:
XLLP_STATUS_T - error code if failed, zero if success
*******************************************************************************/
XLLP_STATUS_T XllpUdcParseConfigDescriptor (P_XLLP_INT8_T pConfigDescriptor,
P_XLLP_UDC_EP_CONFIG_TABLE_T pEndpointsConfigTable)
{
XLLP_STATUS_T error;
return error;
}
#ifdef temp
// The DMA related functions are under investigation
XLLP_STATUS_T XllpUdcModifyEvenDescriptorsDma (XsDmaDescriptorElementsTTP rootDescriptorP,
XLLP_UDC_EP_T udcEndpoinNtum)
{
XLLP_STATUS_T error;
return error;
}
XsDmaDescriptorElementsTPT
XllpUdcCreateDescriptorChainDma (XLLP_UINT32_T channel,
XLLP_UINT32_T numDescriptors,
XLLP_UINT32_T xferByteCount,
XLLP_UDC_EP_T udcEndpointNum)
{
}
XLLP_STATUS_T XllpUdcConfigureDmaIn (XsDmaChannelPriorityT desiredPriority,
XsDmaDeviceNamesT deviceName,
XLLP_BOOL_T isTarget,
XsDmaDescriptorElementsTPT * firstDescVtP,
XLLP_UINT32_T numDescriptors,
XLLP_UINT32_T xferByteCount,
P_XLLP_UINT32_T returnChannelNumP)
{
XLLP_STATUS_T error;
return error;
}
#endif
XLLP_STATUS_T XsUdcSetupInEndpointDma (P_XLLP_UDC_T pUdcHandle,
XLLP_UDC_USB_EP_T usbEndpointNum,
P_XLLP_UINT32_T pTxBuff,
XLLP_UINT32_T xferLength)
{
XLLP_STATUS_T error;
return error;
}
void XsUdcSetupInEndpoint (P_XLLP_UDC_T pUdcHandle,
XLLP_UDC_EP_T udcEndpointNum,
P_XLLP_UINT32_T pTxBuff,
XLLP_UINT32_T xferLength)
{
volatile P_XLLP_UDC_REGISTERS_T pRegs = (P_XLLP_UDC_REGISTERS_T)pUdcHandle->pRegsBase;
// Initilize the UDC's endpoint xfer structure
pUdcHandle->EpXferTable[udcEndpointNum].pDataEp = pTxBuff;
pUdcHandle->EpXferTable[udcEndpointNum].xferLength = xferLength;
pUdcHandle->EpXferTable[udcEndpointNum].xferDataCounter = 0;
pUdcHandle->EpXferTable[udcEndpointNum].maxPacketSize =
((pRegs->UDCCRZ[udcEndpointNum] & XLLP_UDC_UDCCRZ_MPS_MASK)
>> XLLP_UDC_UDCCRZ_MPS_SHIFT);
pUdcHandle->EpXferTable[udcEndpointNum].TxXferComplete = XLLP_FALSE;
}
void XsUdcSetupOutEndpoint (P_XLLP_UDC_T pUdcHandle,
XLLP_UDC_EP_T udcEndpointNum,
XLLP_UINT32_T numBytes)
{
volatile P_XLLP_UDC_REGISTERS_T pRegs = (P_XLLP_UDC_REGISTERS_T)pUdcHandle->pRegsBase;
// Allocate memory for temp. Rx buffer
if (pUdcHandle->EpXferTable[udcEndpointNum].pDataEp == NULL)
pUdcHandle->EpXferTable[udcEndpointNum].pDataEp = malloc(numBytes);
// Initilize the UDC's endpoint xfer structure
pUdcHandle->EpXferTable[udcEndpointNum].xferLength = numBytes;
pUdcHandle->EpXferTable[udcEndpointNum].xferDataCounter = 0;
pUdcHandle->EpXferTable[udcEndpointNum].maxPacketSize =
((pRegs->UDCCRZ[udcEndpointNum] & XLLP_UDC_UDCCRZ_MPS_MASK)
>> XLLP_UDC_UDCCRZ_MPS_SHIFT);
pUdcHandle->EpXferTable[udcEndpointNum].RxXferComplete = XLLP_FALSE;
pUdcHandle->EpXferTable[udcEndpointNum].RxBlockXferComplete = XLLP_FALSE;
// Clear DMA enable bit in UDCCSR register
// (writing zero to all other bits would not modify them).
pRegs->UDCCSR[udcEndpointNum] = 0;
// Enable endpoint's packet complete interrupt
XllpUdcEnableInterrupt (pUdcHandle,
udcEndpointNum,
PACKET_COMPL_INT);
// Enable endpoint's FIFO error interrupt
XllpUdcEnableInterrupt (pUdcHandle,
udcEndpointNum,
FIFO_ERROR_INT);
}
void XllpUdcSetupOutEndpoint (P_XLLP_UDC_T pUdcHandle, XLLP_UDC_EP_T udcEndpointNum)
{
XLLP_UINT32_T numBytes;
numBytes = XSUDC_TEMP_OUT_BUFF_SIZE;
XsUdcSetupOutEndpoint (pUdcHandle, udcEndpointNum, numBytes);
}
/******************************************************************************
Function Name:
XllpUdcProcessVendorRequest
Description:
This function sets up Bulk, ISO, and Interrupt transfers.
It enables or disables endpoints' interrupts based on the status
enableDma, sets up the Dma engine or preloads the endpoints'
FIFO with the data for the IN transaction.
Vendor Requests are used to setup various types of the transfers.
Vendor Request format:
bmRequestType: bits 6 and 5 = 10 (vendor defined)
bits 4 through 0 = 00010 (endpoint)
bRequest: SETUP IN EP = 0x01
SETUP OUT EP = 0x02
SETUP INT EP = 0x03
SETUP LOOPBACK = 0x04
bRequest is passed in requestType
wValue: LSB - Rx(OUT) Endpoint number
MSB - Tx(IN) Endpoint number
wValue is used to pass IN and/or OUT Endpoints
wIndex: Not Used
wLength: 4 bytes will be sent in the data stage to the UDC
these bytes can be used to control various functions
To setup loopback: 1. Send SETUP OUT EPx request
2. Send SETUP LOOPBACK on EPx and EPy
Global Register Modified:
None.
Input Arguments:
P_XLLP_UDC_T pUdcHandle - a pointer to the UDC's handle
Output Arguments:
None.
Return Value:
XLLP_STATUS_T - error code if failed, zero if success
*******************************************************************************/
XLLP_STATUS_T XllpUdcProcessVendorRequest (P_XLLP_UDC_T pUdcHandle)
{
XLLP_STATUS_T error;
return error;
}
/******************************************************************************
Function Name:
XsUdcInterruptHandler
Description:
This is the UDC's main interrupt handler.
Global Register Modified:
None.
Input Arguments:
P_XLLP_UDC_T pUdcHandle - a pointer to the UDC's handle
Output Arguments:
None
Return Value:
None
*******************************************************************************/
void XsUdcInterruptHandler (P_XLLP_UDC_T pUdcHandle)
{
XLLP_UINT32_T statusISR0 = 0;
XLLP_UINT32_T statusISR1 = 0;
XLLP_UINT32_T udcEndpointNum = 0, i = 0, j = 0;
XLLP_UINT32_T packetComplIntStatus;
XLLP_UINT32_T fifoErrorIntStatus;
volatile P_XLLP_UDC_REGISTERS_T pRegs = (P_XLLP_UDC_REGISTERS_T)pUdcHandle->pRegsBase;
// Save status of the UDCISR0
statusISR0 = pRegs->UDCISR0;
// Save status of the UDCISR1
statusISR1 = pRegs->UDCISR1;
// Clear all USB Event Interrupts
pRegs->UDCISR1 |= XLLP_UDC_UDCISR1_EVENTS;
// Determine type of UDC interrupt
// Check if there are any of the event interrupts
if (statusISR1 & XLLP_UDC_UDCISR1_EVENTS)
{
// Is this Reset interrupt?
if (statusISR1 & XLLP_UDC_UDCISR1_IRRS)
{
// Enable the Endpoint 0 interrupts
XllpUdcEnableInterrupt (pUdcHandle,
INT_ENDPOINT_0,
PACKET_COMPL_INT);
XllpUdcEnableInterrupt (pUdcHandle,
INT_ENDPOINT_0,
FIFO_ERROR_INT);
// Enable Configuration request interrupts
XllpUdcEnableInterrupt (pUdcHandle,
INT_CONFIG,
0);
pUdcHandle->enumerateComplete = XLLP_FALSE;
// Update statistics
++pUdcHandle->interruptStat.ResetIntCount;
}
// Is this Suspend interrupt?
else if (statusISR1 & XLLP_UDC_UDCISR1_IRSU)
{
// Update statistics
++pUdcHandle->interruptStat.SuspendIntCount;
}
// Is this Resume interrupt?
else if (statusISR1 & XLLP_UDC_UDCISR1_IRRU)
{
// Update statistics
++pUdcHandle->interruptStat.ResumeIntCount;
}
// Is this SOF interrupt?
else if (statusISR1 & XLLP_UDC_UDCISR1_IRSOF)
{
// Update statistics
++pUdcHandle->interruptStat.SOFIntCount;
}
// Is this Configuration Change interrupt?
else if (statusISR1 & XLLP_UDC_UDCISR1_IRCC)
{
XllpUdcConfigInterruptHandler (pUdcHandle);
pUdcHandle->enumerateComplete = XLLP_TRUE;
// Alocate temp. buffers for OUT Endpoints in active configuration
while (pUdcHandle->listOfActiveEndpoints[j].udcEndpointNum > 0)
{
// Check if this is OUT endpoint
udcEndpointNum = pUdcHandle->listOfActiveEndpoints[j].udcEndpointNum;
if (!(pRegs->UDCCRZ[udcEndpointNum] & XLLP_UDC_UDCCRZ_ED))
{
if (pUdcHandle->EpXferTable[udcEndpointNum].pDataEp == NULL)
XllpUdcSetupOutEndpoint (pUdcHandle, udcEndpointNum);
}
++j;
}
udcEndpointNum = 0;
// Update statistics
++pUdcHandle->interruptStat.ConfigIntCount;
}
}
// Check if this is Endpoint 0 Packet Complete interrupt
if (statusISR0 & XLLP_UDC_UDCISR0_IR0_0)
{
PostDisplayProgress(ERR_L_XSUDC, ERR_S_XSUDC_MAIN_INT, 1);
// Call Endpoint 0 interrupt handler
XllpUdcEp0InterruptHandler (pUdcHandle);
// Clear the Endpoint 0 Interrupt
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -