diff --git a/firmware/controllers/algo/engine.h b/firmware/controllers/algo/engine.h index 7afe8d15cd..19045e39b4 100644 --- a/firmware/controllers/algo/engine.h +++ b/firmware/controllers/algo/engine.h @@ -16,6 +16,7 @@ #include "accel_enrichment.h" #include "trigger_central.h" #include "local_version_holder.h" +#include "tcu.h" #if EFI_SIGNAL_EXECUTOR_ONE_TIMER // PROD real firmware uses this implementation @@ -52,11 +53,6 @@ class IEtbController; class IFuelComputer; class IInjectorModel; -class TCU { -public: - gear_e currentGear = NEUTRAL; -}; - class PrimaryTriggerConfiguration : public TriggerConfiguration { public: PrimaryTriggerConfiguration(Engine *engine); @@ -94,11 +90,11 @@ public: cyclic_buffer triggerErrorDetection; + GearControllerBase *gearController; + PrimaryTriggerConfiguration primaryTriggerConfiguration; VvtTriggerConfiguration vvtTriggerConfiguration; - TCU tcu; - #if EFI_SHAFT_POSITION_INPUT void OnTriggerStateDecodingError(); void OnTriggerStateProperState(efitick_t nowNt) override; diff --git a/firmware/controllers/controllers.mk b/firmware/controllers/controllers.mk index 73a5cac59e..6874f7ce9f 100644 --- a/firmware/controllers/controllers.mk +++ b/firmware/controllers/controllers.mk @@ -48,6 +48,7 @@ CONTROLLERS_SRC_CPP = \ $(CONTROLLERS_DIR)/persistent_store.cpp \ $(CONTROLLERS_DIR)/serial/serial_rx.cpp \ $(CONTROLLERS_DIR)/serial/serial_sensor.cpp \ + $(CONTROLLERS_DIR)/tcu.cpp \ CONTROLLERS_INC=\ diff --git a/firmware/controllers/engine_controller.cpp b/firmware/controllers/engine_controller.cpp index 59a132935a..948ec7dd29 100644 --- a/firmware/controllers/engine_controller.cpp +++ b/firmware/controllers/engine_controller.cpp @@ -263,6 +263,10 @@ static void doPeriodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) { engine->periodicSlowCallback(PASS_ENGINE_PARAMETER_SIGNATURE); #endif /* if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT */ + + if (CONFIG(tcuEnabled)) { + engine->gearController->update(); + } } void initPeriodicEvents(DECLARE_ENGINE_PARAMETER_SIGNATURE) { diff --git a/firmware/controllers/tcu.cpp b/firmware/controllers/tcu.cpp new file mode 100644 index 0000000000..29011cdb41 --- /dev/null +++ b/firmware/controllers/tcu.cpp @@ -0,0 +1,50 @@ +/** + * @file tcu.cpp + * @brief Base classes for gear selection and transmission control + * + * @date Aug 31, 2020 + * @author David Holdeman, (c) 2020 + */ + +#include "tcu.h" +#include "tunerstudio_outputs.h" + +void TransmissionControllerBase::update(gear_e gear) { + setCurrentGear(gear); + postState(); +} + +gear_e TransmissionControllerBase::setCurrentGear(gear_e gear) { + currentGear = gear; + return getCurrentGear(); +} + +gear_e TransmissionControllerBase::getCurrentGear() const { + return currentGear; +} + +void TransmissionControllerBase::postState() { +#if EFI_TUNER_STUDIO + tsOutputChannels.tcuCurrentGear = getCurrentGear(); +#endif +} + +void GearControllerBase::update() { + transmissionController.update(getDesiredGear()); + postState(); +} + +gear_e GearControllerBase::getDesiredGear() const { + return desiredGear; +} + +gear_e GearControllerBase::setDesiredGear(gear_e gear) { + desiredGear = gear; + return getDesiredGear(); +} + +void GearControllerBase::postState() { +#if EFI_TUNER_STUDIO + tsOutputChannels.tcuDesiredGear = getDesiredGear(); +#endif +} diff --git a/firmware/controllers/tcu.h b/firmware/controllers/tcu.h new file mode 100644 index 0000000000..e8c522146a --- /dev/null +++ b/firmware/controllers/tcu.h @@ -0,0 +1,37 @@ +/** + * @file tcu.h + * @brief Base classes for gear selection and transmission control + * + * @date Aug 31, 2020 + * @author David Holdeman, (c) 2020 + */ +#pragma once + +#include "global.h" +#include "io_pins.h" +#include "persistent_configuration.h" +#include "engine_configuration_generated_structures.h" +#include "globalaccess.h" + +class TransmissionControllerBase { +public: + void update(gear_e); + gear_e getCurrentGear() const; +private: + gear_e currentGear = NEUTRAL; +protected: + gear_e setCurrentGear(gear_e); + void postState(); +}; + +class GearControllerBase { +public: + virtual void update(); + gear_e getDesiredGear() const; +private: + gear_e desiredGear = NEUTRAL; +protected: + gear_e setDesiredGear(gear_e); + void postState(); + TransmissionControllerBase transmissionController; +}; diff --git a/firmware/hw_layer/debounce.cpp b/firmware/hw_layer/debounce.cpp new file mode 100644 index 0000000000..185162aaec --- /dev/null +++ b/firmware/hw_layer/debounce.cpp @@ -0,0 +1,49 @@ +/** + * @file debounce.cpp + * @brief Generic button debounce class + * + * @date Aug 31, 2020 + * @author David Holdeman, (c) 2020 + */ +#include "debounce.h" + +void ButtonDebounce::init (int t, brain_pin_e p, pin_input_mode_e m) { + threshold = MS2NT(t); + timeLast = 0; + pin = p; +#ifdef PAL_MODE_INPUT_PULLDOWN + // getInputMode converts from pin_input_mode_e to iomode_t + mode = getInputMode(m); + efiSetPadMode("Button", p, mode); +#endif +} + +/** +@returns true if the button is pressed, and will not return true again within the set timeout +*/ +bool ButtonDebounce::readPinEvent() { + if (!pin) { + return false; + } + efitick_t timeNow = getTimeNowNt(); + // If it's been less than the threshold since we were last called + if ((timeNow - timeLast) < threshold) { + return false; + } + // readValue is a class variable, so it needs to be reset. + // We don't actually need it to be a class variable in this method, + // but when a method is implemented to actually get the pin's state, + // for example to implement long button presses, it will be needed. + readValue = false; +#ifdef PAL_MODE_INPUT_PULLDOWN + readValue = efiReadPin(pin); + // Invert + if (mode != PAL_MODE_INPUT_PULLDOWN) { + readValue = !readValue; + } +#endif + if (readValue) { + timeLast = timeNow; + } + return readValue; +} diff --git a/firmware/hw_layer/debounce.h b/firmware/hw_layer/debounce.h new file mode 100644 index 0000000000..88594e2ff1 --- /dev/null +++ b/firmware/hw_layer/debounce.h @@ -0,0 +1,21 @@ +/** + * @file debounce.h + * @brief Generic button debounce class + * + * @date Aug 31, 2020 + * @author David Holdeman, (c) 2020 + */ +#include "globalaccess.h" +#include "io_pins.h" + +class ButtonDebounce { +public: + void init(int t, brain_pin_e p, pin_input_mode_e m); + bool readPinEvent(); +private: + int threshold; + efitick_t timeLast; + brain_pin_e pin; + iomode_t mode; + bool readValue; +}; diff --git a/firmware/hw_layer/hw_layer.mk b/firmware/hw_layer/hw_layer.mk index c378ebcee1..f71e3cc7d9 100644 --- a/firmware/hw_layer/hw_layer.mk +++ b/firmware/hw_layer/hw_layer.mk @@ -42,10 +42,11 @@ HW_LAYER_EMS_CPP = $(HW_LAYER_EGT_CPP) \ $(PROJECT_DIR)/hw_layer/io_pins.cpp \ $(PROJECT_DIR)/hw_layer/rtc_helper.cpp \ $(PROJECT_DIR)/hw_layer/cdm_ion_sense.cpp \ - $(PROJECT_DIR)/hw_layer/backup_ram.cpp + $(PROJECT_DIR)/hw_layer/backup_ram.cpp \ + $(PROJECT_DIR)/hw_layer/debounce.cpp # # '-include' is a magic kind of 'include' which would survive if file to be included is not found # -include $(PROJECT_DIR)/hw_layer/$(CPU_HWLAYER)/hw_ports.mk - \ No newline at end of file + diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 8cf2bb86de..8d39da3b42 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -301,9 +301,6 @@ custom switch_input_pin_e 1 bits, U08, @OFFSET@, [0:7], @@switch_input_pin_ #define output_pin_e_enum "NONE", "INVALID", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15", "PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7", "PB8", "PB9", "PB10", "PB11", "PB12", "PB13", "PB14", "PB15", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "PC6", "PC7", "PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", "PC15", "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PD8", "PD9", "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", "PE0", "PE1", "PE2", "PE3", "PE4", "PE5", "PE6","PE7","PE8","PE9","PE10","PE11","PE12","PE13","PE14","PE15", "PF0","PF1","PF2","PF3","PF4","PF5","PF6","PF7","PF8","PF9","PF10","PF11","PF12","PF13","PF14","PF15", "PG0","PG1","PG2","PG3","PG4","PG5","PG6","PG7","PG8","PG9","PG10","PG11","PG12","PG13","PG14","PG15", "PH0","PH1","PH2","PH3","PH4","PH5","PH6","PH7","PH8","PH9","PH10","PH11","PH12","PH13","PH14","PH15","TLE6240_1", "TLE6240_2", "TLE6240_3", "TLE6240_4", "TLE6240_5", "TLE6240_6", "TLE6240_7", "TLE6240_8", "TLE6240_9", "TLE6240_10", "TLE6240_11", "TLE6240_12", "TLE6240_13", "TLE6240_14", "TLE6240_15", "TLE6240_16", "MC33972_1", "MC33972_2", "MC33972_3", "MC33972_4", "MC33972_5", "MC33972_6", "MC33972_7", "MC33972_8", "MC33972_9", "MC33972_10", "MC33972_11", "MC33972_12", "MC33972_13", "MC33972_14", "MC33972_15", "MC33972_16", "MC33972_17", "MC33972_18", "MC33972_19", "MC33972_20", "MC33972_21", "MC33972_22", "TLE8888_1", "TLE8888_2", "TLE8888_3", "TLE8888_4", "TLE8888_5", "TLE8888_6", "TLE8888_7", "TLE8888_8", "TLE8888_9", "TLE8888_10", "TLE8888_11", "TLE8888_12", "TLE8888_13", "TLE8888_14", "TLE8888_15", "TLE8888_16", "TLE8888_17", "TLE8888_18", "TLE8888_19", "TLE8888_20", "TLE8888_21", "TLE8888_22", "TLE8888_23", "TLE8888_24", "TLE8888_25", "TLE8888_26", "TLE8888_27", "TLE8888_28", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" custom output_pin_e 1 bits, U08, @OFFSET@, [0:7], @@output_pin_e_enum@@ - - - #define pin_output_mode_e_enum "default", "default inverted", "open collector", "open collector inverted" custom pin_output_mode_e 1 bits, U08, @OFFSET@, [0:1], @@pin_output_mode_e_enum@@