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

📄 mdd.c

📁 wince4.2 USB function driver for magic eye mmsp2 platform
💻 C
📖 第 1 页 / 共 5 页
字号:
    pHWHead = pHWObj->pFuncTbl->HWInit(Identifier, pSerialHead);
    pSerialHead->pHWHead = pHWHead;
    pSerialHead->pHWObj = pHWObj;

    /* 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")));

    // 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\n\r")));
        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 with start at %x\r\n"),
                          pSerialHead->RxBufferInfo.RxCharBuffer));

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

    }

    DEBUGMSG (ZONE_INIT | ZONE_FUNCTION, (TEXT("-COM_Init\r\n")));
    return (pSerialHead);
}
/*
 *  @doc INTERNAL
 *	@func		BOOL | 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.
 */
BOOL
ApplyDCB (PHW_INDEP_INFO pSerialHead,DCB *pDCB, BOOL fOpen)
{
    PHWOBJ          pHWObj      = pSerialHead->pHWObj;

    if ( !pHWObj->pFuncTbl->HWSetDCB(pSerialHead->pHWHead,
                                     pDCB) ) {
        return(FALSE);
    }

    if ( !fOpen ) {
        return TRUE;
    }
    // If PDD SetDCB was successful, save the supplied DCB and
    // configure port to match these settings.
    memcpy(&(pSerialHead->DCB), pDCB, sizeof(DCB));

    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 TRUE;
}

/*
 @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\n\r")));
        return (NULL);
    }

    // Init the structure 
    pOpenHead->pSerialHead = pSerialHead;  // pointer back to our parent
    pOpenHead->StructUsers = 0;
    pOpenHead->AccessCode = AccessCode;
    pOpenHead->ShareMode = ShareMode;
    pOpenHead->CommEvents.hCommEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    pOpenHead->CommEvents.fEventMask = 0;
    pOpenHead->CommEvents.fEventData = 0;
    pOpenHead->CommEvents.fAbort = 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\n\r"),
                  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\n\r"),
                  pOpenHead));

        if ( pSerialHead->pHWObj->BindFlags & THREAD_AT_OPEN ) {
            DEBUGMSG(ZONE_INIT|ZONE_OPEN,
                     (TEXT("COM_Open: Starting DispatchThread x%X\n\r"),
                      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\n\r"),
                          pOpenHead));
                goto OpenFail;
            }
            CeSetThreadPriority(pSerialHead->pDispatchThread,
                              pSerialHead->Priority256);
        }

        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,&pSerialHead->DCB, 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);

        if ( pHWObj->BindFlags & THREAD_IN_MDD ) {
            CeSetThreadPriority(pSerialHead->pDispatchThread,
                              pSerialHead->Priority256);
        }

        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"),
                                        NULL, 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);
    LocalFree( pOpenHead );

    return (NULL);


}

// ****************************************************************
//
//	@doc EXTERNAL
//
//	@func BOOL	| COM_Close | close the serial device.
//
//	@parm DWORD | pHead		| Context pointer returned from COM_Open
//
//	@rdesc TRUE if success; FALSE if failure
//
//	@remark This routine is called by the device manager to close the device.
//			
//
//
BOOL
COM_Close(PHW_OPEN_INFO pOpenHead)
{
    PHW_INDEP_INFO  pSerialHead = pOpenHead->pSerialHead;
    PHWOBJ          pHWObj;
    int i;

    DEBUGMSG (ZONE_CLOSE|ZONE_FUNCTION, (TEXT("+COM_Close\r\n")));

    if ( !pSerialHead ) {
        DEBUGMSG (ZONE_ERROR, (TEXT("!!COM_Close: pSerialHead == NULL!!\r\n")));
        SetLastError(ERROR_INVALID_HANDLE);

⌨️ 快捷键说明

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