diff --git a/radio/src/audio_arm.cpp b/radio/src/audio_arm.cpp index 089a604e3..c20dd154c 100644 --- a/radio/src/audio_arm.cpp +++ b/radio/src/audio_arm.cpp @@ -201,6 +201,8 @@ const char * audioFilenames[] = { "rssi_org", "rssi_red", "swr_red", + "rx_org", + "rx_red", "telemko", "telemok" }; @@ -1064,12 +1066,14 @@ void audioEvent(uint8_t e, uint16_t f) case AU_TIMER_30: audioQueue.playTone(BEEP_DEFAULT_FREQ+150, 120, 20, PLAY_REPEAT(2)|PLAY_NOW); break; + case AU_RXBATT_ORANGE: case AU_A1_ORANGE: case AU_A2_ORANGE: case AU_A3_ORANGE: case AU_A4_ORANGE: audioQueue.playTone(BEEP_DEFAULT_FREQ+600, 200, 20, PLAY_NOW); break; + case AU_RXBATT_RED: case AU_A1_RED: case AU_A2_RED: case AU_A3_RED: diff --git a/radio/src/audio_arm.h b/radio/src/audio_arm.h index b0dccb080..756352c3c 100644 --- a/radio/src/audio_arm.h +++ b/radio/src/audio_arm.h @@ -292,6 +292,8 @@ void audioStart(); #define AUDIO_RSSI_ORANGE() audioEvent(AU_RSSI_ORANGE) #define AUDIO_RSSI_RED() audioEvent(AU_RSSI_RED) #define AUDIO_SWR_RED() audioEvent(AU_SWR_RED) +#define AUDIO_RXBATT_ORANGE() audioEvent(AU_RXBATT_ORANGE) +#define AUDIO_RXBATT_RED() audioEvent(AU_RXBATT_RED) #define AUDIO_TELEMETRY_LOST() audioEvent(AU_TELEMETRY_LOST) #define AUDIO_TELEMETRY_BACK() audioEvent(AU_TELEMETRY_BACK) diff --git a/radio/src/gui/menu_model.cpp b/radio/src/gui/menu_model.cpp index 36f3bde08..6f17aeb1e 100644 --- a/radio/src/gui/menu_model.cpp +++ b/radio/src/gui/menu_model.cpp @@ -5348,6 +5348,11 @@ void menuModelCustomScripts(uint8_t event) #endif enum menuModelTelemetryItems { +#if defined(CPUARM) + ITEM_TELEMETRY_RXBATT_LABEL, + ITEM_TELEMETRY_RXBATT_ALARM1, + ITEM_TELEMETRY_RXBATT_ALARM2, +#endif ITEM_TELEMETRY_A1_LABEL, ITEM_TELEMETRY_A1_RANGE, ITEM_TELEMETRY_A1_OFFSET, @@ -5445,35 +5450,41 @@ enum menuModelTelemetryItems { #define TELEM_SCRTYPE_COL (10*FW) #endif -#if defined(PCBTARANIS) - #define CHANNEL_ROWS (uint8_t)-1, 1, 0, 0, 0 - #define RSSI_ROWS (uint8_t)-1, 0, 0 +#if defined(CPUARM) + #define RXBATT_ROWS LABEL(RXBATT), 0, 0, #else - #define CHANNEL_ROWS (uint8_t)-1, 1, 0, 2, 2 - #define RSSI_ROWS (uint8_t)-1, 1, 1 + #define RXBATT_ROWS +#endif + +#if defined(PCBTARANIS) + #define CHANNEL_ROWS LABEL(CHANNEL), 1, 0, 0, 0 + #define RSSI_ROWS LABEL(RSSI), 0, 0 +#else + #define CHANNEL_ROWS LABEL(CHANNEL), 1, 0, 2, 2 + #define RSSI_ROWS LABEL(RSSI), 1, 1 #endif #if defined(GAUGES) - #define SCREEN_TYPE_ROWS 0 + #define SCREEN_TYPE_ROWS 0 #else - #define SCREEN_TYPE_ROWS (uint8_t)-1 + #define SCREEN_TYPE_ROWS LABEL(SCREEN) #endif #if defined(PCBSTD) - #define VARIO_RANGE_ROWS 1 + #define VARIO_RANGE_ROWS 1 #else - #define VARIO_RANGE_ROWS 3 + #define VARIO_RANGE_ROWS 3 #endif #if defined(FAS_OFFSET) || !defined(CPUM64) - #define IF_FAS_OFFSET(x) x, + #define IF_FAS_OFFSET(x) x, #else #define IF_FAS_OFFSET(x) #endif void menuModelTelemetry(uint8_t event) { - MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, ITEM_TELEMETRY_MAX+1, {0, CHANNEL_ROWS, CHANNEL_ROWS, CASE_CPUARM(CHANNEL_ROWS) CASE_CPUARM(CHANNEL_ROWS) RSSI_ROWS, USRDATA_LINES 0, 0, IF_FAS_OFFSET(0) CASE_CPUARM(0) CASE_VARIO(LABEL(Vario)) CASE_VARIO(0) CASE_VARIO(VARIO_RANGE_ROWS) CASE_PCBTARANIS(LABEL(TopBar)) CASE_PCBTARANIS(0) SCREEN_TYPE_ROWS, 2, 2, 2, 2, SCREEN_TYPE_ROWS, 2, 2, 2, 2, CASE_CPUARM(SCREEN_TYPE_ROWS) CASE_CPUARM(2) CASE_CPUARM(2) CASE_CPUARM(2) CASE_CPUARM(2) }); + MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, ITEM_TELEMETRY_MAX+1, {0, RXBATT_ROWS CHANNEL_ROWS, CHANNEL_ROWS, CASE_CPUARM(CHANNEL_ROWS) CASE_CPUARM(CHANNEL_ROWS) RSSI_ROWS, USRDATA_LINES 0, 0, IF_FAS_OFFSET(0) CASE_CPUARM(0) CASE_VARIO(LABEL(Vario)) CASE_VARIO(0) CASE_VARIO(VARIO_RANGE_ROWS) CASE_PCBTARANIS(LABEL(TopBar)) CASE_PCBTARANIS(0) SCREEN_TYPE_ROWS, 2, 2, 2, 2, SCREEN_TYPE_ROWS, 2, 2, 2, 2, CASE_CPUARM(SCREEN_TYPE_ROWS) CASE_CPUARM(2) CASE_CPUARM(2) CASE_CPUARM(2) CASE_CPUARM(2) }); uint8_t sub = m_posVert - 1; @@ -5508,6 +5519,23 @@ void menuModelTelemetry(uint8_t event) FrSkyChannelData & channel = g_model.frsky.channels[ch]; uint8_t dest = TELEM_A1-1+ch; switch (k) { +#if defined(CPUARM) + case ITEM_TELEMETRY_RXBATT_LABEL: + lcd_putsLeft(y, "RxBatt"); + putsTelemetryChannel(TELEM_COL2+6*FW, y, dest, frskyData.analog[TELEM_ANA_RxBatt].value, LEFT); + break; + case ITEM_TELEMETRY_RXBATT_ALARM1: + case ITEM_TELEMETRY_RXBATT_ALARM2: + { + uint8_t alarm = (k==ITEM_TELEMETRY_RXBATT_ALARM1 ? 0 : 1); + lcd_putsLeft(y, (alarm==0 ? STR_LOWALARM : STR_CRITICALALARM)); + putsTelemetryChannel(TELEM_COL2, y, TELEM_RX_VOLTAGE-1, 5*g_model.rxBattAlarms[alarm], LEFT|attr); + if (attr && (s_editMode>0 || p1valdiff)) { + g_model.rxBattAlarms[alarm] = checkIncDec(event, g_model.rxBattAlarms[alarm], 0, 255, EE_MODEL); + } + break; + } +#endif case ITEM_TELEMETRY_A1_LABEL: case ITEM_TELEMETRY_A2_LABEL: #if defined(CPUARM) diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index a9f4cf6c5..2e854f216 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -318,7 +318,7 @@ PACK(typedef struct t_ScriptData { TRAINER_MODULE }; #define MODELDATA_BITMAP char bitmap[LEN_BITMAP_NAME]; - #define MODELDATA_EXTRA uint8_t externalModule; uint8_t trainerMode; ModuleData moduleData[NUM_MODULES+1]; char curveNames[MAX_CURVES][6]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][4]; uint8_t nPotsToWarn; int8_t potPosition[NUM_POTS]; + #define MODELDATA_EXTRA uint8_t externalModule; uint8_t trainerMode; ModuleData moduleData[NUM_MODULES+1]; char curveNames[MAX_CURVES][6]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][4]; uint8_t nPotsToWarn; int8_t potPosition[NUM_POTS]; uint8_t rxBattAlarms[2]; #define LIMITDATA_EXTRA char name[LEN_CHANNEL_NAME]; int8_t curve; #define swstate_t uint16_t #elif defined(PCBSKY9X) @@ -328,7 +328,7 @@ PACK(typedef struct t_ScriptData { TRAINER_MODULE }; #define MODELDATA_BITMAP - #define MODELDATA_EXTRA uint8_t externalModule; ModuleData moduleData[NUM_MODULES+1]; uint8_t nPotsToWarn; int8_t potPosition[NUM_POTS]; + #define MODELDATA_EXTRA uint8_t externalModule; ModuleData moduleData[NUM_MODULES+1]; uint8_t nPotsToWarn; int8_t potPosition[NUM_POTS]; uint8_t rxBattAlarms[2]; #define LIMITDATA_EXTRA #define swstate_t uint8_t #else diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 6dd2f110d..90c8aa879 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -1340,6 +1340,8 @@ enum AUDIO_SOUNDS { AU_RSSI_ORANGE, AU_RSSI_RED, AU_SWR_RED, + AU_RXBATT_ORANGE, + AU_RXBATT_RED, AU_TELEMETRY_LOST, AU_TELEMETRY_BACK, #endif diff --git a/radio/src/telemetry/frsky.cpp b/radio/src/telemetry/frsky.cpp index 06fd308e5..a6f0fd47b 100644 --- a/radio/src/telemetry/frsky.cpp +++ b/radio/src/telemetry/frsky.cpp @@ -127,6 +127,10 @@ void FrskyValueWithMinMax::set(uint8_t value, uint8_t unit) } #if defined(CPUARM) +inline bool rxBattAlarmRaised(uint8_t alarm) +{ + return g_model.rxBattAlarms[alarm] > 0 && frskyData.analog[TELEM_ANA_RxBatt].value < 5*g_model.rxBattAlarms[alarm]; +} inline bool alarmRaised(uint8_t channel, uint8_t idx) { return g_model.frsky.channels[channel].ratio > 0 && g_model.frsky.channels[channel].alarms_value[idx] > 0 && frskyData.analog[channel].value < g_model.frsky.channels[channel].alarms_value[idx]; @@ -252,6 +256,7 @@ NOINLINE void processSerialData(uint8_t data) enum AlarmsCheckSteps { ALARM_SWR_STEP, ALARM_RSSI_STEP, + ALARM_RXBATT_STEP, ALARM_A1_STEP, ALARM_A2_STEP, ALARM_A3_STEP, @@ -340,6 +345,16 @@ void telemetryWakeup() alarmsCheckTime = get_tmr10ms() + 300; /* next check in 3 seconds */ } } + else if (alarmsCheckStep == ALARM_RXBATT_STEP) { + if (rxBattAlarmRaised(1)) { + AUDIO_RXBATT_RED(); + alarmsCheckTime = get_tmr10ms() + 300; /* next check in 3 seconds */ + } + else if (rxBattAlarmRaised(0)) { + AUDIO_RXBATT_ORANGE(); + alarmsCheckTime = get_tmr10ms() + 300; /* next check in 3 seconds */ + } + } else if (alarmsCheckStep == ALARM_A1_STEP) { if (alarmRaised(TELEM_ANA_A1, 1)) { AUDIO_A1_RED();