static void ServiceUsbConnectionData ( const uint64_t currentTime ) { // We could write here a loop in order to process as much data as we can, // but we don't want to starve the main loop for too long. // // We must call the processing routine at least once, even if no data was sent or received, // in case there is a time-out to trigger. const bool atLeastOneByteReceived = ReceiveData(); if ( s_connectionStatus == csLastRxDataAfterConnectionLost && !atLeastOneByteReceived ) { s_connectionStatus = csNoConnection; UsbConnectionLost(); return; } BusPirateConnection_ProcessData( &s_usbRxBuffer, &s_usbTxBuffer, currentTime ); if ( s_connectionStatus == csLastRxDataAfterConnectionLost ) { // The connection is not there any more, drop all eventual data to send. s_usbTxBuffer.Reset(); // Continue reading until the end of data, when we will declare the connection as lost. WakeFromMainLoopSleep(); } else { const bool atLeastOneByteSent = SendData(); // If we have sent at least one byte of data, then there is more space available in the tx buffer, // which means that perhaps the next command already waiting in the rx buffer could be processed // straight away, for its reply would fit now in the tx buffer. if ( atLeastOneByteSent ) WakeFromMainLoopSleep(); } }
void CCommandProcessor::ProcessUsbSpeedTestCmd ( const char * const paramBegin, const uint64_t currentTime ) { // Examples about how to automate the speed test from the bash command line: // Tests where the Arduino Due is sending: // echo "UsbSpeedTest TxFastLoopRawUsb" | socat - /dev/jtagdue1,b115200,raw,echo=0,crnl | pv -pertb >/dev/null // Tests where the Arduino Due is receiving: // (echo "UsbSpeedTest RxWithCircularBuffer" && yes ".") | pv -pertb - | socat - /dev/jtagdue1,b115200,raw,echo=0,crnl >/dev/null const uint32_t TEST_TIME_IN_MS = 5000; // We could make a user parameter out of this value. if ( *paramBegin == 0 ) { PrintStr( "Please specify the test type as an argument:" EOL ); PrintStr( " TxSimpleWithTimestamps" EOL ); PrintStr( " TxSimpleLoop" EOL ); PrintStr( " TxFastLoopCircularBuffer" EOL ); PrintStr( " TxFastLoopRawUsb" EOL ); PrintStr( " RxWithCircularBuffer" EOL ); return; } const char * const paramEnd = SkipCharsNotInSet( paramBegin, SPACE_AND_TAB ); assert( g_usbSpeedTestType == stNone ); UsbSpeedTestEnum testType = stNone; bool extraParamsFound = false; if ( IsCmd( paramBegin, paramEnd, "TxSimpleWithTimestamps", false, false, &extraParamsFound ) ) testType = stTxSimpleWithTimestamps; else if ( IsCmd( paramBegin, paramEnd, "TxSimpleLoop", false, false, &extraParamsFound ) ) testType = stTxSimpleLoop; else if ( IsCmd( paramBegin, paramEnd, "TxFastLoopCircularBuffer", false, false, &extraParamsFound ) ) testType = stTxFastLoopCircularBuffer; else if ( IsCmd( paramBegin, paramEnd, "TxFastLoopRawUsb", false, false, &extraParamsFound ) ) testType = stTxFastLoopRawUsb; else if ( IsCmd( paramBegin, paramEnd, "RxWithCircularBuffer", false, false, &extraParamsFound ) ) testType = stRxWithCircularBuffer; if ( testType != stNone ) { for ( size_t i = 0; i < sizeof( g_usbSpeedTestBuffer ); ++i ) g_usbSpeedTestBuffer[ i ] = '.'; g_usbSpeedTestEndTime = currentTime + TEST_TIME_IN_MS; g_usbSpeedTestType = testType; // This message may not make it to the console, depending on the test type. PrintStr( "Starting USB speed test..." EOL ); WakeFromMainLoopSleep(); return; } if ( extraParamsFound ) Printf( "No parameters are allowed after test type \"%.*s\"." EOL, paramEnd - paramBegin, paramBegin ); else Printf( "Unknown test type \"%.*s\"." EOL, paramEnd - paramBegin, paramBegin ); }