diff --git a/firmware/config/boards/hellen/hellen128/board_configuration.cpp b/firmware/config/boards/hellen/hellen128/board_configuration.cpp index fa4d420f0d..20510e8279 100644 --- a/firmware/config/boards/hellen/hellen128/board_configuration.cpp +++ b/firmware/config/boards/hellen/hellen128/board_configuration.cpp @@ -115,6 +115,8 @@ void setBoardConfigOverrides(void) { engineConfiguration->canTxPin = GPIOD_1; engineConfiguration->canRxPin = GPIOD_0; + + engineConfiguration->vrThreshold[0].pin = GPIOD_14; } void setPinConfigurationOverrides(void) { diff --git a/firmware/controllers/algo/engine.cpp b/firmware/controllers/algo/engine.cpp index 0c7cb5cd4f..2889038a6a 100644 --- a/firmware/controllers/algo/engine.cpp +++ b/firmware/controllers/algo/engine.cpp @@ -31,6 +31,7 @@ #include "boost_control.h" #include "fan_control.h" #include "ac_control.h" +#include "vr_pwm.h" #if EFI_MC33816 #include "mc33816.h" #endif // EFI_MC33816 @@ -216,6 +217,8 @@ void Engine::periodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) { updateSlowSensors(PASS_ENGINE_PARAMETER_SIGNATURE); checkShutdown(PASS_ENGINE_PARAMETER_SIGNATURE); + updateVrPwm(PASS_ENGINE_PARAMETER_SIGNATURE); + #if EFI_FSIO runFsio(PASS_ENGINE_PARAMETER_SIGNATURE); #else diff --git a/firmware/controllers/engine_controller.cpp b/firmware/controllers/engine_controller.cpp index 3f9533573e..0e1bbb44e4 100644 --- a/firmware/controllers/engine_controller.cpp +++ b/firmware/controllers/engine_controller.cpp @@ -54,6 +54,7 @@ #include "buttonshift.h" #include "start_stop.h" #include "dynoview.h" +#include "vr_pwm.h" #if EFI_SENSOR_CHART #include "sensor_chart.h" @@ -643,6 +644,8 @@ void initEngineContoller(DECLARE_ENGINE_PARAMETER_SUFFIX) { engineStateBlinkingTask.Start(); + initVrPwm(PASS_ENGINE_PARAMETER_SIGNATURE); + #if EFI_PWM_TESTER initPwmTester(); #endif /* EFI_PWM_TESTER */ diff --git a/firmware/controllers/sensors/sensors.mk b/firmware/controllers/sensors/sensors.mk index 77dc10d0eb..524c22dec7 100644 --- a/firmware/controllers/sensors/sensors.mk +++ b/firmware/controllers/sensors/sensors.mk @@ -18,4 +18,5 @@ CONTROLLERS_SENSORS_SRC_CPP = $(PROJECT_DIR)/controllers/sensors/thermistors.cp $(PROJECT_DIR)/controllers/sensors/Lps25Sensor.cpp \ $(PROJECT_DIR)/controllers/sensors/converters/linear_func.cpp \ $(PROJECT_DIR)/controllers/sensors/converters/resistance_func.cpp \ - $(PROJECT_DIR)/controllers/sensors/converters/thermistor_func.cpp + $(PROJECT_DIR)/controllers/sensors/converters/thermistor_func.cpp \ + $(PROJECT_DIR)/controllers/sensors/vr_pwm.cpp diff --git a/firmware/controllers/sensors/vr_pwm.cpp b/firmware/controllers/sensors/vr_pwm.cpp new file mode 100644 index 0000000000..a24f90c189 --- /dev/null +++ b/firmware/controllers/sensors/vr_pwm.cpp @@ -0,0 +1,48 @@ +#include "pch.h" + +#include "vr_pwm.h" + +static OutputPin pins[2]; +static SimplePwm pwms[2]; + +static void updateVrPwm(int rpm, size_t index DECLARE_ENGINE_PARAMETER_SUFFIX) { + auto& cfg = CONFIG(vrThreshold)[index]; + + if (cfg.pin == GPIO_UNASSIGNED) { + return; + } + + float thresholdVoltage = interpolate2d(rpm / RPM_1_BYTE_PACKING_MULT, cfg.rpmBins, cfg.values) / 100.0f; + + // 0v threshold voltage = 3.3v output from mcu = 100% duty + // 2.5v threshold voltage = 0v output from mcu = 0% duty + float duty = interpolateClamped(0, 1, 2.5f, 0, thresholdVoltage); + + pwms[index].setSimplePwmDutyCycle(duty); +} + +void updateVrPwm(DECLARE_ENGINE_PARAMETER_SIGNATURE) { + auto rpm = GET_RPM(); + + for (size_t i = 0; i < efi::size(CONFIG(vrThreshold)); i++) { + updateVrPwm(rpm, i PASS_ENGINE_PARAMETER_SUFFIX); + } +} + +void initVrPwm(DECLARE_ENGINE_PARAMETER_SIGNATURE) { + for (size_t i = 0; i < efi::size(CONFIG(vrThreshold)); i++) { + auto& cfg = CONFIG(vrThreshold)[i]; + + if (cfg.pin == GPIO_UNASSIGNED) { + continue; + } + + startSimplePwmHard(&pwms[i], "VR PWM", + &engine->executor, + cfg.pin, + &pins[i], + 10000, // it's guaranteed to be hardware PWM, the faster the PWM, the less noise makes it through + 0 + ); + } +} diff --git a/firmware/controllers/sensors/vr_pwm.h b/firmware/controllers/sensors/vr_pwm.h new file mode 100644 index 0000000000..89fba27b27 --- /dev/null +++ b/firmware/controllers/sensors/vr_pwm.h @@ -0,0 +1,4 @@ +#pragma once + +void initVrPwm(DECLARE_ENGINE_PARAMETER_SIGNATURE); +void updateVrPwm(DECLARE_ENGINE_PARAMETER_SIGNATURE); diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 3422ab731e..129068fdfa 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -1073,7 +1073,16 @@ custom maf_sensor_type_e 4 bits, S32, @OFFSET@, [0:1], @@maf_sensor_type_e_enum@ float[CAM_INPUTS_COUNT iterate] vvtOffsets;+Angle between cam sensor and VVT zero position\nset vvt_offset X;"value", 1, 0, -720, 1000, 1 float[CAM_INPUTS_COUNT_padding] vvtOffsetsPadding;; - int[53] unusedAtOldBoardConfigurationEnd;;"units", 1, 0, -20, 100, 0 +struct vr_threshold_s + brain_pin_e pin; + uint8_t[3] pad;;"",1,0,0,0,0 + uint8_t[6] rpmBins;;"rpm", {@@RPM_1_BYTE_PACKING_MULT@@}, 0, 0, 12000, 0 + uint8_t[6] values;;"volts", 0.01, 0, 0, 2.5, 2 +end_struct + + vr_threshold_s[2 iterate] vrThreshold; + + int[45] unusedAtOldBoardConfigurationEnd;;"units", 1, 0, -20, 100, 0 uint16_t vehicleWeight;;"kg", 1, 0, 0, 10000, 0 brain_pin_e lps25BaroSensorScl brain_pin_e lps25BaroSensorSda diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index c3ec271bfe..e46c04c9d0 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -647,7 +647,21 @@ enable2ndByteCanID = false yAxis = 0, 2, 5 xBins = injector_battLagCorrBins, VBatt yBins = injector_battLagCorr - + + curve = vrThresholdCurve1, "VR 1 Threshold" + columnLabel = "RPM", "Voltage" + xAxis = 0, 8000, 9 + yAxis = 0, 2.5, 6 + xBins = vrThreshold1_rpmBins, RPMValue + yBins = vrThreshold1_values + + curve = vrThresholdCurve2, "VR 2 Threshold" + columnLabel = "RPM", "Voltage" + xAxis = 0, 8000, 9 + yAxis = 0, 2.5, 6 + xBins = vrThreshold2_rpmBins, RPMValue + yBins = vrThreshold2_values + curve = mafDecodingCurve, "MAF sensor" columnLabel = "Voltage", "kg/hour" xAxis = -1, 6, 10 @@ -1604,6 +1618,7 @@ menuDialog = main subMenu = parkingLot, "Experimental/Broken" subMenu = rotaryDialog, "Rotary" subMenu = mc33Dialog, "GDI Dreams" + subMenu = vrThreshold, "VR Sensor Threshold" subMenu = std_separator subMenu = hipFunction, "HIP9011 settings (knock sensor) (alpha version)" @@if_ts_show_hip9011 @@ -3650,6 +3665,18 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00" webHelp = @@MAIN_HELP_URL@@ text = "" + dialog = vrThreshold1, "VR 1 Threshold" + field = "Pin", vrThreshold1_pin + panel = vrThresholdCurve1 + + dialog = vrThreshold2, "VR 2 Threshold" + field = "Pin", vrThreshold2_pin + panel = vrThresholdCurve2 + + dialog = vrThreshold + panel = vrThreshold1 + panel = vrThreshold2 + dialog = gppwm1left, "" field = "Pin", gppwm1_pin field = ""