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

📄 ser16550.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 4 页
字号:
//
VOID
SL_Close(
    PVOID   pHead // @parm PVOID returned by HWinit.
    )
{
    PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;

    if( pHWHead->OpenCount )
        pHWHead->OpenCount--;

try
    {
         // Disable all interrupts and clear MCR.

        OUTB(pHWHead, pIER, (UCHAR)0); 
        OUTB(pHWHead, pMCR, (UCHAR)0);
        pHWHead->IIR   = INB(pHWHead, pIIR_FCR);        
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just get out of here.
    }
}

//
// @doc OEM 
// @func PVOID | SL_Init | Initializes 16550 device head.  
//
VOID
SL_Init(
    PVOID   pHead, // @parm points to device head
    PUCHAR  pRegBase, // Pointer to 16550 register base
    UINT8   RegStride, // Stride amongst the 16550 registers
    EVENT_FUNC EventCallback, // This callback exists in MDD
    PVOID   pMddHead,   // This is the first parm to callback
    PLOOKUP_TBL   pBaudTable  // BaudRate Table
    )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

	// Set up pointers to 16550 registers
    pHWHead->pData    = pRegBase + (RegStride * RECEIVE_BUFFER_REGISTER);
    pHWHead->pIER     = pRegBase + (RegStride * INTERRUPT_ENABLE_REGISTER);
    pHWHead->pIIR_FCR = pRegBase + (RegStride * INTERRUPT_IDENT_REGISTER);
    pHWHead->pLCR     = pRegBase + (RegStride * LINE_CONTROL_REGISTER);
    pHWHead->pMCR     = pRegBase + (RegStride * MODEM_CONTROL_REGISTER);
    pHWHead->pLSR     = pRegBase + (RegStride * LINE_STATUS_REGISTER);
    pHWHead->pMSR     = pRegBase + (RegStride * MODEM_STATUS_REGISTER);
    pHWHead->pScratch = pRegBase + (RegStride * SCRATCH_REGISTER);

     // Store info for callback function
    pHWHead->EventCallback = EventCallback;
    pHWHead->pMddHead = pMddHead;
    
     // Now set up remaining fields
    if( pBaudTable != NULL )
        pHWHead->pBaudTable = (LOOKUP_TBL *) pBaudTable;
    else
        pHWHead->pBaudTable = (LOOKUP_TBL *) &LS_BaudTable;
    pHWHead->FlushDone	  = CreateEvent(0, FALSE, FALSE, NULL);

    pHWHead->OpenCount = 0;
    
     /* Initialize the critical sections that will guard the parts of
      * the receive buffer.
      */
    InitializeCriticalSection(&(pHWHead->TransmitCritSec));

    // For now, we don't support DCC auto-connect on CEPC.  Disable
    // interrupts and clear any pending interrupts.
    
    OUTB(pHWHead, pIER, 0); // disable TX interrupts while flowed off
    OUTB(pHWHead, pMCR, 0);
    OUTB(pHWHead, pIIR_FCR, (SERIAL_FCR_RCVR_RESET | SERIAL_FCR_TXMT_RESET) );
    ReadLSR( pHWHead );

    ReadMSR( pHWHead );
}

//
// @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;
    
    // 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.
    )
{
    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearDTR, 0x%X\r\n"), pHead));
    try
    {
        unsigned char 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
    }
    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.
    )
{    
    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_SetDTR, 0x%X\r\n"), pHead));
    try
    {
        unsigned char 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
    }
}

//
// @doc OEM
// @func VOID | SL_ClearRTS | This routine clears RTS.
// 
// @rdesc None.
// 
VOID
SL_ClearRTS(
    PVOID   pHead // @parm PVOID returned by HWinit.
    )
{
    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearRTS, 0x%X\r\n"), pHead));
    try
    {
        unsigned char 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
    }
    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.
    )
{
    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_SetRTS, 0x%X\r\n"), pHead));
    try
    {
        unsigned char 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
    }
    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.
    )
{
    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearBreak, 0x%X\r\n"), pHead));
    try
    {
        unsigned char 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
    }
    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.
    )
{
    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_SetBreak, 0x%X\r\n"), pHead));
    try
    {
        unsigned char 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
    }
    DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_SetBreak, 0x%X\r\n"), pHead));
}


//
// @doc OEM
// @func VOID | 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.
    )
{
    PSER16550_INFO	pHWHead = (PSER16550_INFO)pHead;
    USHORT		divisor;
    UCHAR		lcr;

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

    divisor = DivisorOfRate(pHead, BaudRate);
    
    pHWHead->dcb.BaudRate = BaudRate;

    if ( divisor )
    {
        try
        {
            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);
            DEBUGMSG (ZONE_FUNCTION,
                      (TEXT("-SL_SetbaudRate 0x%X (%d Baud)\r\n"),
                       pHead, BaudRate));
            return( TRUE );
        }
        except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
            DEBUGMSG (ZONE_FUNCTION | ZONE_ERROR,
                      (TEXT("-SL_SetbaudRate - Exception\r\n")) );
            return( FALSE );
        }
        
    }
    else
    {
        DEBUGMSG (ZONE_FUNCTION | ZONE_ERROR,
                  (TEXT("-SL_SetbaudRate - Bad BaudRate %d\r\n"),
                   BaudRate) );
        return( FALSE );
    }

}

//
// @doc OEM
// @func VOID | 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;
    
    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("+SL_SetByteSize 0x%X, x%X\r\n"), pHead, ByteSize));

    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;
            default:
            case 8:
                lcr |= SERIAL_8_DATA;
                break;
        }
        OUTB(pHWHead, pLCR, lcr);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Do nothing - we're in enough trouble
    }

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

    return TRUE;
}
//
// @doc OEM
// @func VOID | SL_SetParity |
//  This routine sets the parity of the device.
//
// @rdesc None.
//
BOOL
SL_SetParity(
    PVOID   pHead,	// @parm     PVOID returned by HWInit
    ULONG   Parity	// @parm     ULONG parity field from DCB.
    )
{
    PSER16550_INFO	pHWHead = (PSER16550_INFO)pHead;
    UINT8 lcr;
    
    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("+SL_SetParity 0x%X, x%X\r\n"), pHead, Parity));

    try
    {
        lcr = INB(pHWHead, pLCR);
        lcr &= ~SERIAL_PARITY_MASK;
        switch( Parity )
        {
            case ODDPARITY:
                lcr |= SERIAL_ODD_PARITY;
                break;
                
            case EVENPARITY:
                lcr |= SERIAL_EVEN_PARITY;
                break;
                
            case MARKPARITY:
                lcr |= SERIAL_MARK_PARITY;
                break;
                
            case SPACEPARITY:
                lcr |= SERIAL_SPACE_PARITY;
                break;

            case NOPARITY:
            default:
                lcr |= SERIAL_NONE_PARITY;
                break;                
        }
        OUTB(pHWHead, pLCR, lcr);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Do nothing - we're in enough trouble
    }

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

    return TRUE;
}
//
// @doc OEM
// @func VOID | SL_SetStopBits |
//  This routine sets the Stop Bits for the device.
//
// @rdesc None.
//
BOOL
SL_SetStopBits(
    PVOID   pHead,	  // @parm     PVOID returned by HWInit
    ULONG   StopBits  // @parm     ULONG StopBits field from DCB.
    )
{
    PSER16550_INFO	pHWHead = (PSER16550_INFO)pHead;
    UINT8 lcr;
    
    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("+SL_SetStopBits 0x%X, x%X\r\n"), pHead, StopBits));

    lcr = INB(pHWHead, pLCR);
    lcr &= ~SERIAL_STOP_MASK;

    try
    {
         // Note that 1.5 stop bits only works if the word size
         // is 5 bits.  Any other xmit word size will cause the
         // 1.5 stop bit setting to generate 2 stop bits.
        switch( StopBits )
        {
            case ONESTOPBIT :
                lcr |= SERIAL_1_STOP ;
                break;
            case ONE5STOPBITS :
                lcr |= SERIAL_1_5_STOP ;
                break;
            case TWOSTOPBITS :
                lcr |= SERIAL_2_STOP ;
                break;   
        }

⌨️ 快捷键说明

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