rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
can_verbose.cpp
Go to the documentation of this file.
1/**
2 * @file can_verbose.cpp
3 *
4 * TODO: change 'verbose' into 'broadcast'?
5 *
6 * If you edit this file, please update rusEFI_CAN_verbose.dbc!
7 * Kvaser Database Editor works well for this task, and is free.
8 *
9 * @author Matthew Kennedy, (c) 2020
10 */
11
12#include "pch.h"
13#if EFI_CAN_SUPPORT
14
15#include "efi_scaled_channel.h"
16#include "can_msg_tx.h"
17#include "can.h"
18#include "fuel_math.h"
19#include "spark_logic.h"
20
21#ifdef HW_HELLEN
22#include "hellen_meta.h"
23#endif // HW_HELLEN
24
25#define CAN_PEDAL_TPS_OFFSET 2
26#define CAN_SENSOR_1_OFFSET 3
27
28struct Status {
29 uint16_t warningCounter;
30 uint16_t lastErrorCode;
31
32 uint8_t revLimit : 1;
33 uint8_t mainRelay : 1;
34 uint8_t fuelPump : 1;
35 uint8_t checkEngine : 1;
36 uint8_t o2Heater : 1;
37 uint8_t lambdaProtectActive : 1;
38
39 uint8_t fan : 1;
40 uint8_t fan2 : 1;
41
42 uint8_t gear;
43
44 uint16_t distanceTraveled;
45};
46
47static void populateFrame(Status& msg) {
48 msg.warningCounter = engine->engineState.warnings.warningCounter;
49 msg.lastErrorCode = static_cast<uint16_t>(engine->engineState.warnings.lastErrorCode);
50
51 msg.revLimit = !engine->module<LimpManager>()->allowInjection() || !engine->module<LimpManager>()->allowIgnition();
52 msg.mainRelay = enginePins.mainRelay.getLogicValue();
53 msg.fuelPump = enginePins.fuelPumpRelay.getLogicValue();
54 msg.checkEngine = enginePins.checkEnginePin.getLogicValue();
55 msg.o2Heater = enginePins.o2heater.getLogicValue();
56#if EFI_SHAFT_POSITION_INPUT
57 msg.lambdaProtectActive = engine->lambdaMonitor.isCut();
58#endif // EFI_SHAFT_POSITION_INPUT
61
63
64#ifdef MODULE_ODOMETER
65 // scale to units of 0.1km
66 msg.distanceTraveled = engine->module<TripOdometer>()->getDistanceMeters() / 100;
67#endif // MODULE_ODOMETER
68}
69
70struct Status11 {
71 uint8_t brakePedal : 1;
72};
73
74static void populateFrame(Status11& msg) {
75 msg.brakePedal = engine->engineState.brakePedalState;
76}
77
78struct Speeds {
79 uint16_t rpm;
80 scaled_angle timing;
81 scaled_channel<uint8_t, 2> injDuty;
82 scaled_channel<uint8_t, 2> coilDuty;
83 scaled_channel<uint8_t> vssKph;
84 uint8_t EthanolPercent;
85};
86
87static void populateFrame(Speeds& msg) {
89 msg.rpm = rpm;
90
91 auto timing = engine->engineState.timingAdvance[0];
92 msg.timing = timing > 360 ? timing - 720 : timing;
93#if EFI_ENGINE_CONTROL
94 msg.injDuty = getInjectorDutyCycle(rpm);
95 msg.coilDuty = getCoilDutyCycle(rpm);
96#endif // EFI_ENGINE_CONTROL
98
100}
101
102struct PedalAndTps {
103 scaled_percent pedal;
104 scaled_percent tps1;
105 scaled_percent tps2;
106 scaled_percent wastegate;
107};
108
109static void populateFrame(PedalAndTps& msg)
110{
111 msg.pedal = Sensor::get(SensorType::AcceleratorPedal).value_or(-1);
112 msg.tps1 = Sensor::get(SensorType::Tps1).value_or(-1);
113 msg.tps2 = Sensor::get(SensorType::Tps2).value_or(-1);
114 msg.wastegate = Sensor::get(SensorType::WastegatePosition).value_or(-1);
115}
116
117struct Sensors1 {
118 scaled_pressure map;
119 scaled_channel<uint8_t> clt;
120 scaled_channel<uint8_t> iat;
121 scaled_channel<uint8_t> aux1;
122 scaled_channel<uint8_t> aux2;
123 scaled_channel<uint8_t> mcuTemp;
124 scaled_channel<uint8_t, 2> fuelLevel;
125};
126
127static void populateFrame(Sensors1& msg) {
129
130 msg.clt = Sensor::getOrZero(SensorType::Clt) + PACK_ADD_TEMPERATURE;
131 msg.iat = Sensor::getOrZero(SensorType::Iat) + PACK_ADD_TEMPERATURE;
132
133 msg.aux1 = Sensor::getOrZero(SensorType::AuxTemp1) + PACK_ADD_TEMPERATURE;
134 msg.aux2 = Sensor::getOrZero(SensorType::AuxTemp2) + PACK_ADD_TEMPERATURE;
135
136#if HAL_USE_ADC
137 msg.mcuTemp = getMCUInternalTemperature() + PACK_ADD_TEMPERATURE;
138#endif
139
141}
142
143struct Sensors2 {
144 uint8_t pad[2];
145
147 uint8_t oilTemp;
148 uint8_t fuelTemp;
149 scaled_voltage vbatt;
150};
151
152static void populateFrame(Sensors2& msg) {
153 msg.oilPressure = Sensor::get(SensorType::OilPressure).value_or(-1);
154 msg.oilTemp = Sensor::getOrZero(SensorType::OilTemperature) + PACK_ADD_TEMPERATURE;
155 msg.fuelTemp = Sensor::getOrZero(SensorType::FuelTemperature) + PACK_ADD_TEMPERATURE;
157}
158
159struct Fueling {
160 scaled_channel<uint16_t, 1000> cylAirmass;
161 scaled_channel<uint16_t, 100> estAirflow;
162 scaled_ms fuel_pulse;
163 uint16_t knockCount;
164};
165
166static void populateFrame(Fueling& msg) {
167#if EFI_ENGINE_CONTROL
169 msg.estAirflow = engine->engineState.airflowEstimate;
171 msg.knockCount = engine->module<KnockController>()->getKnockCount();
172#endif // EFI_ENGINE_CONTROL
173}
174
175struct Fueling2 {
176 scaled_channel<uint16_t> fuelConsumedGram;
177 scaled_channel<uint16_t, PACK_MULT_FUEL_FLOW> fuelFlowRate;
178 scaled_percent fuelTrim[2];
179};
180
181static void populateFrame(Fueling2& msg) {
182#ifdef MODULE_ODOMETER
183 msg.fuelConsumedGram = engine->module<TripOdometer>()->getConsumedGrams();
184 msg.fuelFlowRate = engine->module<TripOdometer>()->getConsumptionGramPerSecond();
185#endif // MODULE_ODOMETER
186
187 for (size_t i = 0; i < FT_BANK_COUNT; i++) {
188 msg.fuelTrim[i] = 100.0f * (engine->engineState.stftCorrection[i] - 1.0f);
189 }
190}
191
192struct Fueling3 {
193 scaled_channel<uint16_t, 10000> Lambda;
194 scaled_channel<uint16_t, 10000> Lambda2;
195 scaled_channel<uint16_t, 30> FuelPressureLow;
196 scaled_channel<uint16_t, 10> FuelPressureHigh;
197};
198
199static void populateFrame(Fueling3& msg) {
202 msg.FuelPressureLow = Sensor::getOrZero(SensorType::FuelPressureLow);
203 msg.FuelPressureHigh = KPA2BAR(Sensor::getOrZero(SensorType::FuelPressureHigh));
204}
205
206struct PerCylinderKnock {
207 int8_t knock[8];
208};
209
210static void populateFrame(PerCylinderKnock& msg) {
211 for (size_t index = 0;index<std::min(8, MAX_CYLINDER_COUNT);index++) {
212 msg.knock[index] = engine->module<KnockController>()->m_knockCyl[index];
213 }
214}
215
216struct Cams {
217 int8_t Bank1IntakeActual;
218 int8_t Bank1IntakeTarget;
219 int8_t Bank1ExhaustActual;
220 int8_t Bank1ExhaustTarget;
221 int8_t Bank2IntakeActual;
222 int8_t Bank2IntakeTarget;
223 int8_t Bank2ExhaustActual;
224 int8_t Bank2ExhaustTarget;
225};
226
227static void populateFrame(Cams& msg) {
228#if EFI_SHAFT_POSITION_INPUT
229 msg.Bank1IntakeActual = engine->triggerCentral.getVVTPosition(0, 0);
230 msg.Bank1ExhaustActual = engine->triggerCentral.getVVTPosition(0, 1);
231 msg.Bank2IntakeActual = engine->triggerCentral.getVVTPosition(1, 0);
232 msg.Bank2ExhaustActual = engine->triggerCentral.getVVTPosition(1, 1);
233#endif // EFI_SHAFT_POSITION_INPUT
234
235 // TODO: maybe don't rely on outputChannels here
236 msg.Bank1IntakeTarget = engine->outputChannels.vvtTargets[0];
237 msg.Bank1ExhaustTarget = engine->outputChannels.vvtTargets[1];
238 msg.Bank2IntakeTarget = engine->outputChannels.vvtTargets[2];
239 msg.Bank2ExhaustTarget = engine->outputChannels.vvtTargets[3];
240}
241
242struct Egts {
243 uint8_t egt[8];
244};
245
246static void populateFrame(Egts& msg) {
247 msg.egt[0] = Sensor::getOrZero(SensorType::EGT1) / 5;
248 msg.egt[1] = Sensor::getOrZero(SensorType::EGT2) / 5;
249 // DBC Defines signals Egt3 through Egt8 but we do not have the code
250}
251
253#if HW_HELLEN && EFI_PROD_CODE
254 if (!getHellenBoardEnabled()) {
255 return;
256 }
257#endif // HW_HELLEN
261
262 transmitStruct<Status> (CanCategory::VERBOSE, base + 0, isExt, canChannel);
263 transmitStruct<Speeds> (CanCategory::VERBOSE, base + 1, isExt, canChannel);
264 transmitStruct<PedalAndTps> (CanCategory::VERBOSE, base + CAN_PEDAL_TPS_OFFSET, isExt, canChannel);
265 transmitStruct<Sensors1> (CanCategory::VERBOSE, base + CAN_SENSOR_1_OFFSET, isExt, canChannel);
266 transmitStruct<Sensors2> (CanCategory::VERBOSE, base + 4, isExt, canChannel);
267 transmitStruct<Fueling> (CanCategory::VERBOSE, base + 5, isExt, canChannel);
268 transmitStruct<Fueling2> (CanCategory::VERBOSE, base + 6, isExt, canChannel);
269 transmitStruct<Fueling3> (CanCategory::VERBOSE, base + 7, isExt, canChannel);
270 transmitStruct<Cams> (CanCategory::VERBOSE, base + 8, isExt, canChannel);
271
272 transmitStruct<Egts> (CanCategory::VERBOSE, base + 9, isExt, canChannel);
273 transmitStruct<PerCylinderKnock> (CanCategory::VERBOSE, base + 10, isExt, canChannel);
274 transmitStruct<Status11> (CanCategory::VERBOSE, base + 11, isExt, canChannel);
275}
276
277#endif // EFI_CAN_SUPPORT
float getMCUInternalTemperature(void)
uint8_t pad[3]
void sendCanVerbose()
static void populateFrame(Status &msg)
FuelComputer fuelComputer
Definition engine.h:139
TriggerCentral triggerCentral
Definition engine.h:318
EngineState engineState
Definition engine.h:344
LambdaMonitor lambdaMonitor
Definition engine.h:236
TunerStudioOutputChannels outputChannels
Definition engine.h:109
constexpr auto & module()
Definition engine.h:200
RegisteredOutputPin mainRelay
Definition efi_gpio.h:76
OutputPin o2heater
Definition efi_gpio.h:99
RegisteredOutputPin fanRelay
Definition efi_gpio.h:86
RegisteredOutputPin fanRelay2
Definition efi_gpio.h:87
RegisteredOutputPin fuelPumpRelay
Definition efi_gpio.h:91
RegisteredOutputPin checkEnginePin
Definition efi_gpio.h:118
float airflowEstimate
WarningCodeState warnings
angle_t timingAdvance[MAX_CYLINDER_COUNT]
bool getLogicValue() const
Definition efi_gpio.cpp:667
virtual SensorResult get() const =0
static float getOrZero(SensorType type)
Definition sensor.h:83
angle_t getVVTPosition(uint8_t bankIndex, uint8_t camIndex)
ObdCode lastErrorCode
EnginePins enginePins
Definition efi_gpio.cpp:24
scaled_channel< int16_t, PACK_MULT_ANGLE > scaled_angle
scaled_channel< int16_t, PACK_MULT_MS > scaled_ms
scaled_channel< uint16_t, PACK_MULT_PRESSURE > scaled_pressure
scaled_channel< int16_t, PACK_MULT_PERCENT > scaled_percent
scaled_channel< uint16_t, PACK_MULT_VOLTAGE > scaled_voltage
static EngineAccessor engine
Definition engine.h:413
static constexpr engine_configuration_s * engineConfiguration
percent_t getInjectorDutyCycle(float rpm)
bool getHellenBoardEnabled()
@ FuelEthanolPercent
fuelTemp("fuelTemp", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 746, 0.01, 0.0, 0.0, "deg C")
oilPressure("Oil Pressure", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 40, 0.03333333333333333, 0.0, 0.0, "kPa")
oilTemp("oilTemp", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 744, 0.01, 0.0, 0.0, "deg C")
distanceTraveled("distanceTraveled", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 760, 0.1, 0.0, 0.0, "km")
warningCounter("Warning: counter", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 140, 1.0, 0.0, 0.0, "count")
fuelFlowRate("Fuel: Flow rate", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 80, 0.005, 0.0, 0.0, "gram/s")
lastErrorCode("Warning: last", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 142, 1.0, 0.0, 0.0, "error")
percent_t getCoilDutyCycle(float rpm)
float stftCorrection[FT_BANK_COUNT]
scaled_channel< uint16_t, 300, 1 > actualLastInjection
static CanTsChannel canChannel