From 248e9636db54dac87222cc83d376601f466b51cf Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Wed, 17 Mar 2021 05:39:13 -0700 Subject: [PATCH] extract CAN TS channel (#2469) * extract CAN channel * this is gross --- firmware/console/binary/ts_can_channel.cpp | 72 ++++++++++++++++++++++ firmware/console/binary/tunerstudio.mk | 1 + firmware/console/binary/tunerstudio_io.cpp | 48 --------------- firmware/console/binary/tunerstudio_io.h | 11 +++- 4 files changed, 81 insertions(+), 51 deletions(-) create mode 100644 firmware/console/binary/ts_can_channel.cpp diff --git a/firmware/console/binary/ts_can_channel.cpp b/firmware/console/binary/ts_can_channel.cpp new file mode 100644 index 0000000000..17079672ec --- /dev/null +++ b/firmware/console/binary/ts_can_channel.cpp @@ -0,0 +1,72 @@ +// TODO: @andreika-git finish this implementation + +#include "tunerstudio_io.h" + +#ifdef TS_CAN_DEVICE +#include "serial_can.h" + +class CanTsChannel : public TsChannelBase { + void start(); + + // TsChannelBase implementation + void write(const uint8_t* buffer, size_t size) override; + size_t readTimeout(uint8_t* buffer, size_t size, int timeout) override; + void flush() override; + bool isReady() override; + void stop() override; + + // Special override for writeCrcPacket for small packets + void writeCrcPacket(uint8_t responseCode, const uint8_t* buf, size_t size) override; +}; + +static CANConfig tsCanConfig = { CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP, CAN_BTR_500 }; + +void CanTsChannel::start() { + efiSetPadMode("ts can rx", GPIOG_13/*CONFIG(canRxPin)*/, PAL_MODE_ALTERNATE(TS_CAN_AF)); // CAN2_RX2_0 + efiSetPadMode("ts can tx", GPIOG_14/*CONFIG(canTxPin)*/, PAL_MODE_ALTERNATE(TS_CAN_AF)); // CAN2_TX2_0 + + canStart(&TS_CAN_DEVICE, &tsCanConfig); + canInit(&TS_CAN_DEVICE); +} + +void CanTsChannel::stop() { + canStop(&TS_CAN_DEVICE); +} + +void CanTsChannel::writeCrcPacket(uint8_t responseCode, const uint8_t* buf, size_t size) { +#ifdef TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME + // a special case for short packets: we can sent them in 1 frame, without CRC & size, + // because the CAN protocol is already protected by its own checksum. + if ((size + 1) <= 7) { + write(&responseCode, 1); // header without size + if (size > 0) { + write(buf, size); // body + } + flush(); + return; + } +#endif /* TS_CAN_DEVICE */ + + // Packet too large, use default implementation + TsChannelBase::writeCrcPacket(responseCode, buf, size); +} + +void CanTsChannel::write(const uint8_t* buffer, size_t size) { + canAddToTxStreamTimeout(&TS_CAN_DEVICE, &size, buffer, BINARY_IO_TIMEOUT); +} + +size_t CanTsChannel::readTimeout(uint8_t* buffer, size_t size, int timeout) { + canStreamReceiveTimeout(&TS_CAN_DEVICE, &size, buffer, timeout); + return size; +} + +void CanTsChannel::flush() { + canFlushTxStream(&TS_CAN_DEVICE); +} + +bool CanTsChannel::isReady() { + // this channel is always ready + return true; +} + +#endif // def TS_CAN_DEVICE diff --git a/firmware/console/binary/tunerstudio.mk b/firmware/console/binary/tunerstudio.mk index ab0961b22d..a68736b0c9 100644 --- a/firmware/console/binary/tunerstudio.mk +++ b/firmware/console/binary/tunerstudio.mk @@ -1,5 +1,6 @@ TUNERSTUDIO_SRC_CPP = $(PROJECT_DIR)/console/binary/tunerstudio_io.cpp \ + $(PROJECT_DIR)/console/binary/ts_can_channel.cpp \ $(PROJECT_DIR)/console/binary/tunerstudio.cpp \ $(PROJECT_DIR)/console/binary/tunerstudio_commands.cpp \ $(PROJECT_DIR)/console/binary/bluetooth.cpp \ diff --git a/firmware/console/binary/tunerstudio_io.cpp b/firmware/console/binary/tunerstudio_io.cpp index 07844edc8f..854d5c2c42 100644 --- a/firmware/console/binary/tunerstudio_io.cpp +++ b/firmware/console/binary/tunerstudio_io.cpp @@ -33,11 +33,6 @@ static_assert(SERIAL_USB_BUFFERS_SIZE >= BLOCKING_FACTOR + 10); extern SERIAL_USB_DRIVER TS_USB_DEVICE; #endif /* TS_USB_DEVICE */ -#ifdef TS_CAN_DEVICE -#include "serial_can.h" -#endif /* TS_CAN_DEVICE */ - - #if TS_UART_DMA_MODE #elif TS_UART_MODE /* Note: This structure is modified from the default ChibiOS layout! */ @@ -56,8 +51,6 @@ static UARTConfig tsUartConfig = { }; #elif defined(TS_SERIAL_DEVICE) static SerialConfig tsSerialConfig = { .speed = 0, .cr1 = 0, .cr2 = USART_CR2_STOP1_BITS | USART_CR2_LINEN, .cr3 = 0 }; -#elif defined(TS_CAN_DEVICE) -static CANConfig tsCanConfig = { CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP, CAN_BTR_500 }; #endif /* TS_UART_DMA_MODE */ #endif /* EFI_PROD_CODE */ @@ -109,19 +102,6 @@ void startTsPort(ts_channel_s *tsChannel) { #endif } #endif /* TS_UART_DMA_MODE || TS_UART_MODE */ - #if defined(TS_CAN_DEVICE) - /*if (CONFIG(useCanForTs))*/ { - print("TunerStudio over CAN"); - - efiSetPadMode("ts can rx", GPIOG_13/*CONFIG(canRxPin)*/, PAL_MODE_ALTERNATE(TS_CAN_AF)); // CAN2_RX2_0 - efiSetPadMode("ts can tx", GPIOG_14/*CONFIG(canTxPin)*/, PAL_MODE_ALTERNATE(TS_CAN_AF)); // CAN2_TX2_0 - - canStart(&TS_CAN_DEVICE, &tsCanConfig); - canInit(&TS_CAN_DEVICE); - - //tsChannel->channel = (BaseChannel *) &TS_CAN_DEVICE; - } - #endif /* TS_CAN_DEVICE */ #elif EFI_SIMULATOR /* EFI_PROD_CODE */ tsChannel->channel = (BaseChannel *) TS_SIMULATOR_PORT; #endif /* EFI_PROD_CODE */ @@ -143,11 +123,6 @@ bool stopTsPort(ts_channel_s *tsChannel) { sdStop(TS_SERIAL_DEVICE); #endif /* TS_SERIAL_DEVICE */ } - #if defined(TS_CAN_DEVICE) - /*if (CONFIG(useCanForTs))*/ { - canStop(&TS_CAN_DEVICE); - } - #endif /* TS_CAN_DEVICE */ tsChannel->channel = (BaseChannel *) NULL; return true; #else /* EFI_PROD_CODE */ @@ -183,8 +158,6 @@ void ts_channel_s::write(const uint8_t* buffer, size_t size) { uartSendTimeout(uartp, &size, buffer, BINARY_IO_TIMEOUT); return; } -#elif defined(TS_CAN_DEVICE) - canAddToTxStreamTimeout(&TS_CAN_DEVICE, &size, buffer, BINARY_IO_TIMEOUT); #endif if (!channel) { return; @@ -225,9 +198,6 @@ size_t ts_channel_s::readTimeout(uint8_t* buffer, size_t size, int timeout) { #elif TS_UART_MODE uartReceiveTimeout(TS_UART_DEVICE, &size, buffer, timeout); return size; -#elif defined(TS_CAN_DEVICE) - canStreamReceiveTimeout(&TS_CAN_DEVICE, &size, buffer, timeout); - return size; #else /* TS_UART_DMA_MODE */ if (channel == nullptr) return 0; @@ -305,18 +275,6 @@ void TsChannelBase::writeCrcPacket(uint8_t responseCode, const uint8_t* buf, siz size = 0; } -#if defined(TS_CAN_DEVICE) && defined(TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME) - // a special case for short packets: we can sent them in 1 frame, without CRC & size, - // because the CAN protocol is already protected by its own checksum. - if ((size + 1) <= 7) { - write(&responseCode, 1); // header without size - if (size > 0) { - write(buf, size); // body - } - flush(); - return; - } -#endif /* TS_CAN_DEVICE */ if (size <= BLOCKING_FACTOR + 7) { // small packets use small packet optimization writeCrcPacketSmall(responseCode, buf, size); @@ -347,9 +305,3 @@ bool ts_channel_s::isReady() { #endif /* EFI_USB_SERIAL */ return true; } - -void ts_channel_s::flush() { -#if defined(TS_CAN_DEVICE) - canFlushTxStream(&TS_CAN_DEVICE); -#endif /* TS_CAN_DEVICE */ -} diff --git a/firmware/console/binary/tunerstudio_io.h b/firmware/console/binary/tunerstudio_io.h index d7268727b3..b1679101f0 100644 --- a/firmware/console/binary/tunerstudio_io.h +++ b/firmware/console/binary/tunerstudio_io.h @@ -27,12 +27,18 @@ public: // Virtual functions - implement these for your underlying transport virtual void write(const uint8_t* buffer, size_t size) = 0; virtual size_t readTimeout(uint8_t* buffer, size_t size, int timeout) = 0; - virtual void flush() = 0; - virtual bool isReady() = 0; + + // These functions are optional to implement, not all channels need them + virtual void flush() { } + virtual bool isReady() { return true; } + virtual void stop() { } // Base functions that use the above virtual implementation size_t read(uint8_t* buffer, size_t size); +#ifdef TS_CAN_DEVICE + virtual // CAN device needs this function to be virtual for small-packet optimization +#endif void writeCrcPacket(uint8_t responseCode, const uint8_t* buf, size_t size); void sendResponse(ts_response_format_e mode, const uint8_t * buffer, int size); @@ -51,7 +57,6 @@ private: struct ts_channel_s : public TsChannelBase { void write(const uint8_t* buffer, size_t size) override; size_t readTimeout(uint8_t* buffer, size_t size, int timeout) override; - void flush() override; bool isReady() override; #if !EFI_UNIT_TEST