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