diff --git a/firmware/config/engines/mazda_miata_1_6.cpp b/firmware/config/engines/mazda_miata_1_6.cpp index cf6371d392..35abc20528 100644 --- a/firmware/config/engines/mazda_miata_1_6.cpp +++ b/firmware/config/engines/mazda_miata_1_6.cpp @@ -334,7 +334,7 @@ void setMiataNA6_MAP_Frankenso(DECLARE_CONFIG_PARAMETER_SIGNATURE) { engineConfiguration->throttlePedalUpPin = GPIOA_7; // green wire from 1Q/W17 to bottom of W46 - engineConfiguration->acSwitchAdc = EFI_ADC_6; // PA6 + engineConfiguration->acSwitch = GPIOA_6; #if ! EFI_UNIT_TEST // W57 PE3 A/C compressor relay out @@ -430,7 +430,7 @@ void setMiataNA6_MAP_MRE(DECLARE_CONFIG_PARAMETER_SIGNATURE) { // EFI_ADC_3: "22 - AN temp 4" - engineConfiguration->acSwitchAdc = EFI_ADC_3; + engineConfiguration->acSwitch = GPIOA_6; engineConfiguration->warningLedPin = GPIOD_13; engineConfiguration->triggerErrorPin = GPIOE_1; diff --git a/firmware/controllers/algo/engine2.cpp b/firmware/controllers/algo/engine2.cpp index a6190c8ca9..45a1d78ffe 100644 --- a/firmware/controllers/algo/engine2.cpp +++ b/firmware/controllers/algo/engine2.cpp @@ -108,10 +108,6 @@ TransmissionState::TransmissionState() { EngineState::EngineState() { timeSinceLastTChargeK = getTimeNowNt(); - -#if ! EFI_PROD_CODE - memset(mockPinStates, 0, sizeof(mockPinStates)); -#endif /* EFI_PROD_CODE */ } void EngineState::updateSlowSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE) { diff --git a/firmware/controllers/algo/engine_configuration.cpp b/firmware/controllers/algo/engine_configuration.cpp index 233ce9ea5e..a047d1f06f 100644 --- a/firmware/controllers/algo/engine_configuration.cpp +++ b/firmware/controllers/algo/engine_configuration.cpp @@ -335,7 +335,6 @@ void prepareVoidConfiguration(engine_configuration_s *engineConfiguration) { */ engineConfiguration->tps2_1AdcChannel = EFI_ADC_NONE; engineConfiguration->auxFastSensor1_adcChannel = EFI_ADC_NONE; - engineConfiguration->acSwitchAdc = EFI_ADC_NONE; engineConfiguration->externalKnockSenseAdc = EFI_ADC_NONE; engineConfiguration->fuelLevelSensor = EFI_ADC_NONE; engineConfiguration->hipOutputChannel = EFI_ADC_NONE; diff --git a/firmware/controllers/algo/engine_state.h b/firmware/controllers/algo/engine_state.h index 1211cc901e..8b8a31118c 100644 --- a/firmware/controllers/algo/engine_state.h +++ b/firmware/controllers/algo/engine_state.h @@ -13,8 +13,6 @@ #include "pid.h" #include "engine_state_generated.h" -#define BRAIN_PIN_COUNT (1 << sizeof(brain_pin_e)) - class EngineState : public engine_state2_s { public: EngineState(); @@ -22,10 +20,6 @@ public: void updateSlowSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE); void updateTChargeK(int rpm, float tps DECLARE_ENGINE_PARAMETER_SUFFIX); -#if ! EFI_PROD_CODE - bool mockPinStates[BRAIN_PIN_COUNT]; -#endif - FuelConsumptionState fuelConsumption; efitick_t crankingTime = 0; diff --git a/firmware/controllers/engine_controller.cpp b/firmware/controllers/engine_controller.cpp index 88aa29e5b3..85d2e41fa6 100644 --- a/firmware/controllers/engine_controller.cpp +++ b/firmware/controllers/engine_controller.cpp @@ -351,7 +351,6 @@ static void printAnalogInfo(void) { printAnalogChannelInfo("CJ UR", engineConfiguration->cj125ur); printAnalogChannelInfo("CJ UA", engineConfiguration->cj125ua); - printAnalogChannelInfo("A/C sw", engineConfiguration->acSwitchAdc); printAnalogChannelInfo("HIP9011", engineConfiguration->hipOutputChannel); for (int i = 0; i < FSIO_ANALOG_INPUT_COUNT ; i++) { diff --git a/firmware/controllers/engine_controller.h b/firmware/controllers/engine_controller.h index 64752173e9..28741d0ca5 100644 --- a/firmware/controllers/engine_controller.h +++ b/firmware/controllers/engine_controller.h @@ -31,6 +31,7 @@ void setMockAfrVoltage(float voltage DECLARE_ENGINE_PARAMETER_SUFFIX); void setMockMafVoltage(float voltage DECLARE_ENGINE_PARAMETER_SUFFIX); void setMockIatVoltage(float voltage DECLARE_ENGINE_PARAMETER_SUFFIX); void setMockCltVoltage(float voltage DECLARE_ENGINE_PARAMETER_SUFFIX); +void setMockState(brain_pin_e pin, bool state DECLARE_ENGINE_PARAMETER_SUFFIX); void printCurrentState(Logging *logging, int seconds, const char *engineTypeName, const char *firmwareBuildId); diff --git a/firmware/controllers/engine_controller_misc.cpp b/firmware/controllers/engine_controller_misc.cpp index ca1b090fd1..61d80dd722 100644 --- a/firmware/controllers/engine_controller_misc.cpp +++ b/firmware/controllers/engine_controller_misc.cpp @@ -15,6 +15,10 @@ EXTERN_ENGINE; extern LoggingWithStorage sharedLogger; extern ButtonDebounce startStopButtonDebounce; +#if ! EFI_PROD_CODE +extern bool mockPinStates[(1 << sizeof(brain_pin_e))]; +#endif + #if ENABLE_PERF_TRACE static uint8_t nextThreadId = 0; void threadInitHook(void* vtp) { @@ -71,6 +75,12 @@ void setMockVBattVoltage(float voltage DECLARE_ENGINE_PARAMETER_SUFFIX) { setMockVoltage(engineConfiguration->vbattAdcChannel, voltage PASS_ENGINE_PARAMETER_SUFFIX); } +void setMockState(brain_pin_e pin, bool state DECLARE_ENGINE_PARAMETER_SUFFIX) { +#if ! EFI_PROD_CODE + mockPinStates[static_cast(pin)] = state; +#endif +} + #endif /* EFI_ENABLE_MOCK_ADC */ #if EFI_PROD_CODE diff --git a/firmware/controllers/sensors/allsensors.cpp b/firmware/controllers/sensors/allsensors.cpp index eeeb8c9f29..d350574d11 100644 --- a/firmware/controllers/sensors/allsensors.cpp +++ b/firmware/controllers/sensors/allsensors.cpp @@ -12,21 +12,17 @@ EXTERN_ENGINE; +ButtonDebounce acDebounce; + void initSensors(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) { initMapDecoder(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX); + acDebounce.init(15, &CONFIG(acSwitch), &CONFIG(acSwitchMode)); +} + +bool getAcToggle(DECLARE_ENGINE_PARAMETER_SIGNATURE) { + return acDebounce.readPinState(); } bool hasAcToggle(DECLARE_ENGINE_PARAMETER_SIGNATURE) { - return engineConfiguration->acSwitchAdc != EFI_ADC_NONE; -} - -// todo: move this somewhere else? maybe. -bool getAcToggle(DECLARE_ENGINE_PARAMETER_SIGNATURE) { - /** - * todo: make this flexible - * - * for now we are looking for a pull-up. High level means input switch is floating (which is OFF position) - * low value means input is ground - which means ON. - */ - return getVoltageDivided("A/C", engineConfiguration->acSwitchAdc PASS_ENGINE_PARAMETER_SUFFIX) < 2.5; + return (CONFIG(acSwitch) != GPIO_UNASSIGNED); } diff --git a/firmware/hw_layer/adc/adc_inputs.cpp b/firmware/hw_layer/adc/adc_inputs.cpp index ca377b5611..7a12172d9f 100644 --- a/firmware/hw_layer/adc/adc_inputs.cpp +++ b/firmware/hw_layer/adc/adc_inputs.cpp @@ -540,7 +540,6 @@ static void configureInputs(void) { } addChannel("AFR", engineConfiguration->afr.hwChannel, ADC_SLOW); addChannel("Oil Pressure", engineConfiguration->oilPressure.hwChannel, ADC_SLOW); - addChannel("AC", engineConfiguration->acSwitchAdc, ADC_SLOW); if (engineConfiguration->high_fuel_pressure_sensor_1 != INCOMPATIBLE_CONFIG_CHANGE) { addChannel("HFP1", engineConfiguration->high_fuel_pressure_sensor_1, ADC_SLOW); } diff --git a/firmware/hw_layer/debounce.cpp b/firmware/hw_layer/debounce.cpp index 7d3eb01508..0a469bbb68 100644 --- a/firmware/hw_layer/debounce.cpp +++ b/firmware/hw_layer/debounce.cpp @@ -86,8 +86,10 @@ bool ButtonDebounce::readPinState() { // 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; -#ifndef EFI_UNIT_TEST +#if EFI_PROD_CODE || EFI_UNIT_TEST readValue = efiReadPin(active_pin); +#endif +#if EFI_PROD_CODE // Invert if (getInputMode(active_mode) == PAL_MODE_INPUT_PULLUP) { readValue = !readValue; diff --git a/firmware/hw_layer/io_pins.cpp b/firmware/hw_layer/io_pins.cpp index cf093dff47..ec5d746fad 100644 --- a/firmware/hw_layer/io_pins.cpp +++ b/firmware/hw_layer/io_pins.cpp @@ -9,10 +9,14 @@ #include "global.h" #include "io_pins.h" +#include "efi_gpio.h" +#include "engine.h" + +EXTERN_ENGINE; #if EFI_PROD_CODE + #include "os_access.h" -#include "efi_gpio.h" #include "drivers/gpio/gpio_ext.h" #include "pin_repository.h" @@ -20,7 +24,6 @@ #include "engine_configuration.h" #include "console_io.h" -EXTERN_ENGINE; #if EFI_ENGINE_CONTROL #include "main_trigger_callback.h" @@ -114,7 +117,9 @@ void efiIcuStart(const char *msg, ICUDriver *icup, const ICUConfig *config) { #endif /* HAL_USE_ICU */ #else +extern bool mockPinStates[(1 << sizeof(brain_pin_e))]; + bool efiReadPin(brain_pin_e pin) { - return false; + return mockPinStates[static_cast(pin)]; } #endif /* EFI_PROD_CODE */ diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 8a5d821a91..015dba8dab 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -990,7 +990,7 @@ bit useFSIO13ForIdleMinValue; bit useFSIO6ForRevLimiter; adc_channel_e hipOutputChannel; - adc_channel_e acSwitchAdc;A/C button input handled as analogue input + switch_input_pin_e acSwitch; A/C button input adc_channel_e vRefAdcChannel; uint8_t etbNeutralPosition;+Expected neutral position;"%", 1, 0, 0, 100, 0 @@ -1386,8 +1386,10 @@ uint8_t[4] unusedsw;;"units", 1, 0, -20, 100, 0 pin_input_mode_e tcuUpshiftButtonPinMode pin_input_mode_e tcuDownshiftButtonPinMode + pin_input_mode_e acSwitchMode + ! just a reminder that 'int' and 'float' are 4 bytes each - int[371] mainUnusedEnd;;"units", 1, 0, -20, 100, 0 + int[370] mainUnusedEnd;;"units", 1, 0, -20, 100, 0 ! end of engine_configuration_s end_struct diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 7678c95510..ed8bba7954 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -1881,7 +1881,8 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00" field = "Clutch up inverted", clutchUpPinMode field = "Throttle Up switch", throttlePedalUpPin field = "Brake pedal switch", brakePedalPin - field = "A/C switch", acSwitchAdc + field = "A/C switch", acSwitch + field = "A/C switch mode", acSwitchMode dialog = triggerInputComparator, "Built-in Comparator Settings (Kinetis-only)" field = "Comparator Center Point Voltage", triggerCompCenterVolt @@ -1920,7 +1921,7 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00" field = "clutchDownPin", clutchDownPin field = "clutchUpPin", clutchUpPin field = "brakePedalPin", brakePedalPin - field = "A/C Switch", acSwitchAdc + field = "A/C Switch", acSwitch field = "Aux Temperature #1", auxTempSensor1_adcChannel field = "Aux Temperature #2", auxTempSensor2_adcChannel field = "Aux Fast Analog", auxFastSensor1_adcChannel diff --git a/unit_tests/engine_test_helper.cpp b/unit_tests/engine_test_helper.cpp index e0ef38c70b..dc4ac810e5 100644 --- a/unit_tests/engine_test_helper.cpp +++ b/unit_tests/engine_test_helper.cpp @@ -24,6 +24,10 @@ extern engine_configuration_s & activeConfiguration; extern bool printTriggerDebug; extern bool printFuelDebug; +// This has been made global so we don't need to worry about efiReadPin having access the object +// we store it in, every time we need to use efiReadPin. +bool mockPinStates[BRAIN_PIN_COUNT]; + EngineTestHelperBase::EngineTestHelperBase() { // todo: make this not a global variable, we need currentTimeProvider interface on engine timeNowUs = 0; @@ -87,6 +91,8 @@ EngineTestHelper::EngineTestHelper(engine_type_e engineType, configuration_callb // Setup running in mock airmass mode engineConfiguration->fuelAlgorithm = LM_MOCK; engine->mockAirmassModel = &mockAirmass; + + memset(mockPinStates, 0, sizeof(mockPinStates)); } EngineTestHelper::~EngineTestHelper() { @@ -97,6 +103,7 @@ EngineTestHelper::~EngineTestHelper() { // Cleanup Sensor::resetRegistry(); + memset(mockPinStates, 0, sizeof(mockPinStates)); } static CompositeEvent compositeEvents[COMPOSITE_PACKET_COUNT]; diff --git a/unit_tests/engine_test_helper.h b/unit_tests/engine_test_helper.h index 8f92b36d4f..c95f1fe8da 100644 --- a/unit_tests/engine_test_helper.h +++ b/unit_tests/engine_test_helper.h @@ -7,6 +7,8 @@ #pragma once +#define BRAIN_PIN_COUNT (1 << sizeof(brain_pin_e)) + #include "engine.h" #include "trigger_central.h" #include "rpm_calculator.h" diff --git a/unit_tests/tests/test_idle_controller.cpp b/unit_tests/tests/test_idle_controller.cpp index d1a4035906..7f6a622517 100644 --- a/unit_tests/tests/test_idle_controller.cpp +++ b/unit_tests/tests/test_idle_controller.cpp @@ -39,15 +39,17 @@ TEST(idle, fsioPidParameters) { applyFsioExpression(QUOTE(MAGIC_OFFSET_FOR_IDLE_MIN_VALUE), "ac_on_switch 0 cfg_acIdleExtraMin if" PASS_ENGINE_PARAMETER_SUFFIX); ASSERT_EQ(1, hasAcToggle(PASS_ENGINE_PARAMETER_SIGNATURE)); - setMockVoltage(engineConfiguration->acSwitchAdc, 0 PASS_ENGINE_PARAMETER_SUFFIX); - ASSERT_EQ(1, getAcToggle(PASS_ENGINE_PARAMETER_SIGNATURE)); + setMockState(engineConfiguration->acSwitch, true PASS_ENGINE_PARAMETER_SUFFIX); + timeNowUs += MS2US(15); + ASSERT_TRUE(getAcToggle(PASS_ENGINE_PARAMETER_SIGNATURE)); eth.engine.periodicSlowCallback(PASS_ENGINE_PARAMETER_SIGNATURE); ASSERT_EQ(40, getIdlePidOffset(PASS_ENGINE_PARAMETER_SIGNATURE)); ASSERT_EQ(30, getIdlePidMinValue(PASS_ENGINE_PARAMETER_SIGNATURE)); - setMockVoltage(engineConfiguration->acSwitchAdc, 5 PASS_ENGINE_PARAMETER_SUFFIX); - ASSERT_EQ(0, getAcToggle(PASS_ENGINE_PARAMETER_SIGNATURE)); + setMockState(engineConfiguration->acSwitch, false PASS_ENGINE_PARAMETER_SUFFIX); + timeNowUs += MS2US(15); + ASSERT_FALSE(getAcToggle(PASS_ENGINE_PARAMETER_SIGNATURE)); eth.engine.periodicSlowCallback(PASS_ENGINE_PARAMETER_SIGNATURE); ASSERT_EQ(50, getIdlePidOffset(PASS_ENGINE_PARAMETER_SIGNATURE));