@@ -28,10 +28,10 @@ local fieldId = 1
2828local fieldChunk = 0
2929local fieldData = {}
3030local fields = {}
31- local badPkt = 0
32- local goodPkt = 0
31+ local devices = {}
32+ local goodBadPkt = " ?/??? "
3333local elrsFlags = 0
34- local elrsFlagsInfo = " no "
34+ local elrsFlagsInfo
3535local fields_count = 0
3636local backButtonId = 2
3737local devicesRefreshTimeout = 50
@@ -50,9 +50,8 @@ local textYoffset = 1
5050local textSize = 8
5151local lcdIsColor
5252
53- local devices = { }
54-
55- local function clearAllField ()
53+ local function allocateFields ()
54+ fields = {}
5655 for i = 1 , fields_count + 2 + # devices do
5756 fields [i ] = { }
5857 end
@@ -135,31 +134,56 @@ local function selectField(step)
135134 field = getField (newLineIndex )
136135 until newLineIndex == lineIndex or (field and field .name )
137136 lineIndex = newLineIndex
138- if lineIndex > maxLineIndex + pageOffset then -- NOTE: increased from 7 to 11 to allow 11 lines in Horus display
139- pageOffset = lineIndex - maxLineIndex -- NOTE: increased from 7 to 11 to allow 11 lines in Horus display
137+ if lineIndex > maxLineIndex + pageOffset then
138+ pageOffset = lineIndex - maxLineIndex
140139 elseif lineIndex <= pageOffset then
141140 pageOffset = lineIndex - 1
142141 end
143142end
144143
145- local function split (str )
146- local t = {}
147- local i = 1
148- for s in string.gmatch (str , " ([^;]+)" ) do
149- t [i ] = s
150- i = i + 1
144+ local function fieldStrFF (data , offset , last )
145+ while data [offset ] ~= 0 do
146+ offset = offset + 1
151147 end
152- return t
148+ return last , offset + 1
153149end
154150
155- local function fieldGetString (data , offset )
151+ local function fieldGetSelectOpts (data , offset , last )
152+ if last then
153+ return fieldStrFF (data , offset , last )
154+ end
155+
156+ -- Split a table of byte values (string) with ; separator into a table
157+ local r = {}
158+ local opt = ' '
159+ local b = data [offset ]
160+ while b ~= 0 do
161+ if b == 59 then -- ';'
162+ r [# r + 1 ] = opt
163+ opt = ' '
164+ else
165+ opt = opt .. string.char (b )
166+ end
167+ offset = offset + 1
168+ b = data [offset ]
169+ end
170+
171+ r [# r + 1 ] = opt
172+ return r , offset + 1
173+ end
174+
175+ local function fieldGetString (data , offset , last )
176+ if last then
177+ return fieldStrFF (data , offset , last )
178+ end
179+
156180 local result = " "
157181 while data [offset ] ~= 0 do
158182 result = result .. string.char (data [offset ])
159183 offset = offset + 1
160184 end
161- offset = offset + 1
162- return result , offset
185+
186+ return result , offset + 1
163187end
164188
165189local function getBitBin (data , bitPosition )
@@ -177,7 +201,7 @@ local function getBitBin(data, bitPosition)
177201 }
178202 return device
179203 end
180-
204+
181205 local function getDevice (name )
182206 for i = 1 , # devices do
183207 if devices [i ].name == name then
@@ -200,7 +224,7 @@ local function fieldUnsignedLoad(field, data, offset, size)
200224 field .min = fieldGetValue (data , offset + size , size )
201225 field .max = fieldGetValue (data , offset + 2 * size , size )
202226 field .default = fieldGetValue (data , offset + 3 * size , size )
203- field .unit , offset = fieldGetString (data , offset + 4 * size )
227+ field .unit , offset = fieldGetString (data , offset + 4 * size , field . unit )
204228 field .step = 1
205229end
206230
@@ -239,9 +263,7 @@ local function fieldSignedSave(field, size)
239263end
240264
241265local function fieldIntDisplay (field , y , attr )
242- -- lcd.drawNumber(COL2, y, field.value, LEFT + attr) -- NOTE: original code getLastPos not available in Horus
243- -- lcd.drawText(lcd.getLastPos(), y, field.unit, attr) -- NOTE: original code getLastPos not available in Horus
244- lcd .drawText (COL2 , y , field .value .. field .unit , attr ) -- NOTE: Concenated fields instead of get lastPos
266+ lcd .drawText (COL2 , y , field .value .. field .unit , attr )
245267end
246268
247269-- UINT8
@@ -292,7 +314,7 @@ local function fieldFloatLoad(field, data, offset)
292314 field .prec = 3
293315 end
294316 field .step = fieldGetValue (data , offset + 17 , 4 )
295- field .unit , offset = fieldGetString (data , offset + 21 )
317+ field .unit , offset = fieldGetString (data , offset + 21 , field . unit )
296318end
297319
298320local function formatFloat (num , decimals )
@@ -311,26 +333,20 @@ end
311333
312334-- TEXT SELECTION
313335local function fieldTextSelectionLoad (field , data , offset )
314- local values
315- values , offset = fieldGetString (data , offset )
316- if values ~= " " then
317- field .values = split (values )
318- end
336+ field .values , offset = fieldGetSelectOpts (data , offset , field .values )
319337 field .value = data [offset ]
320338 field .min = data [offset + 1 ]
321339 field .max = data [offset + 2 ]
322340 field .default = data [offset + 3 ]
323- field .unit , offset = fieldGetString (data , offset + 4 )
341+ field .unit , offset = fieldGetString (data , offset + 4 , field . unit )
324342end
325343
326344local function fieldTextSelectionSave (field )
327345 crossfireTelemetryPush (0x2D , { deviceId , handsetId , field .id , field .value })
328346end
329347
330348local function fieldTextSelectionDisplay (field , y , attr )
331- -- lcd.drawText(COL2, y, field.values[field.value+1], attr) -- NOTE: original code getLastPos not available in Horus
332- -- lcd.drawText(lcd.getLastPos(), y, field.unit, attr) -- NOTE: original code getLastPos not available in Horus
333- lcd .drawText (COL2 , y , field .values [field .value + 1 ] .. field .unit , attr ) -- NOTE: Concenated fields instead of get lastPos
349+ lcd .drawText (COL2 , y , field .values [field .value + 1 ] .. field .unit , attr )
334350end
335351
336352-- STRING
412428
413429local function changeDeviceId (devId ) -- change to selected device ID
414430 folderAccess = 0
415- clearAllField ()
416431 deviceIsELRS = false
417432 elrsFlags = 0
418433 -- if the selected device ID (target) is a TX Module, we use our Lua ID, so TX Flag that user is using our LUA
@@ -435,7 +450,6 @@ local function parseDeviceInfoMessage(data)
435450 local offset
436451 local id = data [2 ]
437452 local devicesName = " "
438- -- deviceId = data[2]
439453 devicesName , offset = fieldGetString (data , 3 )
440454 local device = getDevice (devicesName )
441455 if device == nil then
@@ -445,10 +459,13 @@ local function parseDeviceInfoMessage(data)
445459 if deviceId == id then
446460 deviceName = devicesName
447461 deviceIsELRS = fieldGetValue (data ,offset ,4 ) == 0x454C5253 -- SerialNumber = 'E L R S'
448- fields_count = data [offset + 12 ]
462+ local newFieldCount = data [offset + 12 ]
449463 reloadAllField ()
450- clearAllField ()
451- fields [fields_count + 1 ] = {id = fields_count + 1 , name = " Other Devices" , parent = 255 , type = 16 } -- add other devices folders
464+ if newFieldCount ~= fields_count then
465+ fields_count = newFieldCount
466+ allocateFields ()
467+ fields [fields_count + 1 ] = {id = fields_count + 1 , name = " Other Devices" , parent = 255 , type = 16 } -- add other devices folders
468+ end
452469 end
453470end
454471
@@ -512,27 +529,10 @@ local function parseParameterInfoMessage(data)
512529 return -- no data extraction
513530 end
514531 field .id = fieldId
515- local parent = fieldData [1 ]
516- local type = fieldData [2 ] % 128
517- local hidden = (bit32.rshift (fieldData [2 ], 7 ) == 1 )
518- if field .name ~= nil then -- already seen this field before, so we can validate this packet is correct
519- if field .parent ~= parent or field .type ~= type or field .hidden ~= hidden then
520- fieldData = {}
521- return -- no data extraction
522- end
523- end
524- field .parent = parent
525- field .type = type
526- field .hidden = hidden
527- local name , i = fieldGetString (fieldData , 3 )
528- if name ~= " " then
529- local indent = " "
530- while parent ~= 0 do
531- indent = indent .. " "
532- parent = fields [parent ].parent
533- end
534- field .name = indent .. name
535- end
532+ field .parent = fieldData [1 ]
533+ field .type = fieldData [2 ] % 128
534+ field .hidden = (bit32.rshift (fieldData [2 ], 7 ) == 1 )
535+ field .name , i = fieldGetString (fieldData , 3 , field .name )
536536 if functions [field .type + 1 ].load then
537537 functions [field .type + 1 ].load (field , fieldData , i )
538538 end
@@ -559,10 +559,11 @@ local function parseElrsInfoMessage(data)
559559 fieldChunk = 0
560560 return
561561 end
562- badPkt = data [3 ]
563- goodPkt = (data [4 ]* 256 ) + data [5 ]
562+ local badPkt = data [3 ]
563+ local goodPkt = (data [4 ]* 256 ) + data [5 ]
564+ goodBadPkt = tostring (badPkt ) .. " /" .. tostring (goodPkt )
564565 elrsFlags = data [6 ]
565- elrsFlagsInfo , offset = fieldGetString (data ,7 )
566+ elrsFlagsInfo = elrsFlags ~= 0 and fieldGetString (data , 7 ) or nil
566567end
567568
568569local function refreshNext ()
@@ -623,7 +624,7 @@ local function lcd_title()
623624 lcd .drawFilledRectangle (0 , 0 , LCD_W , barHeight , CUSTOM_COLOR )
624625 lcd .setColor (CUSTOM_COLOR , BLACK )
625626 lcd .drawText (textXoffset + 1 , 4 , title , CUSTOM_COLOR )
626- lcd .drawText (LCD_W - 3 , 4 , tostring ( badPkt ) .. " / " .. tostring ( goodPkt ) , RIGHT + BOLD + CUSTOM_COLOR )
627+ lcd .drawText (LCD_W - 3 , 4 , goodBadPkt , RIGHT + BOLD + CUSTOM_COLOR )
627628 -- progress bar
628629 if allParamsLoaded ~= 1 and fields_count > 0 then
629630 local barW = (COL2 - 4 )* fieldId / fields_count
@@ -637,7 +638,7 @@ local function lcd_title()
637638 local barHeight = 9
638639
639640 lcd .clear ()
640- lcd .drawText (LCD_W , 1 , tostring ( badPkt ) .. " / " .. tostring ( goodPkt ) , RIGHT )
641+ lcd .drawText (LCD_W , 1 , goodBadPkt , RIGHT )
641642 -- keep the title this way to keep the script from error when module is not set correctly
642643 if allParamsLoaded ~= 1 and fields_count > 0 then
643644 lcd .drawFilledRectangle (COL2 , 0 , LCD_W , barHeight , GREY_DEFAULT )
@@ -648,7 +649,7 @@ local function lcd_title()
648649 end
649650 end
650651end
651-
652+
652653
653654local function lcd_warn ()
654655 lcd .drawText (textSize * 3 ,textSize * 2 ,tostring (elrsFlags ).. " : " .. elrsFlagsInfo ,0 )
@@ -728,7 +729,7 @@ local function runDevicePage(event)
728729 handleDevicePageEvent (event )
729730
730731 lcd_title ()
731-
732+
732733 if # devices > 1 then -- show other device folder
733734 fields [fields_count + 1 ].parent = 0
734735 end
@@ -792,7 +793,7 @@ local function runPopupPage(event)
792793 end
793794 return 0
794795end
795-
796+
796797local function setLCDvar ()
797798 lcdIsColor = lcd .RGB ~= nil
798799 if LCD_W == 480 then
@@ -806,7 +807,7 @@ local function setLCDvar()
806807 COL2 = 110
807808 else
808809 COL2 = 70
809- end
810+ end
810811 maxLineIndex = 6
811812 textXoffset = 0
812813 textYoffset = 3
@@ -820,7 +821,7 @@ local function setMock()
820821 if string.sub (rv , - 5 ) ~= " -simu" then return end
821822 local mock = loadScript (" mockup/elrsmock.lua" )
822823 if mock == nil then return end
823- fields , goodPkt = mock (), 500
824+ fields , goodBadPkt = mock (), " 0/ 500"
824825 fields_count = # fields - 1
825826 fieldId = # fields - 3
826827end
0 commit comments