#ifndef NO_LUA #include "gm9internali2c.h" #include "fsperm.h" #include "system/i2c.h" typedef struct { uint8_t dev_id; uint8_t reg_addr_start; uint8_t reg_addr_end; } WhiteListPair; static const WhiteListPair WriteWhitelist[] = { // Device_id, Register_address, Register_address_end { I2C_DEV_MCU, 0x15, 0x17 }, { I2C_DEV_MCU, 0x1c, 0x1f }, { I2C_DEV_MCU, 0x28, 0x29 }, { I2C_DEV_MCU, 0x2a, 0x2d }, }; static bool IsWriteAllowed(uint8_t dev_id, uint8_t reg_addr) { for (unsigned i = 0; i < sizeof(WriteWhitelist)/sizeof(WriteWhitelist[0]); i++) { if (WriteWhitelist[i].dev_id == dev_id && reg_addr >= WriteWhitelist[i].reg_addr_start && reg_addr <= WriteWhitelist[i].reg_addr_end) return true; } return false; } static int i2c_read(lua_State *L) { int dev_id = luaL_checkinteger(L, 1); int reg_addr = luaL_checkinteger(L, 2); int length = luaL_checkinteger(L, 3); if (dev_id < 0 || dev_id > 17) { return luaL_error(L, "Invalid device ID: %d (must be 0-17)", dev_id); } if (length <= 0 || length > 64) { return luaL_error(L, "Invalid length: %d (must be 1-64)", length); } if (reg_addr < 0 || reg_addr > 255) { return luaL_error(L, "Invalid register address: %d (must be 0-255)", reg_addr); } // Create a buffer for the read data u8 *buffer = malloc(length); if (!buffer) { return luaL_error(L, "Memory allocation failed"); } bool success = I2C_readRegBuf((I2cDevice)dev_id, (u8)reg_addr, buffer, (u32)length); if (success) { // Create a Lua table to hold the byte values lua_createtable(L, length, 0); // Fill the table with byte values as integers for (int i = 0; i < length; i++) { lua_pushinteger(L, buffer[i]); // Push byte value as integer lua_rawseti(L, -2, i + 1); // Set table[i+1] = byte } free(buffer); return 1; } else { free(buffer); return luaL_error(L, "I2C read failed"); } } static int i2c_write(lua_State *L) { SetWritePermissionsLuaError(L, PERM_MEMORY); int dev_id = luaL_checkinteger(L, 1); int reg_addr = luaL_checkinteger(L, 2); if (!lua_istable(L, 3)) { return luaL_error(L, "Third parameter must be a table of byte values"); } int length = lua_rawlen(L, 3); if (dev_id < 0 || dev_id > 17) { return luaL_error(L, "Invalid device ID: %d (must be 0-17)", dev_id); } if (length <= 0 || length > 64) { return luaL_error(L, "Invalid data length: %d (must be 1-64)", length); } if (reg_addr < 0 || reg_addr > 255) { return luaL_error(L, "Invalid register address: %d (must be 0-255)", reg_addr); } if (!IsWriteAllowed(dev_id, reg_addr)) { return luaL_error(L, "Write to device %d, register %d is not allowed", dev_id, reg_addr); } // Create a buffer for the write data u8 *buffer = malloc(length); if (!buffer) { return luaL_error(L, "Memory allocation failed"); } // Extract byte values from Lua table for (int i = 0; i < length; i++) { lua_rawgeti(L, 3, i + 1); // Get table[i+1] if (!lua_isinteger(L, -1)) { free(buffer); return luaL_error(L, "Table element %d is not an integer", i + 1); } int value = lua_tointeger(L, -1); if (value < 0 || value > 255) { free(buffer); return luaL_error(L, "Table element %d is out of range: %d (must be 0-255)", i + 1, value); } buffer[i] = (u8)value; lua_pop(L, 1); // Remove the value from stack } bool success = I2C_writeRegBuf((I2cDevice)dev_id, (u8)reg_addr, buffer, (u32)length); free(buffer); if (success) { return 0; } else { return luaL_error(L, "I2C write failed"); } } static const luaL_Reg i2c[] = { {"read", i2c_read}, {"write", i2c_write}, {NULL, NULL} }; int gm9lua_open_internali2c(lua_State* L) { luaL_newlib(L, i2c); return 1; } #endif