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

📄 mdd.c

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		// can't save this off yet as the pdd data block has not been allocated yet...
	    }
    datasize = sizeof(DWORD);
    if ( RegQueryValueEx(hKey, L"TxFifoTrigger", NULL, &kvaluetype,
                         (LPBYTE)&dwTxFifoTrigger, &datasize) == ERROR_SUCCESS ) 
		{
        DEBUGMSG (ZONE_INIT,
                  (TEXT("Got TxFifoTrigger value %x\r\n"), dwTxFifoTrigger));
		// can't save this off yet as the pdd data block has not been allocated yet...
	    }
    datasize = sizeof(DWORD);
    if ( RegQueryValueEx(hKey, L"BaudClock", NULL, &kvaluetype,
                         (LPBYTE)&dwBaudClock, &datasize) == ERROR_SUCCESS ) 
		{
        DEBUGMSG (ZONE_INIT,
                  (TEXT("Got BaudClock value %x\r\n"), dwBaudClock));
		// can't save this off yet as the pdd data block has not been allocated yet...
	    }

    /* Close the device key
     */
    RegCloseKey (hKey);

    DEBUGMSG (ZONE_INIT,
              (TEXT("DevIndex %X\r\n"), DevIndex));
    pHWObj  = pDL->DeviceArray[DevIndex];

    DEBUGMSG (ZONE_INIT, (TEXT("About to call HWInit(%s,0x%X)\r\n"),
                          Identifier, pSerialHead));
    pHWHead = pHWObj->pFuncTbl->HWInit(Identifier, pSerialHead);

    /* Check that HWInit did stuff ok.  From here on out, call Deinit function
     * when things fail.
     */
    if ( !pHWHead ) {
        DEBUGMSG (ZONE_INIT | ZONE_ERROR,
                  (TEXT("Hardware doesn't init correctly, COM_Init failed\r\n")));
        COM_Deinit(pSerialHead);
        return (NULL);
    }
    DEBUGMSG (ZONE_INIT,
              (TEXT("Back from hardware init\r\n")));

    // Hook them up and get hw buffer size.
    pSerialHead->pHWHead = pHWHead;
    pSerialHead->pHWObj = pHWObj;

	// Save the Registry entries off now...
	if (dwSleepDisable != -1)
		((PSER16950_INFO)pHWHead)->bSleepDisable = (BOOL)dwSleepDisable;
	if (dwRxFifoTrigger != -1)
		((PSER16950_INFO)pHWHead)->RxFifoTrigger = (BYTE)dwRxFifoTrigger;
	if (dwTxFifoTrigger != -1)
		((PSER16950_INFO)pHWHead)->TxFifoTrigger = (BYTE)dwTxFifoTrigger;
	if (dwBaudClock != -1)
		((PSER16950_INFO)pHWHead)->BaudClock = (BYTE)dwBaudClock;

    // Allocate at least twice the hardware buffer size so we have headroom
    HWBufferSize        = 2 * pHWObj->pFuncTbl->HWGetRxBufferSize(pHWHead);

    // Init rx buffer and buffer length here.
    pSerialHead->RxBufferInfo.Length =
    HWBufferSize > RX_BUFFER_SIZE ? HWBufferSize:RX_BUFFER_SIZE;

    pSerialHead->RxBufferInfo.RxCharBuffer =
    LocalAlloc(LPTR, pSerialHead->RxBufferInfo.Length);

    if ( !pSerialHead->RxBufferInfo.RxCharBuffer ) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,
                 (TEXT("Error allocating receive buffer, COM_Init failed\r\n")));
        COM_Deinit(pSerialHead);
        return (NULL);
    }

    DEBUGMSG (ZONE_INIT, (TEXT("RxHead init'ed\r\n")));

    RxResetFifo(pSerialHead);
    InitializeCriticalSection(&(pSerialHead->RxBufferInfo.CS));
    DEBUGMSG (ZONE_INIT, (TEXT("RxBuffer init'ed of size %d with start at %x\r\n"),
							pSerialHead->RxBufferInfo.Length, 
                          pSerialHead->RxBufferInfo.RxCharBuffer));

#ifdef FULL_MDD
    if ( pHWObj->BindFlags & THREAD_AT_INIT ) {
        // Hook the interrupt and start the associated thread.
        if ( ! StartDispatchThread( pSerialHead ) ) {
            // Failed on InterruptInitialize or CreateThread.  Bail.
            COM_Deinit(pSerialHead);
            return (NULL);        
        }

    }
#endif
    DEBUGMSG (ZONE_INIT | ZONE_FUNCTION, (TEXT("-COM_Init\r\n")));
    return (pSerialHead);
}
/*
 *  @doc INTERNAL
 *	@func		VOID | ApplyDCB | Apply the current DCB.
 *
 *	This function will apply the current DCB settings to the device.
 *	It will also call to the PDD to set the PDD values.
 */
void
ApplyDCB (PHW_INDEP_INFO pSerialHead, BOOL fOpen)
{
    PHWOBJ          pHWObj      = pSerialHead->pHWObj;

    pHWObj->pFuncTbl->HWSetDCB(pSerialHead->pHWHead, &(pSerialHead->DCB));

    if ( !fOpen ) {
        return;
    }

    if ( pSerialHead->DCB.fDtrControl == DTR_CONTROL_DISABLE ) {
        pHWObj->pFuncTbl->HWClearDTR(pSerialHead->pHWHead);
    } else if ( pSerialHead->DCB.fDtrControl == DTR_CONTROL_ENABLE ) {
        pHWObj->pFuncTbl->HWSetDTR(pSerialHead->pHWHead);
    }

    if ( pSerialHead->DCB.fRtsControl == RTS_CONTROL_DISABLE ) {
        pHWObj->pFuncTbl->HWClearRTS(pSerialHead->pHWHead);
    } else if ( pSerialHead->DCB.fRtsControl == RTS_CONTROL_ENABLE ) {
        pHWObj->pFuncTbl->HWSetRTS(pSerialHead->pHWHead);
    }

    if ( pSerialHead->DCB.fDtrControl == DTR_CONTROL_HANDSHAKE ) {
        if ( (!pSerialHead->DtrFlow) && 
             (4*RxBytesAvail(pSerialHead) > (3*RxLength(pSerialHead))) ) {
            DEBUGMSG (ZONE_READ|ZONE_FLOW,
                      (TEXT("IOCTL:DTR_CONTROL_HANDSHAKE Clearing DTR\r\n")));
            pSerialHead->DtrFlow = 1;
            pHWObj->pFuncTbl->HWClearDTR(pSerialHead->pHWHead);
        } else {
            DEBUGMSG (ZONE_READ|ZONE_FLOW,
                      (TEXT("IOCTL:DTR_CONTROL_HANDSHAKE Setting DTR\r\n")));
            pSerialHead->DtrFlow = 0;
            pHWObj->pFuncTbl->HWSetDTR(pSerialHead->pHWHead);
        }
    }
    if ( pSerialHead->DCB.fRtsControl == RTS_CONTROL_HANDSHAKE ) {
        if ( (pSerialHead->RtsFlow) &&
             (4*RxBytesAvail(pSerialHead) > (3*RxLength(pSerialHead))) ) {
            DEBUGMSG (ZONE_READ|ZONE_FLOW,
                      (TEXT("IOCTL:RTS_CONTROL_HANDSHAKE Clearing RTS\r\n")));
            pSerialHead->RtsFlow = 1;
            pHWObj->pFuncTbl->HWClearRTS(pSerialHead->pHWHead);
        } else {
            DEBUGMSG (ZONE_READ|ZONE_FLOW,
                      (TEXT("IOCTL:RTS_CONTROL_HANDSHAKE Setting RTS\r\n")));
            pSerialHead->RtsFlow = 0;
            pHWObj->pFuncTbl->HWSetRTS(pSerialHead->pHWHead);
        }
    }

    if ( pSerialHead->DCB.fOutX || pSerialHead->DCB.fInX ) {
        pSerialHead->XFlow = 1;
    } else {
        pSerialHead->XFlow = 0;
    }
    return;
}

/*
 @doc EXTERNAL
 @func		HANDLE | COM_Open | Serial port driver initialization.
 *	Description: This routine must be called by the user to open the
 *	serial device. The HANDLE returned must be used by the application in
 *	all subsequent calls to the serial driver. This routine starts the thread
 *	which handles the serial events.
 *	Exported to users.
 *
 @rdesc This routine returns a HANDLE representing the device.
 */
HANDLE
COM_Open(
        HANDLE  pHead,          // @parm Handle returned by COM_Init.
        DWORD   AccessCode,     // @parm access code.
        DWORD   ShareMode       // @parm share mode - Not used in this driver.
        )
{
    PHW_INDEP_INFO  pSerialHead = (PHW_INDEP_INFO)pHead;
    PHW_OPEN_INFO   pOpenHead;
    PHWOBJ          pHWObj      = pSerialHead->pHWObj;

    DEBUGMSG (ZONE_OPEN|ZONE_FUNCTION, (TEXT("+COM_Open handle x%X, access x%X, share x%X\r\n"),
                                        pHead, AccessCode, ShareMode));

    // Return NULL if SerialInit failed.
    if ( !pSerialHead ) {
        DEBUGMSG (ZONE_OPEN|ZONE_ERROR,
                  (TEXT("Open attempted on uninited device!\r\n")));
        SetLastError(ERROR_INVALID_HANDLE);        
        return (NULL);
    }

    // Return NULL if opening with access & someone else already has
    if ( (AccessCode & (GENERIC_READ | GENERIC_WRITE)) &&
         pSerialHead->pAccessOwner ) {
        DEBUGMSG (ZONE_OPEN|ZONE_ERROR,
                  (TEXT("Open requested access %x, handle x%X already has x%X!\r\n"),
                   AccessCode, pSerialHead->pAccessOwner,
                   pSerialHead->pAccessOwner->AccessCode));
        SetLastError(ERROR_INVALID_ACCESS);        
        return (NULL);
    }

    // OK, lets allocate an open structure
    pOpenHead    =  (PHW_OPEN_INFO)LocalAlloc(LPTR, sizeof(HW_OPEN_INFO));
    if ( !pOpenHead ) {
        DEBUGMSG(ZONE_INIT | ZONE_ERROR,
                 (TEXT("Error allocating memory for pOpenHead, COM_Open failed\r\n")));
        return (NULL);
    }

    // Init the structure 
    pOpenHead->pSerialHead = pSerialHead;  // pointer back to our parent
    pOpenHead->StructUsers = 0;
    pOpenHead->AccessCode = AccessCode;
    pOpenHead->ShareMode = ShareMode;
    InitializeCriticalSection(&(pOpenHead->CommEvents.EventCritSec));
    pOpenHead->CommEvents.hCommEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    pOpenHead->CommEvents.fEventMask = 0;
    pOpenHead->CommEvents.fEventData = 0;

    // if we have access permissions, note it in pSerialhead
    if ( AccessCode & (GENERIC_READ | GENERIC_WRITE) ) {
        DEBUGMSG(ZONE_INIT|ZONE_CLOSE,
                 (TEXT("COM_Open: Access permission handle granted x%X\r\n"),
                  pOpenHead));
        pSerialHead->pAccessOwner = pOpenHead;
    }

    // add this open entry to list of open entries.
    EnterCriticalSection(&(pSerialHead->OpenListCS));
    InsertHeadList(&pSerialHead->OpenList,
                   &pOpenHead->llist);
    LeaveCriticalSection(&(pSerialHead->OpenListCS));

    // If port not yet opened, we need to do some init
    if ( ! pSerialHead->OpenCnt ) {
        DEBUGMSG(ZONE_INIT|ZONE_OPEN,
                 (TEXT("COM_Open: First open : Do Init x%X\r\n"),
                  pOpenHead));

#ifdef FULL_MDD            
        if ( pSerialHead->pHWObj->BindFlags & THREAD_AT_OPEN ) {
            DEBUGMSG(ZONE_INIT|ZONE_OPEN,
                     (TEXT("COM_Open: Starting DispatchThread x%X\r\n"),
                      pOpenHead));
            // Hook the interrupt and start the associated thread.
            if ( ! StartDispatchThread( pSerialHead ) ) {
                // Failed on InterruptInitialize or CreateThread.  Bail.
                DEBUGMSG(ZONE_INIT|ZONE_OPEN,
                         (TEXT("COM_Open: Failed StartDispatchThread x%X\r\n"),
                          pOpenHead));
                goto OpenFail;
            }
        }
#endif
        pSerialHead->RxBytes = 0;
        pSerialHead->TxBytes = 0;
        pSerialHead->TxBytesPending = 0;
        pSerialHead->DroppedBytesMDD = 0;
        pSerialHead->DroppedBytesPDD = 0;

        pSerialHead->DCB.DCBlength  = sizeof(DCB);
        pSerialHead->DCB.BaudRate   = 9600;
        pSerialHead->DCB.fBinary    = TRUE;
        pSerialHead->DCB.fParity    = FALSE;

        pSerialHead->DCB.fOutxCtsFlow = FALSE;
        pSerialHead->DCB.fOutxDsrFlow = FALSE;
        pSerialHead->DCB.fDtrControl = DTR_CONTROL_ENABLE;
        pSerialHead->DCB.fDsrSensitivity = FALSE;
        pSerialHead->DCB.fTXContinueOnXoff = FALSE;
        pSerialHead->DCB.fOutX      = FALSE;
        pSerialHead->DCB.fInX       = FALSE;
        pSerialHead->DCB.fErrorChar = FALSE; //NOTE: ignored
        pSerialHead->DCB.fNull      = FALSE; //NOTE: ignored
        pSerialHead->DCB.fRtsControl = RTS_CONTROL_ENABLE;
        pSerialHead->DCB.fAbortOnError = FALSE; //NOTE: ignored

        pSerialHead->DCB.XonLim     = 512;
        pSerialHead->DCB.XoffLim    = 128;

        pSerialHead->DCB.ByteSize   = 8;
        pSerialHead->DCB.Parity     = NOPARITY;
        pSerialHead->DCB.StopBits   = ONESTOPBIT;

        pSerialHead->DCB.XonChar    = X_ON_CHAR;
        pSerialHead->DCB.XoffChar   = X_OFF_CHAR;
        pSerialHead->DCB.ErrorChar  = ERROR_CHAR;
        pSerialHead->DCB.EofChar    = E_OF_CHAR;
        pSerialHead->DCB.EvtChar    = EVENT_CHAR;

        pSerialHead->StopXmit = 0;
        pSerialHead->SentXoff = 0;
        pSerialHead->DtrFlow = 0;
        pSerialHead->RtsFlow = 0;

        ApplyDCB (pSerialHead, FALSE);

        pHWObj->pFuncTbl->HWSetCommTimeouts(pSerialHead->pHWHead,
                                            &(pSerialHead->CommTimeouts));

        if ( !pHWObj->pFuncTbl->HWOpen(pSerialHead->pHWHead) ) {
            DEBUGMSG (ZONE_OPEN|ZONE_ERROR, (TEXT("HW Open failed.\r\n")));
            goto OpenFail;
        }

        pHWObj->pFuncTbl->HWPurgeComm(pSerialHead->pHWHead, PURGE_RXCLEAR);
        memset(pSerialHead->RxBufferInfo.RxCharBuffer, 0, pSerialHead->RxBufferInfo.Length);

#ifdef FULL_MDD            
        if ( pHWObj->BindFlags & THREAD_IN_MDD ) {
            SetThreadPriority(pSerialHead->pDispatchThread,
                              THREAD_PRIORITY_TIME_CRITICAL);
        }
#endif

        RxResetFifo (pSerialHead);
    }

    ++(pSerialHead->OpenCnt);

    DEBUGMSG (ZONE_OPEN|ZONE_FUNCTION, (TEXT("-COM_Open handle x%X, x%X, Ref x%X\r\n"),
                                        pOpenHead, pOpenHead->pSerialHead, pSerialHead->OpenCnt));
    return (pOpenHead);

OpenFail :
    DEBUGMSG (ZONE_OPEN|ZONE_FUNCTION, (TEXT("-COM_Open handle x%X, x%X, Ref x%X\r\n"),
                                        pOpenHead, pOpenHead->pSerialHead, pSerialHead->OpenCnt));

    SetLastError(ERROR_OPEN_FAILED);

    // If this was the handle with access permission, remove pointer
    if ( pOpenHead == pSerialHead->pAccessOwner )
        pSerialHead->pAccessOwner = NULL;

    // Remove the Open entry from the linked list
    EnterCriticalSection(&(pSerialHead->OpenListCS));
    RemoveEntryList(&pOpenHead->llist);
    LeaveCriticalSection(&(pSerialHead->OpenListCS));

    // Free all data allocated in open
    if ( pOpenHead->CommEvents.hCommEvent )
        CloseHandle(pOpenHead->CommEvents.hCommEvent);

⌨️ 快捷键说明

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