90#include "rusEfiFunctionalTest.h"
96 efiPrintf(
"TunerStudio size=%d / total=%d / errors=%d / H=%d / O=%d / P=%d / B=%d",
101 efiPrintf(
"TunerStudio errors: underrun=%d / overrun=%d / crc=%d / unrecognized=%d / outofrange=%d / other=%d",
107 efiPrintf(
"Scatter list (global)");
108 for (
int i = 0; i < HIGH_SPEED_COUNT; i++) {
110 uint16_t type = packed >> 13;
111 uint16_t offset = packed & 0x1FFF;
115 size_t size = 1 << (type - 1);
117 efiPrintf(
"%02d offset 0x%04x size %d", i, offset,
size);
122#define TS_COMMUNICATION_TIMEOUT TIME_MS2I(1000)
124#define TS_COMMUNICATION_TIMEOUT_SHORT TIME_MS2I(10)
131#ifdef EFI_CONSOLE_RX_BRAIN_PIN
132 efiPrintf(
"Primary UART RX %s",
hwPortname(EFI_CONSOLE_RX_BRAIN_PIN));
133 efiPrintf(
"Primary UART TX %s",
hwPortname(EFI_CONSOLE_TX_BRAIN_PIN));
151#if EFI_TUNER_STUDIO_VERBOSE
152 efiPrintf(
"%s: %s", tsChannel->
name, msg);
170 case TS_RESPONSE_UNDERRUN:
173 case TS_RESPONSE_OVERRUN:
176 case TS_RESPONSE_CRC_FAILURE:
179 case TS_RESPONSE_UNRECOGNIZED_COMMAND:
182 case TS_RESPONSE_OUT_OF_RANGE:
218 efiPrintf(
"TS -> Page %d write chunk offset %d count %d (output_count=%d)",
223 sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND,
"locked");
236 memcpy(
addr, content, count);
243 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE,
"ERROR: WR invalid page");
276 efiPrintf(
"TS <- Get CRC offset %d count %d result %08x", offset, count, (
unsigned int)crc);
281 int totalResponseSize = 0;
282 for (
int i = 0; i < HIGH_SPEED_COUNT; i++) {
284 uint16_t type = packed >> 13;
286 size_t size = type == 0 ? 0 : 1 << (type - 1);
290 totalResponseSize +=
size;
300 uint8_t dataBuffer[8];
301 for (
int i = 0; i < HIGH_SPEED_COUNT; i++) {
303 uint16_t type = packed >> 13;
304 uint16_t offset = packed & 0x1FFF;
308 size_t size = 1 << (type - 1);
312 tsChannel->
write(dataBuffer,
size,
false);
313 crc = crc32inc((
void*)dataBuffer, crc,
size);
320 tsChannel->
write(
reinterpret_cast<uint8_t*
>(dataBuffer), 4,
true);
328 efiPrintf(
"TS <- Page %d read chunk offset %d count %d", page, offset, count);
341 memset(
addr, 0, count);
346#if EFI_TUNER_STUDIO_VERBOSE
350 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE,
"ERROR: RD invalid page");
359#if EFI_CONFIGURATION_STORAGE
368 Timer calibrationsWriteTimer;
380 efiPrintf(
"TS -> Burn");
389 efiPrintf(
"Burned in %.1fms", t.getElapsedSeconds() * 1e3);
392#if (EFI_PROD_CODE || EFI_SIMULATOR)
395 return command == TS_HELLO_COMMAND || command == TS_READ_COMMAND || command == TS_OUTPUT_COMMAND
396 || command == TS_BURN_COMMAND || command == TS_SINGLE_WRITE_COMMAND
397 || command == TS_CHUNK_WRITE_COMMAND || command == TS_EXECUTE
398 || command == TS_IO_TEST_COMMAND
400 || command == TS_SIMULATE_CAN
403 || command == TS_GET_SCATTERED_GET_COMMAND
405 || command == TS_SET_LOGGER_SWITCH
406 || command == TS_GET_COMPOSITE_BUFFER_DONE_DIFFERENTLY
407 || command == TS_GET_TEXT
408 || command == TS_CRC_CHECK_COMMAND
409 || command == TS_GET_FIRMWARE_VERSION
410 || command == TS_PERF_TRACE_BEGIN
411 || command == TS_PERF_TRACE_GET_BUFFER
412 || command == TS_GET_CONFIG_ERROR
413 || command == TS_QUERY_BOOTLOADER;
421 char testOutputBuffer[64];
427 tsChannel->
write((
const uint8_t*)QUOTE(SIGNATURE_HASH),
sizeof(QUOTE(SIGNATURE_HASH)));
430 tsChannel->
write((
const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
432 chsnprintf(testOutputBuffer,
sizeof(testOutputBuffer),
" uptime=%ds ", (
int)
getTimeNowS());
433 tsChannel->
write((
const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
435 chsnprintf(testOutputBuffer,
sizeof(testOutputBuffer), __DATE__
" %s\r\n", PROTOCOL_TEST_RESPONSE_TAG);
436 tsChannel->
write((
const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
438 if (hasFirmwareError()) {
440 chsnprintf(testOutputBuffer,
sizeof(testOutputBuffer),
"error=%s\r\n", error);
441 tsChannel->
write((
const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
456 efiPrintf(
"TS <- Query signature: %s", signature);
457 tsChannel->
sendResponse(mode, (
const uint8_t *)signature, strlen(signature) + 1);
469 }
else if (command == TS_HELLO_COMMAND || command == TS_QUERY_COMMAND) {
471 efiPrintf(
"Got naked Query command");
474 }
else if (command == TS_TEST_COMMAND || command ==
'T') {
477 }
else if (command == TS_COMMAND_F) {
487 tsChannel->
write((
const uint8_t *)TS_PROTOCOL, strlen(TS_PROTOCOL));
502 chThdSleepMilliseconds(10);
509 size_t received = tsChannel->
readTimeout(&firstByte, 1, TS_COMMUNICATION_TIMEOUT);
511 logMsg(
"received %d\r\n", received);
516#if EFI_BLUETOOTH_SETUP
533 received = tsChannel->
readTimeout(&secondByte, 1, TS_COMMUNICATION_TIMEOUT_SHORT);
540 uint16_t incomingPacketSize = firstByte << 8 | secondByte;
541 size_t expectedSize = incomingPacketSize + TS_PACKET_TAIL_SIZE;
543 if ((incomingPacketSize == 0) || (expectedSize >
sizeof(tsChannel->
scratchBuffer))) {
545 efiPrintf(
"process_ts: channel=%s invalid size: %d", tsChannel->
name, incomingPacketSize);
548 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE,
"invalid size");
561 if (received != expectedSize) {
563 efiPrintf(
"Got only %d bytes while expecting %d for command 0x%02x", received,
564 expectedSize, command);
574 efiPrintf(
"unexpected command %x", command);
575 sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND,
"unknown");
589 received = tsChannel->
readTimeout((uint8_t*)(tsChannel->
scratchBuffer) + 1, expectedSize - 1, TS_COMMUNICATION_TIMEOUT);
590 if (received != expectedSize - 1) {
597 logMsg(
"command %c\r\n", command);
600 uint32_t expectedCrc = *(uint32_t*) (tsChannel->
scratchBuffer + incomingPacketSize);
604 uint32_t actualCrc = crc32(tsChannel->
scratchBuffer, incomingPacketSize);
605 if (actualCrc != expectedCrc) {
608 efiPrintf(
"TunerStudio: command %c actual CRC %x/expected %x", tsChannel->
scratchBuffer[0],
609 (
unsigned int)actualCrc, (
unsigned int)expectedCrc);
611 sendErrorCode(tsChannel, TS_RESPONSE_CRC_FAILURE,
"crc_issue");
623 efiPrintf(
"got unexpected TunerStudio command %x:%c", command, command);
657#if EFI_PROD_CODE || EFI_SIMULATOR
664 char versionBuffer[32];
665 chsnprintf(versionBuffer,
sizeof(versionBuffer),
"%s v%d@%u", FRONTEND_TITLE_BAR_NAME,
getRusEfiVersion(), SIGNATURE_HASH);
666 tsChannel->
sendResponse(
TS_CRC, (
const uint8_t *) versionBuffer, strlen(versionBuffer) + 1);
678 logMsg(
"get test sending [%d]\r\n", outputSize);
681 tsChannel->
writeCrcPacket(TS_RESPONSE_OK,
reinterpret_cast<const uint8_t*
>(output), outputSize,
true);
683 logMsg(
"sent [%d]\r\n", outputSize);
689 data[incomingPacketSize] = 0;
692 logMsg(
"execute [%s]\r\n", trimmed);
702 char command = data[0];
705 const uint16_t* data16 =
reinterpret_cast<uint16_t*
>(data);
714 if (incomingPacketSize >= 3) {
718 if (incomingPacketSize >= 5) {
724 case TS_OUTPUT_COMMAND:
725 if (incomingPacketSize == 1) {
727 count = TS_TOTAL_OUTPUT_SIZE;
731 case TS_OUTPUT_ALL_COMMAND:
733 count = TS_TOTAL_OUTPUT_SIZE;
737 case TS_HELLO_COMMAND:
741 case TS_GET_FIRMWARE_VERSION:
752 case TS_CHUNK_WRITE_COMMAND:
755 calibrationsWriteTimer.reset();
757 case TS_SINGLE_WRITE_COMMAND:
762 calibrationsWriteTimer.reset();
764 case TS_GET_SCATTERED_GET_COMMAND:
768 criticalError(
"Slow/wireless mode not supported");
771 case TS_CRC_CHECK_COMMAND:
774 case TS_BURN_COMMAND:
777 case TS_READ_COMMAND:
781 case TS_TEST_COMMAND:
787 case TS_SIMULATE_CAN:
788 void handleWrapCan(
TsChannelBase* tsChannel,
char *data,
int incomingPacketSize);
789 handleWrapCan(tsChannel, data, incomingPacketSize - 1);
792 case TS_IO_TEST_COMMAND:
804 case TS_SET_LOGGER_SWITCH:
806 case TS_COMPOSITE_ENABLE:
809 case TS_COMPOSITE_DISABLE:
812 case TS_COMPOSITE_READ:
822 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, DO_NOT_LOG);
827 case TS_TRIGGER_SCOPE_ENABLE:
830 case TS_TRIGGER_SCOPE_DISABLE:
833 case TS_TRIGGER_SCOPE_READ:
841 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, DO_NOT_LOG);
854 case TS_GET_COMPOSITE_BUFFER_DONE_DIFFERENTLY:
866 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, DO_NOT_LOG);
872 case TS_GET_COMPOSITE_BUFFER_DONE_DIFFERENTLY:
873 sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE, DO_NOT_LOG);
877 case TS_PERF_TRACE_BEGIN:
881 case TS_PERF_TRACE_GET_BUFFER:
889 case TS_PERF_TRACE_BEGIN:
890 criticalError(
"TS_PERF_TRACE not supported");
892 case TS_PERF_TRACE_GET_BUFFER:
893 criticalError(
"TS_PERF_TRACE_GET_BUFFER not supported");
896 case TS_GET_CONFIG_ERROR: {
901 case TS_QUERY_BOOTLOADER: {
902 uint8_t bldata = TS_QUERY_BOOTLOADER_NONE;
904 bldata = TS_QUERY_BOOTLOADER_OPENBLT;
911 sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND,
"unknown_command");
912static char tsErrorBuff[80];
913 chsnprintf(tsErrorBuff,
sizeof(tsErrorBuff),
"ERROR: ignoring unexpected command %d [%c]", command, command);
930 static_assert(
sizeof(
persistent_config_s) == TOTAL_CONFIG_SIZE,
"TS datapage size mismatch");
942#if EFI_BLUETOOTH_SETUP
947 addConsoleActionSSS(
"bluetooth_hc05", [](
const char *baudRate,
const char *name,
const char *pinCode) {
950 addConsoleActionSSS(
"bluetooth_hc06", [](
const char *baudRate,
const char *name,
const char *pinCode) {
953 addConsoleActionSSS(
"bluetooth_bk", [](
const char *baudRate,
const char *name,
const char *pinCode) {
956 addConsoleActionSSS(
"bluetooth_jdy", [](
const char *baudRate,
const char *name,
const char *pinCode) {
959 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
Timer engineTypeChangeTimer
TunerStudioOutputChannels outputChannels
WarningCodeState warnings
virtual bool isReady() const
char scratchBuffer[scratchBuffer_SIZE+30]
uint32_t writePacketHeader(const uint8_t responseCode, const size_t size)
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)
static uint8_t getUserEnteredTuningDetector()
static bool isTuningDetectorUndefined()
void sendErrorCode(TsChannelBase *tsChannel, uint8_t code, const char *msg="")
void handleScatteredReadCommand(TsChannelBase *tsChannel)
bool handlePlainCommand(TsChannelBase *tsChannel, uint8_t command)
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 handlePageReadCommand(TsChannelBase *tsChannel, uint16_t page, uint16_t offset, uint16_t count)
void handleWriteChunkCommand(TsChannelBase *tsChannel, uint16_t page, uint16_t offset, uint16_t count, void *content)
int handleCrcCommand(TsChannelBase *tsChannel, char *data, int incomingPacketSize)
void handleExecuteCommand(TsChannelBase *tsChannel, char *data, int incomingPacketSize)
virtual TsChannelBase * setupChannel()=0
void ThreadTask() override
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)
static Engine *const engine
static constexpr engine_configuration_s * engineConfiguration
bool validateConfigOnStartUpOrBurn()
const char * getCriticalErrorMessage()
void configError(const char *fmt,...)
const char * getConfigErrorMessage()
void setNeedToWriteConfiguration()
FragmentList getLiveDataFragments()
const char * swapOutputBuffers(size_t *actualOutputBufferSize)
This data structure holds current malfunction codes.
@ STACK_USAGE_COMMUNICATION
const BigBufferHandle perfTraceGetBuffer()
@ TunerStudioHandleCrcCommand
const char * hwPortname(brain_pin_e brainPin)
const char * getTsSignature()
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)
bool needToTriggerTsRefresh()
static void handleGetVersion(TsChannelBase *tsChannel)
tunerstudio_counters_s tsState
PUBLIC_API_WEAK bool isBoardAskingTriggerTsRefresh()
static void setTsSpeed(int value)
CommandHandler console_line_callback
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)
void startTunerStudioConnectivity()
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()
static void printTsStats(void)
uint8_t * getWorkingPageAddr()
void tunerStudioError(TsChannelBase *tsChannel, const char *msg)
SerialTsChannelBase * getBluetoothChannel()