📄 isp1581.cpp
字号:
PUSBSLAVE_PDD_CONTEXT pContext
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
USBChipEnable(pContext, TRUE);
FUNCTION_LEAVE_MSG();
}
static
VOID
SetClearTransferInterrupts(
PUSBSLAVE_PDD_CONTEXT pContext,
PEP_STATUS peps,
PSTransfer pTransfer,
BOOL bSet
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
if(peps->dwEndpoint != 0)
{
if(bSet)
EnableEndpointInterrupt(pContext, peps->dwEndpoint );
else
DisableEndpointInterrupt(pContext, peps->dwEndpoint );
}
FUNCTION_LEAVE_MSG();
}
void USBClearEndpoint(PUSBSLAVE_PDD_CONTEXT pContext, PEP_STATUS peps)
{
volatile unsigned short *pIOBASE = (unsigned short *)pContext->pusTemIOBASE;
pIOBASE[HwUSBEndpointIndex >> REG_ALIGN_OFFSET] = ( unsigned short )peps->dwEndpoint;
pIOBASE[HwUSBEndpointControl >> REG_ALIGN_OFFSET] |= USB_EPCONTROL_CLEAR;
}
//
// USBReadEndpoint reads data from the specified endpoint.
//
unsigned long
UDC_USBReadEndpoint(PUSBSLAVE_PDD_CONTEXT pContext, PEP_STATUS peps, unsigned char *ppucData,
unsigned long pusLength, BOOL bSetup)
{
unsigned long ulLength;
volatile unsigned short *pIOBASE = (unsigned short *)pContext->pusTemIOBASE;
unsigned long ulEndpoint = peps->dwEndpoint;
//
// Select the appropriate endpoint.
//
pIOBASE[HwUSBEndpointIndex >> REG_ALIGN_OFFSET] = ( unsigned short )(ulEndpoint) | USB_ENDPOINT_DIR_OUT | (bSetup?USB_ENDPOINT_SETUP:0);
//
// Read the length of the data buffer.
//
ulLength = pIOBASE[HwUSBEndpointBufferLength >> REG_ALIGN_OFFSET] ;
// if(ulLength==0)
// RETAILMSG(1, ( TEXT("Read pusLength = %d\r\n"),ulLength));
if(ulLength > pusLength )
ulLength = pusLength;
//
// Is there buffer space to fill with this data or should we throw the
// data away?
//
if(ulLength)
{
if(g_dma_enabled &&
((peps->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK))
{
unsigned long ulTemp;
volatile unsigned long *pulDMA = DMA_M2M1_BASE;
//
// Clear the status register.
//
pulDMA[M2M_STATUS>>2] = 0;
if( ulLength & 0x01 )
{
pulDMA[M2M_CTRL >> 2] = (
M2M_CTRL_DONEINTEN |
M2M_CTRL_BWC_FULLTRANS |
M2M_CTRL_PW_BYTE |
M2M_CTRL_SAH |
M2M_CTRL_TM_HARDINITP2M |
DMA_PIN_CONFIG |
M2M_CTRL_RSS_EXTDREQ |
(5<< M2M_CTRL_PWSC_SHIFT));
pIOBASE[HwUSBDMAConfig >> REG_ALIGN_OFFSET] =
(USB_DMACONFIG_BURST_1|
USB_DMACONFIG_MODE_DACK |
USB_DMACONFIG_WIDTH_8);
}
else
{
pulDMA[M2M_CTRL >> 2] = (
M2M_CTRL_DONEINTEN |
M2M_CTRL_BWC_FULLTRANS |
M2M_CTRL_PW_HALFWORD |
M2M_CTRL_SAH |
M2M_CTRL_TM_HARDINITP2M |
DMA_PIN_CONFIG |
M2M_CTRL_RSS_EXTDREQ |
(5<< M2M_CTRL_PWSC_SHIFT));
pIOBASE[HwUSBDMAConfig >> REG_ALIGN_OFFSET] =
(USB_DMACONFIG_BURST_1|
USB_DMACONFIG_MODE_DACK |
USB_DMACONFIG_WIDTH_16);
}
//
// Set the DMA Source address.
// The DMA assress for 1581 must be a unused chip-select's physical address.
// The CS3 hasn't be used in our ref-board.
//
pulDMA[M2M_SAR_BASE0 >> 2] = 0x30000000;
//
// Set the DMA Dst address.
//
pulDMA[M2M_DAR_BASE0 >> 2] = pContext->pusDMAPhysicalBASE;
pulDMA[M2M_BCR0 >> 2] = ulLength;
//
// enable dma
//
pulDMA[M2M_CTRL >> 2] |= M2M_CTRL_ENABLE;
//
// clear int
//
ulTemp = pIOBASE[HwUSBDMAIntReason >> REG_ALIGN_OFFSET];
pIOBASE[HwUSBDMAIntReason >> REG_ALIGN_OFFSET] = (unsigned short)ulTemp;
//
// Set 1581 DMA Endpoint
//
pIOBASE[HwUSBEndpointIndex >> REG_ALIGN_OFFSET] = 0;
pIOBASE[HwUSBDMAEndpoint >> REG_ALIGN_OFFSET] = ( unsigned short )(ulEndpoint) ;
//
// set 1581 dma count
//
pIOBASE[HwUSBDMACount >> REG_ALIGN_OFFSET] = (unsigned short)( ulLength );
pIOBASE[(HwUSBDMACount >> REG_ALIGN_OFFSET) + 1] = 0;
//
// set 1581 dma command
//
pIOBASE[HwUSBDMACommand >> REG_ALIGN_OFFSET] = USB_DMACOMMAND_GDMA_WRITE;
//
// Wait for DMA transfer complete.
//
while(!(pulDMA[M2M_STATUS >> 2] & M2M_STATUS_DONE))
{
}
//
// Set DMA ep to an unused endpoint.
//
pIOBASE[HwUSBDMAEndpoint >> REG_ALIGN_OFFSET] = USB_DMAEP_SEVEN_OUT;
pIOBASE[HwUSBEndpointIndex >> REG_ALIGN_OFFSET] = ( unsigned short )(ulEndpoint) ;
//
// clear Setting the EP931x DMA control REG
//
pulDMA[M2M_INT >> 2] |= pulDMA[M2M_INT >> 2];
pulDMA[M2M_CTRL >> 2] &= ~M2M_CTRL_ENABLE;
memcpy((unsigned char *)ppucData, (unsigned char *)pContext->pusDMAVirtualBASE, ulLength);
}
else
{
//
// Read the data into the receive buffer.
//
for(unsigned long ulIdx = 0; ulIdx < (ulLength&~0x1); ulIdx += sizeof(unsigned short))
{
*((unsigned short*)ppucData) = pIOBASE[HwUSBEndpointData>>REG_ALIGN_OFFSET];
ppucData += sizeof(unsigned short);
}
if(ulLength & 0x1)
{
*ppucData = (unsigned char) pIOBASE[HwUSBEndpointData>>REG_ALIGN_OFFSET];
}
}
}
else
{
//
// Send the clear buffer command so that the endpoint can receive
// another packet.
//
pIOBASE[HwUSBEndpointControl >> REG_ALIGN_OFFSET] |= USB_EPCONTROL_CLEAR;
}
//
// Return the size of the packet received.
//
return(ulLength);
}
//
// USBWriteEndpoint writes data to the specified endpoint.
//
static unsigned long
UDC_USBWriteEndpoint(PUSBSLAVE_PDD_CONTEXT pContext,PEP_STATUS peps, unsigned char *ppucData,
unsigned long pusLength,unsigned long max)
{
unsigned long ulLength;
volatile unsigned short *pIOBASE = (unsigned short *)pContext->pusTemIOBASE;
ulLength = (pusLength > max) ? max: pusLength;
//
// Select the appropriate endpoint.
//
pIOBASE[HwUSBEndpointIndex >> REG_ALIGN_OFFSET] = (unsigned short) (peps->dwEndpoint) | USB_ENDPOINT_DIR_IN;
//
// Write the packet length.
//
pIOBASE[HwUSBEndpointBufferLength >> REG_ALIGN_OFFSET] = (unsigned short)ulLength;
// RETAILMSG(1, ( TEXT("Write pusLength = %d\r\n"),ulLength));
if(g_dma_enabled &&
((peps->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK))
{
unsigned long ulTemp;
volatile unsigned long *pulDMA = DMA_M2M1_BASE;
memcpy((unsigned char *)pContext->pusDMAVirtualBASE, (unsigned char *)ppucData, ulLength);
//
// Clear the status register.
//
pulDMA[M2M_STATUS>>2] = 0;
if( ulLength & 0x01 )
{
pulDMA[M2M_CTRL >> 2] = (
M2M_CTRL_DONEINTEN |
M2M_CTRL_BWC_FULLTRANS |
M2M_CTRL_PW_BYTE |
M2M_CTRL_DAH |
M2M_CTRL_TM_HARDINITM2P |
DMA_PIN_CONFIG |
M2M_CTRL_RSS_EXTDREQ |
(5<< M2M_CTRL_PWSC_SHIFT));
pIOBASE[HwUSBDMAConfig >> REG_ALIGN_OFFSET] =
(USB_DMACONFIG_BURST_1|
USB_DMACONFIG_MODE_DACK |
USB_DMACONFIG_WIDTH_8);
}
else
{
pulDMA[M2M_CTRL >> 2] = (
M2M_CTRL_DONEINTEN |
M2M_CTRL_BWC_FULLTRANS |
M2M_CTRL_PW_HALFWORD |
M2M_CTRL_DAH |
M2M_CTRL_TM_HARDINITM2P |
DMA_PIN_CONFIG |
M2M_CTRL_RSS_EXTDREQ |
(5<< M2M_CTRL_PWSC_SHIFT));
pIOBASE[HwUSBDMAConfig >> REG_ALIGN_OFFSET] =
(USB_DMACONFIG_BURST_1|
USB_DMACONFIG_MODE_DACK |
USB_DMACONFIG_WIDTH_16);
}
//
// Set the DMA Source address.
//
pulDMA[M2M_SAR_BASE0 >> 2] = pContext->pusDMAPhysicalBASE;
//
// Set the DMA Dst address.
// The DMA assress for 1581 must be a unused chip-select's physical address.
// The CS3 hasn't be used in our ref-board.
//
pulDMA[M2M_DAR_BASE0 >> 2] = 0x30000000;
pulDMA[M2M_BCR0 >> 2] = ulLength;
//
// enable dma
//
pulDMA[M2M_CTRL >> 2] |= M2M_CTRL_ENABLE;
//
// clear int
//
ulTemp = pIOBASE[HwUSBDMAIntReason >> REG_ALIGN_OFFSET];
pIOBASE[HwUSBDMAIntReason >> REG_ALIGN_OFFSET] = (unsigned short)ulTemp;
//
// Set 1581 DMA Endpoint
//
pIOBASE[HwUSBEndpointIndex >> REG_ALIGN_OFFSET] = USB_DMAEP_SIX_OUT;
pIOBASE[HwUSBDMAEndpoint >> REG_ALIGN_OFFSET] = ( unsigned short )(peps->dwEndpoint) ;
//
// set 1581 dma count
//
pIOBASE[HwUSBDMACount >> REG_ALIGN_OFFSET] = (unsigned short)( ulLength );
pIOBASE[(HwUSBDMACount >> REG_ALIGN_OFFSET) + 1] = 0;
//
// set 1581 dma command
//
pIOBASE[HwUSBDMACommand >> REG_ALIGN_OFFSET] = USB_DMACOMMAND_GDMA_READ;
//
// Wait for DMA transfer complete.
//
while(!(pulDMA[M2M_STATUS >> 2] & M2M_STATUS_DONE))
{
}
//
// Set DMA ep to an unused endpoint.
//
pIOBASE[HwUSBDMAEndpoint >> REG_ALIGN_OFFSET] = USB_DMAEP_SEVEN_OUT;
pIOBASE[HwUSBEndpointIndex >> REG_ALIGN_OFFSET] = ( unsigned short )(peps->dwEndpoint) ;
//
// clear Setting the EP931x DMA control REG
//
pulDMA[M2M_INT >> 2] |= pulDMA[M2M_INT >> 2];
pulDMA[M2M_CTRL >> 2] &= ~M2M_CTRL_ENABLE;
}
else
{
//
// Write the data into the transmit buffer.
//
for(unsigned long ulIdx = 0; ulIdx < (ulLength&~0x1); ulIdx += sizeof(unsigned short))
{
pIOBASE[HwUSBEndpointData>>REG_ALIGN_OFFSET] = *((unsigned short*)ppucData);
ppucData += sizeof(unsigned short);
}
if(ulLength & 0x1)
{
pIOBASE[HwUSBEndpointData>>REG_ALIGN_OFFSET] = *ppucData;
}
}
//
// Decrement the count of bytes to write.
//
return(ulLength);
}
// Surround calls with cs on both the endpoint and the transfer.
static
VOID
CompleteTransfer(
PUSBSLAVE_PDD_CONTEXT pContext,
PEP_STATUS peps,
DWORD dwUsbError
)
{
PSTransfer pTransfer = peps->pTransfer;
peps->pTransfer = NULL;
// Sleep(1);
//DelayuS(500);
// RETAILMSG(1, ( TEXT("CompleteTransfer Ep %d\r\n"), peps->dwEndpoint));
// Disable transfer interrupts until another transfer is issued.
SetClearTransferInterrupts(pContext, peps, pTransfer, CLEAR);
if(pTransfer)
{
pTransfer->dwUsbError = dwUsbError;
}
pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_TRANSFER_COMPLETE,
(DWORD) pTransfer);
}
static
VOID
HandleTx(
PUSBSLAVE_PDD_CONTEXT pContext,
PEP_STATUS peps
)
{
PSTransfer pTransfer = peps->pTransfer;
BOOL fCompleted = FALSE;
DWORD dwStatus;
// DWORD dwCurrentPermissions = GetCurrentPermissions();
// SetProcPermissions(pTransfer->dwCallerPermissions);
__try
{
BYTE *c_pbBuffer = (BYTE*) pTransfer->pvBuffer + pTransfer->cbTransferred;
DWORD c_cbBuffer = pTransfer->cbBuffer - pTransfer->cbTransferred;
DWORD cbWritten ;
BOOL fValidatePacket = FALSE;
DWORD cbLast = 0;
cbWritten = UDC_USBWriteEndpoint(pContext,peps, c_pbBuffer,c_cbBuffer,peps->wMaxPacketSize);
DumpHexBuf((unsigned char*)c_pbBuffer, cbWritten);
pTransfer->cbTransferred += cbWritten;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_ERROR, (_T("Exception!\r\n")));
fCompleted = TRUE;
dwStatus = UFN_CLIENT_BUFFER_ERROR;
}
// SetProcPermissions(dwCurrentPermissions);
if (fCompleted) {
CompleteTransfer(pContext, peps, dwStatus);
}
}
static
VOID
HandleRx(
PUSBSLAVE_PDD_CONTEXT pContext,
PEP_STATUS peps
)
{
PSTransfer pTransfer = peps->pTransfer;
BOOL fCompleted = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -