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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 Ig+gIm^cAxw)5H zn~~9B^G=>zX2uo~0jBS&@YW`+ynEX-8lZE4h^8d+p+VdDEOinZwp8P@k6XS!)k98s$k4?7K zRp(uLl7V5#Nd|^RCm9$PPcGCIX6%{#ak}{AIl5}1KEH%KJ)GGY6c{)^ocYDUV93Dv z!D;e!T|?dn*BBTanHd<4a56CPOcvE!$+&OwemzCO_&-bx{2Ht`-Q`?74H!5-ES>yO z@44iH>kJIDIT#cIIT#dzI2aUyp`MsO`J=wEV8wL?hACVO3hdkr3Tn&@3LTS84f185 z|C{eEQ^BCaa3SxJMFpbYDvdBn&H z3YrU(Yt5`BK>_2&!=P}Ai$UQ87lQ&DH-o}vE(V2~$rsIpMXRneFhue&D4geFP&mWI zps<9CL7{B&PqTE!s>zAw+Kg*A_nPxFGBN+2JkMeiW6k71OL4}9n=>uTnHc3aKeSF| zWL&q|-PV?ov2b#$ojd2W>kJIDt}`&qn0(bPo!|JMas`7n^92TFO?sQCL6qx+pQC9Q<2ZO>ZE(V1OTnq{`xEK@~xEK_UZB}%e4|3E&XKTjb z&3~O485zG!{_o<;czm+2t2HOchD}@y3g;(JbTww2J^85XW5%Y*E8XrhMo#W@SLOfm z@4te84#N$NSoRGDdp#!ab+2TMm~8H`lJVi@haRGg!b<-X7__~aZC`F;R*ICcG+_TA zIhoU|+%fVF149B2g96Bc)m#h;U%40*HuEqjB-~+ONWR0s;KIS6ka>rJ0TlD|t}`%v z*lOk5x#6|Uje2Gc?;GqN)=xg@^;{HW$}gzrLArcECQRPztB0}#(9%teT*6B zO`hl@%_uv0t&c1>-(TUq2i!9F7#QYFzUouXI*)@vVaen`Utz{&lT&>!GtQfA=@-p7 zZ}L>Xt&DY(z5N$6noWN1-^+M$b8SFBD7W(lB{E7)&JXfroHu!AkUitP$v=boc|qQ= zV1{_(_~xm>?2L?+ljnv^W;{OGFjSav&Sck6XGZVMouTiU81HVbj3{T4{QZ~RTc<## z;KQ>6ZXoR?Tnq}091IF`CUZs`gY$~dbp{5H>!7^i8STj!GI?@zJfp(o&(Y>gEWan~ z#F#M7nVc9C%eZ0l{up6KMyt)2V@nx%&;M4);8N0LFfm~JP`o)b{wbsQmVb;&Zr*O5 zQUz|_Oh!@#ZXS$AY#&ND2PU3o!&*u5bwv3E!AA>a+j<-`Vy5Kf_jj@7@jk zp3EzlCbNFnHd(pIlu>JQWDz$bclJ*u1`W>-lB^%nCg&GRbFcfU#K53v!NB@q<>aZw z-HekaE0$O?zL^|dBF%Vaa(Rg}quA!%C3hKFS6pXcxG;HcnKfg~Y;$2%HxuL6&3|hyGcs=7e6dcOkx_o~ z-+E;x-rtjz8dMm6O?GckW_&R@yFrq1-sIK>U&bw)FE{WqdN%(uU{LX7`EdCc$8!S) zmJijx3>XwWSw5WpB?RUd|1w~Z^JMvO_?Il0pZ&{#LE4k$!|q?6V1Dv10|p6CmJgdJ zYc}}{_TOP(n0$wUVdfnMhWU3G7?w`%Y?3xT{Zo;FL&?sA<-;*B%f^G{!@-|6J{(Gl z4Ave$zkB`x$y<4_eAot-xA0*3uyOOvCU!=~kjW354H>g03%BGl8c%L)xzAWKIkDBA z>CLIhi&~RF6kD4XW5;B}Hfg2@*CzY5DKXYhE^N~jeejpZ)5DpK!GeMLL&84}21N$u z57#EIZxdxaJ^5&xG2`UTKig(AGHOnq+TqSPd-C0mNN%&AtU4Mu6d0I4P5Rudj&}B*n8iwf{0B8;JSm+GM+l?-*k@>rUckgi6{@&Szpg zHhJw-amJ3xN2i`=?3g@tnmgxt4h98KrdYZ8=`?Oe#z~VuPB&(pyIFO{ekN8>U2$si z%UPO?uOGnVM!Qe^sY=~uSfj6!9G4k-WB zuWYv)g>Mxy-540Ze~;l}iV<*zbB7gWuTU)gRF1_ zH<*!8b@JSK9~r|Y_s~A(5)|2*8~pq2^N3Rn44J1G z7#=7IY-Lbv+c1g2--GFc+iw9S21Sr%j=z08LG;AQxeFv24JNlQNR$r#&81wg#GuG9 znP~-wHN%I~KVYgqO=ey=)ob+~28O-73<~S+Ffi=nWl-31hk*eUlAweDDu;L8VPJT5 zhk@bf9R>za6Xn7k28IS+28FX63<}rpFfa(HGcYvrGAKN{Gx^a%FQ!L#ChIM7V(gz> zxJX$3-5myoZ+93NKHgzq_`X$!fn&9F1wVr*0~-UwWTp>wlNT@YG+h2uk%7&d!;oFc zg5jhD(}(##8D=w@y_NVc@$k6~GlPQPMFxf+TlpD87}ywO8JIpePL^G4FPs09-JH?v z4Oqpuv#2VBK`P`OkyPwC4N}3zz@W;e?jvKs!1UqC~+u6xX zOPqLr|1f0WRZ?K!HDvnmb#mYmN8T$xG#L~atiU4YCeL4@%V;q9>=IkX8I!q}nhMqa zU^Ln4^!DQSy$9Stj{SCaa?sK!F83dX49_8^Zd)qH*g5&?Qgz1C$$ytdi@N`Kpv0g! ziNVH$>4W1B8(4HLTg&)tvh;FIeNY=jgc;Jv*~7-505bJAG{`|w@<8ds)=3NuiibR= zZ(#heYjXbzdEvUh%*qW)42ruw7^eLHUjFy{_t%pTt|+X}_^({SsGWUrvG-z6=?W%o zh6{^4xmPfL*zliOg=seT+8AdJWdzpMOZP!v$oU|{^<{ePmjWCeq! z=tTh~{uPWLod5TE>oG`IFlxtNoaC#)z`ye6_w4`ts~9vGE^09tFm!r;{oekcLy5`c z@g{~zOo|Lj+$;Vweg89g^Gf9?$%+PV=?VsIhKnqZU6gXXXH+^l&z3l43=#YFh{=*k zli_CkbMBRYzq9;cP-0dVWZ+)$|2yB`(C19rycdgn_*W`0{QRy0wNQy6&y#z_*Y6Jh zCmXD?V=DPKxnPwV^9b$F)J`k`~Us; z^4*C2h|G5{w_d zPR?B|t~m7{#8i;GeE%#1r#nz|Jmz9h$hgbEP&#?(YI)xFy9^8|91IH9cNrKwCtqAG zTwi~efg$KF149Bx4XBZSl7S)hE+hxdzstZ7#>1en<~jqzv6Bo8-FG25sqZcW1Iuiw ziYwqyOS~Y=U}1cF6PtF-jf>t)GjCURJB43lo2|vbFj+y7QTeRL|L<9U*k*G~W}nTd z&2Zu8gOlFU863uU>zQ;J>Tmvjz-XGw@OINtk7tZ#5(W&cN=G~!3>ZJ;{$@#5e;Q5zTm*L_Gu*fFQi3W@x9R9NDGF;pb7O7wFImLkSgZbYb53DogGS+y5k`U*` z`Q9_@7&PNA&aPyd+3m!5u{u*O&MupYgZWdv-08w$24@22hGsQT+eC z>NhAgGkz%fZNR|G(B{eb;pH!F1}279aFVP43rYqmilAg*{@eZe?aF!24H#-Y89&7Q zHeg_#Smnw1;o>jW*-Q+T5cTPQL0JqGQ`!vNE2chUnOz9CKJxE}=LQUUo{S&tej6}w zPR#aX{IK~K=WHg1EU;!z6utky@BhUzJJw6O;!=!(vXm3UMULkn-^YM`-~Na3Is0rT zZPtr1-b}OR#xUqITwr_7prFjXg1LZsc7*5c8U}6Qi=ZS@d$Br`e8q z;jmB9$m9R_p2_uVWnF52G0&E+VbEs2r~yv45EbVXRXzTH&;P|d`*szm0MLJ`1eRsE zsPz%J+z_9Bi1H+b+3=E(;W9lJ7$$C*#K8FB?PS#r)h4We*uW||R{a0I_h)higEq?r4kZhQ z6i>zv-rx$EV+G@fIlmPuY%~~dc0FMH;P!L!l?_vv?a#UIfl|gQu>9^{AhX!OW`WE${-InU#lUC9sKt0wUR(Gg z>pBC5#Eie+AN&CIvY9U$FwF5}{ICG*B8JIEiUtg9*8jgt{Fq#^S;qPQca9&*6)M_1 z7bkcye(3tep}~F=&9c(#e>QmX ztpa&H3~mvNHOGp7-_K0u-y$k?^^bCejyA(ZCRGOILg`E;4#O9l7$*P!F8*_}-4+Eg z6}Tp5u%K9h%} z#S1H*C1m{hzVAP`Ckq3^hqC_)4Ezino(vye|FdRbVo(4_PUBA&Wrk^>sNh)9_w0aM z122ODCd%fRsNE(1dkFM|T8)di}bK5^V-V0gjBpm1sO-L29YCifT^_V6+&Y`)9D zuoGI{fKmyl5eUjSpwzPNE(1fv4F(4LdkhQ=O34|53^O+U{m%3!IfG*z#2W?-|Gu~U zg9S5#GKjzGAIKwiVCRSYpPaBw#61W+Oah9)b)JkLgnoiFfTE9KGMn|k?_K{^Lj5fB z%z|OLC&P!g|121oCoc75_>lCEc{UTnVow8xuit-6-n~tmDdFGb7u!}z{`~I$qujgP zQ=$OW@(_N?p~SP2V+F&9E0b4mS2Yd)XTi|7DMgXt!<1ro6^AnmiU7a9ON7; z7^eOEe&a8rvXLUkih3mw@8V?E9r8Se{~|q`Hi4qw?#E<<9a{A(eivnMsCk36EB&Zf zVgPFaX_)z!RXN5P)N_9#p}@fK;qPBi965V3d?@-0iX%s`9*!SOU@IBGv0VQb6k~i( z85J*W0>!%LU+Jfi&|sL%v4TPQ-}k(~pv>~;yYfG9W)ah7z9{Ai^4X*R5Q9M4=1hLS zL%jade~?yC0%rxMHIKjhC0WdW)gRYlxXJgF(MZ7)WXYHB`~HLS8MF2OC!g*@VjYx7 zK(YE28pAhkFfe?-%fP^JkAYz^4}-#P9tMT8JPZo#_ZS$s?=dh$++<+r;D98i9xet2 z;d=}WIrY~W81k+&Ff6?XDRdYZx)~ju_!(sGLB@_$?lCav++$!U*sABv%P<>MC0x(} z$F$EyZE*eXaX|~rce%)*<$Qr%O~XfA2~@l?eBl4jplf@9RY`$C#gpN~rhkmOIv1Fg zlspq;89uE3$E2%zL4hHWSxMfL!+_z#;(yG#tTz=Hn3ZHaxeXXT%>Ks$e$DmTL#G$MR>RPQ}w*L2> z;m^14C4bm96znzeWLm-Sp<;6RE<@MEfBT9nTrH1uklURRsQ1 z_vTfQs!;RJaFML=mYeB#a?`)>Gk!Cvh&@oLVASEgp$JxIJNfM{`Fh=d3`&ciOM*qz z|J?^SiLY}oC|u)UP`JSXDUz)2F)-ZWU{DCX$G~uf1JcQKzsJCEkAp$sE(e1Gs5VNt z2dSZQ?lCZw-(z67%E6$p5>#T{VPJT~!JtrkkAb269%!(UL8Z;F-J6x6K}nIpU~~6w zV@AfB$@}+IvrGI1c~E+?<6dz_<;jtIb(uc>ncT5gAu{_Er1C$)1{v94=4Md1z{a4! zdy0WU@)QGu>L~_>J8TRJhNl=9Ua&DJc%EWl_{GMc(8tA~V9Udx;D3sNL5ZC~p^S?` zVGva3pB#gz*#u!($Exh26Xi3SUn$Fo4Dzolh|^fbz?vdkhTV zJcE>FCUY?;2yEr@mZ)IXV7~0oV%}>@%ZG2 z`-R-}-zW$uajXQf=ls3?{D2#*lL@LVa;`%h z4$9wC?lCaTxyQhub%%k0eJf~mgx$oLQBi{7+xJ($*!TX}8s-)5EtT-?d*rX*-;Mr# z``-QQmvXRAh@S$3aRI}JNxvBx6d1mJzcM-cfTBCBp#;Mw8#)AN^&~`F4>(;m`N8 zfBvig{{HXRVN&#u4hv;@LS5{bEqoE&w^y@h^{}l*iZaGJmDKPbfYIwN0L0`1*ayzyBIP zE-)w?7uU46Jt<7C>_$~v3 r`R1?JeON@3Qw@v~jd{5k{9WC`buA#=&0%*~87CLs&ENd&t{w{jN{BBY diff --git a/firmware.packed.bin b/firmware.packed.bin index 45d7935dd1e42fcda53cd8da8e1a27f16b27c12c..11d02b793a163e514d7b78a012817a82b64373e1 100644 GIT binary patch delta 17937 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 aI7Lok5onn1FHe+4-mTrSJx3YaGCcv0Q_uDQ 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;