1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-21 15:25:17 +03:00
opentx/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky SBEC.lua
2020-01-27 15:10:46 +01:00

284 lines
7.8 KiB
Lua

---- #########################################################################
---- # #
---- # Copyright (C) OpenTX #
-----# #
---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html #
---- # #
---- # This program is free software; you can redistribute it and/or modify #
---- # it under the terms of the GNU General Public License version 2 as #
---- # published by the Free Software Foundation. #
---- # #
---- # This program is distributed in the hope that it will be useful #
---- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
---- # GNU General Public License for more details. #
---- # #
---- #########################################################################
local version = "v1.2"
local VALUE = 0
local COMBO = 1
local edit = false
local page = 1
local current = 1 --row
local refreshState = 0
local refreshIndex = 0
local pageOffset = 0
local pages = {}
local fields = {}
local modifications = {}
local margin = 1
local spacing = 8
local appId = 0
local function drawScreenTitle(title,page, pages)
if math.fmod(math.floor(getTime()/100),10) == 0 then
title = version
end
if LCD_W == 480 then
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
lcd.drawText(1, 5, title, MENU_TITLE_COLOR)
lcd.drawText(LCD_W-40, 5, page.."/"..pages, MENU_TITLE_COLOR)
else
lcd.drawScreenTitle(title, page, pages)
end
end
local settingsFields = {
{"SBEC OUTPUT (V)", VALUE, 0x80, nil, 50, 84 },
{"Physical ID", VALUE, 0x01, nil, 0, 26 },
{"Application IDgroup", VALUE, 0x0D, nil, 0, 15 },
{"Data rate(*100ms)", VALUE, 0x22, nil, 1, 255 },
}
-- Change display attribute to current field
local function addField(step)
local field = fields[current]
local min, max
if field[2] == VALUE then
min = field[5]
max = field[6]
elseif field[2] == COMBO then
min = 0
max = #(field[5]) - 1
end
if field[2] ~= FLPOT then --only read ?
if field[2] == VALUE and field[6] > 256 then
if field[4] > 1000 then
step = step * 50
field[4] = math.floor(field[4]/50)
field[4] = field[4] *50
elseif field[4] > 500 then
step = step * 20
field[4] = math.floor(field[4]/20)
field[4] = field[4] *20
elseif field[4] > 200 then
step = step * 10
field[4] = math.floor(field[4]/10)
field[4] = field[4] *10
else
step = step * 1
field[4] = math.floor(field[4]/1)
field[4] = field[4] *1
end
end
if (step < 0 and field[4] > min) or (step > 0 and field[4] < max) then
field[4] = field[4] + step
end
else
field[4] = field[4]
end
end
-- Select the next or previous editable field
local function selectField(step)
current = current + step
if current > #fields then
current = #fields
elseif current < 1 then
current = 1
end
if current > 7 + pageOffset then
pageOffset = current - 7
elseif current <= pageOffset then
pageOffset = current - 1
end
end
local function drawProgressBar()
if LCD_W == 480 then
local width = (300 * refreshIndex) / #fields
lcd.drawRectangle(100, 10, 300, 6)
lcd.drawFilledRectangle(102, 13, width, 2);
else
local width = (60 * refreshIndex) / #fields
lcd.drawRectangle(45, 1, 60, 6)
lcd.drawFilledRectangle(47, 3, width, 2);
end
end
-- Redraw the current page
local function redrawFieldsPage()
lcd.clear()
drawScreenTitle("SBEC", page, #pages)
if refreshIndex < #fields then
drawProgressBar()
end
for index = 1, 7, 1 do
local field = fields[pageOffset+index]
if field == nil then
break
end
local attr = current == (pageOffset+index) and ((edit == true and BLINK or 0) + INVERS) or 0
lcd.drawText(1, margin+ spacing * index, field[1])
if field[4] == nil then
lcd.drawText(LCD_W, margin+ spacing * index, "---", attr + RIGHT)
else
if field[2] == VALUE then
if field[3] == 0x80 then
lcd.drawNumber(LCD_W, margin+ spacing * index, field[4] , attr + RIGHT + PREC1)
else
lcd.drawNumber(LCD_W, margin+ spacing * index, field[4] , attr + RIGHT)
end
end
end
end
end
local function telemetryRead(fieldx)
return sportTelemetryPush(0x17, 0x30, appId, fieldx)
end
local function telemetryIdle(field)
return sportTelemetryPush(0x17, 0x21, appId, field)
end
local function telemetryUnIdle(field)
return sportTelemetryPush(0x17, 0x20, appId, field)
end
local function telemetryWrite(fieldx, valuex)
return sportTelemetryPush(0x17, 0x31, appId, fieldx + valuex*256)
end
local telemetryPopTimeout = 0
local function refreshNext()
if refreshState == 0 then
if #modifications > 0 then
local modificationstmp = modifications[1][2]
telemetryWrite(modifications[1][1], modificationstmp)
refreshIndex = 0
modifications[1] = nil
elseif refreshIndex < #fields then
local field = fields[refreshIndex + 1]
if telemetryRead(field[3]) == true then
refreshState = 1
telemetryPopTimeout = getTime() + 80
end
end
elseif refreshState == 1 then
local physicalId, primId, dataId, value = sportTelemetryPop()
if primId == 0x32 and dataId == appId then
local fieldId = value % 256
local field = fields[refreshIndex + 1]
if fieldId == field[3] then
local value = math.floor(value / 256)
if field[2] == VALUE then
value = value
end
fields[refreshIndex + 1][4] = value
refreshIndex = refreshIndex + 1
refreshState = 0
end
elseif getTime() > telemetryPopTimeout then
refreshState = 0
end
end
end
local function updateField(field)
local value = field[4]
if field[2] == VALUE and #field == 6 then
value = value
end
modifications[#modifications+1] = {field[3], value}
end
-- Main1
local function runFieldsPage(event)
if event == EVT_VIRTUAL_EXIT then
telemetryUnIdle(0x80)
return 2
elseif event == EVT_VIRTUAL_ENTER then
if fields[current][4] ~= nil then
edit = not edit
if edit == false then
updateField(fields[current])
end
end
elseif edit then
if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then
addField(1)
elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then
addField(-1)
end
else
if event == EVT_VIRTUAL_NEXT then
selectField(1)
elseif event == EVT_VIRTUAL_PREV then
selectField(-1)
end
end
redrawFieldsPage()
return 0
end
local function runSettingsPage(event)
fields = settingsFields
return runFieldsPage(event)
end
-- Init
local function init()
current, edit, refreshState, refreshIndex = 1, false, 0, 0
if LCD_W == 480 then
margin = 10
spacing = 20
end
pages = {
runSettingsPage,
}
for index = 1, 40, 1 do
local sensor = model.getSensor(index)
if sensor ~= nil and sensor.id >= 0x0e50 and sensor.id <= 0x0e5f then
appId = sensor.id
break
end
end
if appId == 0 then
error("No SBEC sensor in this model!")
end
telemetryIdle(0x80)
end
local function run(event)
if event == nil then
error("Cannot run as a model script!")
return 2
end
local result = pages[page](event)
refreshNext()
return result
end
return { init=init, background=background, run=run }