GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 0.0% 0 / 0 / 42
Functions: 0.0% 0 / 0 / 6
Branches: 0.0% 0 / 0 / 13
Decisions: 0.0% 0 / - / 2

firmware/controllers/can/can_dash_ms.cpp
Line Branch Decision Exec Source
1 /**
2 * @file can_dash_ms.cpp
3 *
4 * This file implements MegaSquirt CAN realtime data broadcasting format
5 *
6 * @date May 8, 2023
7 * @author AndreyGusakov, (c) 2023
8 */
9
10 #include "pch.h"
11
12 #if EFI_CAN_SUPPORT || EFI_UNIT_TEST
13 #include "can.h"
14 #include "can_msg_tx.h"
15
16 #include "rusefi_types.h"
17 #include "rtc_helper.h"
18 #include "fuel_math.h"
19
20 /* TODO:
21 * use engine->outputChannels instead of Sensor::getOrZero as it cheaper */
22
23 struct ms1512 {
24 /* kPa */
25 scaled_channel<int16_t, 10> Map;
26 /* RPM */
27 scaled_channel<uint16_t, 1> Rpm;
28 /* Fahrenheit! */
29 scaled_channel<int16_t, 10> Clt;
30 /* % */
31 scaled_channel<int16_t, 10> Tps;
32 };
33
34 void populateFrame(ms1512& msg)
35 {
36 msg.Map = Sensor::getOrZero(SensorType::Map);
37 msg.Rpm = Sensor::getOrZero(SensorType::Rpm);
38 /* Celsius to Fahrenheit */
39 msg.Clt = Sensor::getOrZero(SensorType::Clt) * 9 / 5 + 32;
40 msg.Tps = Sensor::getOrZero(SensorType::Tps1);
41 }
42
43 struct ms1513 {
44 /* mS */
45 scaled_channel<uint16_t, 1000> pw1;
46 scaled_channel<uint16_t, 1000> pw2;
47 scaled_channel<int16_t, 10> mat;
48 scaled_channel<int16_t, 10> adv_deg;
49 };
50
51 void populateFrame(ms1513& msg)
52 {
53 /* TODO: per-bank */
54 msg.pw1 = msg.pw2 = engine->engineState.injectionDuration;
55 /* Celsius to Fahrenheit */
56 msg.mat = Sensor::getOrZero(SensorType::Iat) * 9 / 5 + 32;
57 float timing = engine->engineState.timingAdvance[0];
58 msg.adv_deg = timing > 360 ? timing - 720 : timing;
59 }
60
61 struct ms1514 {
62 scaled_channel<uint8_t, 10> afrtgt1;
63 scaled_channel<uint8_t, 10> AFR1;
64 scaled_channel<int16_t, 10> EGOcor1;
65 scaled_channel<int16_t, 10> egt1;
66 scaled_channel<int16_t, 10> pwseq1;
67 };
68
69 void populateFrame(ms1514& msg)
70 {
71 #if EFI_ENGINE_CONTROL
72 msg.afrtgt1 = (float)engine->fuelComputer.targetLambda * STOICH_RATIO;
73 msg.AFR1 = Sensor::getOrZero(SensorType::Lambda1) * STOICH_RATIO;
74 /* TODO: banks? */
75 msg.EGOcor1 = engine->engineState.stftCorrection[0];
76 /* TODO */
77 msg.egt1 = 0;
78 msg.pwseq1 = engine->engineState.injectionDuration;
79 #endif // EFI_ENGINE_CONTROL
80 }
81
82 struct ms1515 {
83 scaled_channel<uint16_t, 10> Vbat;
84 scaled_channel<uint16_t, 10> sensor1;
85 scaled_channel<uint16_t, 10> sensor2;
86 scaled_channel<uint8_t, 10> knk_rtd;
87 uint8_t unused; /* do we need this? */
88 };
89
90 void populateFrame(ms1515& msg)
91 {
92 msg.Vbat = Sensor::getOrZero(SensorType::BatteryVoltage);
93 /* TODO */
94 msg.sensor1 = 0;
95 msg.sensor2 = 0;
96 msg.knk_rtd = engine->module<KnockController>()->m_knockLevel;
97 msg.unused = 0;
98 }
99
100 struct ms1516 {
101 scaled_channel<uint16_t, 10> VSS1;
102 scaled_channel<uint16_t, 10> tc_retard;
103 scaled_channel<uint16_t, 10> launch_timing;
104 uint16_t unsused;
105 };
106
107 void populateFrame(ms1516& msg)
108 {
109 /* ms-1 ??? */
110 msg.VSS1 = Sensor::getOrZero(SensorType::VehicleSpeed);
111 /* TODO */
112 msg.tc_retard = 0;
113 msg.launch_timing = 0;
114 msg.unsused = 0;
115 }
116
117 void canDashboardTS(CanCycle cycle) {
118 /* TODO: get from settings */
119 uint32_t baseId = 1512; /* 0x5e8 */
120
121 if (!cycle.isInterval(CI::_10ms)) {
122 return;
123 }
124
125 bool busIndex = 0;
126 transmitStruct<ms1512>(CanCategory::NBC, baseId + 0, false, busIndex);
127 transmitStruct<ms1513>(CanCategory::NBC, baseId + 1, false, busIndex);
128 transmitStruct<ms1514>(CanCategory::NBC, baseId + 2, false, busIndex);
129 transmitStruct<ms1515>(CanCategory::NBC, baseId + 3, false, busIndex);
130 transmitStruct<ms1516>(CanCategory::NBC, baseId + 4, false, busIndex);
131 }
132
133 #endif /* EFI_CAN_SUPPORT */
134