1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-24 00:35:18 +03:00

[Crossfire] Lua script continued

This commit is contained in:
Bertrand Songis 2016-11-02 13:31:50 +01:00
parent a50d69c3b2
commit 45a8cd94e7

View file

@ -2,15 +2,47 @@ local COLUMN_2 = 140
local pages = { } local pages = { }
local pageIndex = 1 local pageIndex = 1
local fieldIndex = 1 local lineIndex = 0
local pageOffset = 0 local pageOffset = 0
local edit = false local edit = false
local charIndex = 1 local charIndex = 1
local f = io.open("traces.txt", "w")
local function getField(line)
local page = pages[pageIndex]
local counter = 1
local index = 1
while 1 do
local field = page.fields[index]
if field == nil then
return nil
elseif field.hidden == 1 then
-- continue
elseif counter < line then
counter = counter + 1
else
return field
end
index = index + 1
end
end
local function initLineIndex()
local index = 0
repeat
index = index + 1
local field = getField(index)
if field ~= nil and field.type ~= 11 and field.type ~= 12 and field.name ~= nil then
lineIndex = index
return
end
until index >= #pages[pageIndex].fields
lineIndex = 0
end
-- Change display attribute to current field -- Change display attribute to current field
local function incrField(step) local function incrField(step)
local fields = pages[pageIndex].fields local field = getField(lineIndex)
local field = fields[fieldIndex]
if field.type == 10 then if field.type == 10 then
local byte = string.byte(field.value, charIndex) + step local byte = string.byte(field.value, charIndex) + step
if byte < 32 then if byte < 32 then
@ -21,7 +53,9 @@ local function incrField(step)
field.value = string.sub(field.value, 1, charIndex-1) .. string.char(byte) .. string.sub(field.value, charIndex+1) field.value = string.sub(field.value, 1, charIndex-1) .. string.char(byte) .. string.sub(field.value, charIndex+1)
else else
local min, max = 0, 0 local min, max = 0, 0
io.write(f, "field type:" .. field.type .. "\n")
if field.type <= 5 then if field.type <= 5 then
io.write(f, "field min:" .. field.min .. ", max:" .. field.max .. ", step:" .. field.step .. "\n")
min = field.min min = field.min
max = field.max max = field.max
step = field.step * step step = field.step * step
@ -31,6 +65,7 @@ local function incrField(step)
end end
if (step < 0 and field.value > min) or (step > 0 and field.value < max) then if (step < 0 and field.value > min) or (step > 0 and field.value < max) then
field.value = field.value + step field.value = field.value + step
io.write(f, "field new value:" .. field.value .. "\n")
end end
end end
end end
@ -38,41 +73,43 @@ end
-- Select the next or previous page -- Select the next or previous page
local function selectPage(step) local function selectPage(step)
pageIndex = 1 + ((pageIndex + step - 1 + #pages) % #pages) pageIndex = 1 + ((pageIndex + step - 1 + #pages) % #pages)
initLineIndex()
end end
-- Select the next or previous editable field -- Select the next or previous editable field
local function selectField(step) local function selectField(step)
local fields = pages[pageIndex].fields local newLineIndex = lineIndex
local newFieldIndex = fieldIndex local field
local field = fields[newFieldIndex]
repeat repeat
newFieldIndex = 1 + ((newFieldIndex + step - 1 + #fields) % #fields) newLineIndex = newLineIndex + step
field = fields[newFieldIndex] if newLineIndex == 0 then
until newFieldIndex == fieldIndex or (field.type ~= 11 and field.type ~= 12 and field.name ~= nil) newLineIndex = #pages[pageIndex].fields
fieldIndex = newFieldIndex elseif newLineIndex == 1 + #pages[pageIndex].fields then
if fieldIndex > 7 + pageOffset then newLineIndex = 1
pageOffset = fieldIndex - 7 end
elseif fieldIndex <= pageOffset then field = getField(newLineIndex)
pageOffset = fieldIndex - 1 until newLineIndex == lineIndex or (field ~= nil and field.type ~= 11 and field.type ~= 12 and field.name ~= nil)
lineIndex = newLineIndex
if lineIndex > 7 + pageOffset then
pageOffset = lineIndex - 7
elseif lineIndex <= pageOffset then
pageOffset = lineIndex - 1
end end
end end
local function drawDevicePage(page) local function drawDevicePage(page)
for index = 1, 7, 1 do for y = 1, 7, 1 do
local field = page.fields[pageOffset+index] local field = getField(pageOffset+y)
if field == nil then if field == nil then
break return
end elseif field.name == nil then
lcd.drawText(0, 1+8*y, "...")
if field.name == nil then
lcd.drawText(0, 1+8*index, "...")
else else
local attr = fieldIndex == (pageOffset+index) and ((edit == true and BLINK or 0) + INVERS) or 0 local attr = lineIndex == (pageOffset+y) and ((edit == true and BLINK or 0) + INVERS) or 0
lcd.drawText(0, 1+8*index, field.name) lcd.drawText(0, 1+8*y, field.name)
if field.functions ~= nil then if field.functions ~= nil then
field.functions.display(field, 1+8*index, attr) field.functions.display(field, 1+8*y, attr)
end end
-- if field[4] == nil then -- if field[4] == nil then
-- lcd.drawText(COLUMN_2, 1+8*index, "---", attr) -- lcd.drawText(COLUMN_2, 1+8*index, "---", attr)
-- else -- else
@ -130,8 +167,8 @@ local function parseDeviceInfoMessage(data)
end end
local function split(inputstr) local function split(inputstr)
local t={} local t = {}
local i=1 local i = 1
for str in string.gmatch(inputstr, "([^;]+)") do for str in string.gmatch(inputstr, "([^;]+)") do
t[i] = str t[i] = str
i = i + 1 i = i + 1
@ -161,8 +198,10 @@ local function fieldUnsignedSelectionLoad(field, data, offset, size)
field.value = fieldGetValue(data, offset, size) field.value = fieldGetValue(data, offset, size)
field.min = fieldGetValue(data, offset+size, size) field.min = fieldGetValue(data, offset+size, size)
field.max = fieldGetValue(data, offset+2*size, size) field.max = fieldGetValue(data, offset+2*size, size)
field.unit, offset = fieldGetString(data, offset+3*size) field.default = fieldGetValue(data, offset+3*size, size)
field.unit, offset = fieldGetString(data, offset+4*size)
field.step = 1 field.step = 1
io.write(f, " unsigned value:" .. field.value .. ", min:" .. field.min .. ", max:" .. field.max, ", step:" .. field.step .. ", unit:" .. field.unit .. "\n")
end end
local function fieldUnsignedToSigned(field, size) local function fieldUnsignedToSigned(field, size)
@ -170,6 +209,8 @@ local function fieldUnsignedToSigned(field, size)
field.value = field.value - bit32.band(field.value, bandval) * 2 field.value = field.value - bit32.band(field.value, bandval) * 2
field.min = field.min - bit32.band(field.min, bandval) * 2 field.min = field.min - bit32.band(field.min, bandval) * 2
field.max = field.max - bit32.band(field.max, bandval) * 2 field.max = field.max - bit32.band(field.max, bandval) * 2
field.default = field.default - bit32.band(field.default, bandval) * 2
io.write(f, " => to signed value:" .. field.value .. ", min:" .. field.min .. ", max:" .. field.max .. ", default:" .. field.default .. "\n")
end end
local function fieldSignedSelectionLoad(field, data, offset, size) local function fieldSignedSelectionLoad(field, data, offset, size)
@ -177,25 +218,26 @@ local function fieldSignedSelectionLoad(field, data, offset, size)
fieldUnsignedToSigned(field, size) fieldUnsignedToSigned(field, size)
end end
local function fieldIntSave(fieldIndex, value, size) local function fieldIntSave(index, value, size)
local frame = { pages[pageIndex].id, 0xEA, fieldIndex } local frame = { pages[pageIndex].id, 0xEA, index }
for i=size-1, 0, -1 do for i=size-1, 0, -1 do
frame[#frame + 1] = (bit32.rshift(value, 8*i) % 256) frame[#frame + 1] = (bit32.rshift(value, 8*i) % 256)
end end
crossfireTelemetryPush(0x2D, frame) crossfireTelemetryPush(0x2D, frame)
end end
local function fieldUnsignedSelectionSave(fieldIndex, size) local function fieldUnsignedSelectionSave(field, size)
local value = pages[pageIndex].fields[fieldIndex].value local value = field.value
fieldIntSave(fieldIndex, value, size) fieldIntSave(field.index, value, size)
end end
local function fieldSignedSelectionSave(fieldIndex, size) local function fieldSignedSelectionSave(field, size)
local value = pages[pageIndex].fields[fieldIndex].value local value = field.value
if value < 0 then if value < 0 then
value = bit32.lshift(0x100, (size-1)*8) - value value = bit32.lshift(0x100, (size-1)*8) + value
end end
fieldIntSave(fieldIndex, value, size) io.write(f, "save value:" .. value .. "\n")
fieldIntSave(field.index, value, size)
end end
local function fieldIntDisplay(field, y, attr) local function fieldIntDisplay(field, y, attr)
@ -208,8 +250,8 @@ local function fieldUint8Load(field, data, offset)
fieldUnsignedSelectionLoad(field, data, offset, 1) fieldUnsignedSelectionLoad(field, data, offset, 1)
end end
local function fieldUint8Save(fieldIndex) local function fieldUint8Save(field)
fieldUnsignedSelectionSave(fieldIndex, 1) fieldUnsignedSelectionSave(field, 1)
end end
-- INT8 -- INT8
@ -217,8 +259,8 @@ local function fieldInt8Load(field, data, offset)
fieldSignedSelectionLoad(field, data, offset, 1) fieldSignedSelectionLoad(field, data, offset, 1)
end end
local function fieldInt8Save(fieldIndex) local function fieldInt8Save(field)
fieldSignedSelectionSave(fieldIndex, 1) fieldSignedSelectionSave(field, 1)
end end
-- UINT16 -- UINT16
@ -226,9 +268,9 @@ local function fieldUint16Load(field, data, offset)
fieldUnsignedSelectionLoad(field, data, offset, 2) fieldUnsignedSelectionLoad(field, data, offset, 2)
end end
local function fieldUint16Save(fieldIndex) local function fieldUint16Save(field)
fieldUnsignedSelectionSave(fieldIndex, 2) fieldUnsignedSelectionSave(field, 2)
end end
-- INT16 -- INT16
@ -236,8 +278,8 @@ local function fieldInt16Load(field, data, offset)
fieldSignedSelectionLoad(field, data, offset, 2) fieldSignedSelectionLoad(field, data, offset, 2)
end end
local function fieldInt16Save(fieldIndex) local function fieldInt16Save(field)
fieldSignedSelectionSave(fieldIndex, 2) fieldSignedSelectionSave(field, 2)
end end
-- UINT32 -- UINT32
@ -245,8 +287,8 @@ local function fieldUint32Load(field, data, offset)
fieldUnsignedSelectionLoad(field, data, offset, 4) fieldUnsignedSelectionLoad(field, data, offset, 4)
end end
local function fieldUint32Save(fieldIndex) local function fieldUint32Save(field)
fieldUnsignedSelectionSave(fieldIndex, 4) fieldUnsignedSelectionSave(field, 4)
end end
-- INT32 -- INT32
@ -254,8 +296,8 @@ local function fieldInt32Load(field, data, offset)
fieldSignedSelectionLoad(field, data, offset, 4) fieldSignedSelectionLoad(field, data, offset, 4)
end end
local function fieldInt32Save(fieldIndex) local function fieldInt32Save(field)
fieldSignedSelectionSave(fieldIndex, 4) fieldSignedSelectionSave(field, 4)
end end
-- FLOAT -- FLOAT
@ -263,13 +305,14 @@ local function fieldFloatSelectionLoad(field, data, offset)
field.value = fieldGetValue(data, offset, 4) field.value = fieldGetValue(data, offset, 4)
field.min = fieldGetValue(data, offset+4, 4) field.min = fieldGetValue(data, offset+4, 4)
field.max = fieldGetValue(data, offset+8, 4) field.max = fieldGetValue(data, offset+8, 4)
field.default = fieldGetValue(data, offset+12, 4)
fieldUnsignedToSigned(field, 4) fieldUnsignedToSigned(field, 4)
field.prec = data[offset+12] field.prec = data[offset+16]
if field.prec > 2 then if field.prec > 2 then
field.prec = 2 field.prec = 2
end end
field.step = fieldGetValue(data, offset+13, 4) field.step = fieldGetValue(data, offset+17, 4)
field.unit, offset = fieldGetString(data, offset+14) field.unit, offset = fieldGetString(data, offset+21)
end end
local function fieldFloatSelectionDisplay(field, y, attr) local function fieldFloatSelectionDisplay(field, y, attr)
@ -291,14 +334,20 @@ local function fieldTextSelectionLoad(field, data, offset)
values, offset = fieldGetString(data, offset) values, offset = fieldGetString(data, offset)
field.values = split(values) field.values = split(values)
field.value = data[offset] field.value = data[offset]
field.min = data[offset+1]
field.max = data[offset+2]
field.default = data[offset+3]
field.unit, offset = fieldGetString(data, offset+4)
io.write(f, " value:" .. field.value .. "(" .. field.values[field.value+1] .. ")\n")
end end
local function fieldTextSelectionSave(fieldIndex) local function fieldTextSelectionSave(field)
crossfireTelemetryPush(0x2D, { pages[pageIndex].id, 0xEA, fieldIndex, pages[pageIndex].fields[fieldIndex].value }) crossfireTelemetryPush(0x2D, { pages[pageIndex].id, 0xEA, field.index, field.value })
end end
local function fieldTextSelectionDisplay(field, y, attr) local function fieldTextSelectionDisplay(field, y, attr)
lcd.drawText(COLUMN_2, y, field.values[field.value+1], attr) lcd.drawText(COLUMN_2, y, field.values[field.value+1], attr)
lcd.drawText(lcd.getLastPos(), y, field.unit, attr)
end end
-- STRING -- STRING
@ -309,8 +358,8 @@ local function fieldStringLoad(field, data, offset)
end end
end end
local function fieldStringSave(fieldIndex) local function fieldStringSave(field)
local frame = { pages[pageIndex].id, 0xEA, fieldIndex } local frame = { pages[pageIndex].id, 0xEA, field.index }
for i=1, string.len(field.value) do for i=1, string.len(field.value) do
frame[#frame + 1] = string.byte(field.value, i) frame[#frame + 1] = string.byte(field.value, i)
end end
@ -331,6 +380,11 @@ local function fieldCommandLoad(field, data, offset)
-- TODO -- TODO
end end
local function fieldCommandSave(field)
local frame = { pages[pageIndex].id, 0xEA, field.index }
crossfireTelemetryPush(0x2D, frame)
end
local function fieldCommandDisplay(field, y, attr) local function fieldCommandDisplay(field, y, attr)
lcd.drawText(0, y, field.name, attr) lcd.drawText(0, y, field.name, attr)
end end
@ -349,39 +403,66 @@ local types_functions = {
{ load=fieldStringLoad, save=fieldStringSave, display=fieldStringDisplay }, { load=fieldStringLoad, save=fieldStringSave, display=fieldStringDisplay },
nil, nil,
{ load=fieldStringLoad, save=nil, display=fieldStringDisplay }, { load=fieldStringLoad, save=nil, display=fieldStringDisplay },
{ load=fieldCommandLoad, save=nil, display=fieldCommandDisplay }, { load=fieldCommandLoad, save=fieldCommandSave, display=fieldCommandDisplay },
} }
local function parseParameterInfoMessage(data) local function parseParameterInfoMessage(data)
local page = pages[pageIndex] local page = pages[pageIndex]
io.write(f, " device:" .. data[2])
if data[2] ~= page.id then
return
end
local index = data[3] local index = data[3]
local field = page.fields[index] local field = page.fields[index]
field.parent = data[4] local chunks = data[4]
field.type = data[5] if field.data then
field.functions = types_functions[field.type+1] for i=5, #data do
local parent = field.parent field.data[#field.data + 1] = data[i]
local name = "" end
while parent ~= 0 do data = field.data
name = name .. " " io.write(f, " (" .. #field.data .. " bytes)")
parent = page.fields[parent].parent
end end
local i = 6 if chunks > 0 then
while data[i] ~= 0 do field.data = data
name = name .. string.char(data[i]) if field.next_chunk then
field.next_chunk = field.next_chunk + 1
else
field.next_chunk = 1
end
io.write(f, ", continued\n")
else
field.index = index
field.parent = data[5]
field.type = data[6] % 128
field.hidden = bit32.rshift(data[6], 7)
field.functions = types_functions[field.type+1]
io.write(f, ", id:" .. index .. ", parent:" .. field.parent .. ", type:" .. field.type .. ", hidden:" .. field.hidden)
local parent = field.parent
local name = ""
while parent ~= 0 do
name = name .. " "
parent = page.fields[parent].parent
end
local i = 7
while data[i] ~= 0 do
name = name .. string.char(data[i])
i = i + 1
end
i = i + 1 i = i + 1
field.name = name
io.write(f, ", name:" .. field.name .. "\n")
if field.functions ~= nil then
field.functions.load(field, data, i)
end
page.fieldstimeout = 0
if lineIndex == 0 and field.hidden == 0 and field.type and field.type ~= 11 and field.type ~= 12 then
initLineIndex()
end
end end
i = i + 1
field.name = name
if field.functions ~= nil then
field.functions.load(field, data, i)
end
if field.type ~= 11 and page.fields[fieldIndex].type == 11 then
fieldIndex = index
end
page.fieldstimeout = 0
end end
local devicesRefreshTimeout = 0 local devicesRefreshTimeout = 0
local paramsReceiveTimeout = 0
local function refreshNext() local function refreshNext()
local command, data = crossfireTelemetryPop() local command, data = crossfireTelemetryPop()
if command == nil then if command == nil then
@ -392,20 +473,31 @@ local function refreshNext()
else else
devicesRefreshTimeout = time + 1000 -- 10s devicesRefreshTimeout = time + 1000 -- 10s
end end
io.write(f, "Ping devices...\n")
crossfireTelemetryPush(0x28, { 0x00, 0xEA }) crossfireTelemetryPush(0x28, { 0x00, 0xEA })
elseif pageIndex <= #pages and time > pages[pageIndex].fieldstimeout then elseif time > paramsReceiveTimeout and pageIndex <= #pages and time > pages[pageIndex].fieldstimeout then
for i=1, #pages[pageIndex].fields do for i=1, #pages[pageIndex].fields do
local field = pages[pageIndex].fields[i] local field = pages[pageIndex].fields[i]
if field.name == nil then if field.name == nil then
crossfireTelemetryPush(0x2C, { pages[pageIndex].id, 0xEA, i }) local chunk = 0
pages[pageIndex].fieldstimeout = time + 200 -- 2s if field.next_chunk then
chunk = field.next_chunk
end
io.write(f, "Request parameter " .. i .. "(" .. chunk .. ")...\n")
crossfireTelemetryPush(0x2C, { pages[pageIndex].id, 0xEA, i, chunk })
paramsReceiveTimeout = time + 200 -- 2s
pages[pageIndex].fieldstimeout = paramsReceiveTimeout
break
end end
end end
end end
elseif command == 0x29 then elseif command == 0x29 then
io.write(f, "Device info received...\n")
parseDeviceInfoMessage(data) parseDeviceInfoMessage(data)
elseif command == 0x2B then elseif command == 0x2B then
io.write(f, "Parameter info received...\n")
parseParameterInfoMessage(data) parseParameterInfoMessage(data)
paramsReceiveTimeout = 0
end end
end end
@ -419,8 +511,8 @@ local function runNoDevicesPage(event)
return 0 return 0
end end
local function runDevicePage(index, event) local function runDevicePage(event)
local page = pages[index] local page = pages[pageIndex]
if event == EVT_EXIT_BREAK then -- exit script if event == EVT_EXIT_BREAK then -- exit script
if edit == true then if edit == true then
edit = false edit = false
@ -428,7 +520,7 @@ local function runDevicePage(index, event)
return 2 return 2
end end
elseif event == EVT_ENTER_BREAK then -- toggle editing/selecting current field elseif event == EVT_ENTER_BREAK then -- toggle editing/selecting current field
local field = page.fields[fieldIndex] local field = getField(lineIndex)
if field.name ~= nil then if field.name ~= nil then
if field.type == 10 then if field.type == 10 then
if edit == false then if edit == false then
@ -437,11 +529,11 @@ local function runDevicePage(index, event)
else else
charIndex = charIndex + 1 charIndex = charIndex + 1
end end
else elseif field.type ~= 13 then
edit = not edit edit = not edit
end end
if edit == false and field.functions.save ~= nil then if edit == false and field.functions.save ~= nil then
field.functions.save(fieldIndex) field.functions.save(field)
end end
end end
elseif edit then elseif edit then
@ -459,14 +551,14 @@ local function runDevicePage(index, event)
end end
lcd.clear() lcd.clear()
lcd.drawScreenTitle(page.name, index, #pages) lcd.drawScreenTitle(page.name, pageIndex, #pages)
drawDevicePage(page) drawDevicePage(page)
return 0 return 0
end end
-- Init -- Init
local function init() local function init()
fieldIndex, edit = 1, false lineIndex, edit = 0, false
end end
-- Main -- Main
@ -485,7 +577,7 @@ local function run(event)
if #pages == 0 then if #pages == 0 then
result = runNoDevicesPage(event) result = runNoDevicesPage(event)
else else
result = runDevicePage(pageIndex, event) result = runDevicePage(event)
end end
refreshNext() refreshNext()