Skip to content

Commit ebf6341

Browse files
Activate lua warning and status information, and change the way warning is displayed (ExpressLRS#1011)
* fix wrong function type chhange miss type * untested * Send back the model-match flag from the RX to the TX * 3 msb is for critical warning * fix lua not loading properly * fix missing attribute in lua * send status to lua * fix * register some warning * fix full screen ciritical warning page call * Compile fixes and wrong order of messages * add a bit nicer status icon * use enum for easier * Add comments * fix spacing * reset connectionHasModelMatch * fix conflicts * fix more spacing * fix some review * fix some review * a bit of visual improvement * FlagsInfo should always read a string * remove confusing comment and add comment Co-authored-by: Paul Kendall <[email protected]>
1 parent f0e79f7 commit ebf6341

6 files changed

Lines changed: 118 additions & 38 deletions

File tree

src/lib/LUA/devLUA.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ extern uint8_t adjustPacketRateForBaud(uint8_t rate);
189189
extern void SetSyncSpam();
190190
extern void EnterBindingMode();
191191
extern bool InBindingMode;
192+
extern bool connectionHasModelMatch;
192193
#if defined(USE_TX_BACKPACK)
193194
extern uint8_t TxBackpackWiFiReadyToSend;
194195
extern uint8_t VRxBackpackWiFiReadyToSend;
@@ -374,6 +375,8 @@ static void registerLuaParameters()
374375

375376
static int event()
376377
{
378+
setLuaWarningFlag(LUA_FLAG_MODEL_MATCH, connectionState == connected && connectionHasModelMatch == false);
379+
setLuaWarningFlag(LUA_FLAG_CONNECTED, connectionState == connected);
377380
uint8_t rate = adjustPacketRateForBaud(config.GetRate());
378381
setLuaTextSelectionValue(&luaAirRate, RATE_MAX - 1 - rate);
379382
setLuaTextSelectionValue(&luaTlmRate, config.GetTlm());

src/lib/LUA/lua.cpp

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ extern CRSF crsf;
99
static volatile bool UpdateParamReq = false;
1010

1111
//LUA VARIABLES//
12-
static uint8_t luaWarningFLags = false;
13-
static uint8_t suppressedLuaWarningFlags = true;
12+
static uint8_t luaWarningFlags = 0b00000000; //8 flag, 1 bit for each flag. set the bit to 1 to show specific warning. 3 MSB is for critical flag
13+
static uint8_t suppressedLuaWarningFlags = 0xFF; //8 flag, 1 bit for each flag. set the bit to 0 to suppress specific warning
1414

1515
#define LUA_MAX_PARAMS 32
1616
static const void *paramDefinitions[LUA_MAX_PARAMS] = {0}; // array of luaItem_*
@@ -167,26 +167,57 @@ void sendLuaCommandResponse(struct luaItem_command *cmd, uint8_t step, const cha
167167
pushResponseChunk(cmd);
168168
}
169169

170-
void suppressCurrentLuaWarning(void){ //0 to suppress
171-
suppressedLuaWarningFlags = ~luaWarningFLags;
170+
void suppressCurrentLuaWarning(void){ //flip all the current warning bits, so that the warning check (getLuaWarningFlags()) returns 0
171+
//only flip 3 Most significant bit, they are the critical warning that blocks lua
172+
suppressedLuaWarningFlags = ~luaWarningFlags | 0b00011111;
172173
}
173174

174-
bool getLuaWarning(void){ //1 if alarm
175-
return luaWarningFLags & suppressedLuaWarningFlags;
175+
void setLuaWarningFlag(lua_Flags flag, bool value){
176+
if (value)
177+
{
178+
luaWarningFlags |= 1 << (uint8_t)flag;
179+
}
180+
else
181+
{
182+
luaWarningFlags &= ~(1 << (uint8_t)flag);
183+
}
184+
}
185+
186+
uint8_t getLuaWarningFlags(void){ //return an unsppressed warning flag
187+
return luaWarningFlags & suppressedLuaWarningFlags;
176188
}
177189

178190
void sendELRSstatus()
179191
{
180-
uint8_t buffer[sizeof(tagLuaElrsParams) + 0];
192+
constexpr const char *messages[] = { //higher order = higher priority
193+
"", //status2 = connected status
194+
"", //status1, reserved for future use
195+
"Model Mismatch", //warning3, model mismatch
196+
"", //warning2, reserved for future use
197+
"", //warning1, reserved for future use
198+
"", //critical warning3, reserved for future use
199+
"", //critical warning2, reserved for future use
200+
"" //critical warning1, reserved for future use
201+
};
202+
const char * warningInfo = "";
203+
204+
for (int i=7 ; i>=0 ; i--)
205+
{
206+
if(getLuaWarningFlags() & (1<<i))
207+
{
208+
warningInfo = messages[i];
209+
break;
210+
}
211+
}
212+
uint8_t buffer[sizeof(tagLuaElrsParams) + strlen(warningInfo) + 1];
181213
struct tagLuaElrsParams * const params = (struct tagLuaElrsParams *)buffer;
182214

183215
params->pktsBad = crsf.BadPktsCountResult;
184216
params->pktsGood = htobe16(crsf.GoodPktsCountResult);
185-
params->flags = getLuaWarning();
217+
params->flags = getLuaWarningFlags();
186218
// to support sending a params.msg, buffer should be extended by the strlen of the message
187219
// and copied into params->msg (with trailing null)
188-
params->msg[0] = '\0';
189-
220+
strcpy(params->msg, warningInfo);
190221
crsf.packetQueueExtended(0x2E, &buffer, sizeof(buffer));
191222
}
192223

src/lib/LUA/lua.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@
55
#include "targets.h"
66
#include "crsf_protocol.h"
77

8+
enum lua_Flags{
9+
LUA_FLAG_CONNECTED = 0, //bit 0 and 1 are status flags, show up as the little icon in the lua top right corner
10+
LUA_FLAG_STATUS1,
11+
LUA_FLAG_MODEL_MATCH, //bit 2,3,4 are warning flags, change the tittle bar every 0.5s
12+
LUA_FLAG_WARNING2,
13+
LUA_FLAG_WARNING1,
14+
LUA_FLAG_CRITICAL_WARNING1, //bit 5,6,7 are critical warning flag, block the lua screen until user confirm to suppress the warning.
15+
LUA_FLAG_CRITICAL_WARNING2,
16+
LUA_FLAG_CRITICAL_WARNING3
17+
};
18+
819
struct luaPropertiesCommon {
920
const char* const name; // display name
1021
const crsf_value_type_e type;
@@ -93,7 +104,8 @@ struct tagLuaElrsParams {
93104
extern void sendLuaCommandResponse(struct luaItem_command *cmd, uint8_t step, const char *message);
94105

95106
extern void suppressCurrentLuaWarning(void);
96-
extern bool getLuaWarning(void);
107+
extern void setLuaWarningFlag(lua_Flags flag, bool value);
108+
extern uint8_t getLuaWarningFlags(void);
97109
extern void ICACHE_RAM_ATTR luaParamUpdateReq();
98110
extern bool luaHandleUpdateParameter();
99111

src/lua/elrsV2.lua

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ local fields = {}
3131
local devices = {}
3232
local goodBadPkt = "?/???"
3333
local elrsFlags = 0
34-
local elrsFlagsInfo
34+
local elrsFlagsInfo = ""
3535
local fields_count = 0
3636
local backButtonId = 2
3737
local devicesRefreshTimeout = 50
@@ -42,6 +42,8 @@ local commandRunningIndicator = 1
4242
local expectedChunks = -1
4343
local deviceIsELRS = false
4444
local linkstatTimeout = 100
45+
local titleShowWarn = false
46+
local titleShowWarnTimeout = 100
4547

4648
local COL2 = 70
4749
local maxLineIndex = 7
@@ -368,8 +370,6 @@ end
368370

369371
local function fieldStringDisplay(field, y, attr)
370372
if edit == true and attr then
371-
-- lcd.drawText(COL2, y, field.value, FIXEDWIDTH) -- NOTE: FIXEDWIDTH unknown....
372-
-- lcd.drawText(134+6*charIndex, y, string.sub(field.value, charIndex, charIndex), FIXEDWIDTH + attr) -- NOTE: FIXEDWIDTH unknown....
373373
lcd.drawText(COL2, y, field.value, attr)
374374
lcd.drawText(COL2+6*(charIndex-1), y, string.sub(field.value, charIndex, charIndex), attr)
375375
else
@@ -491,7 +491,7 @@ local functions = {
491491

492492
local function createDeviceField() -- put other device in the field list
493493
fields[fields_count+2+#devices] = fields[backButtonId]
494-
backButtonId = fields_count+2+#devices
494+
backButtonId = fields_count+2+#devices -- move back button to the end of the list, so it will always show up at the bottom.
495495
for i=1, #devices do
496496
if devices[i].id == deviceId then
497497
fields[fields_count+1+i] = {id = fields_count+1+i, name=devices[i].name, parent = 255, type=15}
@@ -559,11 +559,15 @@ local function parseElrsInfoMessage(data)
559559
fieldChunk = 0
560560
return
561561
end
562+
562563
local badPkt = data[3]
563564
local goodPkt = (data[4]*256) + data[5]
564-
goodBadPkt = tostring(badPkt) .. "/" .. tostring(goodPkt)
565565
elrsFlags = data[6]
566-
elrsFlagsInfo = elrsFlags ~= 0 and fieldGetString(data, 7) or nil
566+
567+
local state = (bit32.btest(elrsFlags, 1) and " C") or " -"
568+
569+
goodBadPkt = tostring(badPkt) .. "/" .. tostring(goodPkt) .. state
570+
elrsFlagsInfo = fieldGetString(data, 7)
567571
end
568572

569573
local function refreshNext()
@@ -591,7 +595,7 @@ local function refreshNext()
591595
elseif time > fieldTimeout and not edit then
592596
if allParamsLoaded < 1 or statusComplete == 0 then
593597
crossfireTelemetryPush(0x2C, { deviceId, handsetId, fieldId, fieldChunk })
594-
fieldTimeout = time + 300 -- 3s
598+
fieldTimeout = time + 50 -- 0.5s
595599
end
596600
end
597601

@@ -605,26 +609,47 @@ local function refreshNext()
605609
end
606610
linkstatTimeout = time + 100
607611
end
612+
if time > titleShowWarnTimeout then
613+
if elrsFlags > 3 and titleShowWarn == false then --if elrsFlags bit set is bit higher than bit 0 and bit 1, it is warning flags
614+
titleShowWarn = true
615+
else
616+
titleShowWarn = false
617+
end
618+
titleShowWarnTimeout = time + 100
619+
end
608620
end
609621

610622
local function lcd_title()
611-
local title = (allParamsLoaded == 1 or elrsFlags > 0) and deviceName or "Loading..."
623+
local title = allParamsLoaded == 1 and deviceName or "Loading..."
624+
lcd.clear()
625+
612626
if lcdIsColor then
613627
-- Color screen
614628
local EBLUE = lcd.RGB(0x43, 0x61, 0xAA)
615629
local EGREEN = lcd.RGB(0x9f, 0xc7, 0x6f)
630+
local EGREY1 = lcd.RGB(0x91, 0xb2, 0xc9)
631+
local EGREY2 = lcd.RGB(0x6f, 0x62, 0x7f)
616632
local barHeight = 30
617633

618-
lcd.clear()
619634
-- Field display area (white w/ 2px green border)
620635
lcd.setColor(CUSTOM_COLOR, EGREEN)
621636
lcd.drawRectangle(0, 0, LCD_W, LCD_H, CUSTOM_COLOR)
622637
lcd.drawRectangle(1, 0, LCD_W - 2, LCD_H - 1, CUSTOM_COLOR)
623638
-- title bar
624639
lcd.drawFilledRectangle(0, 0, LCD_W, barHeight, CUSTOM_COLOR)
640+
lcd.setColor(CUSTOM_COLOR, EGREY1)
641+
lcd.drawFilledRectangle(LCD_W - textSize, 0, textSize, barHeight, CUSTOM_COLOR)
642+
lcd.setColor(CUSTOM_COLOR, EGREY2)
643+
lcd.drawRectangle(LCD_W - textSize, 0, textSize, barHeight - 1, CUSTOM_COLOR)
644+
lcd.drawRectangle(LCD_W - textSize, 1 , textSize - 1, barHeight - 2, CUSTOM_COLOR) -- left and bottom line only 1px, make it look bevelled
625645
lcd.setColor(CUSTOM_COLOR, BLACK)
626-
lcd.drawText(textXoffset+1, 4, title, CUSTOM_COLOR)
627-
lcd.drawText(LCD_W-3, 4, goodBadPkt, RIGHT + BOLD + CUSTOM_COLOR)
646+
if titleShowWarn == false then
647+
lcd.drawText(textXoffset + 1, 4, title, CUSTOM_COLOR)
648+
lcd.drawText(LCD_W - 5, 4, goodBadPkt, RIGHT + BOLD + CUSTOM_COLOR)
649+
else
650+
lcd.drawText(textXoffset + 1, 4, elrsFlagsInfo, CUSTOM_COLOR)
651+
lcd.drawText(LCD_W - textSize - 5, 4, tostring(elrsFlags), RIGHT + BOLD + CUSTOM_COLOR)
652+
end
628653
-- progress bar
629654
if allParamsLoaded ~= 1 and fields_count > 0 then
630655
local barW = (COL2-4)*fieldId/fields_count
@@ -637,23 +662,31 @@ local function lcd_title()
637662
-- B&W screen
638663
local barHeight = 9
639664

640-
lcd.clear()
641-
lcd.drawText(LCD_W, 1, goodBadPkt, RIGHT)
642-
-- keep the title this way to keep the script from error when module is not set correctly
665+
if titleShowWarn == false then
666+
lcd.drawText(LCD_W - 1, 1, goodBadPkt, RIGHT)
667+
lcd.drawLine(LCD_W - 10, 0, LCD_W - 10, barHeight-1, SOLID, INVERS)
668+
else
669+
lcd.drawText(LCD_W, 1, tostring(elrsFlags), RIGHT)
670+
end
671+
643672
if allParamsLoaded ~= 1 and fields_count > 0 then
644673
lcd.drawFilledRectangle(COL2, 0, LCD_W, barHeight, GREY_DEFAULT)
645674
lcd.drawGauge(0, 0, COL2, barHeight, fieldId, fields_count, 0)
646675
else
647676
lcd.drawFilledRectangle(0, 0, LCD_W, barHeight, GREY_DEFAULT)
648-
lcd.drawText(textXoffset, 1, title, INVERS)
677+
if titleShowWarn == false then
678+
lcd.drawText(textXoffset, 1, title, INVERS)
679+
else
680+
lcd.drawText(textXoffset, 1, elrsFlagsInfo, INVERS)
681+
end
649682
end
650683
end
651684
end
652685

653686

654687
local function lcd_warn()
655-
lcd.drawText(textSize*3,textSize*2,tostring(elrsFlags).." : "..elrsFlagsInfo,0)
656-
lcd.drawText(textSize*10,textSize*6,"ok",BLINK + INVERS)
688+
lcd.drawText(textSize*3, textSize*2, tostring(elrsFlags).." : "..elrsFlagsInfo, 0)
689+
lcd.drawText(textSize*10, textSize*6, "ok", BLINK + INVERS)
657690
end
658691

659692
local function handleDevicePageEvent(event)
@@ -680,7 +713,7 @@ local function handleDevicePageEvent(event)
680713
fields[backButtonId].parent = 255
681714
end
682715
elseif event == EVT_VIRTUAL_ENTER then -- toggle editing/selecting current field
683-
if elrsFlags > 0 then
716+
if elrsFlags > 0x1F then
684717
elrsFlags = 0
685718
crossfireTelemetryPush(0x2D, { deviceId, handsetId, 0x2E, 0x00 })
686719
else
@@ -733,8 +766,7 @@ local function runDevicePage(event)
733766
if #devices > 1 then -- show other device folder
734767
fields[fields_count+1].parent = 0
735768
end
736-
737-
if elrsFlags > 0 then
769+
if elrsFlags > 0x1F then
738770
lcd_warn()
739771
else
740772
for y = 1, maxLineIndex+1 do
@@ -794,14 +826,14 @@ local function runPopupPage(event)
794826
return 0
795827
end
796828

797-
local function setLCDvar()
829+
local function setLCDvar() --set constant value depending on LCD resolution
798830
lcdIsColor = lcd.RGB ~= nil
799831
if LCD_W == 480 then
800832
COL2 = 240
801833
maxLineIndex = 10
802834
textXoffset = 3
803835
textYoffset = 10
804-
textSize = 22
836+
textSize = 22 --textSize is actually referring to the text Height
805837
else
806838
if LCD_W == 212 then
807839
COL2 = 110
@@ -821,7 +853,7 @@ local function setMock()
821853
if string.sub(rv, -5) ~= "-simu" then return end
822854
local mock = loadScript("mockup/elrsmock.lua")
823855
if mock == nil then return end
824-
fields, goodBadPkt = mock(), "0/500"
856+
fields, goodBadPkt = mock(), "0/500 C"
825857
fields_count = #fields - 1
826858
fieldId = #fields - 3
827859
end

src/src/rx_main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ bool ICACHE_RAM_ATTR HandleSendTelemetryResponse()
298298
// and must be inverted on the TX side. Positive values are used
299299
// so save a bit to encode which antenna is in use
300300
Radio.TXdataBuffer[2] = crsf.LinkStatistics.uplink_RSSI_1 | (antenna << 7);
301-
Radio.TXdataBuffer[3] = crsf.LinkStatistics.uplink_RSSI_2;
301+
Radio.TXdataBuffer[3] = crsf.LinkStatistics.uplink_RSSI_2 | (connectionHasModelMatch << 7);
302302
Radio.TXdataBuffer[4] = crsf.LinkStatistics.uplink_SNR;
303303
Radio.TXdataBuffer[5] = crsf.LinkStatistics.uplink_Link_quality;
304304
Radio.TXdataBuffer[6] = MspReceiver.GetCurrentConfirm() ? 1 : 0;

src/src/tx_main.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ LQCALC<10> LQCalc;
7575

7676
volatile bool busyTransmitting;
7777
static volatile bool ModelUpdatePending;
78-
78+
volatile bool connectionHasModelMatch = true;
7979

8080
bool InBindingMode = false;
8181
uint8_t BindingPackage[5];
@@ -257,15 +257,16 @@ void ICACHE_RAM_ATTR ProcessTLMpacket()
257257
{
258258
case ELRS_TELEMETRY_TYPE_LINK:
259259
// Antenna is the high bit in the RSSI_1 value
260-
crsf.LinkStatistics.active_antenna = Radio.RXdataBuffer[2] >> 7;
261260
// RSSI received is signed, inverted polarity (positive value = -dBm)
262261
// OpenTX's value is signed and will display +dBm and -dBm properly
263262
crsf.LinkStatistics.uplink_RSSI_1 = -(Radio.RXdataBuffer[2] & 0x7f);
264-
crsf.LinkStatistics.uplink_RSSI_2 = -(Radio.RXdataBuffer[3]);
263+
crsf.LinkStatistics.uplink_RSSI_2 = -(Radio.RXdataBuffer[3] & 0x7f);
265264
crsf.LinkStatistics.uplink_SNR = Radio.RXdataBuffer[4];
266265
crsf.LinkStatistics.uplink_Link_quality = Radio.RXdataBuffer[5];
267266
crsf.LinkStatistics.downlink_SNR = Radio.LastPacketSNR;
268267
crsf.LinkStatistics.downlink_RSSI = Radio.LastPacketRSSI;
268+
crsf.LinkStatistics.active_antenna = Radio.RXdataBuffer[2] >> 7;
269+
connectionHasModelMatch = Radio.RXdataBuffer[3] >> 7;
269270
// -- uplink_TX_Power is updated when sending to the handset, so it updates when missing telemetry
270271
// -- rf_mode is updated when we change rates
271272
// -- downlink_Link_quality is updated before the LQ period is incremented
@@ -621,6 +622,7 @@ static void UpdateConnectDisconnectStatus()
621622
else
622623
{
623624
connectionState = disconnected;
625+
connectionHasModelMatch = true;
624626
}
625627
}
626628

0 commit comments

Comments
 (0)