From 16434c8d14efcd2768bab5e409b4212c74af8167 Mon Sep 17 00:00:00 2001 From: OneOfEleven Date: Sun, 10 Sep 2023 13:52:41 +0100 Subject: [PATCH] clean up --- app/app.c | 5 +- driver/keyboard.c | 70 +++-- driver/keyboard.h | 44 +-- firmware | Bin 172692 -> 172692 bytes firmware.bin | Bin 57016 -> 56804 bytes firmware.packed.bin | Bin 57034 -> 56822 bytes font.c | 637 ++++++++++++++++++++++---------------------- font.h | 10 +- radio.c | 71 ++--- radio.h | 10 +- ui/helper.c | 35 ++- ui/lock.c | 1 + ui/main.c | 244 ++++++++--------- 13 files changed, 567 insertions(+), 560 deletions(-) diff --git a/app/app.c b/app/app.c index 8453ff5..cdb2e88 100644 --- a/app/app.c +++ b/app/app.c @@ -1661,9 +1661,8 @@ static void APP_ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) gUpdateStatus = true; } - if (gF_LOCK) - if (Key == KEY_PTT || Key == KEY_SIDE2 || Key == KEY_SIDE1) - return; + if (gF_LOCK && (Key == KEY_PTT || Key == KEY_SIDE2 || Key == KEY_SIDE1)) + return; if (!bFlag) { diff --git a/driver/keyboard.c b/driver/keyboard.c index cc19af6..ffc3422 100644 --- a/driver/keyboard.c +++ b/driver/keyboard.c @@ -37,33 +37,45 @@ KEY_Code_t KEYBOARD_Poll(void) SYSTICK_DelayUs(1); // Keys connected to gnd - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) + { Key = KEY_SIDE1; goto Bye; } - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) + { Key = KEY_SIDE2; goto Bye; } + // Original doesn't do PTT // First row GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4); SYSTICK_DelayUs(1); - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) { + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) + { Key = KEY_MENU; goto Bye; } - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) + { Key = KEY_1; goto Bye; } - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) + { Key = KEY_4; goto Bye; } - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) + { Key = KEY_7; goto Bye; } @@ -75,19 +87,26 @@ KEY_Code_t KEYBOARD_Poll(void) GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4); SYSTICK_DelayUs(1); - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) { + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) + { Key = KEY_UP; goto Bye; } - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) + { Key = KEY_2; goto Bye; } - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) + { Key = KEY_5; goto Bye; } - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) + { Key = KEY_8; goto Bye; } @@ -105,19 +124,26 @@ KEY_Code_t KEYBOARD_Poll(void) GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6); SYSTICK_DelayUs(1); - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) { + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) + { Key = KEY_DOWN; goto Bye; } - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) + { Key = KEY_3; goto Bye; } - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) + { Key = KEY_6; goto Bye; } - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) + { Key = KEY_9; goto Bye; } @@ -129,19 +155,26 @@ KEY_Code_t KEYBOARD_Poll(void) GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6); SYSTICK_DelayUs(1); - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) { + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) + { Key = KEY_EXIT; goto Bye; } - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) + { Key = KEY_STAR; goto Bye; } - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) + { Key = KEY_0; goto Bye; } - if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) { + + if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) + { Key = KEY_F; goto Bye; } @@ -154,4 +187,3 @@ Bye: return Key; } - diff --git a/driver/keyboard.h b/driver/keyboard.h index dba318d..36a5d3c 100644 --- a/driver/keyboard.h +++ b/driver/keyboard.h @@ -22,34 +22,34 @@ #include enum KEY_Code_t { - KEY_0 = 0, - KEY_1 = 1, - KEY_2 = 2, - KEY_3 = 3, - KEY_4 = 4, - KEY_5 = 5, - KEY_6 = 6, - KEY_7 = 7, - KEY_8 = 8, - KEY_9 = 9, - KEY_MENU = 10, - KEY_UP = 11, - KEY_DOWN = 12, - KEY_EXIT = 13, - KEY_STAR = 14, - KEY_F = 15, - KEY_PTT = 21, - KEY_SIDE2 = 22, - KEY_SIDE1 = 23, - KEY_INVALID = 255, + KEY_0 = 0, + KEY_1 = 1, + KEY_2 = 2, + KEY_3 = 3, + KEY_4 = 4, + KEY_5 = 5, + KEY_6 = 6, + KEY_7 = 7, + KEY_8 = 8, + KEY_9 = 9, + KEY_MENU = 10, + KEY_UP = 11, + KEY_DOWN = 12, + KEY_EXIT = 13, + KEY_STAR = 14, + KEY_F = 15, + KEY_PTT = 21, + KEY_SIDE2 = 22, + KEY_SIDE1 = 23, + KEY_INVALID = 255 }; typedef enum KEY_Code_t KEY_Code_t; extern KEY_Code_t gKeyReading0; extern KEY_Code_t gKeyReading1; -extern uint16_t gDebounceCounter; -extern bool gWasFKeyPressed; +extern uint16_t gDebounceCounter; +extern bool gWasFKeyPressed; KEY_Code_t KEYBOARD_Poll(void); diff --git a/firmware b/firmware index b7e296f92e14bc9ae64d68060c75613cf559945f..6f715c1d2b8a0b537017c821ec1fbca0a0ca86e8 100644 GIT binary patch delta 13474 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 S{`6|TP9y)fp|%_N)AWBPi@9t7 delta 13747 zcmZWw30&0G_P^)OFbs$aC<%fx3o0-!EbgSN8N-0P=DwsBrY6?&iDr&1`pn8qtV^P% z?^)rRQaWmBzBZS#7+bVxp|YlWnPa8D0cQDs?*Q@B|Ig3m{=Vm&d+xpGo_p@{8#lif zzWKfIjRnIi>ll+Mgvp2SPd;4!F-W>W!`ROejD<={3twU+!_jXJJ$gJqzdSdLzU5(! zj_yR8!sutmp>R^dcx9bqPiOj_DA)1AZPZI=NpgFfEBkzMW@BH~(r2poe zb$p*d_vvV(qr^%X|v1Axk z(NfWVIDJQ2adkMQ&{YwaP5Y@*oX#dYO%iwJ&}WJEhGAu|jLIr!7EP_rUD?3QS!KKa z#swlPm%7DYYpk-7F|lm3?b7lP_rIIS5aNE%H<;<&9>;^Zw1DWO_%@H?yUg`4v$?FG z*bIHTTGp4<#($@CuMtuCWG0OmkWZuNm}5;o#q)L+A2VCZ4CSHjuN-^tfD+!*?})vV zIup%v^eLph)b6#W5cji947IHnKUk?x$oa-l_cJ1l?+o@idlhh`RCAjV6l*WV~lU#7-as%@;!^P!m1v7%-7ah>nZL?m}IkI~;e>X`<(a zeKLJQtHih|Bw~+xIgGHt7LS^>waoo~12gE{>0ZI7QVu;O@~4usz0LPs&GJ}{sZXKK zeTOhkqs8>Scy=0@V}5}LEYvf@K&0RBz6kjrj{EK-*vd4s^)(T*8@ z5m%l*(JxO zduc7v|3ut;xJIhu^n7}d(_lx|LfK7+vF|IrZii+wQE_rjc0T% zODm*|5cgW~;u09+Zt=+yx=vjjXCI(`T557M{F4q*#~c34@_rVLGoV~-)Vi-aj+N6D zq9n&FE2zDOc8bFf!>(p=Xcc9L_V9k^;_gjCSw-6t6!dTJ`9R>S+|l;*!H!l< zHLuXRlf2@fo%-|p>Ks4WDV*AU-DqOTR(G7%eMvN}ruc}2CKF@E!A$G!(j-ie(0WqD z{zqs66$#Cwluc_L`HxZzr>`87A19}VHaRToFn~1C5qN?uM5l!1Nix!_qU1?9?l!SR zqNhZ~lQfK~h4V@3M-v?M6nMH*pEI`dbCLQqrH-jS!&s-oHw-z&dXtgmP@|ICXk>cR zutJS{n^(Twj2px?zy8z_*XgIhx6*$Szg} zyUCd6u$FaTU0~e;Q#Z!lPY2AbZ)Rc{HwQBRvnJfeO#gYz%u+I6UM4m5nDxWsW~R@a zGdslg(kuf@n*E>I0cCQ)bK>1Fgjnu)pptG7)r$FBD3QPZxmdpilkGLJcMJ8PL&CX* zO6<3lvMtZD2}RMRV<*+*wYxOFkd@|6I+UmTF=HB9{+sV~@5oCAc0G-e-jvQ( z*EA@xP3bJ#W}s8C+@w#Jl#b%XDvApm@1)AOS&_5)i~m+p9~vgER#AMrCw$NR#EiSr zsBD;s*-FMC`L0+-#?xt0Ib%bq>`dmSj#k&{-s`{U$_{3}o)NV!wv?H=vw$+9F>RLJ z6*Y^tbe*-^)wS%LShSVWZJlhDt9Wu3Cz-xnQegaYd1UdJ{L1vnvBp^}nb(fVE6Tl4 zQ()Y(q$s~KqbfG6sMD-~a@-qvf|AL}OqX3#R`JyOT1u^VD&pE!il4Kkkr@}-bcVPx zk22MVkW^~Pj4zK(U=~(OhEp|g4IeXx7(7Zba_K6cA}8PiA0QP* z{9BWOH7HGfw+og6zAP4RqnM6gG>tAcm&VUeEFH`|$|+H?jZ(UNf+fPEczrOi(W7u* zp&{4mQEJ2|+bF%;A&*BVC5+oK;Sxmtb~2Co)7M

W{O8~dgDi;dEVo$u7&89HxB4W?`tj^EW3HY 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 Dudv#? diff --git a/firmware.bin b/firmware.bin index c07ad4138e438db4da00691fe6889fb803f77b1e..92bb02a65e32a3853e9edc3ad2d24d940184240f 100644 GIT binary patch delta 7489 zcmaKRd0bP+_V~=r%BHwb0|7~HK$fU1QAAN$#aymi-72CMTiXZK`l5bYL#tkGUn{L$ z)Nw&kt5p=LRwTu(Vzss6^6X2rDr)-`Yc;Q}wQ+%)J>N4C-|zSR=L?_1S?0`{nKNh3 zoVgrnk^K6#Wc6_TaLtHYjLl`~i`Rx=v*lo@7{Z*sVfmu>1B^o~o1ROOv!~7?6bSqk z`2HytjsR`}c;({7e1KEdvzA|CUz1~vWvuSg2t3E~b2^86{@Wed64@N$xZi~xZcBFN zy-?o z?o;7JI-RL#j1G*+t!N;!s&C63ACMk}I;>V{1 zGY@Y#|~j| zGC45bfQMP`j32`Es1G2W!L(qU0frB;DjZ{oe&Po>o-|KghmE&U;VUhwf zRu`$BJQ1HDHz&v8nZz|Yj(OlGswo=$IvF~}gQr*qPaTV){oNM~c$?+$3#}N>B0}k9 zTudfS->5q7Wniguc{PkBwIatE7t+WbE)QYK^6+X>SZ0gp<-6TfrIN4%jB-Z=(a!ig zUP#u=&_z|9Luj57X|e#80R1}PcP!^-gyHCgz*dAJ4T_ZK(WW8Lv^@-Is>q)+|G*M* zeO4Uv#A9*Js>gV}Wk>mFj8|HIoBcI|lPq;}R$zR_lJsgNW_Dh)to_^j82?40EBE7p zme$He3`Ulmd9b9fEg!tzL&7i~vc+`2PqP!V>3jwkW6I!}%otO;5ogLANspUYW@@BWXqnnA|$wuG%xkwBywGTdh?Y9G6VGyW_^-etZ8nlRZn+7&;zPWW>|Zej_au^ca`8Az;X6?bR$5B`VUytL z7Jc<)jQd&wALuczCi+!cyqJt#rNgg~1wcC>uaGV8yq{H(2R}iYdLQ+3Y zeLfowTCe6#P2LzKt3`R(EvCA)NXd>cN*u3vDK#9Z@*p(~s50-cpyp7cTZ{^7W`lG> zussVXp45FDz%iumlXx6KzW?MJv;6|u_UWq>$ycZ1;g*cmNenI|rEB-cWd?Bn0k*-x zP?A`YR*9VA`2gd%6hMwgL`Np!pU7fThF4oIlXwil^?047*KYq1R>8-Z6nv~HvIS`v z$5zYH^)E8h>8ef#SB8+YS&F)$KH$S5HV!e4DFGcCXoxp4x`1Kldtp3ccfPAbDTdvP zV@xY_wdl@2bVzAbwt1}3qXKQ-fToo6tXN&jpz4CKwn;`*vAndpKz>C*18U6r%7EDD>hy|$SnN(O zUvBSFjyK1Ye_@X?T_CS-$(R(yV|LRrCWW!$6uAwtHx}HedcL3}|5B5peflycwYLoq zqcW88$X2AeUKKhfzi>j~<^?tB%95IlQk7bzE$>wx5F5RbEjaaeuwW;@ZBa*Ta3k$J zUapBYImH)9kF8O!obe&8Oyd-dfN4xv0b}6vd^jN-aD_*X`sHZ~6c95E@c;H`kV_Q( z4toa51-{)gb?j1&9_1UN&GEYEyvclYp;Nr#nJ`9Ip{|Ut$VN`_I9atdrO&@0l{-bJ z5B#fjihi$Alg~NDFUf_i8M6IOr}&uQZGG?^61`1}RU~Jd?)krbPsb?t1jII%q!#HJ zE7AnSL2gB(qa~K-(Anuu@uF8f4(8=OW{)vC#WUV$;BI>@cAR~($tix}J8E}|-}uhK z-yg_6OU_mAMD#AN5jQ2gsm*6;4)K-|34}!`n)${Nf)0 zrYaf&X# za*%@G)ubG}rJ%z$1kO22LUyS!PZD>fL|^nPK$3hFp|4;8j%K;`y~brQbSnAVuAz7r z*|94He@ZUwD(v&RU&*E*rk-)!a^9(^ES_j&h*NxtB-ZKh1j5w~7Vi7z7EfECL+=|@ z)uGxB@mJt$fUoZ2e*(U3!JnGSVuYPy-=ICZg4IqP`mjsqJm{!QI`mN&|1Gr%{AJZP)CPhC)lF(J%;X*YIsFZ9rVj7&HnS8f9=lM5$;e6bb*8Y#$P%U*YQy+`5 z<947!r^f9nsyD|cipjl7LhBQ9<~S8Ch?Vdi_RAqiV+1QR07B0r)XqjWBklW*YtbYl zcH{*jSvdOj*pU;Mz)`%4RMy8qQM9st1pbD6U!RCe$RG7_jNMN{8)ijueyo$Si1g9w zV6Tuv;&MT_Ep3PsCc9f85iS|IM#3tvkV}<{r9qJM8Qqv;Vv)W07*N+AKqe zgzSwscSCqBcFZT1FSx0QnD|Tx#=a#_9aK2 z@#4W>6+DJf=)6j=kVE@YyETANF~|`#45A17o@0LV68ZjtJ#60be2f{Tdaa0!fgIUE zM(x*Umbp-}#Jcd1Pkhe((ji*Tw^^4%c;rH$)Op*1T8l;i{h4<}FjW5XlF#>#kqz`a zMK^i8Kd~^;Q)dr|6@geVE=yHkN3cSsA;#nv&wJ*uD*k50q(WvhDUjN*#wT|3(4(Vd zL*a(Tj(o2M`9vux`*N`QAnXg>D;hBEtfP4?lpkk|YZ|fRIkNZ5A;LSp9?(-pj`7FF zO9|3R2t$~fCa$RO_WZ^%@1r~hMPI0ruQo1=K`2>jZ89P=N=DXIRm`SUuooY^=>9CFPft|k^c9=d5Ctmkdh`OV8v>L^=n z6=D@@>7FQT@|s9?F4rv`3yz=NSf?Pe+VMu5r8Ymo39458m^LLlhuaQjesI4W97Jk0 z^33L&Riq%xDyvmCsLVLsFYa_lXyx@GDgz2-C2&Exe5IhZbp{%MY-ieOx}m=EyDR#J z>SW1fZ5?8abIL1?ODg#nHRXJ@3dbA0MPPIgdWkrU4WK zFxMa_(x=@aP&^GlpLW>*!vWmDUj(=b(Cq?3G`Dv^PG12)&&yUYco1ls0wq9_NJ@a@cdwAX+cw+-&mc!>{AaOHJ#8UU|)j1sx^|1Ax74fqydGfOc0U*aiUjNt2Vdl(e>7Ql_ghZ zT%L;bvK#UmIr}QN06c?SdAc~rbVu${*=)`XvQFp0dpE1j+ZDBpUS^vKk-u#Q{lJo7 zm)5G6(r*yqY$>NfwL*GCJKg7H;5>B|)-SO#Ian`)!_||W$kl);n-jXc1(9Go+zts5 z{=)D!CCfwieb9c&nNxABf)w1Ly!!0G?e>!EyqQ-Cp=W(FkAxI0SGM;5fiH0Q8vBl7kj<=io?w1o|66o(}XT zfSo|!27C&D9@)&rpilsW8SuXVKdiV@-R%5zWF`z83%rtLI3BVY=8X0oz^^$^HXNGB zM7hcDhsJf^8tAE&>$DIjl|=#Z2^oDjkxBBA`G?}{u5c!nRpku3Mj%w+(%gKA#q2O27C>d z&C>(+)RZ&_UNug=`9@z!D!!hgkF@<4uSKeglTAKx1zB)3D(*+uKy%-bkDIVw-Bvj^ zwIYy;tn4ouWQLvmi0nL?7+(iZPR>cIgi?MUEQh|uI>b=lYbA4GL6?aAXimx)x7=Qt zQ-&^0pT%|B^C6)j{XOf95)3k`-R7NMQU==F34bgp#NnM(G8wpP^7gTf5&!mOR$z1q zQl4M@CyD<$PKbdGhUz+ZG`MgLzY@o}49uD;8P4wqz?$jH|fW+%hqw-m> z3<5qB&)H`P5ysn0OI~;SW0*I#FB~N;XNLDn3(zrT!%O`fD))97%d`9y&?y% z^NVF<=E?Y|`2W=+3%2BwH7C=0r1(VmD57XgZy5wdcn6g3wv&By@43=T(!u)JF6#rq z`Yrzn`+$;x+@4xc7zr%ETL!D7#WgGK{B512mGh5~&I=&u3(|Ja%cavFCt z0apMVh4v~~I*sKsK+gx6`3AXhY8S(L$?|WFLIWg}d*GN(fNvqS#VL^H3D7dI(hF$n zJTvHo0Nod4o#4E5z`p_h4dg!orWx=w;2)v?Jpd;FeZ3BZL^U6<1x9`eaAb2RuQE%L zWo?helmH`BhWVA^UHBy87mtwf-`Vh8qCH(G=zaZoRrM3`yFgM&61Zstx%ZC#~6Oc|?9}W2puSc*kgFVW6hDNRSDL=qN^BmGf z8K3fr9#QnTMX}Yr+x~|}+5opc?i6?X?`t9jR@p$A?f%P95*~nc(N`Mv0}VYInludG z1yBAbM1kG_plGI_G!zD`RUuJ)3j zAQd~NyD%JEQM}=iXbV7&uacL)*9vvcoN+nE4CEE3xxC^M0F{@46X+99xUh!N`ov={ zpV$chn(>LZJehns%0N(H5Auq6E@}Tx8`5~i*?|GU%QfECKZw;f8Ay-&<=PZur#Rc6 z4Bs|UB7IY4y88wHi^Eu*Vn2VPDdBHH_7SjrAkp*yUWyO>9pVVTTXPcTYICQv@NP7D z#X|u#|9gcLZ7z_vVO{iCJ-i?Hd4m7#fvH~)goDdF#s2;%{v3EyiBR53DT?{L%VVc* zSYA7`R4%*-*;oO;y#@G9NEK3h>Ut^Xyp+XF)l5K2g#>O=HXl+m8;eq7h1gW3a->p; zmYX20(I14$%i)8YQp$|X&(9x;3WPkgkmI;wZ9X^Fpz7UIh)fzaYShr-B^;NLuk8_{ z$b#0aVvbAci{L|m0Mi--Q&9G1^Lx`D7^%0C!KESck@+)A$1UmEqvsNVcA@rJfeu31 zd?6$x1cU7PMFLDiK>0#G(&XjmVu6|x^592cVi`e@DkFv9+-MIl`n-0Q5E7kI+z+f| zN(3xmNiHbo#%uC4@ws`~dATq5R`z~bA~j1TvrDf*Pe?8*%FZq-DoTbw$wKzz$&*z`xh#ZH?b@})EGVT?Gb&n|2NTR2frQB9B5)`; zYKheRg4Dc(Hq*}8UR6SZih`HQltwU$=g@^8eBU8F+05*>SB8IeG0l^5HeL OWLV-N%av<)qV#=Yn)~%I*9`8y_djRVzVHA4FTc4nXU^O?Gjrz5Ip=cz zJ=viy+14A$FWaV^;Uc`YQKTt?{M&XQQi|Z3du@A0{6R>O?Zq3$D241}0HM&OQ0`T1 zO+}o6u=MM%ixB=%c+B=w!ZIb!+2jzS4?MwEBP8u_1W@rE<|#I zkMdJy5)ZAP(n=nr(NoV7IlVMBja;H}1^Y-dJz8KT^XScm-zQl;Q|jKBk#7Nm%&v4b zdqAIGxBKsQDa|iR)L!&QTFg?WK)X zv&jJMtx6=-)KitnjSf-GT%Od@NppSVXxdo3uEV+zzhKJisem*?!6`C?rqOk_C=vQ{ZezgGMG~lqp>|QQgA($WL_J zLVfHnIIAnvz)wK<9qD@z|7kn6a1e?637h6f;2}m?$hszC*Umw}|3WX`_8ZBkr*2Q= z#`_xs3;ZX#rvvc>qiY!jCgUzb%zaulwO^yPXZxs#r# z?DTZ=E(O!6yLd@<8qy>7&Av zq45MEx7b2Y8VKp8hRr(iHm%&OC);T~(oa#kc?xNxj?I~5u8lmUC(7<00M`6K)1OYC z)%H2S@Xi6gutF{9ppbZ_bgvH7!jv+ZYrCIOHzL&>rY0jr{gcCzlghkOY*;c6xsBoe z2}nIoUwb-4{-CdINg_AVPq&=pV!om~p1F%5<<@larY(Ex7>+zltDE*EE(?*d8IIg= zD#`4iQ-fRjA|!J~y214a)zdkohpwUv$mg~bG>M=mSDv*E|5tFLpfbhRsZ0rVFci7_k{5`l9)9n!-%V^STb4;f$G5NQJ8)yMUaW_*1W zQI;irq^nCNM7{nqL5S_a(8_a0ifV)_csp^VyCq&N!&X>&`m8ovC+LP zDdYfkv{YJeFhk2Wm|H%~JbPY8@t~fnGB6j-J5a1VadfQw)H}v3h-(Z<$GxTc+> zH-*N&q?=UY)Bw>P%^F%bTSe+VH#Q9sokz!RIu#H5jql_PZPb`S7zH6|nm4P)>Ks}_ zTHo;ubIHR+yB0T%B855Wsq3 zHW;-QO#&FePWbK)OoagG6ueuiK+IC(JH!Orr2�g?NQe38M@7Vil$ihwa~eJa{Bu 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 CUxf?+ diff --git a/firmware.packed.bin b/firmware.packed.bin index 9b269faaf69ac0617eabac0041bc0ba60b3a9c2c..3f3decfe9965ab4800fb05452da6f0e7b7773511 100644 GIT binary patch delta 18446 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 A3jhEB delta 18660 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' - 0x3844041800100000, // '?' - - 0x003C449C945C201C, // '@' - 0x1818243C42420000, // 'A' - 0x7844784444780000, // 'B' - 0x3844808044380000, // 'C' - 0x7844444444780000, // 'D' - 0x7C407840407C0000, // 'E' - 0x7C40784040400000, // 'F' - 0x3844809C44380000, // 'G' - 0x42427E4242420000, // 'H' - 0x3E080808083E0000, // 'I' - 0x1C04040444380000, // 'J' - 0x4448507048440000, // 'K' - 0x40404040407E0000, // 'L' - 0x4163554941410000, // 'M' - 0x4262524A46420000, // 'N' - 0x1C222222221C0000, // 'O' - - 0x7844784040400000, // 'P' - 0x1C222222221C0200, // 'Q' - 0x7844785048440000, // 'R' - 0x1C22100C221C0000, // 'S' - 0x7F08080808080000, // 'T' - 0x42424242423C0000, // 'U' - 0x8142422424180000, // 'V' - 0x4141495563410000, // 'W' - 0x4224181824420000, // 'X' - 0x4122140808080000, // 'Y' - 0x7E040810207E0000, // 'Z' - 0x3820202020380000, // '[' - 0x4020100804020000, // '\' - 0x3808080808380000, // ']' - 0x1028000000000000, // '^' - 0x00000000007E0000, // '_' - - 0x1008000000000000, // '`' - 0x003C023E463A0000, // 'a' - 0x40407C42625C0000, // 'b' - 0x00001C20201C0000, // 'c' - 0x02023E42463A0000, // 'd' - 0x003C427E403C0000, // 'e' - 0x0018103810100000, // 'f' - 0x0000344C44340438, // 'g' - 0x2020382424240000, // 'h' - 0x0800080808080000, // 'i' - 0x0800180808080870, // 'j' - 0x20202428302C0000, // 'k' - 0x1010101010180000, // 'l' - 0x0000665A42420000, // 'm' - 0x00002E3222220000, // 'n' - 0x00003C42423C0000, // 'o' - - 0x00005C62427C4040, // 'p' - 0x00003A46423E0202, // 'q' - 0x00002C3220200000, // 'r' - 0x001C201804380000, // 's' - 0x00103C1010180000, // 't' - 0x00002222261A0000, // 'u' - 0x0000424224180000, // 'v' - 0x000081815A660000, // 'w' - 0x0000422418660000, // 'x' - 0x0000422214081060, // 'y' - 0x00003C08103C0000, // 'z' - 0x1C103030101C0000, // '{' - 0x0808080808080800, // '|' - 0x38080C0C08380000, // '}' - 0x000000324C000000, // '~' - 0x7E7E7E7E7E7E0000 // 'DEL' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'space' + {0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00}, // '!' + {0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '"' + {0x00, 0x28, 0x7C, 0x28, 0x7C, 0x28, 0x00, 0x00}, // '#' + {0x08, 0x1E, 0x28, 0x1C, 0x0A, 0x3C, 0x08, 0x00}, // '$' + {0x60, 0x94, 0x68, 0x16, 0x29, 0x06, 0x00, 0x00}, // '%' + {0x1C, 0x20, 0x20, 0x19, 0x26, 0x19, 0x00, 0x00}, // '&' + {0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ''' + {0x08, 0x10, 0x20, 0x20, 0x10, 0x08, 0x00, 0x00}, // '(' + {0x10, 0x08, 0x04, 0x04, 0x08, 0x10, 0x00, 0x00}, // ')' + {0x2A, 0x1C, 0x3E, 0x1C, 0x2A, 0x00, 0x00, 0x00}, // '*' + {0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00}, // '+' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00}, // ',' + {0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00}, // '-' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00}, // '.' + {0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00}, // '/' + {0x18, 0x24, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00}, // '0' + {0x08, 0x18, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00}, // '1' + {0x3C, 0x42, 0x04, 0x18, 0x20, 0x7E, 0x00, 0x00}, // '2' + {0x3C, 0x42, 0x04, 0x18, 0x42, 0x3C, 0x00, 0x00}, // '3' + {0x08, 0x18, 0x28, 0x48, 0x7C, 0x08, 0x00, 0x00}, // '4' + {0x7E, 0x40, 0x7C, 0x02, 0x42, 0x3C, 0x00, 0x00}, // '5' + {0x3C, 0x40, 0x7C, 0x42, 0x42, 0x3C, 0x00, 0x00}, // '6' + {0x7E, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00}, // '7' + {0x3C, 0x42, 0x3C, 0x42, 0x42, 0x3C, 0x00, 0x00}, // '8' + {0x3C, 0x42, 0x42, 0x3E, 0x02, 0x3C, 0x00, 0x00}, // '9' + {0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00}, // ':' + {0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x10, 0x00}, // ';' + {0x00, 0x06, 0x18, 0x60, 0x18, 0x06, 0x00, 0x00}, // '<' + {0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00}, // '=' + {0x00, 0x60, 0x18, 0x06, 0x18, 0x60, 0x00, 0x00}, // '>' + {0x38, 0x44, 0x04, 0x18, 0x00, 0x10, 0x00, 0x00}, // '?' + {0x00, 0x3C, 0x44, 0x9C, 0x94, 0x5C, 0x20, 0x1C}, // '@' + {0x18, 0x18, 0x24, 0x3C, 0x42, 0x42, 0x00, 0x00}, // 'A' + {0x78, 0x44, 0x78, 0x44, 0x44, 0x78, 0x00, 0x00}, // 'B' + {0x38, 0x44, 0x80, 0x80, 0x44, 0x38, 0x00, 0x00}, // 'C' + {0x78, 0x44, 0x44, 0x44, 0x44, 0x78, 0x00, 0x00}, // 'D' + {0x7C, 0x40, 0x78, 0x40, 0x40, 0x7C, 0x00, 0x00}, // 'E' + {0x7C, 0x40, 0x78, 0x40, 0x40, 0x40, 0x00, 0x00}, // 'F' + {0x38, 0x44, 0x80, 0x9C, 0x44, 0x38, 0x00, 0x00}, // 'G' + {0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x00, 0x00}, // 'H' + {0x3E, 0x08, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00}, // 'I' + {0x1C, 0x04, 0x04, 0x04, 0x44, 0x38, 0x00, 0x00}, // 'J' + {0x44, 0x48, 0x50, 0x70, 0x48, 0x44, 0x00, 0x00}, // 'K' + {0x40, 0x40, 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00}, // 'L' + {0x41, 0x63, 0x55, 0x49, 0x41, 0x41, 0x00, 0x00}, // 'M' + {0x42, 0x62, 0x52, 0x4A, 0x46, 0x42, 0x00, 0x00}, // 'N' + {0x1C, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x00}, // 'O' + {0x78, 0x44, 0x78, 0x40, 0x40, 0x40, 0x00, 0x00}, // 'P' + {0x1C, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x02, 0x00}, // 'Q' + {0x78, 0x44, 0x78, 0x50, 0x48, 0x44, 0x00, 0x00}, // 'R' + {0x1C, 0x22, 0x10, 0x0C, 0x22, 0x1C, 0x00, 0x00}, // 'S' + {0x7F, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, // 'T' + {0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00}, // 'U' + {0x81, 0x42, 0x42, 0x24, 0x24, 0x18, 0x00, 0x00}, // 'V' + {0x41, 0x41, 0x49, 0x55, 0x63, 0x41, 0x00, 0x00}, // 'W' + {0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x00, 0x00}, // 'X' + {0x41, 0x22, 0x14, 0x08, 0x08, 0x08, 0x00, 0x00}, // 'Y' + {0x7E, 0x04, 0x08, 0x10, 0x20, 0x7E, 0x00, 0x00}, // 'Z' + {0x38, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, 0x00}, // '[' + {0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00}, // '\' + {0x38, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00}, // ']' + {0x10, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '^' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00}, // '_' + {0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '`' + {0x00, 0x3C, 0x02, 0x3E, 0x46, 0x3A, 0x00, 0x00}, // 'a' + {0x40, 0x40, 0x7C, 0x42, 0x62, 0x5C, 0x00, 0x00}, // 'b' + {0x00, 0x00, 0x1C, 0x20, 0x20, 0x1C, 0x00, 0x00}, // 'c' + {0x02, 0x02, 0x3E, 0x42, 0x46, 0x3A, 0x00, 0x00}, // 'd' + {0x00, 0x3C, 0x42, 0x7E, 0x40, 0x3C, 0x00, 0x00}, // 'e' + {0x00, 0x18, 0x10, 0x38, 0x10, 0x10, 0x00, 0x00}, // 'f' + {0x00, 0x00, 0x34, 0x4C, 0x44, 0x34, 0x04, 0x38}, // 'g' + {0x20, 0x20, 0x38, 0x24, 0x24, 0x24, 0x00, 0x00}, // 'h' + {0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, // 'i' + {0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x70}, // 'j' + {0x20, 0x20, 0x24, 0x28, 0x30, 0x2C, 0x00, 0x00}, // 'k' + {0x10, 0x10, 0x10, 0x10, 0x10, 0x18, 0x00, 0x00}, // 'l' + {0x00, 0x00, 0x66, 0x5A, 0x42, 0x42, 0x00, 0x00}, // 'm' + {0x00, 0x00, 0x2E, 0x32, 0x22, 0x22, 0x00, 0x00}, // 'n' + {0x00, 0x00, 0x3C, 0x42, 0x42, 0x3C, 0x00, 0x00}, // 'o' + {0x00, 0x00, 0x5C, 0x62, 0x42, 0x7C, 0x40, 0x40}, // 'p' + {0x00, 0x00, 0x3A, 0x46, 0x42, 0x3E, 0x02, 0x02}, // 'q' + {0x00, 0x00, 0x2C, 0x32, 0x20, 0x20, 0x00, 0x00}, // 'r' + {0x00, 0x1C, 0x20, 0x18, 0x04, 0x38, 0x00, 0x00}, // 's' + {0x00, 0x10, 0x3C, 0x10, 0x10, 0x18, 0x00, 0x00}, // 't' + {0x00, 0x00, 0x22, 0x22, 0x26, 0x1A, 0x00, 0x00}, // 'u' + {0x00, 0x00, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00}, // 'v' + {0x00, 0x00, 0x81, 0x81, 0x5A, 0x66, 0x00, 0x00}, // 'w' + {0x00, 0x00, 0x42, 0x24, 0x18, 0x66, 0x00, 0x00}, // 'x' + {0x00, 0x00, 0x42, 0x22, 0x14, 0x08, 0x10, 0x60}, // 'y' + {0x00, 0x00, 0x3C, 0x08, 0x10, 0x3C, 0x00, 0x00}, // 'z' + {0x1C, 0x10, 0x30, 0x30, 0x10, 0x1C, 0x00, 0x00}, // '{' + {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00}, // '|' + {0x38, 0x08, 0x0C, 0x0C, 0x08, 0x38, 0x00, 0x00}, // '}' + {0x00, 0x00, 0x00, 0x32, 0x4C, 0x00, 0x00, 0x00} // '~' }; */ - -const uint8_t gFont6x8[96][6] = +const uint8_t gFont5x8[95][5] = { -{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, -{ 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00 }, -{ 0x00, 0x07, 0x00, 0x07, 0x00, 0x00 }, -{ 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00 }, -{ 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00 }, -{ 0x23, 0x13, 0x08, 0x64, 0x62, 0x00 }, -{ 0x36, 0x49, 0x56, 0x20, 0x50, 0x00 }, -{ 0x00, 0x08, 0x07, 0x03, 0x00, 0x00 }, -{ 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00 }, -{ 0x00, 0x41, 0x22, 0x1C, 0x00, 0x00 }, -{ 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00 }, -{ 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00 }, -{ 0x00, 0x80, 0x70, 0x30, 0x00, 0x00 }, -{ 0x08, 0x08, 0x08, 0x08, 0x08, 0x00 }, -{ 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 }, -{ 0x20, 0x10, 0x08, 0x04, 0x02, 0x00 }, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x5F, 0x00, 0x00}, + {0x00, 0x07, 0x00, 0x07, 0x00}, + {0x14, 0x7F, 0x14, 0x7F, 0x14}, + {0x24, 0x2A, 0x7F, 0x2A, 0x12}, + {0x23, 0x13, 0x08, 0x64, 0x62}, + {0x36, 0x49, 0x56, 0x20, 0x50}, + {0x00, 0x08, 0x07, 0x03, 0x00}, + {0x00, 0x1C, 0x22, 0x41, 0x00}, + {0x00, 0x41, 0x22, 0x1C, 0x00}, + {0x2A, 0x1C, 0x7F, 0x1C, 0x2A}, + {0x08, 0x08, 0x3E, 0x08, 0x08}, + {0x00, 0x80, 0x70, 0x30, 0x00}, + {0x08, 0x08, 0x08, 0x08, 0x08}, + {0x00, 0x00, 0x60, 0x60, 0x00}, + {0x20, 0x10, 0x08, 0x04, 0x02}, -//{ 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00 }, -{ 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00 }, -{ 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00 }, -{ 0x72, 0x49, 0x49, 0x49, 0x46, 0x00 }, -{ 0x21, 0x41, 0x49, 0x4D, 0x33, 0x00 }, -{ 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00 }, -{ 0x27, 0x45, 0x45, 0x45, 0x39, 0x00 }, -{ 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00 }, -{ 0x41, 0x21, 0x11, 0x09, 0x07, 0x00 }, -{ 0x36, 0x49, 0x49, 0x49, 0x36, 0x00 }, -{ 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00 }, -{ 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 }, -{ 0x00, 0x40, 0x34, 0x00, 0x00, 0x00 }, -{ 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 }, -{ 0x14, 0x14, 0x14, 0x14, 0x14, 0x00 }, -{ 0x00, 0x41, 0x22, 0x14, 0x08, 0x00 }, -{ 0x02, 0x01, 0x59, 0x09, 0x06, 0x00 }, + {0x3E, 0x41, 0x41, 0x41, 0x3E}, + {0x00, 0x42, 0x7F, 0x40, 0x00}, + {0x72, 0x49, 0x49, 0x49, 0x46}, + {0x21, 0x41, 0x49, 0x4D, 0x33}, + {0x18, 0x14, 0x12, 0x7F, 0x10}, + {0x27, 0x45, 0x45, 0x45, 0x39}, + {0x3C, 0x4A, 0x49, 0x49, 0x31}, + {0x41, 0x21, 0x11, 0x09, 0x07}, + {0x36, 0x49, 0x49, 0x49, 0x36}, + {0x46, 0x49, 0x49, 0x29, 0x1E}, + {0x00, 0x00, 0x14, 0x00, 0x00}, + {0x00, 0x40, 0x34, 0x00, 0x00}, + {0x00, 0x08, 0x14, 0x22, 0x41}, + {0x14, 0x14, 0x14, 0x14, 0x14}, + {0x00, 0x41, 0x22, 0x14, 0x08}, + {0x02, 0x01, 0x59, 0x09, 0x06}, -{ 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00 }, -{ 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00 }, -{ 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00 }, -{ 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00 }, -{ 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00 }, -{ 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00 }, -{ 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00 }, -{ 0x3E, 0x41, 0x41, 0x51, 0x73, 0x00 }, -{ 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00 }, -{ 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00 }, -{ 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00 }, -{ 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00 }, -{ 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00 }, -{ 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00 }, -{ 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00 }, -{ 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00 }, + {0x3E, 0x41, 0x5D, 0x59, 0x4E}, + {0x7C, 0x12, 0x11, 0x12, 0x7C}, + {0x7F, 0x49, 0x49, 0x49, 0x36}, + {0x3E, 0x41, 0x41, 0x41, 0x22}, + {0x7F, 0x41, 0x41, 0x41, 0x3E}, + {0x7F, 0x49, 0x49, 0x49, 0x41}, + {0x7F, 0x09, 0x09, 0x09, 0x01}, + {0x3E, 0x41, 0x41, 0x51, 0x73}, + {0x7F, 0x08, 0x08, 0x08, 0x7F}, + {0x00, 0x41, 0x7F, 0x41, 0x00}, + {0x20, 0x40, 0x41, 0x3F, 0x01}, + {0x7F, 0x08, 0x14, 0x22, 0x41}, + {0x7F, 0x40, 0x40, 0x40, 0x40}, + {0x7F, 0x02, 0x1C, 0x02, 0x7F}, + {0x7F, 0x04, 0x08, 0x10, 0x7F}, + {0x3E, 0x41, 0x41, 0x41, 0x3E}, -{ 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00 }, -{ 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00 }, -{ 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00 }, -{ 0x26, 0x49, 0x49, 0x49, 0x32, 0x00 }, -{ 0x03, 0x01, 0x7F, 0x01, 0x03, 0x00 }, -{ 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00 }, -{ 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00 }, -{ 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00 }, -{ 0x63, 0x14, 0x08, 0x14, 0x63, 0x00 }, -{ 0x03, 0x04, 0x78, 0x04, 0x03, 0x00 }, -{ 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00 }, -{ 0x00, 0x7F, 0x41, 0x41, 0x41, 0x00 }, -{ 0x02, 0x04, 0x08, 0x10, 0x20, 0x00 }, -{ 0x00, 0x41, 0x41, 0x41, 0x7F, 0x00 }, -{ 0x04, 0x02, 0x01, 0x02, 0x04, 0x00 }, -{ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00 }, + {0x7F, 0x09, 0x09, 0x09, 0x06}, + {0x3E, 0x41, 0x51, 0x21, 0x5E}, + {0x7F, 0x09, 0x19, 0x29, 0x46}, + {0x26, 0x49, 0x49, 0x49, 0x32}, + {0x03, 0x01, 0x7F, 0x01, 0x03}, + {0x3F, 0x40, 0x40, 0x40, 0x3F}, + {0x1F, 0x20, 0x40, 0x20, 0x1F}, + {0x3F, 0x40, 0x38, 0x40, 0x3F}, + {0x63, 0x14, 0x08, 0x14, 0x63}, + {0x03, 0x04, 0x78, 0x04, 0x03}, + {0x61, 0x59, 0x49, 0x4D, 0x43}, + {0x00, 0x7F, 0x41, 0x41, 0x41}, + {0x02, 0x04, 0x08, 0x10, 0x20}, + {0x00, 0x41, 0x41, 0x41, 0x7F}, + {0x04, 0x02, 0x01, 0x02, 0x04}, + {0x40, 0x40, 0x40, 0x40, 0x40}, -{ 0x00, 0x03, 0x07, 0x08, 0x00, 0x00 }, -{ 0x20, 0x54, 0x54, 0x78, 0x40, 0x00 }, -{ 0x7F, 0x28, 0x44, 0x44, 0x38, 0x00 }, -{ 0x38, 0x44, 0x44, 0x44, 0x28, 0x00 }, -{ 0x38, 0x44, 0x44, 0x28, 0x7F, 0x00 }, -{ 0x38, 0x54, 0x54, 0x54, 0x18, 0x00 }, -{ 0x00, 0x08, 0x7E, 0x09, 0x02, 0x00 }, -{ 0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x00 }, -{ 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00 }, -{ 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00 }, -{ 0x20, 0x40, 0x40, 0x3D, 0x00, 0x00 }, -{ 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00 }, -{ 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00 }, -{ 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00 }, -{ 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00 }, -{ 0x38, 0x44, 0x44, 0x44, 0x38, 0x00 }, + {0x00, 0x03, 0x07, 0x08, 0x00}, + {0x20, 0x54, 0x54, 0x78, 0x40}, + {0x7F, 0x28, 0x44, 0x44, 0x38}, + {0x38, 0x44, 0x44, 0x44, 0x28}, + {0x38, 0x44, 0x44, 0x28, 0x7F}, + {0x38, 0x54, 0x54, 0x54, 0x18}, + {0x00, 0x08, 0x7E, 0x09, 0x02}, + {0x18, 0xA4, 0xA4, 0x9C, 0x78}, + {0x7F, 0x08, 0x04, 0x04, 0x78}, + {0x00, 0x44, 0x7D, 0x40, 0x00}, + {0x20, 0x40, 0x40, 0x3D, 0x00}, + {0x7F, 0x10, 0x28, 0x44, 0x00}, + {0x00, 0x41, 0x7F, 0x40, 0x00}, + {0x7C, 0x04, 0x78, 0x04, 0x78}, + {0x7C, 0x08, 0x04, 0x04, 0x78}, + {0x38, 0x44, 0x44, 0x44, 0x38}, -{ 0xFC, 0x18, 0x24, 0x24, 0x18, 0x00 }, -{ 0x18, 0x24, 0x24, 0x18, 0xFC, 0x00 }, -{ 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00 }, -{ 0x48, 0x54, 0x54, 0x54, 0x24, 0x00 }, -{ 0x04, 0x04, 0x3F, 0x44, 0x24, 0x00 }, -{ 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00 }, -{ 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00 }, -{ 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00 }, -{ 0x44, 0x28, 0x10, 0x28, 0x44, 0x00 }, -{ 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00 }, -{ 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00 }, -{ 0x00, 0x08, 0x36, 0x41, 0x00, 0x00 }, -{ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00 }, -{ 0x00, 0x41, 0x36, 0x08, 0x00, 0x00 }, -{ 0x02, 0x01, 0x02, 0x04, 0x02, 0x00 }, -{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + {0xFC, 0x18, 0x24, 0x24, 0x18}, + {0x18, 0x24, 0x24, 0x18, 0xFC}, + {0x7C, 0x08, 0x04, 0x04, 0x08}, + {0x48, 0x54, 0x54, 0x54, 0x24}, + {0x04, 0x04, 0x3F, 0x44, 0x24}, + {0x3C, 0x40, 0x40, 0x20, 0x7C}, + {0x1C, 0x20, 0x40, 0x20, 0x1C}, + {0x3C, 0x40, 0x30, 0x40, 0x3C}, + {0x44, 0x28, 0x10, 0x28, 0x44}, + {0x4C, 0x90, 0x90, 0x90, 0x7C}, + {0x44, 0x64, 0x54, 0x4C, 0x44}, + {0x00, 0x08, 0x36, 0x41, 0x00}, + {0x00, 0x00, 0x77, 0x00, 0x00}, + {0x00, 0x41, 0x36, 0x08, 0x00}, + {0x02, 0x01, 0x02, 0x04, 0x02} }; /* // ASCII 5x7 font @@ -374,7 +368,6 @@ const uint8_t gFont5x7[96][5] = {0x00, 0x00, 0x60, 0x60, 0x00}, {0x20, 0x10, 0x08, 0x04, 0x02}, -// {0x3E, 0x51, 0x49, 0x45, 0x3E}, // '0' {0x3E, 0x41, 0x41, 0x41, 0x3E}, // '0' {0x00, 0x42, 0x7F, 0x40, 0x00}, {0x72, 0x49, 0x49, 0x49, 0x46}, diff --git a/font.h b/font.h index c525ff6..bf7cd0d 100644 --- a/font.h +++ b/font.h @@ -19,12 +19,12 @@ #include -extern const uint8_t gFontBig[95][16]; -extern const uint8_t gFontBigDigits[11][26]; -extern const uint8_t gFontSmallDigits[11][7]; +extern const uint8_t gFontBig[95][16]; +extern const uint8_t gFontBigDigits[11][26]; +extern const uint8_t gFontSmallDigits[11][7]; -//extern const uint64_t gFont8x8[16 * 6]; -extern const uint8_t gFont6x8[96][6]; +//extern const uint8_t gFont8x8[95][8]; +extern const uint8_t gFont5x8[95][5]; //extern const uint8_t gFont5x7[96][5]; #endif diff --git a/radio.c b/radio.c index b3af4b4..ec0e34a 100644 --- a/radio.c +++ b/radio.c @@ -116,7 +116,7 @@ void RADIO_InitInfo(VFO_Info_t *pInfo, uint8_t ChannelSave, uint8_t Band, uint32 pInfo->Band = Band; pInfo->SCANLIST1_PARTICIPATION = true; pInfo->SCANLIST2_PARTICIPATION = true; - pInfo->STEP_SETTING = STEP_25_0kHz; + pInfo->STEP_SETTING = STEP_12_5kHz; // STEP_25_0kHz; pInfo->StepFrequency = 2500; pInfo->CHANNEL_SAVE = ChannelSave; pInfo->FrequencyReverse = false; @@ -137,8 +137,6 @@ void RADIO_ConfigureChannel(uint8_t VFO, uint32_t Arg) uint8_t Band; bool bParticipation2; uint16_t Base; - uint8_t Data[8]; - uint8_t Tmp; uint32_t Frequency; VFO_Info_t *pRadio = &gEeprom.VfoInfo[VFO]; @@ -199,8 +197,8 @@ void RADIO_ConfigureChannel(uint8_t VFO, uint32_t Arg) } Index = Channel - FREQ_CHANNEL_FIRST; - RADIO_InitInfo(pRadio, Channel, Index, gLowerLimitFrequencyBandTable[Index]); + RADIO_InitInfo(pRadio, Channel, Index, gLowerLimitFrequencyBandTable[Index]); return; } @@ -232,27 +230,28 @@ void RADIO_ConfigureChannel(uint8_t VFO, uint32_t Arg) if (Arg == 2 || Channel >= FREQ_CHANNEL_FIRST) { - EEPROM_ReadBuffer(Base + 8, Data, 8); + uint8_t Tmp; + uint8_t Data[8]; + + EEPROM_ReadBuffer(Base + 8, Data, sizeof(Data)); Tmp = Data[3] & 0x0F; if (Tmp > 2) Tmp = 0; - gEeprom.VfoInfo[VFO].FREQUENCY_DEVIATION_SETTING = Tmp; gEeprom.VfoInfo[VFO].AM_CHANNEL_MODE = !!(Data[3] & 0x10); Tmp = Data[6]; if (Tmp > STEP_8_33kHz) Tmp = STEP_25_0kHz; - gEeprom.VfoInfo[VFO].STEP_SETTING = Tmp; gEeprom.VfoInfo[VFO].StepFrequency = StepFrequencyTable[Tmp]; Tmp = Data[7]; if (Tmp > 10) Tmp = 0; + gEeprom.VfoInfo[VFO].SCRAMBLING_TYPE = Tmp; - gEeprom.VfoInfo[VFO].SCRAMBLING_TYPE = Tmp; gEeprom.VfoInfo[VFO].ConfigRX.CodeType = (Data[2] >> 0) & 0x0F; gEeprom.VfoInfo[VFO].ConfigTX.CodeType = (Data[2] >> 4) & 0x0F; @@ -307,10 +306,11 @@ void RADIO_ConfigureChannel(uint8_t VFO, uint32_t Arg) } else { - gEeprom.VfoInfo[VFO].FrequencyReverse = !!(Data[4] & 1u); - gEeprom.VfoInfo[VFO].CHANNEL_BANDWIDTH = !!(Data[4] & 2u); - gEeprom.VfoInfo[VFO].OUTPUT_POWER = (Data[4] >> 2) & 3u; - gEeprom.VfoInfo[VFO].BUSY_CHANNEL_LOCK = !!(Data[4] & 0x10); + const uint8_t d4 = Data[4]; + gEeprom.VfoInfo[VFO].FrequencyReverse = !!(d4 & 0x01); + gEeprom.VfoInfo[VFO].CHANNEL_BANDWIDTH = !!(d4 & 0x02); + gEeprom.VfoInfo[VFO].OUTPUT_POWER = (d4 >> 2) & 0x03; + gEeprom.VfoInfo[VFO].BUSY_CHANNEL_LOCK = !!(d4 & 0x10); } if (Data[5] == 0xFF) @@ -320,17 +320,17 @@ void RADIO_ConfigureChannel(uint8_t VFO, uint32_t Arg) } else { - gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = !!(Data[5] & 1u); - gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = (Data[5] >> 1) & 3u; + gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = !!(Data[5] & 0x01); + gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = (Data[5] >> 1) & 0x03; } struct { uint32_t Frequency; uint32_t Offset; - } Info; + } __attribute__((packed)) Info; - EEPROM_ReadBuffer(Base, &Info, 8); + EEPROM_ReadBuffer(Base, &Info, sizeof(Info)); pRadio->ConfigRX.Frequency = Info.Frequency; @@ -341,24 +341,23 @@ void RADIO_ConfigureChannel(uint8_t VFO, uint32_t Arg) } Frequency = pRadio->ConfigRX.Frequency; + + // TODO: FIX-ME !!! if (Frequency < gLowerLimitFrequencyBandTable[Band]) - pRadio->ConfigRX.Frequency = gLowerLimitFrequencyBandTable[Band]; + Frequency = gLowerLimitFrequencyBandTable[Band]; else if (Frequency > gUpperLimitFrequencyBandTable[Band]) - pRadio->ConfigRX.Frequency = gUpperLimitFrequencyBandTable[Band]; + Frequency = gUpperLimitFrequencyBandTable[Band]; else if (Channel >= FREQ_CHANNEL_FIRST) - pRadio->ConfigRX.Frequency = FREQUENCY_FloorToStep(pRadio->ConfigRX.Frequency, gEeprom.VfoInfo[VFO].StepFrequency, gLowerLimitFrequencyBandTable[Band]); + Frequency = FREQUENCY_FloorToStep(Frequency, gEeprom.VfoInfo[VFO].StepFrequency, gLowerLimitFrequencyBandTable[Band]); pRadio->ConfigRX.Frequency = Frequency; if (Frequency >= 10800000 && Frequency < 13600000) gEeprom.VfoInfo[VFO].FREQUENCY_DEVIATION_SETTING = FREQUENCY_DEVIATION_OFF; else if (!IS_MR_CHANNEL(Channel)) - { - Frequency = FREQUENCY_FloorToStep(gEeprom.VfoInfo[VFO].FREQUENCY_OF_DEVIATION, gEeprom.VfoInfo[VFO].StepFrequency, 0); - gEeprom.VfoInfo[VFO].FREQUENCY_OF_DEVIATION = Frequency; - } + gEeprom.VfoInfo[VFO].FREQUENCY_OF_DEVIATION = FREQUENCY_FloorToStep(gEeprom.VfoInfo[VFO].FREQUENCY_OF_DEVIATION, gEeprom.VfoInfo[VFO].StepFrequency, 0); RADIO_ApplyOffset(pRadio); @@ -466,6 +465,7 @@ void RADIO_ApplyOffset(VFO_Info_t *pInfo) break; } + // limit to 50MHz to 600MHz if (Frequency < 5000000) Frequency = 5000000; else @@ -494,13 +494,12 @@ void RADIO_SelectVfos(void) if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A) gEeprom.TX_CHANNEL = 0; - gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_CHANNEL]; - if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) gEeprom.RX_CHANNEL = gEeprom.TX_CHANNEL; else gEeprom.RX_CHANNEL = (gEeprom.TX_CHANNEL == 0) ? 1 : 0; + gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_CHANNEL]; gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_CHANNEL]; RADIO_SelectCurrentVfo(); @@ -509,11 +508,11 @@ void RADIO_SelectVfos(void) void RADIO_SetupRegisters(bool bSwitchToFunction0) { BK4819_FilterBandwidth_t Bandwidth; - uint16_t Status; uint16_t InterruptMask; uint32_t Frequency; GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); + gEnableSpeaker = false; BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, false); @@ -521,17 +520,18 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0) Bandwidth = gRxVfo->CHANNEL_BANDWIDTH; if (Bandwidth != BK4819_FILTER_BW_WIDE) Bandwidth = BK4819_FILTER_BW_NARROW; - BK4819_SetFilterBandwidth(Bandwidth); BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, false); + BK4819_SetupPowerAmplifier(0, 0); + BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, false); while (1) { - Status = BK4819_ReadRegister(BK4819_REG_0C); - if ((Status & 1U) == 0) // INTERRUPT REQUEST + const uint16_t Status = BK4819_ReadRegister(BK4819_REG_0C); + if ((Status & 1u) == 0) // INTERRUPT REQUEST break; BK4819_WriteRegister(BK4819_REG_02, 0); @@ -559,8 +559,12 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0) gRxVfo->SquelchCloseNoiseThresh, gRxVfo->SquelchCloseGlitchThresh, gRxVfo->SquelchOpenGlitchThresh); + BK4819_PickRXFilterPathBasedOnFrequency(Frequency); + BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, true); + + // AF Rx Gain and DAC BK4819_WriteRegister(BK4819_REG_48, 0xB3A8); InterruptMask = 0 | BK4819_REG_3F_SQUELCH_FOUND | BK4819_REG_3F_SQUELCH_LOST; @@ -571,11 +575,8 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0) { if (!gRxVfo->IsAM) { - uint8_t CodeType; - uint8_t Code; - - CodeType = gSelectedCodeType; - Code = gSelectedCode; + uint8_t CodeType = gSelectedCodeType; + uint8_t Code = gSelectedCode; if (gCssScanMode == CSS_SCAN_MODE_OFF) { CodeType = gRxVfo->pRX->CodeType; @@ -655,6 +656,8 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0) BK4819_EnableDTMF(); InterruptMask |= BK4819_REG_3F_DTMF_5TONE_FOUND; } + + // enable/disable BK4819 interrupts BK4819_WriteRegister(BK4819_REG_3F, InterruptMask); FUNCTION_Init(); diff --git a/radio.h b/radio.h index 20ffca9..9dc48ab 100644 --- a/radio.h +++ b/radio.h @@ -48,7 +48,8 @@ enum PTT_ID_t { typedef enum PTT_ID_t PTT_ID_t; #if 0 - enum STEP_Setting_t { + enum STEP_Setting_t + { STEP_2_5kHz, STEP_5_0kHz, STEP_6_25kHz, @@ -58,7 +59,8 @@ typedef enum PTT_ID_t PTT_ID_t; STEP_8_33kHz, }; #else - enum STEP_Setting_t { + enum STEP_Setting_t + { STEP_1_25kHz, STEP_2_5kHz, STEP_6_25kHz, @@ -71,7 +73,8 @@ typedef enum PTT_ID_t PTT_ID_t; typedef enum STEP_Setting_t STEP_Setting_t; -enum VfoState_t { +enum VfoState_t +{ VFO_STATE_NORMAL = 0, VFO_STATE_BUSY, VFO_STATE_BAT_LOW, @@ -156,4 +159,3 @@ void RADIO_PrepareCssTX(void); void RADIO_SendEndOfTransmission(void); #endif - diff --git a/ui/helper.c b/ui/helper.c index 8adfee0..543170f 100644 --- a/ui/helper.c +++ b/ui/helper.c @@ -92,50 +92,49 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_ #if 0 { // 5x7 font + const unsigned int char_width = ARRAY_SIZE(gFont5x7[0]); + const unsigned int char_spacing = char_width + 1; + uint8_t *pFb = gFrameBuffer[Line] + Start; for (i = 0; i < Length; i++) { if (pString[i] >= 32) { const unsigned int Index = ((unsigned int)pString[i] - 32); if (Index < ARRAY_SIZE(gFont5x7)) - { - const unsigned int ofs = (unsigned int)Start + (i * 6); - memcpy(gFrameBuffer[Line] + ofs, &gFont5x7[Index], ARRAY_SIZE(gFont5x7[Index])); - } + memcpy(pfB + (i * char_spacing), &gFont5x7[Index], char_width); } } } - #else - { // 6x8 font + #elif 1 + { // 5x8 font + const unsigned int char_width = ARRAY_SIZE(gFont5x8[0]); + const unsigned int char_spacing = char_width + 1; + uint8_t *pFb = gFrameBuffer[Line] + Start; for (i = 0; i < Length; i++) { if (pString[i] >= 32) { const unsigned int Index = (unsigned int)pString[i] - 32; - if (Index < ARRAY_SIZE(gFont6x8)) - { - const unsigned int ofs = (unsigned int)Start + (i * 7); - memcpy(gFrameBuffer[Line] + ofs, &gFont6x8[Index], ARRAY_SIZE(gFont6x8[Index])); - } + if (Index < ARRAY_SIZE(gFont5x8)) + memcpy(pFb + (i * char_spacing), &gFont5x8[Index], char_width); } } } -/* - { // 8x8 font + #else + { // 8x8 font .. not yet working + const unsigned int char_width = ARRAY_SIZE(gFont8x8[0]); + const unsigned int char_spacing = char_width + 1; + uint8_t *pFb = gFrameBuffer[Line] + Start; for (i = 0; i < Length; i++) { if (pString[i] >= 32) { const unsigned int Index = (unsigned int)pString[i] - 32; if (Index < ARRAY_SIZE(gFont8x8)) - { - const unsigned int ofs = (unsigned int)Start + (i * 8); - memcpy(gFrameBuffer[Line] + ofs, &gFont8x8[Index], 8); - } + memcpy(pFb + (i * char_spacing), &gFont8x8[Index], char_width); } } } -*/ #endif } diff --git a/ui/lock.c b/ui/lock.c index b45b794..4856f69 100644 --- a/ui/lock.c +++ b/ui/lock.c @@ -15,6 +15,7 @@ */ #include + #include "ARMCM0.h" #include "app/uart.h" #include "audio.h" diff --git a/ui/main.c b/ui/main.c index 17ee218..9fc29cb 100644 --- a/ui/main.c +++ b/ui/main.c @@ -43,11 +43,13 @@ void UI_DisplayMain(void) return; } -//#ifndef SINGLE_VFO_CHAN +// #ifdef SINGLE_VFO_CHAN +// const bool single_vfo = (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? true : false; +// #else + const bool single_vfo = false; +// #endif + for (vfo_num = 0; vfo_num < 2; vfo_num++) -//#else -// vfo_num = 0; -//#endif { uint8_t Channel = gEeprom.TX_CHANNEL; bool bIsSameVfo = !!(Channel == vfo_num); @@ -55,7 +57,17 @@ void UI_DisplayMain(void) uint8_t *pLine0 = gFrameBuffer[Line + 0]; uint8_t *pLine1 = gFrameBuffer[Line + 1]; uint32_t frequency_Hz = 0; + + if (single_vfo) + { + if (!bIsSameVfo) + continue; // skip the unused vfo .. screen is dedicated to just a single VFO + //Line = 1; + //pLine0 = gFrameBuffer[Line + 0]; + //pLine1 = gFrameBuffer[Line + 1]; + } + if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF && gRxVfoIsActive) Channel = gEeprom.RX_CHANNEL; @@ -67,73 +79,53 @@ void UI_DisplayMain(void) if (!gDTMF_InputMode) { + memset(Contact, 0, sizeof(Contact)); if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT) - { - if (gDTMF_State == DTMF_STATE_CALL_OUT_RSP) - strcpy(String, "CALL OUT(RSP)"); - else - strcpy(String, "CALL OUT"); - } + strcpy(String, (gDTMF_State == DTMF_STATE_CALL_OUT_RSP) ? "CALL OUT(RSP)" : "CALL OUT"); else if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED) - { - if (DTMF_FindContact(gDTMF_Caller, Contact)) - sprintf(String, "CALL:%s", Contact); - else - sprintf(String, "CALL:%s", gDTMF_Caller); - } + sprintf(String, "CALL:%s", (DTMF_FindContact(gDTMF_Caller, Contact)) ? Contact : gDTMF_Caller); else if (gDTMF_IsTx) - { - if (gDTMF_State == DTMF_STATE_TX_SUCC) - strcpy(String, "DTMF TX(SUCC)"); - else - strcpy(String, "DTMF TX"); - } + strcpy(String, (gDTMF_State == DTMF_STATE_TX_SUCC) ? "DTMF TX(SUCC)" : "DTMF TX"); } else sprintf(String, ">%s", gDTMF_InputBox); - UI_PrintString(String, 2, 127, vfo_num * 3, 8, false); memset(String, 0, sizeof(String)); - memset(Contact, 0, sizeof(Contact)); - if (!gDTMF_InputMode) { + memset(Contact, 0, sizeof(Contact)); if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT) { - if (DTMF_FindContact(gDTMF_String, Contact)) - sprintf(String, ">%s", Contact); - else - sprintf(String, ">%s", gDTMF_String); + sprintf(String, ">%s", (DTMF_FindContact(gDTMF_String, Contact)) ? Contact : gDTMF_String); } else if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED) { - if (DTMF_FindContact(gDTMF_Callee, Contact)) - sprintf(String, ">%s", Contact); - else - sprintf(String, ">%s", gDTMF_Callee); + sprintf(String, ">%s", (DTMF_FindContact(gDTMF_Callee, Contact)) ? Contact : gDTMF_Callee); } else if (gDTMF_IsTx) sprintf(String, ">%s", gDTMF_String); } - UI_PrintString(String, 2, 127, 2 + (vfo_num * 3), 8, false); + continue; } - if (bIsSameVfo) + // highlight the selected/used VFO with a marker + if (!single_vfo && bIsSameVfo) memcpy(pLine0 + 2, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default)); } else - { + if (!single_vfo) + { // highlight the selected/used VFO with a marker if (bIsSameVfo) memcpy(pLine0 + 2, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default)); - else - memcpy(pLine0 + 2, BITMAP_VFO_NotDefault, sizeof(BITMAP_VFO_NotDefault)); + //else + //memcpy(pLine0 + 2, BITMAP_VFO_NotDefault, sizeof(BITMAP_VFO_NotDefault)); } // 0x8EE2 @@ -149,29 +141,23 @@ void UI_DisplayMain(void) else #endif { - if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) - Channel = gEeprom.RX_CHANNEL; - else - Channel = gEeprom.TX_CHANNEL; - + Channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_CHANNEL : gEeprom.TX_CHANNEL; if (Channel == vfo_num) - { + { // show the TX symbol SomeValue = 1; memcpy(pLine0 + 14, BITMAP_TX, sizeof(BITMAP_TX)); } } } else - { + { // show the RX symbol SomeValue = 2; - if ((gCurrentFunction == FUNCTION_RECEIVE || gCurrentFunction == FUNCTION_MONITOR) && gEeprom.RX_CHANNEL == vfo_num) memcpy(pLine0 + 14, BITMAP_RX, sizeof(BITMAP_RX)); } - // 0x8F3C if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num])) - { + { // show the mrmory channel number memcpy(pLine1 + 2, BITMAP_M, sizeof(BITMAP_M)); if (gInputBoxIndex == 0 || gEeprom.TX_CHANNEL != vfo_num) NUMBER_ToDigits(gEeprom.ScreenChannel[vfo_num] + 1, String); @@ -181,7 +167,7 @@ void UI_DisplayMain(void) } else if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num])) - { + { // show the frequency band number char c; memcpy(pLine1 + 14, BITMAP_F, sizeof(BITMAP_F)); c = (gEeprom.ScreenChannel[vfo_num] - FREQ_CHANNEL_FIRST) + 1; @@ -189,7 +175,9 @@ void UI_DisplayMain(void) } else { + // show the 'N' narrow band symbol memcpy(pLine1 + 7, BITMAP_NarrowBand, sizeof(BITMAP_NarrowBand)); + if (gInputBoxIndex == 0 || gEeprom.TX_CHANNEL != vfo_num) { NUMBER_ToDigits((gEeprom.ScreenChannel[vfo_num] - NOAA_CHANNEL_FIRST) + 1, String); @@ -209,16 +197,13 @@ void UI_DisplayMain(void) #ifndef DISABLE_ALARM if (gCurrentFunction == FUNCTION_TRANSMIT && gAlarmState == ALARM_STATE_ALARM) { - if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) - Channel = gEeprom.RX_CHANNEL; - else - Channel = gEeprom.TX_CHANNEL; + Channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_CHANNEL : gEeprom.TX_CHANNEL; if (Channel == vfo_num) State = VFO_STATE_ALARM; } #endif - if (State) + if (State != VFO_STATE_NORMAL) { uint8_t Width = 10; @@ -226,23 +211,23 @@ void UI_DisplayMain(void) switch (State) { - case 1: + case VFO_STATE_BUSY: strcpy(String, "BUSY"); Width = 15; break; - case 2: + case VFO_STATE_BAT_LOW: strcpy(String, "BAT LOW"); break; - case 3: + case VFO_STATE_TX_DISABLE: strcpy(String, "DISABLE"); break; - case 4: + case VFO_STATE_TIMEOUT: strcpy(String, "TIMEOUT"); break; - case 5: + case VFO_STATE_ALARM: strcpy(String, "ALARM"); break; - case 6: + case VFO_STATE_VOL_HIGH: sprintf(String, "VOL HIGH"); Width = 8; break; @@ -251,7 +236,7 @@ void UI_DisplayMain(void) UI_PrintString(String, 31, 111, vfo_num * 4, Width, true); } else - { + { // normal state if (gInputBoxIndex && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]) && gEeprom.TX_CHANNEL == vfo_num) { UI_DisplayFrequency(gInputBox, 31, vfo_num * 4, true, false); @@ -260,23 +245,17 @@ void UI_DisplayMain(void) { if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num])) { + frequency_Hz = gEeprom.VfoInfo[vfo_num].pRX->Frequency; if (gCurrentFunction == FUNCTION_TRANSMIT) - { - if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) - Channel = gEeprom.RX_CHANNEL; - else - Channel = gEeprom.TX_CHANNEL; + { // transmitting + Channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_CHANNEL : gEeprom.TX_CHANNEL; if (Channel == vfo_num) frequency_Hz = gEeprom.VfoInfo[vfo_num].pTX->Frequency; - else - frequency_Hz = gEeprom.VfoInfo[vfo_num].pRX->Frequency; } - else - frequency_Hz = gEeprom.VfoInfo[vfo_num].pRX->Frequency; switch (gEeprom.CHANNEL_DISPLAY_MODE) { - case MDF_FREQUENCY: + case MDF_FREQUENCY: // show the channel frequency NUMBER_ToDigits(frequency_Hz, String); // show the first lot of the frequency digits @@ -296,13 +275,13 @@ void UI_DisplayMain(void) frequency_Hz = 0; break; - case MDF_CHANNEL: + case MDF_CHANNEL: // show the channel number sprintf(String, "CH-%03d", gEeprom.ScreenChannel[vfo_num] + 1); UI_PrintString(String, 31, 112, vfo_num * 4, 8, true); frequency_Hz = 0; break; - case MDF_NAME: + case MDF_NAME: // show the channel name if (gEeprom.VfoInfo[vfo_num].Name[0] == 0 || gEeprom.VfoInfo[vfo_num].Name[0] == 0xFF) { // channel number sprintf(String, "CH-%03d", gEeprom.ScreenChannel[vfo_num] + 1); @@ -316,7 +295,7 @@ void UI_DisplayMain(void) break; #ifdef CHAN_NAME_FREQ - case MDF_NAME_FREQ: + case MDF_NAME_FREQ: // show the channel name and frequency if (gEeprom.VfoInfo[vfo_num].Name[0] == 0 || gEeprom.VfoInfo[vfo_num].Name[0] == 0xFF) { // channel number sprintf(String, "CH-%03d", gEeprom.ScreenChannel[vfo_num] + 1); @@ -334,96 +313,92 @@ void UI_DisplayMain(void) } else { + frequency_Hz = gEeprom.VfoInfo[vfo_num].pRX->Frequency; if (gCurrentFunction == FUNCTION_TRANSMIT) - { - if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) - Channel = gEeprom.RX_CHANNEL; - else - Channel = gEeprom.TX_CHANNEL; + { // transmitting + Channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_CHANNEL : gEeprom.TX_CHANNEL; if (Channel == vfo_num) frequency_Hz = gEeprom.VfoInfo[vfo_num].pTX->Frequency; - else - frequency_Hz = gEeprom.VfoInfo[vfo_num].pRX->Frequency; } - else - frequency_Hz = gEeprom.VfoInfo[vfo_num].pRX->Frequency; NUMBER_ToDigits(frequency_Hz, String); // 8 digits + + // show main part of frequency UI_DisplayFrequency(String, 31, vfo_num * 4, false, false); + // show the remaing 2 small frequency digits + UI_DisplaySmallDigits(2, String + 6, 112, Line + 1); if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num])) { const uint8_t Attributes = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; - if (Attributes & MR_CH_SCANLIST1) memcpy(pLine0 + 113, BITMAP_ScanList, sizeof(BITMAP_ScanList)); - if (Attributes & MR_CH_SCANLIST2) memcpy(pLine0 + 120, BITMAP_ScanList, sizeof(BITMAP_ScanList)); } - - UI_DisplaySmallDigits(2, String + 6, 112, Line + 1); frequency_Hz = 0; } } } - // 0x926E - uint8_t Level = 0; + { // show the TX/RX level - if (SomeValue == 1) - { - if (gRxVfo->OUTPUT_POWER == OUTPUT_POWER_LOW) - Level = 2; + uint8_t Level = 0; + + if (SomeValue == 1) + { // TX power level + switch (gRxVfo->OUTPUT_POWER) + { + case OUTPUT_POWER_LOW: + Level = 2; + break; + case OUTPUT_POWER_MID: + Level = 4; + break; + case OUTPUT_POWER_HIGH: + Level = 6; + break; + } + } else - if (gRxVfo->OUTPUT_POWER == OUTPUT_POWER_MID) - Level = 4; - else - Level = 6; + if (SomeValue == 2) + { // RX signal level + if (gVFO_RSSI_Level[vfo_num]) + Level = gVFO_RSSI_Level[vfo_num]; + } + + if (Level >= 1) + { + memcpy(pLine1 + 128 + 0, BITMAP_Antenna, sizeof(BITMAP_Antenna)); + memcpy(pLine1 + 128 + 5, BITMAP_AntennaLevel1, sizeof(BITMAP_AntennaLevel1)); + if (Level >= 2) + memcpy(pLine1 + 128 + 8, BITMAP_AntennaLevel2, sizeof(BITMAP_AntennaLevel2)); + if (Level >= 3) + memcpy(pLine1 + 128 + 11, BITMAP_AntennaLevel3, sizeof(BITMAP_AntennaLevel3)); + if (Level >= 4) + memcpy(pLine1 + 128 + 14, BITMAP_AntennaLevel4, sizeof(BITMAP_AntennaLevel4)); + if (Level >= 5) + memcpy(pLine1 + 128 + 17, BITMAP_AntennaLevel5, sizeof(BITMAP_AntennaLevel5)); + if (Level >= 6) + memcpy(pLine1 + 128 + 20, BITMAP_AntennaLevel6, sizeof(BITMAP_AntennaLevel6)); + } } - else - if (SomeValue == 2) - { - if (gVFO_RSSI_Level[vfo_num]) - Level = gVFO_RSSI_Level[vfo_num]; - } - - // show TX power level - if (Level >= 1) - { - memcpy(pLine1 + 128 + 0, BITMAP_Antenna, sizeof(BITMAP_Antenna)); - memcpy(pLine1 + 128 + 5, BITMAP_AntennaLevel1, sizeof(BITMAP_AntennaLevel1)); - if (Level >= 2) - memcpy(pLine1 + 128 + 8, BITMAP_AntennaLevel2, sizeof(BITMAP_AntennaLevel2)); - if (Level >= 3) - memcpy(pLine1 + 128 + 11, BITMAP_AntennaLevel3, sizeof(BITMAP_AntennaLevel3)); - if (Level >= 4) - memcpy(pLine1 + 128 + 14, BITMAP_AntennaLevel4, sizeof(BITMAP_AntennaLevel4)); - if (Level >= 5) - memcpy(pLine1 + 128 + 17, BITMAP_AntennaLevel5, sizeof(BITMAP_AntennaLevel5)); - if (Level >= 6) - memcpy(pLine1 + 128 + 20, BITMAP_AntennaLevel6, sizeof(BITMAP_AntennaLevel6)); - } - - // 0x931E + if (gEeprom.VfoInfo[vfo_num].IsAM) - { + { // show the AM symbol memcpy(pLine1 + 128 + 27, BITMAP_AM, sizeof(BITMAP_AM)); } else - { - const FREQ_Config_t *pConfig; - - pConfig = (SomeValue == 1) ? gEeprom.VfoInfo[vfo_num].pTX : gEeprom.VfoInfo[vfo_num].pRX; - + { // show the CTCSS or DCS symbol + const FREQ_Config_t *pConfig = (SomeValue == 1) ? gEeprom.VfoInfo[vfo_num].pTX : gEeprom.VfoInfo[vfo_num].pRX; switch (pConfig->CodeType) { - case CODE_TYPE_CONTINUOUS_TONE: + case CODE_TYPE_CONTINUOUS_TONE: // CTCSS memcpy(pLine1 + 128 + 27, BITMAP_CT, sizeof(BITMAP_CT)); break; case CODE_TYPE_DIGITAL: - case CODE_TYPE_REVERSE_DIGITAL: + case CODE_TYPE_REVERSE_DIGITAL: // DCS memcpy(pLine1 + 128 + 24, BITMAP_DCS, sizeof(BITMAP_DCS)); break; default: @@ -431,9 +406,8 @@ void UI_DisplayMain(void) } } - // 0x936C switch (gEeprom.VfoInfo[vfo_num].OUTPUT_POWER) - { + { // show the TX power symbol case OUTPUT_POWER_LOW: memcpy(pLine1 + 128 + 44, BITMAP_PowerLow, sizeof(BITMAP_PowerLow)); break; @@ -446,22 +420,26 @@ void UI_DisplayMain(void) } if (gEeprom.VfoInfo[vfo_num].ConfigRX.Frequency != gEeprom.VfoInfo[vfo_num].ConfigTX.Frequency) - { + { // show the TX offset symbol if (gEeprom.VfoInfo[vfo_num].FREQUENCY_DEVIATION_SETTING == FREQUENCY_DEVIATION_ADD) memcpy(pLine1 + 128 + 54, BITMAP_Add, sizeof(BITMAP_Add)); if (gEeprom.VfoInfo[vfo_num].FREQUENCY_DEVIATION_SETTING == FREQUENCY_DEVIATION_SUB) memcpy(pLine1 + 128 + 54, BITMAP_Sub, sizeof(BITMAP_Sub)); } + // show the TX/RX reverse symbol if (gEeprom.VfoInfo[vfo_num].FrequencyReverse) memcpy(pLine1 + 128 + 64, BITMAP_ReverseMode, sizeof(BITMAP_ReverseMode)); + // show the narrow band symbol if (gEeprom.VfoInfo[vfo_num].CHANNEL_BANDWIDTH == BANDWIDTH_NARROW) memcpy(pLine1 + 128 + 74, BITMAP_NarrowBand, sizeof(BITMAP_NarrowBand)); + // show the DTMF decoding symbol if (gEeprom.VfoInfo[vfo_num].DTMF_DECODING_ENABLE || gSetting_KILLED) memcpy(pLine1 + 128 + 84, BITMAP_DTMF, sizeof(BITMAP_DTMF)); + // show the audio scramble symbol if (gEeprom.VfoInfo[vfo_num].SCRAMBLING_TYPE && gSetting_ScrambleEnable) memcpy(pLine1 + 128 + 110, BITMAP_Scramble, sizeof(BITMAP_Scramble));