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 + -
显示快捷键?