mdd.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,337 行 · 第 1/4 页

C
1,337
字号
                hConfig,
                TEXT("ECPIRQ"),
                0,
                &dwType,
                (PUCHAR)&dwData,
                &dwSize);
    if (dwRet != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_INIT,
            (TEXT("PARALLEL:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
            L"ECPIRQ", dwRet));
        goto grc_fail;
    }
    *lpuIrq = dwData;

    dwSize = sizeof(DWORD);
    dwRet = RegQueryValueEx(
                hConfig,
                TEXT("ECPEnable"),
                0,
                &dwType,
                (PUCHAR)&dwData,
                &dwSize);
    if (dwRet != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_INIT,
            (TEXT("PARALLEL:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
            L"ECPEnable", dwRet));
        goto grc_fail;
    }
    *lpfEcpEnable = dwData;


    return ERROR_SUCCESS;

grc_fail:
    RegCloseKey(hConfig);
    return dwRet;
}   // GetRegistryConfig




/*
 @doc EXTERNAL
 @func         HANDLE | LPT_Open | Parallel port driver initialization.
 *   Description: This routine must be called by the user to open the
 *   parallel device. The HANDLE returned must be used by the application in
 *   all subsequent calls to the parallel driver. This routine starts the thread
 *   which handles the parallel events.
 *   Exported to users.
 *
 @rdesc This routine returns a HANDLE representing the device.
 */
PPortInformation
LPT_Open(
     PPortInformation    pPortObj, // @parm Handle returned by LPT_Init.
     DWORD     AccessCode,         // @parm access code.
     DWORD     ShareMode      // @parm share mode - Not used in this driver.
     )
{
    char *Name;
    DWORD IoBase;
    DWORD IoLen;
    DWORD dwRet;


    DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: entry\r\n")));
    Name= LPT_DEFAULT_NAME;

    if ( (dwRet = GetRegistryConfig( PARALLEL_DRIVER_KEY, 
                                     &IoBase,  
                                     &IoLen, 
                                     &(pPortObj->uEcpIrq),      // irq
                                     &(pPortObj->ulEcpTimeout), // tiemout const
                                     &(pPortObj->fEcpEnable),   // bool enable
                                     &(pPortObj->cMaxTimeouts)  // cmaxtimeouts                                     
                                   )
        
         )
        != ERROR_SUCCESS 
       ) 
    {
        DEBUGMSG(ZONE_IO,
            (TEXT("LPT_Open GetRegistryConfig failed %d\r\n"),
            dwRet));
    }

    DEBUGMSG(ZONE_INIT,(TEXT("PARALLEL: Registry - \r\n\tIRQ = 0x%x\r\n\tEcpTimeout = %d\r\n\tEcpEnable = %d\r\n\tMaxTimeouts = %d\r\n"),
                 pPortObj->uEcpIrq, pPortObj->ulEcpTimeout, pPortObj->fEcpEnable, pPortObj->cMaxTimeouts));

    DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: Portname = %a IoBase= %Xh IoLen= %d\r\n"),Name,IoBase,IoLen));
    IoBase=(DWORD)Par_InternalMapRegisterAddresses(IoBase,IoLen);

    DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: Portname = %a IoBase= %Xh IoLen= %d\r\n"),Name,IoBase,IoLen));
    pPortObj->ulBase = IoBase;
    memcpy(pPortObj->Name, Name, 4);
    pPortObj->dwPortSharing = 0;
    pPortObj->blPortOpen = FALSE;
    pPortObj->pPortData.LossByte = 0;
    pPortObj->dwPortSharing |= PORT_IN_USE;
    pPortObj->wHost = HOST_NO_ECP;
    pPortObj->bCurrentMode = LPT_MODE;
    pPortObj->bCurrentPhase = FORWARD_IDLE;
    pPortObj->bFrdProtocol = ID_LPT;
    pPortObj->pPortData.PDLength = (WORD)sizeof(PortData);
    pPortObj->pPortData.PDVersion = 0x100;
    pPortObj->hOEvent = 0;
    pPortObj->hIEvent = 0;
    pPortObj->blInTransfer = FALSE;
    pPortObj->pDeviceID.pdeviceID = 0;
    pPortObj->pDeviceID.ulSize = 0;

    pPortObj->dwInkStatusLen = 0;
    memset(pPortObj->pInkStatus, 0, 4*sizeof(BYTE));

    // set up ECP Fifo 
    memset(pPortObj->abEcpFifo, 0, DEFAULT_ECP_FIFO_LENGTH);
    ResetEcpFifo(pPortObj);
    //pPortObj->fFlushEcpFifo = FALSE;
    pPortObj->cFifoBytes = 0;
    //pPortObj->iFifoCurrent = 0;
    pPortObj->cOrphanBytes = 0;

    // turn off all notification marks
    pPortObj->dwNotifyFlags = 0;
    pPortObj->TxLO = 0xFFFFFFFF;
    pPortObj->RxHI = 0xFFFFFFFF;

     // Init CommTimeouts.
     pPortObj->CommTimeouts.ReadIntervalTimeout = READ_TIMEOUT;
     pPortObj->CommTimeouts.ReadTotalTimeoutMultiplier =
          READ_TIMEOUT_MULTIPLIER;
     pPortObj->CommTimeouts.ReadTotalTimeoutConstant =
          READ_TIMEOUT_CONSTANT;
     pPortObj->CommTimeouts.WriteTotalTimeoutMultiplier=    WRITE_TIMEOUT_MULTIPLIER;
     pPortObj->CommTimeouts.WriteTotalTimeoutConstant  =    WRITE_TIMEOUT_CONSTANT;
         
     DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: Calling NegotiateChannel...\r\n")));
    
    ResetPort(pPortObj);  
    ResetECP(pPortObj);
    Sleep(1000);

    // 
    // call NegotiateChannel with TRUE to get device id
    // (to be returned in IOCTL_PARALLEL_GETDEVICEID
    //
    NegotiateChannel(pPortObj,TRUE);            
    TerminateChannel(pPortObj);    
    
    // 
    // if we got the device ID, attempt to negotiate (and store bCurrentMode for later)
    // else printer is off or unsupported (if we can't get the device id, we refuse)
    //
    if( pPortObj->pDeviceID.pdeviceID != NULL )
    {    
        if (IsHwECP(pPortObj))
        {
            DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: Host has ECP support.\r\n")));
            pPortObj->wHost = HOST_HAS_ECP;

            // Setting current cability of port
            pPortObj->bCurrentMode = ELPT_MODE;
            pPortObj->bFrdProtocol = ID_ECP;
        }

        NegotiateChannel(pPortObj,FALSE);     // bRequestDeviceID = FALSE / ...     
    }
    else
    {
        DEBUGMSG(ZONE_ERROR,(TEXT("Parallel: Could not retrieve device ID for printer.\r\n")));
        pPortObj->bCurrentMode = 0xff;
    }

    if (pPortObj->bCurrentMode == NIBBLE_MODE)
    {
          DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: In NIBBLE_MODE calling TerminateChannel...\r\n")));
        // If we are in nibble mode return to the forward direction
        TerminateChannel(pPortObj);

    }
    else if( pPortObj->bCurrentMode == ECP_MODE )
    {                
        DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: Setting up ECP Mode...\r\n")));
        // 
        // To set ECP mode, need to : 
        //   1. set direction = 0  [dcr:5]
        //   2. strobe = 0         [dcr:0]
        //   3. autoFd = 0         [dcr:1]
        //   4. Mode = ECP 011     [ecr:7,6,5]
        // 
        // To enable programmed I/O interrupt, need to: 
        //   1. set direction = 0  
        //   2. set state (!?)
        //   3. dmaEn = 0           [ecr:3]
        //   4. serviceIntr = 0     [ecr:2]
        // 

        pPortObj -> hOEvent = (ULONG)CreateEvent(NULL, FALSE, FALSE, NULL);         
        if( INVALID_HANDLE_VALUE == (HANDLE) pPortObj -> hOEvent )
        {
            DEBUGMSG(ZONE_ERROR,(TEXT("Invalid CreateEvent() handle returned for Interrupt event\r\n")));
        }

#ifdef x86
        pPortObj->IORefData = MapIrq2SysIntr(pPortObj->uEcpIrq);
#else
        pPortObj->IORefData = pPortObj->uEcpIrq;
#endif

        
        if( !InterruptInitialize(pPortObj->IORefData, (HANDLE)pPortObj->hOEvent, NULL, 0) )
        {
            DEBUGMSG(ZONE_ERROR,(TEXT("InterruptInitialize() fails.\r\n")));
        }
        //TerminateChannel(pPortObj);

        
        pPortObj->dwEcpMode = 0;
        pPortObj->cTimeouts = 0;

        pPortObj->bCurrentMode = ECP_MODE;
    }
    else    // couldn't set the mode? we're broken! (or the printer's turned off)
    {
        ResetECP(pPortObj);
        ResetPort(pPortObj);
        LPT_Close(pPortObj);        
        LPT_Deinit(pPortObj);

        DEBUGMSG(ZONE_ERROR,(TEXT("Parallel: Device is offline or not responding. Returning NULL handle.\r\n")));
        pPortObj = NULL;
    }
    
    DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: return pPortObj=%Xh\r\n"),pPortObj));
    return pPortObj;
}



// ****************************************************************
//
//   @doc EXTERNAL
//
//   @func BOOL     | LPT_Close | close the parallel device.
//
//   @parm DWORD | pHead      | Context pointer returned from LPT_Open
//
//   @rdesc TRUE if success; FALSE if failure
//
//   @remark This routine is called by the device manager to close the device.
//
//
//
BOOL
LPT_Close(PPortInformation pOpenHead)
{
    DEBUGMSG(ZONE_IO,(TEXT("LPT_Close: entry\r\n")));

    Sleep(500);

    if( pOpenHead->bFrdProtocol == ID_ECP )
    {
        InterruptDisable(pOpenHead->IORefData);
        CloseHandle((HANDLE)pOpenHead->hOEvent);

        //ResetECP(pOpenHead);
    }

//    ResetPort(pOpenHead);    bug!
    
    if( pOpenHead->pDeviceID.pdeviceID )
    {
        free( pOpenHead->pDeviceID.pdeviceID );
        pOpenHead->pDeviceID.pdeviceID = 0;
        pOpenHead->pDeviceID.ulSize = 0;
    }

    return TRUE;
}

/*
 @doc EXTERNAL
 @func    BOOL | LPT_Deinit | De-initialize parallel port.
 @parm DWORD | pSerialHead | Context pointer returned from LPT_Init
 *
 @rdesc None.
 */
BOOL
LPT_Deinit(PPortInformation pPortObj)
{
    DEBUGMSG(ZONE_IO,(TEXT("LPT_Deinit: entry\r\n")));

    LocalFree(pPortObj);
    

    return TRUE;
}


/*
   @doc EXTERNAL
   @func  ULONG | LPT_Read | Allows application to receive characters from
   * parallel port. This routine sets the buffer and bufferlength to be used
   * by the reading thread. It also enables reception and controlling when
   * to return to the user. It writes to the referent of the fourth argument
   * the number of bytes transacted. It returns the status of the call.
   *
   * Exported to users.
   @rdesc This routine returns: -1 if error, or number of bytes read.
   */
ULONG
LPT_Read(
    PPortInformation pPortObj,     //@parm [IN]    HANDLE returned by LPT_Open
    PUCHAR          pTargetBuffer, //@parm [IN,OUT] Pointer to valid memory.
    ULONG      BufferLength   //@parm [IN]    Size in bytes of pTargetBuffer.
    )
{
     ULONG               BytesRead = 0;
     DEBUGMSG(ZONE_IO,(TEXT("LPT_Read: entry\r\n")));
     return BytesRead;
}


/*
   @doc EXTERNAL
   @func ULONG | LPT_Write | Allows application to transmit bytes to the parallel port. Exported to users.
   *
   @rdesc It returns the number of bytes written or -1 if error.
   *
   *
   */
ULONG
LPT_Write(PPortInformation pPortObj, /*@parm [IN]  HANDLE returned by LPT_Open.*/
            PUCHAR pSourceBytes,   /*@parm [IN]  Pointer to bytes to be written.*/
            ULONG    NumberOfBytes /*@parm [IN]  Number of bytes to be written. */

⌨️ 快捷键说明

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