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

📄 bvd_udc_ser.c

📁 Xcale270Bsp包,wince平台
💻 C
📖 第 1 页 / 共 3 页
字号:
}

//
// @doc OEM
// @func VOID | SerSetDTR | This routine sets DTR.
// 
// @rdesc None.
//
static
VOID SerSetDTR(
    PVOID   pHead // @parm PVOID returned by HWinit.
    )
{    
  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("SerSetDTR, 0x%X\r\n"),
	     pHead));

  // We don't support DTR emulation.
}

//
// @doc OEM
// @func VOID | SerClearRTS | This routine clears RTS.
// 
// @rdesc None.
// 
static
VOID SerClearRTS(
    PVOID   pHead // @parm PVOID returned by HWinit.
    )
{
  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("SerClearRTS, 0x%X\r\n"),
	     pHead));

  // We don't support RTS emulation.
}

//
// @doc OEM
// @func VOID | SerSetRTS | This routine sets RTS.
// 
// @rdesc None.
//
static
VOID SerSetRTS(
    PVOID   pHead // @parm PVOID returned by HWinit.
    )
{
  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("SerSetRTS, 0x%X\r\n"),
	     pHead));

  // We don't support RTS emulation.
}

/*
 @doc OEM
 @func BOOL | SerEnableIR | This routine enables ir.
 *  Not exported to users, only to driver.
 *
 @rdesc Returns TRUE if successful, FALSEotherwise.
 */
static
BOOL SerEnableIR(
           PVOID   pHead, // @parm PVOID returned by Serinit.
           ULONG   BaudRate  // @parm PVOID returned by HWinit.
           )
{
  PSER_INFO pHWHead = (PSER_INFO)pHead;

  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("SerEnableIR, 0x%X\r\n"),
	     pHead));

  // We don't support an IR mode, so fail.
  return (FALSE);
}

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

  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("SerDisableIR, 0x%X\r\n"),
	     pHead));

  // We don't support an IR mode.  But don't fail, in case
  // someone calls this redundantly to ensure that we are
  // in wired mode, which is what we support.
  return (TRUE);
}

//
// @doc OEM
// @func VOID | SerClearBreak | This routine clears break.
// 
// @rdesc None.
// 
static
VOID SerClearBreak(
    PVOID   pHead // @parm PVOID returned by HWinit.
    )
{
  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("SerClearBreak, 0x%X\r\n"),
	     pHead));

  // We don't have a concept of break over USB serial
}

//
// @doc OEM
// @func VOID | SerSetBreak | This routine sets break.
// 
// @rdesc None.
//
static
VOID SerSetBreak(
    PVOID   pHead // @parm PVOID returned by HWinit.
    )
{
  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("SerSetBreak, 0x%X\r\n"),
	     pHead));

  // We don't have a concept of break over USB serial
}

//
// @doc OEM
// @func	BOOL | SerXmitComChar | Transmit a char immediately
// 
// @rdesc	TRUE if succesful
//
static
BOOL SerXmitComChar(
    PVOID   pHead,    // @parm PVOID returned by HWInit.
    UCHAR   ComChar   // @parm Character to transmit. 
    )
{
  PSER_INFO pHWHead = (PSER_INFO)pHead;
    
  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("+SerXmitComChar 0x%X\r\n"), pHead));

  // Get critical section, then transmit when buffer empties
  DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar wait for CritSec %x.\r\n"),
			 &(pHWHead->TransmitCritSec)));

  EnterCriticalSection(&(pHWHead->TransmitCritSec));

  DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar got CritSec %x.\r\n"),
			 &(pHWHead->TransmitCritSec)));
  try
    {
      DEBUGMSG (1,
		(TEXT("!!! SerXmitComChar 0x%X not implemented\r\n"),
		 pHead));
    }
  except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
	  EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
    // Just exit
  }
    
  LeaveCriticalSection(&(pHWHead->TransmitCritSec));

  DEBUGMSG (ZONE_WRITE,
	    (TEXT("XmitComChar released CritSec %x.\r\n"),
	     &(pHWHead->TransmitCritSec)));
    
  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("-SerXmitComChar 0x%X\r\n"), pHead));
    
  return TRUE;
}
        

//  
// @doc OEM
// @func	ULONG | SerGetStatus | This structure is called by the MDD
//   to retrieve the contents of a COMSTAT structure.
//
// @rdesc	The return is a ULONG, representing success (0) or failure (-1).
//
static
ULONG SerGetStatus(
    PVOID	pHead,	// @parm PVOID returned by HWInit.
    LPCOMSTAT	lpStat	// Pointer to LPCOMMSTAT to hold status.
    )
{
  PSER_INFO pHWHead = (PSER_INFO)pHead;
  ULONG RetVal = pHWHead->CommErrors;
    
  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("+SerGetStatus 0x%X\r\n"), pHead));

  pHWHead->CommErrors = 0; // Clear old errors each time

  // We don't emulate any of this, so always return a fixed result.
  if ( lpStat ) {
    // TODO - Make sure we return reasonable results here.
    pHWHead->Status.fCtsHold = 0;
    pHWHead->Status.fDsrHold = 0;
    pHWHead->Status.cbInQue  = 0;
    pHWHead->Status.cbOutQue = 0;
  }
  else
    RetVal = (ULONG)-1;

  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("-SerGetStatus 0x%X\r\n"), pHead));

  return RetVal;
}

//
// @doc OEM
// @func	ULONG | SerReset | Perform any operations associated
//   with a device reset
//
// @rdesc	None.
//
static
VOID SerReset(
    PVOID   pHead	// @parm PVOID returned by HWInit.
    )
{
  PSER_INFO pHWHead = (PSER_INFO)pHead;

  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("+SerReset 0x%X\r\n"), pHead));

  memset(&pHWHead->Status, 0, sizeof(COMSTAT));

  // TODO - Is there anything special we need to do here.
    
  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("-SerReset 0x%X\r\n"), pHead));
}

//
// @doc OEM
// @func	VOID | SerGetModemStatus | Retrieves modem status.
//
// @rdesc	None.
//
static
VOID SerGetModemStatus(
    PVOID   pHead,	    // @parm PVOID returned by HWInit.
    PULONG  pModemStatus    // @parm PULONG passed in by user.
    )
{
  PSER_INFO pHWHead = (PSER_INFO)pHead;
    
  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("+SerGetModemStatus 0x%X\r\n"), pHead));

  *pModemStatus = pHWHead->ModemStatus;

  DEBUGMSG (ZONE_FUNCTION | ZONE_EVENTS,
	    (TEXT("-SerGetModemStatus 0x%X (stat x%X) \r\n"),
	     pHead,
	     *pModemStatus));
  return;
}

/*
 @doc OEM
 @func	VOID | SerGetCommProperties | Retrieves Comm Properties.
 *
 @rdesc	None.
 */
static
VOID SerGetCommProperties(
                    PVOID   pHead,      // @parm PVOID returned by SerInit. 
                    LPCOMMPROP  pCommProp   // @parm Pointer to receive COMMPROP structure. 
                    )
{
  PSER_INFO pHWHead = (PSER_INFO)pHead;

  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("+SerGetCommProperties 0x%X\r\n"), pHead));

  *pCommProp = pHWHead->CommProp;
  return;
}

//
// @doc OEM
// @func	VOID | SerPurgeComm | Purge RX and/or TX
// 
// @rdesc	None.
//
static
VOID SerPurgeComm(
    PVOID   pHead,	    // @parm PVOID returned by HWInit.
    DWORD   fdwAction	    // @parm Action to take. 
    )
{
  PSER_INFO pHWHead = (PSER_INFO)pHead;
    
  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("+SerPurgeComm 0x%X\r\n"), pHead));

  EnterCriticalSection(&(pHWHead->HwRegCritSec));

  if ( (fdwAction & PURGE_TXCLEAR) || (fdwAction & PURGE_TXABORT) ) {
    // Abort any pending TX data.  The MDD takes care of aborting
    // data pended in the driver.  All I can do to stop an IN that
    // has already been queued is to Un-Arm this endpoint, causing
    // subsequent INs to get naked.  If the IN transfer has started, 
    // its not clear I can stop it in progress.
    // In addition to NAKing host, clearing ARM tells TxIntr that he
    // can use the buffer for the next write that comes down.

#if TODO
    ucECR = SA_USB_Read(pHWHead, EP1AControl);
    ucECR &= 0xFE;   // Clear the ARM bit.
    SA_USB_Write(pHWHead, EP1AControl, ucECR );
#endif
  }

  if ( (fdwAction & PURGE_RXCLEAR) || (fdwAction & PURGE_RXABORT) ) {
#if TODO
    // Abort any pending RX data.
    SA_USB_Write(pHWHead, IntStatus, 0x04 );   // Clear the EP2 interrupt
    SA_USB_Write(pHWHead, EP2AControl, 0x03);  // Reenable the endpoint
#endif
  }
    
  LeaveCriticalSection(&(pHWHead->HwRegCritSec));

  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("-SerPurgeComm 0x%X\r\n"), pHead));
  return;
}

//
// @doc OEM
// @func	BOOL | SerSetDCB | Sets new values for DCB.  This
// routine gets a DCB from the MDD.  It must then compare
// this to the current DCB, and if any fields have changed take
// appropriate action.
// 
// @rdesc	BOOL
//
static
BOOL SerSetDCB(
    PVOID   pHead,	    // @parm	PVOID returned by HWInit.
    LPDCB   lpDCB       // @parm    Pointer to DCB structure
    )
{
  PSER_INFO pHWHead = (PSER_INFO)pHead;
  BOOL bRet;
    
  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("+SerSetDCB 0x%X\r\n"), pHead));

  bRet = TRUE;

  // 
  // If the device is open, scan for changes and do whatever
  // is needed for the changed fields.  if the device isn't
  // open yet, just save the DCB for later use by the open.
  //
  // We don't do anything here due to the nature of this driver...
  //
  if( pHWHead->OpenCount ) { }
    
  if (bRet) {
    // Now that we have done the right thing, store this DCB
    pHWHead->dcb = *lpDCB;
  }

  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("-SerSetDCB 0x%X\r\n"), pHead));

  return bRet;
}

//
// @doc OEM
// @func	BOOL | SerSetCommTimeouts | Sets new values for the
// CommTimeouts structure. routine gets a DCB from the MDD.  It
// must then compare this to the current DCB, and if any fields
// have changed take appropriate action.
// 
// @rdesc	ULONG
//
static
ULONG SerSetCommTimeouts(
    PVOID   pHead,	    // @parm	PVOID returned by HWInit.
    LPCOMMTIMEOUTS   lpCommTimeouts // @parm Pointer to CommTimeout structure
    )
{
  PSER_INFO pHWHead = (PSER_INFO)pHead;
  ULONG retval = 0;
    
  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("+SerSetCommTimeout 0x%X\r\n"), pHead));

  // OK, first check for any changes and act upon them
  if( lpCommTimeouts->WriteTotalTimeoutMultiplier !=
      pHWHead->CommTimeouts.WriteTotalTimeoutMultiplier )
    {
    }
    
  // Now that we have done the right thing, store this DCB
  pHWHead->CommTimeouts = *lpCommTimeouts;

  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("-SerSetCommTimeout 0x%X\r\n"), pHead));

  return retval;
}

//
//  @doc OEM
//  @func    BOOL | SerIoctl | Device IO control routine.  
//  @parm DWORD | dwOpenData | value returned from COM_Open call
//    @parm DWORD | dwCode | io control code to be performed
//    @parm PBYTE | pBufIn | input data to the device
//    @parm DWORD | dwLenIn | number of bytes being passed in
//    @parm PBYTE | pBufOut | output data from the device
//    @parm DWORD | dwLenOut |maximum number of bytes to receive from device
//    @parm PDWORD | pdwActualOut | actual number of bytes received from device
//
//    @rdesc        Returns TRUE for success, FALSE for failure
//
//  @remark  The MDD will pass any unrecognized IOCTLs through to this function.
//
static
BOOL SerIoctl(PVOID pHead, DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,
         PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
{
  PSER_INFO pHWHead = (PSER_INFO)pHead;
  BOOL RetVal = TRUE;

  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("+SerIoctl 0x%X\r\n"), pHead));

  switch (dwCode) {
    // Currently, no defined IOCTLs
  default:
    RetVal = FALSE;

    DEBUGMSG (ZONE_FUNCTION,
	      (TEXT(" Unsupported ioctl 0x%X\r\n"), dwCode));
    break;            
  }

  DEBUGMSG (ZONE_FUNCTION,
	    (TEXT("-SerIoctl 0x%X\r\n"), pHead));

  return(RetVal);
}

const
HW_VTBL IoVTbl = {
    SerInit,
    SerPostInit,
    SerDeinit,
    SerOpen,
    SerClose,
    SerGetInterruptType,
    SerRxIntr,
    SerTxIntr,
    SerModemIntr,
    SerLineIntr,
    SerGetRxBufferSize,
    SerPowerOff,
    SerPowerOn,
    SerClearDTR,
    SerSetDTR,
    SerClearRTS,
    SerSetRTS,
    SerEnableIR,
    SerDisableIR,
    SerClearBreak,
    SerSetBreak,
    SerXmitComChar,
    SerGetStatus,
    SerReset,
    SerGetModemStatus,
    SerGetCommProperties,
    SerPurgeComm,
    SerSetDCB,
    SerSetCommTimeouts,
    SerIoctl};

extern const HW_VTBL SerCardIoVTbl;

PHWOBJ
GetSerialObject(
		DWORD DeviceArrayIndex
		)
{
  PHWOBJ pSerObj;

  // We do not have a statically allocated array of HWObjs.  Instead, we 
  // allocate a new HWObj for each instance of the driver.  The MDD will 
  // always call GetSerialObj/HWInit/HWDeinit in that order, so we can do 
  // the alloc here and do any subsequent free in HWDeInit.
  
  // Allocate space for the HWOBJ.
  pSerObj = (PHWOBJ)LocalAlloc( LPTR, sizeof(HWOBJ) );
  if ( !pSerObj )
    return (NULL);

  // Fill in the HWObj structure that we just allocated.
  pSerObj->BindFlags = THREAD_IN_PDD;      // We take care of our own IST
  pSerObj->dwIntID = SYSINTR_USB_CLIENT;   // SysIntr 
  pSerObj->pFuncTbl = (HW_VTBL *) &IoVTbl; // Return pointer to functions

  // Now return this structure to the MDD.
  return (pSerObj);
}


⌨️ 快捷键说明

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