From 9f9b4ddc8535d7df642bab5f0d71e069f6cc1b4b Mon Sep 17 00:00:00 2001 From: OneOfEleven Date: Fri, 29 Sep 2023 08:43:05 +0100 Subject: [PATCH] Added RSSI dBM, S meter and bar graph meter compile option --- Makefile | 5 +- README.md | 1 + am_fix.c | 1 - app/app.c | 4 +- app/dtmf.c | 2 +- app/dtmf.h | 2 +- app/menu.c | 4 +- firmware.bin | Bin 57816 -> 57876 bytes firmware.packed.bin | Bin 57834 -> 57894 bytes ui/main.c | 216 ++++++++++++++++++++++++++++++++++++-------- ui/main.h | 1 + ui/rssi.c | 157 -------------------------------- ui/rssi.h | 23 ----- version.c | 2 +- 14 files changed, 193 insertions(+), 225 deletions(-) delete mode 100644 ui/rssi.c delete mode 100644 ui/rssi.h diff --git a/Makefile b/Makefile index 427efbb..78a246d 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,7 @@ ENABLE_NO_SCAN_TIMEOUT := 1 ENABLE_AM_FIX := 1 ENABLE_AM_FIX_SHOW_DATA := 1 ENABLE_SQUELCH1_LOWER := 0 +ENABLE_RSSI_BAR := 1 ENABLE_AUDIO_BAR := 0 #ENABLE_COPY_CHAN_TO_VFO := 1 #ENABLE_SINGLE_VFO_CHAN := 1 @@ -117,7 +118,6 @@ OBJS += ui/inputbox.o OBJS += ui/lock.o OBJS += ui/main.o OBJS += ui/menu.o -OBJS += ui/rssi.o OBJS += ui/scanner.o OBJS += ui/status.o OBJS += ui/ui.o @@ -224,6 +224,9 @@ endif ifeq ($(ENABLE_SQUELCH1_LOWER),1) CFLAGS += -DENABLE_SQUELCH1_LOWER endif +ifeq ($(ENABLE_RSSI_BAR),1) + CFLAGS += -DENABLE_RSSI_BAR +endif ifeq ($(ENABLE_AUDIO_BAR),1) CFLAGS += -DENABLE_AUDIO_BAR endif diff --git a/README.md b/README.md index f183076..961582c 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ ENABLE_NO_SCAN_TIMEOUT := 1 remove the 32 sec timeout from the CTCS ENABLE_AM_FIX := 1 dynamically adjust the front end gains when in AM mode to helo prevent AM demodulator saturation - ignore the on-screen RSSI (for now) ENABLE_AM_FIX_SHOW_DATA := 1 show debug data for the AM fix ENABLE_SQUELCH1_LOWER := 0 adjusts squelch setting '1' to be more sensitive - I plan to let user adjust it in the menu +ENABLE_RSSI_BAR := 1 enable a dBm/Sx RSSI bar graph level ENABLE_AUDIO_BAR := 0 experimental, display an audo bar level when TX'ing #ENABLE_COPY_CHAN_TO_VFO := 1 not yet implemented - copy the channel into the VFO #ENABLE_SINGLE_VFO_CHAN := 1 not yet implemented - single VFO on display when possible diff --git a/am_fix.c b/am_fix.c index 1b61e84..619d12d 100644 --- a/am_fix.c +++ b/am_fix.c @@ -29,7 +29,6 @@ #include "frequencies.h" #include "functions.h" #include "misc.h" -#include "ui/rssi.h" // original QS front end register settings const uint8_t orig_lna_short = 3; // 0dB diff --git a/app/app.c b/app/app.c index b6f95d2..f89a649 100644 --- a/app/app.c +++ b/app/app.c @@ -59,7 +59,6 @@ #include "ui/inputbox.h" #include "ui/main.h" #include "ui/menu.h" -#include "ui/rssi.h" #include "ui/status.h" #include "ui/ui.h" @@ -79,6 +78,7 @@ static void updateRSSI(const int vfo) return; // no change gCurrentRSSI[vfo] = rssi; +// gCurrentRSSI[vfo] = (gCurrentRSSI[vfo] + rssi) / 2; UI_UpdateRSSI(rssi, vfo); } @@ -2305,7 +2305,7 @@ Skip: { SETTINGS_SaveChannel(gTxVfo->CHANNEL_SAVE, gEeprom.TX_CHANNEL, gTxVfo, gRequestSaveChannel); if (gScreenToDisplay != DISPLAY_SCANNER) - if (gVfoConfigureMode == VFO_CONFIGURE_NONE) + if (gVfoConfigureMode == VFO_CONFIGURE_NONE) // 'if' is so as we don't wipe out previously setting this variable elsewhere gVfoConfigureMode = VFO_CONFIGURE; } else diff --git a/app/dtmf.c b/app/dtmf.c index 7973787..146e75c 100644 --- a/app/dtmf.c +++ b/app/dtmf.c @@ -40,7 +40,7 @@ uint8_t gDTMF_WriteIndex = 0; uint8_t gDTMF_PreviousIndex = 0; uint8_t gDTMF_RecvTimeout = 0; -char gDTMF_ReceivedSaved[17]; +char gDTMF_ReceivedSaved[20]; uint8_t gDTMF_RecvTimeoutSaved = 0; bool gIsDtmfContactValid; diff --git a/app/dtmf.h b/app/dtmf.h index 5b7549a..141aec5 100644 --- a/app/dtmf.h +++ b/app/dtmf.h @@ -63,7 +63,7 @@ extern uint8_t gDTMF_WriteIndex; extern uint8_t gDTMF_PreviousIndex; extern uint8_t gDTMF_RecvTimeout; -extern char gDTMF_ReceivedSaved[17]; +extern char gDTMF_ReceivedSaved[20]; extern uint8_t gDTMF_RecvTimeoutSaved; extern bool gIsDtmfContactValid; diff --git a/app/menu.c b/app/menu.c index a22f6fe..0d85e73 100644 --- a/app/menu.c +++ b/app/menu.c @@ -432,7 +432,7 @@ void MENU_AcceptSetting(void) { // trailing trim for (int i = 9; i >= 0; i--) { - if (edit[i] != ' ' && edit[i] != '_' && edit[i] != 0 && edit[i] != 0xff) + if (edit[i] != ' ' && edit[i] != '_' && edit[i] != 0x00 && edit[i] != 0xff) break; edit[i] = ' '; } @@ -455,7 +455,7 @@ void MENU_AcceptSetting(void) gEeprom.VOX_LEVEL = gSubMenuSelection - 1; BOARD_EEPROM_LoadMoreSettings(); gFlagReconfigureVfos = true; - gUpdateStatus = true; + gUpdateStatus = true; break; case MENU_ABR: diff --git a/firmware.bin b/firmware.bin index 369d702cea17a2693af183df09844016fb1c3cb5..703bf6db5735960547c1b3882f94fe4c9a47d85f 100644 GIT binary patch delta 7127 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 WUEC7-M0>ex^pmB9D!#UTko3PAL0;bg delta 6922 zcmaJ`d0bT0+dt>d!XP3Lp)4Y^00ILxh-;{cC@>CWxs)V+l+;(;5=#RugRI=s^r&g$ zQYr z*_+|-(~nq8gpn>2heVVrX+QCks3DYY5bt!1qf``wqo)bXeY%! zqRHa9ID0T1Bi1C1pb>9hB;=NcXgey1_7~7^Sa8==43yP%EM3A@bZ4u}Su{0}-3PE0RU5{&2#h1p$=J(2u;R}<81v-UZPXKE4EP}qy?7bqR=3%^I zl%9p=TVOlzDs%RlOy{xE-bT7he7AQP6%=l^xlcWPoju#P6a7e>(zimO3F6i4NtEsu z^ZWOwbQXJOKz{H#boT+Up8YUja#)tnP)Upm8!;HlgQPXg@>CU_&Q3q|L})*M7D~3; zV5syR3mW(=O=86ZC)0cE=)kJ@z~nLQGnfnsR}cJq>N4aLY;2B^u3<}ZCed*AM^1c{ z4K;70IQA$lRBE4O-G2{TuSL*%s;q@9%n^EvV-{u^{982ts0U=t?by4 z>vRFD%lnxYvnBaSVSoAj+VFJJlrlDGkEyYMHRjKyqgn5QI(k*SS`bAe^*${zS`__% ztyk!aqx+hIq!<=Fv?8bYG9lx!o_v6v7@!RhA&-ZC0x%f*DWKf*o3T(*!;?iz_Wahl zsY;PzX$q1)V@HR!M)6);XvvM|tqOS$tkKdHX?fF9f$!MDEPPiL#?g4Tt1v#KgEzAA zNM2b7LN>D>3M*8b(f@Y#Y*8frm`y4=hq`^A9)s`NryJ-S%ra~n?Zy5W_Aa%H^PgGC zvpsZpDUD?_hnvBFG5jffox@j#ax?lM47nM{#kC`XD4okTjbvEH%u$haBO5X*ms-Rn zqy7-+6>;w93L(br4YH({cP^K19m(U(XQSzxpc`56n5;mq6vFNTpgl8>G1HNZjTuL^ z?9Va11*My%m-Illr6ptO9`SHVB&AP^=f=*Vp=aINvUd7Z(!->dUJ*x)yGc9k^-+DE zCC?mNo@Wud<6A(xtED;Ov!$nLXf+17g<-i9-e9Q{dc(h^6Z%t+xCLMO61y_dLRX5Z zlYXUiJByrrlJ*p@Og0MPb6we$J&fb+e)*VFC3$=-dTJWo&2pz2=xsK6Y66|e7EP@| z5@bvZ7WkexV}pXO5$)x@Y24})gzP-y_g_BX_mhS&%e#BR%!*opsib|(@N!R@CKkUO zLPMrG^(4hC#i*qJVKZNe3)u~s==uIiU((3 zp{iOKWn-IO&88)+`PG@~?HI4+g!pvDW-7FtV0SCK(fKTX?kd`ceKxl-unBxD&YHJO zplzb}^>dUqi1s(IX(upml|cw~GktX;b+PEL5d&P6rq161A%R~~* zO6i{#CcY*wsD?T7kgB%C>pvxSPCqRydEV9%E!y;B9jv254 z*aFnBB@5zuo_6YpMn9lHDSZ>*`hh#@>{qDK>qvHiQ#N~e`IFG@3zYW(_qo`-0D(A? zU41K)PGymA&!AcC&9{H1vsvjoPYJ)DVq4#NkrVa8G`g5&E{qdeF0iK;>S-05wJeRJL|;KK6zyi;F{gIaTQ?O!-IS)9CHG60>IOM0qE;&?9v%@xOjT$G8&icr21e>Y`LRR zNp7?ftwM@-I$HN2IM1?K%d_YuRz{N4%h@<-)Q_%dd820; z$il4X#qD&0^gZPDkQYCaPeE>)bw@iTk5E}I@oSK*WqE?6^cu+0M|Jk2PIS3}EPo{L zVeXAZ^sH#!G=ky;*tGc`eU7c%5*7N9TSo+azf7T4kcP0&w`2}TccW>MfKHp@1u4m` zOjk9x({j0Nupq^|)sRE~k)zz2bY(LyRicLuZl?WEn=!(Dr*-rxLZ$#M`tSy#TexR6 z8CD=jdG2sM(ec4@+=XUNSFsr%#!wSm^kHe-2zNU}70L+{YBkwJI_>zo_I;-KXzkFQ zh~~ynqTLO82y`zfUr8Pad>{S-@@?Q4z^^Da&}!5>1O6iT@UDcs3HjP(cI~5~0!X*5 zgXl^&Yine}U6eln?g4T`XQJ5|R~bg4h#JWxNN=!hTg{oDAT!h!O=gh34>=hvNL!r5 zN_*Xj_D5fB?T5|#X*&<2F!DHB#S_@b;|qYb50StHzh7 zc@2!3r0!bS*@Rwhu#4Lg+UuRPXHbt{TaV;DIKzbPgF@YoOcJWslF&>+YGcoC&j~&6 zNX1F^WI*#B+p;|a%X(&ef4ZK9)bxC8zJvB?7<9)jTJ%!GYUI=Z7QDZQN(b1=+JwkAyb41#dOcV`*7)TLuPpz@j@HhqD)SpEsd1Wp zn`N6hu2L`(+g5W(EtU586^Vj1WLHV9#z6FfE(Pu|5Wk%0CAx5Z3Zat4zseF*Nm8Ti z;rcMN$n~$VbR%)-ZJd2|Q3?sGbIQ~FVLJ#eb7{mxmYCb*MMxT<$Mt%$TF?=FNUdLx zJxr`Kybx1aZHdE$iP)9b2kWO>*3TW3YmGjY^-$-!CiE3jN%OeYkUFodbP&D55JAvf z?%*BODi}lUFBgW@X^B%#d^Dh*yaY4a+A%3Sg+8Mb$1q2~1~3GAWPf6LbTM{c@gX9n{RHD<|EM*VK8H7C*4}#!(REkiaZ|&;*PuHI^0xtg^)R{W@kd^B5)It7uld@ zX5SfERRwN1FdmqLlJ9Ugp9G$}a|`Hm=;Kqk{2S<(LFSpX0#s>@tvnxCwNhIo>63M- zUTrLCvRi}=m*y@T^t@edO@q_4I%+rrJEwZoRt*cXQn=XJa?%o4rpdZeC1jAQW_Jti zIfLA(KUQ#y_KG$UmHumUwTVhIyflN@e{V4nh5m^79cU(c(ZGH^plLKOhGvXc0nLvA z%@^in&*JKF(Aa;<-#&uS+13Hy=sl_^<8VhYbn}uwwL~})}vdS7#8&m0(e{^H( zd5sv=cBS<_b8IEDpnIFV-a8*n1Y^3*h>!`XP1O12d2SxfRGJMMN*03q)nz0Cc_$EZ zRX7faK2gWRptn1}_0rtUxGc;^trFB%t(phU?owF=GWTKq$zGmf+*3xx^x9iW>#To< zFZN1k{1TcBK;z(5)4++YU^Jc@Xl(wkwto4rOKBZDG_Lad5|bfz5V31ox%DLh>lb-w zYmikis_Z2e;e$;jB!k%0IH?UGwTg0ub+q}?>%@tMxa%GntC}V>jvkhSRy9`n5Tnejo9^7N&>u^Zd9l^Jp zRqcu&JRc=-7(-!C354y#8sF)XP-7;_E}<2%KXFt4Xe&s&$$Pl1OF;QJm*HmilLN7O(ph8H-a8bW&90Qfub_ONSemnQ0U<+9jK{6Bs4lFV0%;AG&sU0!iko^fvmy4xzVky?1!iB(iSS^ zIobI=YlH+RoBFw4x6+-~GNCMM=oqs31rvHLbxqV!X*4dK?Fr|uvt6I-gz0W(`}}cX zf}7p?JUOJV(?pinw?pY})~P&H9+)YtG}CYcu+6PmY1R>o6eBzcOpEwYppyTpGIL(h!u*Ei8BN?NXJ^ zbzj0`WsZY|$(6bRf7VlDx26}%NE*3x_1b^XmP$XeKkE%I`sI8_X_=~#D5wo0*yBMWjWlzX79aLRqoLwPbj10$NC_``@8QW50`cwmty?n31Z)ME8$@* z+G=l&FZ0NU{2^u~p4YGXwIqya%tZRlmksA=1I~HVsWgyv+!dPI6?muevxH~BEx7kC zupBbKb@B7*z6Oe4kQU#wD-CgFJrD(7qF99X3xFRtJWBW_kS7k0mfgVUCPJP{{JKyRQqiNa>zCf~cMBH~oM?|{jf7lUkwvqj@zf;xs{=ZjV6^OM0@8K9_Z&%gvG}4SAx@*mR zkiQT_JkJ!_{u}q$UNc_LDPZqhHjQnV&zAIEj{4rLc0-^8VhV`0eP^U zq~+Rzl2Zyh;qt1*T88;aMt_@1uf@xqNcBFNk#1Ay_2%*MMB3>SGLmdsQmW7=m^CIM zZSyHIRLywR>N}f5AX|OPM{;On-YZYD=Es$R9BorE)(6!dZlG!$?`#hZNo^vJjoy4co%ESkFFMd`J-oDG5gOK zxe@!3WBe-1pKd`&nQkoPKtjake`!_Fc4XNHVhl@sB(X}bG3fZys#XC#@jQ@cd(?Z% z8++iDL8MAnaUgR@sqb)W+EAnU`xgYn$P2#xt<)H9PYKj`*4Nb%s*SBowv-KyskC(2 zkaM!$C$D!4i5*)KD`|RYlP*xNKf7}vp(?{i^xIlv0-CPAp95Foi-?vBKoh{D?MVc} zW$>dw&x7(uWB_wbjm1x0(gfpILSu@g10;>HZ&zK1Pt)D}-ezx?q38s6l=slesI20j$} z7$6C_3^^0@7f>^(3v>m>?~nS!AnWm~`Kypu1N;GQggk}OLy^V&w-XA@b8F1^B%4i6KYZuaWo?p0Ua?GlMWSsO#JBdzht&pS1>e0#v_9?~;TRe+DgGZ1@> z^MU*aaL~E6^*61u4zGUNCU5ort_{~~>NvmAdl7HczaN==d8T8ceBwO6*I@D+fi$=w zsDb}F64WD$>Y~X5`L-*l(b4eS(C00&;~&VyF1Os>_ds6eav4Sxj(l26vdW3H+D-9p zejuM`V~*$wSNewz8(PqpxMi2uEyw#j@@EAAyvpez&zvF7&oyk$?96B~!1F^u;?=VeDx4$X&cz z%k45H`CyQ`i5j{T8OxD!E@Cj2^NHqo+v{Qr+T_mOSj!1rE5DoEw6)1=eEt*%{v*gL z{|Sq^NJ(NfgbegvVjmoh#cx9mM@1Fedwe=hb0ntegejEn6$;+YqhF5CCx_n=$DWuO zmU@V9qksws1)>2hkPPrL6OaY;7TYcsDx)S$GIcM_3T;P*4as{xqt8Q8eD1P}vRPMV Kinp$GQ~n=Hh%X=j diff --git a/firmware.packed.bin b/firmware.packed.bin index 45d7935dd1e42fcda53cd8da8e1a27f16b27c12c..11d02b793a163e514d7b78a012817a82b64373e1 100644 GIT binary patch delta 17937 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 delta 17877 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%0Ds5Kxx5Y!>X$$E|vEt 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 diff --git a/ui/main.c b/ui/main.c index 5259389..bb0dcca 100644 --- a/ui/main.c +++ b/ui/main.c @@ -36,21 +36,25 @@ #include "ui/main.h" #include "ui/ui.h" +// *************************************************************************** + #ifdef ENABLE_AUDIO_BAR unsigned int sqrt16(unsigned int value) { // return square root of 'value' - unsigned int shift = 15; - unsigned int bit = 1u << shift; + unsigned int shift = 16; // number of bits supplied in 'value' .. 2 ~ 32 + unsigned int bit = 1u << --shift; unsigned int sqrti = 0; - do { + while (bit) + { const unsigned int temp = ((sqrti << 1) | bit) << shift--; if (value >= temp) { value -= temp; sqrti |= bit; } - } while (bit >>= 1); + bit >>= 1; + } return sqrti; } @@ -105,6 +109,152 @@ } #endif +#if defined(ENABLE_RSSI_BAR) + void UI_DisplayRSSIBar(const int16_t rssi, const bool now) + { + char s[16]; + unsigned int i; + + const unsigned int max_dB = -33; + const unsigned int min_dB = -127; + + const unsigned int txt_width = 7 * 10; // 10 chars + const unsigned int bar_x = txt_width + 4; + const unsigned int bar_width = LCD_WIDTH - 1 - bar_x; + + const int16_t dBm = (rssi / 2) - 160; + const unsigned int clamped_dBm = (dBm < min_dB) ? min_dB : (dBm > max_dB) ? max_dB : dBm; + const unsigned int width = max_dB - min_dB; + const unsigned int len = (((clamped_dBm - min_dB) * bar_width) + (width / 2)) / width; + + const unsigned int line = 3; + uint8_t *pLine = gFrameBuffer[line]; + + unsigned int s_level = 0; + + if (gEeprom.KEY_LOCK && gKeypadLocked > 0) + return; // display is in use + if (gCurrentFunction == FUNCTION_TRANSMIT || gScreenToDisplay != DISPLAY_MAIN) + return; // display is in use + + if (dBm >= -63) // S9+10dB + s_level = 10 + (((dBm - -63) / 10) * 10); + else + if (clamped_dBm >= -127) // S0 + s_level = (clamped_dBm - -127) / 6; + + if (now) + memset(pLine, 0, LCD_WIDTH); + + if (s_level < 10) + sprintf(s, "%-4d S%u ", dBm, s_level); // S0 ~ S9 + else + sprintf(s, "%-4d S9+%u", dBm, s_level); // S9+ + UI_PrintStringSmall(s, 2, 0, line); + + for (i = 0; i < bar_width; i += 2) + pLine[bar_x + i] = ((i & 1) == 0 && i <= len) ? 0x7f : 0x41; + + if (now) + ST7565_BlitFullScreen(); + } +#endif + +void UI_UpdateRSSI(const int16_t rssi, const int vfo) +{ + #ifdef ENABLE_RSSI_BAR + + const bool rx = (gCurrentFunction == FUNCTION_RECEIVE || + gCurrentFunction == FUNCTION_MONITOR || + gCurrentFunction == FUNCTION_INCOMING); + + if (rx) + UI_DisplayRSSIBar(rssi, true); + + #else + + const uint8_t Line = (vfo == 0) ? 3 : 7; + uint8_t *pLine = gFrameBuffer[Line - 1]; +// const int16_t dBm = (rssi / 2) - 160; + + #if 0 + //const unsigned int band = gRxVfo->Band; + const unsigned int band = 0; + const int16_t level0 = gEEPROM_RSSI_CALIB[band][0]; + const int16_t level1 = gEEPROM_RSSI_CALIB[band][1]; + const int16_t level2 = gEEPROM_RSSI_CALIB[band][2]; + const int16_t level3 = gEEPROM_RSSI_CALIB[band][3]; + #else + const int16_t level0 = (-115 + 160) * 2; // dB + const int16_t level1 = ( -89 + 160) * 2; // dB + const int16_t level2 = ( -64 + 160) * 2; // dB + const int16_t level3 = ( -39 + 160) * 2; // dB + #endif + const int16_t level01 = (level0 + level1) / 2; + const int16_t level12 = (level1 + level2) / 2; + const int16_t level23 = (level2 + level3) / 2; + + gVFO_RSSI[vfo] = rssi; + + uint8_t rssi_level = 0; + + if (rssi >= level3) rssi_level = 7; + else + if (rssi >= level23) rssi_level = 6; + else + if (rssi >= level2) rssi_level = 5; + else + if (rssi >= level12) rssi_level = 4; + else + if (rssi >= level1) rssi_level = 3; + else + if (rssi >= level01) rssi_level = 2; + else + if (rssi >= level0) rssi_level = 1; + + if (gVFO_RSSI_bar_level[vfo] == rssi_level) + return; + + gVFO_RSSI_bar_level[vfo] = rssi_level; + + // ********************************************************** + + if (gEeprom.KEY_LOCK && gKeypadLocked > 0) + return; // display is in use + + if (gCurrentFunction == FUNCTION_TRANSMIT || gScreenToDisplay != DISPLAY_MAIN) + return; // display is in use + + pLine = gFrameBuffer[Line - 1]; + + memset(pLine, 0, 23); + + if (rssi_level > 0) + { + //if (rssi_level >= 1) + memmove(pLine, BITMAP_Antenna, 5); + if (rssi_level >= 2) + memmove(pLine + 5, BITMAP_AntennaLevel1, sizeof(BITMAP_AntennaLevel1)); + if (rssi_level >= 3) + memmove(pLine + 8, BITMAP_AntennaLevel2, sizeof(BITMAP_AntennaLevel2)); + if (rssi_level >= 4) + memmove(pLine + 11, BITMAP_AntennaLevel3, sizeof(BITMAP_AntennaLevel3)); + if (rssi_level >= 5) + memmove(pLine + 14, BITMAP_AntennaLevel4, sizeof(BITMAP_AntennaLevel4)); + if (rssi_level >= 6) + memmove(pLine + 17, BITMAP_AntennaLevel5, sizeof(BITMAP_AntennaLevel5)); + if (rssi_level >= 7) + memmove(pLine + 20, BITMAP_AntennaLevel6, sizeof(BITMAP_AntennaLevel6)); + } + else + pLine = NULL; + + ST7565_DrawLine(0, Line, 23, pLine); + #endif +} + +// *************************************************************************** + void UI_DisplayMain(void) { char String[16]; @@ -428,17 +578,7 @@ void UI_DisplayMain(void) else if (duff_beer == 2) { // RX signal level - #ifdef ENABLE_DBM - // dBm - // - // this doesn't yet quite fit into the available screen space - // I suppose the '-' sign could be dropped - // - const int16_t dBm = (gVFO_RSSI[vfo_num] / 2) - 160; - sprintf(String, "%-3d", dBm); - //sprintf(String, "%3d", abs(dBm)); - UI_PrintStringSmall(String, 2, 0, Line + 2); - #else + #ifndef ENABLE_RSSI_BAR // bar graph if (gVFO_RSSI_bar_level[vfo_num] > 0) Level = gVFO_RSSI_bar_level[vfo_num]; @@ -523,42 +663,44 @@ void UI_DisplayMain(void) } if (center_line_is_free) - { // we're free to use the middle empty line for something + { // we're free to use the middle line + + const bool rx = (gCurrentFunction == FUNCTION_RECEIVE || + gCurrentFunction == FUNCTION_MONITOR || + gCurrentFunction == FUNCTION_INCOMING); #if defined(ENABLE_AM_FIX) && defined(ENABLE_AM_FIX_SHOW_DATA) - if (gSetting_AM_fix && gEeprom.VfoInfo[gEeprom.RX_CHANNEL].AM_mode) + if (rx && gEeprom.VfoInfo[gEeprom.RX_CHANNEL].AM_mode && gSetting_AM_fix) { - switch (gCurrentFunction) - { - case FUNCTION_TRANSMIT: - case FUNCTION_BAND_SCOPE: - case FUNCTION_POWER_SAVE: - break; - - case FUNCTION_FOREGROUND: - break; - - case FUNCTION_RECEIVE: - case FUNCTION_MONITOR: - case FUNCTION_INCOMING: - AM_fix_print_data(gEeprom.RX_CHANNEL, String); - UI_PrintStringSmall(String, 0, 0, 3); - break; - } + AM_fix_print_data(gEeprom.RX_CHANNEL, String); + UI_PrintStringSmall(String, 0, 0, 3); } else #endif + + #ifdef ENABLE_RSSI_BAR + if (rx) + UI_DisplayRSSIBar(gCurrentRSSI[gEeprom.RX_CHANNEL], false); + else + #endif + { #ifdef ENABLE_AUDIO_BAR UI_DisplayAudioBar(); // if (!gSetting_mic_bar) #endif - if (gCurrentFunction != FUNCTION_TRANSMIT) + if (rx || gCurrentFunction == FUNCTION_FOREGROUND) { if (gSetting_live_DTMF_decoder && gDTMF_ReceivedSaved[0] >= 32) { // show live DTMF decode - UI_PrintStringSmall(gDTMF_ReceivedSaved, 8, 0, 3); + const unsigned int len = strlen(gDTMF_ReceivedSaved); + unsigned int idx = 0; + while ((len - idx) > (17 - 5)) // display the last 'n' on-screen fittable chars + idx++; + strcpy(String, "DTMF "); + strcat(String, gDTMF_ReceivedSaved + idx); + UI_PrintStringSmall(String, 2, 0, 3); } else if (gChargingWithTypeC) @@ -576,3 +718,5 @@ void UI_DisplayMain(void) ST7565_BlitFullScreen(); } + +// *************************************************************************** diff --git a/ui/main.h b/ui/main.h index 347b9f4..3c5b27d 100644 --- a/ui/main.h +++ b/ui/main.h @@ -18,6 +18,7 @@ #define UI_MAIN_H void UI_DisplayAudioBar(void); +void UI_UpdateRSSI(const int16_t rssi, const int vfo); void UI_DisplayMain(void); #endif diff --git a/ui/rssi.c b/ui/rssi.c deleted file mode 100644 index fd29c6b..0000000 --- a/ui/rssi.c +++ /dev/null @@ -1,157 +0,0 @@ -/* Copyright 2023 Dual Tachyon - * https://github.com/DualTachyon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include // abs() - -#include "bitmaps.h" -#include "driver/st7565.h" -#include "external/printf/printf.h" -#include "functions.h" -#include "misc.h" -#include "settings.h" -#include "ui/helper.h" -#include "ui/rssi.h" -#include "ui/ui.h" - -#ifdef ENABLE_DBM - -void UI_UpdateRSSI(const int16_t rssi, const int vfo) -{ - // dBm - // - // this doesn't yet quite fit into the available screen space - // I suppose the '-' sign could be dropped - - char s[8]; - const uint8_t line = (vfo == 0) ? 3 : 7; - - if (gEeprom.KEY_LOCK && gKeypadLocked > 0) - return; // the screen is currently in use - - gVFO_RSSI[vfo] = rssi; - gVFO_RSSI_bar_level[vfo] = 0; - - { // drop the '.5' bit - const int16_t dBm = (rssi / 2) - 160; - sprintf(s, "%-3d", dBm); -// sprintf(s, "%3d", abs(dBm)); - } - else - strcpy(s, " "); - - UI_PrintStringSmall(s, 2, 0, line); -} - -#else - -void render(const int16_t rssi, const uint8_t rssi_level, const int vfo) -{ // bar graph - - uint8_t *pLine; - uint8_t Line; - - if (gEeprom.KEY_LOCK && gKeypadLocked > 0) - return; // the screen is currently in use - - if (gCurrentFunction == FUNCTION_TRANSMIT || gScreenToDisplay != DISPLAY_MAIN) - return; // it's still in use - - if (vfo == 0) - { - pLine = gFrameBuffer[2]; - Line = 3; - } - else - { - pLine = gFrameBuffer[6]; - Line = 7; - } - - memset(pLine, 0, 23); - - if (rssi_level == 0) - { - pLine = NULL; - } - else - { - //if (rssi_level >= 1) - memmove(pLine, BITMAP_Antenna, 5); - if (rssi_level >= 2) - memmove(pLine + 5, BITMAP_AntennaLevel1, sizeof(BITMAP_AntennaLevel1)); - if (rssi_level >= 3) - memmove(pLine + 8, BITMAP_AntennaLevel2, sizeof(BITMAP_AntennaLevel2)); - if (rssi_level >= 4) - memmove(pLine + 11, BITMAP_AntennaLevel3, sizeof(BITMAP_AntennaLevel3)); - if (rssi_level >= 5) - memmove(pLine + 14, BITMAP_AntennaLevel4, sizeof(BITMAP_AntennaLevel4)); - if (rssi_level >= 6) - memmove(pLine + 17, BITMAP_AntennaLevel5, sizeof(BITMAP_AntennaLevel5)); - if (rssi_level >= 7) - memmove(pLine + 20, BITMAP_AntennaLevel6, sizeof(BITMAP_AntennaLevel6)); - } - - ST7565_DrawLine(0, Line, 23, pLine); -} - -void UI_UpdateRSSI(const int16_t rssi, const int vfo) -{ - gVFO_RSSI[vfo] = rssi; - - //const int16_t dBm = (rssi / 2) - 160; - - #if 0 - //const unsigned int band = gRxVfo->Band; - const unsigned int band = 0; - const int16_t level0 = gEEPROM_RSSI_CALIB[band][0]; - const int16_t level1 = gEEPROM_RSSI_CALIB[band][1]; - const int16_t level2 = gEEPROM_RSSI_CALIB[band][2]; - const int16_t level3 = gEEPROM_RSSI_CALIB[band][3]; - #else - const int16_t level0 = (-115 + 160) * 2; // dB - const int16_t level1 = ( -89 + 160) * 2; // dB - const int16_t level2 = ( -64 + 160) * 2; // dB - const int16_t level3 = ( -39 + 160) * 2; // dB - #endif - const int16_t level01 = (level0 + level1) / 2; - const int16_t level12 = (level1 + level2) / 2; - const int16_t level23 = (level2 + level3) / 2; - - uint8_t Level = 0; - - if (rssi >= level3) Level = 7; - else - if (rssi >= level23) Level = 6; - else - if (rssi >= level2) Level = 5; - else - if (rssi >= level12) Level = 4; - else - if (rssi >= level1) Level = 3; - else - if (rssi >= level01) Level = 2; - else - if (rssi >= level0) Level = 1; - - if (gVFO_RSSI_bar_level[vfo] != Level) - { - gVFO_RSSI_bar_level[vfo] = Level; - render(rssi, Level, vfo); - } -} - -#endif diff --git a/ui/rssi.h b/ui/rssi.h deleted file mode 100644 index e0bf246..0000000 --- a/ui/rssi.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright 2023 Dual Tachyon - * https://github.com/DualTachyon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef UI_RSSI_H -#define UI_RSSI_H - -void UI_UpdateRSSI(const int16_t RSSI, const int vfo); - -#endif - diff --git a/version.c b/version.c index 7615aa5..c257f1f 100644 --- a/version.c +++ b/version.c @@ -2,7 +2,7 @@ #ifdef GIT_HASH #define VER GIT_HASH #else - #define VER "230925" + #define VER "230930" #endif const char Version[] = "OEFW-"VER;