GCC Code Coverage Report


Directory: ./
File: firmware/config/engines/hyundai.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 47.5% 48 0 101
Functions: 40.0% 2 0 5
Branches: -% 0 0 0
Decisions: -% 0 - 0

Line Branch Decision Exec Source
1 /*
2 * @file hyundai.cpp
3 *
4 https://rusefi.com/docs/pinouts/hellen/hellen-hyundai-pb-mt/
5 *
6 https://rusefi.com/docs/pinouts/hellen/hellen154hyundai/
7 * @date Oct 11, 2021
8 * @author Andrey Belomutskiy, (c) 2012-2021
9 */
10
11 #include "pch.h"
12
13 #include "hyundai.h"
14 #include "proteus_meta.h"
15 #include "hellen_meta.h"
16 #include "defaults.h"
17 #include "lua_lib.h"
18 #include "hyundai_coupe_canned_tables.cpp"
19 #include "hyundai_pb_canned.cpp"
20
21 1 static void set201xHyundai() {
22 #if HW_PROTEUS
23 1 setPPSCalibration(0.73, 4.0, 0.34, 1.86);
24 #else
25 setPPSCalibration(0.73, 4.0, 0.74, 2.28);
26 #endif
27
28 // note how these numbers are very flipped m111 defaults?
29 // extract method?
30 1 setTPS1Calibration(98, 926, 891, 69);
31 1 setEtbPID(8.8944, 70.2307, 0.1855);
32 // Some sensible defaults for other options
33 1 setAlgorithm(engine_load_mode_e::LM_SPEED_DENSITY);
34
35 1 engineConfiguration->vvtControlMinRpm = 1500;
36 1 }
37
38 // set engine_type 104
39 1 void setHyundaiPb() {
40 1 setGDIFueling();
41 // override injection phase
42 1 cannedPbTables();
43 1 setInline4();
44 1 engineConfiguration->displacement = 1.6;
45 1 strcpy(engineConfiguration->engineMake, ENGINE_MAKE_Hyundai);
46 1 strcpy(engineConfiguration->engineCode, "Gamma");
47
48 1 engineConfiguration->trigger.type = trigger_type_e::TT_TOOTHED_WHEEL_60_2;
49 1 engineConfiguration->globalTriggerAngleOffset = 115;
50 1 engineConfiguration->vvtOffsets[0] = 227;
51 1 engineConfiguration->vvtOffsets[1] = 50;
52
53 1 engineConfiguration->enableSoftwareKnock = true;
54 1 engineConfiguration->etbIdleThrottleRange = 6.0;
55
56 1 engineConfiguration->totalGearsCount = 5;
57 1 engineConfiguration->gearRatio[0] = 12;
58 1 engineConfiguration->gearRatio[1] = 6;
59 1 engineConfiguration->gearRatio[2] = 4.4;
60 1 engineConfiguration->gearRatio[3] = 2.4;
61 1 engineConfiguration->gearRatio[4] = 1;
62
63 // ETB buzzing is annoying :(
64 1 engineConfiguration->disableEtbWhenEngineStopped = true;
65
66 1 engineConfiguration->afr.hwChannel = EFI_ADC_NONE;
67 1 engineConfiguration->enableAemXSeries = true;
68
69 1 set201xHyundai();
70 // Injectors flow 1214 cc/min at 100 bar pressure
71 1 engineConfiguration->injector.flow = 1214;
72
73 1 setCustomMap(/*lowValue*/ 20, /*mapLowValueVoltage*/ 0.79, /*highValue*/ 101.3, /*mapHighValueVoltage*/ 4);
74
75 1 engineConfiguration->mc33_hpfp_i_peak = 10;
76 1 engineConfiguration->mc33_hpfp_i_hold = 4;
77
78 1 engineConfiguration->vvtMode[0] = VVT_SINGLE_TOOTH;
79 1 engineConfiguration->vvtMode[1] = VVT_SINGLE_TOOTH;
80
81 1 engineConfiguration->hpfpCamLobes = 4;
82 1 setHpfpLobeProfileAngle(engineConfiguration->hpfpCamLobes);
83 1 engineConfiguration->rethrowHardFault = true;
84
85 1 engineConfiguration->highPressureFuel.v1 = 0.5; /* volts */;
86 1 engineConfiguration->highPressureFuel.value1 = 0;
87 1 engineConfiguration->highPressureFuel.v2 = 4.5; /* volts */;
88 // page 98, Fuel System > Engine Control System > Rail Pressure Sensor (RPS) > Specifications
89 1 engineConfiguration->highPressureFuel.value2 = 20'000;
90
91 #ifdef HW_HELLEN_4K_GDI
92 engineConfiguration->starterControlPin = Gpio::TLE9104_2_OUT_2; // vvt3
93
94 #endif
95
96 #ifdef HW_HELLEN_4CHAN
97 engineConfiguration->triggerInputPins[0] = Gpio::H144_IN_CAM;
98 engineConfiguration->triggerInputPins[1] = Gpio::H144_IN_D_4;
99 engineConfiguration->highPressureFuel.hwChannel = H144_IN_O2S2;
100
101 engineConfiguration->starterControlPin = Gpio::H144_OUT_PWM5; // F1
102 engineConfiguration->startStopButtonPin = Gpio::H144_IN_VSS; // C4
103 config->boardUse2stepPullDown = true; // looks like 1K extra pull-down is needed on the harness?! :(
104 engineConfiguration->camInputs[0] = Gpio::H144_IN_D_4; // E6
105 engineConfiguration->map.sensor.hwChannel = H144_IN_MAP2;
106 #endif // HW_HELLEN_4CHAN
107
108 #if defined(HW_HELLEN_4CHAN) || EFI_UNIT_TEST
109 1 engineConfiguration->hpfpValvePin = Gpio::H144_OUT_IO6; // E2
110 #endif // HW_HELLEN_4CHAN
111
112 #if HW_PROTEUS && EFI_PROD_CODE
113 engineConfiguration->highPressureFuel.hwChannel = PROTEUS_IN_ANALOG_VOLT_4;
114 setCommonNTCSensorParameters(&engineConfiguration->clt);
115 setCommonNTCSensorParameters(&engineConfiguration->iat);
116
117 // engineConfiguration->acRelayPin = Gpio::PROTEUS_LS_6;
118 engineConfiguration->acSwitch = PROTEUS_DIGITAL_5;
119
120 engineConfiguration->fanPin = Gpio::PROTEUS_LS_5;
121 engineConfiguration->tachOutputPin = Gpio::PROTEUS_IGN_12;
122 engineConfiguration->hpfpValvePin = Gpio::PROTEUS_LS_6;
123 engineConfiguration->vvtPins[0] = Gpio::PROTEUS_LS_15; // intake
124 engineConfiguration->vvtPins[1] = Gpio::PROTEUS_LS_16; // exhaust
125
126
127 engineConfiguration->triggerInputPins[0] = PROTEUS_VR_1;
128 engineConfiguration->camInputs[0] = PROTEUS_DIGITAL_1;
129 engineConfiguration->camInputs[1] = PROTEUS_DIGITAL_2; // currently intake, TODO: flip!
130
131 setProteusEtbIO();
132
133 // something something input levels are not happy for digital input pin?
134 engineConfiguration->starterControlPin = Gpio::PROTEUS_LS_14;
135 engineConfiguration->startStopButtonPin = PROTEUS_IN_AV_6_DIGITAL;
136 #endif // HW_PROTEUS
137 1 engineConfiguration->startStopButtonMode = PI_DEFAULT;
138
139 #if HW_PROTEUS || HW_HELLEN_4CHAN
140 2 strncpy(config->luaScript, GET_BIT_RANGE_LSB TWO_BYTES_LSB PRINT_ARRAY SET_TWO_BYTES_LSB HYUNDAI_SUM_NIBBLES R"(
141
142 GDI4_BASE_ADDRESS = 0xBB20
143 GDI_CHANGE_ADDRESS = GDI4_BASE_ADDRESS + 0x10
144
145 GDI4_CAN_SET_TAG = 0x78
146 local data_set_settings = { GDI4_CAN_SET_TAG, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
147
148 FIXED_POINT = 128
149
150 setTickRate(100)
151
152 function onCanConfiguration3(bus, id, dlc, data)
153 -- print("Received configuration3 "..arrayToString(data))
154 pumpPeak = getTwoBytesLSB(data, 6, 1 / 128)
155 print("GDI4 says PumpPeakCurrent ".. pumpPeak)
156 setLuaGauge(1, pumpPeak)
157 end
158
159 function onCanVersion(bus, id, dlc, data)
160 year = data[1] * 100 + data[2]
161 month = data[3]
162 day = data[4]
163 -- print ("GDI4 firmware " ..year ..'/' ..month ..'/' ..day)
164 end
165
166 canRxAdd(GDI4_BASE_ADDRESS + 3, onCanConfiguration3)
167 canRxAdd(GDI4_BASE_ADDRESS + 5, onCanVersion)
168
169
170 EMS_DCT11_128 = 0x80
171 EMS_DCT12_129 = 0x81
172 EMS_H12_399 = 0x18f
173 EMS6_608 = 0x260
174 EMS5_672 = 0x2a0
175 EMS11_790 = 0x316
176 EMS12_809 = 0x329
177 EMS9_898 = 0x382
178 EMS14_1349 = 0x545
179
180 counter = 0
181
182 payLoad128 = { 0x00, 0x17, 0x70, 0x0F, 0x1B, 0x2C, 0x1B, 0x75 }
183 payLoad129 = { 0x40, 0x84, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x75 }
184 payLoad399 = { 0x00, 0x30, 0x1d, 0x00, 0x00, 0x63, 0x00, 0x00 }
185 payLoad608 = { 0x05, 0x1d, 0x00, 0x30, 0x01, 0xa5, 0x7f, 0x31 }
186 payLoad672 = { 0xe0, 0x00, 0x5f, 0x98, 0x39, 0x12, 0x9e, 0x08 }
187 payLoad809 = { 0xd7, 0x7b, 0x7e, 0x0c, 0x11, 0x2c, 0x00, 0x10 }
188 payLoad898 = { 0x40, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x08 }
189 payLoad1349 = { 0xCA, 0x16, 0x00, 0x8A, 0x75, 0xFF, 0x75, 0xFF }
190
191 speedSensor = Sensor.new("VehicleSpeed")
192 speedSensor : setTimeout(3000)
193
194 function onCluPacket(bus, id, dlc, data)
195 speedKph = getBitRange(data, 8, 9) * 0.5
196 -- print('onCAR_SPEED ' ..speedKph)
197 speedSensor : set(speedKph)
198 end
199
200 canRxAdd(1, 1264, onCluPacket)
201
202 function onTick()
203 local RPMread = math.floor(getSensor("RPM") * 4)
204 local RPMhi = RPMread >> 8
205 local RPMlo = RPMread & 0xff
206
207 payLoad128[3] = RPMlo
208 payLoad128[4] = RPMhi
209
210 counter = (counter + 1) % 16
211
212 check128 = hyundaiSumNibbles(payLoad128, counter)
213 payLoad128[8] = check128 * 16 + counter
214 txCan(1, EMS_DCT11_128, 0, payLoad128)
215
216 check129 = hyundaiSumNibbles(payLoad129, counter)
217 payLoad129[8] = check129 * 16 + counter
218 txCan(1, EMS_DCT12_129, 0, payLoad129)
219
220 canRPMpayload = { 0x05, 0x1B, RPMlo, RPMhi, 0x1B, 0x2C, 0x00, 0x7F }
221
222 txCan(1, EMS11_790, 0, canRPMpayload)
223 txCan(1, EMS14_1349, 0, payLoad1349)
224
225 txCan(1, EMS_H12_399, 0, payLoad399)
226 txCan(1, EMS6_608, 0, payLoad608)
227 txCan(1, EMS5_672, 0, payLoad672)
228 txCan(1, EMS12_809, 0, payLoad809)
229 txCan(1, EMS9_898, 0, payLoad898)
230
231 pumpPeakCurrent = getCalibration("mc33_hpfp_i_peak")
232 pumpHoldCurrent = getCalibration("mc33_hpfp_i_hold")
233
234 TholdOff = getCalibration("mc33_t_hold_off")
235 THoldDuration = getCalibration("mc33_t_hold_tot")
236
237
238 setTwoBytesLsb(data_set_settings, 1, TholdOff)
239 setTwoBytesLsb(data_set_settings, 3, THoldDuration)
240 setTwoBytesLsb(data_set_settings, 5, pumpPeakCurrent * FIXED_POINT)
241 -- print('Will be sending ' ..arrayToString(data_set_settings))
242 txCan(1, GDI_CHANGE_ADDRESS + 3, 1, data_set_settings)
243
244 setTwoBytesLsb(data_set_settings, 1, pumpHoldCurrent * FIXED_POINT)
245 setTwoBytesLsb(data_set_settings, 3, GDI4_BASE_ADDRESS)
246 -- print('Will be sending ' ..arrayToString(data_set_settings))
247 txCan(1, GDI_CHANGE_ADDRESS + 4, 1, data_set_settings)
248 end
249
250 1 )", efi::size(config->luaScript));
251 #endif // HW_PROTEUS
252
253 1 }
254
255 static void commonGenesisCoupe() {
256 set201xHyundai();
257
258 #if HW_HELLEN_HYUNDAI
259 cannedprimeBins();
260 cannedprimeValues();
261 cannedcltIdleCorrBins();
262 cannedcltIdleCorr();
263 couplecannedignitionTable();
264 couplecannedveTable();
265 #endif // HW_HELLEN_HYUNDAI
266
267 engineConfiguration->displayLogicLevelsInEngineSniffer = true;
268
269 engineConfiguration->enableSoftwareKnock = true;
270
271 engineConfiguration->injectorCompensationMode = ICM_FixedRailPressure;
272
273 strcpy(engineConfiguration->engineMake, ENGINE_MAKE_Hyundai);
274 strcpy(engineConfiguration->engineCode, "Theta II");
275
276 // canned tune https://rusefi.com/online/view.php?msq=1507
277 // default "Single Coil"
278 engineConfiguration->ignitionMode = IM_INDIVIDUAL_COILS;
279 // default 2.0
280 engineConfiguration->displacement = 1.998;
281 // default "false"
282 engineConfiguration->isForcedInduction = true;
283 engineConfiguration->globalTriggerAngleOffset = 360 + 115;
284 engineConfiguration->vvtOffsets[0] = -154;
285 engineConfiguration->vvtOffsets[1] = 335;
286 // default "None"
287 engineConfiguration->injectorCompensationMode = ICM_FixedRailPressure;
288
289
290 // default 95.0
291 engineConfiguration->fanOnTemperature = 80;
292 // default 91.0
293 engineConfiguration->fanOffTemperature = 75;
294 // default "false"
295 engineConfiguration->disableFan1WhenStopped = true;
296 // default 95.0
297 engineConfiguration->fan2OnTemperature = 87;
298 // default 91.0
299 engineConfiguration->fan2OffTemperature = 82;
300 // default "false"
301 engineConfiguration->disableFan2WhenStopped = true;
302 // default 50.0
303 setArrayValues(config->cltCrankingCorr, 70);
304 // default 200.0
305 setArrayValues(config->afterCrankingIACtaperDuration, 100);
306 // default 0.0
307 engineConfiguration->tpsAccelLookback = 0.3;
308 // default 40.0
309 engineConfiguration->tpsAccelEnrichmentThreshold = 12;
310 // default 0.0
311 engineConfiguration->tpsDecelEnleanmentThreshold = 7;
312 // default 0.0
313 engineConfiguration->tpsAccelFractionPeriod = 3;
314 // default 0.0
315 engineConfiguration->tpsAccelFractionDivisor = 3;
316 // default "false"
317 engineConfiguration->useSeparateAdvanceForIdle = true;
318 // default 0.0
319 engineConfiguration->iacByTpsHoldTime = 2;
320 // default 0.0
321 engineConfiguration->iacByTpsDecayTime = 3;
322 // default "false"
323 engineConfiguration->useIdleTimingPidControl = true;
324 // default "false"
325 engineConfiguration->invertVvtControlExhaust = true;
326 // default 33.0
327 engineConfiguration->auxPid[0].offset = 38;
328 // default 0.005
329 engineConfiguration->auxPid[0].iFactor = 25.4;
330 // default 0.0
331 engineConfiguration->auxPid[0].dFactor = 0.1;
332 // default 0.0
333 engineConfiguration->auxPid[1].offset = 38;
334 // default 0.0
335 engineConfiguration->auxPid[1].pFactor = 2;
336 // default 0.0
337 engineConfiguration->auxPid[1].iFactor = 25.4;
338 // default 0.0
339 engineConfiguration->auxPid[1].dFactor = 0.2;
340 // end of canned tune
341
342 strncpy(config->luaScript, R"(
343
344 setTickRate(100)
345 t = Timer.new()
346 t : reset()
347
348 local data_0x329 = { 0x2C, 0x96, 0x80, 0x0E, 0x11, 0x2E, 0x00, 0x14 }
349 local slowCounter = 0
350 local slowRoll = 0
351
352 local slowRollTable = { 0x0C, 0x4F, 0x80, 0xE3 }
353
354 -- wakeup CAN messages
355 local data_0x382 = { 0x00, 0x3A, 0X44, 0x24, 0x00, 0x00, 0x00, 0x00 }
356 local data_0x0a0 = { 0x00, 0x68, 0x00, 0x00, 0x00, 0xFF, 0x01, 0x00 }
357 local data_0x0a1 = { 0x80, 0x80, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00 }
358 local data_0x18f = { 0xFA , 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
359 local data_0x545 = { 0xEC, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00 }
360 local data_0xA1 = { 0x80, 0x80, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00 }
361 local data_0xA0 = { 0x00, 0x68, 0x00, 0x00, 0x00, 0xFF, 0x01, 0x00 }
362 local data_0x260 = { 0x01, 0x1A, 0x1A, 0x10, 0x00, 0xAB, 0x93, 0x00 }
363 local data_0x2A0 = { 0x00, 0x00, 0x04, 0x00, 0x78, 0x05, 0x0D, 0x01 }
364
365 function onTick()
366
367 -- keep alives
368 txCan(1, 0x18f, 0, data_0x18f)
369 txCan(1, 0x545, 0, data_0x545)
370 -- more random can sends
371 txCan(1, 0x545, 0, data_0x545)
372 txCan(1, 0x382, 0, data_0x382)
373 txCan(1, 0xA0, 0, data_0xA0)
374 txCan(1, 0xA1, 0, data_0xA1)
375 txCan(1, 0x260, 0, data_0x260)
376 txCan(1, 0x2A0, 0, data_0x2A0)
377
378 local RPMread = math.floor(getSensor("RPM") + 0.5) * 4
379
380 local RPMhi = RPMread >> 8
381 local RPMlo = RPMread & 0xff
382
383 local CLTread = 50
384 if getSensor("CLT") then
385 CLTread = math.floor(getSensor("CLT") + 0.5)
386 else
387 CLTread = 50
388 end
389
390 local CLThi = CLTread
391 local CLTlo = CLTread * 256
392
393 canCLTpayloadNo = { 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
394 canCLTpayloadLo = { 0x00, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
395 canCLTpayloadHi = { 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
396 canCLTpayloadHi2 = { 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
397
398 if slowCounter == 0 then
399 -- cycle through 0, 40, 80, c0
400 slowRoll = (slowRoll + 1) & 3
401 data_0x329[1] = slowRollTable[slowRoll + 1]
402
403 txCan(1, 0x329, 0, data_0x329)
404 slowCounter = 30
405 end
406 slowCounter = slowCounter -1
407
408 -- rpm fun stuff
409 if t : getElapsedSeconds() < 1.5 then
410 canRPMpayload = { 0x05, 0x1C, 0xFC, 0x7B, 0x1C, 0x2F, 0x00, 0x80 }
411 else
412 canRPMpayload = { 0x05, RPMlo, RPMhi, RPMhi, RPMlo, 0x2F, 0x00, 0x80 }
413 end
414
415 txCan(1, 0x316, 0, canRPMpayload)
416 if CLTread < 60 then
417 txCan(1, 0x608, 0, canCLTpayloadNo)
418 elseif CLTread >= 60 and CLTread < 85 then
419 txCan(1, 0x608, 0, canCLTpayloadLo)
420 elseif CLTread >= 85 and CLTread < 110 then
421 txCan(1, 0x608, 0, canCLTpayloadHi)
422 else
423 txCan(1, 0x608, 0, canCLTpayloadHi2)
424 end
425 end
426
427
428 )", efi::size(config->luaScript));
429 }
430
431 void setGenesisCoupeBK1() {
432 commonGenesisCoupe();
433 // 2010-2012 315cc at 43.5psi
434 // fuel system is fixed pressure 55psi
435 engineConfiguration->injector.flow = 354.19; // https://www.google.com/search?q=315*sqrt%2855%2F43.5%29
436 engineConfiguration->fuelReferencePressure = PSI2KPA(55);
437
438 }
439
440 void setGenesisCoupeBK2() {
441 commonGenesisCoupe();
442 // 2013+ 450cc at 43.5
443 // fuel system is fixed pressure 85psi
444 // flow rate P2 = flow rate P1 * sqrt(P2/P1)
445 engineConfiguration->injector.flow = 629.03; // https://www.google.com/search?q=450*sqrt%2885%2F43.5%29
446 engineConfiguration->fuelReferencePressure = PSI2KPA(85);
447 // default "Throttle 2"
448 engineConfiguration->etbFunctions[1] = DC_Wastegate;
449
450 }
451