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

📄 ser16552.c

📁 2440 wince uart source code
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/* 
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.


Abstract:  

    based serial device.

Functions: UART for serial driver
*/
#include <windows.h>
#include <serhw.h>
#include <serdbg.h>
#include <s2440.h>
#include <ser16550.h>
#include "macros.h"
#include <ser16552.h>
#include "hw16550.h"      


#define CHIP_ID_16550	1  
#define CHIP_ID_16450	2               
#define QYDEBUG  		0           
#define IER_NORMAL_INTS 	SERIAL_IER_RDA   
volatile IOPreg *v_pIOPRegs1;

PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress); 

#define BAUD_SER_TABLE_SIZE 11             
static const PAIRS	SER_BaudPairs[BAUD_SER_TABLE_SIZE] =	{

   	{50,        4608},
	{1200,       192},
	{2400,        96},
	{9600,        24},
	{14400,       16},
	{19200,       12},
	{38400,        6},
	{57600,        4},
	{76800,        3},
	{115200,       2},
	{230400,       1}
};

const LOOKUP_TBL  SER_BaudTable = {BAUD_SER_TABLE_SIZE, (PAIRS *) SER_BaudPairs};


BOOL
SL_SetByteSizeq(
              PVOID   pHead,        // @parm     PVOID returned by HWInit
              ULONG   ByteSize    // @parm     ULONG ByteSize field from DCB.
              );
BOOL
SL_SetStopBitsq(
              PVOID   pHead,      // @parm     PVOID returned by HWInit
              ULONG   StopBits  // @parm     ULONG StopBits field from DCB.
              );
BOOL
SL_SetParityq(
            PVOID   pHead,    // @parm     PVOID returned by HWInit
            ULONG   Parity    // @parm     ULONG parity field from DCB.
            );

__inline
VOID
ReadMSRq(
       PSER16550_INFO  pHWHead
       );

__inline
VOID
ReadLSRq(
      // PSER16550_INFO  pHWHead
      PVOID   pHead
       );


__inline
VOID
ReadLSRq(
       PSER16550_INFO  pHWHead
  //	PVOID   pHead
       )
{
	// PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;
    ULONG LineEvents = 0;

    try {
        pHWHead->LSR = INB(pHWHead, pLSR);
       
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        pHWHead->LSR = SERIAL_LSR_THRE;
    }
	RETAILMSG(QYDEBUG ,(TEXT("SER16550 Register LSR =0x%x\r\n"),pHWHead->LSR));
    if ( pHWHead->LSR & (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE)) {//0x02 & 0x04 & 0x08
        // Note: Its not wise to do debug msgs in here since they will
        // pretty much guarantee that the FIFO gets overrun.
        if ( pHWHead->LSR & SERIAL_LSR_OE ) {
    
            pHWHead->DroppedBytes++;
            pHWHead->CommErrors |= CE_OVERRUN;//0x0002
        }

        if ( pHWHead->LSR & SERIAL_LSR_PE ) {
          
            pHWHead->CommErrors |= CE_RXPARITY;//0x0004
        }

        if ( pHWHead->LSR & SERIAL_LSR_FE ) {
      
            pHWHead->CommErrors |= CE_FRAME;//0x0008
        }

        LineEvents |= EV_ERR;//0x0080
    }

    if ( pHWHead->LSR & SERIAL_LSR_BI )//break interrupt(0x10)
    	LineEvents |= EV_BREAK;//0x0040

    // Let WaitCommEvent know about this error
    if ( LineEvents )
        pHWHead->EventCallback( pHWHead->pMddHead, LineEvents );
    
    RETAILMSG(QYDEBUG,(TEXT("-ReadLSRq(return LineEvents=%x)\r\n"),LineEvents));
}
__inline
VOID
ReadMSRq(
       PSER16550_INFO  pHWHead
       )
{
    ULONG        Events = 0;
    UCHAR       msr;
	RETAILMSG(QYDEBUG,(TEXT("+ReadMSRq()\r\n")));
    try {
        msr = INB(pHWHead, pMSR);
        RETAILMSG(QYDEBUG,(TEXT("SER16550 Register MSR=0x%x\r\n"),msr));
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        msr = 0;
    }

    // Save the MSR value in a shadow
    pHWHead->MSR = msr;

    // For changes, we use callback to evaluate the event
    if (msr & SERIAL_MSR_DCTS)//0x01
        Events |= EV_CTS;//0x08

    if ( msr & SERIAL_MSR_DDSR )//0x02
        Events |= EV_DSR;//0x10

    if ( msr & SERIAL_MSR_TERI )//0x04
        Events |= EV_RING;//0x100

    if ( msr & SERIAL_MSR_DDCD )//0x08
        Events |= EV_RLSD;//0x20

    if ( Events )
        pHWHead->EventCallback( pHWHead->pMddHead, Events );
        RETAILMSG(QYDEBUG,(TEXT("EventCallback return Events =0x%x\r\n"),Events));
    	RETAILMSG(QYDEBUG,(TEXT("-ReadMSRq()\r\n")));
}

VOID
ClearPendingIntsq(
       PVOID   pHead // @parm PVOID returned by HWinit.
       )
{
    PSER16550_INFO pHWHead = (PSER16550_INFO)pHead;
	RETAILMSG(QYDEBUG,(TEXT("+ ClearPendingIntsq() START \r\n")));

    EnterCriticalSection(&(pHWHead->RegCritSec));
   try {
        pHWHead->IIR = INB(pHWHead, pIIR_FCR);
       	
        while ( !(pHWHead->IIR & 0x01) ) {
            RETAILMSG(QYDEBUG, (TEXT("!!IIR %X\r\n"), pHWHead->IIR));
            // Reading LSR clears RLS interrupts.
            ReadLSRq( pHWHead );

            OUTB(pHWHead, pIIR_FCR, pHWHead->FCR | SERIAL_FCR_RCVR_RESET);
	
            // Reading MSR clears Modem Status interrupt
            ReadMSRq( pHWHead );

            // Simply reading IIR is sufficient to clear THRE
            pHWHead->IIR = INB(pHWHead, pIIR_FCR);
            RETAILMSG(QYDEBUG, (TEXT("Read IIR = 0X%X\r\n"), pHWHead->IIR));
        }
   		
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        DEBUGMSG (ZONE_ERROR,(TEXT("-SL_PostInit, 0x%X - ERROR\r\n"), pHWHead));
        // Just fall through & release CritSec
    }

    LeaveCriticalSection(&(pHWHead->RegCritSec));
    RETAILMSG(QYDEBUG,(TEXT("- ClearPendingIntsq()  \r\n")));
}

VOID
DumpSerialRegistersq(
                   PVOID  pHead
                   )
{
    ULONG byte;
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

RETAILMSG(QYDEBUG,(TEXT("+DumpSerialRegistersq\r\n")));
    try {
        ReadLSRq( pHWHead );
        byte = pHWHead->LSR;

        NKDbgPrintfW(TEXT("16550 lsr: \t%2.2X\t"), byte);
        if ( byte & SERIAL_LSR_DR )
            NKDbgPrintfW(TEXT("DataReady "));
        if ( byte & SERIAL_LSR_OE )
            NKDbgPrintfW(TEXT("OverRun "));
        if ( byte & SERIAL_LSR_PE )
            NKDbgPrintfW(TEXT("ParityErr "));
        if ( byte & SERIAL_LSR_FE )
            NKDbgPrintfW(TEXT("FramingErr "));
        if ( byte & SERIAL_LSR_BI )
            NKDbgPrintfW(TEXT("BreakIntpt "));
        if ( byte & SERIAL_LSR_THRE )
            NKDbgPrintfW(TEXT("THREmpty "));
        if ( byte & SERIAL_LSR_TEMT )
            NKDbgPrintfW(TEXT("TXEmpty "));
        if ( byte & SERIAL_LSR_FIFOERR )
            NKDbgPrintfW(TEXT("FIFOErr "));
        NKDbgPrintfW(TEXT("\r\n"));

        byte = INB(pHWHead, pData);
        NKDbgPrintfW(TEXT("16550 rbr/thr:\t%2.2X\r\n"), byte);

        byte = INB(pHWHead, pIER);
        NKDbgPrintfW(TEXT("16550 IER: \t%2.2X\t"), byte);
        if ( byte & SERIAL_IER_RDA )
            NKDbgPrintfW(TEXT("RXData "));
        if ( byte & SERIAL_IER_THR )
            NKDbgPrintfW(TEXT("TXData "));
        if ( byte & SERIAL_IER_RLS )
            NKDbgPrintfW(TEXT("RXErr "));
        if ( byte & SERIAL_IER_MS )
            NKDbgPrintfW(TEXT("ModemStatus "));
        NKDbgPrintfW(TEXT("\r\n"));

        byte = INB(pHWHead, pIIR_FCR);
        NKDbgPrintfW(TEXT("16550 iir: \t%2.2X\t"), byte);
        if ( byte & SERIAL_IIR_RDA )
            NKDbgPrintfW(TEXT("RXData "));
        if ( byte & SERIAL_IIR_THRE )
            NKDbgPrintfW(TEXT("TXData "));
        if ( byte & SERIAL_IIR_RLS )
            NKDbgPrintfW(TEXT("RXErr "));
        if ( (byte & SERIAL_IIR_CTI) == SERIAL_IIR_CTI )
            NKDbgPrintfW(TEXT("CTI "));
        if ( byte & SERIAL_IIR_MS )
            NKDbgPrintfW(TEXT("ModemStatus "));
        if ( byte & 0x01 )
            NKDbgPrintfW(TEXT("IntPending "));
        NKDbgPrintfW(TEXT("\r\n"));

        byte = INB(pHWHead, pLCR);
        NKDbgPrintfW(TEXT("16550 lcr: \t%2.2X\t"), byte);

        NKDbgPrintfW(TEXT("%dBPC "), ((byte & 0x03)+5) );

        if ( byte & SERIAL_LCR_DLAB )
            NKDbgPrintfW(TEXT("DLAB "));
        if ( byte & SERIAL_LCR_DLAB )
            NKDbgPrintfW(TEXT("Break "));
        NKDbgPrintfW(TEXT("\r\n"));

        byte = INB(pHWHead, pMCR);
        NKDbgPrintfW(TEXT("16550 mcr: \t%2.2X\t"), byte);
        if ( byte & SERIAL_MCR_DTR )
            NKDbgPrintfW(TEXT("DTR "));
        if ( byte & SERIAL_MCR_RTS )
            NKDbgPrintfW(TEXT("RTS "));
        if ( byte & SERIAL_MCR_OUT1 )
            NKDbgPrintfW(TEXT("OUT1 "));
        if ( byte & SERIAL_MCR_OUT2 )
            NKDbgPrintfW(TEXT("OUT2 "));
        if ( byte & SERIAL_MCR_LOOP )
            NKDbgPrintfW(TEXT("LOOP "));
        NKDbgPrintfW(TEXT("\r\n"));

        ReadMSRq( pHWHead );
        byte = pHWHead->MSR;
        NKDbgPrintfW(TEXT("16550 msr: \t%2.2X\t"), byte);
        if ( byte & SERIAL_MSR_DCTS )
            NKDbgPrintfW(TEXT("DCTS "));
        if ( byte & SERIAL_MSR_DDSR )
            NKDbgPrintfW(TEXT("DDSR "));
        if ( byte & SERIAL_MSR_TERI )
            NKDbgPrintfW(TEXT("TERI "));
        if ( byte & SERIAL_MSR_DDCD )
            NKDbgPrintfW(TEXT("DDCD"));
        if ( byte & SERIAL_MSR_CTS )
            NKDbgPrintfW(TEXT(" CTS"));
        if ( byte & SERIAL_MSR_DSR )
            NKDbgPrintfW(TEXT("DSR "));
        if ( byte & SERIAL_MSR_RI )
            NKDbgPrintfW(TEXT("RI "));
        if ( byte & SERIAL_MSR_DCD )
            NKDbgPrintfW(TEXT("DCD "));
        NKDbgPrintfW(TEXT("\r\n"));

    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Nothing much to clean up here.
    }
    RETAILMSG(QYDEBUG,(TEXT("-DumpSerialRegistersq\r\n")));
}


ULONG
LookUpValueq(
           ULONG    Key,
           PLOOKUP_TBL pTbl,
           PULONG    pErrorCode
           )
{
    ULONG   index = 0;
    *pErrorCode = 0;
	RETAILMSG(QYDEBUG,(TEXT("+LookUpValueq()\r\n")));
    while ( index < pTbl->Size ) {
        if ( Key == pTbl->Table[index].Key ){
        	RETAILMSG(QYDEBUG,(TEXT("-LookUpValueq(S) return(0x%x)\r\n"),pTbl->Table[index].AssociatedValue));
            return(pTbl->Table[index].AssociatedValue);
        	}
        ++index;
    }
    *pErrorCode = (ULONG)-1;
	RETAILMSG(QYDEBUG,(TEXT("-LookUpValueq(F)\r\n")));
    return(0);
}
//
// Helper function.  Pass in a baudrate, and the corresponding divisor
// (from the baudtable) is returned.  If no matching baudrate is found
// in baudtable, then return 0.
//

USHORT
DivisorOfRateq(
             PVOID   pHead,      // @parm PVOID returned by HWinit.
             ULONG   BaudRate    // @parm     ULONG representing decimal baud rate.    
             )
{    PSER16550_INFO    pHWHead = (PSER16550_INFO)pHead;
    ULONG   errorcode = 0;
    USHORT  divisor;    

    divisor = (USHORT)LookUpValueq(BaudRate,
                                  ((PSER16550_INFO) pHead)->pBaudTable, &errorcode);
    if ( errorcode )
        divisor = 0;
    

    return(divisor);
}

⌨️ 快捷键说明

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