Skip to content

Commit

Permalink
AP_Scripting: Add transfer_str alternative to transfer()
Browse files Browse the repository at this point in the history
  • Loading branch information
IanBurwell committed Jul 8, 2024
1 parent 1f791ab commit 958dcbe
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 0 deletions.
8 changes: 8 additions & 0 deletions libraries/AP_Scripting/docs/docs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,14 @@ function AP_HAL__I2CDevice_ud:set_address(address) end
---@return table|nil
function AP_HAL__I2CDevice_ud:transfer(data_table, read_length) end

-- Performs an I2C transfer, sending data_str bytes (see string.pack) and
-- returning a string of any requested read bytes (see string.unpack)
---@param data_str string
---@param read_length integer
---@return string|nil
function AP_HAL__I2CDevice_ud:transfer_str(data_str, 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
Expand Down
107 changes: 107 additions & 0 deletions libraries/AP_Scripting/examples/RM3100_self_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
-- Runs the Built-In Self Test on the RM3100 LR circuits
-- Note COMPASS_DISBLMSK should have the 16th bit set to 1 (RM3100)
---@diagnostic disable: need-check-nil

-- Init i2c device
local rm3100 = i2c:get_device(0, 0x20)

-- Queues a Built-In Self Test
function queue_test()
gcs:send_text('1', "Running RM3100 self test")

-- Queue a self test by setting BIST register
local ret = rm3100:transfer_str(string.pack("BB", 0x33, 0x8F), 0)
if ret == nil then
gcs:send_text('1', "Rm3100 BIST transfer failed")
return queue_test, 1000
end

-- Send a POLL request to run a BIST
ret = rm3100:transfer_str(string.pack("BB", 0x00, 0x70), 0)
if ret == nil then
gcs:send_text('1', "Rm3100 POLL transfer failed")
return queue_test, 1000
end

-- As a measurement takes time, delay a bit by scheduling a different function
return read_test, 1000
end


-- Reads back values from a Built-In Self Test
function read_test()
-- Read the BIST results
local results_str = rm3100:transfer_str(string.pack("B", 0x33), 1)
if results_str ~= nil then
local results = string.unpack("B", results_str)

if results & (1 << 4) == 0 then
gcs:send_text('1', "RM3100 X is unhealthy")
else
gcs:send_text('1', "RM3100 X is OK")
end

if results & (1 << 5) == 0 then
gcs:send_text('1', "RM3100 Y is unhealthy")
else
gcs:send_text('1', "RM3100 Y is OK")
end

if results & (1 << 6) == 0 then
gcs:send_text('1', "RM3100 Z is unhealthy")
else
gcs:send_text('1', "RM3100 Z is OK")
end
else
gcs:send_text('1', "Rm3100 BIST read transfer failed")
return queue_test, 1000
end

-- Reset the BIST register
local ret = rm3100:transfer_str(string.pack("BB", 0x33, 0x0F), 0)
if ret == nil then
gcs:send_text('1', "Rm3100 BIST reset transfer failed")
return queue_test, 1000
end

-- Send a POLL request to take a data point
ret = rm3100:transfer_str(string.pack("BB", 0x00, 0x70), 0)
if ret == nil then
gcs:send_text('1', "Rm3100 POLL data transfer failed")
return queue_test, 1000
end

-- As a measurement takes time, delay a bit by scheduling a different function
return read_data, 1000
end

-- Reads data from the RM3100
function read_data()
-- Check that data is ready for a read
local status_str = rm3100:transfer_str(string.pack("B", 0x34), 1)
if status_str ~= nil then
local status = string.unpack("B", status_str)
if status & (1 << 7) == 0 then
gcs:send_text('1', "RM3100 data not ready for reading")
return queue_test, 1000
end
else
gcs:send_text('1', "Rm3100 BIST status reg transfer failed")
return queue_test, 1000
end

-- Read measured values
local measurements_str = rm3100:transfer_str(string.pack("B", 0x24), 9)
if measurements_str ~= nil then
local MX, MY, MZ = string.unpack(">i3>i3>i3", measurements_str)
gcs:send_text('6', string.format("RM3100 Mag: X=%8d Y=%8d Z=%8d", MX, MY, MZ))
else
gcs:send_text('1', "Rm3100 data read transfer failed")
return queue_test, 1000
end

-- Loop back to the first function to run another set of tests
return queue_test, 1000
end

return queue_test, 1000
1 change: 1 addition & 0 deletions libraries/AP_Scripting/generator/description/bindings.desc
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ 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 manual transfer_str AP_HAL__I2CDevice_transfer_str 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)
Expand Down
31 changes: 31 additions & 0 deletions libraries/AP_Scripting/lua_bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,37 @@ int AP_HAL__I2CDevice_transfer(lua_State *L) {
return success;
}

int AP_HAL__I2CDevice_transfer_str(lua_State *L) {
const int args = lua_gettop(L);
if (args != 3){
return luaL_argerror(L, args, "expected 2 arguments");
}
if (!lua_isstring(L, 2)) {
return luaL_argerror(L, 2, "expected a string as the first argument");
}

AP_HAL::I2CDevice * ud = *check_AP_HAL__I2CDevice(L, 1);

// Parse string of bytes to send
size_t send_len;
const uint8_t* send_data = (const uint8_t*)(lua_tolstring(L, 2, &send_len));

// 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<bool>(ud->transfer(send_data, send_len, rx_data, rx_len));
ud->get_semaphore()->give();

// Return a string
if (success) {
lua_pushlstring(L, (const char *)rx_data, rx_len);
}
return success;
}

#if AP_SCRIPTING_CAN_SENSOR_ENABLED
int lua_get_CAN_device(lua_State *L) {

Expand Down
1 change: 1 addition & 0 deletions libraries/AP_Scripting/lua_bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ 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__I2CDevice_transfer_str(lua_State *L);
int lua_get_CAN_device(lua_State *L);
int lua_get_CAN_device2(lua_State *L);
int lua_serial_find_serial(lua_State *L);
Expand Down

0 comments on commit 958dcbe

Please sign in to comment.