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:
parent
87a8cb9a78
commit
72dac58f9b
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -48,5 +48,4 @@ bool dfuStartLoop(void);
|
|||
*/
|
||||
void dfuJumpToApp(uint32_t addr);
|
||||
|
||||
ts_channel_s *getTsChannel();
|
||||
|
||||
SerialTsChannelBase* getTsChannel();
|
||||
|
|
|
@ -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,7 +44,7 @@ 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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -55,7 +55,6 @@ void requestBurn(void);
|
|||
|
||||
void startTunerStudioConnectivity(void);
|
||||
void syncTunerStudioCopy(void);
|
||||
void runBinaryProtocolLoop(TsChannelBase* tsChannel);
|
||||
|
||||
#if defined __GNUC__
|
||||
// GCC
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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 = {
|
||||
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;
|
||||
|
||||
iqObjectInit(&fifoRxQueue, buffer, sizeof(buffer), nullptr, nullptr);
|
||||
}
|
||||
|
||||
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 = 0,
|
||||
.speed = baud,
|
||||
.cr1 = 0,
|
||||
.cr2 = 0/*USART_CR2_STOP1_BITS*/ | USART_CR2_LINEN,
|
||||
.cr3 = 0,
|
||||
.rxhalf_cb = tsRxIRQHalfHandler
|
||||
};
|
||||
};
|
||||
|
||||
void startUartDmaConnector(UARTDriver *uartp DECLARE_CONFIG_PARAMETER_SUFFIX) {
|
||||
// init FIFO queue
|
||||
iqObjectInit(&tsUartDma.fifoRxQueue, tsUartDma.buffer, sizeof(tsUartDma.buffer), NULL, NULL);
|
||||
uartStart(m_driver, &m_config);
|
||||
|
||||
// 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);
|
||||
// Start the buffered read process
|
||||
readPos = 0;
|
||||
uartStartReceive(m_driver, sizeof(dmaBuffer), dmaBuffer);
|
||||
}
|
||||
|
||||
#endif // TS_UART_DMA_MODE || PRIMARY_UART_DMA_MODE
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -248,12 +248,6 @@ void updateDevConsoleState(void) {
|
|||
// ITM_SendChar(msg[i]);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
if (!isCommandLineConsoleReady()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
// todo: unify with simulator!
|
||||
if (hasFirmwareError()) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -210,6 +210,9 @@ void runRusEfi(void) {
|
|||
startTunerStudioConnectivity();
|
||||
#endif /* EFI_TUNER_STUDIO */
|
||||
|
||||
// Start hardware serial ports (including bluetooth, if present)
|
||||
startSerialChannels();
|
||||
|
||||
/**
|
||||
* Initialize hardware drivers
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -162,5 +162,5 @@ void logMsg(const char *format, ...) {
|
|||
}
|
||||
|
||||
BaseChannel * getConsoleChannel(void) {
|
||||
return (BaseChannel *)EFI_CONSOLE_SERIAL_DEVICE;
|
||||
return (BaseChannel *)TS_PRIMARY_SERIAL;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue