@@ -117,6 +117,8 @@ FILE_COMPILE_FOR_SPEED
117117#define GFORCE_FILTER_TC 0.2
118118
119119#define DELAYED_REFRESH_RESUME_COMMAND (checkStickPosition(THR_HI) || checkStickPosition(PIT_HI))
120+ #define STATS_PAGE2 (checkStickPosition(ROL_HI))
121+ #define STATS_PAGE1 (checkStickPosition(ROL_LO))
120122
121123#define SPLASH_SCREEN_DISPLAY_TIME 4000 // ms
122124#define ARMED_SCREEN_DISPLAY_TIME 1500 // ms
@@ -156,6 +158,8 @@ typedef struct statistic_s {
156158 int16_t max_current ; // /100
157159 int16_t max_power ; // /100
158160 int16_t min_rssi ;
161+ int16_t min_lq ; // for CRSF
162+ int16_t min_rssi_dbm ; // for CRSF
159163 int32_t max_altitude ;
160164 uint32_t max_distance ;
161165} statistic_t ;
@@ -168,6 +172,7 @@ static bool refreshWaitForResumeCmdRelease;
168172static bool fullRedraw = false;
169173
170174static uint8_t armState ;
175+ static uint8_t statsPagesCheck = 0 ;
171176
172177typedef struct osdMapData_s {
173178 uint32_t scale ;
@@ -528,6 +533,21 @@ static uint16_t osdConvertRSSI(void)
528533 return constrain (getRSSI () * 100 / RSSI_MAX_VALUE , 0 , 99 );
529534}
530535
536+ static uint16_t osdGetLQ (void )
537+ {
538+ int16_t statsLQ = rxLinkStatistics .uplinkLQ ;
539+ int16_t scaledLQ = scaleRange (constrain (statsLQ , 0 , 100 ), 0 , 100 , 170 , 300 );
540+ if (rxLinkStatistics .rfMode == 2 ) {
541+ return scaledLQ ;
542+ } else {
543+ return statsLQ ;
544+ }
545+ }
546+
547+ static uint16_t osdGetdBm (void )
548+ {
549+ return rxLinkStatistics .uplinkRSSI ;
550+ }
531551/**
532552* Displays a temperature postfixed with a symbol depending on the current unit system
533553* @param label to display
@@ -1714,7 +1734,9 @@ static bool osdDrawSingleElement(uint8_t item)
17141734 return true;
17151735 }
17161736
1737+ #if defined(USE_SERIALRX_CRSF )
17171738 case OSD_CRSF_RSSI_DBM :
1739+ {
17181740 if (rxLinkStatistics .activeAnt == 0 ) {
17191741 buff [0 ] = SYM_RSSI ;
17201742 tfp_sprintf (buff + 1 , "%4d%c" , rxLinkStatistics .uplinkRSSI , SYM_DBM );
@@ -1729,12 +1751,12 @@ static bool osdDrawSingleElement(uint8_t item)
17291751 }
17301752 }
17311753 break ;
1732-
1733- #if defined( USE_SERIALRX_CRSF )
1734- case OSD_CRSF_LQ : {
1735- buff [0 ] = SYM_BLANK ;
1736- int16_t statsLQ = rxLinkStatistics .uplinkLQ ;
1737- int16_t scaledLQ = scaleRange (constrain (statsLQ , 0 , 100 ), 0 , 100 , 170 , 300 );
1754+ }
1755+ case OSD_CRSF_LQ :
1756+ {
1757+ buff [0 ] = SYM_BLANK ;
1758+ int16_t statsLQ = rxLinkStatistics .uplinkLQ ;
1759+ int16_t scaledLQ = scaleRange (constrain (statsLQ , 0 , 100 ), 0 , 100 , 170 , 300 );
17381760 if (rxLinkStatistics .rfMode == 2 ) {
17391761 if (osdConfig ()-> crsf_lq_format == OSD_CRSF_LQ_TYPE1 ) {
17401762 tfp_sprintf (buff , "%5d%s" , scaledLQ , "%" );
@@ -1744,9 +1766,9 @@ static bool osdDrawSingleElement(uint8_t item)
17441766 } else {
17451767 if (osdConfig ()-> crsf_lq_format == OSD_CRSF_LQ_TYPE1 ) {
17461768 tfp_sprintf (buff , "%5d%s" , rxLinkStatistics .uplinkLQ , "%" );
1747- } else {
1769+ } else {
17481770 tfp_sprintf (buff , "%d:%3d%s" , rxLinkStatistics .rfMode , rxLinkStatistics .uplinkLQ , "%" );
1749- }
1771+ }
17501772 }
17511773 if (!failsafeIsReceivingRxData ()){
17521774 TEXT_ATTRIBUTES_ADD_BLINK (elemAttr );
@@ -1756,31 +1778,32 @@ static bool osdDrawSingleElement(uint8_t item)
17561778 break ;
17571779 }
17581780
1759- case OSD_CRSF_SNR_DB : {
1760- const char * showsnr = "-20" ;
1761- const char * hidesnr = " " ;
1762- int16_t osdSNR_Alarm = rxLinkStatistics .uplinkSNR ;
1763- if (osdSNR_Alarm <= osdConfig ()-> snr_alarm ) {
1764- buff [0 ] = SYM_SRN ;
1765- tfp_sprintf (buff + 1 , "%3d%c" , rxLinkStatistics .uplinkSNR , SYM_DB );
1766- }
1767- else if (osdSNR_Alarm > osdConfig ()-> snr_alarm ) {
1768- if (cmsInMenu ) {
1769- buff [0 ] = SYM_SRN ;
1770- tfp_sprintf (buff + 1 , "%s%c" , showsnr , SYM_DB );
1771- } else {
1772- buff [0 ] = SYM_BLANK ;
1773- tfp_sprintf (buff + 1 , "%s%c" , hidesnr , SYM_BLANK );
1781+ case OSD_CRSF_SNR_DB :
1782+ {
1783+ const char * showsnr = "-20" ;
1784+ const char * hidesnr = " " ;
1785+ int16_t osdSNR_Alarm = rxLinkStatistics .uplinkSNR ;
1786+ if (osdSNR_Alarm > osdConfig ()-> snr_alarm ) {
1787+ if (cmsInMenu ) {
1788+ buff [0 ] = SYM_SNR ;
1789+ tfp_sprintf (buff + 1 , "%s%c" , showsnr , SYM_DB );
1790+ } else {
1791+ buff [0 ] = SYM_BLANK ;
1792+ tfp_sprintf (buff + 1 , "%s%c" , hidesnr , SYM_BLANK );
1793+ }
1794+ } else if (osdSNR_Alarm <= osdConfig ()-> snr_alarm ) {
1795+ buff [0 ] = SYM_SNR ;
1796+ tfp_sprintf (buff + 1 , "%3d%c" , rxLinkStatistics .uplinkSNR , SYM_DB );
17741797 }
1798+ break ;
17751799 }
1776- break ;
1777- }
1778- #endif
17791800
1780- case OSD_CRSF_TX_POWER : {
1781- tfp_sprintf (buff , "%4d%c" , rxLinkStatistics .uplinkTXPower , SYM_MW );
1782- break ;
1783- }
1801+ case OSD_CRSF_TX_POWER :
1802+ {
1803+ tfp_sprintf (buff , "%4d%c" , rxLinkStatistics .uplinkTXPower , SYM_MW );
1804+ break ;
1805+ }
1806+ #endif
17841807
17851808 case OSD_CROSSHAIRS : // Hud is a sub-element of the crosshair
17861809
@@ -2987,6 +3010,8 @@ static void osdResetStats(void)
29873010 stats .max_speed = 0 ;
29883011 stats .min_voltage = 5000 ;
29893012 stats .min_rssi = 99 ;
3013+ stats .min_lq = 300 ;
3014+ stats .min_rssi_dbm = 0 ;
29903015 stats .max_altitude = 0 ;
29913016}
29923017
@@ -3019,22 +3044,30 @@ static void osdUpdateStats(void)
30193044 if (stats .min_rssi > value )
30203045 stats .min_rssi = value ;
30213046
3047+ value = osdGetLQ ();
3048+ if (stats .min_lq > value )
3049+ stats .min_lq = value ;
3050+
3051+ value = osdGetdBm ();
3052+ if (stats .min_rssi_dbm > value )
3053+ stats .min_rssi_dbm = value ;
3054+
30223055 stats .max_altitude = MAX (stats .max_altitude , osdGetAltitude ());
30233056}
30243057
3025- /* Attention: NTSC screen only has 12 fully visible lines - it is FULL now! */
3026- static void osdShowStats (void )
3058+ static void osdShowStatsPage1 (void )
30273059{
30283060 const char * disarmReasonStr [DISARM_REASON_COUNT ] = { "UNKNOWN" , "TIMEOUT" , "STICKS" , "SWITCH" , "SWITCH" , "KILLSW" , "FAILSAFE" , "NAV SYS" };
30293061 uint8_t top = 1 ; /* first fully visible line */
30303062 const uint8_t statNameX = 1 ;
30313063 const uint8_t statValuesX = 20 ;
30323064 char buff [10 ];
3065+ statsPagesCheck = 1 ;
30333066
30343067 displayBeginTransaction (osdDisplayPort , DISPLAY_TRANSACTION_OPT_RESET_DRAWING );
30353068 displayClearScreen (osdDisplayPort );
3036- if ( osdDisplayIsPAL ())
3037- displayWrite (osdDisplayPort , statNameX , top ++ , " --- STATS ---" );
3069+
3070+ displayWrite (osdDisplayPort , statNameX , top ++ , "--- STATS --- 1/2 " );
30383071
30393072 if (feature (FEATURE_GPS )) {
30403073 displayWrite (osdDisplayPort , statNameX , top , "MAX SPEED :" );
@@ -3055,26 +3088,64 @@ static void osdShowStats(void)
30553088 osdFormatAltitudeStr (buff , stats .max_altitude );
30563089 displayWrite (osdDisplayPort , statValuesX , top ++ , buff );
30573090
3058- displayWrite ( osdDisplayPort , statNameX , top , "MIN BATTERY VOLT :" );
3059- osdFormatCentiNumber ( buff , stats . min_voltage , 0 , osdConfig () -> main_voltage_decimals , 0 , osdConfig () -> main_voltage_decimals + 2 );
3060- strcat ( buff , "V" );
3061- osdLeftAlignString (buff );
3091+ #if defined( USE_SERIALRX_CRSF )
3092+ displayWrite ( osdDisplayPort , statNameX , top , "MIN LQ :" );
3093+ itoa ( stats . min_lq , buff , 10 );
3094+ strcat (buff , "%" );
30623095 displayWrite (osdDisplayPort , statValuesX , top ++ , buff );
30633096
3097+ displayWrite (osdDisplayPort , statNameX , top , "MIN RSSI :" );
3098+ itoa (stats .min_rssi_dbm , buff , 10 );
3099+ tfp_sprintf (buff , "%s%c" , buff , SYM_DBM );
3100+ displayWrite (osdDisplayPort , statValuesX , top ++ , buff );
3101+ #else
30643102 displayWrite (osdDisplayPort , statNameX , top , "MIN RSSI :" );
30653103 itoa (stats .min_rssi , buff , 10 );
30663104 strcat (buff , "%" );
30673105 displayWrite (osdDisplayPort , statValuesX , top ++ , buff );
3106+ #endif
3107+
3108+ displayWrite (osdDisplayPort , statNameX , top , "FLY TIME :" );
3109+ uint16_t flySeconds = getFlightTime ();
3110+ uint16_t flyMinutes = flySeconds / 60 ;
3111+ flySeconds %= 60 ;
3112+ uint16_t flyHours = flyMinutes / 60 ;
3113+ flyMinutes %= 60 ;
3114+ tfp_sprintf (buff , "%02u:%02u:%02u" , flyHours , flyMinutes , flySeconds );
3115+ displayWrite (osdDisplayPort , statValuesX , top ++ , buff );
3116+
3117+ displayWrite (osdDisplayPort , statNameX , top , "DISARMED BY :" );
3118+ displayWrite (osdDisplayPort , statValuesX , top ++ , disarmReasonStr [getDisarmReason ()]);
3119+ displayCommitTransaction (osdDisplayPort );
3120+ }
3121+
3122+ static void osdShowStatsPage2 (void )
3123+ {
3124+ uint8_t top = 1 ; /* first fully visible line */
3125+ const uint8_t statNameX = 1 ;
3126+ const uint8_t statValuesX = 20 ;
3127+ char buff [10 ];
3128+ statsPagesCheck = 1 ;
3129+
3130+ displayBeginTransaction (osdDisplayPort , DISPLAY_TRANSACTION_OPT_RESET_DRAWING );
3131+ displayClearScreen (osdDisplayPort );
3132+
3133+ displayWrite (osdDisplayPort , statNameX , top ++ , "--- STATS --- 2/2" );
3134+
3135+ displayWrite (osdDisplayPort , statNameX , top , "MIN BATTERY VOLT :" );
3136+ osdFormatCentiNumber (buff , stats .min_voltage , 0 , osdConfig ()-> main_voltage_decimals , 0 , osdConfig ()-> main_voltage_decimals + 2 );
3137+ tfp_sprintf (buff , "%s%c" , buff , SYM_VOLT );
3138+ displayWrite (osdDisplayPort , statValuesX , top ++ , buff );
30683139
30693140 if (feature (FEATURE_CURRENT_METER )) {
30703141 displayWrite (osdDisplayPort , statNameX , top , "MAX CURRENT :" );
30713142 itoa (stats .max_current , buff , 10 );
3072- strcat (buff , "A" );
3143+ tfp_sprintf (buff , "%s%c" , buff , SYM_AMP );
30733144 displayWrite (osdDisplayPort , statValuesX , top ++ , buff );
30743145
30753146 displayWrite (osdDisplayPort , statNameX , top , "MAX POWER :" );
30763147 itoa (stats .max_power , buff , 10 );
3077- strcat (buff , "W" );
3148+ tfp_sprintf (buff , "%s%c" , buff , SYM_WATT );
30783149 displayWrite (osdDisplayPort , statValuesX , top ++ , buff );
30793150
30803151 if (osdConfig ()-> stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH ) {
@@ -3083,7 +3154,7 @@ static void osdShowStats(void)
30833154 } else {
30843155 displayWrite (osdDisplayPort , statNameX , top , "USED WH :" );
30853156 osdFormatCentiNumber (buff , getMWhDrawn () / 10 , 0 , 2 , 0 , 3 );
3086- strcat (buff , "\xAB" ); // SYM_WH
3157+ tfp_sprintf (buff , "%s%c" , buff , SYM_WH );
30873158 }
30883159 displayWrite (osdDisplayPort , statValuesX , top ++ , buff );
30893160
@@ -3116,15 +3187,6 @@ static void osdShowStats(void)
31163187 }
31173188 }
31183189
3119- displayWrite (osdDisplayPort , statNameX , top , "FLY TIME :" );
3120- uint16_t flySeconds = getFlightTime ();
3121- uint16_t flyMinutes = flySeconds / 60 ;
3122- flySeconds %= 60 ;
3123- uint16_t flyHours = flyMinutes / 60 ;
3124- flyMinutes %= 60 ;
3125- tfp_sprintf (buff , "%02u:%02u:%02u" , flyHours , flyMinutes , flySeconds );
3126- displayWrite (osdDisplayPort , statValuesX , top ++ , buff );
3127-
31283190 const float max_gforce = accGetMeasuredMaxG ();
31293191 displayWrite (osdDisplayPort , statNameX , top , "MAX G-FORCE :" );
31303192 osdFormatCentiNumber (buff , max_gforce * 100 , 0 , 2 , 0 , 3 );
@@ -3134,12 +3196,9 @@ static void osdShowStats(void)
31343196 displayWrite (osdDisplayPort , statNameX , top , "MIN/MAX Z G-FORCE:" );
31353197 osdFormatCentiNumber (buff , acc_extremes [Z ].min * 100 , 0 , 2 , 0 , 4 );
31363198 strcat (buff ,"/" );
3137- displayWrite (osdDisplayPort , statValuesX , top , buff );
3199+ displayWrite (osdDisplayPort , statValuesX - 1 , top , buff );
31383200 osdFormatCentiNumber (buff , acc_extremes [Z ].max * 100 , 0 , 2 , 0 , 3 );
3139- displayWrite (osdDisplayPort , statValuesX + 5 , top ++ , buff );
3140-
3141- displayWrite (osdDisplayPort , statNameX , top , "DISARMED BY :" );
3142- displayWrite (osdDisplayPort , statValuesX , top ++ , disarmReasonStr [getDisarmReason ()]);
3201+ displayWrite (osdDisplayPort , statValuesX + 4 , top ++ , buff );
31433202 displayCommitTransaction (osdDisplayPort );
31443203}
31453204
@@ -3257,13 +3316,14 @@ static void osdRefresh(timeUs_t currentTimeUs)
32573316 osdResetStats ();
32583317 osdShowArmed (); // reset statistic etc
32593318 uint32_t delay = ARMED_SCREEN_DISPLAY_TIME ;
3319+ statsPagesCheck = 0 ;
32603320#if defined(USE_SAFE_HOME )
32613321 if (isSafeHomeInUse ())
32623322 delay *= 3 ;
32633323#endif
32643324 osdSetNextRefreshIn (delay );
32653325 } else {
3266- osdShowStats (); // show statistic
3326+ osdShowStatsPage1 (); // show first page of statistic
32673327 osdSetNextRefreshIn (STATS_SCREEN_DISPLAY_TIME );
32683328 }
32693329
@@ -3282,6 +3342,14 @@ static void osdRefresh(timeUs_t currentTimeUs)
32823342 if ((currentTimeUs > resumeRefreshAt ) || ((!refreshWaitForResumeCmdRelease ) && DELAYED_REFRESH_RESUME_COMMAND )) {
32833343 displayClearScreen (osdDisplayPort );
32843344 resumeRefreshAt = 0 ;
3345+ } else if ((currentTimeUs > resumeRefreshAt ) || ((!refreshWaitForResumeCmdRelease ) && STATS_PAGE1 )) {
3346+ if (statsPagesCheck == 1 ) {
3347+ osdShowStatsPage1 ();
3348+ }
3349+ } else if ((currentTimeUs > resumeRefreshAt ) || ((!refreshWaitForResumeCmdRelease ) && STATS_PAGE2 )) {
3350+ if (statsPagesCheck == 1 ) {
3351+ osdShowStatsPage2 ();
3352+ }
32853353 } else {
32863354 displayHeartbeat (osdDisplayPort );
32873355 }
0 commit comments