GCC Code Coverage Report


Directory: ./
File: firmware/controllers/modules/tachometer/tachometer.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 82.1% 23 0 28
Functions: 100.0% 4 0 4
Branches: 66.7% 8 0 12
Decisions: 70.0% 7 - 10

Line Branch Decision Exec Source
1 /*
2 * @file tachometer.cpp
3 * @brief This is about driving external analog tachometers
4 *
5 * This implementation produces one pulse per engine cycle
6 *
7 * @date Aug 18, 2015
8 * @author Andrey Belomutskiy, (c) 2012-2020
9 */
10
11 #include "pch.h"
12
13 #include "tachometer.h"
14
15 static SimplePwm tachControl("tach");
16 static float tachFreq;
17 static float duty;
18
19 #if EFI_UNIT_TEST
20 1 float getTachFreq() {
21 1 return tachFreq;
22 }
23
24 1 float getTachDuty() {
25 1 return duty;
26 }
27 #endif
28
29
30 1120 void TachometerModule::onFastCallback() {
31 // Only do anything if tach enabled
32
2/2
✓ Branch 0 taken 1117 times.
✓ Branch 1 taken 3 times.
2/2
✓ Decision 'true' taken 1117 times.
✓ Decision 'false' taken 3 times.
1120 if (!tachHasInit) {
33 1117 return;
34 }
35
36 // How many tach pulse periods do we have?
37 3 float periods = engineConfiguration->tachPulsePerRev;
38
39
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 3 times.
3 if (periods == 0 || periods > 10) {
40 firmwareError(ObdCode::CUSTOM_ERR_6709, "Invalid tachometer pulse per rev: %.2f", periods);
41 tachHasInit = false; // disable until nex fw init to avoid spamming the output
42 return;
43 }
44
45 // What is the angle per tach output period?
46 3 float cycleTimeMs = 60000.0f / Sensor::getOrZero(SensorType::Rpm);
47 3 float periodTimeMs = cycleTimeMs / periods;
48 3 tachFreq = 1000.0f / periodTimeMs;
49
50
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 3 times.
✗ Decision 'false' not taken.
3 if (engineConfiguration->tachPulseDurationAsDutyCycle) {
51 // Simple case - duty explicitly set
52 3 duty = engineConfiguration->tachPulseDuractionMs;
53 } else {
54 // Constant high-time mode - compute the correct duty cycle
55 duty = engineConfiguration->tachPulseDuractionMs / periodTimeMs;
56 }
57
58 // In case Freq is under 1Hz, we stop pwm to avoid warnings!
59
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 3 times.
3 if (tachFreq < 1) {
60 tachFreq = NAN;
61 }
62
63 3 tachControl.setSimplePwmDutyCycle(duty);
64 3 tachControl.setFrequency(tachFreq);
65 }
66
67 584 void TachometerModule::init(){
68 584 tachHasInit = false;
69
70
2/2
✓ Branch 1 taken 583 times.
✓ Branch 2 taken 1 time.
2/2
✓ Decision 'true' taken 583 times.
✓ Decision 'false' taken 1 time.
584 if (!isBrainPinValid(engineConfiguration->tachOutputPin)) {
71 583 return;
72 }
73
74 1 startSimplePwm(&tachControl,
75 "Tachometer",
76 &engine->scheduler,
77 &enginePins.tachOut,
78 NAN, 0.1f);
79
80 1 tachHasInit = true;
81 }
82