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 Speeds {
71 uint16_t rpm;
72 scaled_angle timing;
73 scaled_channel<uint8_t, 2> injDuty;
74 scaled_channel<uint8_t, 2> coilDuty;
75 scaled_channel<uint8_t> vssKph;
76 uint8_t EthanolPercent;
77};
78
79static void populateFrame(Speeds& msg) {
81 msg.rpm = rpm;
82
83 auto timing = engine->engineState.timingAdvance[0];
84 msg.timing = timing > 360 ? timing - 720 : timing;
85#if EFI_ENGINE_CONTROL
86 msg.injDuty = getInjectorDutyCycle(rpm);
87 msg.coilDuty = getCoilDutyCycle(rpm);
88#endif // EFI_ENGINE_CONTROL
90
92}
93
94struct PedalAndTps {
95 scaled_percent pedal;
96 scaled_percent tps1;
97 scaled_percent tps2;
98 scaled_percent wastegate;
99};
100
101static void populateFrame(PedalAndTps& msg)
102{
103 msg.pedal = Sensor::get(SensorType::AcceleratorPedal).value_or(-1);
104 msg.tps1 = Sensor::get(SensorType::Tps1).value_or(-1);
105 msg.tps2 = Sensor::get(SensorType::Tps2).value_or(-1);
106 msg.wastegate = Sensor::get(SensorType::WastegatePosition).value_or(-1);
107}
108
109struct Sensors1 {
110 scaled_pressure map;
111 scaled_channel<uint8_t> clt;
112 scaled_channel<uint8_t> iat;
113 scaled_channel<uint8_t> aux1;
114 scaled_channel<uint8_t> aux2;
115 scaled_channel<uint8_t> mcuTemp;
116 scaled_channel<uint8_t, 2> fuelLevel;
117};
118
119static void populateFrame(Sensors1& msg) {
121
122 msg.clt = Sensor::getOrZero(SensorType::Clt) + PACK_ADD_TEMPERATURE;
123 msg.iat = Sensor::getOrZero(SensorType::Iat) + PACK_ADD_TEMPERATURE;
124
125 msg.aux1 = Sensor::getOrZero(SensorType::AuxTemp1) + PACK_ADD_TEMPERATURE;
126 msg.aux2 = Sensor::getOrZero(SensorType::AuxTemp2) + PACK_ADD_TEMPERATURE;
127
128#if HAL_USE_ADC
129 msg.mcuTemp = getMCUInternalTemperature() + PACK_ADD_TEMPERATURE;
130#endif
131
133}
134
135struct Sensors2 {
136 uint8_t pad[2];
137
139 uint8_t oilTemp;
140 uint8_t fuelTemp;
141 scaled_voltage vbatt;
142};
143
144static void populateFrame(Sensors2& msg) {
145 msg.oilPressure = Sensor::get(SensorType::OilPressure).value_or(-1);
146 msg.oilTemp = Sensor::getOrZero(SensorType::OilTemperature) + PACK_ADD_TEMPERATURE;
147 msg.fuelTemp = Sensor::getOrZero(SensorType::FuelTemperature) + PACK_ADD_TEMPERATURE;
149}
150
151struct Fueling {
152 scaled_channel<uint16_t, 1000> cylAirmass;
153 scaled_channel<uint16_t, 100> estAirflow;
154 scaled_ms fuel_pulse;
155 uint16_t knockCount;
156};
157
158static void populateFrame(Fueling& msg) {
159#if EFI_ENGINE_CONTROL
161 msg.estAirflow = engine->engineState.airflowEstimate;
163 msg.knockCount = engine->module<KnockController>()->getKnockCount();
164#endif // EFI_ENGINE_CONTROL
165}
166
167struct Fueling2 {
168 scaled_channel<uint16_t> fuelConsumedGram;
169 scaled_channel<uint16_t, PACK_MULT_FUEL_FLOW> fuelFlowRate;
170 scaled_percent fuelTrim[2];
171};
172
173static void populateFrame(Fueling2& msg) {
174#ifdef MODULE_ODOMETER
175 msg.fuelConsumedGram = engine->module<TripOdometer>()->getConsumedGrams();
176 msg.fuelFlowRate = engine->module<TripOdometer>()->getConsumptionGramPerSecond();
177#endif // MODULE_ODOMETER
178
179 for (size_t i = 0; i < FT_BANK_COUNT; i++) {
180 msg.fuelTrim[i] = 100.0f * (engine->engineState.stftCorrection[i] - 1.0f);
181 }
182}
183
184struct Fueling3 {
185 scaled_channel<uint16_t, 10000> Lambda;
186 scaled_channel<uint16_t, 10000> Lambda2;
187 scaled_channel<uint16_t, 30> FuelPressureLow;
188 scaled_channel<uint16_t, 10> FuelPressureHigh;
189};
190
191static void populateFrame(Fueling3& msg) {
194 msg.FuelPressureLow = Sensor::getOrZero(SensorType::FuelPressureLow);
195 msg.FuelPressureHigh = KPA2BAR(Sensor::getOrZero(SensorType::FuelPressureHigh));
196}
197
198struct PerCylinderKnock {
199 int8_t knock[8];
200};
201
202static void populateFrame(PerCylinderKnock& msg) {
203 for (size_t index = 0;index<std::min(8, MAX_CYLINDER_COUNT);index++) {
204 msg.knock[index] = engine->module<KnockController>()->m_knockCyl[index];
205 }
206}
207
208struct Cams {
209 int8_t Bank1IntakeActual;
210 int8_t Bank1IntakeTarget;
211 int8_t Bank1ExhaustActual;
212 int8_t Bank1ExhaustTarget;
213 int8_t Bank2IntakeActual;
214 int8_t Bank2IntakeTarget;
215 int8_t Bank2ExhaustActual;
216 int8_t Bank2ExhaustTarget;
217};
218
219static void populateFrame(Cams& msg) {
220#if EFI_SHAFT_POSITION_INPUT
221 msg.Bank1IntakeActual = engine->triggerCentral.getVVTPosition(0, 0);
222 msg.Bank1ExhaustActual = engine->triggerCentral.getVVTPosition(0, 1);
223 msg.Bank2IntakeActual = engine->triggerCentral.getVVTPosition(1, 0);
224 msg.Bank2ExhaustActual = engine->triggerCentral.getVVTPosition(1, 1);
225#endif // EFI_SHAFT_POSITION_INPUT
226
227 // TODO: maybe don't rely on outputChannels here
228 msg.Bank1IntakeTarget = engine->outputChannels.vvtTargets[0];
229 msg.Bank1ExhaustTarget = engine->outputChannels.vvtTargets[1];
230 msg.Bank2IntakeTarget = engine->outputChannels.vvtTargets[2];
231 msg.Bank2ExhaustTarget = engine->outputChannels.vvtTargets[3];
232}
233
234struct Egts {
235 uint8_t egt[8];
236};
237
238static void populateFrame(Egts& msg) {
239 msg.egt[0] = Sensor::getOrZero(SensorType::EGT1) / 5;
240 msg.egt[1] = Sensor::getOrZero(SensorType::EGT2) / 5;
241 // DBC Defines signals Egt3 through Egt8 but we do not have the code
242}
243
245#if HW_HELLEN && EFI_PROD_CODE
246 if (!getHellenBoardEnabled()) {
247 return;
248 }
249#endif // HW_HELLEN
253
254 transmitStruct<Status> (CanCategory::VERBOSE, base + 0, isExt, canChannel);
255 transmitStruct<Speeds> (CanCategory::VERBOSE, base + 1, isExt, canChannel);
256 transmitStruct<PedalAndTps> (CanCategory::VERBOSE, base + CAN_PEDAL_TPS_OFFSET, isExt, canChannel);
257 transmitStruct<Sensors1> (CanCategory::VERBOSE, base + CAN_SENSOR_1_OFFSET, isExt, canChannel);
258 transmitStruct<Sensors2> (CanCategory::VERBOSE, base + 4, isExt, canChannel);
259 transmitStruct<Fueling> (CanCategory::VERBOSE, base + 5, isExt, canChannel);
260 transmitStruct<Fueling2> (CanCategory::VERBOSE, base + 6, isExt, canChannel);
261 transmitStruct<Fueling3> (CanCategory::VERBOSE, base + 7, isExt, canChannel);
262 transmitStruct<Cams> (CanCategory::VERBOSE, base + 8, isExt, canChannel);
263
264 transmitStruct<Egts> (CanCategory::VERBOSE, base + 9, isExt, canChannel);
265 transmitStruct<PerCylinderKnock> (CanCategory::VERBOSE, base + 10, isExt, canChannel);
266}
267
268#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