rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
lua_hooks.cpp
Go to the documentation of this file.
1#include "pch.h"
2
3#include "rusefi_lua.h"
4#include "lua_hooks.h"
5
6#include "lua_biquad.h"
7#include "fuel_math.h"
8#include "airmass.h"
9#include "lua_airmass.h"
10#include "value_lookup.h"
11#include "can_filter.h"
12#include "tunerstudio.h"
13#include "lua_pid.h"
14#include "start_stop.h"
15#include "tinymt32.h" // TL,DR: basic implementation of 'random'
16#include "signaldebounce.h"
17
18#if EFI_PROD_CODE && HW_HELLEN
19#include "hellen_meta.h"
20#endif
21
22#if EFI_DAC
23#include "dac.h"
24#endif // EFI_DAC
25
26#if EFI_CAN_SUPPORT || EFI_UNIT_TEST
27#include "can_msg_tx.h"
28#endif // EFI_CAN_SUPPORT
29#include "settings.h"
30#include <new>
31
32// We don't want to try and use the STL on a microcontroller
33#define LUAAA_WITHOUT_CPP_STDLIB
34#include "luaaa.hpp"
35#include "lua_hooks_util.h"
36using namespace luaaa;
37
38#include "script_impl.h"
40
41#if EFI_PROD_CODE
42#include "electronic_throttle.h"
43#endif // EFI_PROD_CODE
44
45#if EFI_SENT_SUPPORT
46#include "sent.h"
47#endif // EFI_SENT_SUPPORT
48
49static int lua_vin(lua_State* l) {
50 auto zeroBasedCharIndex = luaL_checkinteger(l, 1);
51 if (zeroBasedCharIndex < 0 || zeroBasedCharIndex > VIN_NUMBER_SIZE) {
52 lua_pushnil(l);
53 } else {
54 char value = engineConfiguration->vinNumber[zeroBasedCharIndex];
55 lua_pushinteger(l, value);
56 }
57 return 1;
58}
59
60static int lua_readpin(lua_State* l) {
61#if EFI_PROD_CODE
62 const char * msg = luaL_checkstring(l, 1);
64 if (!isBrainPinValid(pin)) {
65 efiPrintf("LUA: invalid pin [%s]", msg);
66 lua_pushnil(l);
67 } else {
68 int physicalValue = palReadPad(getHwPort("read", pin), getHwPin("read", pin));
69 lua_pushinteger(l, physicalValue);
70 }
71#else
72 UNUSED(l);
73#endif
74 return 1;
75}
76
77static int getSensor(lua_State* l, SensorType type) {
78 auto result = Sensor::get(type);
79
80 if (result) {
81 // return value if valid
82 lua_pushnumber(l, result.Value);
83 } else {
84 // return nil if invalid
85 lua_pushnil(l);
86 }
87
88 return 1;
89}
90
91static int lua_getAuxAnalog(lua_State* l) {
92 // todo: shall we use HUMAN_OFFSET since UI goes from 1 and Lua loves going from 1?
93 auto zeroBasedSensorIndex = luaL_checkinteger(l, 1);
94
95 auto type = static_cast<SensorType>(zeroBasedSensorIndex + static_cast<int>(SensorType::AuxAnalog1));
96
97 return getSensor(l, type);
98}
99
100static int lua_getSensorByIndex(lua_State* l) {
101 auto zeroBasedSensorIndex = luaL_checkinteger(l, 1);
102
103 return getSensor(l, static_cast<SensorType>(zeroBasedSensorIndex));
104}
105
106static SensorType findSensorByName(lua_State* l, const char* name) {
107 SensorType type = findSensorTypeByName(name);
108
109 if (l && type == SensorType::Invalid) {
110 luaL_error(l, "Invalid sensor type: %s", name);
111 }
112
113 return type;
114}
115
116static int lua_getSensorByName(lua_State* l) {
117 auto sensorName = luaL_checklstring(l, 1, nullptr);
118 SensorType type = findSensorByName(l, sensorName);
119
120 return getSensor(l, type);
121}
122
123static int lua_getSensorRaw(lua_State* l) {
124 auto zeroBasedSensorIndex = luaL_checkinteger(l, 1);
125
126 lua_pushnumber(l, Sensor::getRaw(static_cast<SensorType>(zeroBasedSensorIndex)));
127 return 1;
128}
129
130static int lua_hasSensor(lua_State* l) {
131 auto zeroBasedSensorIndex = luaL_checkinteger(l, 1);
132
133 lua_pushboolean(l, Sensor::hasSensor(static_cast<SensorType>(zeroBasedSensorIndex)));
134 return 1;
135}
136
137/**
138 * @return number of elements
139 */
140uint32_t getLuaArray(lua_State* l, int paramIndex, uint8_t *data, uint32_t size) {
141 uint32_t result = 0;
142
143 luaL_checktype(l, paramIndex, LUA_TTABLE);
144 while (true) {
145 lua_pushnumber(l, result + 1);
146 auto elementType = lua_gettable(l, paramIndex);
147 auto val = lua_tonumber(l, -1);
148 lua_pop(l, 1);
149
150 if (elementType == LUA_TNIL) {
151 // we're done, this is the end of the array.
152 break;
153 }
154
155 if (elementType != LUA_TNUMBER) {
156 // We're not at the end, but this isn't a number!
157 luaL_error(l, "Unexpected data at position %d: %s", result, lua_tostring(l, -1));
158 }
159
160 // This element is valid, increment DLC
161 result++;
162
163 if (result > size) {
164 luaL_error(l, "Input array longer than buffer");
165 }
166 else {
167 data[result - 1] = val;
168 }
169 }
170 return result;
171}
172
173#if EFI_CAN_SUPPORT || EFI_UNIT_TEST
174
176 lua_Integer channel = luaL_checkinteger(l, 1);
177 // TODO: support multiple channels
178 luaL_argcheck(l, channel == 1 || channel == 2, 1, "only buses 1 and 2 currently supported");
179 return channel - HUMAN_OFFSET;
180}
181
182static int lua_txCan(lua_State* l) {
184 int bus;
185 int id;
186 int ext;
187 int dataIndex;
188 if (lua_gettop(l) == 2) {
189 bus = 0;
190 id = luaL_checkinteger(l, 1);
191 ext = 0;
192 dataIndex = 2;
193 } else {
195 id = luaL_checkinteger(l, 2);
196 ext = luaL_checkinteger(l, 3);
197 dataIndex = 4;
198 }
199
200 // Check that ID is valid based on std vs. ext
201 if (ext == 0) {
202 luaL_argcheck(l, id <= 0x7FF, 2, "ID specified is greater than max std ID");
203 } else {
204 luaL_argcheck(l, id <= 0x1FFF'FFFF, 2, "ID specified is greater than max ext ID");
205 }
206
207 // conform ext parameter to true/false
208 CanTxMessage msg(CanCategory::LUA, id, 8, bus, ext == 0 ? false : true);
209
210 // Unfortunately there is no way to inspect the length of a table,
211 // so we have to just iterate until we run out of numbers
212 uint8_t dlc = 0;
213
214 // todo: reduce code duplication with getLuaArray
215 luaL_checktype(l, dataIndex, LUA_TTABLE);
216 while (true) {
217 lua_pushnumber(l, dlc + 1);
218 auto elementType = lua_gettable(l, dataIndex);
219 auto val = lua_tonumber(l, -1);
220 lua_pop(l, 1);
221
222 if (elementType == LUA_TNIL) {
223 // we're done, this is the end of the array.
224 break;
225 }
226
227 if (elementType != LUA_TNUMBER) {
228 // We're not at the end, but this isn't a number!
229 luaL_error(l, "Unexpected CAN data at position %d: %s", dlc, lua_tostring(l, -1));
230 }
231
232 // This element is valid, increment DLC
233 dlc++;
234
235 if (dlc > 8) {
236 luaL_error(l, "CAN frame length cannot be longer than 8");
237 }
238
239 msg[dlc - 1] = val;
240 }
241
242 msg.setDlc(dlc);
243
244 // no return value
245 return 0;
246}
247#endif // EFI_CAN_SUPPORT
248
250
254
255#if !EFI_UNIT_TEST
256static SimplePwm pwms[LUA_PWM_COUNT];
257
258struct P {
259 SimplePwm& pwm;
260 lua_Integer idx;
261};
262
263static P luaL_checkPwmIndex(lua_State* l, int pos) {
264 auto channel = luaL_checkinteger(l, pos);
265
266 // todo: what a mess :( CAN buses start at 1 and PWM channels start at 0 :(
267 // Ensure channel is valid
268 if (channel < 0 || channel >= LUA_PWM_COUNT) {
269 luaL_error(l, "setPwmDuty invalid channel %d", channel);
270 }
271
272 return { pwms[channel], channel };
273}
274
275#ifndef PWM_FREQ_PWM
276#define PWM_FREQ_PWM 1000
277#endif
278
279void startPwm(int index, float freq, float duty) {
280 // clamp to 1..1000 hz, this line would turn 0hz on/off PWM into 1hz behind the scenes
281 freq = clampF(1, freq, 1000);
282
284
286 &pwms[index], "lua", &engine->scheduler,
287 pwmPin, &enginePins.luaOutputPins[index],
288 freq, duty
289 );
290
291 efiPrintf("LUA PWM on %s at %f initial duty",
292 hwPortname(pwmPin),
293 PERCENT_MULT * duty);
294}
295
296static int lua_startPwm(lua_State* l) {
297 auto p = luaL_checkPwmIndex(l, 1);
298 auto freq = luaL_checknumber(l, 2);
299 auto duty = luaL_checknumber(l, 3);
300
301 if (duty < 0 || duty > PWM_MAX_DUTY) {
302 luaL_error(l, "Duty parameter should be from 0 to 1 got %f", duty);
303 return 0;
304 }
305
306 startPwm(p.idx, freq, duty);
307
308 return 0;
309}
310
312 // Simply de-init all pins - when the script runs again, they will be re-init'd
313 for (size_t i = 0; i < efi::size(enginePins.luaOutputPins); i++) {
315 }
316}
317
318void setPwmDuty(int index, float duty) {
319 // clamp to 0..1
320 duty = clampF(0, duty, 1);
321
323}
324
325static int lua_setPwmDuty(lua_State* l) {
326 auto p = luaL_checkPwmIndex(l, 1);
327 auto duty = luaL_checknumber(l, 2);
328 setPwmDuty(p.idx, duty);
329
330 return 0;
331}
332
333static int lua_setPwmFreq(lua_State* l) {
334 auto p = luaL_checkPwmIndex(l, 1);
335 auto freq = luaL_checknumber(l, 2);
336
337 // clamp to 1..1000 hz
338 freq = clampF(1, freq, 1000);
339
340 p.pwm.setFrequency(freq);
341
342 return 0;
343}
344
345static int lua_getDigital(lua_State* l) {
346 auto idx = luaL_checkinteger(l, 1);
347
348 bool state = false;
349
350 switch (idx) {
351 case 0: state = engine->engineState.clutchDownState; break;
352 case 1: state = engine->engineState.clutchUpState; break;
353 case 2: state = engine->engineState.brakePedalState; break;
354 case 3: state = engine->module<AcController>().unmock().acButtonState; break;
355 default:
356 // Return nil to indicate invalid parameter
357 lua_pushnil(l);
358 return 1;
359 }
360
361 lua_pushboolean(l, state);
362 return 1;
363}
364
365bool getAuxDigital(int index) {
366#if EFI_PROD_CODE
368#else
369 UNUSED(index);
370 return false;
371#endif
372}
373
374static int lua_getAuxDigital(lua_State* l) {
375 auto idx = luaL_checkinteger(l, 1);
376 if (idx < 0 || idx >= LUA_DIGITAL_INPUT_COUNT) {
377 // Return nil to indicate invalid parameter
378 lua_pushnil(l);
379 return 1;
380 }
381
383 // Return nil to indicate invalid pin
384 lua_pushnil(l);
385 return 1;
386 }
387
388#if !EFI_SIMULATOR
389 bool state = getAuxDigital(idx);
390 lua_pushboolean(l, state);
391#endif // !EFI_SIMULATOR
392
393 return 1;
394}
395
396static int lua_setDebug(lua_State* l) {
397 // wrong debug mode, ignore
398 if (engineConfiguration->debugMode != DBG_LUA) {
399 return 0;
400 }
401
402 auto idx = luaL_checkinteger(l, 1);
403 auto val = luaL_checknumber(l, 2);
404
405 // invalid index, ignore
406 if (idx < 1 || idx > 7) {
407 return 0;
408 }
409
410 auto firstDebugField = &engine->outputChannels.debugFloatField1;
411 firstDebugField[idx - 1] = val;
412
413 return 0;
414}
415
416#if EFI_ENGINE_CONTROL
417static auto lua_getAirmassResolveMode(lua_State* l) {
418 if (lua_gettop(l) == 0) {
419 // zero args, return configured mode
421 } else {
422 return static_cast<engine_load_mode_e>(luaL_checkinteger(l, 1));
423 }
424}
425
426static int lua_getAirmass(lua_State* l) {
427 auto airmassMode = lua_getAirmassResolveMode(l);
428 auto airmass = getAirmassModel(airmassMode);
429
430 if (!airmass) {
431 return luaL_error(l, "null airmass");
432 }
433
435 auto result = airmass->getAirmass(rpm, false).CylinderAirmass;
436
437 lua_pushnumber(l, result);
438 return 1;
439}
440
441static int lua_setAirmass(lua_State* l) {
442 float airmass = luaL_checknumber(l, 1);
443 float engineLoadPercent = luaL_checknumber(l, 2);
444
445 airmass = clampF(0, airmass, 10);
446 engineLoadPercent = clampF(0, engineLoadPercent, 1000);
447
448 luaAirmass.setAirmass({airmass, engineLoadPercent});
449
450 return 0;
451}
452#endif // EFI_ENGINE_CONTROL
453
454#endif // EFI_UNIT_TEST
455
456// TODO: PR this back in to https://github.com/gengyong/luaaa
457namespace LUAAA_NS {
458 template<typename TCLASS, typename ...ARGS>
459 struct PlacementConstructorCaller<TCLASS, lua_State*, ARGS...>
460 {
461 // this speciailization passes the Lua state to the constructor as first argument, as it shouldn't
462 // participate in the index generation as it's not a normal parameter passed via the Lua stack.
463
464 static TCLASS * Invoke(lua_State * state, void * mem)
465 {
466 return InvokeImpl(state, mem, typename make_indices<sizeof...(ARGS)>::type());
467 }
468
469 private:
470 template<std::size_t ...Ns>
471 static TCLASS * InvokeImpl(lua_State * state, void * mem, indices<Ns...>)
472 {
473 (void)state;
474 return new(mem) TCLASS(state, LuaStack<ARGS>::get(state, Ns + 1)...);
475 }
476 };
477}
478
479struct LuaSensor final : public StoredValueSensor {
480 LuaSensor() : LuaSensor(nullptr, "Invalid") { }
481
482 ~LuaSensor() {
483 unregister();
484 }
485
486 LuaSensor(lua_State* l, const char* name)
487 : StoredValueSensor(findSensorByName(l, name), MS2NT(100))
488 {
489 // do a soft collision check to avoid a fatal error from the hard check in Register()
490 if (l && Sensor::hasSensor(type())) {
491 luaL_error(l, "Tried to create a Lua sensor of type %s, but one was already registered.", getSensorName());
492 } else {
493 Register();
494 efiPrintf("LUA registered sensor of type %s", getSensorName());
495 }
496 }
497
498 bool isRedundant() const override {
499 return m_isRedundant;
500 }
501
502 // do we need method defined exactly on LuaSensor for Luaa to be happy?
503 void setTimeout(int timeoutMs) override {
505 }
506
507 void setRedundant(bool value) {
508 m_isRedundant = value;
509 }
510
511 void set(float value) {
512 setValidValue(value, getTimeNowNt());
513 }
514
515 void invalidate() {
517 }
518
519 void showInfo(const char* sensorName) const override {
520 const auto value = get();
521 efiPrintf("Sensor \"%s\": Lua sensor: Valid: %s Converted value %.2f", sensorName, boolToString(value.Valid), value.Value);
522 }
523
524private:
525 bool m_isRedundant = false;
526};
527
528static bool isFunction(lua_State* l, int idx) {
529 return lua_type(l, idx) == LUA_TFUNCTION;
530}
531
532int getLuaFunc(lua_State* l) {
533 if (!isFunction(l, 1)) {
534 return luaL_error(l, "expected function");
535 } else {
536 return luaL_ref(l, LUA_REGISTRYINDEX);
537 }
538}
539
540#if EFI_CAN_SUPPORT
541int lua_canRxAdd(lua_State* l) {
542 uint32_t eid;
543
544 // defaults if not passed
545 int bus = ANY_BUS;
546 int callback = NO_CALLBACK;
547 int argumentCount = lua_gettop(l);
548
549 switch (argumentCount) {
550 case 1:
551 // handle canRxAdd(id)
552 eid = luaL_checkinteger(l, 1);
553 break;
554
555 case 2:
556 if (isFunction(l, 2)) {
557 // handle canRxAdd(id, callback)
558 eid = luaL_checkinteger(l, 1);
559 lua_remove(l, 1);
560 callback = getLuaFunc(l);
561 } else {
562 // handle canRxAdd(bus, id)
564 eid = luaL_checkinteger(l, 2);
565 }
566
567 break;
568 case 3:
569 // handle canRxAdd(bus, id, callback)
571 eid = luaL_checkinteger(l, 2);
572 lua_remove(l, 1);
573 lua_remove(l, 1);
574 callback = getLuaFunc(l);
575 break;
576 default:
577 return luaL_error(l, "Wrong number of arguments to canRxAdd. Got %d, expected 1, 2, or 3.", argumentCount);
578 }
579
580 addLuaCanRxFilter(eid, FILTER_SPECIFIC, bus, callback);
581
582 return 0;
583}
584
585int lua_canRxAddMask(lua_State* l) {
586 uint32_t eid;
587 uint32_t mask;
588
589 // defaults if not passed
590 int bus = ANY_BUS;
591 int callback = NO_CALLBACK;
592
593 switch (lua_gettop(l)) {
594 case 2:
595 // handle canRxAddMask(id, mask)
596 eid = luaL_checkinteger(l, 1);
597 mask = luaL_checkinteger(l, 2);
598 break;
599
600 case 3:
601 if (isFunction(l, 3)) {
602 // handle canRxAddMask(id, mask, callback)
603 eid = luaL_checkinteger(l, 1);
604 mask = luaL_checkinteger(l, 2);
605 lua_remove(l, 1);
606 lua_remove(l, 1);
607 callback = getLuaFunc(l);
608 } else {
609 // handle canRxAddMask(bus, id, mask)
611 eid = luaL_checkinteger(l, 2);
612 mask = luaL_checkinteger(l, 3);
613 }
614
615 break;
616 case 4:
617 // handle canRxAddMask(bus, id, mask, callback)
619 eid = luaL_checkinteger(l, 2);
620 mask = luaL_checkinteger(l, 3);
621 lua_remove(l, 1);
622 lua_remove(l, 1);
623 lua_remove(l, 1);
624 callback = getLuaFunc(l);
625 break;
626 default:
627 return luaL_error(l, "Wrong number of arguments to canRxAddMask. Got %d, expected 2, 3, or 4.");
628 }
629
630 addLuaCanRxFilter(eid, mask, bus, callback);
631
632 return 0;
633}
634#endif // EFI_CAN_SUPPORT
635
636PUBLIC_API_WEAK void boardConfigureLuaHooks(lua_State* lState) {
637 UNUSED(lState);
638}
639
641
642void configureRusefiLuaHooks(lua_State* lState) {
644
645 tinymt32_init(&tinymt, 1534525); // todo: share instance with launch_control? probably not?
646 lua_register(lState, "random", [](lua_State* l) {
647 auto random = tinymt32_generate_float(&tinymt);
648 lua_pushnumber(l, random);
649 return 1;
650 });
651
652 LuaClass<Timer> luaTimer(lState, "Timer");
653 luaTimer
654 .ctor()
655 .fun("reset", static_cast<void (Timer::*)() >(&Timer::reset ))
656 .fun("getElapsedSeconds", static_cast<float(Timer::*)()const>(&Timer::getElapsedSeconds));
657
658 LuaClass<LuaSensor> luaSensor(lState, "Sensor");
659 luaSensor
660 .ctor<lua_State*, const char*>()
661 .fun("set", &LuaSensor::set)
662 .fun("setRedundant", &LuaSensor::setRedundant)
663 .fun("setTimeout", &LuaSensor::setTimeout)
664 .fun("invalidate", &LuaSensor::invalidate);
665
666#ifndef WITH_LUA_PID
667#define WITH_LUA_PID TRUE
668#endif
669
670#if WITH_LUA_PID
671 LuaClass<LuaBiQuad> biQuard(lState, "Biquad");
672 biQuard
673 .ctor()
674 .fun("filter", &LuaBiQuad::filter)
675 .fun("configureLowpass", &LuaBiQuad::configureLowpass);
676
677 LuaClass<LuaPid> luaPid(lState, "Pid");
678 luaPid
679 .ctor<float, float, float, float, float>()
680 .fun("get", &LuaPid::get)
681 .fun("setOffset", &LuaPid::setOffset)
682 .fun("reset", &LuaPid::reset);
683
684 LuaClass<LuaIndustrialPid> luaIndustrialPid(lState, "IndustrialPid");
685 luaIndustrialPid
686 .ctor<float, float, float, float, float>()
687 .fun("get", &LuaIndustrialPid::get)
688 .fun("setOffset", &LuaIndustrialPid::setOffset)
689 .fun("setDerivativeFilterLoss", &LuaIndustrialPid::setDerivativeFilterLoss)
690 .fun("setAntiwindupFreq", &LuaIndustrialPid::setAntiwindupFreq)
691 .fun("reset", &LuaIndustrialPid::reset);
692#endif
693
695
696 lua_register(lState, "readPin", lua_readpin);
697#if EFI_PROD_CODE && EFI_SHAFT_POSITION_INPUT
698 lua_register(lState, "startCrankingEngine", [](lua_State* l) {
700 return 0;
701 });
702#endif // EFI_PROD_CODE && EFI_SHAFT_POSITION_INPUT
703 lua_register(lState, "vin", lua_vin);
704
705 lua_register(lState, "getAuxAnalog", lua_getAuxAnalog);
706 lua_register(lState, "getSensorByIndex", lua_getSensorByIndex);
707 lua_register(lState, "getSensor", lua_getSensorByName);
708 lua_register(lState, "getSensorRaw", lua_getSensorRaw);
709 lua_register(lState, "hasSensor", lua_hasSensor);
710
711#ifndef WITH_LUA_CONSUMPTION
712#define WITH_LUA_CONSUMPTION TRUE
713#endif
714
715#if EFI_VEHICLE_SPEED && WITH_LUA_CONSUMPTION && defined (MODULE_ODOMETER)
716 lua_register(lState, "getConsumedGrams", [](lua_State* l) {
717 lua_pushnumber(l, engine->module<TripOdometer>()->getConsumedGrams());
718 return 1;
719 });
720 lua_register(lState, "getConsumedGramsRemainder", [](lua_State* l) {
721 lua_pushnumber(l, engine->module<TripOdometer>()->getConsumedGramsRemainder());
722 return 1;
723 });
724 lua_register(lState, "getConsumptionGramPerSecond", [](lua_State* l) {
725 lua_pushnumber(l, engine->module<TripOdometer>()->getConsumptionGramPerSecond());
726 return 1;
727 });
728 lua_register(lState, "resetOdometer", [](lua_State*) {
729 engine->module<TripOdometer>()->reset();
730 return 0;
731 });
732#endif // EFI_VEHICLE_SPEED WITH_LUA_CONSUMPTION MODULE_ODOMETER
733 lua_register(lState, "table3d", [](lua_State* l) {
734 auto humanTableIdx = luaL_checkinteger(l, 1);
735 auto x = luaL_checknumber(l, 2);
736 auto y = luaL_checknumber(l, 3);
737
738 // index table, compute table lookup
739 auto result = getscriptTable(humanTableIdx - HUMAN_OFFSET)->getValue(x, y);
740
741 lua_pushnumber(l, result);
742 return 1;
743 });
744 // time since console or TunerStudio
745 lua_register(lState, "secondsSinceTsActivity", [](lua_State* l) {
746 lua_pushinteger(l, getSecondsSinceChannelsRequest());
747 return 1;
748 });
749
750 lua_register(lState, "curve", [](lua_State* l) {
751 // index starting from 1
752 auto humanCurveIdx = luaL_checkinteger(l, 1);
753 auto x = luaL_checknumber(l, 2);
754
755 auto result = getCurveValue(humanCurveIdx - HUMAN_OFFSET, x);
756
757 lua_pushnumber(l, result);
758 return 1;
759 });
760
761#if EFI_PROD_CODE || EFI_SIMULATOR
762extern int luaCommandCounters[LUA_BUTTON_COUNT];
763
764 lua_register(lState, "getTsButtonCount",
765 [](lua_State* l) {
766 auto humanIndex = luaL_checkinteger(l, 1);
767 if (humanIndex < 1 || humanIndex > LUA_BUTTON_COUNT) {
768 luaL_error(l, "Invalid button index: %d", humanIndex);
769 return 0;
770 }
771 lua_pushinteger(l, luaCommandCounters[humanIndex - 1]);
772 return 1;
773 });
774#endif // EFI_PROD_CODE || EFI_SIMULATOR
775
776#if EFI_PROD_CODE && EFI_SENT_SUPPORT
777 lua_register(lState, "getSentValue",
778 [](lua_State* l) {
779 auto humanIndex = luaL_checkinteger(l, 1);
780 auto value = getSentValue(static_cast<SentInput>(humanIndex));
781 lua_pushnumber(l, value);
782 return 1;
783 });
784
785 lua_register(lState, "getSentValues",
786 [](lua_State* l) {
787 uint16_t sig0;
788 uint16_t sig1;
789 auto humanIndex = luaL_checkinteger(l, 1);
790 /*auto ret = */getSentValues(static_cast<SentInput>(humanIndex), &sig0, &sig1);
791 lua_pushinteger(l, sig0);
792 lua_pushinteger(l, sig1);
793 return 2;
794 });
795#endif // EFI_SENT_SUPPORT
796
797#if EFI_LAUNCH_CONTROL
798 lua_register(lState, "setSparkSkipRatio", [](lua_State* l) {
799 auto targetSkipRatio = luaL_checknumber(l, 1);
800 engine->engineState.luaSoftSparkSkip = targetSkipRatio;
802 return 0;
803 });
804 lua_register(lState, "setSparkHardSkipRatio", [](lua_State* l) {
805 auto targetSkipRatio = luaL_checknumber(l, 1);
806 engine->engineState.luaHardSparkSkip = targetSkipRatio;
808 return 0;
809 });
810 lua_register(lState, "setLaunchTrigger", [](lua_State* l) {
811 auto value = luaL_checkinteger(l, 1);
813 return 0;
814 });
815#endif // EFI_LAUNCH_CONTROL
816#if EFI_ANTILAG_SYSTEM
817 lua_register(lState, "setRollingIdleTrigger", [](lua_State* l) {
818 auto value = luaL_checkinteger(l, 1);
820 return 0;
821 });
822#endif // EFI_ANTILAG_SYSTEM
823
824#if EFI_EMULATE_POSITION_SENSORS && !EFI_UNIT_TEST
825 lua_register(lState, "selfStimulateRPM", [](lua_State* l) {
826 auto rpm = luaL_checkinteger(l, 1);
827 if (rpm < 1) {
829 return 0;
830 }
833 }
835 return 0;
836 });
837#endif // EFI_UNIT_TEST
838
839 /**
840 * same exact could be accomplished via LuaSensor just with more API
841 */
842 lua_register(lState, "setLuaGauge", [](lua_State* l) {
843 auto index = luaL_checkinteger(l, 1) - 1;
844 auto value = luaL_checknumber(l, 2);
845 if (index < 0 || index >= LUA_GAUGE_COUNT)
846 return 0;
847 extern StoredValueSensor luaGauges[LUA_GAUGE_COUNT];
848 luaGauges[index].setValidValue(value, getTimeNowNt());
849 return 0;
850 });
851
852 lua_register(lState, "enableCanTx", [](lua_State* l) {
853 engine->allowCanTx = lua_toboolean(l, 1);
854 return 0;
855 });
856
857 lua_register(lState, "enableCanRxWorkaround", [](lua_State*) {
858 // that's about global_can_data
860 return 0;
861 });
862// high-performance CANbus should be done on F7+, let's preserve couple of priceless bytes on F4
863#if !defined(STM32F4)
864#if EFI_CAN_SUPPORT
865 lua_register(lState, "getCanRxDropped", [](lua_State* l) {
866 auto count = getLuaCanRxDropped();
867 lua_pushinteger(l, count);
868 return 1;
869 });
870#endif // EFI_CAN_SUPPORT
871 lua_register(lState, "disableExtendedCanBroadcast", [](lua_State*) {
872 // that's about global_can_data
874 return 0;
875 });
876 lua_register(lState, "getCanBaudRate", [](lua_State* l) {
877 auto index = luaL_checkinteger(l, 1);
878 if (index == 1) {
879 lua_pushinteger(l, engineConfiguration->canBaudRate);
880 } else {
881 lua_pushinteger(l, engineConfiguration->can2BaudRate);
882 }
883 return 1;
884 });
885#endif // STM32F4
886
887#if !defined(STM32F4) || defined(WITH_LUA_GET_GPPWM_STATE)
888 lua_register(lState, "getGpPwm", [](lua_State* l) {
889 auto index = luaL_checkinteger(l, 1);
890 // this works due to updateGppwm being invoked from periodicSlowCallback
891 auto result = engine->outputChannels.gppwmOutput[index];
892 lua_pushnumber(l, result);
893 return 1;
894 });
895#endif
896
897#if EFI_ELECTRONIC_THROTTLE_BODY && EFI_PROD_CODE
898 lua_register(lState, "getEtbTarget", [](lua_State* l) {
899 auto controller = engine->etbControllers[0];
900 assertNotNull(controller, 0);
901 auto result = controller->getCurrentTarget();
902 lua_pushnumber(l, result);
903 return 1;
904 });
905 lua_register(lState, "restartEtb", [](lua_State*) {
906 // this is about Lua sensor acting in place of real analog PPS sensor
907 // todo: smarter implementation
908 doInitElectronicThrottle(true); // lame, we run with 'isStartupInit=true' in order to reset, NOT COOL
909 return 0;
910 });
911#endif // EFI_ELECTRONIC_THROTTLE_BODY
912
913 // checksum stuff
914 lua_register(lState, "crc8_j1850", [](lua_State* l) {
915 uint8_t data[8];
916 uint32_t length = getLuaArray(l, 1, data, sizeof(data));
917 auto trimLength = luaL_checkinteger(l, 2);
918 int crc = crc8(data, minI(length, trimLength));
919
920 lua_pushinteger(l, crc);
921 return 1;
922 });
923
924#if EFI_BOOST_CONTROL
925 lua_register(lState, "setBoostTargetAdd", [](lua_State* l) {
926 engine->module<BoostController>().unmock().luaTargetAdd = luaL_checknumber(l, 1);
927 return 0;
928 });
929 lua_register(lState, "setBoostTargetMult", [](lua_State* l) {
930 engine->module<BoostController>().unmock().luaTargetMult = luaL_checknumber(l, 1);
931 return 0;
932 });
933 lua_register(lState, "setBoostDutyAdd", [](lua_State* l) {
934 engine->module<BoostController>().unmock().luaOpenLoopAdd = luaL_checknumber(l, 1);
935 return 0;
936 });
937#endif // EFI_BOOST_CONTROL
938#if EFI_IDLE_CONTROL
939 lua_register(lState, "setIdleAdd", [](lua_State* l) {
940 engine->module<IdleController>().unmock().luaAdd = luaL_checknumber(l, 1);
941 return 0;
942 });
943 lua_register(lState, "setIdleRpm", [](lua_State* l) {
944 auto rpm = luaL_checknumber(l, 1);
945 setLinearCurve(config->cltIdleRpm, rpm, rpm, 1);
946 return 0;
947 });
948#endif
949 lua_register(lState, "setTimingAdd", [](lua_State* l) {
950 engine->ignitionState.luaTimingAdd = luaL_checknumber(l, 1);
951 return 0;
952 });
953#ifndef DISABLE_LUA_SET_TIMING_MULT
954 lua_register(lState, "setTimingMult", [](lua_State* l) {
955 engine->ignitionState.luaTimingMult = luaL_checknumber(l, 1);
956 return 0;
957 });
958#endif // !defined(DISABLE_LUA_SET_TIMING_MULT)
959#ifndef DISABLE_LUA_SET_FUEL_ADD
960 lua_register(lState, "setFuelAdd", [](lua_State* l) {
961 engine->engineState.lua.fuelAdd = luaL_checknumber(l, 1);
962 return 0;
963 });
964#endif // !defined(DISABLE_LUA_SET_FUEL_ADD)
965 lua_register(lState, "setFuelMult", [](lua_State* l) {
966 engine->engineState.lua.fuelMult = luaL_checknumber(l, 1);
967 return 0;
968 });
969#if EFI_ELECTRONIC_THROTTLE_BODY && EFI_PROD_CODE
970 lua_register(lState, "setEtbAdd", [](lua_State* l) {
971 auto luaAdjustment = luaL_checknumber(l, 1);
972
974
975 return 0;
976 });
977 lua_register(lState, "setEwgAdd", [](lua_State* l) {
978 auto luaAdjustment = luaL_checknumber(l, 1);
979
981
982 return 0;
983 });
984 lua_register(lState, "setEtbDisabled", [](lua_State* l) {
985 engine->engineState.lua.luaDisableEtb = lua_toboolean(l, 1);
986 return 0;
987 });
988#endif // EFI_ELECTRONIC_THROTTLE_BODY
989#if EFI_PROD_CODE
990 lua_register(lState, "setIgnDisabled", [](lua_State* l) {
991 engine->engineState.lua.luaIgnCut = lua_toboolean(l, 1);
992 return 0;
993 });
994 lua_register(lState, "setFuelDisabled", [](lua_State* l) {
995 engine->engineState.lua.luaFuelCut = lua_toboolean(l, 1);
996 return 0;
997 });
998 lua_register(lState, "setDfcoDisabled", [](lua_State* l) {
1000 return 0;
1001 });
1002#endif // EFI_PROD_CODE
1003
1004 lua_register(lState, "setClutchUpState", [](lua_State* l) {
1005 engine->engineState.lua.clutchUpState = lua_toboolean(l, 1);
1006 return 0;
1007 });
1008 lua_register(lState, "setClutchDownState", [](lua_State* l) {
1009 engine->engineState.lua.clutchDownState = lua_toboolean(l, 1);
1010 return 0;
1011 });
1012 lua_register(lState, "setBrakePedalState", [](lua_State* l) {
1013 engine->engineState.lua.brakePedalState = lua_toboolean(l, 1);
1014 return 0;
1015 });
1016
1017 lua_register(lState, "setAcRequestState", [](lua_State* l) {
1018 engine->engineState.lua.acRequestState = lua_toboolean(l, 1);
1019 return 0;
1020 });
1021
1022#if !defined(STM32F4)
1023 lua_register(lState, "getTorque", [](lua_State* l) {
1026
1027 auto result = interpolate3d(
1029 config->torqueLoadBins, tps,
1030 config->torqueRpmBins, rpm
1031 );
1032 lua_pushnumber(l, result);
1033 return 1;
1034 });
1035#endif
1036
1037 lua_register(lState, "setTorqueReductionState", [](lua_State* l) {
1038 engine->engineState.lua.torqueReductionState = lua_toboolean(l, 1);
1039 return 0;
1040 });
1041
1042 lua_register(lState, "getCalibration", [](lua_State* l) {
1043 auto propertyName = luaL_checklstring(l, 1, nullptr);
1044 auto result = getConfigValueByName(propertyName);
1045 lua_pushnumber(l, result);
1046 return 1;
1047 });
1048
1049#if EFI_TUNER_STUDIO && (EFI_PROD_CODE || EFI_SIMULATOR)
1050 lua_register(lState, "getOutput", [](lua_State* l) {
1051 auto propertyName = luaL_checklstring(l, 1, nullptr);
1052 // fresh values need to be requested explicitly, there is no periodic invocation of that method
1054 auto result = getOutputValueByName(propertyName);
1055 lua_pushnumber(l, result);
1056 return 1;
1057 });
1058#endif // EFI_PROD_CODE || EFI_SIMULATOR
1059
1060#if EFI_SHAFT_POSITION_INPUT
1061 lua_register(lState, "getEngineState", [](lua_State* l) {
1063 int luaStateCode;
1064 if (state == STOPPED) {
1065 luaStateCode = 0;
1066 } else if (state == RUNNING) {
1067 luaStateCode = 2;
1068 } else {
1069 // spinning-up or cranking
1070 luaStateCode = 1;
1071 }
1072 lua_pushinteger(l, luaStateCode);
1073 return 1;
1074 });
1075#endif //EFI_SHAFT_POSITION_INPUT
1076
1077 lua_register(lState, "setCalibration", [](lua_State* l) {
1078 auto propertyName = luaL_checklstring(l, 1, nullptr);
1079 auto value = luaL_checknumber(l, 2);
1080 auto incrementVersion = lua_toboolean(l, 3);
1081 bool isGoodName = setConfigValueByName(propertyName, value);
1082 if (isGoodName) {
1083 efiPrintf("LUA: applying [%s][%f]", propertyName, value);
1084 } else {
1085 efiPrintf("LUA: invalid calibration key [%s]", propertyName);
1086 }
1087 if (incrementVersion) {
1089 }
1090 return 0;
1091 });
1092 lua_register(lState, CMD_BURNCONFIG, [](lua_State*) {
1093 requestBurn();
1094 return 0;
1095 });
1096
1097 lua_register(lState, "getGlobalConfigurationVersion", [](lua_State* l) {
1098 lua_pushinteger(l, engine->getGlobalConfigurationVersion());
1099 return 1;
1100 });
1101
1102 lua_register(lState, "setAcDisabled", [](lua_State* l) {
1103 auto value = lua_toboolean(l, 1);
1104 engine->module<AcController>().unmock().isDisabledByLua = value;
1105 return 0;
1106 });
1107 lua_register(lState, "getTimeSinceAcToggleMs", [](lua_State* l) {
1108 float result = engine->module<AcController>().unmock().timeSinceStateChange.getElapsedSeconds() * 1000;
1109 lua_pushnumber(l, result);
1110 return 1;
1111 });
1112
1113#if !EFI_UNIT_TEST
1114 lua_register(lState, "startPwm", lua_startPwm);
1115 lua_register(lState, "setPwmDuty", lua_setPwmDuty);
1116 lua_register(lState, "setPwmFreq", lua_setPwmFreq);
1117 lua_register(lState, "getFan", [](lua_State* l) {
1118 lua_pushboolean(l, enginePins.fanRelay.getLogicValue());
1119 return 1;
1120 });
1121 lua_register(lState, "getFan2", [](lua_State* l) {
1122 lua_pushboolean(l, enginePins.fanRelay2.getLogicValue());
1123 return 1;
1124 });
1125 lua_register(lState, "getAcRelay", [](lua_State* l) {
1126 lua_pushboolean(l, enginePins.acRelay.getLogicValue());
1127 return 1;
1128 });
1129 lua_register(lState, "getDigital", lua_getDigital);
1130 lua_register(lState, "getAuxDigital", lua_getAuxDigital);
1131 lua_register(lState, "setDebug", lua_setDebug);
1132#if EFI_ENGINE_CONTROL
1133 lua_register(lState, "getAirmass", lua_getAirmass);
1134 lua_register(lState, "setAirmass", lua_setAirmass);
1135#endif // EFI_ENGINE_CONTROL
1136
1137
1138#ifndef WITH_LUA_STOP_ENGINE
1139#define WITH_LUA_STOP_ENGINE TRUE
1140#endif
1141
1142#if WITH_LUA_STOP_ENGINE
1143 lua_register(lState, "isFirmwareError", [](lua_State* l) {
1144 lua_pushboolean(l, hasFirmwareError());
1145 return 1;
1146 });
1147#if EFI_SHAFT_POSITION_INPUT
1148 lua_register(lState, "stopEngine", [](lua_State*) {
1150 return 0;
1151 });
1152 lua_register(lState, "isEngineStopRequested", [](lua_State* l) {
1154 lua_pushboolean(l, result);
1155 return 1;
1156 });
1157 lua_register(lState, "getTimeSinceTriggerEventMs", [](lua_State* l) {
1158 int result = engine->triggerCentral.m_lastEventTimer.getElapsedUs() / 1000;
1159 lua_pushinteger(l, result);
1160 return 1;
1161 });
1162#endif // EFI_SHAFT_POSITION_INPUT
1163#endif // WITH_LUA_STOP_ENGINE
1164
1165#if EFI_CAN_SUPPORT
1166 lua_register(lState, "canRxAdd", lua_canRxAdd);
1167 lua_register(lState, "canRxAddMask", lua_canRxAddMask);
1168#endif // EFI_CAN_SUPPORT
1169#endif // not EFI_UNIT_TEST
1170
1171#if EFI_CAN_SUPPORT || EFI_UNIT_TEST
1172 lua_register(lState, "txCan", lua_txCan);
1173#endif
1174
1175#if EFI_PROD_CODE
1176 /* todo: hasCriticalReportFile method #7291
1177 lua_register(lState, "hasCriticalReportFile", [](lua_State*) {
1178 // todo: actual method to scan SD card for error report files
1179 lua_pushinteger(l, hasCriticalReportFile());
1180 return 1;
1181 }
1182*/
1183#endif // EFI_PROD_CODE
1184
1185#if EFI_PROD_CODE && HW_HELLEN
1186 lua_register(lState, "hellenEnablePower", [](lua_State*) {
1187 hellenEnableEn("Lua");
1188 return 0;
1189 });
1190 lua_register(lState, "hellenDisablePower", [](lua_State*) {
1191 hellenDisableEn("Lua");
1192 return 0;
1193 });
1194#endif // HW_HELLEN
1195
1196#if EFI_DAC
1197 lua_register(lState, "setDacVoltage", [](lua_State* l) {
1198 auto channel = luaL_checkinteger(l, 1);
1199 auto voltage = luaL_checknumber(l, 2);
1200 setDacVoltage(channel, voltage);
1201 return 0;
1202 });
1203#endif // EFI_DAC
1204
1205 LuaClass<SignalDebounce> luaDebounce(lState, "SignalDebounce");
1206 luaDebounce
1207 .ctor<float>()
1208 .fun("set", &SignalDebounce::set)
1209 .fun("get", &SignalDebounce::get);
1210
1211#if EFI_UNIT_TEST
1212 lua_register(lState, "advanceTimeUs", [](lua_State *l){
1213 auto us = luaL_checknumber(l, 1);
1214 advanceTimeUs(us);
1215 return 0;
1216 });
1217#endif // EFI_UNIT_TEST
1218}
uint16_t channel
Definition adc_inputs.h:104
int luaCommandCounters[LUA_BUTTON_COUNT]
void addLuaCanRxFilter(int32_t eid, uint32_t mask, int bus, int callback)
Timer timeSinceStateChange
Definition ac_control.h:16
void setDlc(uint8_t dlc)
TriggerCentral triggerCentral
Definition engine.h:318
int getGlobalConfigurationVersion() const
Definition engine.cpp:289
IgnitionState ignitionState
Definition engine.h:239
bool allowCanTx
Definition engine.h:114
SingleTimerExecutor scheduler
Definition engine.h:271
LaunchControlBase launchController
Definition engine.h:220
EngineState engineState
Definition engine.h:344
RpmCalculator rpmCalculator
Definition engine.h:306
AntilagSystemBase antilagController
Definition engine.h:228
IEtbController * etbControllers[ETB_COUNT]
Definition engine.h:126
TunerStudioOutputChannels outputChannels
Definition engine.h:109
constexpr auto & module()
Definition engine.h:200
RegisteredOutputPin fanRelay
Definition efi_gpio.h:86
OutputPin luaOutputPins[LUA_PWM_COUNT]
Definition efi_gpio.h:100
RegisteredOutputPin fanRelay2
Definition efi_gpio.h:87
RegisteredOutputPin acRelay
Definition efi_gpio.h:90
void updateSparkSkip()
Definition engine2.cpp:137
ShutdownController shutdownController
void setAirmass(AirmassResult airmass)
Definition lua_airmass.h:11
void deInit()
Definition efi_gpio.cpp:802
bool getLogicValue() const
Definition efi_gpio.cpp:667
spinning_state_e getState() const
bool Register()
Definition sensor.cpp:131
virtual bool hasSensor() const
Definition sensor.h:141
virtual SensorResult get() const =0
virtual bool isRedundant() const
Definition sensor.h:155
virtual float getRaw() const
Definition sensor.h:148
static float getOrZero(SensorType type)
Definition sensor.h:83
const char * getSensorName() const
Definition sensor.h:130
SensorType type() const
Definition sensor.h:162
void unregister()
Definition sensor.cpp:135
bool isEngineStop(efitick_t nowNt) const
void set(bool newState)
bool get() const
void setSimplePwmDutyCycle(float dutyCycle) override
Base class for sensors that compute a value on one thread, and want to make it available to consumers...
void showInfo(const char *sensorName) const override
void setValidValue(float value, efitick_t timestamp)
virtual void setTimeout(int timeoutMs)
SensorResult get() const final override
float getConsumedGramsRemainder() const
float getConsumptionGramPerSecond() const
uint32_t getConsumedGrams() const
virtual float getValue(float xColumn, float yRow) const =0
void setDacVoltage(int channel, float voltage)
Definition dac.cpp:59
EnginePins enginePins
Definition efi_gpio.cpp:24
ioportid_t getHwPort(const char *msg, brain_pin_e brainPin)
brain_pin_e parseBrainPin(const char *str)
ioportmask_t getHwPin(const char *msg, brain_pin_e brainPin)
const char * boolToString(bool value)
Definition efilib.cpp:19
efitick_t getTimeNowNt()
Definition efitime.cpp:19
void advanceTimeUs(int us)
void setEtbLuaAdjustment(percent_t pos)
void setEwgLuaAdjustment(percent_t pos)
void doInitElectronicThrottle(bool isStartupInit)
LimpManager * getLimpManager()
Definition engine.cpp:596
static EngineAccessor engine
Definition engine.h:413
void incrementGlobalConfigurationVersion(const char *msg)
static constexpr persistent_config_s * config
static constexpr engine_configuration_s * engineConfiguration
AirmassModelBase * getAirmassModel(engine_load_mode_e mode)
void hellenEnableEn(const char *msg)
void hellenDisableEn(const char *msg)
StoredValueSensor luaGauges[]
Definition init_aux.cpp:21
bool efiReadPin(brain_pin_e pin)
Definition io_pins.cpp:89
UNUSED(samplingTimeSeconds)
size_t getLuaCanRxDropped()
static int lua_setPwmFreq(lua_State *l)
void startPwm(int index, float freq, float duty)
static auto lua_getAirmassResolveMode(lua_State *l)
static int lua_readpin(lua_State *l)
Definition lua_hooks.cpp:60
PUBLIC_API_WEAK void boardConfigureLuaHooks(lua_State *lState)
int lua_canRxAddMask(lua_State *l)
static int lua_txCan(lua_State *l)
int getLuaFunc(lua_State *l)
void setPwmDuty(int index, float duty)
static tinymt32_t tinymt
uint32_t getLuaArray(lua_State *l, int paramIndex, uint8_t *data, uint32_t size)
static int lua_setAirmass(lua_State *l)
static SimplePwm pwms[LUA_PWM_COUNT]
static int lua_getDigital(lua_State *l)
bool getAuxDigital(int index)
static int lua_getAuxDigital(lua_State *l)
static SensorType findSensorByName(lua_State *l, const char *name)
static LuaAirmass luaAirmass
static int lua_getAuxAnalog(lua_State *l)
Definition lua_hooks.cpp:91
static int lua_getSensorByIndex(lua_State *l)
void configureRusefiLuaHooks(lua_State *lState)
static int validateCanChannelAndConvertFromHumanIntoZeroIndex(lua_State *l)
static int lua_hasSensor(lua_State *l)
static int lua_getSensorByName(lua_State *l)
AirmassModelBase & getLuaAirmassModel()
static int lua_getAirmass(lua_State *l)
static int lua_setPwmDuty(lua_State *l)
static int lua_getSensorRaw(lua_State *l)
static int getSensor(lua_State *l, SensorType type)
Definition lua_hooks.cpp:77
static bool isFunction(lua_State *l, int idx)
void luaDeInitPins()
int lua_canRxAdd(lua_State *l)
static int lua_setDebug(lua_State *l)
static int lua_startPwm(lua_State *l)
static int lua_vin(lua_State *l)
Definition lua_hooks.cpp:49
static P luaL_checkPwmIndex(lua_State *l, int pos)
void configureRusefiLuaUtilHooks(lua_State *lState)
float getOutputValueByName(const char *name)
@ LuaOneCanTxFunction
const char * hwPortname(brain_pin_e brainPin)
bool isBrainPinValid(brain_pin_e brainPin)
void startSimplePwmExt(SimplePwm *state, const char *msg, Scheduler *executor, brain_pin_e brainPin, OutputPin *output, float frequency, float dutyCycle, pwm_gen_callback *callback)
spinning_state_e
@ RUNNING
@ STOPPED
SentInput
float getCurveValue(int index, float key)
ValueProvider3D * getscriptTable(int index)
SensorType findSensorTypeByName(const char *name)
Definition sensor.cpp:259
SensorType
Definition sensor_type.h:18
luaAdjustment("ETB: luaAdjustment", SensorCategory.SENSOR_INPUTS, FieldType.INT, 1828, 1.0, 0.0, 3.0, "%")
state("state", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1871, 1.0, -1.0, -1.0, "")
float getSentValue(SentInput input)
Definition sent.cpp:135
int getSentValues(SentInput input, uint16_t *sig0, uint16_t *sig1)
Definition sent.cpp:153
This file is about configuring engine via the human-readable protocol.
void doScheduleStopEngine(StopRequestedReason reason)
void doStartCranking()
brain_pin_e pin
Definition stm32_adc.cpp:15
void configureLowpass(float samplingFrequency, float cutoffFrequency)
Definition lua_biquad.h:17
float filter(float input)
Definition lua_biquad.h:9
void setOffset(float offset)
Definition lua_pid.h:87
void setDerivativeFilterLoss(float derivativeFilterLoss)
Definition lua_pid.h:92
void setAntiwindupFreq(float antiwindupFreq)
Definition lua_pid.h:97
float get(float target, float input)
Definition lua_pid.h:76
float get(float target, float input)
Definition lua_pid.h:27
void reset()
Definition lua_pid.h:43
void setOffset(float offset)
Definition lua_pid.h:38
scaled_channel< int16_t, 2, 1 > luaTargetAdd
switch_input_pin_e luaDigitalInputPins[LUA_DIGITAL_INPUT_COUNT]
scaled_channel< uint8_t, 2, 1 > gppwmOutput[4]
scaled_channel< uint8_t, 1, 10 > torqueTable[TORQUE_CURVE_SIZE][TORQUE_CURVE_RPM_SIZE]
scaled_channel< uint8_t, 1, 20 > cltIdleRpm[CLT_CURVE_SIZE]
void setLinearCurve(TValue(&array)[TSize], float from, float to, float precision=0.01f)
static float duty
void tinymt32_init(tinymt32_t *random, uint32_t seed)
Definition tinymt32.c:62
Tiny Mersenne Twister only 127 bit internal state.
static float tinymt32_generate_float(tinymt32_t *random)
Definition tinymt32.h:191
composite packet size
void disableTriggerStimulator()
void setTriggerEmulatorRPM(int rpm)
void enableTriggerStimulator(bool incGlobalConfiguration)
void requestBurn()
void updateTunerStudioState()
int getSecondsSinceChannelsRequest()
uint16_t count
Definition tunerstudio.h:1
bool setConfigValueByName(const char *name, float value)
float getConfigValueByName(const char *name)