GCC Code Coverage Report


Directory: ./
File: firmware/init/sensor/init_maf.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 28.6% 10 0 35
Functions: 40.0% 2 0 5
Branches: 14.3% 2 0 14
Decisions: 14.3% 2 - 14

Line Branch Decision Exec Source
1 #include "pch.h"
2
3 #include "init.h"
4 #include "adc_subscription.h"
5 #include "functional_sensor.h"
6 #include "table_func.h"
7 #include "func_chain.h"
8
9 static FunctionalSensor maf (SensorType::Maf , /* timeout = */ MS2NT(50));
10 static FunctionalSensor maf2(SensorType::Maf2, /* timeout = */ MS2NT(50));
11
12 // Just check min/max allowed voltage
13 struct MafVoltageCheck : public SensorConverter {
14 SensorResult convert(float input) const override {
15 if (input > 5) {
16 return UnexpectedCode::High;
17 }
18
19 if (input < 0) {
20 return UnexpectedCode::Low;
21 }
22
23 return input;
24 }
25 };
26
27
28 // extract the type of the elements in the bin/value arrays
29 using BinType = std::remove_extent_t<decltype(config->mafDecodingBins)>;
30 using ValueType = std::remove_extent_t<decltype(config->mafDecoding)>;
31
32 // This function converts volts -> kg/h
33 static TableFunc mafCurve(config->mafDecodingBins, config->mafDecoding);
34
35 // grumble grumble func_chain doesn't do constructor parameters so we need an adapter
36 struct MafTable : public SensorConverter {
37 SensorResult convert(float input) const override {
38 return mafCurve.convert(input);
39 }
40 };
41
42 struct MafFilter final : public SensorConverter {
43 SensorResult convert(float input) const override {
44 // engine->outputChannels.mafMeasured_preFilter = input;
45
46 float param = engineConfiguration->mafFilterParameter;
47 if (param == 0) {
48 return input;
49 }
50
51 float rpm = Sensor::getOrZero(SensorType::Rpm);
52
53 if (rpm == 0) {
54 m_lastValue = input;
55 return input;
56 }
57
58 float invTimeConstant = rpm / param;
59 float alpha = (1e-3 * FAST_CALLBACK_PERIOD_MS) * invTimeConstant;
60
61 if (alpha < 0.001f) {
62 // Limit to 0.001 to avoid numerical issues
63 alpha = 0.001f;
64 } else if (alpha > 0.98f) {
65 // alpha > 0.98 (engine very fast and/or small manifold)
66 // -> disable filtering entirely
67 m_lastValue = input;
68 return input;
69 }
70
71 m_lastValue = alpha * input + (1 - alpha) * m_lastValue;
72
73 return m_lastValue;
74 }
75
76 mutable float m_lastValue = 0;
77 };
78
79 static FuncChain<MafVoltageCheck, MafTable, MafFilter> mafFunction;
80
81 4 static void initMaf(adc_channel_e channel, FunctionalSensor& m) {
82
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 2 times.
4 if (!isAdcChannelValid(channel)) {
83 2 return;
84 }
85
86 2 m.setFunction(mafFunction);
87
88 2 AdcSubscription::SubscribeSensor(m, channel, /*lowpassCutoff =*/ 50);
89 2 m.Register();
90 }
91
92 2 void initMaf() {
93 2 initMaf(engineConfiguration->mafAdcChannel, maf);
94 2 initMaf(engineConfiguration->maf2AdcChannel, maf2);
95 2 }
96