rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
can_vss.cpp
Go to the documentation of this file.
1/**
2 * @file can_vss.cpp
3 *
4 * This file handles incoming vss values from can.
5 *
6 * @date Apr 19, 2020
7 * @author Alex Miculescu, (c) 2020
8 */
9
10#include "pch.h"
11
12#if EFI_CAN_SUPPORT
13#include "can_rx.h"
14#include "dynoview.h"
15#include "stored_value_sensor.h"
16
17static bool isInit = false;
18static uint16_t filterVssCanID = 0;
19static uint16_t filterSecondVssCanID = 0;
20static uint16_t filterRpmCanID = 0;
21
23
24static expected<uint16_t> look_up_rpm_can_id(can_vss_nbc_e type) {
25 switch (type) {
26 case HONDA_CIVIC9:
27 return 0x17C;
28// case HYUNDAI_PB:
29 case NISSAN_350:
30 return 0x23D;
31 case BMW_e46:
32 case W202:
33 case BMW_e90:
34 case HYUNDAI_PB:
35 firmwareError(ObdCode::OBD_Vehicle_Speed_SensorB, "RPM Can type not implemented yet: %d", type);
36 return unexpected;
37 default:
38 firmwareError(ObdCode::OBD_Vehicle_Speed_SensorB, "Wrong RPM Can type: %d", type);
39 return unexpected;
40 }
41}
42
43static expected<uint16_t> look_up_vss_can_id(can_vss_nbc_e type) {
44 switch (type) {
45 case BMW_e46:
46 return 0x01F0; /* BMW e46 ABS Message */
47 case BMW_e90:
48 return 0x1A0; // BMW E90 ABS speed frame (not wheel speeds, vehicle speed)
49 case NISSAN_350:
50 // decimal 640 0x280 has cluster speed but we use wheel speeds
51 return /*0x284*/644;
52 case HYUNDAI_PB:
53 // decimal 1264 0x4F0 CLU1 has cluster speed but we use wheel speeds
54 return /*0x1F1*/497;
55 case HONDA_CIVIC9:
56 return 0x309;
57 case W202:
58 return 0x0200; /* W202 C180 ABS signal */
59 default:
60 firmwareError(ObdCode::OBD_Vehicle_Speed_SensorB, "Wrong VSS Can type selected: %d", type);
61 return unexpected;
62 }
63}
64
66 switch (type) {
67 case NISSAN_350:
68 // decimal 640 0x280 has cluster speed but we use wheel speeds
69 return /*0x285*/645;
70 default:
71 // it's OK not to require second packet
72 return 0;
73 }
74}
75
76/* Module specific processing functions */
77/* source: http://z4evconversion.blogspot.com/2016/07/completely-forgot-but-it-does-live-on.html */
78float processBMW_e46(const CANRxFrame& frame) {
79 // average the rear wheels since those are the driven ones (more accurate gear detection!)
80 uint16_t left = getTwoBytesLsb(frame, 4);
81 uint16_t right = getTwoBytesLsb(frame, 6);
82
83 return (left + right) / (16 * 2);
84}
85
86// open question if that's front axle or rear axle?
87static int nissanFrontAxle = 0;
88
89float processNissan(const CANRxFrame& frame) {
90 // todo: open question which one is left which one is right
91 int left = getTwoBytesMsb(frame, 0);
92 int right = getTwoBytesMsb(frame, 2);
93
94 nissanFrontAxle = left + right;
95
96 return nissanFrontAxle / (100.0 * 2);
97}
98
99float processBMW_e90(const CANRxFrame& frame) {
100 return 0.1f * getTwoBytesLsb(frame, 0);
101}
102
103float processW202(const CANRxFrame& frame) {
104 // todo: reuse one of the getTwoBytes methods!
105 uint16_t tmp = (frame.data8[2] << 8);
106 tmp |= frame.data8[3];
107 return tmp * 0.0625;
108}
109
110#define SLIP_RATIO(frontAxle, rearAxle) (((frontAxle) == 0 || (rearAxle) == 0) ? 1 : 1.0 * (frontAxle) / (rearAxle))
111
112float processHyundai(const CANRxFrame& frame, efitick_t nowNt) {
113 int frontL = getBitRangeLsb(frame.data8, 16, 12);
114 int frontR = getBitRangeLsb(frame.data8, 28, 12);
115 int rearL = getBitRangeLsb(frame.data8, 40, 12);
116 int rearR = getBitRangeLsb(frame.data8, 52, 12);
117
118 int frontAxle = (frontL + frontR);
119 int rearAxle = (rearL + rearR);
120
122 efiPrintf("processHyundai: frontL %d rearL %d", frontL, rearL);
123 }
124
125 wheelSlipRatio.setValidValue(SLIP_RATIO(frontAxle, rearAxle), nowNt);
126
127 return frontAxle / /*average*/2 / /* scale */8;
128}
129
130/* End of specific processing functions */
131
132expected<float> processCanRxVssImpl(const CANRxFrame& frame, efitick_t nowNt) {
134 case BMW_e46:
135 return processBMW_e46(frame);
136 case BMW_e90:
137 return processBMW_e90(frame);
138 case W202:
139 return processW202(frame);
140 case HYUNDAI_PB:
141 return processHyundai(frame, nowNt);
142 case NISSAN_350:
143 return processNissan(frame);
144 default:
145 efiPrintf("vss unsupported can option selected %x", engineConfiguration->canVssNbcType );
146 }
147
148 return unexpected;
149}
150
152
153static void processNissanSecondVss(const CANRxFrame& frame, efitick_t nowNt) {
154 // todo: open question which one is left which one is right
155 int left = getTwoBytesMsb(frame, 0);
156 int right = getTwoBytesMsb(frame, 2);
157
158 int rearAxle = left + right;
159
161 efiPrintf("processNissan: front %d rear %d", nissanFrontAxle, rearAxle);
162 }
163
164 wheelSlipRatio.setValidValue(SLIP_RATIO(nissanFrontAxle, rearAxle), nowNt);
165}
166
167void processCanRxSecondVss(const CANRxFrame& frame, efitick_t nowNt) {
169 case NISSAN_350:
170 processNissanSecondVss(frame, nowNt);
171 return;
172 default:
173 criticalError("Unexpected processCanRxSecondVss %d", (int)engineConfiguration->canVssNbcType);
174 }
175}
176
177void processCanRxVss(const CANRxFrame& frame, efitick_t nowNt) {
179 return;
180 }
181
182 //filter it we need to process the can message or not
183 if (CAN_SID(frame) == filterVssCanID) {
184 if (auto speed = processCanRxVssImpl(frame, nowNt)) {
186 }
187 }
188
189 if (CAN_SID(frame) == filterSecondVssCanID) {
190 processCanRxSecondVss(frame, nowNt);
191 }
192
193
194 if (CAN_SID(frame) == filterRpmCanID) {
195 }
196
197}
198
202 filterVssCanID = canId.Value;
206 isInit = true;
207 } else {
208 isInit = false;
209 }
210
211
212 // todo: how do we handle 'isInit' for case with only RPM without VSS for instance?
215 filterRpmCanID = canId.Value;
216 }
217
218 }
219}
220
221void setCanVss(int type) {
223}
224
225#endif // EFI_CAN_SUPPORT
uint16_t getTwoBytesLsb(const CANRxFrame &frame, int offset)
Definition can_rx.cpp:126
uint16_t getTwoBytesMsb(const CANRxFrame &frame, int offset)
Definition can_rx.cpp:130
static void processNissanSecondVss(const CANRxFrame &frame, efitick_t nowNt)
Definition can_vss.cpp:153
float processW202(const CANRxFrame &frame)
Definition can_vss.cpp:103
static uint16_t filterRpmCanID
Definition can_vss.cpp:20
static uint16_t look_up_second_vss_can_id(can_vss_nbc_e type)
Definition can_vss.cpp:65
void processCanRxVss(const CANRxFrame &frame, efitick_t nowNt)
Definition can_vss.cpp:177
expected< float > processCanRxVssImpl(const CANRxFrame &frame, efitick_t nowNt)
Definition can_vss.cpp:132
static bool isInit
Definition can_vss.cpp:17
static expected< uint16_t > look_up_rpm_can_id(can_vss_nbc_e type)
Definition can_vss.cpp:24
void setCanVss(int type)
Definition can_vss.cpp:221
float processBMW_e90(const CANRxFrame &frame)
Definition can_vss.cpp:99
static StoredValueSensor canSpeed(SensorType::VehicleSpeed, MS2NT(500))
static StoredValueSensor wheelSlipRatio(SensorType::WheelSlipRatio, MS2NT(1000))
static uint16_t filterVssCanID
Definition can_vss.cpp:18
float processNissan(const CANRxFrame &frame)
Definition can_vss.cpp:89
float processHyundai(const CANRxFrame &frame, efitick_t nowNt)
Definition can_vss.cpp:112
float processBMW_e46(const CANRxFrame &frame)
Definition can_vss.cpp:78
static int nissanFrontAxle
Definition can_vss.cpp:87
void initCanVssSupport()
Definition can_vss.cpp:199
void processCanRxSecondVss(const CANRxFrame &frame, efitick_t nowNt)
Definition can_vss.cpp:167
static uint16_t filterSecondVssCanID
Definition can_vss.cpp:19
static expected< uint16_t > look_up_vss_can_id(can_vss_nbc_e type)
Definition can_vss.cpp:43
bool Register()
Definition sensor.cpp:131
Base class for sensors that compute a value on one thread, and want to make it available to consumers...
void setValidValue(float value, efitick_t timestamp)
int getBitRangeLsb(const uint8_t data[], int bitIndex, int bitWidth)
Definition efilib.cpp:207
static constexpr engine_configuration_s * engineConfiguration
void firmwareError(ObdCode code, const char *fmt,...)
@ OBD_Vehicle_Speed_SensorB
can_vss_nbc_e
Base class for a sensor that has its value asynchronously set, then later retrieved by a consumer.
uint8_t data8[8]
Frame data.
Definition can_mocks.h:55