GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 19 / 0 / 19
Functions: 100.0% 1 / 0 / 1
Branches: 50.0% 8 / 0 / 16
Decisions: 50.0% 8 / - / 16

firmware/controllers/can/can_tx.cpp
Line Branch Decision Exec Source
1 /**
2 * @file can_tx.cpp
3 *
4 * CAN transmission handling. This file handles the dispatch of various outgoing regularly scheduled CAN message types.
5 *
6 * @date Mar 19, 2020
7 * @author Matthew Kennedy, (c) 2020
8 */
9
10 #include "pch.h"
11
12 #if EFI_CAN_SUPPORT || EFI_UNIT_TEST
13 #include "can.h"
14 #include "can_dash.h"
15 #endif
16
17 #if EFI_CAN_SUPPORT
18 #include "can_hw.h"
19 #include "obd2.h"
20 #include "can_sensor.h"
21 #include "can_bench_test.h"
22 #include "rusefi_wideband.h"
23
24 extern CanListener* canListeners_head;
25
26
27 CanWrite::CanWrite()
28 : PeriodicController("CAN TX", PRIO_CAN_TX, CAN_CYCLE_FREQ)
29 {
30 }
31
32 static CI roundTxPeriodToCycle(uint16_t period) {
33 if (period < 10) return CI::_5ms;
34 else if (period < 20) return CI::_10ms;
35 else if (period < 50) return CI::_20ms;
36 else if (period < 100) return CI::_50ms;
37 else if (period < 200) return CI::_100ms;
38 else if (period < 250) return CI::_200ms;
39 else if (period < 500) return CI::_250ms;
40 else if (period < 1000) return CI::_500ms;
41 else return CI::_1000ms;
42 }
43
44 PUBLIC_API_WEAK bool boardEnableSendWidebandInfo() { return true; }
45
46 static uint16_t m_cycleCount = 0;
47
48 /* public API for custom boards */ void resetCanWriteCycle() {
49 m_cycleCount = 0;
50 }
51
52 // this is invoked at CAN_CYCLE_FREQ frequency
53 void CanWrite::PeriodicTask(efitick_t) {
54 ScopePerf pc(PE::CanThreadTx);
55 CanCycle cycle(m_cycleCount);
56
57 //in case we have Verbose Can enabled, we should keep user configured period
58 if (engineConfiguration->enableVerboseCanTx) {
59 // slow down verbose CAN while in serial CAN
60 int canSleepPeriodMs = (engine->pauseCANdueToSerial ? 5 : 1) * engineConfiguration->canSleepPeriodMs;
61
62 auto roundedInterval = roundTxPeriodToCycle(canSleepPeriodMs);
63 if (cycle.isInterval(roundedInterval)) {
64 void sendCanVerbose();
65 sendCanVerbose();
66 }
67 }
68
69 CanListener* current = canListeners_head;
70
71 while (current) {
72 current = current->request();
73 }
74
75 if (cycle.isInterval(CI::_MAX_Cycle)) {
76 //we now reset cycleCount since we reached max cycle count
77 m_cycleCount = 0;
78 }
79
80 updateDash(cycle);
81
82 if (engineConfiguration->enableExtendedCanBroadcast || isHwQcMode()) {
83 if (cycle.isInterval(CI::_100ms)) {
84 sendQcBenchEventCounters();
85 sendQcBenchRawAnalogValues();
86 #ifdef HW_HELLEN_8CHAN
87 sendQcBenchEventCounters(/*bus*/1);
88 sendQcBenchRawAnalogValues(/*bus*/1);
89 #endif
90 }
91
92 if (cycle.isInterval(CI::_250ms)) {
93 sendQcBenchBoardStatus();
94 #ifdef HW_HELLEN_8CHAN
95 sendQcBenchBoardStatus(/*bus*/1);
96 #endif
97 sendQcBenchButtonCounters();
98 sendQcBenchAuxDigitalCounters();
99 }
100 }
101
102 if (engineConfiguration->enableAemXSeries && cycle.isInterval(CI::_50ms) && boardEnableSendWidebandInfo()) {
103 sendWidebandInfo();
104 }
105
106 m_cycleCount++;
107 }
108
109 #endif
110
111 #if EFI_CAN_SUPPORT || EFI_UNIT_TEST
112
113 1 CanInterval CanCycle::computeFlags(uint32_t cycleCount) {
114 1 CanInterval cycleMask = CanInterval::_5ms;
115
116
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 1 time.
✗ Decision 'false' not taken.
1 if ((cycleCount % 2) == 0) {
117 1 cycleMask |= CI::_10ms;
118 }
119
120
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 1 time.
✗ Decision 'false' not taken.
1 if ((cycleCount % 4) == 0) {
121 1 cycleMask |= CI::_20ms;
122 }
123
124
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 1 time.
✗ Decision 'false' not taken.
1 if ((cycleCount % 10) == 0) {
125 1 cycleMask |= CI::_50ms;
126 }
127
128
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 1 time.
✗ Decision 'false' not taken.
1 if ((cycleCount % 20) == 0) {
129 1 cycleMask |= CI::_100ms;
130 }
131
132
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 1 time.
✗ Decision 'false' not taken.
1 if ((cycleCount % 40) == 0) {
133 1 cycleMask |= CI::_200ms;
134 }
135
136
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 1 time.
✗ Decision 'false' not taken.
1 if ((cycleCount % 50) == 0) {
137 1 cycleMask |= CI::_250ms;
138 }
139
140
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 1 time.
✗ Decision 'false' not taken.
1 if ((cycleCount % 100) == 0) {
141 1 cycleMask |= CI::_500ms;
142 }
143
144
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 1 time.
✗ Decision 'false' not taken.
1 if ((cycleCount % 200) == 0) {
145 1 cycleMask |= CI::_1000ms;
146 }
147
148 1 return cycleMask;
149 }
150
151 #endif // EFI_CAN_SUPPORT
152