⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sc2450pdd.cpp

📁 S3C2450BSP开发包,里面有很多资料。可以提供大家参考下。有什么需要解决问题。可以联系我QQ:314661
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    EnableDisableEndpointInterrupt(pContext, dwEndpoint, FALSE);

    FUNCTION_LEAVE_MSG();
}

/*++

Routine Description:

Clear the interrupt status register index of an endpoint.

Arguments:

dwEndpoint - the target endpoint

Return Value:

None.

--*/
static
VOID
ClearEndpointInterrupt(
                       PCTRLR_PDD_CONTEXT pContext,
                       DWORD        dwEndpoint
                       )
{    
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    // Clear the Endpoint Interrupt
    BYTE bIntBit = EpToIrqStatBit(dwEndpoint);
    WriteReg(pContext, EIR, bIntBit);

    FUNCTION_LEAVE_MSG();
} // _ClearInterrupt


// Reset an endpoint

VOID
ResetEndpoint(
              PCTRLR_PDD_CONTEXT pContext,
              EP_STATUS *peps
              )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    ValidateContext(pContext);
    PREFAST_DEBUGCHK(peps);

   RETAILMSG(DBG, (_T(" ResetEndpoint \r\n")));

    // Since Reset can be called before/after an Endpoint has been configured,
    // it is best to clear all IN and OUT bits associated with endpoint. 
    DWORD dwEndpoint = peps->dwEndpointNumber;
	//0816
	WORD bEDR;
    if(dwEndpoint == 0 ) {
        // Clear all EP0 Status bits
        WriteReg(pContext, EP0SR, (EP0SHT | EP0TST |EP0RSR));
        WriteReg(pContext, EP0CR, 0x0000);
    }
    else if(dwEndpoint < ENDPOINT_COUNT) {
        // Clear all EP Status bits
        WriteIndexedReg(pContext, dwEndpoint, ESR, (OSD | DTCZ | SPT | FFS | FSC | TPS));
        // Clear all EP Control bits
        bEDR = ReadIndexedReg(pContext, dwEndpoint, EDR);
        if(bEDR & (0x1 << dwEndpoint)) {		// Tx
             WriteIndexedReg(pContext, dwEndpoint, ECR, 0x0000);  // Single Buffer Mode
        	}
        else
        	{
             WriteIndexedReg(pContext, dwEndpoint, ECR, 0x0080); // Dual Buffer Mode
        	}
        

        // Clear and disable endpoint interrupt
        WriteReg(pContext, EIR, EpToIrqStatBit(peps->dwEndpointNumber));
        DisableEndpointInterrupt(pContext, peps->dwEndpointNumber);
    }
    else {
        DEBUGCHK(FALSE);
    }

    FUNCTION_LEAVE_MSG();
}



// Reset the device and EP0.

VOID
ResetDevice(
            PCTRLR_PDD_CONTEXT pContext
            )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DEBUGCHK(IS_VALID_SC2450_CONTEXT(pContext));

    RETAILMSG(DBG, (_T(" ResetDevice \r\n")));

    // Reset System Control Register
    WriteReg(pContext, SCR, 0x0020);

    // Reset System Status Register
    WriteReg(pContext, SSR, (VBUSOFF | VBUSON | TBM | SDE | HFRM | HFSUSP | HFRES ) );


    // Disable endpoint interrupts - write Zeros to Disable
    WriteReg(pContext, EIER, EP_INTERRUPT_DISABLE_ALL);

    // End point Interrupt Status - Write a '1' to Clear
    WriteReg(pContext, EIR, CLEAR_ALL_EP_INTRS);

    // Reset all endpoints
    for (DWORD dwEpIdx = 0; dwEpIdx < ENDPOINT_COUNT; ++dwEpIdx) {
        EP_STATUS *peps = GetEpStatus(pContext, dwEpIdx);
        ResetEndpoint(pContext, peps);
    }

    FUNCTION_LEAVE_MSG();
}


static
VOID
CompleteTransfer(
                 PCTRLR_PDD_CONTEXT pContext,
                 PEP_STATUS peps,
                 DWORD dwUsbError
                 )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PSTransfer pTransfer = peps->pTransfer;
    peps->pTransfer = NULL;

    pTransfer->dwUsbError = dwUsbError;
    pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_TRANSFER_COMPLETE, 
        (DWORD) pTransfer);

    FUNCTION_LEAVE_MSG();
}


#ifdef DEBUG
static
VOID
ValidateTransferDirection(
                          PCTRLR_PDD_CONTEXT pContext,
                          PEP_STATUS peps,
                          PSTransfer pTransfer
                          )
{
    DEBUGCHK(pContext);
    PREFAST_DEBUGCHK(peps);
    PREFAST_DEBUGCHK(pTransfer);

    if (peps->dwEndpointNumber != 0) {
        DEBUGCHK(peps->dwDirectionAssigned == pTransfer->dwFlags);
    }
}
#else
#define ValidateTransferDirection(ptr1, ptr2, ptr3)
#endif


// Read data from an endpoint.

static 
VOID
HandleRx(
         PCTRLR_PDD_CONTEXT       pContext,
         PEP_STATUS peps,
         PBOOL pfCompleted,
         PDWORD pdwStatus
         )
{

    BOOL fCompleted = FALSE;
    DWORD dwStatus = ERROR_GEN_FAILURE;
    DWORD dwEndpoint = peps->dwEndpointNumber;
    BYTE bRet = 0;
    WORD bEpIrqStat;
	
    SETFNAME();
    FUNCTION_ENTER_MSG();

    bEpIrqStat = ReadIndexedReg(pContext, dwEndpoint, ESR);

    PSTransfer pTransfer = peps->pTransfer;

    pTransfer = peps->pTransfer;
    if (pTransfer) {
        DEBUGCHK(pTransfer->dwFlags == USB_OUT_TRANSFER);
        DEBUGCHK(pTransfer->dwUsbError == UFN_NOT_COMPLETE_ERROR);

        ValidateTransferDirection(pContext, peps, pTransfer);

        DEBUGCHK(peps->fInitialized);

        DWORD dwCurrentPermissions = GetCurrentPermissions();
        SetProcPermissions(pTransfer->dwCallerPermissions);

        __try {
            volatile ULONG *pulFifoReg = _GetDataRegister(dwEndpoint);
            DEBUGCHK(pulFifoReg != NULL);

            PBYTE  pbBuffer =  (PBYTE)pTransfer->pvBuffer + pTransfer->cbTransferred;

            DWORD cbBuffer = pTransfer->cbBuffer - pTransfer->cbTransferred;
            DWORD cbFifoWord = ReadIndexedReg(pContext, dwEndpoint, BRCR);
			
	     WORD ReadData = 0 ;
	     DWORD cbFifo;

	    if(dwEndpoint ==0){
		     if (bEpIrqStat & EP0LWO) 
			 	cbFifo = cbFifoWord*2-1;
		     else 
			 	cbFifo = cbFifoWord*2;
	   	}
	    else {
			if (bEpIrqStat & LWO) 
			 	cbFifo = cbFifoWord*2-1;
		     else 
			 	cbFifo = cbFifoWord*2;
	    	}
			
            DEBUGCHK(cbFifo <= peps->dwPacketSizeAssigned);

            // Read from the FIFO
            const DWORD cbRead = min(cbFifo, cbBuffer);
            DWORD cbToRead;
	     for (cbToRead = 0; cbToRead < cbRead; cbToRead+=2) {
		      ReadData= (WORD)*pulFifoReg;
		      *pbBuffer = (BYTE)ReadData;
		      *(pbBuffer+1) = (BYTE)(ReadData>>8);
		      pbBuffer +=2;
                }

            pTransfer->cbTransferred += cbRead;

            if ( (cbRead < peps->dwPacketSizeAssigned) ||
                 (pTransfer->cbTransferred == pTransfer->cbBuffer) ) {
                // Short packet or filled buffer. Complete transfer.
                fCompleted = TRUE;
                dwStatus = UFN_NO_ERROR;
            }

            if (dwEndpoint == 0) {
		 	SetClearReg(pContext, EP0SR, EP0RSR, SET); 
                if (fCompleted) {
                    pContext->Ep0State = EP0_STATE_IDLE;
                }
            }
            else {
		  if((peps->dwEndpointType == USB_ENDPOINT_TYPE_BULK) && (!fCompleted)){
			if(bEpIrqStat & PSIF)  {
				pbBuffer =  (PBYTE)pTransfer->pvBuffer + pTransfer->cbTransferred;
           			cbBuffer = pTransfer->cbBuffer - pTransfer->cbTransferred;
            			cbFifoWord = ReadIndexedReg(pContext, dwEndpoint, BRCR);
	      			ReadData = 0 ;

	     			if (bEpIrqStat & LWO) 
		 			cbFifo = cbFifoWord*2-1;
	     			else 
		 			cbFifo = cbFifoWord*2;

		            // Read from the FIFO
 			       const DWORD cbRead = min(cbFifo, cbBuffer);
				for (cbToRead = 0; cbToRead < cbRead; cbToRead+=2) {
		      			ReadData= (WORD)*pulFifoReg;
		      			*pbBuffer = (BYTE)ReadData;
		      			*(pbBuffer+1) = (BYTE)(ReadData>>8);
		      			pbBuffer +=2;
                		}

				pTransfer->cbTransferred += cbRead;

		              if ( (cbRead < peps->dwPacketSizeAssigned) ||
                 			(pTransfer->cbTransferred == pTransfer->cbBuffer) ) {
   	  	              	// Short packet or filled buffer. Complete transfer.
   		              	fCompleted = TRUE;
        		       	dwStatus = UFN_NO_ERROR;
            			}
			}
			else {
				RETAILMSG(DBG, (_T("Now_NO One Packet, bEpIrqStat : 0x%08x \r\n"),bEpIrqStat));
				}
				
		}

            }
        }
        __except(EXCEPTION_EXECUTE_HANDLER) {
            RETAILMSG(DBG, (_T("%s Exception!\r\n"), pszFname));
            fCompleted = TRUE;
            dwStatus = UFN_CLIENT_BUFFER_ERROR;
        }

        SetProcPermissions(dwCurrentPermissions);
    
        if (fCompleted) {
            RETAILMSG(DBG, (_T("%s RxDone Ep%x BufferSize=%u, Xfrd=%u\r\n"), 
                pszFname, dwEndpoint,pTransfer->cbBuffer, pTransfer->cbTransferred));
        }
    }
	else 
		SetClearIndexedReg(pContext,dwEndpoint,ESR,RPS,SET);
		

    *pfCompleted = fCompleted;
    *pdwStatus = dwStatus;
    FUNCTION_LEAVE_MSG();
}


// Write data to an endpoint.
static 
VOID
HandleTx(
         PCTRLR_PDD_CONTEXT       pContext,
         PEP_STATUS peps,
         BOOL fEnableInterrupts
         )
{
    SETFNAME();
    DEBUGCHK(pContext);
    PREFAST_DEBUGCHK(peps);

    // This routine can be entered from both ISTMain and MDD/Client threads so
    // need critical section.

    FUNCTION_ENTER_MSG();

#if 1
    BOOL fCompleted = FALSE; 
    PSTransfer pTransfer = peps->pTransfer;
    DWORD dwStatus = ERROR_GEN_FAILURE;
    DEBUGCHK(peps->fInitialized);
    DWORD dwEndpoint = peps->dwEndpointNumber;

    pTransfer = peps->pTransfer;

    if (pTransfer) {
        ValidateTransferDirection(pContext, peps, pTransfer);

        DEBUGCHK(pTransfer->dwFlags == USB_IN_TRANSFER);
        DEBUGCHK(pTransfer->dwUsbError == UFN_NOT_COMPLETE_ERROR);

        DWORD dwCurrentPermissions = GetCurrentPermissions();
        SetProcPermissions(pTransfer->dwCallerPermissions);

        // Transfer is ready
        __try {
            PBYTE pbBuffer = (PBYTE) pTransfer->pvBuffer + pTransfer->cbTransferred;
            DWORD cbBuffer = pTransfer->cbBuffer - pTransfer->cbTransferred;

			
            volatile ULONG *pulFifoReg = _GetDataRegister(dwEndpoint);

            DWORD cbWritten = 0;
	     WORD WriteData = 0;

            // Min of input byte count and supported size
            DWORD cbToWrite = min(cbBuffer, peps->dwPacketSizeAssigned); 

            if (dwEndpoint == 0) {

		  WriteIndexedReg(pContext, 0, BWCR, cbToWrite);
		  
                for (cbWritten = 0; cbWritten < cbToWrite; cbWritten+=2) {
		      WriteData=((*(pbBuffer+1))<<8) | *pbBuffer;	
                    *pulFifoReg = WriteData;
		      pbBuffer +=2;
                }

                /* We can complete on a packet which is full. We need to wait till
                * next time and generate a zero length packet, so only complete
                * if we're at the end and it is not the max packet size.
                */
                pTransfer->cbTransferred += cbToWrite;
				// We have to consider 16bit buffer interface
		  if (pTransfer->cbTransferred == pTransfer->cbBuffer 
					&& pTransfer->pvPddData == 0) {
				
                    dwStatus = UFN_NO_ERROR;
                    fCompleted = TRUE;
                    pContext->Ep0State = EP0_STATE_IDLE;
                }
                
            }
            else {
				
                // Enable Interrupts before writing to the FIFO. This insures
                // That any interrupts generated because of the write will be
                // "latched"
                if (fEnableInterrupts) {
                    DEBUGCHK(dwEndpoint != 0);
		       EnableEndpointInterrupt(pContext, dwEndpoint);
                }

		// If Packet was completed in a previous interrupt cycle,
		// the data length to be txed will be zero, and 
		// zero length data packet should not be transmitted 
		if( cbToWrite != 0) WriteIndexedReg(pContext, dwEndpoint, BWCR, cbToWrite);;

		  for (cbWritten = 0; cbWritten < cbToWrite; cbWritten+=2) {
		      WriteData=((*(pbBuffer+1))<<8) | *pbBuffer;	
                    *pulFifoReg = WriteData;
		      pbBuffer +=2;
                }

			
				// We have to consider 16bit buffer interface
                if (pTransfer->cbTransferred == pTransfer->cbBuffer 
					|| cbWritten == 0) {
                    dwStatus = UFN_NO_ERROR;
                    fCompleted = TRUE;
                }

                // By Placing the check for packet complete here, before
                // cbTransferred is updated, there is a 1 interrupt cycle delay
                // That is complete is not declared until the data has actually
                // been ACKd (TPC set) by the host
		  pTransfer->cbTransferred += cbToWrite;
            }
        }
        __except(EXCEPTION_EXECUTE_HANDLER) {
            RETAILMSG(DBG, (_T("%s Exception!\r\n"), pszFname));
            fCompleted = TRUE;
            dwStatus = UFN_CLIENT_BUFFER_ERROR;
        }

        SetProcPermissions(dwCurrentPermissions);
    }   
    else {
        // It is possible for an interrupt to come in while still in this 
        // function for first pass of transfer. If this happens it is possible
        // to complete the transfer and have that interrupt be unnecessary
        // so... just ignore it.
        RETAILMSG(DBG, (_T("%s Not Transfer \r\n"), 
            pszFname));
        goto EXIT;
    }


    if (fCompleted) {
        // Disable transfer interrupts until another transfer is issued.
        if (peps->dwEndpointNumber != 0) {
            DisableEndpointInterrupt(pContext, peps->dwEndpointNumber);
        }

        RETAILMSG(DBG, (_T("%s Tx Done  Ep%x  Status %u\r\n"), pszFname, 
            dwEndpoint, dwStatus));
        CompleteTransfer(pContext, peps, dwStatus);
    }
    else {
        RETAILMSG(DBG, (_T("%s Tx EP%x BufferSize=%u, Xfrd=%u\r\n"), 
            pszFname, dwEndpoint, pTransfer->cbBuffer, pTransfer->cbTransferred));
    }

EXIT:
    FUNCTION_LEAVE_MSG();
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -