diff --git a/firmware/config/stm32f4ems/efifeatures.h b/firmware/config/stm32f4ems/efifeatures.h index aa3a524b41..b543b71053 100644 --- a/firmware/config/stm32f4ems/efifeatures.h +++ b/firmware/config/stm32f4ems/efifeatures.h @@ -178,6 +178,10 @@ #define EFI_CAN_SUPPORT TRUE #endif +#ifndef EFI_AUX_SERIAL +#define EFI_AUX_SERIAL TRUE +#endif + #ifndef EFI_HD44780_LCD #define EFI_HD44780_LCD TRUE #endif @@ -343,6 +347,8 @@ //#define TS_UART_DEVICE (&UARTD3) #define TS_SERIAL_DEVICE (&SD3) +#define AUX_SERIAL_DEVICE (&SD6) + // todo: add DMA-mode for Console? #if (TS_UART_DMA_MODE || TS_UART_MODE) #undef EFI_CONSOLE_SERIAL_DEVICE diff --git a/firmware/config/stm32f4ems/mcuconf.h b/firmware/config/stm32f4ems/mcuconf.h index ed5cac9feb..6ee203ff79 100644 --- a/firmware/config/stm32f4ems/mcuconf.h +++ b/firmware/config/stm32f4ems/mcuconf.h @@ -303,7 +303,7 @@ #define STM32_SERIAL_USE_USART3 TRUE #define STM32_SERIAL_USE_UART4 FALSE #define STM32_SERIAL_USE_UART5 FALSE -#define STM32_SERIAL_USE_USART6 FALSE +#define STM32_SERIAL_USE_USART6 TRUE /** * UART priority should not be too low so that we do not miss bytes */ diff --git a/firmware/config/stm32f7ems/efifeatures.h b/firmware/config/stm32f7ems/efifeatures.h index ab21b78ecb..bffe61773f 100644 --- a/firmware/config/stm32f7ems/efifeatures.h +++ b/firmware/config/stm32f7ems/efifeatures.h @@ -50,11 +50,12 @@ #define BOARD_TLE8888_COUNT 1 #endif - - #undef EFI_CAN_SUPPORT #define EFI_CAN_SUPPORT TRUE +#undef EFI_AUX_SERIAL +#define EFI_AUX_SERIAL TRUE + #undef EFI_HD44780_LCD #define EFI_HD44780_LCD TRUE @@ -89,6 +90,8 @@ #undef TS_SERIAL_DEVICE #define TS_SERIAL_DEVICE (&SD3) +#define AUX_SERIAL_DEVICE (&SD6) + // todo: add DMA-mode for Console? #if (TS_UART_DMA_MODE || TS_UART_MODE) #undef EFI_CONSOLE_SERIAL_DEVICE diff --git a/firmware/config/stm32f7ems/mcuconf.h b/firmware/config/stm32f7ems/mcuconf.h index 17d0f340eb..a8410c33f8 100644 --- a/firmware/config/stm32f7ems/mcuconf.h +++ b/firmware/config/stm32f7ems/mcuconf.h @@ -315,7 +315,7 @@ #define STM32_SERIAL_USE_USART3 TRUE #define STM32_SERIAL_USE_UART4 FALSE #define STM32_SERIAL_USE_UART5 FALSE -#define STM32_SERIAL_USE_USART6 FALSE +#define STM32_SERIAL_USE_USART6 TRUE #define STM32_SERIAL_USE_UART7 FALSE #define STM32_SERIAL_USE_UART8 FALSE #define STM32_SERIAL_USART1_PRIORITY (PRECISE_SCHEDULING_TIMER_PRIORITY + 2) diff --git a/firmware/controllers/controllers.mk b/firmware/controllers/controllers.mk index 78dcadfa8f..077d0d4d06 100644 --- a/firmware/controllers/controllers.mk +++ b/firmware/controllers/controllers.mk @@ -45,6 +45,8 @@ CONTROLLERS_SRC_CPP = \ $(CONTROLLERS_DIR)/engine_controller.cpp \ $(CONTROLLERS_DIR)/engine_controller_misc.cpp \ $(CONTROLLERS_DIR)/persistent_store.cpp \ + $(CONTROLLERS_DIR)/serial/serial_rx.cpp \ + $(CONTROLLERS_DIR)/serial/serial_sensor.cpp \ CONTROLLERS_INC=\ @@ -64,4 +66,5 @@ CONTROLLERS_INC=\ $(CONTROLLERS_DIR)/generated \ $(CONTROLLERS_DIR)/actuators \ $(CONTROLLERS_DIR)/actuators/gppwm \ + $(CONTROLLERS_DIR)/serial \ diff --git a/firmware/controllers/sensors/ego.cpp b/firmware/controllers/sensors/ego.cpp index 7fdfffa110..20ed5a7a4f 100644 --- a/firmware/controllers/sensors/ego.cpp +++ b/firmware/controllers/sensors/ego.cpp @@ -96,7 +96,7 @@ void initEgoAveraging(DECLARE_ENGINE_PARAMETER_SIGNATURE) { #endif bool hasAfrSensor(DECLARE_ENGINE_PARAMETER_SIGNATURE) { - if (CONFIG(enableAemXSeries)) { + if (CONFIG(enableAemXSeries) || CONFIG(enableInnovateLC2)) { return true; } @@ -109,6 +109,7 @@ bool hasAfrSensor(DECLARE_ENGINE_PARAMETER_SIGNATURE) { } extern float aemXSeriesLambda; +extern float InnovateLC2AFR; float getAfr(DECLARE_ENGINE_PARAMETER_SIGNATURE) { #if EFI_CAN_SUPPORT @@ -117,6 +118,11 @@ float getAfr(DECLARE_ENGINE_PARAMETER_SIGNATURE) { } #endif +#if EFI_AUX_SERIAL + if (CONFIG(enableInnovateLC2)) + return InnovateLC2AFR; +#endif + #if EFI_CJ125 && HAL_USE_SPI if (CONFIG(isCJ125Enabled)) { return cjGetAfr(PASS_ENGINE_PARAMETER_SIGNATURE); diff --git a/firmware/controllers/serial/serial.h b/firmware/controllers/serial/serial.h new file mode 100644 index 0000000000..159c68cd2f --- /dev/null +++ b/firmware/controllers/serial/serial.h @@ -0,0 +1,37 @@ +/** + * @file serial.h + * + * @date Mar 19, 2020 + * @author Konstantin Smola, (c) 2020 + */ + +#pragma once + +#include "hal.h" + +#include "periodic_thread_controller.h" + +#define TIME_100MSEC ((sysinterval_t)chTimeMS2I(100)) + +#define SERBUFFLEN 64 + +constexpr uint8_t lc2_header_mask = 162; +constexpr uint16_t lc2_pcklen_mask = 383; + +class Logging; + +typedef enum {UNKNOWN, HEADER_FOUND, IDENTIFIED} innovate_serial_id_state_t; + +extern uint8_t ser_buffer[SERBUFFLEN]; //buffer for incoming serial data +extern size_t innovate_msg_len; +extern innovate_serial_id_state_t innovate_serial_id_state; +extern uint8_t sb; +extern bool clear_ser_buffer; + +class SerialRead final : public ThreadController<256> { +public: + SerialRead(); + void ThreadTask(); + + uint16_t len; +}; \ No newline at end of file diff --git a/firmware/controllers/serial/serial_rx.cpp b/firmware/controllers/serial/serial_rx.cpp new file mode 100644 index 0000000000..5c75fae85d --- /dev/null +++ b/firmware/controllers/serial/serial_rx.cpp @@ -0,0 +1,58 @@ +/** + * @file serial_rx.cpp + * + * This file handles auxilery serial communication. + * + * @date Mar 19, 2020 + * @author Konstantin Smola, (c) 2020 + */ + +#include "globalaccess.h" + +#if EFI_AUX_SERIAL +#include "engine.h" +#include "serial.h" +#include "serial_hw.h" +#include "serial_sensor.h" + +#include "allsensors.h" +#include "vehicle_speed.h" + +EXTERN_ENGINE; + +static LoggingWithStorage logger("AUX Serial RX"); + +uint8_t ser_buffer[SERBUFFLEN] = {}; +size_t innovate_msg_len = 1; +innovate_serial_id_state_t innovate_serial_id_state = UNKNOWN; +uint8_t sb = 0; +bool clear_ser_buffer = false; + +SerialRead::SerialRead() + : ThreadController("AUX Serial RX", NORMALPRIO) { +} + +void SerialRead::ThreadTask() { + while (true) { + if (CONFIG(enableInnovateLC2)) { + len = innovate_msg_len; + } + + if (len >= SERBUFFLEN) + len = SERBUFFLEN; + + if (sdReadTimeout(AUX_SERIAL_DEVICE, &ser_buffer[sb], len, TIME_100MSEC) == len) { + ParseSerialData(); + } else { + ResetSerialSensor(); + } + + //clear buffer every frame to avoid parsing old data + if (clear_ser_buffer) { + ClearSerialBuffer(); + clear_ser_buffer = false; + } + } +} + +#endif // EFI_AUX_SERIAL diff --git a/firmware/controllers/serial/serial_sensor.cpp b/firmware/controllers/serial/serial_sensor.cpp new file mode 100644 index 0000000000..f864369fda --- /dev/null +++ b/firmware/controllers/serial/serial_sensor.cpp @@ -0,0 +1,191 @@ +/** + * @file serial_sensor.cpp + * + * + * @date Mar 19, 2020 + * @author Konstantin Smola, (c) 2020 + */ + +#include "global.h" +#if EFI_AUX_SERIAL +#include "serial.h" +#include "serial_sensor.h" +#include "engine.h" + +#define NUM_INNOVATE_O2_SENSORS 1 +#define AFR_MULTIPLIER 147 + +EXTERN_ENGINE; + +volatile float InnovateLC2AFR = AFR_ERROR; + +typedef enum +{ + NO_ERROR = 0, + HEATER_SHORTED = 1, + HEATER_OPEN = 2, + PUMPCELL_SHORTED = 3, + PUMPCELL_OPEN = 4, + REFCELL_SHORTED = 5, + REFCELL_OPEN = 6, + SYSTEM_ERROR = 7, + SENSOR_TIMING_ERR = 8, + SUPP_V_LOW = 9 +} sensor_error_code_t; + +typedef struct +{ + int function_code; + float AFR; + float AFR_multiplier; + float lambda; + float warmup; + sensor_error_code_t error_code; +} sensor_data_t; + +static sensor_data_t innovate_o2_sensor[NUM_INNOVATE_O2_SENSORS]; + +static size_t tmsglen; + +void IdentifyInnovateSerialMsg() { //this identifies an innovate LC1/LC2 o2 sensor by it's first word (header) + if (CONFIG(enableInnovateLC2)) { + if ((((ser_buffer[0]) & lc2_header_mask) != lc2_header_mask) && innovate_serial_id_state == IDENTIFIED) { //not serial header word + innovate_serial_id_state = UNKNOWN; + innovate_msg_len = 1; + sb = 0; + } + + switch (innovate_serial_id_state) { + case UNKNOWN: + InnovateLC2AFR = AFR_ERROR; + // read one byte, identify with mask, advance and read next byte + if (((ser_buffer[0]) & lc2_header_mask) == lc2_header_mask) { // check if it's the first byte of header + // first byte identified, now continue reading and advance statemachine + innovate_serial_id_state = HEADER_FOUND; + innovate_msg_len = 1; + sb = 1; + } else { + innovate_serial_id_state = UNKNOWN; + } + break; + + case HEADER_FOUND: + // now we should have both header bytes in array, and we can read the total packet length + tmsglen = (((ser_buffer[0] << 8) | ser_buffer[1]) & lc2_pcklen_mask); //0000000101111111 mask + + if (tmsglen) { + tmsglen += 1; // length in words including header (2 bytes) + tmsglen *= 2; // length in bytes (incl header) + innovate_msg_len = tmsglen - 2; + sb = 2; + innovate_serial_id_state = IDENTIFIED; //advance state machine + } else { + innovate_serial_id_state = UNKNOWN; + } + + break; + + case IDENTIFIED: + innovate_msg_len = tmsglen; + sb = 0; + // serial packet fully identified + ParseInnovateSerialMsg(); //takes about 570ns + clear_ser_buffer = true; + break; + + default: + break; + } + } +} + +void ParseInnovateSerialMsg() { + float raw_afr; + //get error code and afr + + // 000 Lambda valid and Aux data valid, normal operation. + // 001 Lambda value contains O2 level in 1/10% + // 010 Free air Calib in progress, Lambda data not valid + // 011 Need Free air Calibration Request, Lambda data not valid + // 100 Warming up, Lambda value is temp in 1/10% of operating temp. + // 101 Heater Calibration, Lambda value contains calibration countdown. + // 110 Error code in Lambda value + // 111 reserved + + for (size_t i = 0; i < ((tmsglen - 2) / 4) && i < NUM_INNOVATE_O2_SENSORS; i++) { + innovate_o2_sensor[i].function_code = (ser_buffer[2 + i * 4] >> 2 & 0x7); + // innovate_o2_sensor[i].AFR_multiplier = ((ser_buffer[2 + i * 4] << 7 | ser_buffer[3 + i * 4]) & 0xFF); + innovate_o2_sensor[i].AFR_multiplier = AFR_MULTIPLIER; + + switch (innovate_o2_sensor[i].function_code) { + case 0: //Lambda valid and aux data valid, normal operation + case 1: //Lambda value contains o2 level in 1/10% + innovate_o2_sensor[i].lambda = ((ser_buffer[4 + i * 4] << 7 | ser_buffer[5 + i * 4]) & 0x1FFF); + raw_afr = ((innovate_o2_sensor[i].lambda + 500) * innovate_o2_sensor[i].AFR_multiplier); + + if (innovate_o2_sensor[i].function_code) {//case 1 + innovate_o2_sensor[i].AFR = raw_afr * 0.001; + } else { // case 0 + innovate_o2_sensor[i].AFR = raw_afr * 0.0001; + } + + if (innovate_o2_sensor[i].AFR > AFRMAX) { + innovate_o2_sensor[i].AFR = AFRMAX; + } else if (innovate_o2_sensor[i].AFR < AFRMIN) + innovate_o2_sensor[i].AFR = AFRMIN; + } + + InnovateLC2AFR = innovate_o2_sensor[0].AFR; //only using one sensor right now + + break; + // this is invalid o2 data, so we can ignore it: + // case 2: // Free air Calib in progress, Lambda data not valid + // break; + // case 3: // Need Free air Calibration Request, Lambda data not valid + // break; + case 4: // Warming up, Lambda value is temp in 1/10% of operating temp + InnovateLC2AFR = AFR_ERROR; + innovate_o2_sensor[i].warmup = ((ser_buffer[4 + i * 4] << 7 | ser_buffer[5 + i * 4]) & 0x1FFF); + //catch potential overflow: + if (innovate_o2_sensor[i].warmup >= 1023) { + innovate_o2_sensor[i].warmup = 1023; + } else if (innovate_o2_sensor[i].warmup <= 0) + innovate_o2_sensor[i].warmup = 0; + } + break; + // case 5: // Heater Calibration, Lambda value contains calibration countdown + // break; + case 6: // Error code in Lambda value + InnovateLC2AFR = AFR_ERROR; + innovate_o2_sensor[i].error_code = (sensor_error_code_t)((ser_buffer[4 + i * 4] << 7 | ser_buffer[5 + i * 4]) & 0x1FFF); + //catch potential overflow: + if (innovate_o2_sensor[i].error_code >= (sensor_error_code_t)1023) { + innovate_o2_sensor[i].error_code = (sensor_error_code_t)1023; + } else if (innovate_o2_sensor[i].error_code <= 0) { + innovate_o2_sensor[i].error_code = (sensor_error_code_t)0; + } + break; + // case 7: // reserved + // break; + default: + InnovateLC2AFR = AFR_ERROR; + break; + } + } +} + +void ResetSerialSensor() { + ClearSerialBuffer(); + ParseSerialData(); +} + +void ClearSerialBuffer() { + memset(ser_buffer, 0, sizeof(ser_buffer)); +} + +void ParseSerialData() { + if (CONFIG(enableInnovateLC2)) + IdentifyInnovateSerialMsg(); +} + +#endif diff --git a/firmware/controllers/serial/serial_sensor.h b/firmware/controllers/serial/serial_sensor.h new file mode 100644 index 0000000000..834c705211 --- /dev/null +++ b/firmware/controllers/serial/serial_sensor.h @@ -0,0 +1,20 @@ +/** + * @file serial_sensor.h + * + * + * @date Mar 19, 2020 + * @author Konstantin Smola, (c) 2020 + */ + +#pragma once + +#define AFRMIN 0 +#define AFRMAX 33 + +#define AFR_ERROR 30 + +void IdentifyInnovateSerialMsg(); +void ParseInnovateSerialMsg(); +void ParseSerialData(); +void ResetSerialSensor(); +void ClearSerialBuffer(); \ No newline at end of file diff --git a/firmware/controllers/settings.cpp b/firmware/controllers/settings.cpp index 0659397e71..c89ecf4e2d 100644 --- a/firmware/controllers/settings.cpp +++ b/firmware/controllers/settings.cpp @@ -694,6 +694,14 @@ static void setCanTxPin(const char *pinName) { setIndividualPin(pinName, &engineConfiguration->canTxPin, "CAN TX"); } +static void setAuxRxpin(const char *pinName) { + setIndividualPin(pinName, &engineConfiguration->auxSerialRxPin, "AUX RX"); +} + +static void setAuxTxpin(const char *pinName) { + setIndividualPin(pinName, &engineConfiguration->auxSerialTxPin, "AUX TX"); +} + static void setAlternatorPin(const char *pinName) { setIndividualPin(pinName, &engineConfiguration->alternatorControlPin, "alternator"); } @@ -1444,6 +1452,9 @@ void initSettings(void) { addConsoleActionS("set_can_rx_pin", setCanRxPin); addConsoleActionS("set_can_tx_pin", setCanTxPin); + addConsoleActionS("set_aux_tx_pin", setAuxTxpin); + addConsoleActionS("set_aux_rx_pin", setAuxRxpin); + #if HAL_USE_ADC addConsoleActionSS("set_analog_input_pin", setAnalogInputPin); #endif diff --git a/firmware/hw_layer/drivers/drivers.mk b/firmware/hw_layer/drivers/drivers.mk index 19d4b8235e..43a70869d1 100644 --- a/firmware/hw_layer/drivers/drivers.mk +++ b/firmware/hw_layer/drivers/drivers.mk @@ -4,6 +4,7 @@ HW_LAYER_DRIVERS_INC = \ $(DRIVERS_DIR) \ $(DRIVERS_DIR)/gpio \ $(DRIVERS_DIR)/can \ + $(DRIVERS_DIR)/serial \ HW_LAYER_DRIVERS_CORE = \ $(DRIVERS_DIR)/gpio/core.c \ @@ -17,4 +18,4 @@ HW_LAYER_DRIVERS = \ HW_LAYER_DRIVERS_CPP = \ $(DRIVERS_DIR)/can/can_hw.cpp \ $(DRIVERS_DIR)/can/can_msg_tx.cpp \ - + $(DRIVERS_DIR)/serial/serial_hw.cpp \ \ No newline at end of file diff --git a/firmware/hw_layer/drivers/serial/serial_hw.cpp b/firmware/hw_layer/drivers/serial/serial_hw.cpp new file mode 100644 index 0000000000..f61d1fbfa2 --- /dev/null +++ b/firmware/hw_layer/drivers/serial/serial_hw.cpp @@ -0,0 +1,93 @@ +/** + * @file serial_hw.cpp + * @brief SERIAL bus low level code + * + * @date Apr 17, 2020 + * @author Konstantin Smola, (c) 2020 + */ + +#include "global.h" + +#if EFI_AUX_SERIAL + +#include "serial.h" +#include "engine_configuration.h" +#include "pin_repository.h" +#include "serial_hw.h" +#include "string.h" +#include "mpu_util.h" +#include "engine.h" + +EXTERN_ENGINE; + +static bool isSerialEnabled = false; +static bool isSerialTXEnabled = false; +static bool isSerialRXEnabled = false; +static LoggingWithStorage logger("SERIAL driver"); + +static SerialConfig uartCfg; +static SerialRead serialRead; + +static void auxInfo(void) { + if (!isSerialEnabled) { + scheduleMsg(&logger, "AUX Serial is not enabled, please enable & restart"); + return; + } + + scheduleMsg(&logger, "AUX Serial TX %s", hwPortname(CONFIG(auxSerialTxPin))); + scheduleMsg(&logger, "AUX Serial RX %s", hwPortname(CONFIG(auxSerialRxPin))); +} + +void enableAuxSerial(DECLARE_ENGINE_PARAMETER_SIGNATURE) { + engineConfiguration->auxSerialTxPin = CONFIG(auxSerialTxPin); + engineConfiguration->auxSerialRxPin = CONFIG(auxSerialRxPin); + engineConfiguration->auxSerialSpeed = CONFIG(auxSerialSpeed); + + uartCfg.speed = engineConfiguration->auxSerialSpeed; + sdStart(AUX_SERIAL_DEVICE, &uartCfg); + + scheduleMsg(&logger, "AUX Serial started"); +} + +void stopAuxSerialPins(DECLARE_ENGINE_PARAMETER_SIGNATURE) { + brain_pin_markUnused(activeConfiguration.auxSerialTxPin); + brain_pin_markUnused(activeConfiguration.auxSerialRxPin); +} + +void startAuxSerialPins(DECLARE_ENGINE_PARAMETER_SIGNATURE) { + if (CONFIG(auxSerialTxPin)) + efiSetPadMode("AuxSerial TX", CONFIG(auxSerialTxPin), PAL_MODE_ALTERNATE(8)); + if (CONFIG(auxSerialRxPin)) + efiSetPadMode("AuxSerial RX", CONFIG(auxSerialRxPin), PAL_MODE_ALTERNATE(8)); + + enableAuxSerial(); +} + +void initAuxSerial(void) { + addConsoleAction("auxinfo", auxInfo); + + isSerialEnabled = + (CONFIG(auxSerialTxPin)) || // we need at least one pin set + (CONFIG(auxSerialRxPin)); + + isSerialRXEnabled = CONFIG(auxSerialRxPin); + isSerialTXEnabled = CONFIG(auxSerialTxPin); + + // exit if no pin is configured + if (!isSerialEnabled) + return; + + // Validate pins + if (isSerialTXEnabled && !isValidSerialTxPin(CONFIG(auxSerialTxPin))) + return; + + if (isSerialRXEnabled && !isValidSerialRxPin(CONFIG(auxSerialRxPin))) + return; + + startAuxSerialPins(); + + if (isSerialRXEnabled) + serialRead.Start(); +} + +#endif // EFI_AUX_SERIAL \ No newline at end of file diff --git a/firmware/hw_layer/drivers/serial/serial_hw.h b/firmware/hw_layer/drivers/serial/serial_hw.h new file mode 100644 index 0000000000..f6499d438f --- /dev/null +++ b/firmware/hw_layer/drivers/serial/serial_hw.h @@ -0,0 +1,21 @@ +/** + * @file serial_hw.h + * @brief SERIAL bus low level code + * + * @date Apr 17, 2020 + * @author Konstantin Smola, (c) 2020 + */ + +#pragma once + +#include "efifeatures.h" +#if EFI_TUNER_STUDIO +#include "tunerstudio_configuration.h" +#endif /* EFI_TUNER_STUDIO */ + +void initAuxSerial(void); +#if EFI_AUX_SERIAL +void stopAuxSerialPins(DECLARE_ENGINE_PARAMETER_SIGNATURE); +void startAuxSerialPins(DECLARE_ENGINE_PARAMETER_SIGNATURE); +void enableAuxSerial(DECLARE_ENGINE_PARAMETER_SIGNATURE); +#endif //EFI_AUX_SERIAL \ No newline at end of file diff --git a/firmware/hw_layer/hardware.cpp b/firmware/hw_layer/hardware.cpp index cbef286ff2..31b29b4bf6 100644 --- a/firmware/hw_layer/hardware.cpp +++ b/firmware/hw_layer/hardware.cpp @@ -28,6 +28,7 @@ #include "eficonsole.h" #include "console_io.h" #include "sensor_chart.h" +#include "serial_hw.h" #include "mpu_util.h" //#include "usb_msd.h" @@ -289,6 +290,10 @@ void applyNewHardwareSettings(void) { stopCanPins(); #endif /* EFI_CAN_SUPPORT */ +#if EFI_AUX_SERIAL + stopAuxSerialPins(); +#endif /* EFI_AUX_SERIAL */ + #if EFI_HIP_9011 stopHip9001_pins(); #endif /* EFI_HIP_9011 */ @@ -364,6 +369,10 @@ void applyNewHardwareSettings(void) { startCanPins(); #endif /* EFI_CAN_SUPPORT */ +#if EFI_AUX_SERIAL + startAuxSerialPins(); +#endif /* EFI_AUX_SERIAL */ + #if EFI_HIP_9011 startHip9001_pins(); #endif /* EFI_HIP_9011 */ @@ -559,6 +568,9 @@ void initHardware(Logging *l) { addConsoleActionII("i2c", sendI2Cbyte); #endif +#if EFI_AUX_SERIAL + initAuxSerial(); +#endif /* EFI_AUX_SERIAL */ // USBMassStorageDriver UMSD1; diff --git a/firmware/hw_layer/ports/mpu_util.h b/firmware/hw_layer/ports/mpu_util.h index 82302b972a..6045fa46b8 100644 --- a/firmware/hw_layer/ports/mpu_util.h +++ b/firmware/hw_layer/ports/mpu_util.h @@ -15,6 +15,9 @@ bool isValidCanRxPin(brain_pin_e pin); CANDriver * detectCanDevice(brain_pin_e pinRx, brain_pin_e pinTx); #endif // HAL_USE_CAN +bool isValidSerialTxPin(brain_pin_e pin); +bool isValidSerialRxPin(brain_pin_e pin); + // SPI #if HAL_USE_SPI void initSpiModule(SPIDriver *driver, brain_pin_e sck, brain_pin_e miso, diff --git a/firmware/hw_layer/ports/stm32/stm32_common.cpp b/firmware/hw_layer/ports/stm32/stm32_common.cpp index 15aba2c2c0..8ddadae2bc 100644 --- a/firmware/hw_layer/ports/stm32/stm32_common.cpp +++ b/firmware/hw_layer/ports/stm32/stm32_common.cpp @@ -145,3 +145,23 @@ void jump_to_bootloader() { NVIC_SystemReset(); } #endif /* EFI_PROD_CODE */ + +#if EFI_AUX_SERIAL + +static bool isValidUART6TxPin(brain_pin_e pin) { + return pin == GPIOC_6 || pin == GPIOG_14; +} + +static bool isValidUART6RxPin(brain_pin_e pin) { + return pin == GPIOC_7 || pin == GPIOG_9; +} + +bool isValidSerialTxPin(brain_pin_e pin) { + return isValidUART6TxPin(pin); +} + +bool isValidSerialRxPin(brain_pin_e pin) { + return isValidUART6RxPin(pin); +} + +#endif /*EFI_AUX_SERIAL*/ \ No newline at end of file