示例#1
0
/*!
This method tries to get the device id back from the printer and does some basic verification.
*/
DRIVER_ERROR SystemServices::GetDeviceID(BYTE* strID, int iSize, BOOL bQuery)
{

    if (iSize < 3)  // must have at least enough space for count bytes and NULL terminator
    {
        return(SYSTEM_ERROR);
    }

	memset (strID, 0, iSize);

    if (bQuery)
    {
        // initialize the first 3 bytes to NULL (1st 2 bytes may be binary count of string
        // length so need to clear them as well as the "real" start of the string)
        // so that if ReadDeviceID() does nothing with buffer we won't act upon what
        // was in the buffer before calling it
        strID[0] = strID[1] = strID[2] = '\0';

        // we are going to try more then once because some printers lie and this
        // specifically fixes problems with the DJ630 & DJ640 printers.
        int i = 0;
        for(i = 0; i < 20; i++)
        {
            // get the string
            if((ReadDeviceID(strID, iSize) != NO_ERROR))
            {
                DBG1("Error from ReadDeviceID or No DevID Available\n");
                if(BusyWait((DWORD)100) == JOB_CANCELED)
                {
                    return JOB_CANCELED;
                }
                continue;  // go back and try again
            }
            // look for the existence of either of the defined manufacturer fields in the string
            // (need to look starting at strID[0] and at strID[2] since the first 2 bytes may or
            // may not be binary count bytes, one of which could be a binary 0 (NULL) which strstr()
            // will interpret as the end of string)
            else
            {
                if ((!strstr((const char*)strID, "MFG:") &&
                    !strstr((const char*)strID+2, "MFG:") &&
                    !strstr((const char*)strID, "MANUFACTURER:") &&
                    !strstr((const char*)strID+2, "MANUFACTURER:")) ||
                    (!strstr((const char*)strID, "MDL:") &&
                    !strstr((const char*)strID+2, "MDL:") &&
                    !strstr((const char*)strID, "MODEL:") &&
                    !strstr((const char*)strID+2, "MODEL:")) ||
                    ((strID[0] == '\0') && (strID[1] == '\0')))
                {
                    DBG1("Successful' DevID request was a lie.  Retry...waiting 100 ms\n");
                    if(BusyWait((DWORD)100) == JOB_CANCELED)
                    {
                        return JOB_CANCELED;
                    }
                    continue;  // go back and try again
                }
                else
                {
                    // If either of the first two bytes is 0, byte count is there, replace them.

                    if (strID[0] == 0 || strID[1] == 0)
                    {
                        strID[0] = strID[1] = ' ';
                    }
                    //DBG1("HPPCL: ReadDeviceID [%hs]\n", strID+2);
                    break; // SUCCESS!
                }
            }
        }
        if(i >= 20)
        {
            return BAD_DEVICE_ID;
        }
    }
    else
    {
        // for use when string doesn't have to be re-fetched from printer

        if (DevIDBuffSize > iSize)
        {
            return SYSTEM_ERROR;
        }

        // the first 2 bytes may be binary so could be 0 (NULL) so can't use strcpy
        // (could get strlen of strDevID if start @ strDevID+2 and then add 2
        //  if do this it wouldn't require that caller's buffer be >=
        //  DevIDBuffSize, only that is it longer that actual devID string read)
        memcpy(strID, strDevID, DevIDBuffSize);
    }
    return NO_ERROR;

    // This is old code from before the 630, 640 loop fix was done (above).  This can
    // eventually be removed.
    // check the read (or copied) DeviceID string for validity

    // check what may be the binary count of the string length (some platforms return
    // the raw DeviceID in which the 1st 2 bytes are a binary count of the string length,
    // other platforms strip off these count bytes)
    // if they are a binary count they shouldn't be zero, and if they aren't a binary
    // count they also shouldn't be zero (NULL) since that would mean end of string
/*    if ((strID[0] == '\0') && (strID[1] == '\0'))
    {
        return BAD_DEVICE_ID;
    }

    // look for the existence of either of the defined manufacturer fields in the string
    // (need to look starting at strID[0] and at strID[2] since the first 2 bytes may or
    //  may not be binary count bytes, one of which could be a binary 0 (NULL) which strstr()
    //  will interpret as the end of string)
    if (!strstr((const char*)strID, "MFG:") &&
        !strstr((const char*)strID+2, "MFG:") &&
        !strstr((const char*)strID, "MANUFACTURER:") &&
        !strstr((const char*)strID+2, "MANUFACTURER:"))
    {
        return BAD_DEVICE_ID;
    }*/

} //GetDeviceID
示例#2
0
/*!
Mandatory call to be inserted in derived constructor.
This method tries to establish communications with printer and identify it.
The derived SystemServices constructor must call this base-class routine.
*/
DRIVER_ERROR SystemServices::InitDeviceComm()
// Must be called from derived class constructor.
// (Base class must be constructed before system calls
//  below can be made.)
// Opens the port, looks for printer and
// dialogues with user if none found;
// then attempts to read and parse device ID string --
// if successful, sets IOMode.bDevID to TRUE (strings stored
// for retrieval by PrintContext).
// Returns an error only if user cancelled. Otherwise
// no error even if unidi.
//
// Calls: OpenPort,PrinterIsAlive,DisplayPrinterStatus,BusyWait,
//   GetDeviceID,DeviceRegistry::ParseDevIDString.
// Sets:    hPort,IOMode, strModel, strPens
{
    DRIVER_ERROR err = NO_ERROR;
    BOOL ErrorDisplayed = FALSE;
    BYTE temp;

    // Check whether this system supports passing back a status-byte
    if( GetStatusInfo(&temp) == FALSE )
    {
        DBG1("InitDeviceComm:  No Status-Byte Available\n");
    }
    else IOMode.bStatus = TRUE;

    // Check whether we can get a DeviceID - this may
    // still fail if the device is just turned off
    err = GetDeviceID(strDevID, DevIDBuffSize, TRUE);

    if ( err == NO_ERROR )
    {
        DBG1("InitDeviceComm:  DevID request successful\n");
        IOMode.bDevID = TRUE;
    }


    // PrinterIsAlive is arbitrary if we can't get the status-byte.
    // This check is also critical so a true uni-di system does not sit
    // in a loop informing the user to turn on the printer.
    if ( IOMode.bStatus == TRUE )
    {
        // Make sure a printer is there, turned on and connected
        // before we go any further.  This takes some additional checking
        // due to the fact that the 895 returns a status byte of F8 when
        // it's out of paper, the same as a 600 when it's turned off.
        // 895 can get a devID even when 'off' so we'll key off that logic.
        if ( (err != NO_ERROR) && (PrinterIsAlive() == FALSE) )
        {
            // Printer is actually turned off
            while(PrinterIsAlive() == FALSE)
            {
                DBG1("PrinterIsAlive returned FALSE\n");
                ErrorDisplayed = TRUE;
                DisplayPrinterStatus(DISPLAY_NO_PRINTER_FOUND);

                if(BusyWait(500) == JOB_CANCELED)
                    return JOB_CANCELED;
            }
            if(ErrorDisplayed == TRUE)
            {
                DisplayPrinterStatus(DISPLAY_PRINTING);
                // if they just turned on/connected the printer,
                // delay a bit to let it initialize
                if(BusyWait(2000) == JOB_CANCELED)
                    return JOB_CANCELED;

                err = GetDeviceID(strDevID, DevIDBuffSize, TRUE);
                if ( err == NO_ERROR )
                {
                    DBG1("InitDeviceComm:  DevID request successful\n");
                    IOMode.bDevID = TRUE;
                }
            }
        }
        // else... we have 8xx/9xx with an out-of-paper error
        // which we will catch in the I/O handling

    }

    if (err!=NO_ERROR)
    {
        DBG1("InitDeviceComm:  No DeviceID Available\n");
        return NO_ERROR;
    }

    err = DR->ParseDevIDString((const char*)strDevID, strModel, &VIPVersion, strPens);

    if (err!=NO_ERROR)
    {
        // The DevID we got is actually garbage!
        DBG1("InitDeviceComm:  The DevID string is invalid!\n");
        IOMode.bDevID=FALSE;
    }

    return NO_ERROR;
}
示例#3
0
void CCommandProcessor::ParseCommand ( const char * const cmdBegin,
                                       const uint64_t currentTime )
{
  const char * const cmdEnd = SkipCharsNotInSet( cmdBegin, SPACE_AND_TAB );
  assert( cmdBegin != cmdEnd );

  const char * const paramBegin = SkipCharsInSet( cmdEnd, SPACE_AND_TAB );

  bool extraParamsFound = false;

  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_QUESTION_MARK, true, false, &extraParamsFound ) ||
       IsCmd( cmdBegin, cmdEnd, CMDNAME_HELP, false, false, &extraParamsFound ) )
  {
    PrintStr( "This console is similar to the Bus Pirate console." EOL );
    PrintStr( "Commands longer than 1 character are case insensitive." EOL );
    PrintStr( "WARNING: If a command takes too long to run, the watchdog may reset the board." EOL );
    PrintStr( "Commands are:" EOL );

    Printf( "  %s, %s: Show this help text." EOL, CMDNAME_QUESTION_MARK, CMDNAME_HELP );
    Printf( "  %s: Show version information." EOL, CMDNAME_I );
    Printf( "  %s: Test USB transfer speed." EOL, CMDNAME_USBSPEEDTEST );
    Printf( "  %s: Show JTAG pin status (read as inputs)." EOL, CMDNAME_JTAGPINS );
    Printf( "  %s: Test JTAG shift speed. WARNING: Do NOT connect any JTAG device." EOL, CMDNAME_JTAGSHIFTSPEEDTEST );
    Printf( "  %s: Exercises malloc()." EOL, CMDNAME_MALLOCTEST );
    Printf( "  %s: Exercises C++ exceptions." EOL, CMDNAME_CPP_EXCEPTION_TEST );
    Printf( "  %s: Shows memory usage." EOL, CMDNAME_MEMORY_USAGE );
    Printf( "  %s" EOL, CMDNAME_CPU_LOAD );
    Printf( "  %s" EOL, CMDNAME_UPTIME );
    Printf( "  %s" EOL, CMDNAME_RESET );
    Printf( "  %s" EOL, CMDNAME_RESET_CAUSE );
    Printf( "  %s <addr> <byte count>" EOL, CMDNAME_PRINT_MEMORY );
    Printf( "  %s <milliseconds>" EOL, CMDNAME_BUSY_WAIT );
    Printf( "  %s <command|protocol>" EOL, CMDNAME_SIMULATE_ERROR );

    return;
  }

  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_I, true, false, &extraParamsFound ) )
  {
    #ifndef NDEBUG
      const char buildType[] = "Debug build";
    #else
      const char buildType[] = "Release build";
    #endif

    Printf( "JtagDue %s" EOL, PACKAGE_VERSION );
    Printf( "%s, compiler version %s" EOL, buildType, __VERSION__ );
    Printf( "Watchdog %s" EOL, ENABLE_WDT ? "enabled" : "disabled" );

    return;
  }


  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_RESET, false, false, &extraParamsFound ) )
  {
    // This message does not reach the other side, we would need to add some delay.
    //   UsbPrint( txBuffer, "Resetting the board..." EOL );
    __disable_irq();
    // Note that this message always goes to the serial port console,
    // even if the user is connected over USB. It might be possible to send
    // it over USB and then wait for the outgoing buffer to be empty.
    SerialSyncWriteStr( "Resetting the board..." EOL );
    SerialWaitForDataSent();
    ResetBoard( ENABLE_WDT );
    assert( false );  // We should never reach this point.
    return;
  }


  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_CPU_LOAD, false, false, &extraParamsFound ) )
  {
    if ( ENABLE_CPU_SLEEP )
      PrintStr( "CPU load statistics not available." EOL );
    else
      DisplayCpuLoad();

    return;
  }


  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_UPTIME, false, false, &extraParamsFound ) )
  {
    char buffer[ CONVERT_TO_DEC_BUF_SIZE ];
    Printf( "Uptime: %s seconds." EOL, convert_unsigned_to_dec_th( GetUptime() / 1000, buffer, ',' ) );
    return;
  }


  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_RESET_CAUSE, false, false, &extraParamsFound ) )
  {
    DisplayResetCause();
    return;
  }


  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_PRINT_MEMORY, false, true, &extraParamsFound ) )
  {
    PrintMemory( paramBegin );
    return;
  }


  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_BUSY_WAIT, false, true, &extraParamsFound ) )
  {
    BusyWait( paramBegin );
    return;
  }


  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_USBSPEEDTEST, false, true, &extraParamsFound ) )
  {
    ProcessUsbSpeedTestCmd( paramBegin, currentTime );
    return;
  }


  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_JTAGPINS, false, false, &extraParamsFound ) )
  {
    PrintJtagPinStatus();
    return;
  }

  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_JTAGSHIFTSPEEDTEST, false, false, &extraParamsFound ) )
  {
    if ( !IsNativeUsbPort() )
      throw std::runtime_error( "This command is only available on the 'Native' USB port." );


    // Fill the Rx buffer with some test data.
    assert( m_rxBuffer != NULL );

    m_rxBuffer->Reset();
    for ( uint32_t i = 0; !m_rxBuffer->IsFull(); ++i )
    {
      m_rxBuffer->WriteElem( CUsbRxBuffer::ElemType( i ) );
    }


    // If the mode is set to MODE_HIZ, you cannot see the generated signal with the oscilloscope.
    // Note also that the built-in pull-ups on the Atmel ATSAM3X8 are too weak (between 50 and 100 KOhm,
    // yields too slow a rising time) to be of any use.

    const bool oldPullUps = GetJtagPullups();
    SetJtagPullups( false );

    const JtagPinModeEnum oldMode = GetJtagPinMode();
    SetJtagPinMode ( MODE_JTAG );


    // Each JTAG transfer needs 2 bits in the Rx buffer, TMS and TDI,
    // but produces only 1 bit, TDO.
    const uint32_t jtagByteCount = m_rxBuffer->GetElemCount() / 2;

    const uint16_t bitCount = jtagByteCount * 8;

    // Shift all JTAG data through several times.

    const uint64_t startTime = GetUptime();
    const uint32_t iterCount = 50;

    for ( uint32_t i = 0; i < iterCount; ++i )
    {
      // We hope that this will not clear the buffer contents.
      assert( m_rxBuffer != NULL );
      assert( m_txBuffer != NULL );

      m_rxBuffer->Reset();
      m_rxBuffer->CommitWrittenElements( jtagByteCount * 2 );

      m_txBuffer->Reset();

      ShiftJtagData( m_rxBuffer,
                     m_txBuffer,
                     bitCount );

      assert( m_txBuffer->GetElemCount() == jtagByteCount );
    }

    const uint64_t finishTime = GetUptime();
    const uint32_t elapsedTime = uint32_t( finishTime - startTime );

    m_rxBuffer->Reset();
    m_txBuffer->Reset();
    const unsigned kBitsPerSec = unsigned( uint64_t(bitCount) * iterCount * 1000 / elapsedTime / 1024 );

    SetJtagPinMode( oldMode );
    SetJtagPullups( oldPullUps );

    // I am getting 221 KiB/s with GCC 4.7.3 and optimisation level "-O3".
    Printf( EOL "Finished JTAG shift speed test, throughput %u Kbits/s (%u KiB/s)." EOL,
               kBitsPerSec, kBitsPerSec / 8 );

    return;
  }


  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_MALLOCTEST, false, false, &extraParamsFound ) )
  {
    PrintStr( "Allocalling memory..." EOL );

    volatile uint32_t * const volatile mallocTest = (volatile uint32_t *) malloc(123);
    *mallocTest = 123;

    PrintStr( "Releasing memory..." EOL );

    free( const_cast< uint32_t * >( mallocTest ) );

    PrintStr( "Test finished." EOL );

    return;
  }


  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_CPP_EXCEPTION_TEST, false, false, &extraParamsFound ) )
  {
    try
    {
      PrintStr( "Throwing integer exception..." EOL );
      throw 123;
      PrintStr( "Throw did not work." EOL );
      assert( false );
    }
    catch ( ... )
    {
      PrintStr( "Caught integer exception." EOL );
    }
    PrintStr( "Test finished." EOL );

    return;
  }


  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_SIMULATE_ERROR, false, true, &extraParamsFound ) )
  {
    SimulateError( paramBegin );
    return;
  }


  if ( IsCmd( cmdBegin, cmdEnd, CMDNAME_MEMORY_USAGE, false, false, &extraParamsFound ) )
  {
    const unsigned heapSize = unsigned( GetHeapEndAddr() - uintptr_t( &_end ) );

    Printf( "Partitions: malloc heap: %u bytes, free: %u bytes, stack: %u bytes." EOL,
               heapSize,
               GetStackStartAddr() - GetHeapEndAddr(),
               STACK_SIZE );

    Printf( "Used stack (estimated): %u from %u bytes." EOL,
               unsigned( GetStackSizeUsageEstimate() ),
               STACK_SIZE );

    const struct mallinfo mi = mallinfo();
    const unsigned heapSizeAccordingToNewlib = unsigned( mi.arena );

    Printf( "Heap: %u allocated from %u bytes." EOL,
               unsigned( mi.uordblks ),
               unsigned( mi.arena ) );

    assert( heapSize == heapSizeAccordingToNewlib );
    UNUSED_IN_RELEASE( heapSizeAccordingToNewlib );

    return;
  }

  if ( extraParamsFound )
    Printf( "Command \"%.*s\" does not take any parameters." EOL, cmdEnd - cmdBegin, cmdBegin );
  else
    Printf( "Unknown command \"%.*s\"." EOL, cmdEnd - cmdBegin, cmdBegin );
}