mdd.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,337 行 · 第 1/4 页
C
1,337 行
)
{
ULONG TotalWritten;
ULONG ulTimeout;
ULONG ulStartTime;
ULONG ulEndTime;
ULONG uStatusPort, uDataPort;
// Initialize the LPT Port variables
uDataPort = pPortObj->ulBase;
uStatusPort = uDataPort + 1;
TotalWritten= NumberOfBytes;
// set total written to requested
// setup transfer size
pPortObj->pPortData.QOutCount = NumberOfBytes;
// if no timeout specified
DEBUGMSG(ZONE_WRITE,(TEXT("LPT_Write: NumberOfBytes = %d\r\n"),NumberOfBytes));
if (!pPortObj->CommTimeouts.WriteTotalTimeoutMultiplier &&
!pPortObj->CommTimeouts.WriteTotalTimeoutConstant) {
do { // start writing until completion
while (pPortObj->pPortData.QOutCount && CheckPrinterStatus (pPortObj, uStatusPort))
{
OutByte(uDataPort, *pSourceBytes++, TRUE);
pPortObj->pPortData.QOutCount --;
}
} while (pPortObj->pPortData.QOutCount);
} else {
// compute timeout
ulTimeout= NumberOfBytes*pPortObj->CommTimeouts.WriteTotalTimeoutMultiplier+
pPortObj->CommTimeouts.WriteTotalTimeoutConstant;
ulStartTime=GetTickCount(); // get starting time
if( pPortObj->cTimeouts > pPortObj->cMaxTimeouts )
{
pPortObj->cTimeouts = 0;
return 0;
}
if( pPortObj->bCurrentMode != ECP_MODE )
{
pPortObj->cTimeouts = 0;
//DEBUGMSG(ZONE_MAXIO, (TEXT("LPT_Write: LPT-Mode Printing!\r\n")));
do {
while (pPortObj->pPortData.QOutCount && CheckPrinterStatus (pPortObj, uStatusPort) )
{
OutByte(uDataPort, *pSourceBytes++, TRUE);
pPortObj->pPortData.QOutCount --;
}
ulEndTime=GetTickCount();
if( ulEndTime-ulStartTime > ulTimeout )
pPortObj->cTimeouts++;
} while ( (pPortObj->pPortData.QOutCount)
&& (ulEndTime-ulStartTime < ulTimeout)
&& (pPortObj->cTimeouts < pPortObj->cMaxTimeouts) );
}
else
{
BYTE bData;
ulTimeout= NumberOfBytes*pPortObj->CommTimeouts.WriteTotalTimeoutMultiplier+
pPortObj->CommTimeouts.WriteTotalTimeoutConstant;
//
// one-time-only stuff;
// hits DCR to make sure we're in forward mode,
// disable nACK interrupt
//
if( pPortObj->dwEcpMode != 0xdeadbeef )
{
bData = READ_PORT_UCHAR((PUCHAR)uDataPort+ECP_DCR_Reg);
WRITE_PORT_UCHAR((PUCHAR)uDataPort+ECP_DCR_Reg, (UCHAR)(bData | ~ECP_NACK_INT_OFF));
// DCR = xx0x xx00
bData = READ_PORT_UCHAR((PUCHAR)uDataPort+ECP_DCR_Reg);
WRITE_PORT_UCHAR((PUCHAR)uDataPort+ECP_DCR_Reg, (UCHAR)(bData & ECP_DCR_ZERO));
bData = READ_PORT_UCHAR((PUCHAR)uDataPort+ECP_DCR_Reg);
DEBUGMSG(ZONE_IO,(TEXT("LPT_Write: ECP Mode Printing, DCR = 0x%x, ulTimeout == %d\r\n"), bData, ulTimeout));
RETAILMSG(1,(TEXT("Parallel: ECP Mode Printing.\r\n"), bData, ulTimeout));
pPortObj->dwEcpMode = 0xdeadbeef;
}
//
// serviceIntr is disabled (=1) by hardware whenever FIFO is not full
// we have to flip it back to 0 to re-enable the interrupt
//
bData = READ_PORT_UCHAR((PUCHAR)uDataPort+ECP_ECR_Reg);
WRITE_PORT_UCHAR((PUCHAR)uDataPort+ECP_ECR_Reg, (ECP_ECP_MODE & ~ECP_ECR_SERVICE_INT_BIT));
ulStartTime = GetTickCount();
if( pPortObj->cOrphanBytes )
{
DEBUGMSG(ZONE_IO,(TEXT("Writing %d orphaned bytes back to ECP fifo\r\n"), pPortObj->cOrphanBytes));
while( pPortObj->cOrphanBytes &&
0 == (READ_PORT_UCHAR((PUCHAR)uDataPort+ECP_ECR_Reg) & ECP_FIFO_FULL_MASK) )
{
OutByte( uDataPort+ECP_DFifo, ReadEcpFifo(pPortObj), FALSE );
pPortObj->cOrphanBytes--;
}
if( pPortObj->cOrphanBytes == 0 )
{
DEBUGMSG(ZONE_IO,(TEXT("*** Flushed orphaned bytes from fifo buffer\r\n")));
ResetEcpFifo(pPortObj);
pPortObj->cTimeouts = 0;
}
else
{
DEBUGMSG(ZONE_IO,(TEXT("*** couldn't flush orphaned fifo buffer\r\n")));
return 0;
}
}
do
{
if( WAIT_OBJECT_0 != WaitForSingleObject((HANDLE)pPortObj->hOEvent, ulTimeout) )
{
pPortObj->cTimeouts++;
break; // break out on timeout
}
//
// issue: this write should be done as a burst, not polling fifo_full.
// we can later determine serviceIntr fifo threshold by using test fifo mode
//
//
// write bytes to fifo, poll ecr, till fifo full
//
while( pPortObj->pPortData.QOutCount &&
0 == (READ_PORT_UCHAR((PUCHAR)uDataPort+ECP_ECR_Reg) & ECP_FIFO_FULL_MASK) )
{
OutByte( uDataPort+ECP_DFifo, *pSourceBytes, FALSE ); // don't strobe for ECP FIFO
WriteEcpFifo( pPortObj, *pSourceBytes );
pSourceBytes++;
pPortObj->pPortData.QOutCount --;
}
WRITE_PORT_UCHAR((PUCHAR)uDataPort+ECP_ECR_Reg, (ECP_ECP_MODE & ~ECP_ECR_SERVICE_INT_BIT));
InterruptDone( pPortObj->IORefData );
} while (pPortObj->pPortData.QOutCount);
}
//
// interrupts start coming in really slow when the printer's out of paper,
// we use cTimeouts to track the pattern of slowness.
//
if( GetTickCount() - ulStartTime > pPortObj->ulEcpTimeout )
pPortObj->cTimeouts++;
else
pPortObj->cTimeouts = 0;
TotalWritten-=pPortObj->pPortData.QOutCount; // return bytes actually written
}
if (TotalWritten != NumberOfBytes)
DEBUGMSG(ZONE_ERROR,(TEXT("LPT_Write: Timeout after %u of %u written.\r\n"),TotalWritten,NumberOfBytes));
return TotalWritten;
}
ULONG
LPT_Seek(
PPortInformation pPortObj,
LONG Position,
DWORD Type
)
{
DEBUGMSG(ZONE_IO,(TEXT("LPT_Seek: entry\r\n")));
return (ULONG)-1;
}
/*
@doc EXTERNAL
@func BOOL | LPT_PowerUp | Turn power on to parallel device
* Exported to users.
@rdesc This routine returns a status of 1 if unsuccessful and 0 otherwise.
*/
BOOL
LPT_PowerUp(
PPortInformation pPortObj /*@parm Handle to device. */
)
{
DEBUGMSG(ZONE_IO,(TEXT("LPT_PowerUp: entry\r\n")));
return 1;
}
/*
@doc EXTERNAL
@func BOOL | LPT_PowerDown | Turns off power to parallel device.
* Exported to users.
@rdesc This routine returns a status of 1 if unsuccessful and 0 otherwise.
*/
BOOL
LPT_PowerDown(
PPortInformation pPortObj /*@parm Handle to device. */
)
{
DEBUGMSG(ZONE_IO,(TEXT("LPT_PowerDown: entry\r\n")));
return 1;
}
/* ****************************************************************
*
* Win32 Comm Api Support follows.
*
* @doc EXTERNAL
*/
// ****************************************************************
//
// @func BOOL | LPT_IOControl | Device IO control routine
// @parm DWORD | dwOpenData | value returned from COM_Open call
// @parm DWORD | dwCode | io control code to be performed
// @parm PBYTE | pBufIn | input data to the device
// @parm DWORD | dwLenIn | number of bytes being passed in
// @parm PBYTE | pBufOut | output data from the device
// @parm DWORD | dwLenOut |maximum number of bytes to receive from device
// @parm PDWORD | pdwActualOut | actual number of bytes received from device
//
// @rdesc Returns TRUE for success, FALSE for failure
//
// @remark Routine exported by a device driver. "PAR" is the string
// passed in as lpszType in RegisterDevice
BOOL
LPT_IOControl(PPortInformation pPortObj,
DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut)
{
BOOL RetVal = TRUE; // Initialize to success
// unsigned int ulStartTime;
// unsigned int ulTimeout;
// DWORD dwRet;
// WORD wTemp;
DEBUGMSG(ZONE_IO,(TEXT("LPT_IOControl: entry code=%u\r\n"),dwCode));
switch (dwCode) {
case IOCTL_PARALLEL_SET_TIMEOUTS:
// if input buffer too small
if (dwLenIn < sizeof(COMMTIMEOUTS))
return FALSE; // return error
// copy timeouts into port info struct
memcpy(&pPortObj->CommTimeouts,pBufIn,sizeof(COMMTIMEOUTS));
break;
case IOCTL_PARALLEL_GET_TIMEOUTS:
// if output buffer too small
if ((unsigned int)dwLenOut < (unsigned int)sizeof(COMMTIMEOUTS))
{
*pdwActualOut=0; // return error
return FALSE;
}
// copy current timeouts to output
memcpy(pBufOut,&pPortObj->CommTimeouts,sizeof(COMMTIMEOUTS));
// return timeout size
*pdwActualOut= sizeof(COMMTIMEOUTS);
break;
case IOCTL_PARALLEL_GETDEVICEID:
{
//
// we [hopefully] collected device ID string during LPT_Open.
//
if( pPortObj->pDeviceID.pdeviceID && pPortObj->pDeviceID.ulSize )
{
CHAR* p;
*pdwActualOut = (pPortObj->pDeviceID.ulSize > dwLenOut ? dwLenOut : pPortObj->pDeviceID.ulSize);
memcpy( pBufOut, pPortObj->pDeviceID.pdeviceID, *pdwActualOut );
p = pBufOut;
while (p = strchr(p, '$'))
{
if (p[2] == 'C')
{
pPortObj->dwInkStatusLen = 4;
pPortObj->pInkStatus[3] |= 0x10;
DEBUGMSG(ZONE_IO,(TEXT("Faking PEN_COLOR\r\n")));
}
else if (p[2] == 'B')
{
pPortObj->dwInkStatusLen = 4;
pPortObj->pInkStatus[3] |= 0x01;
DEBUGMSG(ZONE_IO,(TEXT("Faking PEN_BLACK\r\n")));
}
p++;
}
}
else
{
*pdwActualOut = 0;
DEBUGMSG(ZONE_ERROR,(TEXT("PARALLEL: could not report device id.\r\n")));
RetVal = FALSE;
}
/*
// compute timeout
ulTimeout= pPortObj->CommTimeouts.WriteTotalTimeoutConstant;
ulStartTime=GetTickCount();
RETAILMSG(1,(TEXT("[LPT_IOControl GetDeviceID] Nibble_Connect\r\n")));
do {
dwRet=0;
// Change to proper mode. We always read the device id in nibble mode.
TerminateChannel(pPortObj);
if (Nibble_Connect(pPortObj, NIBBLE_MODE | PN_REQ_DEVID) != PD_SUCCESS)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?