rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
can_dash.cpp
Go to the documentation of this file.
1/**
2 * @file can_dash.cpp
3 *
4 * This file handles transmission of ECU data to various OE dashboards.
5 *
6 * @date Mar 19, 2020
7 * @author Matthew Kennedy, (c) 2020
8 */
9
10#include "pch.h"
11
12#if EFI_CAN_SUPPORT
13#include "can_dash.h"
14#include "can_dash_ms.h"
15#include "can_dash_nissan.h"
16#include "can_dash_haltech.h"
17#include "board_overrides.h"
18#include "can_bmw.h"
19#include "can_vag.h"
20#include "can_dash_honda.h"
21
22#include "rusefi_types.h"
23#include "rtc_helper.h"
24#include "fuel_math.h"
25
26// CAN Bus ID for broadcast
27#define CAN_FIAT_MOTOR_INFO 0x561
28#define CAN_MAZDA_RX_RPM_SPEED 0x201
29#define CAN_MAZDA_RX_STEERING_WARNING 0x300
30#define CAN_MAZDA_RX_STATUS_1 0x212
31#define CAN_MAZDA_RX_STATUS_2 0x420
32
33//w202 DASH
34#define W202_STAT_1 0x308 /* _20ms cycle */
35#define W202_STAT_2 0x608 /* _100ms cycle */
36#define W202_ALIVE 0x210 /* _200ms cycle */
37#define W202_STAT_3 0x310 /* _200ms cycle */
38
39//BMW E90 DASH
40#define E90_ABS_COUNTER 0x0C0
41#define E90_SEATBELT_COUNTER 0x0D7
42#define E90_T15 0x130
43#define E90_RPM 0x175
44#define E90_BRAKE_COUNTER 0x19E
45#define E90_SPEED 0x1A6
46// https://github.com/HeinrichG-V12/E65_ReverseEngineering/blob/main/docs/0x1D0.md
47#define E90_TEMP 0x1D0
48// MECH Anzeige Getriebedaten
49#define E90_GEAR 0x1D2
50#define E90_FUEL 0x349
51#define E90_EBRAKE 0x34F
52#define E90_TIME 0x39E
53
54static time_msecs_t mph_timer;
55static time_msecs_t mph_ctr;
56
57/**
58 * https://docs.google.com/spreadsheets/d/1IkP05ODpjNt-k4YQLYl58_TNlN9U4IBu5z7i0BPVEM4
59 */
60#define GENESIS_COUPLE_RPM_316 0x316
61#define GENESIS_COUPLE_COOLANT_329 0x329
62#define GENESIS_COUPLE_SENSORS_382 0x382
63// when A/C compressor is allowed to be on, these values need to be sent so the A/C panel activates the compressor
64#define GENESIS_COUPLE_AC_ENABLE_18F 0x18F
65
66
67static uint8_t rpmcounter;
68static uint8_t seatbeltcnt;
69static uint8_t abscounter = 0xF0;
70static uint8_t brakecnt_1 = 0xF0, brakecnt_2 = 0xF0;
72static uint16_t mph_counter = 0xF000;
73static bool cluster_time_set;
74
75constexpr uint8_t e90_temp_offset = 49;
76
77// todo: those forward declarations are out of overall code style
78void canDashboardFiat(CanCycle cycle);
79void canMazdaRX8(CanCycle cycle);
80void canDashboardW202(CanCycle cycle);
83void canDashboardAim(CanCycle cycle);
84
85//BMW Dashboard
86//todo: we use 50ms fixed cycle, trace is needed to check for correct period
87static void canDashboardBmwE46(CanCycle cycle) {
88
89 if (cycle.isInterval(CI::_10ms)) {
90 {
91 CanTxMessage msg(CanCategory::NBC, CAN_BMW_E46_RPM);
92 msg[0] = 0x05; // ASC message
93 msg[1] = 0x0C; // Indexed Engine Torque in % of C_TQ_STND TBD
94 msg.setShortValue((int) (Sensor::getOrZero(SensorType::Rpm) * 6.4), 2);
95 msg[4] = 0x0C;
96 msg[5] = 0x15;
97 msg[6] = 0x00;
98 msg[7] = 0x35;
99 }
100
101 {
102 CanTxMessage msg(CanCategory::NBC, CAN_BMW_E46_DME2);
103 msg[0] = 0x11;
104 msg[1] = (Sensor::getOrZero(SensorType::Clt) + 48.373) / 0.75;
105 msg[2] = 0x00; // baro sensor
106 msg[3] = 0x08;
107 msg[4] = 0x00; // TPS_VIRT_CRU_CAN, not used.
108 msg[5] = 0x00; // TPS out, but we set to 0 just in case.
109 msg[6] = 0x00; // brake system status Ok.
110 msg[7] = 0x00; // not used
111 }
112 }
113}
114
115//todo: we use 50ms fixed cycle, trace is needed to check for correct period
117 if (cycle.isInterval(CI::_50ms)) {
118 {
119 CanTxMessage msg(CanCategory::NBC, CAN_MAZDA_RX_STEERING_WARNING);
120 // todo: something needs to be set here? see http://rusefi.com/wiki/index.php?title=Vehicle:Mazda_Rx8_2004
121 }
122
123 {
124 CanTxMessage msg(CanCategory::NBC, CAN_MAZDA_RX_RPM_SPEED);
125
127
128 // todo: LSB+SWAP? lol, that's MSB?
130 msg.setShortValue(0xFFFF, 2);
131 // todo: LSB+SWAP? lol, that's MSB?
132 msg.setShortValue(SWAP_UINT16((int )(100 * kph + 10000)), 4);
133 msg.setShortValue(0, 6);
134 }
135
136 {
137 CanTxMessage msg(CanCategory::NBC, CAN_MAZDA_RX_STATUS_1);
138 msg[0] = 0xFE; //Unknown
139 msg[1] = 0xFE; //Unknown
140 msg[2] = 0xFE; //Unknown
141 msg[3] = 0x34; //DSC OFF in combo with byte 5 Live data only seen 0x34
142 msg[4] = 0x00; // B01000000; // Brake warning B00001000; //ABS warning
143 msg[5] = 0x40; // TCS in combo with byte 3
144 msg[6] = 0x00; // Unknown
145 msg[7] = 0x00; // Unused
146 }
147
148 {
149 CanTxMessage msg(CanCategory::NBC, CAN_MAZDA_RX_STATUS_2);
151 msg[0] = (uint8_t)(clt.value_or(0) + 69); //temp gauge //~170 is red, ~165 last bar, 152 centre, 90 first bar, 92 second bar
152 // TODO: fixme!
153 //msg[1] = ((int16_t)(engine->engineState.vssEventCounter*(engineConfiguration->vehicleSpeedCoef*0.277*2.58))) & 0xff;
154 msg[2] = 0x00; // unknown
155 msg[3] = 0x00; //unknown
156 msg[4] = 0x01; //Oil Pressure (not really a gauge)
157 msg[5] = 0x00; //check engine light
158 msg[6] = 0x00; //Coolant, oil and battery
159 if ((Sensor::getOrZero(SensorType::Rpm)>0) && (Sensor::get(SensorType::BatteryVoltage).value_or(VBAT_FALLBACK_VALUE)<13)) {
160 msg.setBit(6, 6); // battery light
161 }
162 if (!clt.Valid || clt.Value > 105) {
163 // coolant light, 101 - red zone, light means its get too hot
164 // Also turn on the light in case of sensor failure
165 msg.setBit(6, 1);
166 }
167 //oil pressure warning lamp bit is 7
168 msg[7] = 0x00; //unused
169 }
170 }
171
172}
173
175 if (cycle.isInterval(CI::_50ms)) {
176 {
177 //Fiat Dashboard
178 CanTxMessage msg(CanCategory::NBC, CAN_FIAT_MOTOR_INFO);
179 msg.setShortValue((int) (Sensor::getOrZero(SensorType::Clt) - 40), 3); //Coolant Temp
181 }
182 }
183}
184
186 if (cycle.isInterval(CI::_10ms)) {
187 {
188 // https://github.com/commaai/opendbc/blob/57c8340a180dd8c75139b18050eb17c72c9cb6e4/vw_golf_mk4.dbc#L394
189 //VAG Dashboard
190 CanTxMessage msg(CanCategory::NBC, CAN_VAG_Motor_1);
192 }
193
195
196 {
197 CanTxMessage msg(CanCategory::NBC, CAN_VAG_Motor_2);
198 msg.setShortValue((int) ((clt + 48.373) / 0.75), 1); //Coolant Temp
199 }
200
201 {
202 CanTxMessage msg(CanCategory::NBC, CAN_VAG_CLT_V2);
203 msg.setShortValue((int) ((clt + 48.373) / 0.75), 4); //Coolant Temp
204 }
205
206 {
207 CanTxMessage msg(CanCategory::NBC, CAN_VAG_IMMO);
208 msg.setShortValue(0x80, 1);
209 }
210 }
211}
212
214 if (cycle.isInterval(CI::_20ms)) {
215 {
216 CanTxMessage msg(CanCategory::NBC, W202_STAT_1);
217 msg[0] = 0x08; // Unknown
219 msg[3] = 0x00; // 0x01 - tank blink, 0x02 - EPC
220 msg[4] = 0x00; // Unknown
221 msg[5] = 0x00; // Unknown
222 msg[6] = 0x00; // Unknown - oil info
223 msg[7] = 0x00; // Unknown - oil info
224 }
225 }
226
227 if (cycle.isInterval(CI::_100ms)) {
228 {
229 CanTxMessage msg(CanCategory::NBC, W202_STAT_2); //dlc 7
230 msg[0] = (int)(Sensor::getOrZero(SensorType::Clt) + 40); // CLT -40 offset
231 msg[1] = 0x3D; // TBD
232 msg[2] = 0x63; // Const
233 msg[3] = 0x41; // Const
234 msg[4] = 0x00; // Unknown
235 msg[5] = 0x05; // Const
236 msg[6] = 0x50; // TBD
237 msg[7] = 0x00; // Unknown
238 }
239 }
240
241 if (cycle.isInterval(CI::_200ms)) {
242 {
243 CanTxMessage msg(CanCategory::NBC, W202_ALIVE);
244 msg[0] = 0x0A; // Const
245 msg[1] = 0x18; // Const
246 msg[2] = 0x00; // Const
247 msg[3] = 0x00; // Const
248 msg[4] = 0xC0; // Const
249 msg[5] = 0x00; // Const
250 msg[6] = 0x00; // Const
251 msg[7] = 0x00; // Const
252 }
253
254 {
255 CanTxMessage msg(CanCategory::NBC, W202_STAT_3);
256 msg[0] = 0x00; // Const
257 msg[1] = 0x00; // Const
258 msg[2] = 0x6D; // TBD
259 msg[3] = 0x7B; // Const
260 msg[4] = 0x21; // TBD
261 msg[5] = 0x07; // Const
262 msg[6] = 0x33; // Const
263 msg[7] = 0x05; // Const
264 }
265 }
266}
267
269 if (cycle.isInterval(CI::_50ms)) {
270 {
271 CanTxMessage msg(CanCategory::NBC, GENESIS_COUPLE_RPM_316, 8);
272 msg.setShortValueMsb(Sensor::getOrZero(SensorType::Rpm) * 4, /*offset*/ 3);
273 }
274 {
275 CanTxMessage msg(CanCategory::NBC, GENESIS_COUPLE_COOLANT_329, 8);
277 msg[1] = clt;
278 }
279 }
280}
281
282/**
283 * https://docs.google.com/spreadsheets/d/1XMfeGlhgl0lBL54lNtPdmmFd8gLr2T_YTriokb30kJg
284 */
286 if (cycle.isInterval(CI::_50ms)) {
287
288 { // 'turn-on'
289 CanTxMessage msg(CanCategory::NBC, 0x3C0, 4);
290 // ignition ON
291 msg[2] = 3;
292 }
293
294 { //RPM
295 CanTxMessage msg(CanCategory::NBC, 0x107, 8);
296 msg.setShortValue(Sensor::getOrZero(SensorType::Rpm) / 3.5, /*offset*/ 3);
297 }
298 }
299}
300
301static void canDashboardBmwE90(CanCycle cycle) {
302
303 if (cycle.isInterval(CI::_50ms)) {
304
305 { //T15 'turn-on'
306 CanTxMessage msg(CanCategory::NBC, E90_T15, 5);
307 msg[0] = 0x45;
308 msg[1] = 0x41;
309 msg[2] = 0x61;
310 msg[3] = 0x8F;
311 msg[4] = 0xFC;
312 }
313
314 { //Ebrake light
315 CanTxMessage msg(CanCategory::OBD, E90_EBRAKE, 2);
316 msg[0] = 0xFD;
317 msg[1] = 0xFF;
318 }
319
320 { //RPM
321 rpmcounter++;
322 if (rpmcounter > 0xFE)
323 rpmcounter = 0xF0;
324 CanTxMessage msg(CanCategory::OBD, E90_RPM, 3);
325 msg[0] = rpmcounter;
327 }
328
329 { //oil & coolant temp (all in C, despite gauge being F)
330 tmp_cnt++;
331 if (tmp_cnt >= 0x0F)
332 tmp_cnt = 0x00;
333 CanTxMessage msg(CanCategory::OBD, E90_TEMP, 8);
334 msg[0] = (int)(Sensor::getOrZero(SensorType::Clt) + e90_temp_offset); //coolant
335 msg[1] = (int)(Sensor::getOrZero(SensorType::AuxTemp1) + e90_temp_offset); //oil (AuxTemp1)
336 msg[2] = tmp_cnt;
337 msg[3] = 0xC8;
338 msg[4] = 0xA7;
339 msg[5] = 0xD3;
340 msg[6] = 0x0D;
341 msg[7] = 0xA8;
342 }
343 }
344
345 if (cycle.isInterval(CI::_100ms)) {
346 {
347 //Seatbelt counter
348 seatbeltcnt++;
349 if (seatbeltcnt > 0xFE)
350 seatbeltcnt = 0x00;
351 CanTxMessage msg(CanCategory::NBC, E90_SEATBELT_COUNTER, 2);
352 msg[0] = seatbeltcnt;
353 msg[1] = 0xFF;
354 }
355
356 {
357 //Brake counter 100ms
358 brakecnt_1 += 16;
359 brakecnt_2 += 16;
360 if (brakecnt_1 > 0xEF)
361 brakecnt_1 = 0x0F;
362 if (brakecnt_2 > 0xF0)
363 brakecnt_2 = 0xA0;
364 CanTxMessage msg(CanCategory::NBC, E90_BRAKE_COUNTER, 8);
365 msg[0] = 0x00;
366 msg[1] = 0xE0;
367 msg[2] = brakecnt_1;
368 msg[3] = 0xFC;
369 msg[4] = 0xFE;
370 msg[5] = 0x41;
371 msg[6] = 0x00;
372 msg[7] = brakecnt_2;
373 }
374
375 { //ABS counter
376 abscounter++;
377 if (abscounter > 0xFE)
378 abscounter = 0xF0;
379 CanTxMessage msg(CanCategory::NBC, E90_ABS_COUNTER, 2);
380 msg[0] = abscounter;
381 msg[1] = 0xFF;
382 }
383
384 { //Fuel gauge
385 CanTxMessage msg(CanCategory::NBC, E90_FUEL, 5); //fuel gauge
386 msg[0] = 0x76;
387 msg[1] = 0x0F;
388 msg[2] = 0xBE;
389 msg[3] = 0x1A;
390 msg[4] = 0x00;
391 }
392
393 { //Gear indicator/counter
394 gear_cnt++;
395 if (gear_cnt >= 0x0F)
396 gear_cnt = 0x00;
397 CanTxMessage msg(CanCategory::NBC, E90_GEAR, 6);
398 msg[0] = 0x78;
399 msg[1] = 0x0F;
400 msg[2] = 0xFF;
401 msg[3] = (gear_cnt << 4) | 0xC;
402 msg[4] = 0xF1;
403 msg[5] = 0xFF;
404 }
405
406 { //E90_SPEED
407 auto vehicleSpeed = Sensor::getOrZero(SensorType::VehicleSpeed);
408 float mph = vehicleSpeed * 0.6213712;
409 mph_ctr = ((TIME_I2MS(chVTGetSystemTime()) - mph_timer) / 50);
410 mph_a = (mph_ctr * mph / 2);
413 mph_counter += mph_ctr * 100;
414 if(mph_counter >= 0xFFF0)
415 mph_counter = 0xF000;
416 mph_timer = TIME_I2MS(chVTGetSystemTime());
417 CanTxMessage msg(CanCategory::NBC, E90_SPEED, 8);
418 msg.setShortValue(mph_2a, 0);
419 msg.setShortValue(mph_2a, 2);
420 msg.setShortValue(mph_2a, 4);
421 msg[6] = mph_counter & 0xFF;
422 // todo: what are we packing into what exactly? note the '| 0xF0'
423 msg[7] = (mph_counter >> 8) | 0xF0;
424 }
425 }
426
427 {
428 if (!cluster_time_set) {
429#if EFI_RTC
430 efidatetime_t dateTime = getRtcDateTime();
431#else // EFI_RTC
432 efidatetime_t dateTime = {
433 .year = 0, .month = 0, .day = 0,
434 .hour = 0, .minute = 0, .second = 0,
435 };
436#endif // EFI_RTC
437 CanTxMessage msg(CanCategory::NBC, E90_TIME, 8);
438 msg[0] = dateTime.hour;
439 msg[1] = dateTime.minute;
440 msg[2] = dateTime.second;
441 msg[3] = dateTime.day;
442 msg[4] = (dateTime.month << 4) | 0x0F;
443 msg[5] = dateTime.year & 0xFF;
444 msg[6] = (dateTime.year >> 8) | 0xF0; // collides CAN dash at 4096!
445 msg[7] = 0xF2;
447 }
448 }
449}
450
451//Based on AIM can protocol
452//https://www.aimtechnologies.com/support/racingecu/AiM_CAN_101_eng.pdf
453
454struct Aim5f0 {
455 scaled_channel<uint16_t, 1> Rpm;
456 scaled_channel<uint16_t, 650> Tps;
457 scaled_channel<uint16_t, 650> Pps;
458 scaled_channel<uint16_t, 100> Vss;
459};
460
467
468struct Aim5f1 {
469 scaled_channel<uint16_t, 10> WheelSpeedFR;
470 scaled_channel<uint16_t, 10> WheelSpeedFL;
471 scaled_channel<uint16_t, 10> WheelSpeedRR;
472 scaled_channel<uint16_t, 10> WheelSpeedRL;
473};
474
475static void populateFrame(Aim5f1& msg) {
476 // We don't handle wheel speed, just set to 0?
477 msg.WheelSpeedFR = 0;
478 msg.WheelSpeedFL = 0;
479 msg.WheelSpeedRR = 0;
480 msg.WheelSpeedRL = 0;
481}
482
483struct Aim5f2 {
484 scaled_channel<uint16_t, 190> Iat;
485 scaled_channel<uint16_t, 190> Ect;
486 scaled_channel<uint16_t, 190> FuelT;
487 scaled_channel<uint16_t, 190> OilT;
488};
489
490static void populateFrame(Aim5f2& msg) {
491 msg.Iat = Sensor::getOrZero(SensorType::Iat) + 45;
492 msg.Ect = Sensor::getOrZero(SensorType::Clt) + 45;
495}
496
497struct Aim5f3 {
498 scaled_channel<uint16_t, 10> Map;
499 scaled_channel<uint16_t, 10> Baro;
500 scaled_channel<uint16_t, 1000> OilP;
501 scaled_channel<uint16_t, 20> FuelP;
502};
503
504static void populateFrame(Aim5f3& msg) {
505 // MAP/Baro are sent in millibar -> 10 millibar per kpa
506 msg.Map = 10 * Sensor::getOrZero(SensorType::Map);
508
509 // Oil/Fuel P use bar -> 100 kpa per bar
512}
513
514struct Aim5f4 {
515 scaled_channel<uint16_t, 10000> Boost;
516 scaled_channel<uint16_t, 3200> Vbat;
517 scaled_channel<uint16_t, 10> FuelConsumptionLH;
518 scaled_channel<int16_t, 1> Gear;
519};
520
521static void populateFrame(Aim5f4& msg) {
522 float deltaKpa = Sensor::getOrZero(SensorType::Map)
523 - Sensor::get(SensorType::BarometricPressure).value_or(STD_ATMOSPHERE);
524 float boostBar = deltaKpa / 100;
525
526#ifdef MODULE_ODOMETER
527 float gPerSecond = engine->module<TripOdometer>()->getConsumptionGramPerSecond();
528#else
529 float gPerSecond = 0;
530#endif // MODULE_ODOMETER
531
532 float gPerHour = gPerSecond * 3600.0f;
533 float literPerHour = gPerHour * 0.00139f;
534
535 msg.Boost = boostBar;
537 msg.FuelConsumptionLH = 10 * literPerHour;
539}
540
541struct Aim5f5 {
542 scaled_channel<uint16_t, 1> ShiftFlag;
543 scaled_channel<uint16_t, 1> GearTime;
544 scaled_channel<uint16_t, 1> TpsV;
545 scaled_channel<uint16_t, 100> FuelLevel;
546};
547
548static void populateFrame(Aim5f5& msg) {
550
551 // Dunno what to do with these
552 msg.ShiftFlag = 0;
553 msg.GearTime = 0;
554 msg.TpsV = 0;
555}
556
557struct Aim5f6 {
558 scaled_channel<uint16_t, 2000> Lambda1;
559 scaled_channel<uint16_t, 2000> Lambda2;
560 scaled_channel<uint16_t, 10> LambdaTemp1;
561 scaled_channel<uint16_t, 10> LambdaTemp2;
562};
563
564static void populateFrame(Aim5f6& msg) {
567 msg.LambdaTemp1 = 0;
568 msg.LambdaTemp2 = 0;
569}
570
571struct Aim5f7 {
572 scaled_channel<uint16_t, 10> LambdaErr1;
573 scaled_channel<uint16_t, 10> LambdaErr2;
574 scaled_channel<uint16_t, 2000> LambdaTarget1;
575 scaled_channel<uint16_t, 2000> LambdaTarget2;
576};
577
578static void populateFrame(Aim5f7& msg) {
579#if EFI_ENGINE_CONTROL
580 // We don't handle wheel speed, just set to 0?
581 msg.LambdaErr1 = 0;
582 msg.LambdaErr2 = 0;
583 // both targets are the same for now
584 msg.LambdaTarget1 = (float)engine->fuelComputer.targetLambda;
585 msg.LambdaTarget2 = (float)engine->fuelComputer.targetLambda;
586#endif // EFI_ENGINE_CONTROL
587}
588
590 if (!cycle.isInterval(CI::_10ms)) {
591 return;
592 }
593
595
596 transmitStruct<Aim5f0>(CanCategory::NBC, 0x5f0, false, canChannel);
597 transmitStruct<Aim5f1>(CanCategory::NBC, 0x5f1, false, canChannel);
598 transmitStruct<Aim5f2>(CanCategory::NBC, 0x5f2, false, canChannel);
599 transmitStruct<Aim5f3>(CanCategory::NBC, 0x5f3, false, canChannel);
600 transmitStruct<Aim5f4>(CanCategory::NBC, 0x5f4, false, canChannel);
601 transmitStruct<Aim5f5>(CanCategory::NBC, 0x5f5, false, canChannel);
602 transmitStruct<Aim5f6>(CanCategory::NBC, 0x5f6, false, canChannel);
603 transmitStruct<Aim5f7>(CanCategory::NBC, 0x5f7, false, canChannel);
604
605 // there are more, but less important for us
606 // transmitStruct<Aim5f8>(0x5f8, false);
607 // transmitStruct<Aim5f9>(0x5f9, false);
608 // transmitStruct<Aim5fa>(0x5fa, false);
609 // transmitStruct<Aim5fb>(0x5fb, false);
610 // transmitStruct<Aim5fc>(0x5fc, false);
611 // transmitStruct<Aim5fd>(0x5fd, false);
612}
613
614std::optional<board_can_update_dash_type> custom_board_update_dash;
615
616PUBLIC_API_WEAK void boardUpdateDash(CanCycle cycle) { UNUSED(cycle); }
617
618void updateDash(CanCycle cycle) {
619 // TODO: use call_board_override
620 if (custom_board_update_dash.has_value()) {
621 custom_board_update_dash.value()(cycle);
622 }
623
624 boardUpdateDash(cycle);
625
626 // Transmit dash data, if enabled
628 case CAN_BUS_NBC_NONE:
629 break;
630 case CAN_BUS_BMW_E46:
631 canDashboardBmwE46(cycle);
632 break;
633 case CAN_BUS_Haltech:
634 canDashboardHaltech(cycle);
635 break;
636 case CAN_BUS_NBC_FIAT:
637 canDashboardFiat(cycle);
638 break;
639 case CAN_BUS_NBC_VAG:
640 canDashboardVAG(cycle);
641 break;
642 case CAN_BUS_MAZDA_RX8:
643 canMazdaRX8(cycle);
644 break;
645 case CAN_BUS_W202_C180:
646 canDashboardW202(cycle);
647 break;
648 case CAN_BUS_BMW_E90:
649 canDashboardBmwE90(cycle);
650 break;
651 case CAN_BUS_MQB:
652 canDashboardVagMqb(cycle);
653 break;
654 case CAN_BUS_NISSAN_VQ:
656 break;
657 case CAN_BUS_GENESIS_COUPE:
659 break;
660 case CAN_BUS_HONDA_K:
661 canDashboardHondaK(cycle);
662 break;
663 case CAN_AIM_DASH:
664 canDashboardAim(cycle);
665 break;
666 case CAN_BUS_MS_SIMPLE_BROADCAST:
667 canDashboardTS(cycle);
668 break;
669 default:
670 criticalError("Nothing for canNbcType %d/%s", engineConfiguration->canNbcType, getCan_nbc_e(engineConfiguration->canNbcType));
671 break;
672 }
673}
674
675#endif // EFI_CAN_SUPPORT
const char * getCan_nbc_e(can_nbc_e value)
static uint8_t mph_last
Definition can_dash.cpp:71
static uint8_t brakecnt_2
Definition can_dash.cpp:70
static uint8_t tmp_cnt
Definition can_dash.cpp:71
static void canDashboardBmwE46(CanCycle cycle)
Definition can_dash.cpp:87
std::optional< board_can_update_dash_type > custom_board_update_dash
Definition can_dash.cpp:614
void canMazdaRX8(CanCycle cycle)
Definition can_dash.cpp:116
static void canDashboardBmwE90(CanCycle cycle)
Definition can_dash.cpp:301
constexpr uint8_t e90_temp_offset
Definition can_dash.cpp:75
PUBLIC_API_WEAK void boardUpdateDash(CanCycle cycle)
Definition can_dash.cpp:616
void canDashboardW202(CanCycle cycle)
Definition can_dash.cpp:213
static time_msecs_t mph_ctr
Definition can_dash.cpp:55
static uint8_t rpmcounter
Definition can_dash.cpp:67
static uint8_t gear_cnt
Definition can_dash.cpp:71
static uint16_t mph_counter
Definition can_dash.cpp:72
void canDashboardAim(CanCycle cycle)
Definition can_dash.cpp:589
void canDashboardVAG(CanCycle cycle)
Definition can_dash.cpp:185
static uint8_t abscounter
Definition can_dash.cpp:69
void canDashboardGenesisCoupe(CanCycle cycle)
Definition can_dash.cpp:268
void canDashboardFiat(CanCycle cycle)
Definition can_dash.cpp:174
static uint8_t mph_2a
Definition can_dash.cpp:71
static uint8_t brakecnt_1
Definition can_dash.cpp:70
static uint8_t seatbeltcnt
Definition can_dash.cpp:68
static uint8_t mph_a
Definition can_dash.cpp:71
static void populateFrame(Aim5f0 &msg)
Definition can_dash.cpp:461
static bool cluster_time_set
Definition can_dash.cpp:73
void canDashboardVagMqb(CanCycle cycle)
Definition can_dash.cpp:285
void updateDash(CanCycle cycle)
Definition can_dash.cpp:618
static time_msecs_t mph_timer
Definition can_dash.cpp:54
void canDashboardHaltech(CanCycle cycle)
void canDashboardHondaK(CanCycle cycle)
void canDashboardTS(CanCycle cycle)
void canDashboardNissanVQ(CanCycle cycle)
Definition can.h:86
bool isInterval(CanInterval interval)
Definition can.h:93
void setBit(size_t byteIdx, size_t bitIdx)
Set a single bit in the transmit buffer. Useful for single-bit flags.
void setShortValueMsb(uint16_t value, size_t offset)
void setShortValue(uint16_t value, size_t offset)
Write a 16-bit short value to the buffer. Note: this writes in Intel little endian byte order.
FuelComputer fuelComputer
Definition engine.h:139
constexpr auto & module()
Definition engine.h:200
virtual SensorResult get() const =0
static float getOrZero(SensorType type)
Definition sensor.h:83
uint16_t SWAP_UINT16(uint16_t x)
Definition efilib.h:22
static EngineAccessor engine
Definition engine.h:413
static constexpr engine_configuration_s * engineConfiguration
static CCM_OPTIONAL FunctionalSensor clt(SensorType::Clt, MS2NT(10))
UNUSED(samplingTimeSeconds)
efidatetime_t getRtcDateTime()
Real Time Clock helper.
@ FuelPressureInjector
@ BarometricPressure
uint32_t year
scaled_channel< uint16_t, 10000, 1 > targetLambda
static CanTsChannel canChannel