From f50bd7fccce5dd97076d6b721f9be7c93f947bcd Mon Sep 17 00:00:00 2001 From: Ian Burwell Date: Fri, 7 Jun 2024 18:24:32 -0400 Subject: [PATCH] AP_Scripting: Add I2C transfer binding --- libraries/AP_Scripting/docs/docs.lua | 7 ++++ .../generator/description/bindings.desc | 1 + libraries/AP_Scripting/lua_bindings.cpp | 42 +++++++++++++++++++ libraries/AP_Scripting/lua_bindings.h | 1 + 4 files changed, 51 insertions(+) diff --git a/libraries/AP_Scripting/docs/docs.lua b/libraries/AP_Scripting/docs/docs.lua index f88cdeecae4731..4e3758dad4ff87 100644 --- a/libraries/AP_Scripting/docs/docs.lua +++ b/libraries/AP_Scripting/docs/docs.lua @@ -1173,6 +1173,13 @@ local AP_HAL__I2CDevice_ud = {} ---@param address integer function AP_HAL__I2CDevice_ud:set_address(address) end +-- Performs an I2C transfer, sending data_table bytes and +-- returning a table of any requested read bytes +---@param data_table table +---@param read_length integer +---@return table|nil +function AP_HAL__I2CDevice_ud:transfer(data_table, read_length) end + -- If no read length is provided a single register will be read and returned. -- If read length is provided a table of register values are returned. ---@param register_num integer diff --git a/libraries/AP_Scripting/generator/description/bindings.desc b/libraries/AP_Scripting/generator/description/bindings.desc index f9ca18bb44a9ff..d0237e88b7b22b 100644 --- a/libraries/AP_Scripting/generator/description/bindings.desc +++ b/libraries/AP_Scripting/generator/description/bindings.desc @@ -578,6 +578,7 @@ ap_object AP_HAL::I2CDevice semaphore-pointer ap_object AP_HAL::I2CDevice method set_retries void uint8_t 0 20 ap_object AP_HAL::I2CDevice method write_register boolean uint8_t'skip_check uint8_t'skip_check ap_object AP_HAL::I2CDevice manual read_registers AP_HAL__I2CDevice_read_registers 2 1 +ap_object AP_HAL::I2CDevice manual transfer AP_HAL__I2CDevice_transfer 2 1 ap_object AP_HAL::I2CDevice method set_address void uint8_t'skip_check include AP_HAL/utility/Socket.h depends (AP_NETWORKING_ENABLED==1) diff --git a/libraries/AP_Scripting/lua_bindings.cpp b/libraries/AP_Scripting/lua_bindings.cpp index 81f58703fe5910..1952190fd7986d 100644 --- a/libraries/AP_Scripting/lua_bindings.cpp +++ b/libraries/AP_Scripting/lua_bindings.cpp @@ -638,6 +638,48 @@ int AP_HAL__I2CDevice_read_registers(lua_State *L) { return success; } +int AP_HAL__I2CDevice_transfer(lua_State *L) { + const int args = lua_gettop(L); + if (args != 3){ + return luaL_argerror(L, args, "expected 2 arguments"); + } + if (!lua_istable(L, 2)) { + return luaL_argerror(L, 2, "expected a table as the first argument"); + } + + AP_HAL::I2CDevice * ud = *check_AP_HAL__I2CDevice(L, 1); + + // Parse table of bytes to send + uint32_t send_len = lua_rawlen(L, 2); + uint8_t send_data[send_len] = {}; + for (unsigned int i = 0; i < send_len; i++){ + lua_rawgeti(L, 2, i + 1); // Grab value from table + send_data[i] = get_uint8_t(L, -1); // Parse/check uint8_t + lua_pop(L, 1); + } + + // Parse and setup rx buffer + uint32_t rx_len = get_uint32(L, 3, 0, UINT32_MAX); + uint8_t rx_data[rx_len]; + + // Transfer + ud->get_semaphore()->take_blocking(); + const bool success = static_cast(ud->transfer(send_data, send_len, rx_data, rx_len)); + ud->get_semaphore()->give(); + + // Return a table + if (success) { + // push to table + lua_newtable(L); + for (uint8_t i=0; i < rx_len; i++) { + lua_pushinteger(L, i+1); + lua_pushinteger(L, rx_data[i]); + lua_settable(L, -3); + } + } + return success; +} + int AP_HAL__UARTDriver_readstring(lua_State *L) { binding_argcheck(L, 2); diff --git a/libraries/AP_Scripting/lua_bindings.h b/libraries/AP_Scripting/lua_bindings.h index add40faa0a7bd8..14850e6f57a8e7 100644 --- a/libraries/AP_Scripting/lua_bindings.h +++ b/libraries/AP_Scripting/lua_bindings.h @@ -8,6 +8,7 @@ int lua_mission_receive(lua_State *L); int AP_Logger_Write(lua_State *L); int lua_get_i2c_device(lua_State *L); int AP_HAL__I2CDevice_read_registers(lua_State *L); +int AP_HAL__I2CDevice_transfer(lua_State *L); int AP_HAL__UARTDriver_readstring(lua_State *L); int lua_get_CAN_device(lua_State *L); int lua_get_CAN_device2(lua_State *L);