aduadu

aduadu

0个粉丝

101

问答

0

专栏

45

资料

aduadu  发布于  2008-07-18 20:42:04
采纳率 0%
101个问答
4542

windows ce 下的串口通信代码

/*++
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.
Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.
Copyright (c) 2001-2002 SAMSUNG Electronics Corporation.  All rights reserved.

Author        [email]hmseo@sec.samsung.com[/email] (SAMSUNG Electronics)

Module Name:  

SER2440_SER.C

Abstract:  

Notes:
--*/

#define EXAMINE_BOOTARGS
#define DEBUGMODE 0

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include "S2440.h"

#define USERDBG        1

#ifdef EXAMINE_BOOTARGS
#include
#include
#include
#endif

#include

#undef ZONE_INIT
#include

static BOOL IRDA;

#define BAUD_TABLE_SIZE 23
static const
PAIRS   BaudPairs[BAUD_TABLE_SIZE] =    {
        {50,        2307},
        {75,        1538},
        {110,       1049},
        {135,       858},
        {150,       769},
        {300,       384},
        {600,       192},
        {1200,      96},
        {1800,      64},
        {2000,      58},
        {2400,      48},
        {3600,      32},
        {4800,      24},
        {7200,      16},
        {9600,      12},
        {12800,     9},
        {14400,     8},
        {19200,     6},
        {23040,     5},
        {28800,     4},
        {38400,     3},
        {57600,     2},
        {115200,    1}
};

static const LOOKUP_TBL  BaudTable = {BAUD_TABLE_SIZE, (PAIRS *) BaudPairs};

// Miscellaneous internal routines.
PUCHAR
static
Ser_InternalMapRegisterAddresses(ULONG HWAddress, ULONG Size)
{
        PUCHAR              ioPortBase;
        ULONG               inIoSpace      = 1;
        PHYSICAL_ADDRESS    ioPhysicalBase = { HWAddress, 0};

        RETAILMSG(DEBUGMODE, (TEXT("+ Ser_InternalMapRegisterAddresses : HalTranslateBusAddress\r\n")));
        if ( HalTranslateBusAddress(Isa, 0, ioPhysicalBase, &inIoSpace, &ioPhysicalBase))
        {
                DEBUGMSG(1, (TEXT("Ser_InternalMapRegisterAddresses : HalTranslateBusAddress - OK\r\n")));
                if ( !inIoSpace )
                {
                        DEBUGMSG(1, (TEXT("Ser_InternalMapRegisterAddresses : ! IO Space\r\n")));
                        if ( (ioPortBase = (PUCHAR)MmMapIoSpace(ioPhysicalBase, Size, FALSE)) == NULL )
                        {
                                // We may as well not continue
                                DEBUGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("Error mapping I/O Ports\r\n")));
                                return (NULL);
                        }
                }
                else
                {
                        DEBUGMSG(1, (TEXT("Ser_InternalMapRegisterAddresses : IO Space\r\n")));
                        ioPortBase = (PUCHAR)ioPhysicalBase.LowPart;
                }
        }
        else
        {
                DEBUGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("Error translating I/O Ports.\r\n")));
                return (NULL);
        }

        RETAILMSG(DEBUGMODE, (TEXT("- Ser_InternalMapRegisterAddresses : %d\r\n"),ioPortBase ));
        return (ioPortBase);
}

static
BOOL
SerSetIRBaudRate(
                        PSER_INFO   pHWHead,
                        ULONG baud     // @parm     UINT16 what is the baud rate
                                        )
{
        PS2440_UART_INFO   pHWHead2   = (PS2440_UART_INFO)pHWHead;

        RETAILMSG(DEBUGMODE, (TEXT("IRDA : +SerSetIRBaudRate\r\n")));   
        DEBUGMSG (ZONE_INIT|1, (TEXT("Serial set IR Baud %d\r\n"), baud));

        if ( (pHWHead2->s2440SerReg->rUCON & CS_MASK) == CS_PCLK )
        {
                RETAILMSG (1, (TEXT("USE CS_PCLK\r\n")));   
                OUTREG(pHWHead2,rUBRDIV,( (int)(S2440PCLK/16.0/baud) -1 ));
        }
        else                // if  ( (pHWHead2->s2440SerReg->rUCON & CS_MASK) == CS_UCLK )
        {
                RETAILMSG (1, (TEXT("USE CS_UCLK\r\n")));   
                OUTREG(pHWHead2,rUBRDIV,( (int)(S2440UCLK/16.0/baud) -1 ));
        }
               
        RETAILMSG(DEBUGMODE, (TEXT("IRDA : -SerSetIRBaudRate\r\n")));
        return (TRUE);
}

/*
*  NOTE : The caller should have set pHWHead->fIRMode.  It is not
* set here, since power on/off may need to temporarily disable
* the intefaces without actually overwriting the current recorded
* mode.
*/
static
void
SerSetOutputMode(
                PSER_INFO   pHWHead,
                BOOL UseIR,     // @parm     BOOL Should we use IR interface
                BOOL Use9Pin    // @parm     BOOL Should we use Wire interface
                )
{
        // If you support IR, here you need to set the interface to either IR mode
        // or normal serial. Note that it is possible for both BOOls to
        // be false (i.e. power down), but never for both to be TRUE.

        PS2440_UART_INFO   pHWHead2   = (PS2440_UART_INFO)pHWHead;

        RETAILMSG (DEBUGMODE, (TEXT("+SerSetOutputMode\r\n")));

        if(UseIR)  
                SETREG(pHWHead2,rULCON,SER2440_IRMODE_MASK);   // Infra-red mode enable.
        else
                CLEARREG(pHWHead2,rULCON,SER2440_IRMODE_MASK);   // Infra-red mode enable.
       
        RETAILMSG(DEBUGMODE, (TEXT("-SerSetOutputMode\r\n")));
}



/*++
*******************************************************************************
Routine:

    Ser_GetRegistryData

Description:

    Take the registry path provided to COM_Init and use it to find this
    requested comm port's DeviceArrayIndex, teh IOPort Base Address, and the
   Interrupt number.
   
Arguments:

    LPCTSTR regKeyPath        the registry path passed in to COM_Init.

Return Value:

    -1 if there is an error.

*******************************************************************************
--*/
BOOL
Ser_GetRegistryData(PSER_INFO pHWHead, LPCTSTR regKeyPath)
{
#define GCI_BUFFER_SIZE 256   

        LONG    regError;
        HKEY    hKey;
        DWORD   dwDataSize = GCI_BUFFER_SIZE;

        RETAILMSG(DEBUGMODE, (TEXT("Try to open %s\r\n"), regKeyPath));

        // We've been handed the name of a key in the registry that was generated
        // on the fly by device.exe.  We're going to open that key and pull from it
        // a value that is the name of this serial port's real key.  That key
        // will have the DeviceArrayIndex that we're trying to find.  
        hKey = OpenDeviceKey(regKeyPath);
        if ( hKey == NULL )
        {
                DEBUGMSG(ZONE_INIT | ZONE_ERROR,(TEXT("Failed to open device key\r\n")));
                return ( FALSE );        
        }

        // Okay, we're finally ready to try and load our registry data.
        dwDataSize = PC_REG_DEVINDEX_VAL_LEN;
        regError = RegQueryValueEx(
                                        hKey,
                                        PC_REG_DEVINDEX_VAL_NAME,
                                        NULL,
                                        NULL,
                                        (LPBYTE)(&pHWHead->dwDevIndex),
                                        &dwDataSize);

        if ( regError == ERROR_SUCCESS )
        {
                dwDataSize = PC_REG_IRQ_VAL_LEN;
                regError = RegQueryValueEx(
                                        hKey,
                                        PC_REG_IRQ_VAL_NAME,
                                        NULL,
                                        NULL,
                                        (LPBYTE)(&pHWHead->dwIRQ),
                                        &dwDataSize);
        }

        if ( regError == ERROR_SUCCESS )
        {
                dwDataSize = PC_REG_IOBASE_VAL_LEN;
                regError = RegQueryValueEx(
                                        hKey,
                                        PC_REG_IOBASE_VAL_NAME,
                                        NULL,
                                        NULL,
                                        (LPBYTE)(&pHWHead->dwIOBase),
                                        &dwDataSize);
        }

        if ( regError == ERROR_SUCCESS )
        {
                dwDataSize = PC_REG_IOLEN_VAL_LEN;
                regError = RegQueryValueEx(
                                        hKey,
                                        PC_REG_IOLEN_VAL_NAME,
                                        NULL,
                                        NULL,
                                        (LPBYTE)(&pHWHead->dwIOLen),
                                        &dwDataSize);
        }

        RegCloseKey (hKey);

        if ( regError != ERROR_SUCCESS )
        {
                RETAILMSG(DEBUGMODE, (TEXT("Failed to get serial registry values, Error 0x%X\r\n"),regError));
                return ( FALSE );
        }

        RETAILMSG (DEBUGMODE,(TEXT("SerInit - Devindex %d, IRQ %d, IOB %X, IOLen %X \r\n"),
                pHWHead->dwDevIndex, pHWHead->dwIRQ, pHWHead->dwIOBase, pHWHead->dwIOLen));

        return ( TRUE );
}



/*
@doc OEM
@func PVOID | SerInit | Initializes device identified by argument.
*  This routine sets information controlled by the user
*  such as Line control and baud rate. It can also initialize events and
*  interrupts, thereby indirectly managing initializing hardware buffers.
*  Exported only to driver, called only once per process.
*
@rdesc The return value is a PVOID to be passed back into the HW
dependent layer when HW functions are called.
*/
static
PVOID
SerInit(
        BOOL bIR,
       ULONG   Identifier, // @parm Device identifier.
       PVOID   pMddHead,   // @parm First argument to mdd callbacks.
       PHWOBJ  pHWObj      // @parm Pointer to our own HW OBJ for this device
       )
{
        PSER_INFO                        pHWHead;

#ifdef EXAMINE_BOOTARGS   
        PVOID                                *ppBootArgs     = NULL;  // Pointer to pointer to bootargs.
        PHYSICAL_ADDRESS        PhysicalAddress = {0,0};
#endif   

        // Note on defaults.  While the PC typcially considers COM1 to be at
        // 3F8, irq4 and COM2 to be 2F8, irq3, NKPC uses COM1 internally for the
        // debugger.  So, when NK tells me to start "COM1" it really means the
        // first one that's available, which is what the PC calls COM2.  Confused?
        // The end result is that COM1 on NK is what the PC considers to be COM2.
        // But wait, there's more.  On a Puzzle, the debugger is on COM2 and the
        // COM1 for NK is ACTUALLY COM1.  So PCs need 2F8 for their port base
        // and Puzzles need 3F8.

        RETAILMSG(DEBUGMODE, (TEXT("SerInit - !!! \r\n")));

        // Allocate for our main data structure and one of it's fields.
        pHWHead = (PSER_INFO)LocalAlloc( LMEM_ZEROINIT|LMEM_FIXED,        sizeof(SER_INFO) );
        if ( !pHWHead )
                return( NULL );

        if ( ! Ser_GetRegistryData(pHWHead, (LPCTSTR)Identifier) )
        {
                DEBUGMSG (ZONE_INIT|ZONE_ERROR,        (TEXT("SerInit - Unable to read registry data.  Failing Init !!! \r\n")));
                goto ALLOCFAILED;
        }

        pHWHead->pBaseAddress = Ser_InternalMapRegisterAddresses(pHWHead->dwIOBase, pHWHead->dwIOLen);

#ifdef EXAMINE_BOOTARGS        
        // Allocate a pointer to our bootargs since they may indicate that we don't have
        // access to the hardware resource.

        // First, map the bootargs pointer itself.  Note that I'm reading/writing
        // directly on the physical address.  I can do this since I know this is CEPC and
        // know the adress is not in IO space.  For OEM platforms you would want to do
        // HalTranslateBusAddress first.
        PhysicalAddress.LowPart = BOOT_ARG_PTR_LOCATION & ~0x80000000;

        if ( ppBootArgs = MmMapIoSpace(PhysicalAddress, sizeof( PVOID ), TRUE ) )
        {
                DEBUGMSG (ZONE_INIT, (TEXT("SerInit - ppBootArgs (%X) at %X\r\n"), PhysicalAddress.LowPart, ppBootArgs ));
        }
        else
        {
                DEBUGMSG (ZONE_INIT | ZONE_ERROR, (TEXT("SerInit - ppBootArgs failure at %X\r\n"), PhysicalAddress.LowPart ));
                goto ALLOCFAILED;
        }

        // Now map the bootargs structure itself
        PhysicalAddress.LowPart = (DWORD) *ppBootArgs;
        if ( pHWHead->pBootArgs = MmMapIoSpace(PhysicalAddress, sizeof(BOOT_ARGS), TRUE ) )
        {
                DEBUGMSG (ZONE_INIT, (TEXT("SerInit - pBootArgs (%X) at %X\r\n"), PhysicalAddress.LowPart, pHWHead->pBootArgs ));
        }
        else
        {
                DEBUGMSG (ZONE_INIT | ZONE_ERROR, (TEXT("SerInit - pBootArgs failure at %X\r\n"), (DWORD)PhysicalAddress.LowPart));
                goto ALLOCFAILED;
        }

        // We no longer need ppBootArgs
        MmUnmapIoSpace( ppBootArgs, sizeof(PVOID) );
#endif // EXAMINE_BOOTARGS

        pHWHead->pMddHead     = pMddHead;
        pHWHead->pHWObj = pHWObj;
        pHWHead->cOpenCount   = 0;

        RETAILMSG(DEBUGMODE,(TEXT("SerInit - IRQ %d = SYSINTR %d\r\n"),
                                        pHWHead->dwIRQ, pHWHead->pHWObj->dwIntID));

        // Set up our Comm Properties data   
        pHWHead->CommProp.wPacketLength       = 0xffff;
        pHWHead->CommProp.wPacketVersion     = 0xffff;
        pHWHead->CommProp.dwServiceMask      = SP_SERIALCOMM;
        pHWHead->CommProp.dwReserved1         = 0;
        pHWHead->CommProp.dwMaxTxQueue        = 16;
        pHWHead->CommProp.dwMaxRxQueue        = 16;
        pHWHead->CommProp.dwMaxBaud       = BAUD_115200;
        pHWHead->CommProp.dwProvSubType      = PST_RS232;
        pHWHead->CommProp.dwProvCapabilities =
                PCF_DTRDSR | PCF_RLSD | PCF_RTSCTS |
                PCF_SETXCHAR |
                PCF_INTTIMEOUTS |
                PCF_PARITY_CHECK |
                PCF_SPECIALCHARS |
                PCF_TOTALTIMEOUTS |
                PCF_XONXOFF;
        pHWHead->CommProp.dwSettableBaud      =
                BAUD_075 | BAUD_110 | BAUD_150 | BAUD_300 | BAUD_600 |
                BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 |
                BAUD_7200 | BAUD_9600 | BAUD_14400 |
                BAUD_19200 | BAUD_38400 | BAUD_56K | BAUD_128K |
                BAUD_115200 | BAUD_57600 | BAUD_USER;
        pHWHead->CommProp.dwSettableParams    =
                SP_BAUD | SP_DATABITS | SP_HANDSHAKING | SP_PARITY |
                SP_PARITY_CHECK | SP_RLSD | SP_STOPBITS;
        pHWHead->CommProp.wSettableData       =
                DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;
        pHWHead->CommProp.wSettableStopParity =
                STOPBITS_10 | STOPBITS_20 |
                PARITY_NONE | PARITY_ODD | PARITY_EVEN | PARITY_SPACE |
                PARITY_MARK;

        pHWHead->fIRMode = bIR;
        pHWHead->s2440COM.UseIrDA = bIR;

#ifdef EXAMINE_BOOTARGS
        // Don't actually init the hardware if it is being used for debugging
        if ( ((pHWHead->pBootArgs->ucComPort == 1) && (pHWHead->dwIOBase == COM1_BASE)) ||
                ((pHWHead->pBootArgs->ucComPort == 2) && (pHWHead->dwIOBase == COM2_BASE)) ||
                ((pHWHead->pBootArgs->ucComPort == 3) && (pHWHead->dwIOBase == COM3_BASE)) ||
                ((pHWHead->pBootArgs->ucComPort == 4) && (pHWHead->dwIOBase == COM4_BASE)) ) {
                DEBUGMSG (ZONE_INIT|ZONE_ERROR, (TEXT("\r\nSerInit - Skipping hardware init of debug port\r\n\r\n")));        
        } else
#endif
        {
                DEBUGMSG (ZONE_INIT|USERDBG, (TEXT("SerInit - Init 16550 data\r\n")));
                SL_Init( pHWHead, pHWHead->pBaseAddress, 1,
                                EvaluateEventFlag, pMddHead, (PLOOKUP_TBL)&BaudTable);
                DEBUGMSG (ZONE_INIT,
                        (TEXT("SerInit - Disabling UART Power\r\n")));
                SerSetOutputMode(pHWHead, FALSE, FALSE );   
        }

        return (pHWHead);

        ALLOCFAILED:
        if ( pHWHead->pBaseAddress )
                VirtualFree(pHWHead->pBaseAddress, 0, MEM_RELEASE);
        if ( ppBootArgs )
                MmUnmapIoSpace( ppBootArgs, sizeof( PVOID ) );
        if ( pHWHead->pBootArgs )
                MmUnmapIoSpace( pHWHead->pBootArgs, sizeof(BOOT_ARGS) );

        LocalFree(pHWHead);
        return (NULL);
}


PVOID
SerInitSerial(
       ULONG   Identifier, // @parm Device identifier.
       PVOID   pMddHead,   // @parm First argument to mdd callbacks.
       PHWOBJ  pHWObj      // @parm Pointer to our own HW OBJ for this device
)
{
        return (SerInit(FALSE, Identifier, pMddHead, pHWObj));
}

PVOID
SerInitIR(
       ULONG   Identifier, // @parm Device identifier.
       PVOID   pMddHead,   // @parm First argument to mdd callbacks.
       PHWOBJ  pHWObj      // @parm Pointer to our own HW OBJ for this device
)
{
        return (SerInit(TRUE, Identifier, pMddHead, pHWObj));
}



/*
@doc OEM
@func ULONG | SerClose | This routine closes the device identified by the PVOID returned by SerInit.
*  Not exported to users, only to driver.
*
@rdesc The return value is 0.
*/
static
ULONG
SerClose(
        PVOID   pHead   // @parm PVOID returned by SerInit.
        )
{
        PSER_INFO   pHWHead = (PSER_INFO)pHead;
        ULONG  uTries;

        RETAILMSG (DEBUGMODE,(TEXT("+SerClose\r\n")));
        if ( pHWHead->cOpenCount )
        {
                DEBUGMSG (ZONE_CLOSE, (TEXT("SerClose, closing device\r\n")));
                pHWHead->cOpenCount--;

                // while we are still transmitting, sleep.
                uTries = 0;
                while((pHWHead->s2440COM.s2440SerReg->rUFSTAT & SER2440_FIFOSTAT_MASK) & (uTries++ < 100))                // TxFifo not empty..
                {
                        DEBUGMSG (ZONE_CLOSE, (TEXT("SerClose, TX in progress.\r\n")));            
                        Sleep(10);
                }

                // When the device is closed, we power it down.
                DEBUGMSG (ZONE_CLOSE, (TEXT("SerClose - Powering down UART\r\n")));
                pHWHead->fIRMode  = FALSE;
                SerSetOutputMode(pHWHead, FALSE, FALSE );

                DEBUGMSG (ZONE_CLOSE, (TEXT("SerClose - Calling SL_Close\r\n")));
                SL_Close( pHWHead );
        }

        RETAILMSG(DEBUGMODE,(TEXT("-SerClose\r\n")));
        return (0);
}

/*
@doc OEM
@func PVOID | SerDeinit | Deinitializes device identified by argument.
*  This routine frees any memory allocated by SerInit.
*
*/
static
BOOL
SerDeinit(PVOID   pHead)   // @parm PVOID returned by SerInit.
{
        PSER_INFO   pHWHead = (PSER_INFO)pHead;

        RETAILMSG(DEBUGMODE,(TEXT("SerDeinit \r\n")));
        if ( !pHWHead )
                return (FALSE);

        // Make sure device is closed before doing DeInit
        if ( pHWHead->cOpenCount )
                SerClose( pHead );

        SL_Deinit( pHead );

        if ( pHWHead->pBaseAddress )
                VirtualFree(pHWHead->pBaseAddress, 0, MEM_RELEASE);

        if ( pHWHead->pBootArgs )
                MmUnmapIoSpace( pHWHead->pBootArgs, sizeof(BOOT_ARGS) );

        // Free the HWObj
        LocalFree(pHWHead->pHWObj);

        // And now free the SER_INFO structure.
        LocalFree(pHWHead);

        return (TRUE);
}

/*
@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;
        RETAILMSG(DEBUGMODE,(TEXT("+SerGetCommProperties\r\n")));
        *pCommProp = pHWHead->CommProp;
        return;
}


/*
@doc OEM
@func VOID | SerSetBaudRate |
* This routine sets the baud rate of the device.
*  Not exported to users, only to driver.
*
@rdesc None.
*/
static
BOOL
SerSetBaudRate(
              PVOID   pHead,  // @parm     PVOID returned by SerInit
              ULONG   BaudRate    // @parm     ULONG representing decimal baud rate.
              )
{
        PSER_INFO   pHWHead = (PSER_INFO)pHead;

        RETAILMSG(DEBUGMODE,(TEXT("IRDA : SerSetBaudRate \r\n")));
        // If we are running in IR mode, try to set the IR baud
        // first, since it supports a subset of the rates supported
        // by the UART.  If we fail setting the IR rate, then
        // return an error and leave the UART alone.
        if ( IRDA )
        {
                if ( ! SerSetIRBaudRate( pHWHead, BaudRate ) )
                {
                        DEBUGMSG (ZONE_ERROR,
                                (TEXT("Unsupported IR BaudRate\r\n")));
                        // We should return an error, but vtbl doesn't expect one
                        return (FALSE);
                }
        }

        // Now set buadrate on the UART
        return ( SL_SetBaudRate( pHead, BaudRate ) );   
}

/*
@doc OEM
@func BOOL | SerPowerOff |
*  Called by driver to turn off power to serial port.
*  Not exported to users, only to driver.
*
@rdesc This routine returns a status.
*/
BOOL
SerPowerOff(PVOID   pHead)       // @parm        PVOID returned by SerInit.
{
        PSER_INFO   pHWHead = (PSER_INFO)pHead;

        RETAILMSG(DEBUGMODE,(TEXT("SerPowerOff\r\n")));
        SerClose( pHWHead );
        // First, power down the UART
        SL_PowerOff( pHWHead );

        // And then disable our IR and 9 Pin interface
        SerSetOutputMode( pHWHead, FALSE, FALSE );

        return (TRUE);
}

/*
@doc OEM
@func BOOL | SerPowerOn |
*  Called by driver to turn on power to serial port.
*  Not exported to users, only to driver.
*
@rdesc This routine returns a status.
*/
BOOL
SerPowerOn(PVOID   pHead)       // @parm        PVOID returned by SerInit.
{
        PSER_INFO   pHWHead = (PSER_INFO)pHead;

        RETAILMSG(DEBUGMODE,(TEXT("SerPowerOn\r\n")));
        // First, power up the UART
        SL_PowerOn( pHWHead );

        // And then enable our IR interface (if needed)
        SerSetOutputMode( pHWHead, pHWHead->fIRMode, !pHWHead->fIRMode );
        return (TRUE);
}

/*
@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;

        RETAILMSG(DEBUGMODE,(TEXT("SerEnableIR\r\n")));
        pHWHead->fIRMode  = TRUE;
        SerSetOutputMode( pHWHead, pHWHead->fIRMode, !pHWHead->fIRMode );
        return (TRUE);
}

/*
@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;

        RETAILMSG(DEBUGMODE,(TEXT("SerDisableIR\r\n")));
        pHWHead->fIRMode  = FALSE;
        SerSetOutputMode( pHWHead, pHWHead->fIRMode, !pHWHead->fIRMode );
        return (TRUE);
}

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

        RETAILMSG(DEBUGMODE,(TEXT("SerEnableSerial\r\n")));
        pHWHead->fIRMode  = FALSE;
        SerSetOutputMode( pHWHead, pHWHead->fIRMode, !pHWHead->fIRMode );
        return (TRUE);
}

/*
@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
SerDisableSerial(PVOID   pHead)                // @parm PVOID returned by Serinit.
{
        PSER_INFO   pHWHead = (PSER_INFO)pHead;

        RETAILMSG(DEBUGMODE,(TEXT("SerDisableSerial\r\n")));

        pHWHead->fIRMode  = TRUE;
        SerSetOutputMode( pHWHead, pHWHead->fIRMode, !pHWHead->fIRMode );
        return (TRUE);
}


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

        // Disallow multiple simultaneous opens
        if ( pHWHead->cOpenCount )
                return (FALSE);

#ifdef EXAMINE_BOOTARGS
        RETAILMSG(DEBUGMODE, (TEXT("SerOpen - Bootargs ComPort %x\r\n"), pHWHead->pBootArgs->ucComPort));
        // If the port is in use as a debugger port, don't allow opens.
        if ( ((pHWHead->pBootArgs->ucComPort == 1) && (pHWHead->dwIOBase == COM1_BASE)) ||
                ((pHWHead->pBootArgs->ucComPort == 2) && (pHWHead->dwIOBase == COM2_BASE)) ||
                ((pHWHead->pBootArgs->ucComPort == 3) && (pHWHead->dwIOBase == COM3_BASE)) ||
                ((pHWHead->pBootArgs->ucComPort == 4) && (pHWHead->dwIOBase == COM4_BASE)) )
        {
                RETAILMSG (DEBUGMODE, (TEXT("SerOpen - Fail open of debug port\r\n")));        
                return (FALSE);        
        }
#endif

        pHWHead->cOpenCount++;

        if ( pHWHead->fIRMode == TRUE )
                RETAILMSG(DEBUGMODE,(TEXT("Use IrDA \r\n")));
        else
                RETAILMSG(DEBUGMODE,(TEXT("Use Serail \r\n")));
        SerSetOutputMode(pHWHead, pHWHead->fIRMode, !pHWHead->fIRMode );  

        // NOTE: - If we wanted to support 16450s, we'll could dynamically
        // identify them here.

        // Init SER2440 info
        RETAILMSG(DEBUGMODE, (TEXT("SerOpen - Calling SL_Open\r\n")));
        SL_Open( pHWHead );
        RETAILMSG(DEBUGMODE, (TEXT("SerOpen - Return TRUE\r\n")));

        return (TRUE);
}

const
HW_VTBL IoVTbl = {
        SerInitSerial,
        SL_PostInit,
        SerDeinit,
        SerOpen,
        SerClose,
        SL_GetInterruptType,
        SL_RxIntr,
        SL_TxIntrEx,
        SL_ModemIntr,
        SL_LineIntr,
        SL_GetRxBufferSize,
        SerPowerOff,
        SerPowerOn,
        SL_ClearDTR,
        SL_SetDTR,
        SL_ClearRTS,
        SL_SetRTS,
        SerEnableSerial,
        SerDisableSerial,
        SL_ClearBreak,
        SL_SetBreak,
        SL_XmitComChar,
        SL_GetStatus,
        SL_Reset,
        SL_GetModemStatus,
        SerGetCommProperties,
        SL_PurgeComm,
        SL_SetDCB,
        SL_SetCommTimeouts,
        };
extern const HW_VTBL SerCardIoVTbl;

const
HW_VTBL IrVTbl = {
        SerInitIR,
        SL_PostInit,
        SerDeinit,
        SerOpen,
        SerClose,
        SL_GetInterruptType,
        SL_RxIntr,
        SL_TxIntrEx,
        SL_ModemIntr,
        SL_LineIntr,
        SL_GetRxBufferSize,
        SerPowerOff,
        SerPowerOn,
        SL_ClearDTR,
        SL_SetDTR,
        SL_ClearRTS,
        SL_SetRTS,
        SerEnableIR,
        SerDisableIR,
        SL_ClearBreak,
        SL_SetBreak,
        SL_XmitComChar,
        SL_GetStatus,
        SL_Reset,
        SL_GetModemStatus,
        SerGetCommProperties,
        SL_PurgeComm,
        SL_SetDCB,
        SL_SetCommTimeouts,
        };
extern const HW_VTBL SerCardIrVTbl;

const HWOBJ IoObj = {
        THREAD_AT_INIT,
        SYSINTR_SERIAL,
        (PHW_VTBL) &IoVTbl
};

const HWOBJ IrObj = {
        THREAD_AT_INIT,
        SYSINTR_IR,
        (PHW_VTBL) &IrVTbl
};

typedef HWOBJ const *PCHWOBJ;

const PCHWOBJ HWObjects[] = {
        &IoObj,
        &IrObj
};

// GetSerialObj : The purpose of this function is to allow multiple PDDs to be
// linked with a single MDD creating a multiport driver.  In such a driver, the
// MDD must be able to determine the correct vtbl and associated parameters for
// each PDD.  Immediately prior to calling HWInit, the MDD calls GetSerialObject
// to get the correct function pointers and parameters.
//
PHWOBJ
GetSerialObject(DWORD DeviceArrayIndex)
{
        PHWOBJ pSerObj;

        RETAILMSG(DEBUGMODE,(TEXT("IRDA : GetSerialObject\r\n")));

        IRDA = DeviceArrayIndex;

        // Now return this structure to the MDD.
        if ( DeviceArrayIndex == 0 )
                pSerObj = (PHWOBJ)(&IoObj);
        else
                pSerObj = (PHWOBJ)(&IrObj);
        return (pSerObj);
}
我来回答
回答0个
时间排序
认可量排序
易百纳技术社区暂无数据
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区