static bool handlePlainCommand(uint8_t command) { if (command == TS_HELLO_COMMAND) { scheduleMsg(&logger, "Got naked Query command"); handleQueryCommand(TS_PLAIN); return true; } else if (command == 't' || command == 'T') { handleTestCommand(); return true; } else if (command == TS_PAGE_COMMAND) { int recieved = chSequentialStreamRead(getTsSerialDevice(), (uint8_t *)&pageIn, sizeof(pageIn)); // todo: validate 'recieved' value handlePageSelectCommand(TS_PLAIN, pageIn); return true; } else if (command == TS_READ_COMMAND) { //scheduleMsg(&logger, "Got naked READ PAGE???"); int recieved = chSequentialStreamRead(getTsSerialDevice(), (uint8_t *)&readRequest, sizeof(readRequest)); if (recieved != sizeof(readRequest)) { // todo: handler error return true; } handlePageReadCommand(TS_PLAIN, readRequest.page, readRequest.offset, readRequest.count); return true; } else if (command == TS_OUTPUT_COMMAND) { //scheduleMsg(&logger, "Got naked Channels???"); handleOutputChannelsCommand(TS_PLAIN); return true; } else if (command == 'F') { tunerStudioDebug("not ignoring F"); tunerStudioWriteData((const uint8_t *) PROTOCOL, strlen(PROTOCOL)); return true; } else { return false; } }
void startTunerStudioConnectivity(void) { if (sizeof(persistent_config_s) != getTunerStudioPageSize(0)) firmwareError("TS page size mismatch: %d/%d", sizeof(persistent_config_s), getTunerStudioPageSize(0)); if (sizeof(TunerStudioOutputChannels) != TS_OUTPUT_SIZE) firmwareError("TS outputs size mismatch: %d/%d", sizeof(TunerStudioOutputChannels), TS_OUTPUT_SIZE); memset(&tsState, 0, sizeof(tsState)); syncTunerStudioCopy(); addConsoleAction("tsinfo", printTsStats); addConsoleAction("reset_ts", resetTs); addConsoleActionI("set_ts_speed", setTsSpeed); tsChannel.channel = getTsSerialDevice(); tsChannel.writeBuffer = tsCrcWriteBuffer; chThdCreateStatic(tsThreadStack, sizeof(tsThreadStack), NORMALPRIO, tsThreadEntryPoint, NULL); }
static msg_t tsThreadEntryPoint(void *arg) { (void) arg; chRegSetThreadName("tunerstudio thread"); int wasReady = false; while (true) { int isReady = ts_serail_ready(); if (!isReady) { chThdSleepMilliseconds(10); wasReady = false; continue; } if (!wasReady) { wasReady = TRUE; // scheduleSimpleMsg(&logger, "ts channel is now ready ", hTimeNow()); } tsCounter++; int recieved = chSequentialStreamRead(getTsSerialDevice(), &firstByte, 1); if (recieved != 1) { tunerStudioError("ERROR: no command"); continue; } // scheduleMsg(&logger, "Got first=%x=[%c]", firstByte, firstByte); if (handlePlainCommand(firstByte)) continue; recieved = chSequentialStreamRead(getTsSerialDevice(), &secondByte, 1); if (recieved != 1) { tunerStudioError("ERROR: no second"); continue; } // scheduleMsg(&logger, "Got secondByte=%x=[%c]", secondByte, secondByte); uint32_t incomingPacketSize = firstByte * 256 + secondByte; if (incomingPacketSize == 0 || incomingPacketSize > (sizeof(crcIoBuffer) - CRC_WRAPPING_SIZE)) { scheduleMsg(&logger, "TunerStudio: invalid size: %d", incomingPacketSize); tunerStudioError("ERROR: size"); sendErrorCode(); continue; } recieved = chnReadTimeout(getTsSerialDevice(), crcIoBuffer, 1, MS2ST(TS_READ_TIMEOUT)); if (recieved != 1) { tunerStudioError("ERROR: did not receive command"); continue; } char command = crcIoBuffer[0]; if (!isKnownCommand(command)) { scheduleMsg(&logger, "unexpected command %x", command); sendErrorCode(); continue; } // scheduleMsg(&logger, "TunerStudio: reading %d+4 bytes(s)", incomingPacketSize); recieved = chnReadTimeout(getTsSerialDevice(), (uint8_t * ) (crcIoBuffer + 1), incomingPacketSize + CRC_VALUE_SIZE - 1, MS2ST(TS_READ_TIMEOUT)); int expectedSize = incomingPacketSize + CRC_VALUE_SIZE - 1; if (recieved != expectedSize) { scheduleMsg(&logger, "got ONLY %d for packet size %d/%d for command %c", recieved, incomingPacketSize, expectedSize, command); tunerStudioError("ERROR: not enough"); continue; } uint32_t expectedCrc = *(uint32_t*) (crcIoBuffer + incomingPacketSize); expectedCrc = SWAP_UINT32(expectedCrc); uint32_t actualCrc = crc32(crcIoBuffer, incomingPacketSize); if (actualCrc != expectedCrc) { scheduleMsg(&logger, "TunerStudio: CRC %x %x %x %x", crcIoBuffer[incomingPacketSize + 0], crcIoBuffer[incomingPacketSize + 1], crcIoBuffer[incomingPacketSize + 2], crcIoBuffer[incomingPacketSize + 3]); scheduleMsg(&logger, "TunerStudio: command %c actual CRC %x/expected %x", crcIoBuffer[0], actualCrc, expectedCrc); tunerStudioError("ERROR: CRC issue"); continue; } // scheduleMsg(&logger, "TunerStudio: P00-07 %x %x %x %x %x %x %x %x", crcIoBuffer[0], crcIoBuffer[1], // crcIoBuffer[2], crcIoBuffer[3], crcIoBuffer[4], crcIoBuffer[5], crcIoBuffer[6], crcIoBuffer[7]); int success = tunerStudioHandleCrcCommand(crcIoBuffer, incomingPacketSize); if (!success) print("got unexpected TunerStudio command %x:%c\r\n", command, command); } #if defined __GNUC__ return 0; #endif }
void tunerStudioWriteData(const uint8_t * buffer, int size) { chSequentialStreamWrite(getTsSerialDevice(), buffer, size); }