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

📄 sc2410_usb_ser.c

📁 三星公司2410的usb驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
					    NULL,
					    (LPBYTE)(&pHWHead->dwIOLen), 
					    &dwDataSize);
	}

	RegCloseKey (hKey);

	if (regError != ERROR_SUCCESS) 
	{
		DEBUGMSG(1,(TEXT("Failed to get serial registry values, Error 0x%X\r\n"),
																		regError));
		return (FALSE);
	}

	DEBUGMSG(1,(TEXT("SerInit - Devindex %d, IRQ %d, IOB %X, IOLen %X \r\n"),
					pHWHead->dwDevIndex,
					pHWHead->dwIRQ,
					pHWHead->dwIOBase,
					pHWHead->dwIOLen));

	return (TRUE); 
}



/*************************************************************************
 @doc OEM 
 @func PVOID | SerInit | Initializes device identified by argument.
 *  This routine sets information controlled by the user
 *  such as Line control and baud rate. It can also initialize events and
 *  interrupts, thereby indirectly managing initializing hardware buffers.
 *  Exported only to driver, called only once per process.
 *
 @rdesc The return value is a PVOID to be passed back into the HW
 dependent layer when HW functions are called.
 ************************************************************************/
static
PVOID SerInit( ULONG   Identifier, // @parm Device identifier.
               PVOID   pMddHead,   // @parm First argument to mdd callbacks.
	       PHWOBJ  pHWObj )    // @parm Pointer to our own HW OBJ for this device

{
	PSER_INFO pHWHead;
	PHYSICAL_ADDRESS PhysicalAddress = {0,0};
	ULONG WaitReturn; //Jonathan01_0915
        
        if(hUSBAcInIntr) //edyeh1108
      	    hUSBAcInIntr = CreateEvent(NULL, FALSE, FALSE,TEXT("PNA500:AC-IN Event")); 

        
        //Jonathan01_0915 start	
        if(!pDriverGlobals)
        {
           pDriverGlobals = (PDRIVER_GLOBALS) VirtualAllocCopy(DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,(char *)TEXT("BLKLGT: DRIVER_GLOBALS"), (PVOID)DRIVER_GLOBALS_PHYSICAL_MEMORY_START);
           if(!pDriverGlobals)
	   {
		    return(NULL);
           }
        }
    
        if(!s2410IOP)
        {
            s2410IOP = (volatile IOPreg *) VirtualAllocCopy(0x400,(char *)TEXT("IOP: GPIO_BASE_VIRTUAL"), (PVOID)IOP_BASE);
            if(!s2410IOP)
	           {
	           	if (pDriverGlobals)
                    VirtualFree((PVOID)pDriverGlobals, 0, MEM_RELEASE);
	       	    return(NULL);
            }
        } 
   
        if(!s2410CLKPW)
        {
        	s2410CLKPW = (volatile CLKPWRreg *) VirtualAllocCopy(0x1000,(char *)TEXT("IOP: CLKPW_BASE_VIRTUAL"), (PVOID)CLKPWR_BASE);
        	if(!s2410CLKPW)
        	{
        		if(pDriverGlobals)
        			VirtualFree((PVOID)pDriverGlobals, 0, MEM_RELEASE);
        
        		if(s2410IOP)
        			VirtualFree((PVOID)s2410IOP, 0, MEM_RELEASE);
        
        		return NULL;
        	}
        } 
        //Jonathan01_0915 end	

#ifdef DEBUG
	dpCurSettings.ulZoneMask = 0;
#endif

	DEBUGMSG (1, (TEXT("++SerInit %X\r\n"), pMddHead ));
	RETAILMSG(1,(TEXT("::: SerInit Start\r\n")));
	
	//Jonathan01_0915 start
	s2410IOP->rGPGUP  |= (0x1 << 8);
        s2410IOP->rGPGCON &= ~(0x3 << 16); //USB_ID
    
        s2410IOP->rGPGUP  |= (0x1 << 1);
        s2410IOP->rGPGCON &= ~(0x3 << 2);  //AC_IN
    
        //USB_EN
        s2410IOP->rGPJDAT &= ~(0x1 << 9); //turn off USB_EN
	
	//edyeh1015, Init in Uboot codes.
	//edyeh1015 //s2410IOP->rGPJUP  |=  (0x1 << 9); //the pull up function is disabled
	//edyeh1015 //s2410IOP->rGPJCON &= ~(0x3 << 18);//Output
        //edyeh1015 //s2410IOP->rGPJCON |= (0x1 << 18);
        
        
        pDriverGlobals->misc.InitUSBClient = 1; 
        //Jonathan01_0915 end
        
	// Allocate for our main data structure and one of it's fields.
	pHWHead = (PSER_INFO)LocalAlloc( LPTR, sizeof(SER_INFO) );
	if ( !pHWHead )
		goto ALLOCFAILED;

	if (!Ser_GetRegistryData(pHWHead, (LPCTSTR)Identifier)) 
	{
		DEBUGMSG (1,(TEXT("SerInit - Unable to read registry data. Failing Init !!! \r\n")));
		goto ALLOCFAILED;
	}

	// Create our interrupt event.
	pHWHead->hSerialEvent = CreateEvent(0,FALSE,FALSE,NULL);

	// Initialize our critical sections
	InitializeCriticalSection(&(pHWHead->TransmitCritSec));
	InitializeCriticalSection(&(pHWHead->HwRegCritSec));

	SerUSBInternalMapRegisterAddresses(pHWHead);
	if(!InitUsbdDriverGlobals())  //:-)
		goto ALLOCFAILED;
	if(!UsbdAllocateVm())  //:-)
		goto ALLOCFAILED;
	

	pHWHead->pMddHead		= pMddHead;
	pHWHead->cOpenCount		= 0;
	pHWHead->pHWObj			= pHWObj;
	pHWHead->wSOFStableCnt	= 0; 				
    
	// Set up our Comm Properties data    
	pHWHead->CommProp.wPacketLength      = 0xffff;
	pHWHead->CommProp.wPacketVersion     = 0xffff;
	pHWHead->CommProp.dwServiceMask      = SP_SERIALCOMM;
	pHWHead->CommProp.dwReserved1        = 0;
	pHWHead->CommProp.dwMaxTxQueue       = 64;
	pHWHead->CommProp.dwMaxRxQueue       = 64;
	pHWHead->CommProp.dwMaxBaud          = BAUD_115200;
	pHWHead->CommProp.dwProvSubType      = PST_RS232;
	pHWHead->CommProp.dwProvCapabilities =  PCF_RLSD | 
						PCF_SETXCHAR |
						PCF_INTTIMEOUTS |
						PCF_SPECIALCHARS |
						PCF_TOTALTIMEOUTS |
						PCF_XONXOFF;
	pHWHead->CommProp.dwSettableBaud      =	BAUD_075 | BAUD_110 | BAUD_150 | 
						BAUD_300 | BAUD_600 |
						BAUD_1200 | BAUD_1800 | 
						BAUD_2400 | BAUD_4800 |
						BAUD_7200 | BAUD_9600 | BAUD_14400 |
						BAUD_19200 | BAUD_38400 | 
						BAUD_56K | BAUD_128K |
						BAUD_115200 | BAUD_57600 | BAUD_USER;
	pHWHead->CommProp.dwSettableParams    =	SP_BAUD | SP_RLSD ;
	pHWHead->CommProp.wSettableData       =	DATABITS_8;
	pHWHead->CommProp.wSettableStopParity =	STOPBITS_10 | STOPBITS_20 |
						PARITY_NONE | PARITY_ODD | 
						PARITY_EVEN | PARITY_SPACE |
						PARITY_MARK;

	pHWHead->fIRMode  = FALSE;   // Select wired by default

        pHWHead->State = IDLE;
    
	// Here is where we do any actual init for the hardware.  In the case of
	// USB function, we mostly just validate the hardware and then enable
 	// interrupts.  When we detect the presence of the bus, GetIntr will take
	// care of identify us to the host and kicking things off.

	SC2410_USB_Init(pHWHead);
	
	//Jonathan01_0915 start
        pDriverGlobals->misc.USBCableEvent =0;
        pHWHead->ModemStatus &= ~MS_RLSD_ON;
        EvaluateEventFlag(pHWHead->pMddHead, EV_RLSD);
       
        //make a delay
        WaitReturn = WaitForSingleObject(pHWHead->hSerialEvent, 0x00000600L);
       
        if(!(s2410IOP->rGPGDAT & (0x1 << 1)) && (s2410IOP->rGPGDAT & (0x1 << 8)))
        {	
             s2410IOP->rGPJDAT |= (0x1 << 9); //turn on USB_EN
                
             s2410CLKPW->rCLKCON |= (0x1<<7);
             pDriverGlobals->misc.USBCableEvent =1;
             pDriverGlobals->misc.InitUSBClient = 0; 
             RETAILMSG(1,(TEXT("::: SerInit -- USB IN \r\n"))); 
        } 
        else //NO USB IN
        {      
             s2410IOP->rGPJDAT &= ~(0x1 << 9); //turn off USB_EN
                   
             s2410CLKPW->rCLKCON &= ~(0x1<<7);
                       
             RETAILMSG(1,(TEXT("::: SerInit -- NO USB IN \r\n")));     	
        }
	//Jonathan01_0915 end			

	DEBUGMSG (1, (TEXT("--SerInit - %X\r\n"), pHWHead ));
	RETAILMSG(1,(TEXT("::: SerInit end\r\n")));

	return (pHWHead);

ALLOCFAILED:
	// Unmap any memory areas that we may have mapped.
	if ( pHWHead->pUSBCtrlAddr)
		VirtualFree((PVOID)pHWHead->pUSBCtrlAddr, 0, MEM_RELEASE);

	if ( pHWHead->pIrqCtrlAddr)
		VirtualFree((PVOID)pHWHead->pIrqCtrlAddr, 0, MEM_RELEASE);

	if ( pHWHead->pCLKPWR)
		VirtualFree((PVOID)pHWHead->pCLKPWR, 0, MEM_RELEASE);

	LocalFree(pHWHead);

	// Free any critical sections we have allocated
	DeleteCriticalSection(&(pHWHead->TransmitCritSec));
	DeleteCriticalSection(&(pHWHead->HwRegCritSec));

	// And free the context data structure
	LocalFree(pHWHead);

	DEBUGMSG (1,(TEXT("--SerInit - %X\r\n"), pHWHead ));
	//RETAILMSG(1,(TEXT("::: SerInit end\r\n")));

	return (NULL);
}

/*************************************************************************
 @doc OEM 
 @func PVOID | SerPostInit | Performs final hardware initialization.
 ************************************************************************/
static
BOOL SerPostInit(PVOID   pHead)   // @parm PVOID returned by SerInit.
{
	PSER_INFO pHWHead = (PSER_INFO)pHead;

	DEBUGMSG(1, (TEXT("+++SerPostInit\r\n")));

	// We use a PDD specific thread, rather than the default thread provided
	// by the MDD.
	StartEventThread( pHWHead );

	// Enable interrupts after thread is started - DAL
	// ....
	
	return TRUE;
}

/*************************************************************************
 @doc OEM 
 @func PVOID | SerDeinit | Deinitializes device identified by argument.
 *  This routine frees any memory allocated by SerInit.
 ************************************************************************/
static
BOOL SerDeinit(PVOID   pHead)   // @parm PVOID returned by SerInit.
{
	PSER_INFO pHWHead = (PSER_INFO)pHead;

	DEBUGMSG(1, (TEXT("+SerDeinit\r\n")));

	// Disable interrupts
	// ...

	if ( !pHWHead )
		return (FALSE);

	// Make sure device is closed before doing DeInit
	if ( pHWHead->cOpenCount )
		SerClose( pHead );

	if ( pHWHead->pUSBCtrlAddr)
		VirtualFree((PVOID)pHWHead->pUSBCtrlAddr, 0, MEM_RELEASE);

	if ( pHWHead->pIrqCtrlAddr)
		VirtualFree((PVOID)pHWHead->pIrqCtrlAddr, 0, MEM_RELEASE);

	if ( pHWHead->pCLKPWR)
		VirtualFree((PVOID)pHWHead->pCLKPWR, 0, MEM_RELEASE);

	UsbdDeallocateVm(); //:-)

	// Free any critical sections we have allocated
	DeleteCriticalSection(&(pHWHead->TransmitCritSec));
	DeleteCriticalSection(&(pHWHead->HwRegCritSec));

	// Free the HWObj allocated in GetSerialObject
	LocalFree(pHWHead->pHWObj);

	LocalFree(pHWHead);

	DEBUGMSG(1, (TEXT("-SerDeinit\r\n")));

	return (TRUE);
}

/*************************************************************************
 @doc OEM
 @func BOOL | SerOpen | This routine is called when the port is opened.
 *  Not exported to users, only to driver.
 *
 @rdesc Returns TRUE if successful, FALSEotherwise.
 ************************************************************************/
static
BOOL SerOpen(PVOID   pHead) /*@parm PVOID returned by Serinit. */
{
	PSER_INFO pHWHead = (PSER_INFO)pHead;

	DEBUGMSG(1,
			(TEXT("SerOpen+\r\n")));
	NKDbgPrintfW(L"SerOpen++\r\n");//jocky0308
	// Disallow multiple simultaneous opens
	if (pHWHead->cOpenCount)
		return (FALSE);
    
	pHWHead->cOpenCount++;

#ifdef POLL_FOR_DISCONNECT
	// Yuck.  We want to poll for detaches when the device is open.
	// But right now, the IST is in a wait infinite.  Spoof an interrupt
	// to let him know we have been opened and he needs to start polling.
	SetEvent(pHWHead->hSerialEvent);
#endif

	return (TRUE);
}

/*************************************************************************
 @doc OEM
 @func ULONG | SerClose | This routine closes the device identified by the 
 *  PVOID returned by SerInit.
 *  Not exported to users, only to driver.
 *
 @rdesc The return value is 0.
 ************************************************************************/
static
ULONG SerClose(PVOID   pHead)   // @parm PVOID returned by SerInit.
{
	PSER_INFO pHWHead = (PSER_INFO)pHead;

	DEBUGMSG (1, (TEXT("++SerClose\r\n")));

	if (pHWHead->cOpenCount) 
	{
		DEBUGMSG (1, (TEXT("SerClose, closing device\r\n")));
		pHWHead->cOpenCount--;

#ifdef TODO
		// Do we need something similar on USB???
		// while we are still transmitting, sleep.
		uTries = 0;

		while ( ((pHWHead->ser16550.IER = READ_PORT_UCHAR(pHWHead->ser16550.pIER)) 
					& SERIAL_IER_THR) &&	// indicates TX in progress
					(uTries++ < 100) &&     // safety net
								// indicates FIFO not yet empty
					!(pHWHead->ser16550.LSR & SERIAL_LSR_TEMT)) 
		{

				DEBUGMSG(1, (TEXT("SerClose, TX in progress, IER 0x%X, LSR 0x%X\r\n"),
						*pHWHead->ser16550.pIER, pHWHead->ser16550.LSR));
				Sleep(10);
		}
#endif

		// TODO - When the device is closed, should power it down or somehow try to
		// let the desktop know that we aren't doing anything with any data that it
		// might be sending our way..
    
		// Mask interrupts? - No, we wont see any more traffic - MBE.
		//pHWHead->pIrqCtrlAddr->icmr.sp0 = 0;
	}

	DEBUGMSG(1,(TEXT("--SerClose\r\n")));

	return (0);
}

/*************************************************************************
 @doc OEM
 @func ULONG | SerRxIntr | This routine gets several characters from the 
	hardware receive buffer and puts them in a buffer provided via the se-
	cond argument. It returns the number of bytes lost to overrun.

 @rdesc The return value indicates the number of overruns detected.
	The actual number of dropped characters may be higher.
**************************************************************************/
static
ULONG SerRxIntr(PVOID pHead,                // @parm Pointer to hardware head
		PUCHAR pRxBuffer,           // @parm Pointer to receive buffer
		ULONG *pBufflen )           // @parm In = max bytes to read, out = bytes read
{
	PSER_INFO   pHWHead			 = (PSER_INFO)pHead;
	ULONG       RetVal			 = 0;
	ULONG       TargetRoom			 = *pBufflen;
	BOOL        fRXFlag			 = FALSE;
	BOOL        fReplaceparityErrors = FALSE;
	BOOL        fNull;
	UCHAR       cEvtChar;
	PUCHAR      pRxOrig			 = pRxBuffer;

	DEBUGMSG(1, (TEXT("++SerRxIntr %d\r\n"), *pBufflen));

	cEvtChar = pHWHead->dcb.EvtChar;
	fNull	 = pHWHead->dcb.fNull;

	if( pHWHead->dcb.fErrorChar && pHWHead->dcb.fParity )
		fReplaceparityErrors = TRUE;

⌨️ 快捷键说明

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