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