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

📄 ser16950.c

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
              (TEXT("+SL_TxIntr 0x%X\r\n"), pHead));
}

//
// @doc OEM
// @func ULONG | SL_LineIntr | This routine is called from the MDD
//   whenever INTR_LINE is returned by SL_GetInterruptType.
// 
// @rdesc None
//
VOID
SL_LineIntr(
    PVOID pHead                // Hardware Head
    )
{
    PSER16950_INFO   pHWHead	= (PSER16950_INFO)pHead;

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

    ReadLSR( pHWHead );

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

//
// @doc OEM
// @func ULONG | SL_OtherIntr | This routine is called from the MDD
//   whenever INTR_MODEM is returned by SL_GetInterruptType.
// 
// @rdesc None
//
VOID
SL_OtherIntr(
    PVOID pHead                // Hardware Head
    )
{
    PSER16950_INFO   pHWHead	= (PSER16950_INFO)pHead;

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

    ReadMSR( pHWHead );
	
    
    try
    {
         // If we are currently flowed off by and end of packet wait 
         // for RI toggle, then we better signal the TX thread when
         // one of them changes so that TX can resume sending.
		if (pHWHead->MSR & SERIAL_MSR_TERI)
		{
			pHWHead->RIToggleCount += 1;
			if( pHWHead->RINGFlowOff )
			{
				pHWHead->RINGFlowOff = FALSE;

				pHWHead->IER |= SERIAL_IER_THR;// Enable xmit intr.
		        OUTB(pHWHead, pIER, pHWHead->IER);

	             // Then simulate a TX intr to get things moving
				pHWHead->AddTXIntr = TRUE;
			}
		}
         // If we are currently flowed off via CTS or DSR, then
         // we better signal the TX thread when one of them changes
         // so that TX can resume sending.
        if ( pHWHead->DSRFlowOff && (pHWHead->MSR & SERIAL_MSR_DSR) )
        {
            DEBUGMSG (ZONE_WRITE|ZONE_FLOW,
					  (TEXT("PutBytes, flowed on via DSR\n") ) );
            pHWHead->DSRFlowOff = FALSE;
             // DSR is set, so go ahead and resume sending
			pHWHead->IER |= SERIAL_IER_THR;// Enable xmit intr.
	        OUTB(pHWHead, pIER, pHWHead->IER);
             // Then simulate a TX intr to get things moving
			pHWHead->AddTXIntr = TRUE;
        }
        if ( pHWHead->CTSFlowOff && (pHWHead->MSR & SERIAL_MSR_CTS) )
        {
            DEBUGMSG (ZONE_WRITE|ZONE_FLOW,
					  (TEXT("PutBytes, flowed on via CTS\n") ) );
            pHWHead->CTSFlowOff = FALSE;
             // CTS is set, so go ahead and resume sending
			pHWHead->IER |= SERIAL_IER_THR;// Enable xmit intr.
	        OUTB(pHWHead, pIER, pHWHead->IER);

             // Then simulate a TX intr to get things moving
			pHWHead->AddTXIntr = TRUE;
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }

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

//  
// @doc OEM
// @func	ULONG | SL_GetStatus | 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).
//
ULONG
SL_GetStatus(
    PVOID	pHead,	// @parm PVOID returned by HWInit.
    LPCOMSTAT	lpStat	// Pointer to LPCOMMSTAT to hold status.
    )
{
    PSER16950_INFO pHWHead = (PSER16950_INFO)pHead;
    ULONG	  RetVal  = pHWHead->CommErrors;
    
    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("+SL_GetStatus 0x%X\r\n"), pHead));

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

    if ( lpStat )
	{
        try
        {
            if (pHWHead->CTSFlowOff)
                pHWHead->Status.fCtsHold = 1;
            else
                pHWHead->Status.fCtsHold = 0;
                    
            if (pHWHead->DSRFlowOff)
                pHWHead->Status.fDsrHold = 1;
            else
                pHWHead->Status.fDsrHold = 0;

            if (pHWHead->RINGFlowOff)			// added 2002-04-28 ** cea for Wendy flow control
                pHWHead->Status.fRlsdHold = 1;
            else
                pHWHead->Status.fRlsdHold = 0;

             // NOTE - I think what they really want to know here is
             // the amount of data in the MDD buffer, not the amount
             // in the UART itself.  Just set to 0 for now since the
             // MDD doesn't take care of this.
            pHWHead->Status.cbInQue  = 0;
            pHWHead->Status.cbOutQue = 0;

            memcpy(lpStat, &(pHWHead->Status), sizeof(COMSTAT));
        }
        except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
            RetVal = (ULONG)-1;
        }        
	}
    else
        RetVal = (ULONG)-1;

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

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

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

    memset(&pHWHead->Status, 0, sizeof(COMSTAT));
    try
    {
		pHWHead->IER &= ~SERIAL_IER_THR;
        OUTB(pHWHead, pIER, pHWHead->IER);// disable xmit intr.
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Do nothing
    }
    
    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("-SL_Reset 0x%X\r\n"), pHead));
}

//
// @doc OEM
// @func	VOID | SL_GetModemStatus | Retrieves modem status.
//
// @rdesc	None.
//
VOID
SL_GetModemStatus(
    PVOID   pHead,	    // @parm PVOID returned by HWInit.
    PULONG  pModemStatus    // @parm PULONG passed in by user.
    )
{
    PSER16950_INFO pHWHead = (PSER16950_INFO)pHead;
    UINT8 ubModemStatus;

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

    ReadMSR( pHWHead );
    ubModemStatus = pHWHead->MSR;
    
    if ( ubModemStatus & SERIAL_MSR_CTS )
        *pModemStatus |= MS_CTS_ON;

    if ( ubModemStatus & SERIAL_MSR_DSR )
        *pModemStatus |= MS_DSR_ON;

    if ( ubModemStatus & SERIAL_MSR_RI )
        *pModemStatus |= MS_RING_ON;

    if ( ubModemStatus & SERIAL_MSR_DCD )
        *pModemStatus |= MS_RLSD_ON;

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

//
// @doc OEM
// @func	VOID | SL_PurgeComm | Purge RX and/or TX
// 
// @rdesc	None.
//

VOID
SL_PurgeComm(
    PVOID   pHead,	    // @parm PVOID returned by HWInit.
    DWORD   fdwAction	    // @parm Action to take. 
    )
{
    PSER16950_INFO pHWHead = (PSER16950_INFO)pHead;

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

    try
    {
#ifdef TODO
        // REVIEW THIS - I don't see how this could have terminated a pending read,
        // nor how RX interrupts would ever get turned back on.  I suspect that
        // RXABORT and TXABORT would both be better implemented in the MDD.
        if ( fdwAction & PURGE_RXABORT )
			{
			pHWHead->IER &= ~SERIAL_IER_RDA;
	        OUTB(pHWHead, pIER, pHWHead->IER);// disable rx intr.
			}
#endif    
        if ( fdwAction & PURGE_TXCLEAR )
        {
            // Write the TX reset bit.  It is self clearing
            OUTB(pHWHead, pIIR_FCR, pHWHead->FCR | SERIAL_FCR_TXMT_RESET);
        }

        if ( fdwAction & PURGE_RXCLEAR )
        {
            // Write the RX reset bit.  It is self clearing
            OUTB(pHWHead, pIIR_FCR, pHWHead->FCR | SERIAL_FCR_RCVR_RESET);
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
    
    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("-SL_PurgeComm 0x%X\r\n"), pHead));
    return;
}

//
// @doc OEM
// @func	BOOL | SL_XmitComChar | Transmit a char immediately
// 
// @rdesc	TRUE if succesful
//
BOOL
SL_XmitComChar(
    PVOID   pHead,    // @parm PVOID returned by HWInit.
    UCHAR   ComChar   // @parm Character to transmit. 
    )
{
    PSER16950_INFO pHWHead = (PSER16950_INFO)pHead;
    
    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("+SL_XmitComChar 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
    {
        while( TRUE )  // We know THR will eventually empty
        {
             // Write the character if we can
            if( ReadLSR( pHWHead ) & SERIAL_LSR_THRE )
            {
                OUTB(pHWHead, pData, ComChar);
                DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar wrote x%X\r\n"),
                                         ComChar));
                break;
            }

            // If we couldn't write the data yet, then wait for a
            // TXINTR to come in and try it again.
            
            // Enable xmit intr.
			pHWHead->IER |= SERIAL_IER_THR;
            OUTB(pHWHead, pIER, pHWHead->IER);
	         // Wait until the txintr has signalled.
            DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar WaitIntr x%X\r\n"),
                                     pHWHead->FlushDone));
            WaitForSingleObject(pHWHead->FlushDone, (ULONG)1000);
        }
    }
    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("-SL_XmitComChar 0x%X\r\n"), pHead));
    
    return TRUE;
}

//
// @doc OEM
// @func	BOOL | SL_PowerOff | Perform powerdown sequence.
// 
// @rdesc	TRUE if succesful
//
VOID
SL_PowerOff(
    PVOID   pHead	    // @parm	PVOID returned by HWInit.
    )
{
#if 0
// These are useless on PC Cards!
    PSER16950_INFO pHWHead = (PSER16950_INFO)pHead;

     // Current FCR is already saved in a shadow
    
     // Current IER is not normally shadowed, save it
    // pHWHead->IER = INB(pHWHead, pIER);

     // Current LCR is not normally shadowed, save it
    //pHWHead->LCR = INB(pHWHead, pLCR);

     // Current MCR is not normally shadowed, save it
    //pHWHead->MCR = INB(pHWHead, pMCR);

     // Current Scratch is not normally shadowed, save it
    pHWHead->Scratch = INB(pHWHead, pScratch);
#endif
}

//
// @doc OEM
// @func	BOOL | SL_PowerOn | Perform poweron sequence.
// 
// @rdesc	TRUE if succesful
//
VOID
SL_PowerOn(
    PVOID   pHead	    // @parm	PVOID returned by HWInit.
    )
{
}

//
// @doc OEM
// @func	BOOL | SL_SetDCB | 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	ULONG
//
ULONG
SL_SetDCB(
    PVOID   pHead,	    // @parm	PVOID returned by HWInit.
    LPDCB   lpDCB       // @parm    Pointer to DCB structure
    )
{
    return 0;
}

//
// @doc OEM
// @func	BOOL | SL_SetCommTimeouts | 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
//
ULONG
SL_SetCommTimeouts(
    PVOID   pHead,	    // @parm	PVOID returned by HWInit.
    LPCOMMTIMEOUTS   lpCommTimeouts // @parm Pointer to CommTimeout structure
    )
{
    PSER16950_INFO pHWHead = (PSER16950_INFO)pHead;
    ULONG retval = 0;
    
    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("+SL_SetCommTimeout 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("-SL_SetCommTimeout 0x%X\r\n"), pHead));
    return retval;
}



//
//  @doc OEM
//  @func	BOOL | SL_Ioctl | 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.
//
BOOL
SL_Ioctl(PVOID pHead, DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,
              PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
{
    BOOL RetVal = TRUE;
    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_Ioctl 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("-SL_Ioctl 0x%X\r\n"), pHead));
    return RetVal;
}

⌨️ 快捷键说明

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