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

📄 ser16550.c

📁 wince下的串口驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    pHWHead->PowerDown = FALSE;
    pHWHead->bSuspendResume = FALSE;
    InstallSoftwareISR(pHWHead,pHWHead->pVirtualStaticAddr,RegStride);
    // Clear any interrupts which may be pending.  Normally only
    // happens if we were warm reset.
    ClearPendingInts( pHWHead );

    DEBUGMSG (ZONE_CLOSE,(TEXT("-SL_INIT, 0x%X\r\n"), pHWHead));
}

//
// @doc OEM
// @func void | SL_PostInit | This routine takes care of final initialization.
//
// @rdesc None.
//
BOOL
SL_PostInit(
           PVOID   pHead // @parm PVOID returned by HWinit.
           )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

    DEBUGMSG (ZONE_INIT,(TEXT("+SL_PostInit, 0x%X\r\n"), pHWHead));
    
    // Since we are just a library which might get used for 
    // builtin ports which init at boot, or by PCMCIA ports
    // which init at Open, we can't do anything too fancy.
    // Lets just make sure we cancel any pending interrupts so
    // that if we are being used with an edge triggered PIC, he
    // will see an edge after the MDD hooks the interrupt.
    ClearPendingInts( pHWHead );
    
    DEBUGMSG (ZONE_INIT,(TEXT("-SL_PostInit, 0x%X\r\n"), pHWHead));
    return(TRUE);
}

//
// @doc OEM 
// @func PVOID | SL_Deinit | De-initializes 16550 device head.  
//
VOID
SL_Deinit(
         PVOID   pHead // @parm points to device head
         )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

    DEBUGMSG (ZONE_CLOSE,(TEXT("+SL_DEINIT, 0x%X\r\n"), pHWHead));
    UninstallSoftwareISR( pHWHead);
    DeleteCriticalSection(&(pHWHead->TransmitCritSec));
    DeleteCriticalSection(&(pHWHead->RegCritSec));

    // Free the flushdone event
    if ( pHWHead->FlushDone )
        CloseHandle( pHWHead->FlushDone );

    DEBUGMSG (ZONE_CLOSE,(TEXT("-SL_DEINIT, 0x%X\r\n"), pHWHead));
}

//
// @doc OEM
// @func void | SL_ClearDtr | This routine clears DTR.
//
// @rdesc None.
//
VOID
SL_ClearDTR(
           PVOID   pHead // @parm PVOID returned by HWinit.
           )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearDTR, 0x%X\r\n"), pHead));
    EnterCriticalSection(&(pHWHead->RegCritSec));
#pragma prefast(disable: 322, "Recover gracefully from hardware failure")
    try {
        unsigned char byte;

        byte = INB((PSER16550_INFO)pHead, pMCR);
        OUTB((PSER16550_INFO)pHead, pMCR, byte & ~SERIAL_MCR_DTR);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
#pragma prefast(pop)
    LeaveCriticalSection(&(pHWHead->RegCritSec));

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

//
// @doc OEM
// @func VOID | SL_SetDTR | This routine sets DTR.
// 
// @rdesc None.
//
VOID
SL_SetDTR(
         PVOID   pHead // @parm PVOID returned by HWinit.
         )
{    
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_SetDTR, 0x%X\r\n"), pHead));
    EnterCriticalSection(&(pHWHead->RegCritSec));
#pragma prefast(disable: 322, "Recover gracefully from hardware failure")
    try {
        unsigned char byte;

        byte = INB((PSER16550_INFO)pHead, pMCR);
        OUTB((PSER16550_INFO)pHead, pMCR, byte | SERIAL_MCR_DTR);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
#pragma prefast(pop)
    LeaveCriticalSection(&(pHWHead->RegCritSec));

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

//
// @doc OEM
// @func VOID | SL_ClearRTS | This routine clears RTS.
// 
// @rdesc None.
// 
VOID
SL_ClearRTS(
           PVOID   pHead // @parm PVOID returned by HWinit.
           )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearRTS, 0x%X\r\n"), pHead));
    EnterCriticalSection(&(pHWHead->RegCritSec));
#pragma prefast(disable: 322, "Recover gracefully from hardware failure")
    try {
        unsigned char byte;

        byte = INB((PSER16550_INFO)pHead, pMCR);
        OUTB((PSER16550_INFO)pHead, pMCR, byte & ~SERIAL_MCR_RTS);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
#pragma prefast(pop)
    LeaveCriticalSection(&(pHWHead->RegCritSec));

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

//
// @doc OEM
// @func VOID | SL_SetRTS | This routine sets RTS.
// 
// @rdesc None.
//
VOID
SL_SetRTS(
         PVOID   pHead // @parm PVOID returned by HWinit.
         )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

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

    EnterCriticalSection(&(pHWHead->RegCritSec));
#pragma prefast(disable: 322, "Recover gracefully from hardware failure")
    try {
        unsigned char byte;

        byte = INB((PSER16550_INFO)pHead, pMCR);
        OUTB((PSER16550_INFO)pHead, pMCR, byte | SERIAL_MCR_RTS);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
#pragma prefast(pop)
    LeaveCriticalSection(&(pHWHead->RegCritSec));

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

//
// @doc OEM
// @func VOID | SL_ClearBreak | This routine clears break.
// 
// @rdesc None.
// 
VOID
SL_ClearBreak(
             PVOID   pHead // @parm PVOID returned by HWinit.
             )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

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

    EnterCriticalSection(&(pHWHead->RegCritSec));
#pragma prefast(disable: 322, "Recover gracefully from hardware failure")
    try {
        unsigned char byte;

        byte = INB((PSER16550_INFO)pHead, pLCR);
        OUTB((PSER16550_INFO)pHead, pLCR, byte & ~SERIAL_LCR_BREAK);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
#pragma prefast(pop)
    LeaveCriticalSection(&(pHWHead->RegCritSec));

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

//
// @doc OEM
// @func VOID | SL_SetBreak | This routine sets break.
// 
// @rdesc None.
//
VOID
SL_SetBreak(
           PVOID   pHead // @parm PVOID returned by HWinit.
           )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

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

    EnterCriticalSection(&(pHWHead->RegCritSec));
#pragma prefast(disable: 322, "Recover gracefully from hardware failure")
    try {
        unsigned char byte;

        byte = INB((PSER16550_INFO)pHead, pLCR);
        OUTB((PSER16550_INFO)pHead, pLCR, byte | SERIAL_LCR_BREAK);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
#pragma prefast(pop)
    LeaveCriticalSection(&(pHWHead->RegCritSec));

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

//
// SetBaudRate
//
// Internal function.  The only real reason for splitting this out
// is so that we can call it from PowerOn and still allow SL_SetBaud
// to do debug messages, acquire critical sections, etc.
//
BOOL
SetBaudRate(
           PVOID   pHead,
           ULONG   BaudRate
           )
{
    PSER16550_INFO    pHWHead = (PSER16550_INFO)pHead;
    USHORT        divisor;
    UCHAR        lcr;

    // **** Warning ***** Make no system calls, called in power context
    divisor = DivisorOfRate(pHead, BaudRate);

    if ( divisor ) {
       InterruptMask(pHWHead->dwSysIntr,TRUE);
       lcr = INB(pHWHead, pLCR);
       OUTB(pHWHead, pLCR, lcr | SERIAL_LCR_DLAB);
       OUTB(pHWHead, pData, divisor & 0xff); //pData is DivLatch Lo
       OUTB(pHWHead, pIER, (divisor >> 8) & 0xff); //pIER is DivLatch Hi
       OUTB(pHWHead, pLCR, lcr);
       InterruptMask(pHWHead->dwSysIntr,FALSE);
       return( TRUE );
    
    } else {
        return( FALSE );
    }

}

//
// @doc OEM
// @func BOOL | SL_SetBaudRate |
//  This routine sets the baud rate of the device.
//
// @rdesc None.
//
BOOL
SL_SetBaudRate(
              PVOID   pHead,    // @parm     PVOID returned by HWInit
              ULONG   BaudRate    // @parm     ULONG representing decimal baud rate.
              )
{
    BOOL fRet;
    PSER16550_INFO    pHWHead = (PSER16550_INFO)pHead;

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

    try {
        // Enter critical section before calling function, since
        // we can't make sys calls inside SetBaudRate
        EnterCriticalSection(&(pHWHead->RegCritSec));
        fRet = SetBaudRate(pHead, BaudRate);
        LeaveCriticalSection(&(pHWHead->RegCritSec));
    }except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
             EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        return( FALSE );
    }

    if ( fRet ) {
        pHWHead->dcb.BaudRate = BaudRate;

        DEBUGMSG (ZONE_FUNCTION,
                  (TEXT("-SL_SetbaudRate 0x%X (%d Baud)\r\n"),
                   pHead, BaudRate));
        return( TRUE );
    } else {
        DEBUGMSG (ZONE_FUNCTION | ZONE_ERROR,
                  (TEXT("-SL_SetbaudRate - Error setting %d, failing to %d\r\n"),
                   BaudRate, pHWHead->dcb.BaudRate) );
        return( FALSE );
    }
}

//
// @doc OEM
// @func BOOL | SL_SetByteSize |
//  This routine sets the WordSize of the device.
//
// @rdesc None.
//
BOOL
SL_SetByteSize(
              PVOID   pHead,        // @parm     PVOID returned by HWInit
              ULONG   ByteSize    // @parm     ULONG ByteSize field from DCB.
              )
{
    PSER16550_INFO    pHWHead = (PSER16550_INFO)pHead;
    UINT8 lcr;
    BOOL bRet;

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

    bRet = TRUE;

    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
        lcr = INB(pHWHead, pLCR);
        lcr &= ~SERIAL_DATA_MASK;
        switch ( ByteSize ) {
        case 5:
            lcr |= SERIAL_5_DATA;
            break;
        case 6:
            lcr |= SERIAL_6_DATA;
            break;
        case 7:
            lcr |= SERIAL_7_DATA;
            break;
        case 8:
            lcr |= SERIAL_8_DATA;
            break;

⌨️ 快捷键说明

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