diff --git a/firmware/controllers/lua/lua_hooks.cpp b/firmware/controllers/lua/lua_hooks.cpp index 8969448ef5..15aedb8e27 100644 --- a/firmware/controllers/lua/lua_hooks.cpp +++ b/firmware/controllers/lua/lua_hooks.cpp @@ -1,8 +1,16 @@ #include "lua.hpp" #include "lua_hooks.h" +#include "engine.h" #include "loggingcentral.h" #include "sensor.h" +#include "adc_inputs.h" +#include "efilib.h" + +// Some functions lean on existing FSIO implementation +#include "fsio_impl.h" + +EXTERN_ENGINE; static int lua_efi_print(lua_State* l) { auto msg = luaL_checkstring(l, 1); @@ -12,7 +20,7 @@ static int lua_efi_print(lua_State* l) { return 0; } -static int lua_get_sensor(lua_State* l) { +static int lua_getSensor(lua_State* l) { auto sensorIndex = luaL_checkinteger(l, 1); auto result = Sensor::get(static_cast(sensorIndex)); @@ -28,7 +36,82 @@ static int lua_get_sensor(lua_State* l) { return 1; } +static int lua_getSensorRaw(lua_State* l) { + auto sensorIndex = luaL_checkinteger(l, 1); + + lua_pushnumber(l, Sensor::getRaw(static_cast(sensorIndex))); + return 1; +} + +static int lua_hasSensor(lua_State* l) { + auto sensorIndex = luaL_checkinteger(l, 1); + + lua_pushboolean(l, Sensor::hasSensor(static_cast(sensorIndex))); + return 1; +} + +static int lua_table3d(lua_State* l) { + auto tableIdx = luaL_checkinteger(l, 1); + auto x = luaL_checknumber(l, 2); + auto y = luaL_checknumber(l, 3); + + // index table, compute table lookup + auto result = getFSIOTable(tableIdx)->getValue(x, y); + + lua_pushnumber(l, result); + return 1; +} + +#if !EFI_UNIT_TEST +static int lua_fan(lua_State* l) { + lua_pushboolean(l, enginePins.fanRelay.getLogicValue()); + return 1; +} + +static int lua_getAnalog(lua_State* l) { + auto idx = luaL_checkinteger(l, 1); + + // Sanitize parameter + idx = clampI(0, idx, FSIO_ANALOG_INPUT_COUNT - 1); + + // Do the analog read + float voltage = getVoltage("lua", engineConfiguration->fsioAdc[idx]); + + lua_pushnumber(l, voltage); + return 1; +} + +static int lua_getDigital(lua_State* l) { + auto idx = luaL_checkinteger(l, 1); + + bool state = false; + + switch (idx) { + case 0: state = engine->clutchDownState; break; + case 1: state = engine->clutchUpState; break; + case 2: state = engine->brakePedalState; break; + case 3: state = engine->acSwitchState; break; + default: + // Return nil to indicate invalid parameter + lua_pushnil(l); + return 1; + } + + lua_pushboolean(l, state); + return 1; +} +#endif // EFI_UNIT_TEST + void configureRusefiLuaHooks(lua_State* l) { lua_register(l, "print", lua_efi_print); - lua_register(l, "getSensor", lua_get_sensor); + lua_register(l, "getSensor", lua_getSensor); + lua_register(l, "getSensorRaw", lua_getSensorRaw); + lua_register(l, "hasSensor", lua_hasSensor); + lua_register(l, "table3d", lua_table3d); + +#if !EFI_UNIT_TEST + lua_register(l, "getFan", lua_fan); + lua_register(l, "getAnalog", lua_getAnalog); + lua_register(l, "getDigital", lua_getDigital); +#endif } diff --git a/firmware/util/efilib.cpp b/firmware/util/efilib.cpp index 59ce10b4ff..f998b7d949 100644 --- a/firmware/util/efilib.cpp +++ b/firmware/util/efilib.cpp @@ -59,6 +59,10 @@ float minF(float i1, float i2) { return i1 < i2 ? i1 : i2; } +int clampI(int min, int clamp, int max) { + return maxI(min, minI(clamp, max)); +} + float clampF(float min, float clamp, float max) { return maxF(min, minF(clamp, max)); } diff --git a/firmware/util/efilib.h b/firmware/util/efilib.h index 14403436ee..b3a283e13a 100644 --- a/firmware/util/efilib.h +++ b/firmware/util/efilib.h @@ -67,6 +67,8 @@ float maxF(float i1, float i2); float minF(float i1, float i2); char* itoa10(char *p, int num); bool isSameF(float v1, float v2); + +int clampI(int min, int clamp, int max); float clampF(float min, float clamp, float max); /** diff --git a/unit_tests/tests/lua/test_lua_hooks.cpp b/unit_tests/tests/lua/test_lua_hooks.cpp index c991884b61..a321ee9a90 100644 --- a/unit_tests/tests/lua/test_lua_hooks.cpp +++ b/unit_tests/tests/lua/test_lua_hooks.cpp @@ -1,5 +1,6 @@ #include "rusefi_lua.h" #include +#include "engine_test_helper.h" #include "sensor.h" static const char* getSensorTest = R"( @@ -19,3 +20,19 @@ TEST(LuaHooks, TestGetSensor) { Sensor::setMockValue(10, 33); EXPECT_EQ(testLuaReturnsNumberOrNil(getSensorTest).value_or(0), 33); } + +static const char* tableTest = R"( +function testFunc() + return table3d(1, 1000, 40) +end +)"; + +TEST(LuaHooks, Table3d) { + WITH_ENGINE_TEST_HELPER(TEST_ENGINE); + + setTable(config->fsioTable2, (uint8_t)33); + EXPECT_EQ(testLuaReturnsNumber(tableTest), 33); + + setTable(config->fsioTable2, (uint8_t)14); + EXPECT_EQ(testLuaReturnsNumber(tableTest), 14); +}