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

📄 z228_usb_msc.cpp

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	PhysicalIoBase.HighPart = 0;
	PhysicalIoBase.LowPart = Z228_RESET;
	reset = (DWORD *)MmMapIoSpace( PhysicalIoBase, 0x1000 ,FALSE );
	if( !reset )    	{
        		RETAILMSG(USB_ERROR,	(TEXT("MAP Z228_RESET register failed \r\n")));
    	}
    	else{	
    			*reset &= ~(Z228_RESET_nUSBRES |Z228_RESET_nUSB48RES|Z228_RESET_nUSBPLLRES |Z228_RESET_nUSB12RES);
			Sleep(10);
			
			*reset |=Z228_RESET_nUSB48RES;
			Sleep(10);
			*reset |=Z228_RESET_nUSBPLLRES;
			Sleep(10);
			*reset |=Z228_RESET_nUSB12RES;
			Sleep(10);
			*reset |=Z228_RESET_nUSBRES;
			Sleep(40);
			
			MmUnmapIoSpace( reset, 0x1000 );
	}
	
	/* Disable interrupts */
	usb_write(0, UDC_ENDP_INTR_ENABLE);
	usb_write(~0, UDC_ENDP_INTR);
	
	usb_write(0, UDC_INTR_ENABLE);
	usb_write(~0, UDC_INTR);
	
    // Reset all endpoints
    for (DWORD dwEpIdx = 0; dwEpIdx < ENDPOINT_COUNT; ++dwEpIdx) {
        PEP_STATUS peps = GetEpStatus(pContext, dwEpIdx);
        ResetEndpoint(pContext, peps);
    }
  
}

// Check the device release number.
static
VOID
CheckDeviceRelease(
    PZ228_CONTEXT pContext
    )
{
    RETAILMSG(USB_DEBUG, (_T("==> CheckDeviceRelease ()\r\n")));
}

inline
static
VOID
SetClearTransferInterrupts(
    PZ228_CONTEXT pContext,
    PEP_STATUS peps,
    PSTransfer pTransfer,
    BOOL bSet
    )
{
    // Enable transfer interrupts.
    if(bSet)
       	usb_set(peps->dwFlags, UDC_ENDP_INTR_ENABLE);
    else
       	usb_clear(peps->dwFlags, UDC_ENDP_INTR_ENABLE);
    RETAILMSG(USB_DEBUG, (_T("SetClearTransferInterrupts:  0x%x \r\n"), usb_read(UDC_ENDP_INTR_ENABLE)));
}

/*
 * Z228 Bus Suspend Interrupt Handler
 */
inline static void z228_suspend_intr(PZ228_CONTEXT pContext)
{
	  DWORD dwID_Change;
         
         RETAILMSG(USB_DEBUG, (_T("+z228_suspend_intr\r\n")));
         if(pContext->fAttached == TRUE)	  {
                   pContext->pfnNotify(pContext->pvMddContext,UFN_MSG_BUS_EVENTS, UFN_DETACH);
                   pContext->fAttached = FALSE;
		     usb_set(UDC_BUSRESET_INTR, UDC_INTR_ENABLE); 
		     usb_clear(UDC_SUSPEND_INTR, UDC_INTR_ENABLE);
	  }		 
	  dwID_Change = usb_read(UHC_OTG_CSR)& UHC_CONN_ID_CHANGE;
	  if(dwID_Change)   {                  
		      usb_write(UHC_CONN_ID_CHANGE, UHC_OTG_CSR);          	  
           			  
		       // clear the ID Change intr
		       DWORD dwMode = (usb_read(UHC_OTG_CSR)&OTG_MODE_DEVICE)? DEV_MODE : HOST_MODE;
                     	if(dwMode == HOST_MODE)  {
                     		RETAILMSG(1, (_T("Device: ID change Done, Mode = %d! set event\r\n"),dwMode));
			        pContext->fExitIST = TRUE;	
			        SetEvent(pContext->hevDevEvent);
		               Sleep(100);		           
		       }
			else {
				usb_set(UDC_BUSRESET_INTR |UDC_SUSPEND_INTR,  UDC_INTR);
			}			
		       
      }
	   //delay for a while waiting upper level DETACH
	   Sleep(200);
}

/*
 * Z228 Bus Reset Interrupt Handler
 */
inline static void z228_reset_intr(PZ228_CONTEXT pContext)
{
	 RETAILMSG(USB_DEBUG, (_T("+z228_reset_intr\r\n")));

	 if (!pContext->fAttached) {
            	// Upon attach sometimes we do not get a VBUS interrupt, 
            	// just the reset interrupt.
            	usb_set(UDC_SUSPEND_INTR, UDC_INTR_ENABLE); 
            	pContext->pfnNotify(pContext->pvMddContext,UFN_MSG_BUS_EVENTS, UFN_ATTACH);
	     	pContext->fAttached = TRUE;		 
   	} 
	 
    	pContext->fSpeedReported = FALSE;
    	pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS,UFN_RESET);
     
	usb_write(0x0, UDC_RX_CONTROL(0));
	usb_write(UDC_RX_FLUSHFIFO, UDC_RX_CONTROL(0));
	
	usb_write(0x0, UDC_TX_CONTROL(0));
	
	usb_write(UDC_TX_FLUSHFIFO, UDC_TX_CONTROL(0)); 
 	usb_write(UDC_FIFOREADY, UDC_RX_CONTROL(0));	

}


static
VOID
HandleTx(
    PZ228_CONTEXT pContext,
    PEP_STATUS peps
    )
{
    	PREFAST_DEBUGCHK(pContext);
    	PREFAST_DEBUGCHK(peps);
    	DEBUGCHK(peps->fInitialized);

    	PSTransfer pTransfer = peps->pTransfer;
    	BOOL fCompleted = FALSE;
    	DWORD dwStatus;
    	DWORD cdwToWrite, iTimes, remains;
    	unsigned char *tsrc,*tdst;
    	DWORD* pdwBuffer;
    	volatile DWORD * const pdwReg =  (DWORD *)(udc_base+(UDC_TX_FIFO(peps->dwEndpoint)>>2)) ;
	
    	//RETAILMSG(1, (_T("==> HandleTx ()\r\n")));

    	ValidateTransferDirection(pContext, peps, pTransfer);

    	DEBUGCHK(TRANSFER_IS_IN(pTransfer));
    	DEBUGCHK(pTransfer->dwUsbError == UFN_NOT_COMPLETE_ERROR);
    	DEBUGMSG(USB_DEBUG, (_T("		UDC_TX_STATUS = 0x%x\r\n"),usb_read(UDC_TX_STATUS(peps->dwEndpoint))));
    	RETAILMSG(USB_DATA_OUT, (_T("		pTransfer->dwEndpoint = 0x%x\r\n"),peps->dwEndpoint));
    	DEBUGMSG(USB_DEBUG, (_T("		pTransfer->cbTransferred = 0x%x\r\n"),pTransfer->cbTransferred));
    	//RETAILMSG(USB_DATA_IN, (_T("		len = 0x%x\r\n"),pTransfer->cbBuffer));
 	
    	DWORD dwCurrentPermissions = GetCurrentPermissions();
    	SetProcPermissions(pTransfer->dwCallerPermissions);

  Tx_Again:
      __try {
  
       const BYTE *c_pbBuffer = (const BYTE*) pTransfer->pvBuffer + pTransfer->cbTransferred;
       const DWORD c_cbBuffer = pTransfer->cbBuffer - pTransfer->cbTransferred;			
            
	 // Min of input byte count and supported size
	cdwToWrite =min(c_cbBuffer,peps->dwPacketSizeAssigned); 
	    
	if(cdwToWrite){ 	       
	         iTimes = cdwToWrite>>2;
	         remains = cdwToWrite & 0x3;
	         				
	         usb_write(cdwToWrite, UDC_TX_TRANSFER_SIZE(peps->dwEndpoint));	    
		
		 // Write to FIFO through register.
               pdwBuffer = (DWORD*) c_pbBuffer;
       
		  // memcpy((BYTE*)pdwReg, (BYTE*)pdwReg, cdwToWrite);
		  
		  for(DWORD a=0; a<iTimes; a++)	   
				*pdwReg=*(pdwBuffer+a);
				      
		   // Now handle the leftovers
		   if (remains) {
			     tdst = (unsigned char *)(pdwReg + a);
			     tsrc = (unsigned char *)(pdwBuffer + a);								
			     while (remains--)
					 *tdst++ = *tsrc++;			
		    }
		    
		     pTransfer->cbTransferred += cdwToWrite;
	}	
		   
	// Set FIFO Ready Bit to send data
	usb_set(UDC_TX_FIFOREADY, UDC_TX_CONTROL(peps->dwEndpoint));	

	 // clear status bit	
	usb_set(UDC_TX_NAKSENT,UDC_TX_STATUS(peps->dwEndpoint));		
	if(pTransfer->cbTransferred == pTransfer->cbBuffer)	{
                  DWORD TxStatus = usb_read(UDC_TX_STATUS(peps->dwEndpoint));
		    if(TxStatus & UDC_TX_DATASENT)  {				  	
			       usb_set(UDC_TX_DATASENT,UDC_TX_STATUS(peps->dwEndpoint));
				usb_set(UDC_TX_NAKSENT,UDC_TX_STATUS(peps->dwEndpoint));				
			       dwStatus = UFN_NO_ERROR;
			       fCompleted = TRUE;
		    }
	 }
	   else{
				fCompleted = FALSE;
	}
    }
    	__except(EXCEPTION_EXECUTE_HANDLER) {
        	RETAILMSG(USB_ERROR, (_T("%s TX Exception!\r\n"), pszFname));
        	fCompleted = TRUE;
        	dwStatus = UFN_CLIENT_BUFFER_ERROR;
    }	
	
    if(fCompleted == FALSE){        
          for(DWORD i=0; i<20; i++)
		if(usb_read(UDC_TX_STATUS(peps->dwEndpoint))&(UDC_TX_DATASENT))
		{
                       usb_set(UDC_TX_DATASENT,UDC_TX_STATUS(peps->dwEndpoint));
			  usb_set(UDC_TX_NAKSENT,UDC_TX_STATUS(peps->dwEndpoint));	
                        goto Tx_Again;
			   break;
		}
   }
	else 
       	CompleteTransfer(pContext, peps, dwStatus);

    SetProcPermissions(dwCurrentPermissions);
	
}

static
VOID
HandleRx(
    PZ228_CONTEXT pContext,
    PEP_STATUS peps
    )
{    

    DEBUGCHK(pContext);
    DEBUGCHK(peps);
    DEBUGCHK(peps->fInitialized);

    PSTransfer pTransfer = peps->pTransfer;
    BOOL fCompleted = FALSE;
    DWORD dwStatus = UFN_NO_ERROR, dwRxStatus;
    DWORD iTimes, remains, size;
    unsigned char *tsrc,*tdst;  
    DWORD  *fifo = (DWORD*)((DWORD) udc_base + (UDC_RX_FIFO>>2)), *pdwBuffer ;
 
    DEBUGCHK(TRANSFER_IS_OUT(pTransfer));
    DEBUGCHK(pTransfer->dwUsbError == UFN_NOT_COMPLETE_ERROR);
    RETAILMSG(0, (_T("+Rx\r\n")));				
    
    ValidateTransferDirection(pContext, peps, pTransfer);

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

Rx_Again:  
    __try {
        PBYTE  pbBuffer = (PBYTE) pTransfer->pvBuffer + pTransfer->cbTransferred;        
        DWORD  cbBuffer = pTransfer->cbBuffer - pTransfer->cbTransferred; 
	
	 dwRxStatus = usb_read(UDC_RX_STATUS);
	 size = (dwRxStatus >> UDC_RX_SIZE_SHIFT) & UDC_RX_SIZE_MASK;
	 size = min(cbBuffer, size);	 
	 RETAILMSG(USB_DATA_OUT, (_T("cbBuffer=0x%x ,size=0x%x\r\n"),cbBuffer,size));

	 if (dwRxStatus & UDC_RX_STATUS_COMPLETE)	{
	   //if(dwRxStatus & UDC_RX_GOOD_STATUS)	 {										
		if(size != 0 )      {
			/* Need to read out some data from FIFO */			
			iTimes = size>>2;
			remains = size & 0x3;
			pdwBuffer= (DWORD *) pbBuffer;
		
			 //memcpy((char *)pdwBuffer, (char *)fifo, size);
			for(DWORD a=0; a<iTimes; a++)
			{
				*(pdwBuffer+a)=*fifo;
				//RETAILMSG(USB_DATA_IN, (TEXT(" 0x%08x "),*(pdwBuffer+a)));
			}	
			/* Now handle the leftovers */
			if (remains) {
				tsrc = (unsigned char *)(fifo + a);
				tdst = (unsigned char *)(pdwBuffer + a);								
				while (remains--)
					*tdst++ = *tsrc++;
				//RETAILMSG(USB_DATA_IN, (TEXT(" 0x%06x "),*(pdwBuffer+a)));
			}					
			//RETAILMSG(USB_DATA_IN,(TEXT("\r\n")));
			pTransfer->cbTransferred += size;
			if(pTransfer->cbTransferred == pTransfer->cbBuffer)
			         fCompleted = TRUE;
			else 
				  fCompleted = FALSE;
		}	    
	     usb_set(UDC_RX_STATUS_COMPLETE, UDC_RX_STATUS);
         }
	  usb_write(UDC_RX_FIFOREADY, UDC_RX_CONTROL(peps->dwEndpoint));
     	}	
    	__except(EXCEPTION_EXECUTE_HANDLER) {
        	RETAILMSG(USB_ERROR, (_T("%s RX Exception!\r\n"), pszFname));
        	fCompleted = TRUE;
        	dwStatus = UFN_CLIENT_BUFFER_ERROR;
     }   
    
    	if (fCompleted) {    
       	CompleteTransfer(pContext, peps, dwStatus);
    	} 
	  else {
          	for(DWORD i=0;	i<10;	i++)       {
                 	dwRxStatus = usb_read(UDC_RX_STATUS);
		   	if (dwRxStatus & UDC_RX_STATUS_COMPLETE)  { 
				goto Rx_Again;		      
		              break;
		   	}
         }
   }
	  
    SetProcPermissions(dwCurrentPermissions);
}


// Calls must be protected by the pTransfer->cs.
static
VOID
StartTransfer(
    PZ228_CONTEXT pContext,
    PEP_STATUS peps,
    PSTransfer pTransfer
    )
{	
    DWORD dwRxStatus;

    DEBUGCHK(pContext);
    PREFAST_DEBUGCHK(peps);
    DEBUGCHK(!peps->pTransfer);
    DEBUGCHK(pTransfer->dwUsbError == UFN_NOT_COMPLETE_ERROR);
    ValidateTransferDirection(pContext, peps, pTransfer);

    //RETAILMSG(1, (_T("+ StartTransfer \r\n")));
    
    DEBUGMSG(USB_DEBUG, (_T(" Setting up %s %s transfer on ep %c for %u bytes\r\n"),
       peps->pszType,  TRANSFER_IS_IN(pTransfer) ? _T("IN") : _T("OUT"),
        GET_ENDPOINT_LETTER(peps->dwEndpoint), pTransfer->cbBuffer));    
      
    peps->pTransfer = pTransfer;

    // Enable transfer interrupts.
   SetClearTransferInterrupts(pContext, peps, pTransfer, SET);
	
   if (TRANSFER_IS_IN(pTransfer) ) {       	
       	 // Fill FIFO
		HandleTx(pContext, peps);
    }
    else if(TRANSFER_IS_OUT(pTransfer) && peps->dwEndpoint){          
	        dwRxStatus = usb_read(UDC_RX_STATUS);			
		// start to Rx 
		if (dwRxStatus & UDC_RX_STATUS_COMPLETE)			
			HandleRx(pContext, peps);
  }  
  RETAILMSG(USB_DEBUG, (_T("-StartTransfer \r\n")));
    
}


DWORD
WINAPI
UfnPdd_IssueTransfer(
    PVOID  pvPddContext,
    DWORD  dwEndpoint,
    PSTransfer pTransfer
    )
{
    DWORD dwRet;

    DEBUGCHK(EP_VALID(dwEndpoint));
    DEBUGCHK(pTransfer->dwUsbError == UFN_NOT_COMPLETE_ERROR);
    DEBUGCHK(pTransfer->cbTransferred == 0);
	
    //RETAILMSG(1, (_T("+UfnPdd_IssueTransfer %d\r\n"),dwEndpoint));

    PZ228_CONTEXT pContext = (PZ228_CONTEXT) pvPddContext;
    ValidateContext(pContext);

    PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);

    LOCK_ENDPOINT1(peps);
  
    DEBUGCHK(peps->fInitialized);   
    
    if ( (peps->dwPacketSizeAssigned & 0x3) != 0 &&
         (pTransfer->cbBuffer > peps->dwPacketSizeAssigned) ) {
        // We do not support transfer greater than the max packet
        // size if the max packet size is not DWORD aligned due to
        // alignment problems in HandleTx().
        // The solution is to issue transfers of max packet size or
        // less.
        
        RETAILMSG(USB_ERROR, (_T("%s Transfer size too large for non-DWORD aligned max packet size\r\n"),
            pszFname));
        dwRet = ERROR_INVALID_PARAMETER;
        goto EXIT;
    }

    DEBUGCHK(peps->pTransfer == NULL);
    StartTransfer(pContext, peps, pTransfer);

    dwRet = ERROR_SUCCESS;

EXIT:
    UNLOCK_ENDPOINT1(peps);   

    return dwRet;
}

// Surround calls with cs on both the endpoint and the transfer.
static
VOID
CompleteTransfer(
    PZ228_CONTEXT pContext,
    PEP_STATUS peps,
    DWORD dwUsbError
    )
{
    
    //RETAILMSG(1, (_T("+CompleteTransfer %d \r\n"),peps->dwEndpoint));

⌨️ 快捷键说明

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