88 #include "rusEfiFunctionalTest.h"
94 efiPrintf(
"TunerStudio size=%d / total=%d / errors=%d / H=%d / O=%d / P=%d / B=%d",
99 efiPrintf(
"TunerStudio errors: underrun=%d / overrun=%d / crc=%d / unrecognized=%d / outofrange=%d / other=%d",
105 efiPrintf(
"Scatter list (global)");
106 for (
int i = 0; i < HIGH_SPEED_COUNT; i++) {
108 uint16_t type = packed >> 13;
109 uint16_t offset = packed & 0x1FFF;
113 size_t size = 1 << (type - 1);
115 efiPrintf(
"%02d offset 0x%04x size %d", i, offset,
size);
120 #define TS_COMMUNICATION_TIMEOUT TIME_MS2I(1000)
122 #define TS_COMMUNICATION_TIMEOUT_SHORT TIME_MS2I(10)
129 #ifdef EFI_CONSOLE_RX_BRAIN_PIN
130 efiPrintf(
"Primary UART RX %s",
hwPortname(EFI_CONSOLE_RX_BRAIN_PIN));
131 efiPrintf(
"Primary UART TX %s",
hwPortname(EFI_CONSOLE_TX_BRAIN_PIN));
149 #if EFI_TUNER_STUDIO_VERBOSE
150 efiPrintf(
"%s: %s", tsChannel->
name, msg);
168 case TS_RESPONSE_UNDERRUN:
171 case TS_RESPONSE_OVERRUN:
174 case TS_RESPONSE_CRC_FAILURE:
177 case TS_RESPONSE_UNRECOGNIZED_COMMAND:
180 case TS_RESPONSE_OUT_OF_RANGE:
198 efiPrintf(
"TS -> Set page (no-op)");
215 sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND,
"locked");
228 memcpy(
addr, content, count);
263 efiPrintf(
"TS <- Get CRC offset %d count %d result %08x", offset, count, (
unsigned int)crc);
268 int totalResponseSize = 0;
269 for (
int i = 0; i < HIGH_SPEED_COUNT; i++) {
271 uint16_t type = packed >> 13;
273 size_t size = type == 0 ? 0 : 1 << (type - 1);
277 totalResponseSize +=
size;
287 uint8_t dataBuffer[8];
288 for (
int i = 0; i < HIGH_SPEED_COUNT; i++) {
290 uint16_t type = packed >> 13;
291 uint16_t offset = packed & 0x1FFF;
295 size_t size = 1 << (type - 1);
299 tsChannel->
write(dataBuffer,
size,
false);
300 crc = crc32inc((
void*)dataBuffer, crc,
size);
307 tsChannel->
write(
reinterpret_cast<uint8_t*
>(dataBuffer), 4,
true);
321 sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND,
"locked");
325 efiPrintf(
"TS -> Write value offset %d value %d", offset, value);
343 sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND,
"reboot");
347 efiPrintf(
"TS <- Read chunk offset %d count %d", offset, count);
357 memset(
addr, 0, count);
362 #if EFI_TUNER_STUDIO_VERBOSE
372 #if EFI_CONFIGURATION_STORAGE
389 efiPrintf(
"TS -> Burn");
398 efiPrintf(
"Burned in %.1fms", t.getElapsedSeconds() * 1e3);
401 #if (EFI_PROD_CODE || EFI_SIMULATOR)
404 return command == TS_HELLO_COMMAND || command == TS_READ_COMMAND || command == TS_OUTPUT_COMMAND
405 || command == TS_PAGE_COMMAND || command == TS_BURN_COMMAND || command == TS_SINGLE_WRITE_COMMAND
406 || command == TS_CHUNK_WRITE_COMMAND || command == TS_EXECUTE
407 || command == TS_IO_TEST_COMMAND
409 || command == TS_SIMULATE_CAN
412 || command == TS_GET_SCATTERED_GET_COMMAND
414 || command == TS_SET_LOGGER_SWITCH
415 || command == TS_GET_COMPOSITE_BUFFER_DONE_DIFFERENTLY
416 || command == TS_GET_TEXT
417 || command == TS_CRC_CHECK_COMMAND
418 || command == TS_GET_FIRMWARE_VERSION
419 #ifdef KNOCK_SPECTROGRAM
420 || command == TS_KNOCK_SPECTROGRAM_ENABLE
421 || command == TS_KNOCK_SPECTROGRAM_DISABLE
423 || command == TS_PERF_TRACE_BEGIN
424 || command == TS_PERF_TRACE_GET_BUFFER
425 || command == TS_GET_CONFIG_ERROR
426 || command == TS_QUERY_BOOTLOADER;
434 char testOutputBuffer[64];
440 tsChannel->
write((
const uint8_t*)QUOTE(SIGNATURE_HASH),
sizeof(QUOTE(SIGNATURE_HASH)));
443 tsChannel->
write((
const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
445 chsnprintf(testOutputBuffer,
sizeof(testOutputBuffer),
" uptime=%ds ", (
int)
getTimeNowS());
446 tsChannel->
write((
const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
448 chsnprintf(testOutputBuffer,
sizeof(testOutputBuffer), __DATE__
" %s\r\n", PROTOCOL_TEST_RESPONSE_TAG);
449 tsChannel->
write((
const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
451 if (hasFirmwareError()) {
453 chsnprintf(testOutputBuffer,
sizeof(testOutputBuffer),
"error=%s\r\n", error);
454 tsChannel->
write((
const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
469 efiPrintf(
"TS <- Query signature: %s", signature);
470 tsChannel->
sendResponse(mode, (
const uint8_t *)signature, strlen(signature) + 1);
482 }
else if (command == TS_HELLO_COMMAND || command == TS_QUERY_COMMAND) {
484 efiPrintf(
"Got naked Query command");
487 }
else if (command == TS_TEST_COMMAND || command ==
'T') {
490 }
else if (command == TS_COMMAND_F) {
500 tsChannel->
write((
const uint8_t *)TS_PROTOCOL, strlen(TS_PROTOCOL));
515 chThdSleepMilliseconds(10);
522 size_t received = tsChannel->
readTimeout(&firstByte, 1, TS_COMMUNICATION_TIMEOUT);
524 logMsg(
"received %d\r\n", received);
529 #if EFI_BLUETOOTH_SETUP
546 received = tsChannel->
readTimeout(&secondByte, 1, TS_COMMUNICATION_TIMEOUT_SHORT);
553 uint16_t incomingPacketSize = firstByte << 8 | secondByte;
554 size_t expectedSize = incomingPacketSize + TS_PACKET_TAIL_SIZE;
556 if ((incomingPacketSize == 0) || (expectedSize >
sizeof(tsChannel->
scratchBuffer))) {
558 efiPrintf(
"process_ts: channel=%s invalid size: %d", tsChannel->
name, incomingPacketSize);
561 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE,
"invalid size");
574 if (received != expectedSize) {
576 efiPrintf(
"Got only %d bytes while expecting %d for command 0x%02x", received,
577 expectedSize, command);
587 efiPrintf(
"unexpected command %x", command);
588 sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND,
"unknown");
602 received = tsChannel->
readTimeout((uint8_t*)(tsChannel->
scratchBuffer) + 1, expectedSize - 1, TS_COMMUNICATION_TIMEOUT);
603 if (received != expectedSize - 1) {
610 logMsg(
"command %c\r\n", command);
613 uint32_t expectedCrc = *(uint32_t*) (tsChannel->
scratchBuffer + incomingPacketSize);
617 uint32_t actualCrc = crc32(tsChannel->
scratchBuffer, incomingPacketSize);
618 if (actualCrc != expectedCrc) {
621 efiPrintf(
"TunerStudio: command %c actual CRC %x/expected %x", tsChannel->
scratchBuffer[0],
622 (
unsigned int)actualCrc, (
unsigned int)expectedCrc);
624 sendErrorCode(tsChannel, TS_RESPONSE_CRC_FAILURE,
"crc_issue");
636 efiPrintf(
"got unexpected TunerStudio command %x:%c", command, command);
670 #if EFI_PROD_CODE || EFI_SIMULATOR
677 char versionBuffer[32];
678 chsnprintf(versionBuffer,
sizeof(versionBuffer),
"%s v%d@%u", FRONTEND_TITLE_BAR_NAME,
getRusEfiVersion(), SIGNATURE_HASH);
679 tsChannel->
sendResponse(
TS_CRC, (
const uint8_t *) versionBuffer, strlen(versionBuffer) + 1);
691 logMsg(
"get test sending [%d]\r\n", outputSize);
694 tsChannel->
writeCrcPacket(TS_RESPONSE_OK,
reinterpret_cast<const uint8_t*
>(output), outputSize,
true);
696 logMsg(
"sent [%d]\r\n", outputSize);
702 data[incomingPacketSize] = 0;
705 logMsg(
"execute [%s]\r\n", trimmed);
715 char command = data[0];
718 const uint16_t* data16 =
reinterpret_cast<uint16_t*
>(data);
725 if (incomingPacketSize >= 3) {
729 if (incomingPacketSize >= 5) {
735 case TS_OUTPUT_COMMAND:
736 if (incomingPacketSize == 1) {
738 count = TS_TOTAL_OUTPUT_SIZE;
742 case TS_HELLO_COMMAND:
746 case TS_GET_FIRMWARE_VERSION:
757 case TS_PAGE_COMMAND:
760 case TS_CHUNK_WRITE_COMMAND:
763 case TS_SINGLE_WRITE_COMMAND:
765 uint8_t value = data[4];
769 case TS_GET_SCATTERED_GET_COMMAND:
773 criticalError(
"Slow/wireless mode not supported");
776 case TS_CRC_CHECK_COMMAND:
779 case TS_BURN_COMMAND:
782 case TS_READ_COMMAND:
785 case TS_TEST_COMMAND:
791 case TS_SIMULATE_CAN:
792 void handleWrapCan(
TsChannelBase* tsChannel,
char *data,
int incomingPacketSize);
793 handleWrapCan(tsChannel, data, incomingPacketSize - 1);
796 case TS_IO_TEST_COMMAND:
808 case TS_SET_LOGGER_SWITCH:
810 case TS_COMPOSITE_ENABLE:
813 case TS_COMPOSITE_DISABLE:
816 case TS_COMPOSITE_READ:
826 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, DO_NOT_LOG);
831 case TS_TRIGGER_SCOPE_ENABLE:
834 case TS_TRIGGER_SCOPE_DISABLE:
837 case TS_TRIGGER_SCOPE_READ:
845 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, DO_NOT_LOG);
858 case TS_GET_COMPOSITE_BUFFER_DONE_DIFFERENTLY:
870 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, DO_NOT_LOG);
876 case TS_GET_COMPOSITE_BUFFER_DONE_DIFFERENTLY:
877 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, DO_NOT_LOG);
880 #ifdef KNOCK_SPECTROGRAM
881 case TS_KNOCK_SPECTROGRAM_ENABLE:
885 case TS_KNOCK_SPECTROGRAM_DISABLE:
890 #if ENABLE_PERF_TRACE
891 case TS_PERF_TRACE_BEGIN:
895 case TS_PERF_TRACE_GET_BUFFER:
903 case TS_GET_CONFIG_ERROR: {
907 if (!hasFirmwareError()) {
908 strcpy((
char*)configError,
"FACTORY_MODE_PLEASE_CONTACT_SUPPORT");
911 tsChannel->
sendResponse(
TS_CRC,
reinterpret_cast<const uint8_t*
>(configError), strlen(configError),
true);
914 case TS_QUERY_BOOTLOADER: {
915 uint8_t bldata = TS_QUERY_BOOTLOADER_NONE;
917 bldata = TS_QUERY_BOOTLOADER_OPENBLT;
924 sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND,
"unknown_command");
925 static char tsErrorBuff[80];
926 chsnprintf(tsErrorBuff,
sizeof(tsErrorBuff),
"ERROR: ignoring unexpected command %d [%c]", command, command);
938 static_assert(
sizeof(
persistent_config_s) == TOTAL_CONFIG_SIZE,
"TS datapage size mismatch");
950 #if EFI_BLUETOOTH_SETUP
955 addConsoleActionSSS(
"bluetooth_hc05", [](
const char *baudRate,
const char *name,
const char *pinCode) {
958 addConsoleActionSSS(
"bluetooth_hc06", [](
const char *baudRate,
const char *name,
const char *pinCode) {
961 addConsoleActionSSS(
"bluetooth_bk", [](
const char *baudRate,
const char *name,
const char *pinCode) {
964 addConsoleActionSSS(
"bluetooth_jdy", [](
const char *baudRate,
const char *name,
const char *pinCode) {
967 addConsoleActionSSS(
"bluetooth_jdy31", [](
const char *baudRate,
const char *name,
const char *pinCode) {
void setBoardConfigOverrides()
void executeTSCommand(uint16_t subsystem, uint16_t index)
Utility methods related to bench testing.
void bluetoothSoftwareDisconnectNotify(SerialTsChannelBase *tsChannel)
void bluetoothStart(bluetooth_module_e moduleType, const char *baudRate, const char *name, const char *pinCode)
const TBuffer * get() const
TunerStudioOutputChannels outputChannels
WarningCodeState warnings
virtual bool isReady() const
uint32_t writePacketHeader(const uint8_t responseCode, const size_t size)
char scratchBuffer[BLOCKING_FACTOR+30]
void writeCrcResponse(uint8_t responseCode)
virtual void writeCrcPacket(uint8_t responseCode, const uint8_t *buf, size_t size, bool allowLongPackets=false)
virtual void write(const uint8_t *buffer, size_t size, bool isEndOfPacket=false)=0
virtual size_t readTimeout(uint8_t *buffer, size_t size, int timeout)=0
void sendResponse(ts_response_format_e mode, const uint8_t *buffer, int size, bool allowLongPackets=false)
void sendErrorCode(TsChannelBase *tsChannel, uint8_t code, const char *msg="")
void handleScatteredReadCommand(TsChannelBase *tsChannel)
void handleWriteChunkCommand(TsChannelBase *tsChannel, uint16_t offset, uint16_t count, void *content)
bool handlePlainCommand(TsChannelBase *tsChannel, uint8_t command)
void handlePageSelectCommand(TsChannelBase *tsChannel)
void handleQueryCommand(TsChannelBase *tsChannel, ts_response_format_e mode)
void cmdOutputChannels(TsChannelBase *tsChannel, uint16_t offset, uint16_t count) override
'Output' command sends out a snapshot of current values Gauges refresh
void handleCrc32Check(TsChannelBase *tsChannel, uint16_t offset, uint16_t count)
void handleWriteValueCommand(TsChannelBase *tsChannel, uint16_t offset, uint8_t value)
void handlePageReadCommand(TsChannelBase *tsChannel, uint16_t offset, uint16_t count)
int handleCrcCommand(TsChannelBase *tsChannel, char *data, int incomingPacketSize)
void handleExecuteCommand(TsChannelBase *tsChannel, char *data, int incomingPacketSize)
void ThreadTask() override
virtual TsChannelBase * setupChannel()=0
void addConsoleAction(const char *token, Void callback)
Register console action without parameters.
void addConsoleActionSSS(const char *token, VoidCharPtrCharPtrCharPtr callback)
void addConsoleActionI(const char *token, VoidInt callback)
Register a console command with one Integer parameter.
void onDataArrived(bool valid)
void(* CommandHandler)(char *)
void printUsbConnectorStats()
char * efiTrim(char *param)
uint32_t SWAP_UINT32(uint32_t x)
uint16_t SWAP_UINT16(uint16_t x)
efitimesec_t getTimeNowS()
Current system time in seconds (32 bits)
bool validateConfigOnStartUpOrBurn()
const char * getCriticalErrorMessage(void)
int getRusEfiVersion(void)
void setNeedToWriteConfiguration()
UNUSED(samplingTimeSeconds)
FragmentList getLiveDataFragments()
const char * swapOutputBuffers(size_t *actualOutputBufferSize)
This data structure holds current malfunction codes.
@ STACK_USAGE_COMMUNICATION
const BigBufferHandle perfTraceGetBuffer()
@ TunerStudioHandleCrcCommand
engine_configuration_s * engineConfiguration
const char * hwPortname(brain_pin_e brainPin)
const char * getTsSignature()
void knockSpectrogramEnable()
void knockSpectrogramDisable()
void printOverallStatus()
uint32_t tunerStudioSerialSpeed
uint16_t highSpeedOffsets[HIGH_SPEED_COUNT]
int readPageCommandsCounter
int errorUnrecognizedCommand
int writeValueCommandCounter
int outputChannelsCommandCounter
int crc32CheckCommandCounter
int writeChunkCommandCounter
void DisableToothLogger()
CompositeBuffer * GetToothLoggerBufferNonblocking()
void ReturnToothLoggerBuffer(CompositeBuffer *buffer)
void EnableToothLoggerIfNotEnabled()
void triggerScopeEnable()
const BigBufferHandle & triggerScopeGetBuffer()
static BigBufferHandle buffer
void triggerScopeDisable()
static void handleBurnCommand(TsChannelBase *tsChannel)
static bool isKnownCommand(char command)
static void handleGetVersion(TsChannelBase *tsChannel)
tunerstudio_counters_s tsState
static void setTsSpeed(int value)
CommandHandler console_line_callback
void startTunerStudioConnectivity(void)
void sendErrorCode(TsChannelBase *tsChannel, uint8_t code, const char *msg)
static void printScatterList()
static void handleGetText(TsChannelBase *tsChannel)
bool validateOffsetCount(size_t offset, size_t count, TsChannelBase *tsChannel)
bool rebootForPresetPending
static void sendOkResponse(TsChannelBase *tsChannel)
static void handleTestCommand(TsChannelBase *tsChannel)
static int tsProcessOne(TsChannelBase *tsChannel)
void tunerStudioDebug(TsChannelBase *tsChannel, const char *msg)
static void printErrorCounters()
uint8_t * getWorkingPageAddr()
static void printTsStats(void)
void tunerStudioError(TsChannelBase *tsChannel, const char *msg)
SerialTsChannelBase * getBluetoothChannel()