diff --git a/firmware/controllers/actuators/aux_pid.cpp b/firmware/controllers/actuators/aux_pid.cpp index 1b45c5f6da..9937b935ce 100644 --- a/firmware/controllers/actuators/aux_pid.cpp +++ b/firmware/controllers/actuators/aux_pid.cpp @@ -134,9 +134,11 @@ void startAuxPins(void) { } void stopAuxPins(void) { +#if EFI_PROD_CODE for (int i = 0;i < AUX_PID_COUNT;i++) { brain_pin_markUnused(activeConfiguration.auxPidPins[i]); } +#endif /* EFI_PROD_CODE */ } void initAuxPid(Logging *sharedLogger) { diff --git a/firmware/controllers/actuators/idle_thread.cpp b/firmware/controllers/actuators/idle_thread.cpp index 4fcd9d0e5f..8d1df16454 100644 --- a/firmware/controllers/actuators/idle_thread.cpp +++ b/firmware/controllers/actuators/idle_thread.cpp @@ -539,6 +539,7 @@ bool isIdleHardwareRestartNeeded() { } void stopIdleHardware(DECLARE_ENGINE_PARAMETER_SIGNATURE) { +#if EFI_PROD_CODE brain_pin_markUnused(activeConfiguration.stepperEnablePin); brain_pin_markUnused(activeConfiguration.bc.idle.stepperStepPin); brain_pin_markUnused(activeConfiguration.bc.idle.solenoidPin); @@ -546,7 +547,7 @@ void stopIdleHardware(DECLARE_ENGINE_PARAMETER_SIGNATURE) { // brain_pin_markUnused(activeConfiguration.bc.idle.); // brain_pin_markUnused(activeConfiguration.bc.idle.); // brain_pin_markUnused(activeConfiguration.bc.idle.); - +#endif /* EFI_PROD_CODE */ } void initIdleHardware(DECLARE_ENGINE_PARAMETER_SIGNATURE) { diff --git a/firmware/controllers/algo/engine.cpp b/firmware/controllers/algo/engine.cpp index c577b96f5b..337409f13d 100644 --- a/firmware/controllers/algo/engine.cpp +++ b/firmware/controllers/algo/engine.cpp @@ -121,7 +121,9 @@ void Engine::periodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) { #if EFI_FSIO runFsio(PASS_ENGINE_PARAMETER_SIGNATURE); -#endif /* EFI_PROD_CODE && EFI_FSIO */ +#else + runHardcodedFsio(PASS_ENGINE_PARAMETER_SIGNATURE); +#endif /* EFI_FSIO */ cylinderCleanupControl(PASS_ENGINE_PARAMETER_SIGNATURE); diff --git a/firmware/controllers/core/fsio_impl.cpp b/firmware/controllers/core/fsio_impl.cpp index d651b152dc..12ee852bbb 100644 --- a/firmware/controllers/core/fsio_impl.cpp +++ b/firmware/controllers/core/fsio_impl.cpp @@ -12,13 +12,13 @@ */ #include "global.h" +#include "fsio_impl.h" +#include "allsensors.h" #if EFI_FSIO #include "os_access.h" -#include "fsio_impl.h" #include "settings.h" -#include "allsensors.h" #include "rpm_calculator.h" #include "efi_gpio.h" #include "pwm_generator_logic.h" @@ -102,6 +102,7 @@ static LEElement * acRelayLogic; static LEElement * fuelPumpLogic; static LEElement * radiatorFanLogic; static LEElement * alternatorLogic; +static LEElement * starterRelayLogic; #if EFI_MAIN_RELAY_CONTROL static LEElement * mainRelayLogic; @@ -464,6 +465,9 @@ void runFsio(DECLARE_ENGINE_PARAMETER_SIGNATURE) { enginePins.mainRelay.setValue(true); #endif /* EFI_MAIN_RELAY_CONTROL */ + if (CONFIGB(starterRelayPin) != GPIO_UNASSIGNED) + setPinState("starter_relay", &enginePins.starterRelay, starterRelayLogic PASS_ENGINE_PARAMETER_SUFFIX); + /** * o2 heater is off during cranking * todo: convert to FSIO? @@ -673,6 +677,8 @@ void initFsioImpl(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { if (CONFIGB(mainRelayPin) != GPIO_UNASSIGNED) mainRelayLogic = sysPool.parseExpression(MAIN_RELAY_LOGIC); #endif /* EFI_MAIN_RELAY_CONTROL */ + if (CONFIGB(starterRelayPin) != GPIO_UNASSIGNED) + starterRelayLogic = sysPool.parseExpression(STARTER_RELAY_LOGIC); #if EFI_PROD_CODE for (int i = 0; i < FSIO_COMMAND_COUNT; i++) { @@ -724,5 +730,37 @@ void initFsioImpl(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { } +#else /* !EFI_FSIO */ + +EXTERN_ENGINE +; +extern EnginePins enginePins; + +// "Limp-mode" implementation for some RAM-limited configs without FSIO +void runHardcodedFsio(DECLARE_ENGINE_PARAMETER_SIGNATURE) { + // see MAIN_RELAY_LOGIC + if (CONFIGB(mainRelayPin) != GPIO_UNASSIGNED) { + enginePins.mainRelay.setValue((getTimeNowSeconds() < 2) || (getVBatt(PASS_ENGINE_PARAMETER_SIGNATURE) > 5) || engine->isInShutdownMode()); + } + // see STARTER_RELAY_LOGIC + if (CONFIGB(starterRelayPin) != GPIO_UNASSIGNED) { + enginePins.starterRelay.setValue(engine->rpmCalculator.getRpm() < engineConfiguration->cranking.rpm); + } + // see FAN_CONTROL_LOGIC + if (CONFIGB(fanPin) != GPIO_UNASSIGNED) { + enginePins.fanRelay.setValue((enginePins.fanRelay.getLogicValue() && (getCoolantTemperature() > engineConfiguration->fanOffTemperature)) || + (getCoolantTemperature() > engineConfiguration->fanOnTemperature) || engine->isCltBroken); + } + // see AC_RELAY_LOGIC + if (CONFIGB(acRelayPin) != GPIO_UNASSIGNED) { + enginePins.acRelay.setValue(getAcToggle(PASS_ENGINE_PARAMETER_SIGNATURE) && engine->rpmCalculator.getRpm() > 850); + } + // see FUEL_PUMP_LOGIC + if (CONFIGB(fuelPumpPin) != GPIO_UNASSIGNED) { + enginePins.fuelPumpRelay.setValue((getTimeNowSeconds() < engineConfiguration->startUpFuelPumpDuration) || (engine->rpmCalculator.getRpm() > 0)); + } + + enginePins.o2heater.setValue(engine->rpmCalculator.isRunning(PASS_ENGINE_PARAMETER_SIGNATURE)); +} #endif /* EFI_FSIO */ diff --git a/firmware/controllers/core/fsio_impl.h b/firmware/controllers/core/fsio_impl.h index f9f728dadc..37fd5d3153 100644 --- a/firmware/controllers/core/fsio_impl.h +++ b/firmware/controllers/core/fsio_impl.h @@ -39,6 +39,7 @@ void setFsioExpression(const char *indexStr, const char *quotedLine DECLARE_ENGI float getFsioOutputValue(int index DECLARE_ENGINE_PARAMETER_SUFFIX); void applyFsioConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE); void onConfigurationChangeFsioCallback(engine_configuration_s *previousConfiguration DECLARE_ENGINE_PARAMETER_SUFFIX); +void runHardcodedFsio(DECLARE_ENGINE_PARAMETER_SIGNATURE); ValueProvider3D *getFSIOTable(int index); diff --git a/firmware/controllers/settings.cpp b/firmware/controllers/settings.cpp index b465d5849d..053fa14f3b 100644 --- a/firmware/controllers/settings.cpp +++ b/firmware/controllers/settings.cpp @@ -115,6 +115,9 @@ static void printOutputs(const engine_configuration_s *engineConfiguration) { scheduleMsg(&logger, "mainRelay: mode %s @ %s", getPin_output_mode_e(boardConfiguration->mainRelayPinMode), hwPortname(boardConfiguration->mainRelayPin)); + scheduleMsg(&logger, "starterRelay: mode %s @ %s", getPin_output_mode_e(boardConfiguration->starterRelayPinMode), + hwPortname(boardConfiguration->starterRelayPin)); + scheduleMsg(&logger, "alternator field: mode %s @ %s", getPin_output_mode_e(boardConfiguration->alternatorControlPinMode), hwPortname(boardConfiguration->alternatorControlPin)); @@ -696,6 +699,10 @@ static void setMainRelayPin(const char *pinName) { setIndividualPin(pinName, &boardConfiguration->mainRelayPin, "main relay"); } +static void setStarterRelayPin(const char *pinName) { + setIndividualPin(pinName, &boardConfiguration->starterRelayPin, "starter relay"); +} + static void setAlternatorPin(const char *pinName) { setIndividualPin(pinName, &boardConfiguration->alternatorControlPin, "alternator"); } @@ -1431,6 +1438,7 @@ void initSettings(void) { addConsoleActionS("set_alternator_pin", setAlternatorPin); addConsoleActionS("set_idle_pin", setIdlePin); addConsoleActionS("set_main_relay_pin", setMainRelayPin); + addConsoleActionS("set_starter_relay_pin", setStarterRelayPin); #if HAL_USE_ADC addConsoleActionSS("set_analog_input_pin", setAnalogInputPin); diff --git a/firmware/controllers/system/efi_gpio.cpp b/firmware/controllers/system/efi_gpio.cpp index 20ff5f4f5b..3616753985 100644 --- a/firmware/controllers/system/efi_gpio.cpp +++ b/firmware/controllers/system/efi_gpio.cpp @@ -30,7 +30,7 @@ extern WaveChart waveChart; // todo: clean this mess, this should become 'static'/private EnginePins enginePins; -extern LoggingWithStorage sharedLogger; +static Logging* logger; pin_output_mode_e DEFAULT_OUTPUT = OM_DEFAULT; @@ -144,6 +144,7 @@ void EnginePins::unregisterPins() { unregisterOutputIfPinOrModeChanged(alternatorPin, bc.alternatorControlPin, bc.alternatorControlPinMode); unregisterOutputIfPinOrModeChanged(mainRelay, bc.mainRelayPin, bc.mainRelayPinMode); + unregisterOutputIfPinOrModeChanged(starterRelay, bc.starterRelayPin, bc.starterRelayPinMode); #endif /* EFI_PROD_CODE */ } @@ -264,7 +265,7 @@ bool NamedOutputPin::stop() { #if EFI_GPIO_HARDWARE if (isInitialized() && getLogicValue()) { setValue(false); - scheduleMsg(&sharedLogger, "turning off %s", name); + scheduleMsg(logger, "turning off %s", name); return true; } #endif /* EFI_GPIO_HARDWARE */ @@ -374,6 +375,7 @@ void initOutputPins(DECLARE_ENGINE_PARAMETER_SIGNATURE) { enginePins.fuelPumpRelay.initPin("fuel pump relay", CONFIGB(fuelPumpPin), &CONFIGB(fuelPumpPinMode)); enginePins.mainRelay.initPin("main relay", CONFIGB(mainRelayPin), &CONFIGB(mainRelayPinMode)); + enginePins.starterRelay.initPin("starter relay", CONFIGB(starterRelayPin), &CONFIGB(starterRelayPinMode)); enginePins.fanRelay.initPin("fan relay", CONFIGB(fanPin), &CONFIGB(fanPinMode)); enginePins.o2heater.initPin("o2 heater", CONFIGB(o2heaterPin)); @@ -474,7 +476,7 @@ void OutputPin::initPin(const char *msg, brain_pin_e brainPin, const pin_output_ void OutputPin::unregisterOutput(brain_pin_e oldPin) { if (oldPin != GPIO_UNASSIGNED) { - scheduleMsg(&sharedLogger, "unregistering %s", hwPortname(oldPin)); + scheduleMsg(logger, "unregistering %s", hwPortname(oldPin)); #if EFI_GPIO_HARDWARE && EFI_PROD_CODE brain_pin_markUnused(oldPin); port = nullptr; @@ -489,7 +491,8 @@ void OutputPin::unregisterOutput(brain_pin_e oldPin) { ioportid_t errorLedPort; ioportmask_t errorLedPin; -void initPrimaryPins(void) { +void initPrimaryPins(Logging *sharedLogger) { + logger = sharedLogger; #if EFI_PROD_CODE enginePins.errorLedPin.initPin("led: ERROR status", LED_ERROR_BRAIN_PIN); errorLedPort = getHwPort("primary", LED_ERROR_BRAIN_PIN); diff --git a/firmware/controllers/system/efi_gpio.h b/firmware/controllers/system/efi_gpio.h index f9d5b4fe33..e1b60f3c12 100644 --- a/firmware/controllers/system/efi_gpio.h +++ b/firmware/controllers/system/efi_gpio.h @@ -13,7 +13,7 @@ #include "io_pins.h" #include "engine_configuration.h" -void initPrimaryPins(void); +void initPrimaryPins(Logging *sharedLogger); void initOutputPins(DECLARE_ENGINE_PARAMETER_SIGNATURE); #if EFI_GPIO_HARDWARE @@ -124,6 +124,7 @@ public: void stopInjectionPins(); void stopIgnitionPins(); OutputPin mainRelay; + OutputPin starterRelay; OutputPin fanRelay; // see acRelayPin OutputPin acRelay; diff --git a/firmware/controllers/system_fsio.h b/firmware/controllers/system_fsio.h index 4b808a71b9..d316277fc0 100644 --- a/firmware/controllers/system_fsio.h +++ b/firmware/controllers/system_fsio.h @@ -68,7 +68,7 @@ // starter block using configurable parameter // Human-readable: rpm < cranking_rpm -#define STARTER_BLOCK "rpm cranking_rpm <" +#define STARTER_RELAY_LOGIC "rpm cranking_rpm <" // Human-readable: fsio_table (3, rpm, map) / 100 #define BOOST_CONTROLLER "3 rpm map fsio_table 100 /" diff --git a/firmware/controllers/system_fsio.txt b/firmware/controllers/system_fsio.txt index fc2761e3ff..8a6148ca9f 100644 --- a/firmware/controllers/system_fsio.txt +++ b/firmware/controllers/system_fsio.txt @@ -46,7 +46,7 @@ RPM_ABOVE_6000_SOLENOID_80_DUTY=(rpm > 6000) * 0.8 RPM_BELOW_USER_SETTING_1=rpm < fsio_setting(1) # starter block using configurable parameter -STARTER_BLOCK=rpm < cranking_rpm +STARTER_RELAY_LOGIC=rpm < cranking_rpm BOOST_CONTROLLER=fsio_table (3, rpm, map) / 100 diff --git a/firmware/hw_layer/hardware.cpp b/firmware/hw_layer/hardware.cpp index d4b5cdde01..19ec970629 100644 --- a/firmware/hw_layer/hardware.cpp +++ b/firmware/hw_layer/hardware.cpp @@ -419,7 +419,7 @@ void initHardware(Logging *l) { /** * We need the LED_ERROR pin even before we read configuration */ - initPrimaryPins(); + initPrimaryPins(sharedLogger); if (hasFirmwareError()) { return; diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 89f09d181e..306d6c8398 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -1084,6 +1084,7 @@ menuDialog = main # Digital outputs subMenu = mainRelay, "Main relay" + subMenu = starterRelay, "Starter relay" subMenu = fuelPump, "Fuel rail" subMenu = fanSetting, "Fan" subMenu = tachSettings, "Tachometer" @@ -1652,6 +1653,8 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" field = "Fan Pin Mode", fanPinMode field = "Main Relay Pin", mainRelayPin field = "Main Relay Mode", mainRelayPinMode + field = "Starter Relay Pin", starterRelayPin + field = "Starter Relay Mode", starterRelayPinMode field = "aux valve #1", auxValves1 field = "aux valve #2", auxValves2 @@ -1995,6 +1998,10 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" field = "Pin", mainRelayPin field = "Pin mode", mainRelayPinMode + dialog = starterRelay, "Starter relay output" + field = "Pin", starterRelayPin + field = "Pin mode", starterRelayPinMode + dialog = statusLeds, "Status LEDs" field = "Running status LED", runningLedPin field = "TS communication status LED", communicationLedPin diff --git a/unit_tests/tests/test_logic_expression.cpp b/unit_tests/tests/test_logic_expression.cpp index 5d4c92e668..96c024528e 100644 --- a/unit_tests/tests/test_logic_expression.cpp +++ b/unit_tests/tests/test_logic_expression.cpp @@ -228,7 +228,7 @@ TEST(fsio, testLogicExpressions) { engine->fsioState.mockCrankingRpm = 200; testExpression2(0, "rpm", 900, engine); testExpression2(0, "cranking_rpm", 200, engine); - testExpression2(0, STARTER_BLOCK, 0, engine); + testExpression2(0, STARTER_RELAY_LOGIC, 0, engine); testExpression2(0, "rpm cranking_rpm > ", 1, engine); } }