From 3b90b0d6c0c3cdeb9f333efacf0f3621337316be Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Mon, 25 Jul 2016 21:56:00 +0200 Subject: [PATCH] [Crossfire] Lua script continued --- radio/sdcard/taranis/CROSSFIRE/Crossfire.lua | 248 +++++++++++++++---- 1 file changed, 194 insertions(+), 54 deletions(-) diff --git a/radio/sdcard/taranis/CROSSFIRE/Crossfire.lua b/radio/sdcard/taranis/CROSSFIRE/Crossfire.lua index 7aef9071e..47e9644e1 100644 --- a/radio/sdcard/taranis/CROSSFIRE/Crossfire.lua +++ b/radio/sdcard/taranis/CROSSFIRE/Crossfire.lua @@ -1,25 +1,37 @@ local COLUMN_2 = 140 -local edit = false +local pages = { } local pageIndex = 1 local fieldIndex = 1 local pageOffset = 0 -local pages = { } +local edit = false +local charIndex = 1 -- Change display attribute to current field local function incrField(step) local fields = pages[pageIndex].fields local field = fields[fieldIndex] - local min, max = 0, 0 - if field.type <= 5 then - min = field.min - max = field.max - elseif field.type == 9 then - min = 0 - max = #field.values - 1 - end - if (step < 0 and field.value > min) or (step > 0 and field.value < max) then - field.value = field.value + step + if field.type == 10 then + local byte = string.byte(field.value, charIndex) + step + if byte < 32 then + byte = 32 + elseif byte > 122 then + byte = 122 + end + field.value = string.sub(field.value, 1, charIndex-1) .. string.char(byte) .. string.sub(field.value, charIndex+1) + else + local min, max = 0, 0 + if field.type <= 5 then + min = field.min + max = field.max + step = field.step * step + elseif field.type == 9 then + min = 0 + max = #field.values - 1 + end + if (step < 0 and field.value > min) or (step > 0 and field.value < max) then + field.value = field.value + step + end end end @@ -32,9 +44,11 @@ end local function selectField(step) local fields = pages[pageIndex].fields local newFieldIndex = fieldIndex + local field = fields[newFieldIndex] repeat newFieldIndex = 1 + ((newFieldIndex + step - 1 + #fields) % #fields) - until newFieldIndex == fieldIndex or (pages[pageIndex].fields[newFieldIndex].type ~= 11 and pages[pageIndex].fields[newFieldIndex].name ~= nil) + field = fields[newFieldIndex] + until newFieldIndex == fieldIndex or (field.type ~= 11 and field.type ~= 12 and field.name ~= nil) fieldIndex = newFieldIndex if fieldIndex > 7 + pageOffset then pageOffset = fieldIndex - 7 @@ -135,45 +149,140 @@ local function fieldGetString(data, offset) return result, offset end --- UINT8 -local function fieldUint8SelectionLoad(field, data, offset) - field.value = data[offset] - field.min = data[offset+1] - field.max = data[offset+2] - field.unit, offset = fieldGetString(data, offset+4) +local function fieldGetValue(data, offset, size) + local result = 0 + for i=0, size-1 do + result = bit32.lshift(result, 8) + data[offset + i] + end + return result end -local function fieldUint8SelectionSave(fieldIndex) - crossfireTelemetryPush(0x2D, { pages[pageIndex].id, 0xEA, fieldIndex, pages[pageIndex].fields[fieldIndex].value }) +local function fieldUnsignedSelectionLoad(field, data, offset, size) + field.value = fieldGetValue(data, offset, size) + field.min = fieldGetValue(data, offset+size, size) + field.max = fieldGetValue(data, offset+2*size, size) + field.unit, offset = fieldGetString(data, offset+3*size) + field.step = 1 end -local function fieldIntSelectionDisplay(field, y, attr) +local function fieldUnsignedToSigned(field, size) + local bandval = bit32.lshift(0x80, (size-1)*8) + field.value = field.value - bit32.band(field.value, bandval) * 2 + field.min = field.min - bit32.band(field.min, bandval) * 2 + field.max = field.max - bit32.band(field.max, bandval) * 2 +end + +local function fieldSignedSelectionLoad(field, data, offset, size) + fieldUnsignedSelectionLoad(field, data, offset, size) + fieldUnsignedToSigned(field, size) +end + +local function fieldIntSave(fieldIndex, value, size) + local frame = { pages[pageIndex].id, 0xEA, fieldIndex } + for i=size-1, 0, -1 do + frame[#frame + 1] = (bit32.rshift(value, 8*i) % 256) + end + crossfireTelemetryPush(0x2D, frame) +end + +local function fieldUnsignedSelectionSave(fieldIndex, size) + local value = pages[pageIndex].fields[fieldIndex].value + fieldIntSave(fieldIndex, value, size) +end + +local function fieldSignedSelectionSave(fieldIndex, size) + local value = pages[pageIndex].fields[fieldIndex].value + if value < 0 then + value = bit32.lshift(0x100, (size-1)*8) - value + end + fieldIntSave(fieldIndex, value, size) +end + +local function fieldIntDisplay(field, y, attr) lcd.drawNumber(COLUMN_2, y, field.value, LEFT + attr) lcd.drawText(lcd.getLastPos(), y, field.unit, attr) end --- UINT16 -local function fieldUint16SelectionLoad(field, data, offset) - field.value = bit32.lshift(data[offset], 8) + data[offset+1] - field.min = bit32.lshift(data[offset+2], 8) + data[offset+3] - field.max = bit32.lshift(data[offset+4], 8) + data[offset+5] - field.unit, offset = fieldGetString(data, offset+6) +-- UINT8 +local function fieldUint8Load(field, data, offset) + fieldUnsignedSelectionLoad(field, data, offset, 1) end -local function fieldUint16SelectionSave(fieldIndex) - crossfireTelemetryPush(0x2D, { pages[pageIndex].id, 0xEA, fieldIndex, bit32.rshift(pages[pageIndex].fields[fieldIndex].value, 8), pages[pageIndex].fields[fieldIndex].value % 255 }) +local function fieldUint8Save(fieldIndex) + fieldUnsignedSelectionSave(fieldIndex, 1) +end + +-- INT8 +local function fieldInt8Load(field, data, offset) + fieldSignedSelectionLoad(field, data, offset, 1) +end + +local function fieldInt8Save(fieldIndex) + fieldSignedSelectionSave(fieldIndex, 1) +end + +-- UINT16 +local function fieldUint16Load(field, data, offset) + fieldUnsignedSelectionLoad(field, data, offset, 2) +end + +local function fieldUint16Save(fieldIndex) + + fieldUnsignedSelectionSave(fieldIndex, 2) +end + +-- INT16 +local function fieldInt16Load(field, data, offset) + fieldSignedSelectionLoad(field, data, offset, 2) +end + +local function fieldInt16Save(fieldIndex) + fieldSignedSelectionSave(fieldIndex, 2) end -- UINT32 -local function fieldUint32SelectionLoad(field, data, offset) - field.value = bit32.lshift(data[offset], 24) + bit32.lshift(data[offset+1], 16) + bit32.lshift(data[offset+2], 8) + data[offset+3] - field.min = bit32.lshift(data[offset+4], 24) + bit32.lshift(data[offset+5], 16) + bit32.lshift(data[offset+6], 8) + data[offset+7] - field.max = bit32.lshift(data[offset+8], 24) + bit32.lshift(data[offset+9], 16) + bit32.lshift(data[offset+10], 8) + data[offset+11] - field.unit, offset = fieldGetString(data, offset+12) +local function fieldUint32Load(field, data, offset) + fieldUnsignedSelectionLoad(field, data, offset, 4) end -local function fieldUint32SelectionSave(fieldIndex) - crossfireTelemetryPush(0x2D, { pages[pageIndex].id, 0xEA, fieldIndex, bit32.rshift(pages[pageIndex].fields[fieldIndex].value, 24), bit32.rshift(pages[pageIndex].fields[fieldIndex].value, 16) % 255, bit32.rshift(pages[pageIndex].fields[fieldIndex].value, 8) % 255, pages[pageIndex].fields[fieldIndex].value % 255 }) +local function fieldUint32Save(fieldIndex) + fieldUnsignedSelectionSave(fieldIndex, 4) +end + +-- INT32 +local function fieldInt32Load(field, data, offset) + fieldSignedSelectionLoad(field, data, offset, 4) +end + +local function fieldInt32Save(fieldIndex) + fieldSignedSelectionSave(fieldIndex, 4) +end + +-- FLOAT +local function fieldFloatSelectionLoad(field, data, offset) + field.value = fieldGetValue(data, offset, 4) + field.min = fieldGetValue(data, offset+4, 4) + field.max = fieldGetValue(data, offset+8, 4) + fieldUnsignedToSigned(field, 4) + field.prec = data[offset+12] + if field.prec > 2 then + field.prec = 2 + end + field.step = fieldGetValue(data, offset+13, 4) + field.unit, offset = fieldGetString(data, offset+14) +end + +local function fieldFloatSelectionDisplay(field, y, attr) + local attrnum + if field.prec == 1 then + attrnum = LEFT + attr + PREC1 + elseif field.prec == 2 then + attrnum = LEFT + attr + PREC2 + else + attrnum = LEFT + attr + end + lcd.drawNumber(COLUMN_2, y, field.value, attrnum) + lcd.drawText(lcd.getLastPos(), y, field.unit, attr) end -- TEXT SELECTION @@ -193,36 +302,54 @@ local function fieldTextSelectionDisplay(field, y, attr) end -- STRING -local function fieldStringSelectionLoad(field, data, offset) +local function fieldStringLoad(field, data, offset) field.value, offset = fieldGetString(data, offset) if #data >= offset then field.maxlen = data[offset] end end -local function fieldStringSelectionSave(fieldIndex) - -- crossfireTelemetryPush(0x2D, { pages[pageIndex].id, 0xEA, fieldIndex, }) +local function fieldStringSave(fieldIndex) + local frame = { pages[pageIndex].id, 0xEA, fieldIndex } + for i=1, string.len(field.value) do + frame[#frame + 1] = string.byte(field.value, i) + end + frame[#frame + 1] = 0 + crossfireTelemetryPush(0x2D, frame) end -local function fieldStringSelectionDisplay(field, y, attr) - lcd.drawText(COLUMN_2, y, field.value, attr) +local function fieldStringDisplay(field, y, attr) + if edit == true and attr ~= 0 then + lcd.drawText(COLUMN_2, y, field.value, FIXEDWIDTH) + lcd.drawText(COLUMN_2+6*charIndex-6, y, string.sub(field.value, charIndex, charIndex), FIXEDWIDTH + attr) + else + lcd.drawText(COLUMN_2, y, field.value, FIXEDWIDTH + attr) + end +end + +local function fieldCommandLoad(field, data, offset) + -- TODO +end + +local function fieldCommandDisplay(field, y, attr) + lcd.drawText(0, y, field.name, attr) end local types_functions = { - { load=fieldUint8SelectionLoad, save=fieldUint8SelectionSave, display=fieldIntSelectionDisplay }, - { load=fieldUint8SelectionLoad, save=fieldUint8SelectionSave, display=fieldIntSelectionDisplay }, - { load=fieldUint16SelectionLoad, save=fieldUint16SelectionSave, display=fieldIntSelectionDisplay }, - { load=fieldUint16SelectionLoad, save=fieldUint16SelectionSave, display=fieldIntSelectionDisplay }, - { load=fieldUint32SelectionLoad, save=fieldUint32SelectionSave, display=fieldIntSelectionDisplay }, - { load=fieldUint32SelectionLoad, save=fieldUint32SelectionSave, display=fieldIntSelectionDisplay }, - nil, + { load=fieldUint8Load, save=fieldUint8Save, display=fieldIntDisplay }, + { load=fieldInt8Load, save=fieldInt8Save, display=fieldIntDisplay }, + { load=fieldUint16Load, save=fieldUint16Save, display=fieldIntDisplay }, + { load=fieldInt16Load, save=fieldInt16Save, display=fieldIntDisplay }, + { load=fieldUint32Load, save=fieldUint32Save, display=fieldIntDisplay }, + { load=fieldInt32Load, save=fieldInt32Save, display=fieldIntDisplay }, nil, nil, + { load=fieldFloatSelectionLoad, save=fieldInt32Save, display=fieldFloatSelectionDisplay }, { load=fieldTextSelectionLoad, save=fieldTextSelectionSave, display=fieldTextSelectionDisplay }, - { load=fieldStringSelectionLoad, save=fieldStringSelectionSave, display=fieldStringSelectionDisplay }, + { load=fieldStringLoad, save=fieldStringSave, display=fieldStringDisplay }, nil, - { load=fieldStringSelectionLoad, save=fieldStringSelectionSave, display=fieldStringSelectionDisplay }, - + { load=fieldStringLoad, save=nil, display=fieldStringDisplay }, + { load=fieldCommandLoad, save=nil, display=fieldCommandDisplay }, } local function parseParameterInfoMessage(data) @@ -295,11 +422,24 @@ end local function runDevicePage(index, event) local page = pages[index] if event == EVT_EXIT_BREAK then -- exit script - return 2 + if edit == true then + edit = false + else + return 2 + end elseif event == EVT_ENTER_BREAK then -- toggle editing/selecting current field local field = page.fields[fieldIndex] if field.name ~= nil then - edit = not edit + if field.type == 10 then + if edit == false then + edit = true + charIndex = 1 + else + charIndex = charIndex + 1 + end + else + edit = not edit + end if edit == false and field.functions.save ~= nil then field.functions.save(fieldIndex) end