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

📄 ser_card.c

📁 wince下的串口驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:

    DEBUGMSG(ZONE_INIT|ZONE_ERROR,
             (TEXT("SC_INIT: RegQueryValueEx(%s) Val = %d\r\n"),
              DEVLOAD_SOCKET_VALNAME, hCardSock));

    // When we finish with registry, be sure to close it
    RegCloseKey(ActiveKey);        

    // OK, we got the handle from the registry, return it
    *pCardSock = hCardSock;
    return (TRUE);
}

#define RESET_DELAY_VALNAME TEXT("ResetDelay")
#define NOSCRATCHPAD_VALNAME TEXT("NoScratchPad")

// For some cards we store special overrides in the registry.
// This routine reads them all in, or sets the default if the
// value is not in the registry.
VOID
GetRegistryData(ULONG Identifier, PSER_CARD_INFO pHWHead)
{
    HKEY ActiveKey;
    DWORD status, ValType, ValLen;
    DWORD ResetDelay = 0;
    DWORD NoScratchPad = 0;
    TCHAR IdStr[300]; // Should be a defined constant??

    status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPCWSTR)Identifier,
                          0,0,&ActiveKey);
    if ( status ) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,
                 (TEXT("SC_INIT - RegOpenKeyEx(%s) returned %d!!!\r\n"),
                  (LPCWSTR)Identifier,status));
        goto GRD_Exit;
    }
    // Open the Key of the currently active device
    ValLen = sizeof(IdStr);
    status = RegQueryValueEx(ActiveKey,DEVLOAD_DEVKEY_VALNAME,
                             NULL,&ValType,(PUCHAR)IdStr,&ValLen);
    if ( status != ERROR_SUCCESS ) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,
                 (TEXT("SC_INIT: RegQueryValueEx(%s) returned %d\r\n"),
                  DEVLOAD_DEVKEY_VALNAME, status));
        RegCloseKey(ActiveKey);
        goto GRD_Exit;
    }
    RegCloseKey(ActiveKey);
    IdStr[300-1]=0;// Make sure it proper terminated.
    // Now, see if we have info for this device in registry
    status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,IdStr,0,0,&ActiveKey);
    if ( status ) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,
                 (TEXT("SC_INIT - RegOpenKeyEx(%s) returned %d!!!\r\n"),
                  IdStr,status));
    } else {
        // Read parameter from registry that specifies an interval to sleep
        // upon a card reset.  This is for some PCMCIA cards (AT&T, USR)
        // which will not function correctly otherwise.  If registry entry
        // is not present, return 0 (no delay).
        ValLen = sizeof(ResetDelay);
        status = RegQueryValueEx( ActiveKey,RESET_DELAY_VALNAME,
                                  NULL,&ValType,(PUCHAR)&ResetDelay,&ValLen);
        if ( status != ERROR_SUCCESS ) {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR,
                     (TEXT("SC_INIT: RegQueryValueExs(%s) returned %d\r\n"),
                      RESET_DELAY_VALNAME,status));
            ResetDelay = 300;
        }

        // Get scratch pad register option.  This is required
        // because some modems don't actually have a scratch
        // pad register even though they appear to be a 16550
        // in every other respect.
        ValLen = sizeof(NoScratchPad);
        status = RegQueryValueEx( ActiveKey,NOSCRATCHPAD_VALNAME,
                                  NULL,&ValType,(PUCHAR)&NoScratchPad,&ValLen);
        if ( status != ERROR_SUCCESS ) {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR,
                     (TEXT("SC_INIT: RegQueryValueExs(%s) returned %d\r\n"),
                      NOSCRATCHPAD_VALNAME,status));
        }
        RegCloseKey(ActiveKey);
    }

    GRD_Exit:
    if ( NoScratchPad )
        pHWHead->NoScratchPad = TRUE;
    pHWHead->ResetDelay = ResetDelay;

    DEBUGMSG(ZONE_INIT,(TEXT("SC_INIT: ResetDelay == %d ms, NoScratchPad = 0x%X\n\r"),
                        ResetDelay, NoScratchPad));
    return;
}

BOOL
InitPCMCIACard( PSER_CARD_INFO pHWHead,
                PVOID   pMddHead )
{

    CARD_CONFIG_INFO ConfigInfo;
    PCARD_CONFIG_INFO pConfigInfo = &ConfigInfo;

    UCHAR ConfigNum;
    UINT32 IOAddress;
    UINT32 IOLen;
    UINT32 Vcc;

    CARD_REGISTER_PARMS Parms;
    CARD_WINDOW_PARMS WinParms;     // For CardRequestWindow
    STATUS status;

    DEBUGMSG (ZONE_INIT, (TEXT("SerCard: Attempting to register\r\n")));

    Parms.fEventMask = 0xffff;
    Parms.uClientData = (UINT32)pHWHead;

    //
    // Register as an IO client.
    //
    Parms.fAttributes = CLIENT_ATTR_IO_DRIVER | CLIENT_ATTR_NOTIFY_SHARED |
                        CLIENT_ATTR_NOTIFY_EXCLUSIVE;
    pHWHead->hCardClient = CallCardServices(CardRegisterClient) (CallBackFn, &Parms);
    DEBUGMSG (ZONE_INIT, ( TEXT("head @ 1 = 0x%X\r\n"), pHWHead));
    if ( pHWHead->hCardClient == 0 ) {
        DEBUGMSG (ZONE_INIT, (
                             TEXT("SerCard: RegisterClient - failed (%d)\r\n"),
                             GetLastError()));
        return (FALSE);
    }

    // Request the I/O window before we reset, so the pcmcia driver doesn't
    // power down the socket after CE_REGISTER_COMPLETE when it sees no clients
    // using the card.
    WinParms.fAttributes = WIN_ATTR_IO_SPACE;
    WinParms.uWindowSize = 16;
    WinParms.fAccessSpeed = WIN_SPEED_USE_WAIT;
    WinParms.hSocket = pHWHead->hCardSock;
    pHWHead->hCardWindow = CallCardServices(CardRequestWindow) (pHWHead->hCardClient, &WinParms);
    if ( pHWHead->hCardWindow == NULL ) {
        DEBUGMSG (ZONE_INIT | ZONE_ERROR,
                  (TEXT("SerCard : CardRequestWindow failed %d\n"), 
                   GetLastError()));
        CallCardServices(CardDeregisterClient) (pHWHead->hCardClient);
        return (FALSE);
    }

    CallCardServices(CardResetFunction) (pHWHead->hCardClient, pHWHead->hCardSock);

#ifdef FORCE_MODEM
    ConfigNum = 32;
    IOAddress = 0x3f8;
    IOLen = 7;
    pHWHead->pCardIOWin = CallCardServices(CardMapWindow) ( pHWHead->hCardWindow, IOAddress, IOLen, &(pHWHead->IO_Granularity) );

    DEBUGMSG (ZONE_INIT,
              (TEXT("SerCard : Using Configuration %d (IOAddr 0x%X, len %d)\n"), 
               ConfigNum, IOAddress, IOLen ));

    // And then use CardRequestConfig to power up
    ConfigInfo.hSocket = pHWHead->hCardSock;
    ConfigInfo.fAttributes = CFG_ATTR_VALID_CLIENT | CFG_ATTR_IRQ_STEERING;
    ConfigInfo.uVcc = 50;
    ConfigInfo.uVpp1 = 0;
    ConfigInfo.uVpp2 = 0;
    ConfigInfo.fInterfaceType = CFG_IFACE_MEMORY_IO;
    ConfigInfo.fRegisters = CFG_REGISTER_EXREG | CFG_REGISTER_STATUS | CFG_REGISTER_CONFIG;
    ConfigInfo.uStatusReg = FCR_FCSR_REQUIRED_BITS | FCR_FCSR_AUDIO;
    ConfigInfo.uPinReg = 0;
    ConfigInfo.uCopyReg = 0;
    ConfigInfo.uConfigReg = 0x20;
    ConfigInfo.uExtendedStatus = 0;
    ConfigInfo.fExtRegisters = CFG_EXREGISTER_IOBASE0 | CFG_EXREGISTER_IOBASE1;
    ConfigInfo.IOBase[0] = (IOAddress & 0xff);
    ConfigInfo.IOBase[1] = ((IOAddress >> 8) & 0xff);

#else

    if ( FindComConfig(pHWHead->hCardSock, &ConfigNum, &IOAddress, &IOLen, &Vcc,
        pHWHead->hCardWindow, &pHWHead->pCardIOWin, &pHWHead->IO_Granularity) == FALSE ) {
        DEBUGMSG (ZONE_INIT | ZONE_ERROR,
                  (TEXT("SerCard : No valid PC card configuration found\n")));
        CallCardServices(CardDeregisterClient) (pHWHead->hCardClient);
        return (FALSE);
    }

    DEBUGMSG (ZONE_INIT,
              (TEXT("SerCard : Using Configuration %d (IOAddr 0x%X, len %d)\n"), 
               ConfigNum, IOAddress, IOLen ));

    // And then use CardRequestConfig to power up
    ConfigInfo.hSocket = pHWHead->hCardSock;
    ConfigInfo.fAttributes = CFG_ATTR_VALID_CLIENT | CFG_ATTR_IRQ_STEERING;
    ConfigInfo.uVcc = Vcc;
    ConfigInfo.uVpp1 = 0;
    ConfigInfo.uVpp2 = 0;
    ConfigInfo.fInterfaceType = CFG_IFACE_MEMORY_IO;
    ConfigInfo.fRegisters = CFG_REGISTER_EXREG | CFG_REGISTER_STATUS | CFG_REGISTER_CONFIG;
    ConfigInfo.uStatusReg = FCR_FCSR_REQUIRED_BITS | FCR_FCSR_AUDIO;
    ConfigInfo.uPinReg = 0;
    ConfigInfo.uCopyReg = 0;
    ConfigInfo.uConfigReg = ConfigNum;
    ConfigInfo.uExtendedStatus = 0;
    ConfigInfo.fExtRegisters = CFG_EXREGISTER_IOBASE0 | CFG_EXREGISTER_IOBASE1;
    ConfigInfo.IOBase[0] = (IOAddress & 0xff);
    ConfigInfo.IOBase[1] = ((IOAddress >> 8) & 0xff);
#endif

    DEBUGMSG (ZONE_INIT, ( TEXT("head @ 2 = 0x%X\r\n"), pHWHead));

    DEBUGMSG (ZONE_INIT,
              (TEXT("SerCard : Mapping Window 0x%X at 0x%X, len %d, Granularity %d\n"), 
               pHWHead->hCardWindow, IOAddress, IOLen, pHWHead->IO_Granularity ));

    // Now we know all the attributes, lets map the IO space
    if ( pHWHead->pCardIOWin == NULL ) {
        DEBUGMSG (ZONE_INIT | ZONE_ERROR,
                  (TEXT("SerCard : CardMapWindow failed %d\n"), 
                   GetLastError()));
        CallCardServices(CardDeregisterClient) (pHWHead->hCardClient);
        return (FALSE);
    } else {
        DEBUGMSG (ZONE_INIT,
                  (TEXT("SerCard : CardMapWindow pCardIOWin = 0x%X\n"), 
                   pHWHead->pCardIOWin));
    }

    status = CallCardServices(CardRequestConfiguration) (pHWHead->hCardClient, pConfigInfo);
    if ( status ) {
        DEBUGMSG (ZONE_INIT | ZONE_ERROR,
                  (TEXT("SerCard : CardRequestConfiguration returned %d\n"), 
                   status) );
        CallCardServices(CardDeregisterClient) (pHWHead->hCardClient);
        return (FALSE);
    } else
        DEBUGMSG (ZONE_INIT,
                  (TEXT("SerCard : CardRequestConfiguration completed \n")));

    return (TRUE);
}


//
// PVOID | SC_SetIRBaudRate | Sets Buad rate for IR interface
//
void
SC_SetIRMode(
            PSER_CARD_INFO   pHWHead,
            BOOL UseIR      // BOOL Should we use IR interface
            )
{
    // We don't support any IR cards. 
}

//
// PVOID | SC_SetIRBaudRate | Sets Buad rate for IR interface
//
BOOL
SC_SetIRBaudRate(
                PSER_CARD_INFO   pHWHead,
                UINT16 baud     // UINT16 what is the baud rate
                )
{
    // We don't support any IR cards.      
    return (TRUE);
}

//
// @doc OEM 
// @func PVOID | SC_Init | Initializes device identified by argument.
//   This routine allocates any memory required by the driver, and
//   initializes a few of the fields.  For PCMCIA cards, that is all
//   we can do this early.  Nearly everything else is done at open
//   time in order to ensure that we do not power the PCMCIA card
//   up nay sooner than required.
// 
// @rdesc The return value is a PVOID to be passed back into the other
// SC_??? entrypoints as a device handle.
//
PVOID
SC_Init(
       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_CARD_INFO   pHWHead;
    CARD_SOCKET_HANDLE hCardSock;

    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SC_INIT\r\n") ));
    DEBUGMSG (ZONE_INIT, (TEXT("Initializing modem\r\n") ));

    // First make sure this card is valid
    if ( !GetCardHandle( Identifier, &hCardSock ) )
        return (UINT32)NULL;

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

    // OK, Now make sure PCMCIA.DLL is available
    if ( ! InitCardServices() ) {
        LocalFree(pHWHead);
        return (UINT32)NULL;
    }

    pHWHead->pMddHead     = pMddHead;

    pHWHead->pHWObj = pHWObj;

    pHWHead->hCardSock = hCardSock;  // GetCardHandle read this from registry

    pHWHead->cOpenCount   = 0;

	pHWHead->fPowerCycle  = FALSE;

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

    // Read reset delay and other parameters from registry
    GetRegistryData( Identifier, pHWHead );

    DEBUGMSG (ZONE_FUNCTION, (TEXT("-SC_INIT\r\n") ));
    return (pHWHead);
}

//
// @doc OEM

⌨️ 快捷键说明

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