From c354177ddc3918c9d16386ca23c6a5890d528b62 Mon Sep 17 00:00:00 2001 From: Nathan Schulte Date: Tue, 2 Dec 2025 13:46:26 -0600 Subject: [PATCH 1/4] WIP: monitor Vbat --- firmware/hw_layer/ports/mpu_util.h | 1 + .../hw_layer/ports/stm32/stm32_adc_v2.cpp | 38 ++++++++++++++----- .../hw_layer/ports/stm32/stm32_adc_v4.cpp | 5 +++ 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/firmware/hw_layer/ports/mpu_util.h b/firmware/hw_layer/ports/mpu_util.h index 77eaf9b61f..fc67dedd55 100644 --- a/firmware/hw_layer/ports/mpu_util.h +++ b/firmware/hw_layer/ports/mpu_util.h @@ -22,6 +22,7 @@ bool isStm32F42x(); // ADC #if HAL_USE_ADC void portInitAdc(); +float getMcuBackupVoltage(); float getMcuTemperature(); // Convert all slow ADC inputs. Returns true if the conversion succeeded, false if a failure occured. bool readSlowAnalogInputs(); diff --git a/firmware/hw_layer/ports/stm32/stm32_adc_v2.cpp b/firmware/hw_layer/ports/stm32/stm32_adc_v2.cpp index 9a6c780ffa..4918b1f4b9 100644 --- a/firmware/hw_layer/ports/stm32/stm32_adc_v2.cpp +++ b/firmware/hw_layer/ports/stm32/stm32_adc_v2.cpp @@ -85,8 +85,8 @@ static const ADCConversionGroup tempSensorConvGroup = { .cr2 = ADC_CR2_SWSTART, // sample times for channels 10...18 .smpr1 = - ADC_SMPR1_SMP_VBAT(ADC_SAMPLE_144) | /* input18 - temperature and vbat input on some STM32F7xx */ - ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_144), /* input16 - temperature sensor input on STM32F4xx */ + ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_144) | /* input16 - temperature sensor on STM32F40x/F41x */ + ADC_SMPR1_SMP_VBAT(ADC_SAMPLE_144), /* input18 - temperature sensor and vbat on STM32F42x/F43x and some STM32F7xx */ .smpr2 = 0, .htr = 0, .ltr = 0, .sqr1 = 0, @@ -103,8 +103,8 @@ static const ADCConversionGroup tempSensorConvGroup = { static constexpr int oversample = 4; static adcsample_t samples[oversample]; -float getMcuTemperature() { - // Temperature sensor is only physically wired to ADC1 +float getInternalAdcVoltage() { + // The temperature sensor, VREFINT and the VBAT channel are available only on the master ADC1 peripheral. adcConvert(&ADCD1, &tempSensorConvGroup, samples, oversample); uint32_t sum = 0; @@ -112,13 +112,33 @@ float getMcuTemperature() { sum += samples[i]; } - float volts = (float)sum / (4096 * oversample); - volts *= engineConfiguration->adcVcc; + float sense = (float)sum / (4095 * oversample); + sense *= engineConfiguration->adcVcc; + + return sense; +} + +float getMcuBackupVoltage() { + // the backup Vbat voltage (RTC, coin cell, backup, battery) + + adcSTM32EnableVBATE(); + + float volts = getInternalAdcVoltage(); + + adcSTM32DisableVBATE(); + + return volts; +} + +float getMcuTemperature() { + // the internal device junction temperature sensor + + float volts = getInternalAdcVoltage(); - volts -= 0.760f; // Subtract the reference voltage at 25 deg C - float degrees = volts / 0.0025f; // Divide by slope 2.5mV + volts -= 0.760f; // Subtract the reference voltage at 25 deg C: 0.76 V + float degrees = volts / 0.0025f; // Divide by average slope: 2.5mV - degrees += 25.0; // Add the 25 deg C + degrees += 25.0f; // Add the 25 deg C if (degrees > 150.0f || degrees < -50.0f) { /* diff --git a/firmware/hw_layer/ports/stm32/stm32_adc_v4.cpp b/firmware/hw_layer/ports/stm32/stm32_adc_v4.cpp index 802d41e8c2..de6d84e61b 100644 --- a/firmware/hw_layer/ports/stm32/stm32_adc_v4.cpp +++ b/firmware/hw_layer/ports/stm32/stm32_adc_v4.cpp @@ -80,6 +80,11 @@ void portInitAdc() { SYSCFG->PMCR &= ~(SYSCFG_PMCR_PA0SO | SYSCFG_PMCR_PA1SO | SYSCFG_PMCR_PC2SO | SYSCFG_PMCR_PC3SO); } +float getMcuBackupVoltage() { + // the backup Vbat voltage (RTC, coin cell, backup, battery) + return 0; +} + float getMcuTemperature() { // Ugh, internal temp sensor is wired to ADC3, which makes it nearly useless on the H7. return 0; From 69f32ba4255e6e414cabe413cbaf7872b1619895 Mon Sep 17 00:00:00 2001 From: Nathan Schulte Date: Tue, 2 Dec 2025 15:05:27 -0600 Subject: [PATCH 2/4] MCU backup voltage output channel --- firmware/console/binary/output_channels.txt | 1 + firmware/console/status_loop.cpp | 3 +++ firmware/controllers/sensors/sensor_type.h | 2 ++ firmware/hw_layer/adc/adc_inputs.cpp | 6 ++++++ firmware/integration/fome_config_shared.txt | 1 + .../io/src/main/java/com/rusefi/enums/SensorType.java | 1 + 6 files changed, 14 insertions(+) diff --git a/firmware/console/binary/output_channels.txt b/firmware/console/binary/output_channels.txt index 2ecea38f0f..2334354757 100644 --- a/firmware/console/binary/output_channels.txt +++ b/firmware/console/binary/output_channels.txt @@ -135,6 +135,7 @@ struct_no_prefix output_channels_s uint16_t autoscale mafMeasured;@@GAUGE_NAME_AIR_FLOW_MEASURED@@;"kg/h",{1/@@PACK_MULT_MASS_FLOW@@}, 0, 0, 0, 1 uint16_t autoscale mafMeasured2;@@GAUGE_NAME_AIR_FLOW_MEASURED_2@@;"kg/h",{1/@@PACK_MULT_MASS_FLOW@@}, 0, 0, 0, 1 + uint16_t autoscale mcuBackupVoltage;@@GAUGE_NAME_ECU_BACKUP_VOLTAGE@@;"V",{1/@@PACK_MULT_VOLTAGE@@}, 0, 0, 0, 2 ! Fueling int16_t[STFT_BANK_COUNT iterate] autoscale fuelPidCorrection;Fuel: Trim bank;"%",{1/@@PACK_MULT_PERCENT@@}, 0, -20, 20, 2 diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index 87f4af97cc..45df01e7b9 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -365,6 +365,9 @@ static void updateMiscSensors() { engine->outputChannels.internalMcuTemperature = Sensor::get(SensorType::EcuInternalTemperature) .value_or(getMCUInternalTemperature()); + engine->outputChannels.mcuBackupVoltage = + Sensor::get(SensorType::EcuBackupVoltage) + .value_or(getMCUBackupVoltage()); #endif /* HAL_USE_ADC */ } diff --git a/firmware/controllers/sensors/sensor_type.h b/firmware/controllers/sensors/sensor_type.h index 06aa1af8a2..34468aee37 100644 --- a/firmware/controllers/sensors/sensor_type.h +++ b/firmware/controllers/sensors/sensor_type.h @@ -75,6 +75,8 @@ enum class SensorType : unsigned char { MainRelayVoltage, Sensor5vVoltage, + EcuBackupVoltage, // STM32 Vbat + BarometricPressure, FuelLevel, diff --git a/firmware/hw_layer/adc/adc_inputs.cpp b/firmware/hw_layer/adc/adc_inputs.cpp index 3dfb0e6023..0e949855f5 100644 --- a/firmware/hw_layer/adc/adc_inputs.cpp +++ b/firmware/hw_layer/adc/adc_inputs.cpp @@ -46,6 +46,11 @@ float getVoltage(const char *msg, adc_channel_e hwChannel) { static uint32_t slowAdcCounter = 0; static float mcuTemperature; +static float mcuBackupVoltage; + +float getMCUBackupVoltage() { + return mcuBackupVoltage; +} float getMCUInternalTemperature() { return mcuTemperature; @@ -77,6 +82,7 @@ void updateSlowAdc(efitick_t nowNt) { // Ask the port to sample the MCU temperature mcuTemperature = getMcuTemperature(); + mcuBackupVoltage = getMcuBackupVoltage(); } { diff --git a/firmware/integration/fome_config_shared.txt b/firmware/integration/fome_config_shared.txt index 920bb381df..c0655b501f 100644 --- a/firmware/integration/fome_config_shared.txt +++ b/firmware/integration/fome_config_shared.txt @@ -106,6 +106,7 @@ #define GAUGE_NAME_OIL_TEMPERATURE "Oil Temperature" #define GAUGE_NAME_ECU_TEMPERATURE "ECU temperature" +#define GAUGE_NAME_ECU_BACKUP_VOLTAGE "ECU backup voltage" #define GAUGE_NAME_AUX_LINEAR_1 "Aux linear 1" #define GAUGE_NAME_AUX_LINEAR_2 "Aux linear 2" diff --git a/java_console/io/src/main/java/com/rusefi/enums/SensorType.java b/java_console/io/src/main/java/com/rusefi/enums/SensorType.java index f6053db9bf..e033d22f27 100644 --- a/java_console/io/src/main/java/com/rusefi/enums/SensorType.java +++ b/java_console/io/src/main/java/com/rusefi/enums/SensorType.java @@ -40,6 +40,7 @@ public enum SensorType { BatteryVoltage, MainRelayVoltage, Sensor5vVoltage, + EcuBackupVoltage, BarometricPressure, FuelLevel, VehicleSpeed, From 4732e6a4458cf93537f19912851f4704b0a13b82 Mon Sep 17 00:00:00 2001 From: Nathan Schulte Date: Tue, 2 Dec 2025 15:05:38 -0600 Subject: [PATCH 3/4] remove dead sensor index comments --- firmware/controllers/sensors/sensor_type.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/controllers/sensors/sensor_type.h b/firmware/controllers/sensors/sensor_type.h index 34468aee37..3a3c4318ce 100644 --- a/firmware/controllers/sensors/sensor_type.h +++ b/firmware/controllers/sensors/sensor_type.h @@ -41,7 +41,7 @@ enum class SensorType : unsigned char { FuelTemperature, // This is the "resolved" position, potentially composited out of the following two - Tps1, // 10 + Tps1, // This is the first sensor Tps1Primary, // This is the second sensor @@ -59,7 +59,7 @@ enum class SensorType : unsigned char { // This maps to the pedal if we have one, and Tps1 if not. DriverThrottleIntent, - AuxTemp1, // 20 + AuxTemp1, AuxTemp2, Lambda1, From 186f44aa9e22b3799d01d0cc8b79c4c51786f08e Mon Sep 17 00:00:00 2001 From: Nathan Schulte Date: Tue, 2 Dec 2025 15:06:26 -0600 Subject: [PATCH 4/4] ECU temperature is "misc sensor" --- firmware/console/binary/output_channels.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/firmware/console/binary/output_channels.txt b/firmware/console/binary/output_channels.txt index 2334354757..9712563512 100644 --- a/firmware/console/binary/output_channels.txt +++ b/firmware/console/binary/output_channels.txt @@ -135,6 +135,7 @@ struct_no_prefix output_channels_s uint16_t autoscale mafMeasured;@@GAUGE_NAME_AIR_FLOW_MEASURED@@;"kg/h",{1/@@PACK_MULT_MASS_FLOW@@}, 0, 0, 0, 1 uint16_t autoscale mafMeasured2;@@GAUGE_NAME_AIR_FLOW_MEASURED_2@@;"kg/h",{1/@@PACK_MULT_MASS_FLOW@@}, 0, 0, 0, 1 + int8_t internalMcuTemperature;@@GAUGE_NAME_ECU_TEMPERATURE@@;"deg C",1, 0, 0, 0, 0 uint16_t autoscale mcuBackupVoltage;@@GAUGE_NAME_ECU_BACKUP_VOLTAGE@@;"V",{1/@@PACK_MULT_VOLTAGE@@}, 0, 0, 0, 2 ! Fueling @@ -165,8 +166,6 @@ struct_no_prefix output_channels_s uint8_t widebandUpdateProgress;;"%", 1, 0, 0, 100, 0 uint8_t orderingErrorCounter;;"",1, 0, 0, 0, 0 - int8_t internalMcuTemperature;@@GAUGE_NAME_ECU_TEMPERATURE@@;"deg C",1, 0, 0, 0, 0 - uint16_t autoscale actualLastInjection;@@GAUGE_NAME_FUEL_LAST_INJECTION@@\nActual last injection time - including all compensation and injection mode;"ms",{1/@@PACK_MULT_MS@@}, 0, 0, 0, 3 uint16_t autoscale actualLastInjectionStage2;@@GAUGE_NAME_FUEL_LAST_INJECTION_STAGE_2@@;"ms",{1/@@PACK_MULT_MS@@}, 0, 0, 0, 3