mdd.c

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

C
1,337
字号
                    {
                    DEBUGMSG(ZONE_IO,(TEXT("[LPT_IOControl GetDeviceID] Nibble_Connect fail\r\n")));
                       continue;
                   }

                   // Try for up to T(l) to get DataAvail
                   // Some slow devices might require this
                   if (!CheckPort(pPortObj->ulBase + 1, 0x08, 0x00, P1284_TL_MS))
                   {
                       DEBUGMSG(ZONE_IO,(TEXT("[LPT_IOControl GetDeviceID] Couldn't Read ID!\r\n")));
                       TerminateChannel(pPortObj);
                         continue;
                    }

                    // Read ID length.
                    if (!NibbleRead(pPortObj->ulBase, (LPSTR)&wTemp, 2, &dwRet))
                    {
                         DEBUGMSG(ZONE_IO,(TEXT("[LPT_IOControl GetDeviceID] Couldn't read size bytes.\r\n")));
                       TerminateChannel(pPortObj);
                         continue;
                    }

                    // Determine the size of the ID string
                    if ((wTemp = swapbyte(wTemp)) <= 2)
                    {
                         TerminateChannel(pPortObj);
                         continue;
                    }
                  DEBUGMSG(ZONE_IO,(TEXT("[LPT_IOControl GetDeviceID] ID string length + 2=%u\r\n"),wTemp));

                    // Adjust of the two size bytes
                    wTemp -= 2;
                    if (dwLenOut < wTemp)
                        wTemp = (WORD)dwLenOut-1;

                    // Read the remainder of the id string
                    NibbleRead ( pPortObj->ulBase, pBufOut, (DWORD)wTemp, &dwRet);
                    TerminateChannel(pPortObj);
                    pBufOut[dwRet]='\0';
                    *pdwActualOut= dwRet;
                    
                    if (!dwRet)
                    {                        
                        Sleep(1000);
                    }
                    else
                    {                       
                        RETAILMSG(1,(TEXT("%s\r\n"), pdwActualOut));
                        break;
                    }
               } while (!dwRet && (unsigned int)GetTickCount()-ulStartTime < ulTimeout);               

               if( pPortObj->bFrdProtocol == ID_ECP )
               {
                    TerminateChannel(pPortObj);
                    NegotiateChannel(pPortObj, FALSE);
               }
               */
               break;
          }

          case IOCTL_PARALLEL_STATUS:
          {               
              DEBUGMSG(ZONE_IO,(TEXT("IOCTL_PARALLEL_STATUS\r\n")));
              if( pPortObj && dwLenOut == sizeof(DWORD) )
              {   
                  BOOL bWasECP = FALSE; 
                  ULONG ulStartTick;

                  if( pPortObj -> bCurrentMode == ECP_MODE )
                  {
                      bWasECP = TRUE;

                      // 
                      // issue: IOCTL_PARALLEL_STATUS is getting called because
                      // we returned 0 bytes written from an LPT_Write call. 
                      // Resetting out of ECP to LPT mode was throwing away whatever bytes
                      // in the FIFO and causing garbage if user resumed after Paper Out. 
                      //

                      ulStartTick = GetTickCount();

                      while( (0 == (READ_PORT_UCHAR((PUCHAR)pPortObj->ulBase+ECP_ECR_Reg) & ECP_FIFO_EMPTY_MASK)) 
                          && (GetTickCount() - ulStartTick < pPortObj->ulEcpTimeout) )
                      {
                          ; 
                      }

                      if( 0 == (READ_PORT_UCHAR((PUCHAR)pPortObj->ulBase+ECP_ECR_Reg) & ECP_FIFO_EMPTY_MASK) )
                      {
                          // 
                          // If we time out waiting for FIFO to flush, something is 
                          // actually broken, so we return OFFLINE
                          //
                          *(PDWORD)pBufOut = CE_DNS;
                          *pdwActualOut = dwLenOut;
                          DEBUGMSG(ZONE_ERROR,(TEXT("Timeout waiting for fifo. Recovering orphaned FIFO data... \r\n")));                          

                          if( pPortObj->cOrphanBytes = GetOrphanedByteCount(pPortObj) )
                          {
                              DEBUGMSG(ZONE_ERROR,(TEXT("Recovering %d bytes from FIFO\r\n"),pPortObj->cOrphanBytes));
                              pPortObj->cFifoBytes = pPortObj->cOrphanBytes;
                              pPortObj->iFifoNextOut = pPortObj->iFifoNextIn - pPortObj->cOrphanBytes;
                          }
                          else
                          {
                              DEBUGMSG(ZONE_ERROR,(TEXT("No bytes oprhaned in FIFO\r\n"),pPortObj->cOrphanBytes));                              
                          }
                          
                      }

                      // 
                      // issue: in ECP mode, status lines are remapped so PAPER_OUT looks like OFFLINE. 
                      // To resolve this we're negotiating back to LPT mode to collect status, then
                      // going back to ECP before returning. 
                      // 
                      ResetECP( pPortObj );

                      pPortObj->dwEcpMode = 0;
                  }

                  
                  //
                  // bug protection
                  // wait for line to stabilize if some one unhooks it
                  //
                  Sleep( 3500 );
                  
                  if( FALSE == CheckPrinterStatus( pPortObj, pPortObj->ulBase+1 ) )
                  {                      
                      if( !bWasECP && pPortObj->pPortData.dwCommError == CE_OOP )
                      {                          
                          //
                          // we may be dealing with a fake-o CE_OOP here
                          //
                          if( PD_SUCCESS != Nibble_Connect(pPortObj,NIBBLE_MODE) )
                              //(bWasECP ? Nibble_Connect(pPortObj,NIBBLE_MODE) : ECP_Connect(pPortObj,ECP_MODE)) )
                              pPortObj->pPortData.dwCommError = CE_DNS;
                          else
                          {
                              TerminateChannel(pPortObj);
                              pPortObj->pPortData.dwCommError = CE_OOP;
                          }                          
                      }

                      memcpy( pBufOut, &(pPortObj->pPortData.dwCommError), dwLenOut );
                      *pdwActualOut = dwLenOut;
                  }
                  else
                  {
                      // 
                      //  CheckPrinterStatus() TRUE == hunky dory 
                      //
                      memset( pBufOut, 0, dwLenOut );
                      *pdwActualOut = dwLenOut;
                  }

                  if( bWasECP )
                  {                      
                      NegotiateChannel(pPortObj,FALSE);     // bRequestDeviceID = FALSE 
                      
                      pPortObj->dwEcpMode = 0;
                      
                      if( pPortObj->bCurrentMode != ECP_MODE )
                      {
                          //RETAILMSG(1,(TEXT("Could not reset ECP mode after checking status. Returning CE_DNS\r\n")));
                          DEBUGMSG(ZONE_ERROR,(TEXT("Could not reset ECP mode after checking status. Returning CE_DNS\r\n")));
                          *(PDWORD)pBufOut = CE_DNS;
                          *pdwActualOut = dwLenOut;
                      }
                  }

              }
              else
              {                 
                 DEBUGMSG(ZONE_ERROR,(TEXT("IOCTL_PARALLEL_STATUS: bogus DeviceIoControl params\r\n")));
                 *pdwActualOut = 0;
                 RetVal = FALSE;
              }
              break;
          }
          case IOCTL_PARALLEL_GET_ECP_CHANNEL32:
          {            
            DEBUGMSG(ZONE_IOCTL,(TEXT("Parallel: IOCTL_PARALLEL_GET_ECP_CHANNEL32\r\n")));

            // this was bug 6597
            if ( ((UINT)dwLenOut < 4) ) // || (0 == pPortObj->dwInkStatusLen))   
            {
                DEBUGMSG(ZONE_ERROR,(TEXT("Unable to get channel 32 info.\r\n")));
                *pdwActualOut = pPortObj->dwInkStatusLen;
                memcpy( pBufOut, pPortObj->pInkStatus, pPortObj->dwInkStatusLen );

                *pdwActualOut=0;		// return error
	            RetVal = FALSE;
            }
            else
            {                        
                pPortObj->dwInkStatusLen = Get_DJ400_Dev_Status(pPortObj->ulBase, (PUCHAR)pPortObj->pInkStatus);
                Sleep(1000);
                NegotiateChannel(pPortObj,FALSE);
                Sleep(500);
		        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
                    RETAILMSG(1,(TEXT("Could not reset after ecp ch32 connect\r\n")));

                *pdwActualOut = pPortObj->dwInkStatusLen;
                memcpy( pBufOut, pPortObj->pInkStatus, pPortObj->dwInkStatusLen );
                
                DEBUGMSG(ZONE_IO,(TEXT("ink status: 0x%02x 0x%02x 0x%02x 0x%02x\r\n"), 
                        pPortObj->pInkStatus[0], 
                        pPortObj->pInkStatus[1], 
                        pPortObj->pInkStatus[2], 
                        pPortObj->pInkStatus[3]) );
            }

            break;

          }

          case IOCTL_PARALLEL_WRITE:
          {                        
            DWORD dwWritten = LPT_Write(pPortObj, pBufIn, dwLenIn);
            
            if( dwWritten < dwLenIn )
            {
                DEBUGMSG(ZONE_ERROR,(TEXT("IOCTL_PARALLEL_WRITE: Only wrote %d of %d requested.\r\n")));
                RetVal = FALSE;
            }
            break;
          }
     }
     return RetVal;
}


void  WriteEcpFifo(PPortInformation pPortObj, BYTE bData)
{    
    if( pPortObj->cFifoBytes < DEFAULT_ECP_FIFO_LENGTH )
        pPortObj->cFifoBytes++;

    pPortObj->abEcpFifo[pPortObj->iFifoNextIn] = bData;

    if( pPortObj->iFifoNextIn < DEFAULT_ECP_FIFO_LENGTH )
        pPortObj->iFifoNextIn++;
}

BYTE  ReadEcpFifo(PPortInformation pPortObj)
{
    BYTE bData; 

    bData = pPortObj->abEcpFifo[pPortObj->iFifoNextOut];

    if( pPortObj->iFifoNextOut > 0 )
        pPortObj->iFifoNextOut--;

    if( pPortObj->cFifoBytes > 0 )
        pPortObj->cFifoBytes--;

    return bData;
}

void ResetEcpFifo(PPortInformation pPortObj)
{
    pPortObj->cFifoBytes = 0;
    pPortObj->iFifoNextIn = 0;
    pPortObj->iFifoNextOut = 0;
    pPortObj->cOrphanBytes = 0;
}

UINT GetOrphanedByteCount(PPortInformation pPortObj)
{
    BYTE        bData;
    DWORD       count;
    BOOL        bRet = FALSE;
    PUCHAR    uECR_reg;
    PUCHAR    uDCR_reg;
    PUCHAR    uData_reg;    

    uECR_reg = (PUCHAR)pPortObj->ulBase+ECP_ECR_Reg;
    uDCR_reg = (PUCHAR)pPortObj->ulBase+ECP_DCR_Reg;
    uData_reg = (PUCHAR)pPortObj->ulBase+ECP_DFifo;

    bData = (BYTE)(READ_PORT_UCHAR(uECR_reg) & ECP_FIFOBITS_MASK);
    if (bData == ECP_FIFO_EMPTY)
        return 0;        
    
    // set dcr (x,x,x,1) nstrobe low to stop transfer
    WRITE_PORT_UCHAR(uDCR_reg, (BYTE)(READ_PORT_UCHAR(uDCR_reg) | NSTROBE_LOW));    

    count = DEFAULT_ECP_FIFO_LENGTH;
    if (bData != ECP_FIFO_FULL)
    {
        // start to fill up FIFO till full to decide # bytes remaining unsent
        do
        {
            WRITE_PORT_UCHAR(uData_reg, 0xFF);
            count --;

            bData = (BYTE)(READ_PORT_UCHAR(uECR_reg) & ECP_FIFOBITS_MASK);
            if (count == 0) break;        
        } while(bData != ECP_FIFO_FULL);
    }

    return count;
}

#if 0 
UINT GetOrphanedByteCount(PPortInformation pPortObj)
{
    PUCHAR uEcr = (PUCHAR)(pPortObj->ulBase+ECP_ECR_Reg);
    PUCHAR uFifo = (PUCHAR)(pPortObj->ulBase+ECP_DFifo);
    UINT cbOrphaned;

    HostRecovery(PortObj);
    WRITE_PORT_UCHAR(uEcr, ECP_CONFG_MODE);
        

    cbOrphaned = 0;


    WRITE_PORT_UCHAR(uEcr, ECP_PS2_MODE);

    return DEFAULT_ECP_FIFO_LENGTH - cbOrphaned;
}

#endif

⌨️ 快捷键说明

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