fix multi-serial-port insanity (#2476)

* carve out UART specific

* implement channel

* config cleanup

* use new config

* bootloader

* dead code

* s

* h7 inherits f7

* oops

* ok now it's right

* tests

* cleanup

* call setup

* put that in its own file

* cleanup

* format

* guard

* not needed

* improve guarding

* portable

* allow override of uart mode

* fixes for bootloader

Co-authored-by: Matthew Kennedy <makenne@microsoft.com>
This commit is contained in:
Matthew Kennedy 2021-03-28 06:06:36 -07:00 committed by GitHub
parent b5dff633ea
commit f0cf4f38ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 274 additions and 683 deletions

View File

@ -18,7 +18,7 @@ DDEFS += -DHAL_USE_EXT=FALSE -DHAL_USE_ICU=FALSE -DHAL_USE_PWM=FALSE -DHAL_USE_R
#disable ChibiOS flsah driver and prevent header from include
DDEFS += -DHAL_USE_FLASH=FALSE
DDEFS += -DPRIMARY_UART_DMA_MODE=FALSE
DDEFS += -DEFI_USE_UART_DMA=FALSE
# disable USB (The bootloader has currently UART support only)
DDEFS += -DEFI_USB_SERIAL=FALSE
@ -173,6 +173,7 @@ CPPSRC = $(ALLCPPSRC) \
$(TUNERSTUDIO_SRC_CPP) \
$(CONSOLE_SRC_CPP) \
$(PROJECT_DIR)/console/binary/tunerstudio_io.cpp \
$(PROJECT_DIR)/console/binary/tunerstudio_io_serial.cpp \
$(PROJECT_DIR)/controllers/system/efi_gpio.cpp \
$(PROJECT_DIR)/controllers/algo/engine_configuration.cpp \
$(PROJECT_DIR)/controllers/persistent_store.cpp \

View File

@ -7,7 +7,7 @@
#include "dfu.h"
// Communication vars
static ts_channel_s blTsChannel;
static UartTsChannel blTsChannel(TS_PRIMARY_UART);
static uint8_t buffer[DFU_BUFFER_SIZE];
// Use short timeout for the first data packet, and normal timeout for the rest
static int sr5Timeout = DFU_SR5_TIMEOUT_FIRST;
@ -314,6 +314,6 @@ bool dfuStartLoop(void) {
return wasCommand;
}
ts_channel_s *getTsChannel() {
SerialTsChannelBase *getTsChannel() {
return &blTsChannel;
}

View File

@ -48,5 +48,4 @@ bool dfuStartLoop(void);
*/
void dfuJumpToApp(uint32_t addr);
ts_channel_s *getTsChannel();
SerialTsChannelBase* getTsChannel();

View File

@ -21,7 +21,6 @@ extern "C"
LoggingWithStorage tsLogger("binary");
static bool wasCommand = false;
static THD_WORKING_AREA(waBootloaderSerial, 128);
static THD_FUNCTION(thBootloaderSerial, arg) {
(void)arg;
@ -45,8 +44,8 @@ int main(void) {
*/
// start UART
startTsPort(getTsChannel());
getTsChannel()->start(38400); // TODO: should bootloader serial speed be configurable?
// start a serial port reader thread
thread_t *thrSerial = chThdCreateStatic(waBootloaderSerial, sizeof(waBootloaderSerial), NORMALPRIO, thBootloaderSerial, NULL);

View File

@ -45,10 +45,6 @@
//#define EFI_UART_ECHO_TEST_MODE FALSE
//#define EFI_USE_UART_FOR_CONSOLE FALSE
#define EFI_CONSOLE_NO_THREAD
/**
* Build-in logic analyzer support. Logic analyzer viewer is one of the java console panes.
*/
@ -283,20 +279,18 @@
* STM32_UART_USE_USARTx
* in mcuconf.h
*/
#define TS_UART_DMA_MODE FALSE
#define TS_UART_MODE FALSE
#define PRIMARY_UART_DMA_MODE FALSE
#define EFI_USE_UART_DMA FALSE
#undef TS_UART_DEVICE
#undef TS_SERIAL_DEVICE
#undef TS_SECONDARY_UART
#undef TS_SECONDARY_SERIAL
// todo: add CAN support
//#define TS_CAN_DEVICE CAND1
#define TS_CAN_AF PAL_MODE_ALTERNATIVE_CAN
#define TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME
#undef EFI_CONSOLE_SERIAL_DEVICE
#undef EFI_CONSOLE_UART_DEVICE
#undef TS_PRIMARY_SERIAL
#undef TS_PRIMARY_UART
#define EFI_USB_SERIAL TRUE
#define EFI_CONSOLE_USB_DEVICE SDU1

View File

@ -24,8 +24,8 @@ DDEFS += -DLED_RUNING_BRAIN_PIN_MODE=INVERTED_OUTPUT
DDEFS += -DLED_WARNING_BRAIN_PIN_MODE=INVERTED_OUTPUT
DDEFS += -DLED_COMMUNICATION_BRAIN_PIN_MODE=INVERTED_OUTPUT
DDEFS += -DSTM32_UART_USE_USART3=FALSE
DDEFS += -DPRIMARY_UART_DMA_MODE=FALSE
# Disable serial ports on this board as UART3 causes a DMA conflict with the SD card
DDEFS += -DTS_NO_PRIMARY -DTS_NO_SECONDARY
# Add them all together
DDEFS += -DEFI_USE_OSC=TRUE -DFIRMWARE_ID=\"hellen72\" $(DEFAULT_ENGINE_TYPE) $(LED_CRITICAL_ERROR_BRAIN_PIN) $(LED_COMMUNICATION_BRAIN_PIN)

View File

@ -44,10 +44,6 @@
//#define EFI_UART_ECHO_TEST_MODE FALSE
//#define EFI_USE_UART_FOR_CONSOLE FALSE
#define EFI_CONSOLE_NO_THREAD TRUE
/**
* Build-in logic analyzer support. Logic analyzer viewer is one of the java console panes.
*/
@ -272,15 +268,10 @@
* STM32_UART_USE_USARTx
* in mcuconf.h
*/
#define TS_UART_DMA_MODE FALSE
#define TS_UART_MODE TRUE
#define PRIMARY_UART_DMA_MODE FALSE
#define EFI_USE_UART_DMA FALSE
#define TS_UART_DEVICE (&UARTD2)
#undef TS_SERIAL_DEVICE
#undef EFI_CONSOLE_SERIAL_DEVICE
#define EFI_CONSOLE_UART_DEVICE (&UARTD1)
#define TS_PRIMARY_UART UARTD2
#undef TS_SECONDARY_UART
#define EFI_CONSOLE_TX_BRAIN_PIN GPIOA_10
#define EFI_CONSOLE_RX_BRAIN_PIN GPIOA_11
@ -371,7 +362,7 @@
if (__debugEnabled) { \
extern char __debugBuffer[80]; \
chsnprintf(__debugBuffer, sizeof(__debugBuffer), fmt, ##__VA_ARGS__); \
uart_lld_blocking_send(EFI_CONSOLE_UART_DEVICE, strlen(__debugBuffer), (void *)__debugBuffer); \
uart_lld_blocking_send(TS_PRIMARY_UART, strlen(__debugBuffer), (void *)__debugBuffer); \
} \
}

View File

@ -34,23 +34,15 @@
#define ADC_CHANNEL_VREF ADC_CHANNEL_IN14
#undef PRIMARY_UART_DMA_MODE
#define PRIMARY_UART_DMA_MODE FALSE
#undef EFI_CONSOLE_SERIAL_DEVICE
#undef EFI_CONSOLE_UART_DEVICE
#undef TS_PRIMARY_SERIAL
#undef TS_PRIMARY_UART
#define TS_PRIMARY_UART UARTD4
#undef EFI_UART_GPS
#define EFI_UART_GPS FALSE
//!!!!!!!!!!!!!!!!!
#undef TS_UART_DMA_MODE
#define TS_UART_DMA_MODE TRUE
#undef TS_UART_DEVICE
#define TS_UART_DEVICE (&UARTD4)
#undef TS_SERIAL_DEVICE
#undef TS_SECONDARY_UART
#undef TS_SECONDARY_SERIAL
#undef EFI_BLUETOOTH_SETUP
#define EFI_BLUETOOTH_SETUP TRUE

View File

@ -17,11 +17,4 @@
#undef HAL_USE_SERIAL
#define HAL_USE_SERIAL FALSE
#undef HAL_USE_UART
#if (TS_UART_DMA_MODE || TS_UART_MODE)
#define HAL_USE_UART TRUE
#else
#define HAL_USE_UART FALSE
#endif
#endif /* _HALCONF_PROMETHEUS_H_ */

View File

@ -43,11 +43,7 @@
#define STM32_SERIAL_USE_USART3 FALSE
#undef STM32_SERIAL_USE_UART4
#if (TS_UART_DMA_MODE || TS_UART_MODE)
#define STM32_SERIAL_USE_UART4 FALSE
#else
#define STM32_SERIAL_USE_UART4 TRUE
#endif
#undef STM32_UART_USE_USART3
#define STM32_UART_USE_USART3 FALSE

View File

@ -21,17 +21,13 @@
#define LED_RUNING_BRAIN_PIN_MODE INVERTED_OUTPUT
/* debug console */
#undef EFI_USE_UART_FOR_CONSOLE
#define EFI_USE_UART_FOR_CONSOLE TRUE
#undef EFI_CONSOLE_SERIAL_DEVICE
#define EFI_CONSOLE_SERIAL_DEVICE (&SD1)
#undef TS_PRIMARY_SERIAL
#undef TS_PRIMARY_UART
#define TS_PRIMARY_SERIAL SD1
/* TunerStudio binary protocol */
/* do not use UART device for console */
#undef TS_UART_DEVICE
/* do not use serial device for console */
#undef TS_SERIAL_DEVICE
// no secondary channel
#undef TS_SECONDARY_UART
#undef TS_SECONDARY_SERIAL
/* Knock detection */
#undef EFI_HIP_9011
@ -101,7 +97,7 @@
#undef SERIAL_SPEED
#define SERIAL_SPEED 115200
#ifdef EFI_CONSOLE_SERIAL_DEVICE
#ifdef TS_PRIMARY_SERIAL
#undef EFI_CONSOLE_TX_PORT
#define EFI_CONSOLE_TX_PORT GPIOA
#undef EFI_CONSOLE_TX_PIN

View File

@ -24,12 +24,8 @@
/* serials and uarts */
#undef STM32_SERIAL_USE_USART1
#undef STM32_UART_USE_USART1
//#if TS_UART_DMA_MODE
//#define STM32_SERIAL_USE_UART1 FALSE
//#else
#define STM32_SERIAL_USE_USART1 TRUE
#define STM32_UART_USE_USART1 FALSE
//#endif
#undef STM32_SERIAL_USE_USART2
#undef STM32_UART_USE_USART2

View File

@ -347,42 +347,16 @@
* PE5
*/
// todo: start using consoleUartDevice? Not sure
#ifndef EFI_CONSOLE_SERIAL_DEVICE
//#define EFI_CONSOLE_SERIAL_DEVICE (&SD3)
// allow override of EFI_USE_UART_DMA from cmdline passed defs
#ifndef EFI_USE_UART_DMA
#define EFI_USE_UART_DMA TRUE
#endif
/**
* Use 'HAL_USE_UART' DMA-mode driver instead of 'HAL_USE_SERIAL'
*
* See also
* STM32_SERIAL_USE_USARTx
* STM32_UART_USE_USARTx
* in mcuconf.h
*/
#ifndef TS_UART_DMA_MODE
#define TS_UART_DMA_MODE FALSE
#endif
#ifndef PRIMARY_UART_DMA_MODE
#define PRIMARY_UART_DMA_MODE TRUE
#endif
#if (PRIMARY_UART_DMA_MODE || TS_UART_DMA_MODE || TS_UART_MODE)
#define EFI_CONSOLE_UART_DEVICE (&UARTD3)
#endif
//#define TS_UART_DEVICE (&UARTD3)
//#define TS_SERIAL_DEVICE (&SD3)
#define TS_PRIMARY_UART UARTD3
#undef TS_SECONDARY_UART
#define AUX_SERIAL_DEVICE (&SD6)
// todo: add DMA-mode for Console?
#if (TS_UART_DMA_MODE || TS_UART_MODE)
#undef EFI_CONSOLE_SERIAL_DEVICE
#endif
// todo: start using consoleSerialTxPin? Not sure
#ifndef EFI_CONSOLE_TX_BRAIN_PIN
#define EFI_CONSOLE_TX_BRAIN_PIN GPIOC_10

View File

@ -32,30 +32,17 @@
#undef EFI_LCD
#define EFI_LCD FALSE
// todo: start using consoleUartDevice? Not sure
#undef EFI_CONSOLE_SERIAL_DEVICE
// todo: our "DMA-half" ChibiOS patch not implemented for USARTv2/STM32F7/STM32H7
#undef EFI_USE_UART_DMA
#define EFI_USE_UART_DMA FALSE
#undef EFI_CONSOLE_UART_DEVICE
// todo: our "DMA-half" ChibiOS patch not implemented for USARTv2/STM32F7
#undef TS_UART_DMA_MODE
#define TS_UART_DMA_MODE FALSE
#undef PRIMARY_UART_DMA_MODE
#define PRIMARY_UART_DMA_MODE FALSE
#undef TS_UART_DEVICE
//#define TS_UART_DEVICE (&UARTD3)
#undef TS_SERIAL_DEVICE
#undef TS_PRIMARY_UART
#undef TS_SECONDARY_UART
#undef TS_PRIMARY_SERIAL
#undef TS_SECONDARY_SERIAL
#define AUX_SERIAL_DEVICE (&SD6)
// todo: add DMA-mode for Console?
#if (TS_UART_DMA_MODE || TS_UART_MODE)
#undef EFI_CONSOLE_SERIAL_DEVICE
#endif
// todo: start using consoleSerialTxPin? Not sure
#undef EFI_CONSOLE_TX_BRAIN_PIN
#define EFI_CONSOLE_TX_BRAIN_PIN GPIOD_8

View File

@ -1,4 +1,4 @@
#include "../stm32f4ems/efifeatures.h"
#include "../stm32f7ems/efifeatures.h"
#pragma once
@ -14,18 +14,6 @@
#undef EFI_CJ125
#define EFI_CJ125 FALSE
// todo: our "DMA-half" ChibiOS patch not implemented for USARTv2/STM32H7
#undef TS_UART_DMA_MODE
#define TS_UART_DMA_MODE FALSE
#undef PRIMARY_UART_DMA_MODE
#define PRIMARY_UART_DMA_MODE FALSE
#undef TS_UART_DEVICE
//#define TS_UART_DEVICE (&UARTD3)
#undef EFI_CONSOLE_UART_DEVICE
#undef BOARD_TLE6240_COUNT
#undef BOARD_MC33972_COUNT
#undef BOARD_TLE8888_COUNT

View File

@ -37,7 +37,7 @@ static const int baudRates[] = { 0, 1200, 2400, 4800, 9600, 19200, 38400, 57600,
static const int baudRateIndexList[] = { 4 /*9600*/, 6 /*38400*/, 8 /*115200*/, 7, 5, 3, 2, 1, -1 };
static const int btModuleTimeout = TIME_MS2I(1000);
static ts_channel_s *tsChannel;
static SerialTsChannelBase *tsChannel;
static THD_WORKING_AREA(btThreadStack, UTILITY_THREAD_STACK_SIZE);
@ -80,42 +80,15 @@ static void runCommands() {
// if the baud rate is changed, reinit the UART
if (baudIdx != prevBaudIdx || restoreAndExit) {
#if EFI_USB_SERIAL
// if we have USB we assume BT operates on primary TTL
// todo: we need to clean a lot in this area :(
#ifdef EFI_CONSOLE_SERIAL_DEVICE
extern SerialConfig serialConfig;
sdStop(EFI_CONSOLE_SERIAL_DEVICE);
#endif /* EFI_CONSOLE_SERIAL_DEVICE */
#ifdef EFI_CONSOLE_UART_DEVICE
extern UARTConfig uartConfig;
uartStop(EFI_CONSOLE_UART_DEVICE);
#endif /* EFI_CONSOLE_UART_DEVICE */
tsChannel->stop();
#else
// deinit UART
if (!stopTsPort(tsChannel)) {
scheduleMsg(&btLogger, "Failed! Cannot restart serial port connection!");
return;
}
#endif /* EFI_USB_SERIAL */
chThdSleepMilliseconds(10); // safety
// change the port speed
CONFIG(tunerStudioSerialSpeed) = restoreAndExit ? savedSerialSpeed : baudRates[baudIdx];
#if EFI_USB_SERIAL
#ifdef EFI_CONSOLE_SERIAL_DEVICE
serialConfig.speed = CONFIG(tunerStudioSerialSpeed);
sdStart(EFI_CONSOLE_SERIAL_DEVICE, &serialConfig);
#endif /* EFI_CONSOLE_SERIAL_DEVICE */
#ifdef EFI_CONSOLE_UART_DEVICE
uartConfig.speed = CONFIG(tunerStudioSerialSpeed);
uartStart(EFI_CONSOLE_UART_DEVICE, &uartConfig);
#endif /* EFI_CONSOLE_UART_DEVICE */
#else
// init UART
startTsPort(tsChannel);
#endif /* EFI_USB_SERIAL */
tsChannel->start(CONFIG(tunerStudioSerialSpeed));
chThdSleepMilliseconds(10); // safety
prevBaudIdx = baudIdx;
}
@ -192,7 +165,7 @@ static THD_FUNCTION(btThreadEntryPoint, arg) {
chThdExit(MSG_OK);
}
void bluetoothStart(ts_channel_s *btChan, bluetooth_module_e moduleType, const char *baudRate, const char *name, const char *pinCode) {
void bluetoothStart(SerialTsChannelBase *btChan, bluetooth_module_e moduleType, const char *baudRate, const char *name, const char *pinCode) {
static const char *usage = "Usage: bluetooth_hc06 <baud> <name> <pincode>";
tsChannel = btChan;

View File

@ -31,7 +31,7 @@ typedef enum {
* - send AT-commands to the module;
* - restore connection to PC.
*/
void bluetoothStart(ts_channel_s *btChannel, bluetooth_module_e moduleType, const char *baudRate, const char *name, const char *pinCode);
void bluetoothStart(SerialTsChannelBase *btChannel, bluetooth_module_e moduleType, const char *baudRate, const char *name, const char *pinCode);
/**
* Cancel Bluetooth procedure

View File

@ -118,14 +118,6 @@ persistent_config_s configWorkingCopy;
static efitimems_t previousWriteReportMs = 0;
static ts_channel_s tsChannel;
// TODO: simplify what happens when we have multiple serial ports
#if !EFI_USB_SERIAL
// this thread wants a bit extra stack
static THD_WORKING_AREA(tunerstudioThreadStack, CONNECTIVITY_THREAD_STACK);
#endif
static void resetTs(void) {
memset(&tsState, 0, sizeof(tsState));
}
@ -159,33 +151,19 @@ static void setTsSpeed(int value) {
#if EFI_BLUETOOTH_SETUP
#if defined(CONSOLE_USB_DEVICE)
/**
* we run BT on "primary" channel which is TTL if we have USB console
*/
extern ts_channel_s primaryChannel;
#define BT_CHANNEL primaryChannel
#else
/**
* if we run two TTL channels we run BT on 2nd TTL channel
*/
#define BT_CHANNEL tsChannel
#endif
// Bluetooth HC-05 module initialization start (it waits for disconnect and then communicates to the module)
static void bluetoothHC05(const char *baudRate, const char *name, const char *pinCode) {
bluetoothStart(&BT_CHANNEL, BLUETOOTH_HC_05, baudRate, name, pinCode);
bluetoothStart(getBluetoothChannel(), BLUETOOTH_HC_05, baudRate, name, pinCode);
}
// Bluetooth HC-06 module initialization start (it waits for disconnect and then communicates to the module)
static void bluetoothHC06(const char *baudRate, const char *name, const char *pinCode) {
bluetoothStart(&BT_CHANNEL, BLUETOOTH_HC_06, baudRate, name, pinCode);
bluetoothStart(getBluetoothChannel(), BLUETOOTH_HC_06, baudRate, name, pinCode);
}
// Bluetooth SPP-C module initialization start (it waits for disconnect and then communicates to the module)
static void bluetoothSPP(const char *baudRate, const char *name, const char *pinCode) {
bluetoothStart(&BT_CHANNEL, BLUETOOTH_SPP, baudRate, name, pinCode);
bluetoothStart(getBluetoothChannel(), BLUETOOTH_SPP, baudRate, name, pinCode);
}
#endif /* EFI_BLUETOOTH_SETUP */
@ -575,35 +553,20 @@ static void tsProcessOne(TsChannelBase* tsChannel) {
}
}
void runBinaryProtocolLoop(TsChannelBase* tsChannel) {
void TunerstudioThread::ThreadTask() {
auto channel = setupChannel();
// No channel configured for this thread, cancel.
if (!tsChannel || !tsChannel->isConfigured()) {
if (!channel || !channel->isConfigured()) {
return;
}
// Until the end of time, process incoming messages.
while(true) {
tsProcessOne(tsChannel);
tsProcessOne(channel);
}
}
void TunerstudioThread::ThreadTask() {
auto channel = setupChannel();
runBinaryProtocolLoop(channel);
}
#if !EFI_USB_SERIAL
static THD_FUNCTION(tsThreadEntryPoint, arg) {
(void) arg;
chRegSetThreadName("tunerstudio thread");
startTsPort(&tsChannel);
runBinaryProtocolLoop(&tsChannel);
}
#endif
/**
* Copy real configuration into the communications layer working copy
*/
@ -928,11 +891,6 @@ void startTunerStudioConnectivity(void) {
addConsoleActionSSS("bluetooth_spp", bluetoothSPP);
addConsoleAction("bluetooth_cancel", bluetoothCancel);
#endif /* EFI_BLUETOOTH_SETUP */
// TODO: simplify what happens when we have multiple serial ports
#if !EFI_USB_SERIAL
chThdCreateStatic(tunerstudioThreadStack, sizeof(tunerstudioThreadStack), PRIO_CONSOLE, (tfunc_t)tsThreadEntryPoint, NULL);
#endif
}
#endif

View File

@ -55,7 +55,6 @@ void requestBurn(void);
void startTunerStudioConnectivity(void);
void syncTunerStudioCopy(void);
void runBinaryProtocolLoop(TsChannelBase* tsChannel);
#if defined __GNUC__
// GCC

View File

@ -1,6 +1,7 @@
TUNERSTUDIO_SRC_CPP = $(PROJECT_DIR)/console/binary/tunerstudio_io.cpp \
$(PROJECT_DIR)/console/binary/tunerstudio_io_serial.cpp \
$(PROJECT_DIR)/console/binary/tunerstudio_io_serial_ports.cpp \
$(PROJECT_DIR)/console/binary/ts_can_channel.cpp \
$(PROJECT_DIR)/console/binary/tunerstudio.cpp \
$(PROJECT_DIR)/console/binary/tunerstudio_commands.cpp \

View File

@ -8,8 +8,6 @@
#include "engine.h"
#include "os_access.h"
#include "tunerstudio_io.h"
#include "console_io.h"
#include "connector_uart_dma.h"
#if EFI_SIMULATOR
#include "rusEfiFunctionalTest.h"
@ -17,175 +15,11 @@
EXTERN_ENGINE;
extern LoggingWithStorage tsLogger;
#if EFI_PROD_CODE
#include "pin_repository.h"
#if TS_UART_DMA_MODE
#elif TS_UART_MODE
/* Note: This structure is modified from the default ChibiOS layout! */
static UARTConfig tsUartConfig = {
.txend1_cb = NULL,
.txend2_cb = NULL,
.rxend_cb = NULL,
.rxchar_cb = NULL,
.rxerr_cb = NULL,
.timeout_cb = NULL,
.speed = 0,
.cr1 = 0,
.cr2 = 0/*USART_CR2_STOP1_BITS*/ | USART_CR2_LINEN,
.cr3 = 0,
.rxhalf_cb = NULL
};
#elif defined(TS_SERIAL_DEVICE)
static SerialConfig tsSerialConfig = { .speed = 0, .cr1 = 0, .cr2 = USART_CR2_STOP1_BITS | USART_CR2_LINEN, .cr3 = 0 };
#endif /* TS_UART_DMA_MODE */
#endif /* EFI_PROD_CODE */
void startTsPort(ts_channel_s *tsChannel) {
#if EFI_PROD_CODE
tsChannel->channel = (BaseChannel *) NULL;
#if defined(TS_UART_DEVICE) || defined(TS_SERIAL_DEVICE)
if (CONFIG(useSerialPort)) {
scheduleMsg(&tsLogger, "TunerStudio over USART");
/**
* We have hard-coded USB serial console so that it would be clear how to connect to each specific board,
* but for UART serial we allow users to change settings.
*/
efiSetPadMode("tunerstudio rx", engineConfiguration->binarySerialRxPin, PAL_MODE_ALTERNATE(TS_SERIAL_AF));
efiSetPadMode("tunerstudio tx", engineConfiguration->binarySerialTxPin, PAL_MODE_ALTERNATE(TS_SERIAL_AF));
#if TS_UART_DMA_MODE
scheduleMsg(&tsLogger, "Using UART-DMA mode");
tsChannel->uartp = TS_UART_DEVICE;
startUartDmaConnector(tsChannel->uartp PASS_CONFIG_PARAMETER_SUFFIX);
#elif TS_UART_MODE
scheduleMsg(&tsLogger, "Using UART mode");
// start DMA driver
tsUartConfig.speed = CONFIG(tunerStudioSerialSpeed);
uartStart(TS_UART_DEVICE, &tsUartConfig);
#elif defined(TS_SERIAL_DEVICE)
scheduleMsg(&tsLogger, "Using Serial mode");
tsSerialConfig.speed = CONFIG(tunerStudioSerialSpeed);
sdStart(TS_SERIAL_DEVICE, &tsSerialConfig);
tsChannel->channel = (BaseChannel *) TS_SERIAL_DEVICE;
#endif
}
#endif /* TS_UART_DMA_MODE || TS_UART_MODE */
#elif EFI_SIMULATOR /* EFI_PROD_CODE */
tsChannel->channel = (BaseChannel *) TS_SIMULATOR_PORT;
#endif /* EFI_PROD_CODE */
}
bool stopTsPort(ts_channel_s *tsChannel) {
#if EFI_PROD_CODE
#if EFI_USB_SERIAL
// don't stop USB!
//usb_serial_stop();
return false;
#endif
if (CONFIG(useSerialPort)) {
// todo: disable Rx/Tx pads?
#if (TS_UART_DMA_MODE || TS_UART_MODE)
uartStop(TS_UART_DEVICE);
#endif /* TS_UART_DMA_MODE || TS_UART_MODE */
#ifdef TS_SERIAL_DEVICE
sdStop(TS_SERIAL_DEVICE);
#endif /* TS_SERIAL_DEVICE */
}
tsChannel->channel = (BaseChannel *) NULL;
return true;
#else /* EFI_PROD_CODE */
// don't stop simulator!
return false;
#endif /* EFI_PROD_CODE */
}
#if EFI_UNIT_TEST
int sr5TestWriteDataIndex = 0;
uint8_t st5TestBuffer[16000];
size_t ts_channel_s::readTimeout(uint8_t* buffer, size_t size, int timeout) {
// unit test, nothing to do here
return size;
}
void ts_channel_s::write(const uint8_t* buffer, size_t size) {
memcpy(&st5TestBuffer[sr5TestWriteDataIndex], buffer, size);
sr5TestWriteDataIndex += size;
}
#endif // EFI_UNIT_TEST
#if EFI_PROD_CODE || EFI_SIMULATOR
void ts_channel_s::write(const uint8_t* buffer, size_t size) {
efiAssertVoid(CUSTOM_ERR_6570, getCurrentRemainingStack() > 64, "tunerStudioWriteData");
#if EFI_SIMULATOR
logMsg("chSequentialStreamWrite [%d]\r\n", size);
#endif
#if (PRIMARY_UART_DMA_MODE || TS_UART_DMA_MODE || TS_UART_MODE) && EFI_PROD_CODE
if (uartp) {
uartSendTimeout(uartp, &size, buffer, BINARY_IO_TIMEOUT);
return;
}
#endif
if (!channel) {
return;
}
// int transferred = chnWriteTimeout(tsChannel->channel, buffer, size, BINARY_IO_TIMEOUT);
// temporary attempt to work around #553
// instead of one huge packet let's try sending a few smaller packets
size_t transferred = 0;
size_t stillToTransfer = size;
while (stillToTransfer > 0) {
int thisTransferSize = minI(stillToTransfer, 768);
transferred += chnWriteTimeout(channel, buffer, thisTransferSize, BINARY_IO_TIMEOUT);
buffer += thisTransferSize;
stillToTransfer -= thisTransferSize;
}
#if EFI_SIMULATOR
logMsg("transferred [%d]\r\n", transferred);
#endif
if (transferred != size) {
#if EFI_SIMULATOR
logMsg("!!! NOT ACCEPTED %d out of %d !!!", transferred, size);
#endif /* EFI_SIMULATOR */
scheduleMsg(&tsLogger, "!!! NOT ACCEPTED %d out of %d !!!", transferred, size);
}
}
size_t ts_channel_s::readTimeout(uint8_t* buffer, size_t size, int timeout) {
#if TS_UART_DMA_MODE || PRIMARY_UART_DMA_MODE
if (uartp) {
extern uart_dma_s tsUartDma;
return iqReadTimeout(&tsUartDma.fifoRxQueue, buffer, size, timeout);
}
#endif
#if TS_UART_DMA_MODE
#elif TS_UART_MODE
uartReceiveTimeout(TS_UART_DEVICE, &size, buffer, timeout);
return size;
#else /* TS_UART_DMA_MODE */
if (channel == nullptr)
return 0;
return chnReadTimeout(channel, buffer, size, timeout);
#endif /* TS_UART_DMA_MODE */
firmwareError(CUSTOM_ERR_6126, "Unexpected channel situation");
return 0;
}
size_t TsChannelBase::read(uint8_t* buffer, size_t size) {
return readTimeout(buffer, size, SR5_READ_TIMEOUT);
}
#endif // EFI_PROD_CODE || EFI_SIMULATOR
#endif
void TsChannelBase::writeCrcPacketSmall(uint8_t responseCode, const uint8_t* buf, size_t size) {
auto scratchBuffer = this->scratchBuffer;
@ -270,11 +104,3 @@ void TsChannelBase::sendResponse(ts_response_format_e mode, const uint8_t * buff
}
}
}
bool ts_channel_s::isConfigured() const {
return
#if TS_UART_DMA_MODE || PRIMARY_UART_DMA_MODE || TS_UART_MODE
this->uartp ||
#endif
this->channel;
}

View File

@ -55,22 +55,6 @@ private:
void writeCrcPacketLarge(uint8_t responseCode, const uint8_t* buf, size_t size);
};
#if EFI_UNIT_TEST
struct BaseChannel;
#endif
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;
bool isConfigured() const override;
BaseChannel * channel = nullptr;
#if TS_UART_DMA_MODE || PRIMARY_UART_DMA_MODE || TS_UART_MODE
UARTDriver *uartp = nullptr;
#endif // TS_UART_DMA_MODE
};
// This class represents a channel for a physical async serial poart
class SerialTsChannelBase : public TsChannelBase {
public:
@ -98,6 +82,7 @@ private:
#if HAL_USE_UART
// This class implements a ChibiOS UART Driver
class UartTsChannel : public SerialTsChannelBase {
public:
UartTsChannel(UARTDriver& driver) : m_driver(&driver) { }
void start(uint32_t baud) override;
@ -106,7 +91,7 @@ class UartTsChannel : public SerialTsChannelBase {
void write(const uint8_t* buffer, size_t size) override;
size_t readTimeout(uint8_t* buffer, size_t size, int timeout) override;
private:
protected:
UARTDriver* const m_driver;
UARTConfig m_config;
};
@ -116,13 +101,13 @@ private:
// todo: double-check this
#define CRC_WRAPPING_SIZE (CRC_VALUE_SIZE + 3)
void startTsPort(ts_channel_s *tsChannel);
bool stopTsPort(ts_channel_s *tsChannel);
// that's 1 second
#define BINARY_IO_TIMEOUT TIME_MS2I(1000)
// that's 1 second
#define SR5_READ_TIMEOUT TIME_MS2I(1000)
void startSerialChannels();
SerialTsChannelBase* getBluetoothChannel();
void sendOkResponse(TsChannelBase *tsChannel, ts_response_format_e mode);

View File

@ -0,0 +1,105 @@
/**
* @file This file initializes the hardware serial ports that run the TS protocol.
*
* @date Mar 26, 2021
*/
#include "engine.h"
#if EFI_PROD_CODE
#include "tunerstudio.h"
#include "tunerstudio_io.h"
#include "connector_uart_dma.h"
EXTERN_ENGINE;
#if (!defined(TS_NO_PRIMARY) && (defined(TS_PRIMARY_UART) || defined(TS_PRIMARY_SERIAL)))
#define HAS_PRIMARY true
#else
#define HAS_PRIMARY false
#endif
#if (!defined(TS_NO_SECONDARY) && (defined(TS_SECONDARY_UART) || defined(TS_SECONDARY_SERIAL)))
#define HAS_SECONDARY true
#else
#define HAS_SECONDARY false
#endif
#if HAS_PRIMARY
#ifdef TS_PRIMARY_UART
#if EFI_USE_UART_DMA
UartDmaTsChannel primaryChannel(TS_PRIMARY_UART);
#else
UartTsChannel primaryChannel(TS_PRIMARY_UART);
#endif
#elif defined(TS_PRIMARY_SERIAL)
SerialTsChannel primaryChannel(TS_PRIMARY_SERIAL);
#endif
struct PrimaryChannelThread : public TunerstudioThread {
PrimaryChannelThread() : TunerstudioThread("Primary TS Channel") { }
TsChannelBase* setupChannel() {
efiSetPadMode("Primary Channel RX", EFI_CONSOLE_RX_BRAIN_PIN, PAL_MODE_ALTERNATE(EFI_CONSOLE_AF));
efiSetPadMode("Primary Channel TX", EFI_CONSOLE_TX_BRAIN_PIN, PAL_MODE_ALTERNATE(EFI_CONSOLE_AF));
primaryChannel.start(CONFIG(uartConsoleSerialSpeed));
return &primaryChannel;
}
};
static PrimaryChannelThread primaryChannelThread;
#endif // HAS_PRIMARY
#if HAS_SECONDARY
#ifdef TS_SECONDARY_UART
#if EFI_USE_UART_DMA
UartDmaTsChannel secondaryChannel(TS_SECONDARY_UART);
#else
UartTsChannel secondaryChannel(TS_SECONDARY_UART);
#endif
#elif defined(TS_SECONDARY_SERIAL)
SerialTsChannel secondaryChannel(TS_SECONDARY_SERIAL);
#endif
struct SecondaryChannelThread : public TunerstudioThread {
SecondaryChannelThread() : TunerstudioThread("Secondary TS Channel") { }
TsChannelBase* setupChannel() {
efiSetPadMode("Secondary Channel RX", engineConfiguration->binarySerialRxPin, PAL_MODE_ALTERNATE(TS_SERIAL_AF));
efiSetPadMode("Secondary Channel TX", engineConfiguration->binarySerialTxPin, PAL_MODE_ALTERNATE(TS_SERIAL_AF));
secondaryChannel.start(CONFIG(uartConsoleSerialSpeed));
return &secondaryChannel;
}
};
static SecondaryChannelThread secondaryChannelThread;
#endif // HAS_SECONDARY
void startSerialChannels() {
#if HAS_PRIMARY
primaryChannelThread.Start();
#endif
#if HAS_SECONDARY
secondaryChannelThread.Start();
#endif
}
SerialTsChannelBase* getBluetoothChannel() {
#if HAS_SECONDARY
// Prefer secondary channel for bluetooth
return &secondaryChannel;
#elif HAS_PRIMARY
// Use primary channel for BT if no secondary exists
return &primaryChannel;
#endif
// no HW serial channels on this board, fail
return nullptr;
}
#endif // EFI_PROD_CODE

View File

@ -7,77 +7,75 @@
#include "connector_uart_dma.h"
#if TS_UART_DMA_MODE || PRIMARY_UART_DMA_MODE
#if TS_UART_DMA_MODE && PRIMARY_UART_DMA_MODE
#error "Only single-DMA implemented right now"
#endif
EXTERN_CONFIG;
// Async. FIFO buffer takes some RAM...
uart_dma_s tsUartDma;
#if HAL_USE_UART && EFI_USE_UART_DMA
/* Common function for all DMA-UART IRQ handlers. */
static void tsCopyDataFromDMA(UARTDriver *uartp) {
void UartDmaTsChannel::copyDataFromDMA() {
chSysLockFromISR();
// get 0-based DMA buffer position
int dmaPos = TS_DMA_BUFFER_SIZE - dmaStreamGetTransactionSize(uartp->dmarx);
int dmaPos = TS_DMA_BUFFER_SIZE - dmaStreamGetTransactionSize(m_driver->dmarx);
// if the position is wrapped (circular DMA-mode enabled)
if (dmaPos < tsUartDma.readPos)
if (dmaPos < readPos)
dmaPos += TS_DMA_BUFFER_SIZE;
// we need to update the current readPos
int newReadPos = tsUartDma.readPos;
int newReadPos = readPos;
for (int i = newReadPos; i < dmaPos; ) {
if (iqPutI(&tsUartDma.fifoRxQueue, tsUartDma.dmaBuffer[newReadPos]) != Q_OK) {
if (iqPutI(&fifoRxQueue, dmaBuffer[newReadPos]) != Q_OK) {
break; // todo: ignore overflow?
}
// the read position should always stay inside the buffer range
newReadPos = (++i) & (TS_DMA_BUFFER_SIZE - 1);
}
tsUartDma.readPos = newReadPos;
readPos = newReadPos;
chSysUnlockFromISR();
}
/* We use the same handler code for both halves. */
static void tsRxIRQHalfHandler(UARTDriver *uartp, uartflags_t full) {
UNUSED(uartp);
UNUSED(full);
tsCopyDataFromDMA(uartp);
reinterpret_cast<UartDmaTsChannel*>(uartp->dmaAdapterInstance)->copyDataFromDMA();
}
/* This handler is called right after the UART receiver has finished its work. */
static void tsRxIRQIdleHandler(UARTDriver *uartp) {
UNUSED(uartp);
tsCopyDataFromDMA(uartp);
reinterpret_cast<UartDmaTsChannel*>(uartp->dmaAdapterInstance)->copyDataFromDMA();
}
/* Note: This structure is modified from the default ChibiOS layout! */
static UARTConfig tsDmaUartConfig = {
.txend1_cb = NULL,
.txend2_cb = NULL,
.rxend_cb = NULL,
.rxchar_cb = NULL,
.rxerr_cb = NULL,
.timeout_cb = tsRxIRQIdleHandler,
.speed = 0,
.cr1 = 0,
.cr2 = 0/*USART_CR2_STOP1_BITS*/ | USART_CR2_LINEN,
.cr3 = 0,
.rxhalf_cb = tsRxIRQHalfHandler
};
UartDmaTsChannel::UartDmaTsChannel(UARTDriver& driver)
: UartTsChannel(driver)
{
// Store a pointer to this instance so we can get it back later in the DMA callback
driver.dmaAdapterInstance = this;
void startUartDmaConnector(UARTDriver *uartp DECLARE_CONFIG_PARAMETER_SUFFIX) {
// init FIFO queue
iqObjectInit(&tsUartDma.fifoRxQueue, tsUartDma.buffer, sizeof(tsUartDma.buffer), NULL, NULL);
// start DMA driver
tsDmaUartConfig.speed = CONFIG(tunerStudioSerialSpeed);
uartStart(uartp, &tsDmaUartConfig);
// start continuous DMA transfer using our circular buffer
tsUartDma.readPos = 0;
uartStartReceive(uartp, sizeof(tsUartDma.dmaBuffer), tsUartDma.dmaBuffer);
iqObjectInit(&fifoRxQueue, buffer, sizeof(buffer), nullptr, nullptr);
}
#endif // TS_UART_DMA_MODE || PRIMARY_UART_DMA_MODE
void UartDmaTsChannel::start(uint32_t baud) {
m_config = {
.txend1_cb = NULL,
.txend2_cb = NULL,
.rxend_cb = NULL,
.rxchar_cb = NULL,
.rxerr_cb = NULL,
.timeout_cb = tsRxIRQIdleHandler,
.speed = baud,
.cr1 = 0,
.cr2 = 0/*USART_CR2_STOP1_BITS*/ | USART_CR2_LINEN,
.cr3 = 0,
.rxhalf_cb = tsRxIRQHalfHandler
};
uartStart(m_driver, &m_config);
// Start the buffered read process
readPos = 0;
uartStartReceive(m_driver, sizeof(dmaBuffer), dmaBuffer);
}
size_t UartDmaTsChannel::readTimeout(uint8_t* buffer, size_t size, int timeout) {
// Instead of reading from the device, read from our custom RX queue
return iqReadTimeout(&fifoRxQueue, buffer, size, timeout);
}
#endif // HAL_USE_UART && EFI_USE_UART_DMA

View File

@ -7,29 +7,36 @@
#pragma once
#include "global.h"
#include "engine_configuration.h"
#include "tunerstudio_io.h"
#if HAL_USE_UART && EFI_USE_UART_DMA
// See uart_dma_s
#define TS_FIFO_BUFFER_SIZE (BLOCKING_FACTOR + 30)
// This must be a power of 2!
#define TS_DMA_BUFFER_SIZE 32
// struct needed for async DMA transfer mode (see TS_UART_DMA_MODE)
typedef struct {
class UartDmaTsChannel : public UartTsChannel {
public:
UartDmaTsChannel(UARTDriver& uartDriver);
void start(uint32_t baud) override;
// Override only read from UartTsChannel
size_t readTimeout(uint8_t* buffer, size_t size, int timeout) override;
void copyDataFromDMA();
private:
// RX FIFO implementation
// circular DMA buffer
uint8_t dmaBuffer[TS_DMA_BUFFER_SIZE];
// current read position for the DMA buffer
volatile int readPos;
// secondary FIFO buffer for async. transfer
uint8_t buffer[TS_FIFO_BUFFER_SIZE];
#if EFI_PROD_CODE || EFI_SIMULATOR
// input FIFO Rx queue
input_queue_t fifoRxQueue;
#endif
} uart_dma_s;
#if TS_UART_DMA_MODE || PRIMARY_UART_DMA_MODE
void startUartDmaConnector(UARTDriver *uartp DECLARE_CONFIG_PARAMETER_SUFFIX);
#endif
};
#endif // HAL_USE_UART && EFI_USE_UART_DMA

View File

@ -50,9 +50,7 @@ EXTERN_ENGINE;
// 10 seconds
#define CONSOLE_WRITE_TIMEOUT 10000
static bool isSerialConsoleStarted = false;
#if (defined(EFI_CONSOLE_SERIAL_DEVICE) && ! EFI_SIMULATOR)
#if (defined(TS_PRIMARY_SERIAL) && ! EFI_SIMULATOR)
static event_listener_t consoleEventListener;
#endif
@ -64,176 +62,9 @@ void onDataArrived(void) {
CommandHandler console_line_callback;
#if (defined(EFI_CONSOLE_SERIAL_DEVICE) && ! EFI_SIMULATOR )
SerialConfig serialConfig = {
.speed = 0,
.cr1 = 0,
.cr2 = USART_CR2_STOP1_BITS | USART_CR2_LINEN,
.cr3 = 0
};
#endif
#if (defined(EFI_CONSOLE_UART_DEVICE) && ! EFI_SIMULATOR )
/* Note: This structure is modified from the default ChibiOS layout! */
UARTConfig uartConfig = {
.txend1_cb = NULL,
.txend2_cb = NULL,
.rxend_cb = NULL,
.rxchar_cb = NULL,
.rxerr_cb = NULL,
.timeout_cb = NULL,
.speed = 0,
.cr1 = 0,
.cr2 = 0/*USART_CR2_STOP1_BITS*/ | USART_CR2_LINEN,
.cr3 = 0,
.rxhalf_cb = NULL
};
// To use UART driver instead of Serial, we need to imitate "BaseChannel" streaming functionality
static msg_t _putt(void *, uint8_t b, sysinterval_t timeout) {
int n = 1;
uartSendTimeout(EFI_CONSOLE_UART_DEVICE, (size_t *)&n, &b, timeout);
return MSG_OK;
}
static size_t _writet(void *, const uint8_t *bp, size_t n, sysinterval_t timeout) {
uartSendTimeout(EFI_CONSOLE_UART_DEVICE, (size_t *)&n, bp, timeout);
return n;
}
static msg_t _put(void *ip, uint8_t b) {
#ifdef UART_USE_BLOCKING_SEND
// this version can be called from the locked state (no interrupts)
uart_lld_blocking_send(EFI_CONSOLE_UART_DEVICE, 1, (void *)&b);
#else
// uartSendTimeout() needs interrupts to wait for the end of transfer, so we have to unlock them temporary
bool wasLocked = isLocked();
if (wasLocked) {
if (isIsrContext()) {
chSysUnlockFromISR()
;
} else {
chSysUnlock()
;
}
}
_putt(ip, b, CONSOLE_WRITE_TIMEOUT);
// Relock if we were locked before
if (wasLocked) {
if (isIsrContext()) {
chSysLockFromISR();
} else {
chSysLock();
}
}
#endif /* UART_USE_BLOCKING_WRITE */
return MSG_OK;
}
static size_t _write(void *ip, const uint8_t *bp, size_t n) {
return _writet(ip, bp, n, CONSOLE_WRITE_TIMEOUT);
}
static msg_t _gett(void *, sysinterval_t /*timeout*/) {
return 0;
}
static size_t _readt(void *, uint8_t */*bp*/, size_t /*n*/, sysinterval_t /*timeout*/) {
return 0;
}
static msg_t _get(void *) {
return 0;
}
static size_t _read(void *, uint8_t */*bp*/, size_t /*n*/) {
return 0;
}
static msg_t _ctl(void *, unsigned int /*operation*/, void */*arg*/) {
return MSG_OK;
}
// This is a "fake" channel for getConsoleChannel() filled with our handlers
static const struct BaseChannelVMT uartChannelVmt = {
.instance_offset = (size_t)0, .write = _write, .read = _read, .put = _put, .get = _get,
.putt = _putt, .gett = _gett, .writet = _writet, .readt = _readt, .ctl = _ctl
};
static const BaseChannel uartChannel = { .vmt = &uartChannelVmt };
#endif /* EFI_CONSOLE_UART_DEVICE */
ts_channel_s primaryChannel;
#if EFI_PROD_CODE || EFI_EGT
BaseChannel * getConsoleChannel(void) {
#if PRIMARY_UART_DMA_MODE
if (primaryChannel.uartp != nullptr) {
// primary channel is in DMA mode - we do not have a stream implementation for this.
return nullptr;
}
#endif
#if defined(EFI_CONSOLE_SERIAL_DEVICE)
return (BaseChannel *) EFI_CONSOLE_SERIAL_DEVICE;
#endif /* EFI_CONSOLE_SERIAL_DEVICE */
#if defined(EFI_CONSOLE_UART_DEVICE)
return (BaseChannel *) &uartChannel;
#endif /* EFI_CONSOLE_UART_DEVICE */
return nullptr;
}
bool isCommandLineConsoleReady(void) {
return isSerialConsoleStarted;
}
#endif /* EFI_PROD_CODE || EFI_EGT */
#if !defined(EFI_CONSOLE_NO_THREAD)
static THD_WORKING_AREA(consoleThreadStack, CONNECTIVITY_THREAD_STACK);
static THD_FUNCTION(consoleThreadEntryPoint, arg) {
(void) arg;
chRegSetThreadName("console thread");
#if !PRIMARY_UART_DMA_MODE
primaryChannel.channel = (BaseChannel *) getConsoleChannel();
#endif
#if EFI_TUNER_STUDIO
runBinaryProtocolLoop(&primaryChannel);
#endif /* EFI_TUNER_STUDIO */
}
#endif /* EFI_CONSOLE_NO_THREAD */
static Logging *logger;
void startConsole(Logging *sharedLogger, CommandHandler console_line_callback_p) {
logger = sharedLogger;
console_line_callback = console_line_callback_p;
#if (defined(EFI_CONSOLE_SERIAL_DEVICE) || defined(EFI_CONSOLE_UART_DEVICE)) && ! EFI_SIMULATOR
efiSetPadMode("console RX", EFI_CONSOLE_RX_BRAIN_PIN, PAL_MODE_ALTERNATE(EFI_CONSOLE_AF));
efiSetPadMode("console TX", EFI_CONSOLE_TX_BRAIN_PIN, PAL_MODE_ALTERNATE(EFI_CONSOLE_AF));
#endif
#if PRIMARY_UART_DMA_MODE && ! EFI_SIMULATOR
primaryChannel.uartp = EFI_CONSOLE_UART_DEVICE;
startUartDmaConnector(primaryChannel.uartp PASS_CONFIG_PARAMETER_SUFFIX);
isSerialConsoleStarted = true;
#elif (defined(EFI_CONSOLE_SERIAL_DEVICE) && ! EFI_SIMULATOR)
/*
* Activates the serial
* it is important to set 'NONE' as flow control! in terminal application on the PC
*/
serialConfig.speed = engineConfiguration->uartConsoleSerialSpeed;
sdStart(EFI_CONSOLE_SERIAL_DEVICE, &serialConfig);
chEvtRegisterMask((event_source_t *) chnGetEventSource(EFI_CONSOLE_SERIAL_DEVICE), &consoleEventListener, 1);
isSerialConsoleStarted = true;
#elif (defined(EFI_CONSOLE_UART_DEVICE) && ! EFI_SIMULATOR)
uartConfig.speed = engineConfiguration->uartConsoleSerialSpeed;
uartStart(EFI_CONSOLE_UART_DEVICE, &uartConfig);
isSerialConsoleStarted = true;
#endif /* EFI_CONSOLE_SERIAL_DEVICE || EFI_CONSOLE_UART_DEVICE */
#if !defined(EFI_CONSOLE_NO_THREAD)
chThdCreateStatic(consoleThreadStack, sizeof(consoleThreadStack), PRIO_CONSOLE, (tfunc_t)consoleThreadEntryPoint, NULL);
#endif /* EFI_CONSOLE_NO_THREAD */
}

View File

@ -24,13 +24,3 @@ typedef void (*CommandHandler)(char *);
void consoleOutputBuffer(const uint8_t *buf, int size);
void startConsole(Logging *sharedLogger, CommandHandler console_line_callback_p);
void onDataArrived(void);
#if EFI_PROD_CODE || EFI_SIMULATOR || EFI_EGT
bool isCommandLineConsoleReady(void);
BaseChannel * getConsoleChannel(void);
#else
#define isCommandLineConsoleReady() true
#endif

View File

@ -248,12 +248,6 @@ void updateDevConsoleState(void) {
// ITM_SendChar(msg[i]);
// }
if (!isCommandLineConsoleReady()) {
return;
}
#if EFI_PROD_CODE
// todo: unify with simulator!
if (hasFirmwareError()) {

View File

@ -81,3 +81,6 @@
// SPI
#define SPI_USE_WAIT TRUE
#define SPI_USE_MUTUAL_EXCLUSION TRUE
// Extra field in the UART driver's struct to store a reference to the DMA receive buffer object
#define UART_DRIVER_EXT_FIELDS void* dmaAdapterInstance;

View File

@ -114,7 +114,7 @@
*/
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
/* Configured in efifeatures.h */
#if (PRIMARY_UART_DMA_MODE || TS_UART_DMA_MODE || TS_UART_MODE)
#if defined(TS_PRIMARY_UART) || defined(TS_PRIMARY_SERIAL)
#define HAL_USE_UART TRUE
#else
#define HAL_USE_UART FALSE
@ -193,11 +193,7 @@
*/
#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
/* Configured in efifeatures.h */
#if (PRIMARY_UART_DMA_MODE || TS_UART_DMA_MODE || TS_UART_MODE)
#define UART_USE_WAIT TRUE
#else
#define UART_USE_WAIT FALSE
#endif
#endif
/**

View File

@ -121,7 +121,7 @@
*/
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
/* Configured in efifeatures.h */
#if (PRIMARY_UART_DMA_MODE || TS_UART_DMA_MODE || TS_UART_MODE)
#if defined(TS_PRIMARY_UART) || defined(TS_PRIMARY_SERIAL)
#define HAL_USE_UART TRUE
#else
#define HAL_USE_UART FALSE
@ -200,7 +200,7 @@
*/
#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
/* Configured in efifeatures.h */
#if (PRIMARY_UART_DMA_MODE || TS_UART_DMA_MODE || TS_UART_MODE)
#if defined(TS_PRIMARY_UART) || defined(TS_PRIMARY_SERIAL)
#define UART_USE_WAIT TRUE
#else
#define UART_USE_WAIT FALSE

View File

@ -210,6 +210,9 @@ void runRusEfi(void) {
startTunerStudioConnectivity();
#endif /* EFI_TUNER_STUDIO */
// Start hardware serial ports (including bluetooth, if present)
startSerialChannels();
/**
* Initialize hardware drivers
*/

View File

@ -13,12 +13,12 @@
// see SIM_SD1_PORT
#define CONSOLE_PORT (&SD1)
// see SIM_SD2_PORT
#define TS_SIMULATOR_PORT (&SD2)
#define TS_PRIMARY_SERIAL SD2
/**
* This implementation writes to both windows console and console port
*/
#define EFI_CONSOLE_SERIAL_DEVICE (&serialAdapterInstance)
#define TS_PRIMARY_SERIAL (&serialAdapterInstance)
int getAdcValue(const char *msg, int channel);
#define getSlowAdcCounter() 0

View File

@ -29,8 +29,6 @@
#define EFI_CANBUS_SLAVE FALSE
#define PRIMARY_UART_DMA_MODE FALSE
#define EFI_BOSCH_YAW FALSE
#define EFI_AUX_SERIAL FALSE
@ -69,7 +67,7 @@
#define CONSOLE_MAX_ACTIONS 256
#define TS_UART_DMA_MODE FALSE
#define EFI_USE_UART_DMA FALSE
#define EFI_MAP_AVERAGING TRUE
#define EFI_ALTERNATOR_CONTROL TRUE

View File

@ -162,5 +162,5 @@ void logMsg(const char *format, ...) {
}
BaseChannel * getConsoleChannel(void) {
return (BaseChannel *)EFI_CONSOLE_SERIAL_DEVICE;
return (BaseChannel *)TS_PRIMARY_SERIAL;
}

View File

@ -1,15 +1,33 @@
#include "engine_test_helper.h"
#include "tunerstudio_io.h"
extern int sr5TestWriteDataIndex;
extern uint8_t st5TestBuffer[16000];
static uint8_t st5TestBuffer[16000];
class MockTsChannel : public TsChannelBase {
public:
void write(const uint8_t* buffer, size_t size) override {
memcpy(&st5TestBuffer[writeIdx], buffer, size);
writeIdx += size;
}
size_t readTimeout(uint8_t* buffer, size_t size, int timeout) override {
// nothing to do here
return size;
}
void reset() {
writeIdx = 0;
}
size_t writeIdx = 0;
};
#define CODE 2
#define PAYLOAD "123"
#define SIZE strlen(PAYLOAD)
static void assertCrcPacket() {
ASSERT_EQ(sr5TestWriteDataIndex, SIZE + 7);
static void assertCrcPacket(MockTsChannel& dut) {
ASSERT_EQ(dut.writeIdx, SIZE + 7);
// todo: proper uint16 comparison
ASSERT_EQ(st5TestBuffer[0], 0);
@ -28,20 +46,20 @@ static void assertCrcPacket() {
}
TEST(binary, testWriteCrc) {
static ts_channel_s test;
MockTsChannel test;
// Let it pick which impl (small vs large) to use
sr5TestWriteDataIndex = 0;
test.reset();
test.writeCrcPacket(CODE, (const uint8_t*)PAYLOAD, SIZE);
assertCrcPacket();
assertCrcPacket(test);
// Force the large impl
sr5TestWriteDataIndex = 0;
test.reset();
test.writeCrcPacket(CODE, (const uint8_t*)PAYLOAD, SIZE);
assertCrcPacket();
assertCrcPacket(test);
// Force the small impl
sr5TestWriteDataIndex = 0;
test.reset();
test.writeCrcPacket(CODE, (const uint8_t*)PAYLOAD, SIZE);
assertCrcPacket();
assertCrcPacket(test);
}