📄 td1120p.c
字号:
/*-----------------------------------------------------------------------------
$File: //tdi_sw/tdi/source/usb/ctrl_drv/pcd/td1120/td1120p.c $
$DateTime: 2004/12/20 19:06:16 $
$Revision: #10 $
Purpose :
CONFIDENTIAL AND PROPRIETARY INFORMATION OF SOFTCONNEX TECHNOLOGIES, INC.
Copyright (c) 1999 - 2002 by SoftConnex Technologies, Inc.
This software is protected by copyright laws and international copyright
treaties, as well as other intellectual property laws and treaties. This
software is a CONFIDENTIAL, unpublished work of authorship, and with portions
constituting TRADE SECRETS of SoftConnex Technologies, Inc., a Delaware USA
corporation. Any unauthorized use, disclosure, and/or reproduction of this
software, or any part of this software; or distribution of this software in any
form or by any means; or storage of this software in any database or retrieval
system, without the express written consent of, and license from, SoftConnex
Technologies, Inc. is strictly prohibited. This software is protected under the
copyright and/or trade secret laws in other countries in addition to USA. All
Rights Reserved. Failure to abide by the use, disclosure and/or reproduction
restrictions may result in civil and /or criminal penalties, and will be
prosecuted to the maximum extent of the law.
-----------------------------------------------------------------------------*/
/******************************************************************************
Include Files
******************************************************************************/
#include "sc_types.h"
#include "sc_error.h"
#include "sc_print.h"
#include "sc_sys.h"
#include "platform.h"
#include "tdictrl.h"
#include "usbdesc.h"
#include "pcd.h"
#include "td1120p.h"
/*------------------------------------------------------------------------------
Global Variables
------------------------------------------------------------------------------*/
U8 testPacket[53] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
0xEE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFC, 0x7E, 0xBF, 0xDF,
0xEF, 0xF7, 0xFB, 0xFD, 0x7E};
STATIC TdiPeriphController* localHandle;
/*******************************************************************************
Local Functions
*******************************************************************************/
/*------------------------------------------------------------------------------
Name : TD1120P_Write1120Buffer
Purpose : Write a buffer to the TD1120 data area.
Arguments : baseAddress - Base address of the TD1120 controller data buffer.
offset - The address in the controller to write to.
epNum - endpoint number
data - A data buffer to write to the host controller.
length - The length of the data buffer.
Return : None.
Notes : None.
------------------------------------------------------------------------------*/
void TD1120P_Write1120Buffer(U32 *baseAddress, U16 offset, U32 epNum, \
U8 *data, U32 length)
{
volatile U16 *buffer = (U16 *) data;
volatile S32 temp = (S32) length;
volatile U8 moduloValue = (length % 4);
while (temp > 1)
{
SYS_Write1120P_Register(baseAddress, offset, *buffer++);
temp -= 2;
}
if (temp)
{
SYS_Write1120P_Register(baseAddress, offset, *buffer++);
temp--;
}
if (length && (!moduloValue))
{
moduloValue = TD1120_DEV_EP_VALID_CODE_4_BYTES;
}
if (!length)
{
moduloValue = TD1120_DEV_EP_VALID_CODE_0_BYTE;
}
/* Explicitly Validate FIFO */
SYS_Write1120P_Register(baseAddress, TD1120_DEV_EP_IN_VALIDATION_REG, \
((epNum << 4) | moduloValue));
}
/*------------------------------------------------------------------------------
Name : TD1120P_Read1120Buffer
Purpose : Read a buffer from the TD1120 data area.
Arguments : baseAddress - Base address of the TD1120 controller data buffer.
offset - The address in the host controller to read from.
epNum - endpoint number
data - The data buffer to write the data read from host controller.
length - The length of the data buffer.
Return : None.
Notes : None.
------------------------------------------------------------------------------*/
void TD1120P_Read1120Buffer(U32 *baseAddress, U16 offset, U32 epNum, \
U8 *data, U32 length)
{
volatile U16 lastWord;
volatile U16 *buffer = (U16 *) data;
volatile S32 temp = (S32) length;
#if (FEATURE_DWORD_EN == 1)
volatile U8 lastDWord = (length % 4);
while (temp >= 4)
{
*buffer++ = SYS_Read1120P_Register(baseAddress, offset);
*buffer++ = SYS_Read1120P_Register(baseAddress, offset);
temp -= 4;
}
if (lastDWord == 3)
{
*buffer++ = SYS_Read1120P_Register(baseAddress, offset);
temp-=2;
lastWord = SYS_Read1120P_Register(baseAddress, offset);
*buffer = (U8)lastWord;
temp--;
}
if (lastDWord == 2)
{
*buffer++ = SYS_Read1120P_Register(baseAddress, offset);
temp-=2;
lastWord = SYS_Read1120P_Register(baseAddress, offset);
}
if (lastDWord == 1)
{
lastWord = SYS_Read1120P_Register(baseAddress, offset);
*buffer = (U8)lastWord;
temp--;
lastWord = SYS_Read1120P_Register(baseAddress, offset);
}
#else
while (temp > 1)
{
*buffer++ = SYS_Read1120P_Register(baseAddress, offset);
temp -= 2;
}
/* if the length is odd, only copy 1 byte */
if (temp == 1)
{
lastWord = SYS_Read1120P_Register(baseAddress, offset);
*buffer = (U8)lastWord;
}
#endif
}
/*------------------------------------------------------------------------------
Name : TD1120P_CallEventService
Purpose : Get SETUP packet from the controller
Arguments : pc - peripheral controller handle
periphSetupPacket - setup packet
Returns : SctStatus
Notes : Check if is the TD1120 Peripheral controller
-----------------------------------------------------------------------------*/
SctStatus TD1120P_CallEventService(TdiPeriphController* pc, \
U32 eventType, void* eventData)
{
TdiCallbackInfo* callbackSearch;
/* Search for an existing entry for type */
for (callbackSearch = pc->callbackLinkStart;
callbackSearch;
callbackSearch = callbackSearch->next)
{
if (callbackSearch->eventType == eventType)
{
callbackSearch->callback(pc, eventType, eventData);
return SCS_SUCCESS;
} /* Endif */
} /* Endfor */
return (SCS_ERROR);
}
/*------------------------------------------------------------------------------
Name : TD1120P_Configure_EP
Purpose : Configures a TD1120 Endpoint
Arguments : Address - base address of the TD1120 controller
epNumber - Endpoint Number
epFormat - type of endpoint (e.g. control, iso, etc)
direction - Direction of transfer
epMPS - endpoint MPS
epThresh - fifo threshold
fifoStart - fifo Start Addr
fifoEnd - fifo End Addr
Returns : None.
Notes : None.
------------------------------------------------------------------------------*/
void TD1120P_Configure_EP(U32 *Address, U32 epNumber, U32 epFormat,
U32 direction, U32 epMPS, U32 epThresh, U32 fifoStart, U32 fifoEnd)
{
SYS_Write1120P_Register(Address, TD1120_DEV_EP_DESCR_REG(epNumber), \
((epFormat << 14) + epMPS));
SYS_Write1120P_Register(Address, TD1120_DEV_EP_FIFO_THRESHOLD(epNumber), epThresh);
if (!epFormat)
{
SYS_Write1120P_Register(Address, TD1120_DEV_EP_OUT_FIFO_START(epNumber), \
fifoStart);
SYS_Write1120P_Register(Address, TD1120_DEV_EP_OUT_FIFO_END(epNumber), \
(fifoStart + (epMPS << 1) - 4));
SYS_Write1120P_Register(Address, TD1120_DEV_EP_IN_FIFO_START(epNumber), \
fifoStart + (epMPS << 1));
SYS_Write1120P_Register(Address, TD1120_DEV_EP_IN_FIFO_END(epNumber), \
fifoEnd);
}
else
{
if (direction == USB_REQUEST_DIRECTION_IN)
{
SYS_Write1120P_Register(Address, \
TD1120_DEV_EP_IN_FIFO_START(epNumber), fifoStart);
SYS_Write1120P_Register(Address, TD1120_DEV_EP_IN_FIFO_END(epNumber), \
fifoEnd);
}
else
{
SYS_Write1120P_Register(Address, TD1120_DEV_EP_OUT_FIFO_START(epNumber), \
fifoStart);
SYS_Write1120P_Register(Address, TD1120_DEV_EP_OUT_FIFO_END(epNumber), \
fifoEnd);
}
}
}
/*------------------------------------------------------------------------------
Name : TD1120P_GetReceivedByteCount
Purpose : Gets the bytes count for last received transaction
Arguments : address - Base address of the TD1120 controller
epNum - EP Number
Returns : number of bytes received.
Notes : None.
------------------------------------------------------------------------------*/
U32 TD1120P_GetReceivedByteCount(U32* address, U32 epNum)
{
U32 size, size1;
size1 = SYS_Read1120P_Register(address, TD1120_DEV_EP_OUT_BYTE_COUNT_REG(epNum));
size = (size1 & TD1120_DEV_OUT_BYTE_COUNT_MASK);
/* Check the valid byte count only if the word count is greater than 0 */
if (size && (size1 & TD1120_DEV_OUT_VALID_BYTE_MASK))
{
/* size is number of DWORDS so don't right shift it and we'll have it in bytes */
size -= (4 - (size1 & TD1120_DEV_OUT_VALID_BYTE_MASK));
}
return (size);
}
/*------------------------------------------------------------------------------
Name : TD1120P_EpTransferDone
Purpose : pc Ep1-15 Done event service.
Arguments : pc - Device controller handle
epNum - endpoint number
type - unused parameter
Return : None
Notes :
------------------------------------------------------------------------------*/
void TD1120P_EpTransferDone(TdiPeriphController *pc, U32 epNum, U8 type)
{
TdiPeriphEp *ep;
TdiPurb* urb;
if (type == ISOUT)
{
/* Set OUT NAK so that we don't receive anything else */
SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_OUT_NAK_SET_REG, (1 << epNum));
}
ep = pc->ep[epNum];
if (ep == NULL)
{
return;
}
if (ep->urb == NULL)
{
return;
}
urb = ep->urb;
urb->status = SCS_SUCCESS;
if (urb->callBackFunction)
{
urb->callBackFunction(urb);
}
}
/*------------------------------------------------------------------------------
Name : TD1120P_DoEpOut
Purpose : Copy data from chip and update the status after Out token completed.
Arguments : dc - Device controller handle
urb - pointer to urb structure
Return : None
Notes :
------------------------------------------------------------------------------*/
void TD1120P_DoEpOut(TdiPeriphController *pc, TdiPurb* urb)
{
U32 size, temp;
U8 *tempstring;
TdiPeriphEp *ep;
ep = urb->ep;
/* disable interrupts on the controller */
PCD_DisableControllerIntr(pc);
do
{
/* Transfer finished, no more data */
if (urb->dataPosition >= urb->length)
{
if (!(urb->dataPosition % ep->maxPktSize))
{
/* There will be no "done" interrupt because the last packet
is not less than maxpacketsize
*/
TD1120P_EpTransferDone(pc, ep->epNumber, ISOUT);
}
/* Enable interrupts on the controller */
PCD_EnableControllerIntr(pc);
return;
}
/* Get the received bytes from EP descriptor */
size = TD1120P_GetReceivedByteCount(pc->ioBase, ep->epNumber);
if (!size)
{
/* Enable interrupts on the controller */
PCD_EnableControllerIntr(pc);
return;
}
/* It's possible that EP received more than one buffer */
size = ((urb->dataPosition + size) > urb->length) ? \
(urb->length - urb->dataPosition) : size;
if (size >= ep->maxPktSize)
{
size = ep->maxPktSize;
temp = size/ep->maxPktSize;
if (temp)
{
size = (ep->maxPktSize * temp);
}
}
else if (!((size < ep->maxPktSize) && \
(SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_EP_OUT_XFER_RCVD_REG) & \
(1 << ep->epNumber))))
{
/* Enable interrupts on the controller */
PCD_EnableControllerIntr(pc);
return;
}
tempstring = urb->data + urb->dataPosition;
TD1120P_Read1120Buffer(pc->ioBase, TD1120_DEV_EP_OUT_FIFO_READ(ep->epNumber), \
ep->epNumber, (urb->data + urb->dataPosition), size);
/* Update the actual Length */
urb->dataPosition += size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -