Skip to content

Commit

Permalink
Merge pull request #10451 from iNavFlight/MrD_mLRS-MSP-message
Browse files Browse the repository at this point in the history
  • Loading branch information
MrD-RC authored Nov 10, 2024
2 parents 7f9a23d + 619948e commit ef35225
Show file tree
Hide file tree
Showing 14 changed files with 232 additions and 80 deletions.
2 changes: 1 addition & 1 deletion docs/Settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -5178,7 +5178,7 @@ Value below which Crossfire SNR Alarm pops-up. (dB)

| Default | Min | Max |
| --- | --- | --- |
| 4 | -20 | 10 |
| 4 | -20 | 99 |

---

Expand Down
8 changes: 4 additions & 4 deletions src/main/cms/cms_menu_osd.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,10 @@ static const OSD_Entry menuCrsfRxEntries[]=
OSD_SETTING_ENTRY("LQ ALARM LEVEL", SETTING_OSD_LINK_QUALITY_ALARM),
OSD_SETTING_ENTRY("SNR ALARM LEVEL", SETTING_OSD_SNR_ALARM),
OSD_SETTING_ENTRY("RX SENSITIVITY", SETTING_OSD_RSSI_DBM_MIN),
OSD_ELEMENT_ENTRY("RX RSSI DBM", OSD_CRSF_RSSI_DBM),
OSD_ELEMENT_ENTRY("RX LQ", OSD_CRSF_LQ),
OSD_ELEMENT_ENTRY("RX SNR ALARM", OSD_CRSF_SNR_DB),
OSD_ELEMENT_ENTRY("TX POWER", OSD_CRSF_TX_POWER),
OSD_ELEMENT_ENTRY("RX RSSI DBM", OSD_RSSI_DBM),
OSD_ELEMENT_ENTRY("RX LQ", OSD_LQ_UPLINK),
OSD_ELEMENT_ENTRY("RX SNR ALARM", OSD_SNR_DB),
OSD_ELEMENT_ENTRY("TX POWER", OSD_TX_POWER_UPLINK),

OSD_BACK_AND_END_ENTRY,
};
Expand Down
5 changes: 5 additions & 0 deletions src/main/common/streambuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ uint8_t sbufReadU8(sbuf_t *src)
return *src->ptr++;
}

int8_t sbufReadI8(sbuf_t *src)
{
return *src->ptr++;
}

uint16_t sbufReadU16(sbuf_t *src)
{
uint16_t ret;
Expand Down
1 change: 1 addition & 0 deletions src/main/common/streambuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ void sbufWriteU16BigEndian(sbuf_t *dst, uint16_t val);
void sbufWriteU32BigEndian(sbuf_t *dst, uint32_t val);

uint8_t sbufReadU8(sbuf_t *src);
int8_t sbufReadI8(sbuf_t *src);
uint16_t sbufReadU16(sbuf_t *src);
uint32_t sbufReadU32(sbuf_t *src);
void sbufReadData(const sbuf_t *dst, void *data, int len);
Expand Down
2 changes: 2 additions & 0 deletions src/main/drivers/osd_symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@
#define SYM_AH_CH_CENTER 0x166 // 358 Crossair center
#define SYM_FLIGHT_DIST_REMAINING 0x167 // 359 Flight distance reminaing
#define SYM_ODOMETER 0x168 // 360 Odometer
#define SYM_RX_BAND 0x169 // 361 RX Band
#define SYM_RX_MODE 0x16A // 362 RX Mode

#define SYM_AH_CH_TYPE3 0x190 // 400 to 402, crosshair 3
#define SYM_AH_CH_TYPE4 0x193 // 403 to 405, crosshair 4
Expand Down
56 changes: 53 additions & 3 deletions src/main/fc/fc_msp.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "common/color.h"
#include "common/maths.h"
#include "common/streambuf.h"
#include "common/string_light.h"
#include "common/bitarray.h"
#include "common/time.h"
#include "common/utils.h"
Expand Down Expand Up @@ -215,7 +216,7 @@ static void mspSerialPassthroughFn(serialPort_t *serialPort)

static void mspFcSetPassthroughCommand(sbuf_t *dst, sbuf_t *src, mspPostProcessFnPtr *mspPostProcessFn)
{
const unsigned int dataSize = sbufBytesRemaining(src);
const unsigned int dataSize = sbufBytesRemaining(src); /* Payload size in Bytes */

if (dataSize == 0) {
// Legacy format
Expand Down Expand Up @@ -1807,7 +1808,7 @@ static void mspFcWaypointOutCommand(sbuf_t *dst, sbuf_t *src)
#ifdef USE_FLASHFS
static void mspFcDataFlashReadCommand(sbuf_t *dst, sbuf_t *src)
{
const unsigned int dataSize = sbufBytesRemaining(src);
const unsigned int dataSize = sbufBytesRemaining(src); /* Payload size in Bytes */
uint16_t readLength;

const uint32_t readAddress = sbufReadU32(src);
Expand All @@ -1831,7 +1832,7 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
uint8_t tmp_u8;
uint16_t tmp_u16;

const unsigned int dataSize = sbufBytesRemaining(src);
const unsigned int dataSize = sbufBytesRemaining(src); /* Payload size in Bytes */

switch (cmdMSP) {
case MSP_SELECT_SETTING:
Expand Down Expand Up @@ -1861,6 +1862,8 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
}
rxMspFrameReceive(frame, channelCount);
}

return MSP_RESULT_NO_REPLY;
}
break;
#endif
Expand Down Expand Up @@ -2917,6 +2920,53 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
return MSP_RESULT_ERROR;
break;

#ifdef USE_RX_MSP
case MSP2_COMMON_SET_MSP_RC_LINK_STATS: {
if (dataSize >= 7) {
uint8_t sublinkID = sbufReadU8(src); // Sublink ID
sbufReadU8(src); // Valid link (Failsafe backup)
if (sublinkID == 0) {
setRSSIFromMSP_RC(sbufReadU8(src)); // RSSI %
rxLinkStatistics.uplinkRSSI = -sbufReadU8(src);
rxLinkStatistics.downlinkLQ = sbufReadU8(src);
rxLinkStatistics.uplinkLQ = sbufReadU8(src);
rxLinkStatistics.uplinkSNR = sbufReadI8(src);
}

return MSP_RESULT_NO_REPLY;
} else
return MSP_RESULT_ERROR;
}
break;

case MSP2_COMMON_SET_MSP_RC_INFO: {
if (dataSize >= 15) {
uint8_t sublinkID = sbufReadU8(src);

if (sublinkID == 0) {
rxLinkStatistics.uplinkTXPower = sbufReadU16(src);
rxLinkStatistics.downlinkTXPower = sbufReadU16(src);

for (int i = 0; i < 4; i++) {
rxLinkStatistics.band[i] = sbufReadU8(src);
}

sl_toupperptr(rxLinkStatistics.band);

for (int i = 0; i < 6; i++) {
rxLinkStatistics.mode[i] = sbufReadU8(src);
}

sl_toupperptr(rxLinkStatistics.mode);
}

return MSP_RESULT_NO_REPLY;
} else
return MSP_RESULT_ERROR;
}
break;
#endif

case MSP_SET_FAILSAFE_CONFIG:
if (dataSize == 20) {
failsafeConfigMutable()->failsafe_delay = sbufReadU8(src);
Expand Down
12 changes: 6 additions & 6 deletions src/main/fc/settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3371,35 +3371,35 @@ groups:
min: -550
max: 1250
- name: osd_snr_alarm
condition: USE_SERIALRX_CRSF
condition: USE_SERIALRX_CRSF || USE_RX_MSP
description: "Value below which Crossfire SNR Alarm pops-up. (dB)"
default_value: 4
field: snr_alarm
min: -20
max: 10
max: 99
- name: osd_link_quality_alarm
condition: USE_SERIALRX_CRSF
condition: USE_SERIALRX_CRSF || USE_RX_MSP
description: "LQ % indicator blinks below this value. For Crossfire use 70%, for Tracer use 50%"
default_value: 70
field: link_quality_alarm
min: 0
max: 100
- name: osd_rssi_dbm_alarm
condition: USE_SERIALRX_CRSF
condition: USE_SERIALRX_CRSF || USE_RX_MSP
description: "RSSI dBm indicator blinks below this value [dBm]. 0 disables this alarm"
default_value: 0
field: rssi_dbm_alarm
min: -130
max: 0
- name: osd_rssi_dbm_max
condition: USE_SERIALRX_CRSF
condition: USE_SERIALRX_CRSF || USE_RX_MSP
description: "RSSI dBm upper end of curve. Perfect rssi (max) = 100%"
default_value: -30
field: rssi_dbm_max
min: -50
max: 0
- name: osd_rssi_dbm_min
condition: USE_SERIALRX_CRSF
condition: USE_SERIALRX_CRSF || USE_RX_MSP
description: "RSSI dBm lower end of curve or RX sensitivity level. Worst rssi (min) = 0%"
default_value: -120
field: rssi_dbm_min
Expand Down
106 changes: 79 additions & 27 deletions src/main/io/osd.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ static bool osdDisplayHasCanvas;

#define AH_MAX_PITCH_DEFAULT 20 // Specify default maximum AHI pitch value displayed (degrees)

PG_REGISTER_WITH_RESET_TEMPLATE(osdConfig_t, osdConfig, PG_OSD_CONFIG, 13);
PG_REGISTER_WITH_RESET_FN(osdLayoutsConfig_t, osdLayoutsConfig, PG_OSD_LAYOUTS_CONFIG, 2);
PG_REGISTER_WITH_RESET_TEMPLATE(osdConfig_t, osdConfig, PG_OSD_CONFIG, 14);
PG_REGISTER_WITH_RESET_FN(osdLayoutsConfig_t, osdLayoutsConfig, PG_OSD_LAYOUTS_CONFIG, 3);

void osdStartedSaveProcess(void) {
savingSettings = true;
Expand Down Expand Up @@ -2467,15 +2467,15 @@ static bool osdDrawSingleElement(uint8_t item)
return true;
}

#if defined(USE_SERIALRX_CRSF)
case OSD_CRSF_RSSI_DBM:
#if defined(USE_SERIALRX_CRSF) || defined(USE_RX_MSP)
case OSD_RSSI_DBM:
{
int16_t rssi = rxLinkStatistics.uplinkRSSI;
buff[0] = (rxLinkStatistics.activeAntenna == 0) ? SYM_RSSI : SYM_2RSS; // Separate symbols for each antenna
if (rssi <= -100) {
tfp_sprintf(buff + 1, "%4d%c", rssi, SYM_DBM);
} else {
tfp_sprintf(buff + 1, "%3d%c%c", rssi, SYM_DBM, ' ');
tfp_sprintf(buff + 1, " %3d%c", rssi, SYM_DBM);
}
if (!failsafeIsReceivingRxData()){
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
Expand All @@ -2484,19 +2484,15 @@ static bool osdDrawSingleElement(uint8_t item)
}
break;
}
case OSD_CRSF_LQ:
case OSD_LQ_UPLINK:
{
buff[0] = SYM_LQ;
int16_t statsLQ = rxLinkStatistics.uplinkLQ;
int16_t scaledLQ = scaleRange(constrain(statsLQ, 0, 100), 0, 100, 170, 300);
switch (osdConfig()->crsf_lq_format) {
case OSD_CRSF_LQ_TYPE1:
if (!failsafeIsReceivingRxData()) {
tfp_sprintf(buff+1, "%3d", 0);
} else {
tfp_sprintf(buff+1, "%3d", rxLinkStatistics.uplinkLQ);
}
break;
uint8_t lqFormat = osdConfig()->crsf_lq_format;

if (rxConfig()->receiverType == RX_TYPE_MSP)
lqFormat = OSD_CRSF_LQ_TYPE1;

switch (lqFormat) {
case OSD_CRSF_LQ_TYPE2:
if (!failsafeIsReceivingRxData()) {
tfp_sprintf(buff+1, "%s:%3d", " ", 0);
Expand All @@ -2508,9 +2504,18 @@ static bool osdDrawSingleElement(uint8_t item)
if (!failsafeIsReceivingRxData()) {
tfp_sprintf(buff+1, "%3d", 0);
} else {
int16_t scaledLQ = scaleRange(constrain(rxLinkStatistics.uplinkLQ, 0, 100), 0, 100, 170, 300);
tfp_sprintf(buff+1, "%3d", rxLinkStatistics.rfMode >= 2 ? scaledLQ : rxLinkStatistics.uplinkLQ);
}
break;
case OSD_CRSF_LQ_TYPE1:
default:
if (!failsafeIsReceivingRxData()) {
tfp_sprintf(buff+1, "%3d", 0);
} else {
tfp_sprintf(buff+1, "%3d", rxLinkStatistics.uplinkLQ);
}
break;
}
if (!failsafeIsReceivingRxData()) {
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
Expand All @@ -2520,7 +2525,24 @@ static bool osdDrawSingleElement(uint8_t item)
break;
}

case OSD_CRSF_SNR_DB:
case OSD_LQ_DOWNLINK:
{
buff[0] = SYM_LQ;
if (!failsafeIsReceivingRxData()) {
tfp_sprintf(buff+1, "%3d%c", 0, SYM_AH_DECORATION_DOWN);
} else {
tfp_sprintf(buff+1, "%3d%c", rxLinkStatistics.downlinkLQ, SYM_AH_DECORATION_DOWN);
}

if (!failsafeIsReceivingRxData()) {
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
} else if (rxLinkStatistics.downlinkLQ < osdConfig()->link_quality_alarm) {
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
}
break;
}

case OSD_SNR_DB:
{
static pt1Filter_t snrFilterState;
static timeMs_t snrUpdated = 0;
Expand All @@ -2539,23 +2561,49 @@ static bool osdDrawSingleElement(uint8_t item)
}
} else if (snrFiltered <= osdConfig()->snr_alarm) {
buff[0] = SYM_SNR;
if (snrFiltered <= -10) {
if (snrFiltered <= -10 || snrFiltered >= 10) {
tfp_sprintf(buff + 1, "%3d%c", snrFiltered, SYM_DB);
} else {
tfp_sprintf(buff + 1, "%2d%c%c", snrFiltered, SYM_DB, ' ');
tfp_sprintf(buff + 1, " %2d%c", snrFiltered, SYM_DB);
}
}
break;
}

case OSD_CRSF_TX_POWER:
case OSD_TX_POWER_UPLINK:
{
if (!failsafeIsReceivingRxData())
tfp_sprintf(buff, "%s%c", " ", SYM_BLANK);
tfp_sprintf(buff, "%s%c", " ", SYM_MW);
else
tfp_sprintf(buff, "%4d%c", rxLinkStatistics.uplinkTXPower, SYM_MW);
break;
}

case OSD_RX_POWER_DOWNLINK:
{
if (!failsafeIsReceivingRxData())
tfp_sprintf(buff, "%s%c%c", " ", SYM_MW, SYM_AH_DECORATION_DOWN);
else
tfp_sprintf(buff, "%4d%c%c", rxLinkStatistics.downlinkTXPower, SYM_MW, SYM_AH_DECORATION_DOWN);
break;
}
case OSD_RX_BAND:
displayWriteChar(osdDisplayPort, elemPosX++, elemPosY, SYM_RX_BAND);
strcat(buff, rxLinkStatistics.band);
if (strlen(rxLinkStatistics.band) < 4)
for (uint8_t i = strlen(rxLinkStatistics.band); i < 4; i++)
buff[i] = ' ';
buff[4] = '\0';
break;

case OSD_RX_MODE:
displayWriteChar(osdDisplayPort, elemPosX++, elemPosY, SYM_RX_MODE);
strcat(buff, rxLinkStatistics.mode);
if (strlen(rxLinkStatistics.mode) < 6)
for (uint8_t i = strlen(rxLinkStatistics.mode); i < 6; i++)
buff[i] = ' ';
buff[6] = '\0';
break;
#endif

case OSD_FORMATION_FLIGHT:
Expand Down Expand Up @@ -3996,7 +4044,7 @@ PG_RESET_TEMPLATE(osdConfig_t, osdConfig,
.adsb_distance_alert = SETTING_OSD_ADSB_DISTANCE_ALERT_DEFAULT,
.adsb_ignore_plane_above_me_limit = SETTING_OSD_ADSB_IGNORE_PLANE_ABOVE_ME_LIMIT_DEFAULT,
#endif
#ifdef USE_SERIALRX_CRSF
#if defined(USE_SERIALRX_CRSF) || defined(USE_RX_MSP)
.snr_alarm = SETTING_OSD_SNR_ALARM_DEFAULT,
.crsf_lq_format = SETTING_OSD_CRSF_LQ_FORMAT_DEFAULT,
.link_quality_alarm = SETTING_OSD_LINK_QUALITY_ALARM_DEFAULT,
Expand Down Expand Up @@ -4147,11 +4195,15 @@ void pgResetFn_osdLayoutsConfig(osdLayoutsConfig_t *osdLayoutsConfig)
osdLayoutsConfig->item_pos[0][OSD_PILOT_LOGO] = OSD_POS(20, 3);
osdLayoutsConfig->item_pos[0][OSD_VTX_CHANNEL] = OSD_POS(8, 6);

#ifdef USE_SERIALRX_CRSF
osdLayoutsConfig->item_pos[0][OSD_CRSF_RSSI_DBM] = OSD_POS(23, 12);
osdLayoutsConfig->item_pos[0][OSD_CRSF_LQ] = OSD_POS(23, 11);
osdLayoutsConfig->item_pos[0][OSD_CRSF_SNR_DB] = OSD_POS(24, 9);
osdLayoutsConfig->item_pos[0][OSD_CRSF_TX_POWER] = OSD_POS(24, 10);
#if defined(USE_SERIALRX_CRSF) || defined(USE_RX_MSP)
osdLayoutsConfig->item_pos[0][OSD_RSSI_DBM] = OSD_POS(23, 12);
osdLayoutsConfig->item_pos[0][OSD_LQ_UPLINK] = OSD_POS(23, 10);
osdLayoutsConfig->item_pos[0][OSD_LQ_DOWNLINK] = OSD_POS(23, 11);
osdLayoutsConfig->item_pos[0][OSD_SNR_DB] = OSD_POS(24, 9);
osdLayoutsConfig->item_pos[0][OSD_TX_POWER_UPLINK] = OSD_POS(24, 10);
osdLayoutsConfig->item_pos[0][OSD_RX_POWER_DOWNLINK] = OSD_POS(24, 11);
osdLayoutsConfig->item_pos[0][OSD_RX_BAND] = OSD_POS(24, 12);
osdLayoutsConfig->item_pos[0][OSD_RX_MODE] = OSD_POS(24, 13);
#endif

osdLayoutsConfig->item_pos[0][OSD_ONTIME] = OSD_POS(23, 8);
Expand Down
Loading

0 comments on commit ef35225

Please sign in to comment.