Line data Source code
1 : /** 2 : * @file tunerstudio_io.h 3 : * @file TS protocol commands and methods are here 4 : * 5 : * @date Mar 8, 2015 6 : * @author Andrey Belomutskiy, (c) 2012-2020 7 : */ 8 : 9 : #pragma once 10 : #include "global.h" 11 : #include "tunerstudio_impl.h" 12 : 13 : #if EFI_USB_SERIAL 14 : #include "usbconsole.h" 15 : #endif // EFI_USB_SERIAL 16 : 17 : #if EFI_PROD_CODE 18 : #include "pin_repository.h" 19 : #endif 20 : 21 : #ifndef USART_CR2_STOP1_BITS 22 : // todo: acticulate why exactly does prometheus_469 as for this hack 23 : #define USART_CR2_STOP1_BITS 0 24 : #endif 25 : 26 : #define TS_PACKET_HEADER_SIZE 3 27 : #define TS_PACKET_TAIL_SIZE 4 28 : 29 : class TsChannelBase { 30 : public: 31 : TsChannelBase(const char *name); 32 : // Virtual functions - implement these for your underlying transport 33 : virtual void write(const uint8_t* buffer, size_t size, bool isEndOfPacket = false) = 0; 34 : virtual size_t readTimeout(uint8_t* buffer, size_t size, int timeout) = 0; 35 : 36 : // These functions are optional to implement, not all channels need them 37 4 : virtual void flush() { } 38 0 : virtual bool isConfigured() const { return true; } 39 0 : virtual bool isReady() const { return true; } 40 0 : virtual void stop() { } 41 : 42 : // Base functions that use the above virtual implementation 43 : size_t read(uint8_t* buffer, size_t size); 44 : 45 : int bytesIn = 0; 46 : int bytesOut = 0; 47 : 48 : #ifdef EFI_CAN_SERIAL 49 : virtual // CAN device needs this function to be virtual for small-packet optimization 50 : #endif 51 : void writeCrcPacket(uint8_t responseCode, const uint8_t* buf, size_t size, bool allowLongPackets = false); 52 : void sendResponse(ts_response_format_e mode, const uint8_t * buffer, int size, bool allowLongPackets = false); 53 : 54 : /** 55 : * See 'blockingFactor' in rusefi.ini 56 : */ 57 : char scratchBuffer[BLOCKING_FACTOR + 30]; 58 : const char *name; 59 : 60 : void assertPacketSize(size_t size, bool allowLongPackets); 61 : uint32_t writePacketHeader(const uint8_t responseCode, const size_t size); 62 : void crcAndWriteBuffer(const uint8_t responseCode, const size_t size); 63 : void copyAndWriteSmallCrcPacket(uint8_t responseCode, const uint8_t* buf, size_t size); 64 : 65 : // Write a response code with no data 66 0 : void writeCrcResponse(uint8_t responseCode) { 67 0 : writeCrcPacketLarge(responseCode, nullptr, 0); 68 0 : } 69 : 70 : /* When TsChannel is in "not in sync" state tsProcessOne will silently try to find 71 : * begining of packet. 72 : * As soon as tsProcessOne was able to receive valid packet with valid size and crc 73 : * TsChannel becomes "in sync". That means it will react on any futher errors: it will 74 : * emit packet with error code and switch back to "not in sync" mode. 75 : * This insures that RE will send only one error message after lost of synchronization 76 : * with TS. 77 : * Also while in "not in sync" state - tsProcessOne will not try to receive whole packet 78 : * by one read. Instead after getting packet size it will try to receive one byte of 79 : * command and check if it is supported. */ 80 : bool in_sync = false; 81 : 82 : private: 83 : bool isBigPacket(size_t size); 84 : void writeCrcPacketLarge(uint8_t responseCode, const uint8_t* buf, size_t size); 85 : }; 86 : 87 : // This class represents a channel for a physical async serial poart 88 : class SerialTsChannelBase : public TsChannelBase { 89 : public: 90 : SerialTsChannelBase(const char *p_name) : TsChannelBase(p_name) {}; 91 : // Open the serial port with the specified baud rate 92 : virtual void start(uint32_t baud) = 0; 93 : }; 94 : 95 : #if HAL_USE_SERIAL 96 : // This class implements a ChibiOS Serial Driver 97 : class SerialTsChannel final : public SerialTsChannelBase { 98 : public: 99 : SerialTsChannel(SerialDriver& driver) : SerialTsChannelBase("Serial"), m_driver(&driver) { } 100 : 101 : void start(uint32_t baud) override; 102 : void stop() override; 103 : 104 : void write(const uint8_t* buffer, size_t size, bool isEndOfPacket) override; 105 : size_t readTimeout(uint8_t* buffer, size_t size, int timeout) override; 106 : 107 : private: 108 : SerialDriver* const m_driver; 109 : }; 110 : #endif // HAL_USE_SERIAL 111 : 112 : #if HAL_USE_UART 113 : // This class implements a ChibiOS UART Driver 114 : class UartTsChannel : public SerialTsChannelBase { 115 : public: 116 : UartTsChannel(UARTDriver& driver) : SerialTsChannelBase("UART"), m_driver(&driver) { } 117 : 118 : void start(uint32_t baud) override; 119 : void stop() override; 120 : 121 : void write(const uint8_t* buffer, size_t size, bool isEndOfPacket) override; 122 : size_t readTimeout(uint8_t* buffer, size_t size, int timeout) override; 123 : 124 : protected: 125 : UARTDriver* const m_driver; 126 : UARTConfig m_config; 127 : }; 128 : #endif // HAL_USE_UART 129 : 130 : // that's 1 second 131 : #define BINARY_IO_TIMEOUT TIME_MS2I(1000) 132 : 133 : // that's 1 second 134 : #define SR5_READ_TIMEOUT TIME_MS2I(1000) 135 : 136 : void startSerialChannels(); 137 : SerialTsChannelBase* getBluetoothChannel(); 138 : 139 : void startCanConsole();