268 Commits
v0.1 ... v0.19

Author SHA1 Message Date
Krzysiek Egzmont
59b3251713 Github actions update 2023-11-29 02:18:34 +01:00
Krzysiek Egzmont
fbb4d08b88 S-meter values readjusted according to measurements from #53 2023-11-29 01:23:20 +01:00
Krzysiek Egzmont
050e04bcfd Enable/disable DTMF calling compile option 2023-11-28 23:00:01 +01:00
Krzysiek Egzmont
7857e8ed7a Scan range function #132 2023-11-28 20:13:02 +01:00
Krzysiek Egzmont
4c3eb98e31 Refactor 2023-11-27 22:51:36 +01:00
Krzysiek Egzmont
fe49f250b0 FM radio button actions changed to be the same as in VFO mode 2023-11-27 19:36:49 +01:00
Krzysiek Egzmont
3c643208ff FIX #152: Zero digit being entered when exiting FM radio with F+0 2023-11-27 13:42:47 +01:00
Krzysiek Egzmont
dc47842892 Refactor 2023-11-27 13:33:39 +01:00
Krzysiek Egzmont
9f22e8a9df FIX #151: Use aviation channels to frequency conversion scheme for 8.33 step rounding 2023-11-27 01:43:36 +01:00
Krzysiek Egzmont
07588853e4 Versioning modified 2023-11-27 00:50:08 +01:00
Krzysiek Egzmont
199b1a27f1 Spectrum: decimal point deletion fix #148, slower buttons repeats 2023-11-26 19:06:18 +01:00
Krzysiek Egzmont
a0d052b68b Spectrum refactor 2023-11-25 19:28:21 +01:00
Krzysiek Egzmont
9a3249a667 FIX #121: Rise tones volume 2023-11-23 21:20:24 +01:00
Krzysiek Egzmont
ffdc0e03b5 FIX #114, #120: Restart monitor mode on PTT release, long press EXIT exits monitor mode 2023-11-23 21:02:47 +01:00
Krzysiek Egzmont
d8d4384b20 Refactoring 2023-11-23 19:48:47 +01:00
Krzysiek Egzmont
0ce7d7bdc3 FIX #129: Bug in radio initialization after reset. 2023-11-22 23:40:39 +01:00
Krzysiek Egzmont
fb30ec8c86 Refactor 2023-11-22 23:40:20 +01:00
Krzysiek Egzmont
67307463e2 FIX #92: Adjust s-meter values 2023-11-22 14:52:16 +01:00
Krzysiek Egzmont
fdd7fc063e Cleanup docker container after build 2023-11-22 14:51:53 +01:00
Krzysiek Egzmont
592810b7d7 FIX #125: Frequency input on the first VFO blanks the display on the second 2023-11-20 22:32:39 +01:00
Krzysiek Egzmont
6e5e7e7aef FIX #85: Equalize tones volume in DTMF codes, fix wrong DTMF frequency values 2023-11-20 21:24:09 +01:00
ErikS-web
cd0dc71de6 Update README.md
Type error corrected
2023-11-18 21:26:37 +01:00
Krzysiek Egzmont
a43a3f949f READ MANUAL prompt for unlocking TX 2023-11-09 10:33:28 +01:00
Krzysiek Egzmont
d7b6cdf444 Modify release GH action 2023-11-08 18:57:50 +01:00
BG8LGP
7916d79ff1 Add github actions #86 2023-11-08 02:35:59 +01:00
Krzysiek Egzmont
49cec54cd3 TX on all bands #68 2023-11-08 01:43:06 +01:00
Krzysiek Egzmont
f154aebd38 Refactoring 2023-11-08 01:29:14 +01:00
ErikS-web
aaa55c5742 Update README.md
Cosmetic corrections
2023-11-07 21:49:20 +01:00
ErikS-web
345f1444f5 Update README.md
spelling mistake corrected
2023-11-07 21:39:22 +01:00
Krzysiek Egzmont
7e91d67b53 Mic bar in the same style as an s-meter 2023-11-07 17:11:25 +01:00
Krzysiek Egzmont
ba29176f33 Don't display mic bar over low the battery popup 2023-11-07 17:11:25 +01:00
Krzysiek Egzmont
05feff432e Rename build option 2023-11-07 17:11:24 +01:00
egzumer
cf4f85cb22 Update README.md 2023-11-07 17:09:07 +01:00
Krzysiek Egzmont
a0c2181197 Fix build error 2023-11-06 21:58:27 +01:00
Krzysiek Egzmont
b4abf369e1 FIX #76: Apollo Quindar mutes microphone 2023-11-06 16:20:45 +01:00
Krzysiek Egzmont
be0636d69b Readme update 2023-11-06 15:57:22 +01:00
wrobepio
23986a8648 Add "BLMIN TMP OFF" function for programmable buttons 2023-11-06 15:55:13 +01:00
Krzysiek Egzmont
b1d3a95ca2 Replace RX CSS menu scanning procedure with BK scanning method 2023-11-06 01:25:44 +01:00
Krzysiek Egzmont
1238bf090c Refactoring of cxcss and channel/frequency scanner code 2023-11-06 01:23:36 +01:00
Krzysiek Egzmont
5987e03141 Change names of some submenu items #80 2023-11-04 17:53:33 +01:00
Krzysiek Egzmont
c5e34c4be9 Delete immediate applying of CTCSS/DCS while scrolling options in the menu.
This also caused the option change not to be discarded on EXIT
2023-11-03 16:39:25 +01:00
Krzysiek Egzmont
b0a01cd8cf BYP/RAW removed by default, can be enabled by compile option 2023-11-03 12:51:06 +01:00
Krzysiek Egzmont
21535c9ca0 Don't use AM fix for USB/BYP/RAW 2023-11-03 12:18:31 +01:00
Krzysiek Egzmont
8c9bdaacbc Add "switch demodulation mode" function for programmable buttons 2023-11-03 01:15:29 +01:00
Krzysiek Egzmont
388c3dadf1 SSB, BYP, RAW demodulation modes added #64 2023-11-03 01:15:29 +01:00
Krzysiek Egzmont
72fc4bf52f FIX #60: LCD interference glitch 2023-11-03 01:13:28 +01:00
Krzysiek Egzmont
def555678d Refactoring 2023-11-02 21:56:48 +01:00
Krzysiek Egzmont
16e79bee7d Change the overvoltage level back to 8.9V 2023-11-02 21:34:10 +01:00
Krzysiek Egzmont
9777b5df8b Modified battery icon levels 2023-11-02 02:44:05 +01:00
Krzysiek Egzmont
c057f8a097 FIX #74: limit spectrum analyzer RSSI trigger values 2023-11-02 01:46:21 +01:00
Krzysiek Egzmont
034139d7d5 Battery curve, slight modification 2023-11-02 00:54:48 +01:00
Krzysiek Egzmont
03a51525b6 Fix s-meter over S9 values calculation 2023-11-01 23:37:31 +01:00
Krzysiek Egzmont
f074114d13 Makefile improvements 2023-11-01 22:35:13 +01:00
Krzysiek Egzmont
8a60535f9d Updated wiki 2023-11-01 20:36:19 +01:00
Krzysiek Egzmont
c2be853ef1 Low battery popup 2023-11-01 01:43:09 +01:00
Krzysiek Egzmont
9f1e6ab91f Extra UI helper functions 2023-11-01 00:10:03 +01:00
Krzysiek Egzmont
25334823e5 Refactoring 2023-10-31 19:58:10 +01:00
Krzysiek Egzmont
2796973ad3 Use the custom battery percentage calculations for battery icon and low battery beeping 2023-10-31 19:40:00 +01:00
Krzysiek Egzmont
2344478301 fix build error 2023-10-31 17:34:09 +01:00
Krzysiek Egzmont
61527d1281 More frequency steps 2023-10-31 14:33:05 +01:00
Krzysiek Egzmont
140b5f4b4a Added second discharge curve for 2200mAh type battery and hidden BatTyp menu entry 2023-10-31 00:41:53 +01:00
Krzysiek Egzmont
3e0ea6f7de Backlight setting 1 was fully off for some reason on higher freq PWM 2023-10-30 18:57:35 +01:00
Krzysiek Egzmont
ed64c7fb49 Mid, low power reduction mod from 1o11 2023-10-30 18:17:54 +01:00
Krzysiek Egzmont
d70fa1b7b4 Refactor 2023-10-30 16:39:18 +01:00
Krzysiek Egzmont
a41628410e FIX #65: code refactoring 2023-10-30 13:26:16 +01:00
Krzysiek Egzmont
f7c25b482d FIX #55: Broken DTMF calling (D Decd) 2023-10-29 22:26:48 +01:00
Krzysiek Egzmont
ac3cd08163 serial debugging helper 2023-10-28 23:11:52 +02:00
Krzysiek Egzmont
c1657a37f2 Refactor 2023-10-28 22:50:42 +02:00
Krzysiek Egzmont
a2580d5d8d Increase backlight PWM frequency to reduce flicker 2023-10-28 16:10:37 +02:00
Krzysiek Egzmont
5d4f7529ed Refactor 2023-10-28 16:09:49 +02:00
Krzysiek Egzmont
20a3e3b605 Fix STE not working when TX CTCSS/DCS is off
Reverts:
fde690a74a: app.c
50a55e34ab: radio.c
2023-10-28 14:41:47 +02:00
Krzysiek Egzmont
f3cc0f5acf Comments, refactor 2023-10-28 14:39:13 +02:00
Krzysiek Egzmont
2086bd6aaa Comments, refactor 2023-10-28 10:53:07 +02:00
Krzysiek Egzmont
3b3db88e5e Fix s-meter displaying for overpowering signals 2023-10-28 10:50:51 +02:00
Krzysiek Egzmont
f6791395cc Modified displaying of little sbar 2023-10-28 10:45:56 +02:00
Krzysiek Egzmont
8739996668 Changed little sbar back to factory 2023-10-27 15:32:14 +02:00
Krzysiek Egzmont
1740583ccc Set the backlight to minimum on reboot 2023-10-27 11:08:28 +02:00
Krzysiek Egzmont
b12244e352 Fix the RX buzzing problem after reboot 2023-10-27 10:53:22 +02:00
Krzysiek Egzmont
e6ac0d1d8d Import bk4819 changes 2023-10-26 18:30:35 +02:00
Krzysiek Egzmont
eda199d47a Back-light PWM 2023-10-26 18:20:28 +02:00
Krzysiek Egzmont
012c375f2e Fix build error 2023-10-26 10:55:33 +02:00
Krzysiek Egzmont
4a96dfa6ce AM fix gains adjusted 2023-10-25 23:24:45 +02:00
Krzysiek Egzmont
ec10aec0c4 Fix monitor listens on the opposite VFO when XB with DW is active at the same time 2023-10-25 21:35:34 +02:00
Krzysiek Egzmont
49c2c6b405 Refactor 2023-10-25 20:56:03 +02:00
Krzysiek Egzmont
38b1e5cbaa #45 piotr022 style S-meter 2023-10-25 14:39:21 +02:00
Krzysiek Egzmont
9a64a18010 #44 Channel/frequency scanner remember last found channel 2023-10-25 02:34:52 +02:00
Krzysiek Egzmont
72eddd009b Refactor 2023-10-25 01:26:14 +02:00
Krzysiek Egzmont
77d58eb8f5 Stop scan with MENU button and accept scan result 2023-10-24 04:09:46 +02:00
Krzysiek Egzmont
856dbe083d Increase DTMF string buffers size 2023-10-24 03:43:48 +02:00
Krzysiek Egzmont
50cc34ad9b Refactor 2023-10-24 03:42:34 +02:00
Krzysiek Egzmont
c996577a0b Fix frequency wraparound over band limit 2023-10-24 03:31:43 +02:00
Krzysiek Egzmont
e877820594 Change upper limit of airband to 137MHz 2023-10-24 03:29:50 +02:00
Krzysiek Egzmont
8ab123c927 Add new "VFO/MR" configurable button function 2023-10-24 02:34:29 +02:00
Krzysiek Egzmont
a510b89c6a Refactor frequency rounding 2023-10-24 02:25:01 +02:00
Krzysiek Egzmont
8b41a1fa66 Fix offset display in menu 2023-10-24 01:56:27 +02:00
Krzysiek Egzmont
99fc8a8311 FIX #43: frequent offset menu is not working properly 2023-10-24 01:54:57 +02:00
Krzysiek Egzmont
5c3eea2fcb Restart dual watch after VFO switched 2023-10-22 02:24:04 +02:00
Krzysiek Egzmont
ffb26a1f86 Refactoring 2023-10-22 02:23:16 +02:00
Krzysiek Egzmont
a8ae1b7739 Add menu configurable long-press function for MENU button 2023-10-22 02:11:26 +02:00
Krzysiek Egzmont
b59df11bd6 Refactoring 2023-10-21 06:12:59 +02:00
Krzysiek Egzmont
146c8dede4 Move copy channel to frequency mode from long press M to 1/BAND 2023-10-21 06:11:28 +02:00
Krzysiek Egzmont
c2090676d8 Side-key functions added: key lock, switch VFOs 2023-10-21 06:11:02 +02:00
Krzysiek Egzmont
b29bae88f1 Change SC_REV menu items names 2023-10-20 19:11:30 +02:00
Krzysiek Egzmont
c55a40481d Spectrum refactoring 2023-10-20 17:23:45 +02:00
Krzysiek Egzmont
a37a1ca6ef Fonts trimmed to save quite a bit of space 2023-10-20 16:52:15 +02:00
Krzysiek Egzmont
8629b1b867 Refactoring 2023-10-20 16:49:53 +02:00
Krzysiek Egzmont
f7c0d4149b Reduce EEPROM wear, don't check if changed before write. 2023-10-20 12:01:06 +02:00
Krzysiek Egzmont
87fd5c19d0 README.md updated 2023-10-20 01:35:11 +02:00
Krzysiek Egzmont
d132969c91 Support for >1GHz frequencies input 2023-10-20 00:15:11 +02:00
Krzysiek Egzmont
a5fa0b1e4b Refactoring, cleanup, comments 2023-10-19 21:42:56 +02:00
Krzysiek Egzmont
a21c8a62ac Small changes 2023-10-19 21:29:54 +02:00
Krzysiek Egzmont
9fd3701f46 Don't activate RX VFO when crossband is active 2023-10-19 17:00:22 +02:00
Krzysiek Egzmont
1d95737088 Refactoring, cleanup, comments 2023-10-19 16:58:12 +02:00
Krzysiek Egzmont
2f7042056a Display frequencies >=1GHz 2023-10-19 02:35:34 +02:00
Krzysiek Egzmont
13b41abce6 REFACTORING: Fixed correct BK4819 GPIO pin names 2023-10-18 17:27:18 +02:00
Krzysiek Egzmont
b9f9566158 Additional fix for RSSI calibration 2023-10-18 17:02:49 +02:00
Krzysiek Egzmont
710a417e12 FIX #31: Disable ENABLE_CTCSS_TAIL_PHASE_SHIFT that causes STE not to work 2023-10-18 00:29:20 +02:00
Krzysiek Egzmont
f11d0fbcda Code refactoring 2023-10-17 21:47:39 +02:00
Krzysiek Egzmont
96144af9e9 Added function buttons configuration to menu 2023-10-17 20:16:56 +02:00
Krzysiek Egzmont
4dd2445833 Menu items reordered 2023-10-17 13:34:18 +02:00
Krzysiek Egzmont
6172d942be Fix scanning on opposite VFO, ignore scan result on EXIT button, changed status bar while scanning 2023-10-17 02:57:55 +02:00
Krzysiek Egzmont
0c0cbb232c Refactoring 2023-10-17 02:26:20 +02:00
Krzysiek Egzmont
298ff29cf4 Fix restore VFO settings after scan 2023-10-16 22:59:17 +02:00
Krzysiek Egzmont
f70707e17f Fix copy channel to VFO function copying wrong VFO, clean VFO setup 2023-10-16 18:39:20 +02:00
Krzysiek Egzmont
f1fc04591c Fix compiler errors 2023-10-16 17:17:17 +02:00
Krzysiek Egzmont
a26c397417 Remove fall-through pragmas 2023-10-16 16:52:32 +02:00
Krzysiek Egzmont
d3a2a7bee9 Menu id fix 2023-10-16 16:02:39 +02:00
Krzysiek Egzmont
d817ff7e6a Fixed RSSI calibration 2023-10-16 13:01:24 +02:00
Krzysiek Egzmont
ec4bec5b1f Flashlight SOS function 2023-10-16 00:15:04 +02:00
Krzysiek Egzmont
d7c458839c Change menu items names 2023-10-15 22:07:55 +02:00
Krzysiek Egzmont
cff2f25e56 Consolidate "T VFO" and "DUALRX" into one "RXMODE" 2023-10-15 21:52:42 +02:00
Krzysiek Egzmont
63ac84883e add execute rights to compile-with-docker.sh 2023-10-15 21:12:06 +02:00
wrobepio
f8252df281 fixed: "compiled-firmware" folder missing under linux - fixed shell variable $PWD 2023-10-14 20:26:29 +02:00
Krzysiek Egzmont
be00bb99ad FIX #28: After entering item 51(BATVOL) of the menu, the automatic lock screen cannot be unlocked 2023-10-12 20:45:26 +02:00
Krzysiek Egzmont
7e6a78ab6c FIX #26: vfo state (TX DISABLE label) update issue when FM radio disabled in Makefile 2023-10-12 00:44:52 +02:00
Krzysiek Egzmont
06c2ddf543 BUG FIX: power save never activated 2023-10-10 19:36:12 +02:00
Krzysiek Egzmont
47f1e80252 Fix #25: When you stop the scan with the PTT the Walkie stays in permanent TX 2023-10-10 17:32:58 +02:00
Krzysiek Egzmont
64bc29d362 FIX #24: lock/unlock doesn't work when FM radio active 2023-10-10 14:29:51 +02:00
Krzysiek Egzmont
8d17f5922c FIX #21: Battery symbol fix of a fix 2023-10-10 02:39:02 +02:00
Krzysiek Egzmont
063dc61e65 Part of the recent changes form 1o11, including DTMF input box error #19 2023-10-09 21:47:06 +02:00
Krzysiek Egzmont
60ccd3372f FIX #8: This should fix compiler errors 2023-10-09 17:17:45 +02:00
Krzysiek Egzmont
149a0f5bdc Revert do not update battery level when TX 2023-10-09 16:57:52 +02:00
Krzysiek Egzmont
c7da7cf725 Battery symbol fix 2023-10-09 16:30:20 +02:00
Krzysiek Egzmont
4b9147327a Fix random upper/lower for TX, bring back TX on last RX 2023-10-09 16:02:57 +02:00
Krzysiek Egzmont
43f4790f5b BUG FIX #15: shifted numbers in spectrum freq input box 2023-10-06 19:57:08 +02:00
Krzysiek Egzmont
43ccce33da README: new build instructions 2023-10-06 12:15:01 +02:00
Krzysiek Egzmont
b2839de2a5 Merge remote-tracking branch 'remotes/OneOfEleven/main' 2023-10-06 11:28:19 +02:00
OneOfEleven
5397b3ee88 Fixed key number offset bug added yesterday 2023-10-06 07:48:45 +01:00
OneOfEleven
9a0a75446a README.md 2023-10-06 00:19:21 +01:00
OneOfEleven
f25e0230f0 Added power-on compile option 2023-10-06 00:18:47 +01:00
OneOfEleven
16c908f0bf Channel/Frequency scanning updates 2023-10-05 23:58:55 +01:00
OneOfEleven
9c7d6a38e5 Remember scan ALL channels option across power cycles 2023-10-05 22:59:26 +01:00
OneOfEleven
ec5e9dde66 Squelch tuning 2023-10-05 22:44:44 +01:00
OneOfEleven
5c346c8466 Fic typing in keys bug 2023-10-05 17:38:25 +01:00
OneOfEleven
40d09591b3 Fixed silly error I made 2023-10-05 16:28:20 +01:00
OneOfEleven
bd9f337a5b Make all warnings vanish over to bricky's house ! 2023-10-05 15:26:08 +01:00
OneOfEleven
cb05a5881f Try again to calm the type warnings 2023-10-05 14:40:34 +01:00
OneOfEleven
6b44659419 Mzybe clear up some signed/unsigned compile warnings 2023-10-05 14:33:05 +01:00
Krzysiek Egzmont
81f18aa281 build errors fix 2023-10-05 15:10:12 +02:00
Krzysiek Egzmont
410c0e47cb Merge remote-tracking branch 'remotes/OneOfEleven/main' 2023-10-05 15:05:54 +02:00
OneOfEleven
2372949eb9 RX bandwidth and squelch update 2023-10-05 13:42:14 +01:00
OneOfEleven
0cf4e1fe36 Merge pull request #123 from bricky149/clang-build
Add support for clang builds
2023-10-05 12:44:47 +01:00
OneOfEleven
9b2ce88a72 RX fixed bandwidth adjustments + squelch sensitivity adjustments 2023-10-05 12:42:40 +01:00
bricky149
a23f359735 Add support for clang builds 2023-10-05 12:22:09 +01:00
OneOfEleven
b343993a72 Don't use fast scan option - for now 2023-10-05 10:19:50 +01:00
OneOfEleven
4d8db8f0b9 Updated 5/7 function key operation (see README.md) 2023-10-05 10:03:07 +01:00
OneOfEleven
609df5f279 Ignore all long-press/function keys whilst in menu 2023-10-05 09:17:38 +01:00
OneOfEleven
e042b21e65 Rename RX_CHANNEL and TX_CHANNEL to RX_VFO and TX_VFO to be much less confusing 2023-10-05 01:07:04 +01:00
OneOfEleven
d632698428 Clean up copy-chan-to-vfo 2023-10-05 00:26:37 +01:00
OneOfEleven
eba4bf9c80 Fix copy-chan-to-vfo 2023-10-05 00:07:35 +01:00
OneOfEleven
56fc929921 Let copy-chan-to-vfo work when dual-watch enabled 2023-10-05 00:01:13 +01:00
Krzysiek Egzmont
2cff29e6db Merge remote-tracking branch 'remotes/OneOfEleven/main' 2023-10-05 00:11:29 +02:00
Krzysiek Egzmont
ced053ba63 Merge remote-tracking branch 'remotes/OneOfEleven/main' 2023-10-05 00:10:14 +02:00
OneOfEleven
a6324ffcf8 Fix for when channel scan has no scanlisted channels to scan 2023-10-04 23:09:55 +01:00
OneOfEleven
6e7f8b1877 Update README.md with new function key operations list 2023-10-04 22:56:54 +01:00
OneOfEleven
74a9adcdbd Merge pull request #119 from bricky149/gc-sections
Retain space saving benefits when not using LTO
2023-10-04 22:35:54 +01:00
bricky149
4a05e69e19 Retain space saving benefits when not using LTO 2023-10-04 22:24:07 +01:00
OneOfEleven
1cfb59fa38 Scanlist now 1, 2 or all channels 2023-10-04 22:08:13 +01:00
Krzysiek Egzmont
bee4a8c41a Merge remote-tracking branch 'remotes/OneOfEleven/main' 2023-10-04 22:35:03 +02:00
OneOfEleven
fe949d2ae3 Sanity check on DTMF hold time 2023-10-04 21:29:35 +01:00
Krzysiek Egzmont
292181a9a6 struct padding fixed in spectrum 2023-10-04 22:29:26 +02:00
Krzysiek Egzmont
654145bd07 Merge remote-tracking branch 'remotes/OneOfEleven/main' 2023-10-04 22:28:24 +02:00
OneOfEleven
5900d46edb Disable the weak signal auto RX bandwidth reduction - test 2023-10-04 21:18:02 +01:00
OneOfEleven
1dbe874240 Slightly reduced tone amplitude - to reduce deviation level 2023-10-04 20:34:57 +01:00
OneOfEleven
eea1756dc0 Disable padding flag - causing problems with structures that need no padding 2023-10-04 20:14:01 +01:00
OneOfEleven
32fad129cc Modify scanlist top status bar symbol 2023-10-04 20:05:00 +01:00
OneOfEleven
6a8c7d5b37 Modify scanlist symbol on status bar (SL-1 / SL-2) 2023-10-04 19:11:19 +01:00
OneOfEleven
efca16088b Merge branch 'main' of https://github.com/OneOfEleven/uv-k5-firmware-custom 2023-10-04 19:01:09 +01:00
OneOfEleven
814e5edb07 Toggle scankists update 2023-10-04 19:01:00 +01:00
OneOfEleven
abfcf15aca Merge pull request #113 from egzumer/batcal
Update all battery bar level values on battery calibration
2023-10-04 19:00:09 +01:00
OneOfEleven
a113d41c1a Merge branch 'main' of https://github.com/OneOfEleven/uv-k5-firmware-custom 2023-10-04 18:54:41 +01:00
OneOfEleven
b26b1fab95 Scanlist update 2023-10-04 18:54:26 +01:00
OneOfEleven
2242c4097a Merge pull request #114 from bricky149/struct-padding
-Wpadded, reorder struct fields, saves 400 bytes
2023-10-04 18:52:56 +01:00
bricky149
74c37451bf -Wpadding, reorder struct fields, saves 400 bytes 2023-10-04 18:35:51 +01:00
Krzysiek Egzmont
59c4c4dcd3 Merge branch 'batcal' 2023-10-04 18:49:02 +02:00
Krzysiek Egzmont
eec8e22e41 Update all battery bar level values on battery calibration 2023-10-04 18:35:50 +02:00
OneOfEleven
429ac36ffe Backlight TX/RX menu update 2023-10-04 16:37:11 +01:00
OneOfEleven
567b0cfa83 Compander bug fixed, found by two other people :) 2023-10-04 14:55:58 +01:00
OneOfEleven
f4b637b51a Added VOX enable/disable compile option 2023-10-04 11:57:34 +01:00
OneOfEleven
5f2e069437 Rename AF constant 2023-10-04 10:01:07 +01:00
OneOfEleven
9d990f7e67 Fix 1750Hz key bug 2023-10-04 00:45:03 +01:00
OneOfEleven
eaccdab1d4 1750Hz tone side key now a momentary action (press to TX tone, release to stop TX tone) 2023-10-04 00:15:01 +01:00
OneOfEleven
6e2ba5c214 Updated README.md 2023-10-03 23:33:28 +01:00
OneOfEleven
4d808de2ac Added Copy-channel-to-VFO - long press 'M' key (menu key) 2023-10-03 23:33:01 +01:00
OneOfEleven
8fb9825ad8 More efficient AM fix table and code 2023-10-03 20:03:04 +01:00
OneOfEleven
4b17aa6d3f serial comms TX lockout bug fix 2023-10-03 19:19:40 +01:00
Krzysiek Egzmont
6d0aea4587 BUG FIX: #6 serial communication error 2023-10-03 20:16:51 +02:00
Krzysiek Egzmont
ec2d6e4a74 Makefile 2023-10-03 19:29:16 +02:00
Krzysiek Egzmont
b301a8d21e Key 5, long press - toggle scan list, F + short press - spectrum 2023-10-03 19:04:37 +02:00
Krzysiek Egzmont
339e280a27 Merge remote-tracking branch 'remotes/OneOfEleven/main' 2023-10-03 18:45:03 +02:00
OneOfEleven
f8aaf47374 AM RX mode could possible not be being set - maybe fixed 2023-10-03 16:09:25 +01:00
OneOfEleven
84e174544d Added backlight on RX menu option "BLT RX" 2023-10-03 13:18:49 +01:00
OneOfEleven
ac05207ef0 Added compile option ENABLE_BACKLIGHT_ON_RX - will make this a menu option soon 2023-10-03 13:02:43 +01:00
OneOfEleven
9d5d36cc1f Fix compand setting not saved for channel mode 2023-10-03 11:55:46 +01:00
OneOfEleven
c5c86d0ad0 Fix frequency band error from yesterday 2023-10-03 11:48:00 +01:00
OneOfEleven
010ea0308a Renames 'ENABLE_SQUELCH_LOWER'. Added faster channel scan option (but makes squelch/grn-LED/back-light more twitchy) 2023-10-03 11:32:04 +01:00
OneOfEleven
b3ca095af1 Maybe fixed reboot when serial comms start 2023-10-03 10:13:22 +01:00
OneOfEleven
6a3a26c470 Re-enabled by default the AM fix data until it's fully working. 2023-10-03 00:26:46 +01:00
OneOfEleven
2551077cef Menu remains on screen whilst TX'ing 2023-10-03 00:14:36 +01:00
Krzysiek Egzmont
2397e3950b Makefile 2023-10-02 23:29:19 +02:00
Krzysiek Egzmont
d11e7863dc Merge remote-tracking branch 'remotes/OneOfEleven/main' 2023-10-02 23:15:34 +02:00
Krzysiek Egzmont
35c7530036 Change default build setting of am fix debugging to 0 2023-10-02 23:06:05 +02:00
OneOfEleven
87d1cf7c86 Increased menu BATCAL, F-CALI and BATVOL timeouts to 2 mins + disable TX when serial config upload/download in progress 2023-10-02 22:04:41 +01:00
OneOfEleven
bf2564b9f5 F-CAL hidden meni compile option added + BATCAL menu range adjust range increased 2023-10-02 20:52:18 +01:00
OneOfEleven
c59e0ea06c Fix DTM TX-UP only 2023-10-02 19:23:37 +01:00
OneOfEleven
9ac3525683 Simplified the frequency band table(s) 2023-10-02 14:13:27 +01:00
OneOfEleven
3ac330ddee Testing disabling the BK chips auto bandwidth switching weak signal option 2023-10-02 12:20:54 +01:00
OneOfEleven
af342cf904 Restored battery bar thresholds back to the stored calibration values. 2023-10-02 10:40:27 +01:00
OneOfEleven
ec33203403 Update RADIO_InitInfo() so that things match up rather than fixed numerical constants 2023-10-02 10:05:15 +01:00
OneOfEleven
3c7f496f3e Tidy ups, speedier channel scanning, RSSI meter updating fix 2023-10-02 09:31:35 +01:00
Krzysiek Egzmont
174c06dfbf build options 2023-10-02 03:52:59 +02:00
Krzysiek Egzmont
d86ccaafcd README updated 2023-10-02 03:31:02 +02:00
Krzysiek Egzmont
d826ecb0ae Merge remote-tracking branch 'remotes/OneOfEleven/main' 2023-10-02 03:21:18 +02:00
OneOfEleven
e0aa1a83be Fix ENABLE_KEEP_MEM_NAME stuff 2023-10-02 02:02:34 +01:00
Krzysiek Egzmont
e64bf6bbd6 Merge branch '1o11main' 2023-10-02 03:01:28 +02:00
OneOfEleven
aafc93c2ee Forgot to remove unrequired batcal code 2023-10-02 01:44:33 +01:00
OneOfEleven
58eced120e On-screen charge level bug fixed 2023-10-02 01:28:56 +01:00
OneOfEleven
bbf8a7061e Fixed CTCSS int overflow bug 2023-10-02 01:19:14 +01:00
OneOfEleven
aea80cb046 Updated menu battery cal from egzumer 2023-10-02 01:09:35 +01:00
OneOfEleven
4333fdeb3a Added menu battery calibration from egzumer (hidden menu option) 2023-10-02 00:38:59 +01:00
OneOfEleven
a9aa37e043 Pulled in egzumer's battery percentage ! 2023-10-01 22:14:45 +01:00
OneOfEleven
1fc1a102ea Merge pull request #85 from wutje/smaller_keyboard_handling
Keyboard: Save 240 bytes of flash.
2023-10-01 21:55:07 +01:00
OneOfEleven
86d2dade7a Menu update + PTT-ID fix 2023-10-01 21:50:05 +01:00
Wouter van Gulik
6f7bb75b52 Keyboard: Save 240 bytes of flash.
Move definition to a table.
Set and read the pins all at once.
Drop extra delays.
Use existing I2C_Stop to generate proper stop condition.
2023-10-01 22:34:03 +02:00
Krzysiek Egzmont
82b8f6755f docker build script 2023-10-01 22:09:52 +02:00
OneOfEleven
8caff25b7c Possible DW AM TX fix 2023-10-01 19:56:04 +01:00
OneOfEleven
c644b30b2f 1750 compile option + maybe DW AM TX fix 2023-10-01 19:17:51 +01:00
OneOfEleven
de174d072c Removed unneeded function call param (band) 2023-10-01 17:19:38 +01:00
OneOfEleven
c3c344daec Menu play + reduce AM AGC hysteresis very slightly. 2023-10-01 15:07:34 +01:00
OneOfEleven
fc1bc8791c Menu update, F-LOCK CE update, main screen fix 2023-10-01 14:34:51 +01:00
Krzysiek Egzmont
5c413eb7cd Calibration description readme 2023-10-01 14:12:37 +02:00
OneOfEleven
fa4ae2caa6 Fix what I did last 2023-10-01 12:44:22 +01:00
Krzysiek Egzmont
e092145542 Remove Alarm function to save space 2023-10-01 13:44:20 +02:00
Krzysiek Egzmont
5ba5b9f2eb Merge OneOfEleven at commit 'b7241f77efb42bca8443b1b129678c64bdb6dbab' 2023-10-01 13:42:05 +02:00
Krzysiek Egzmont
4fb8f7b0e7 Spectrum analyzer updated
ffe1573a4b
2023-10-01 12:38:55 +02:00
Krzysiek Egzmont
0f210ff872 Battery calibration function added 2023-10-01 12:17:49 +02:00
OneOfEleven
b45043aab2 Rename compile option ENABLE_NO_SCAN_TIMEOUT to ENABLE_CODE_SCAN_TIMEOUT 2023-10-01 10:27:10 +01:00
OneOfEleven
ba3decad78 Show "TX DISABLE" on the correct VFO/screen line 2023-10-01 10:15:24 +01:00
OneOfEleven
7df7461d31 Fix dual-watch so that TX only uses the main channel (black triangle) 2023-10-01 09:14:19 +01:00
OneOfEleven
b7241f77ef Forgot to save/update radio.c 2023-10-01 00:30:13 +01:00
OneOfEleven
ae6cf797cb Adjusted rssi bar to start at S4, end at S9+30 2023-10-01 00:10:45 +01:00
OneOfEleven
618a184bf1 S0 meter now -147dBm 2023-10-01 00:04:51 +01:00
OneOfEleven
b0f6be2c7c Make all 10 squelch settings slightly more sensitive 2023-09-30 23:56:31 +01:00
OneOfEleven
aba9e435f2 Fix lower squelch-1 setting bug 2023-09-30 20:21:37 +01:00
OneOfEleven
6546f9d4ce s-meter now shows S9+ in 1dB increments 2023-09-30 20:03:09 +01:00
OneOfEleven
1eac6018ba Even easier to change 'S0' base dBm level on the s-meter. 2023-09-30 17:14:48 +01:00
Krzysiek Egzmont
f32eeda636 README changed 2023-09-30 16:12:47 +02:00
OneOfEleven
9493f34c23 Various DTMF bug fixes and renames 2023-09-30 11:22:19 +01:00
108 changed files with 8368 additions and 6518 deletions

49
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
on:
push:
jobs:
build:
runs-on: ubuntu-22.04
container:
image: archlinux:latest
steps:
- name: base-devel
run: pacman -Syyu base-devel --noconfirm
- name: arm-none-eabi-gcc
run: pacman -Syyu arm-none-eabi-gcc --noconfirm
- name: arm-none-eabi-newlib
run: pacman -Syyu arm-none-eabi-newlib --noconfirm
- name: git
run: pacman -Syyu git --noconfirm
- name: python-pip
run: pacman -Syyu python-pip --noconfirm
- name: python-crcmod
run: pacman -Syyu python-crcmod --noconfirm
- name: Checkout
uses: actions/checkout@v3
- name: safe.directory
run: git config --global --add safe.directory /__w/uv-k5-firmware-custom/uv-k5-firmware-custom
- name: Make
run: make
- name: size
run: arm-none-eabi-size firmware
- name: 'Upload Artifact'
uses: actions/upload-artifact@v3
with:
name: firmware
path: firmware*.bin
- name: Upload binaries to release
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: firmware.packed.bin
asset_name: egzumer_$tag.packed.bin
tag: ${{ github.ref }}
overwrite: true
release_name: release ${{ github.ref_name }}

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@
firmware
/firmware.packed.bin
/firmware.bin
/compiled-firmware

12
Dockerfile Normal file
View File

@@ -0,0 +1,12 @@
FROM archlinux:latest
RUN pacman -Syyu base-devel --noconfirm
RUN pacman -Syyu arm-none-eabi-gcc --noconfirm
RUN pacman -Syyu arm-none-eabi-newlib --noconfirm
RUN pacman -Syyu git --noconfirm
RUN pacman -Syyu python-pip --noconfirm
RUN pacman -Syyu python-crcmod --noconfirm
WORKDIR /app
COPY . .
RUN git submodule update --init --recursive
#RUN make && cp firmware* compiled-firmware/

230
Makefile
View File

@@ -3,38 +3,57 @@
# 0 = disable
# 1 = enable
#
ENABLE_CLANG := 0
ENABLE_SWD := 0
ENABLE_OVERLAY := 1
ENABLE_OVERLAY := 0
ENABLE_LTO := 1
ENABLE_UART := 1
ENABLE_AIRCOPY := 0
ENABLE_FMRADIO := 0
ENABLE_FMRADIO := 1
ENABLE_NOAA := 0
ENABLE_VOICE := 0
ENABLE_ALARM := 1
ENABLE_VOX := 1
ENABLE_ALARM := 0
ENABLE_TX1750 := 0
ENABLE_PWRON_PASSWORD := 0
ENABLE_BIG_FREQ := 1
ENABLE_SMALL_BOLD := 1
ENABLE_KEEP_MEM_NAME := 1
ENABLE_WIDE_RX := 1
ENABLE_TX_WHEN_AM := 0
ENABLE_CTCSS_TAIL_PHASE_SHIFT := 1
ENABLE_MAIN_KEY_HOLD := 1
ENABLE_F_CAL_MENU := 0
ENABLE_CTCSS_TAIL_PHASE_SHIFT := 0
ENABLE_BOOT_BEEPS := 0
ENABLE_COMPANDER := 1
ENABLE_SHOW_CHARGE_LEVEL := 1
ENABLE_REVERSE_BAT_SYMBOL := 1
ENABLE_NO_SCAN_TIMEOUT := 1
ENABLE_REVERSE_BAT_SYMBOL := 0
ENABLE_NO_CODE_SCAN_TIMEOUT := 1
ENABLE_AM_FIX := 1
ENABLE_AM_FIX_SHOW_DATA := 1
ENABLE_SQUELCH1_LOWER := 0
ENABLE_AM_FIX_SHOW_DATA := 0
ENABLE_SQUELCH_MORE_SENSITIVE := 1
ENABLE_FASTER_CHANNEL_SCAN := 1
ENABLE_RSSI_BAR := 1
ENABLE_AUDIO_BAR := 1
ENABLE_COPY_CHAN_TO_VFO := 1
ENABLE_SPECTRUM := 1
#ENABLE_COPY_CHAN_TO_VFO := 1
#ENABLE_SINGLE_VFO_CHAN := 1
#ENABLE_BAND_SCOPE := 1
ENABLE_REDUCE_LOW_MID_TX_POWER:= 0
ENABLE_BYP_RAW_DEMODULATORS := 0
ENABLE_BLMIN_TMP_OFF := 0
ENABLE_SCAN_RANGES := 1
ENABLE_DTMF_CALLING := 1
#############################################################
TARGET = firmware
ifeq ($(ENABLE_CLANG),1)
# GCC's linker, ld, doesn't understand LLVM's generated bytecode
ENABLE_LTO := 0
endif
ifeq ($(ENABLE_LTO),1)
# can't have LTO and OVERLAY enabled at same time
ENABLE_OVERLAY := 0
endif
BSP_DEFINITIONS := $(wildcard hardware/*/*.def)
BSP_HEADERS := $(patsubst hardware/%,bsp/%,$(BSP_DEFINITIONS))
BSP_HEADERS := $(patsubst %.def,%.h,$(BSP_HEADERS))
@@ -82,6 +101,8 @@ ifeq ($(ENABLE_AIRCOPY),1)
OBJS += app/aircopy.o
endif
OBJS += app/app.o
OBJS += app/chFrScanner.o
OBJS += app/common.o
OBJS += app/dtmf.o
ifeq ($(ENABLE_FMRADIO),1)
OBJS += app/fm.o
@@ -96,7 +117,9 @@ OBJS += app/scanner.o
ifeq ($(ENABLE_UART),1)
OBJS += app/uart.o
endif
OBJS += am_fix.o
ifeq ($(ENABLE_AM_FIX), 1)
OBJS += am_fix.o
endif
OBJS += audio.o
OBJS += bitmaps.o
OBJS += board.o
@@ -119,7 +142,9 @@ ifeq ($(ENABLE_FMRADIO),1)
endif
OBJS += ui/helper.o
OBJS += ui/inputbox.o
OBJS += ui/lock.o
ifeq ($(ENABLE_PWRON_PASSWORD),1)
OBJS += ui/lock.o
endif
OBJS += ui/main.o
OBJS += ui/menu.o
OBJS += ui/scanner.o
@@ -129,37 +154,89 @@ OBJS += ui/welcome.o
OBJS += version.o
OBJS += main.o
ifeq ($(OS),Windows_NT)
ifeq ($(OS), Windows_NT)
TOP := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
else
TOP := $(shell pwd)
endif
ifdef OS # windows
RM = del /Q
FixPath = $(subst /,\,$1)
WHERE = where
NULL_OUTPUT = nul
else # unix
ifeq ($(shell uname), Linux)
RM = rm -f
FixPath = $1
WHERE = which
NULL_OUTPUT = /dev/null
endif
endif
AS = arm-none-eabi-gcc
CC = arm-none-eabi-gcc
CC =
LD = arm-none-eabi-gcc
ifeq ($(ENABLE_CLANG),0)
CC += arm-none-eabi-gcc
# Use GCC's linker to avoid undefined symbol errors
# LD += arm-none-eabi-gcc
else
# May need to adjust this to match your system
CC += clang --sysroot=/usr/arm-none-eabi --target=arm-none-eabi
# Bloats binaries to 512MB
# LD = ld.lld
endif
OBJCOPY = arm-none-eabi-objcopy
SIZE = arm-none-eabi-size
AUTHOR_STRING := EGZUMER
# the user might not have/want git installed
# can set own version string here (max 7 chars)
GIT_HASH := $(shell git rev-parse --short HEAD)
#GIT_HASH := 230930b
ifneq (, $(shell $(WHERE) git))
VERSION_STRING := $(shell git describe --tags --exact-match 2>$(NULL_OUTPUT))
ifeq (, $(VERSION_STRING))
VERSION_STRING := $(shell git rev-parse --short HEAD)
endif
endif
#VERSION_STRING := 230930b
$(info GIT_HASH = $(GIT_HASH))
ASFLAGS = -c -mcpu=cortex-m0
ifeq ($(ENABLE_OVERLAY),1)
ASFLAGS += -DENABLE_OVERLAY
endif
CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD
#CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c99 -MMD
#CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=gnu99 -MMD
#CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=gnu11 -MMD
CFLAGS =
ifeq ($(ENABLE_CLANG),0)
CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD
#CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c99 -MMD
#CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=gnu99 -MMD
#CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=gnu11 -MMD
else
# Oz needed to make it fit on flash
CFLAGS += -Oz -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD
endif
ifeq ($(ENABLE_LTO),1)
CFLAGS += -flto=2
else
# We get most of the space savings if LTO creates problems
CFLAGS += -ffunction-sections -fdata-sections
endif
# May cause unhelpful build failures
#CFLAGS += -Wpadded
# catch any and all warnings
CFLAGS += -Wextra
#CFLAGS += -Wpedantic
CFLAGS += -DPRINTF_INCLUDE_CONFIG_H
CFLAGS += -DGIT_HASH=\"$(GIT_HASH)\"
CFLAGS += -DAUTHOR_STRING=\"$(AUTHOR_STRING)\" -DVERSION_STRING=\"$(VERSION_STRING)\"
ifeq ($(ENABLE_SPECTRUM),1)
CFLAGS += -DENABLE_SPECTRUM
@@ -167,15 +244,15 @@ endif
ifeq ($(ENABLE_SWD),1)
CFLAGS += -DENABLE_SWD
endif
ifeq ($(ENABLE_OVERLAY),1)
CFLAGS += -DENABLE_OVERLAY
endif
ifeq ($(ENABLE_AIRCOPY),1)
CFLAGS += -DENABLE_AIRCOPY
endif
ifeq ($(ENABLE_FMRADIO),1)
CFLAGS += -DENABLE_FMRADIO
endif
ifeq ($(ENABLE_OVERLAY),1)
CFLAGS += -DENABLE_OVERLAY
endif
ifeq ($(ENABLE_UART),1)
CFLAGS += -DENABLE_UART
endif
@@ -191,11 +268,20 @@ endif
ifeq ($(ENABLE_VOICE),1)
CFLAGS += -DENABLE_VOICE
endif
ifeq ($(ENABLE_VOX),1)
CFLAGS += -DENABLE_VOX
endif
ifeq ($(ENABLE_ALARM),1)
CFLAGS += -DENABLE_ALARM
endif
ifeq ($(ENABLE_TX1750),1)
CFLAGS += -DENABLE_TX1750
endif
ifeq ($(ENABLE_PWRON_PASSWORD),1)
CFLAGS += -DENABLE_PWRON_PASSWORD
endif
ifeq ($(ENABLE_KEEP_MEM_NAME),1)
CFLAGS += -DKEEP_MEM_NAME
CFLAGS += -DENABLE_KEEP_MEM_NAME
endif
ifeq ($(ENABLE_WIDE_RX),1)
CFLAGS += -DENABLE_WIDE_RX
@@ -203,26 +289,23 @@ endif
ifeq ($(ENABLE_TX_WHEN_AM),1)
CFLAGS += -DENABLE_TX_WHEN_AM
endif
ifeq ($(ENABLE_F_CAL_MENU),1)
CFLAGS += -DENABLE_F_CAL_MENU
endif
ifeq ($(ENABLE_CTCSS_TAIL_PHASE_SHIFT),1)
CFLAGS += -DENABLE_CTCSS_TAIL_PHASE_SHIFT
endif
ifeq ($(ENABLE_MAIN_KEY_HOLD),1)
CFLAGS += -DENABLE_MAIN_KEY_HOLD
endif
ifeq ($(ENABLE_BOOT_BEEPS),1)
CFLAGS += -DENABLE_BOOT_BEEPS
endif
ifeq ($(ENABLE_COMPANDER),1)
CFLAGS += -DENABLE_COMPANDER
endif
ifeq ($(ENABLE_SHOW_CHARGE_LEVEL),1)
CFLAGS += -DENABLE_SHOW_CHARGE_LEVEL
endif
ifeq ($(ENABLE_REVERSE_BAT_SYMBOL),1)
CFLAGS += -DENABLE_REVERSE_BAT_SYMBOL
endif
ifeq ($(ENABLE_NO_SCAN_TIMEOUT),1)
CFLAGS += -DENABLE_NO_SCAN_TIMEOUT
ifeq ($(ENABLE_NO_CODE_SCAN_TIMEOUT),1)
CFLAGS += -DENABLE_CODE_SCAN_TIMEOUT
endif
ifeq ($(ENABLE_AM_FIX),1)
CFLAGS += -DENABLE_AM_FIX
@@ -233,8 +316,14 @@ endif
ifeq ($(ENABLE_AM_FIX_TEST1),1)
CFLAGS += -DENABLE_AM_FIX_TEST1
endif
ifeq ($(ENABLE_SQUELCH1_LOWER),1)
CFLAGS += -DENABLE_SQUELCH1_LOWER
ifeq ($(ENABLE_SQUELCH_MORE_SENSITIVE),1)
CFLAGS += -DENABLE_SQUELCH_MORE_SENSITIVE
endif
ifeq ($(ENABLE_FASTER_CHANNEL_SCAN),1)
CFLAGS += -DENABLE_FASTER_CHANNEL_SCAN
endif
ifeq ($(ENABLE_BACKLIGHT_ON_RX),1)
CFLAGS += -DENABLE_BACKLIGHT_ON_RX
endif
ifeq ($(ENABLE_RSSI_BAR),1)
CFLAGS += -DENABLE_RSSI_BAR
@@ -251,12 +340,41 @@ endif
ifeq ($(ENABLE_BAND_SCOPE),1)
CFLAGS += -DENABLE_BAND_SCOPE
endif
ifeq ($(ENABLE_REDUCE_LOW_MID_TX_POWER),1)
CFLAGS += -DENABLE_REDUCE_LOW_MID_TX_POWER
endif
ifeq ($(ENABLE_BYP_RAW_DEMODULATORS),1)
CFLAGS += -DENABLE_BYP_RAW_DEMODULATORS
endif
ifeq ($(ENABLE_BLMIN_TMP_OFF),1)
CFLAGS += -DENABLE_BLMIN_TMP_OFF
endif
ifeq ($(ENABLE_SCAN_RANGES),1)
CFLAGS += -DENABLE_SCAN_RANGES
endif
ifeq ($(ENABLE_DTMF_CALLING),1)
CFLAGS += -DENABLE_DTMF_CALLING
endif
LDFLAGS = -mcpu=cortex-m0 -nostartfiles -Wl,-T,firmware.ld
LDFLAGS =
ifeq ($(ENABLE_CLANG),0)
LDFLAGS += -mcpu=cortex-m0 -nostartfiles -Wl,-T,firmware.ld
else
# Fix warning about implied executable stack
LDFLAGS += -z noexecstack -mcpu=cortex-m0 -nostartfiles -Wl,-T,firmware.ld
endif
# Use newlib-nano instead of newlib
LDFLAGS += --specs=nano.specs
ifeq ($(ENABLE_LTO),0)
# Throw away unneeded func/data sections like LTO does
LDFLAGS += -Wl,--gc-sections
endif
ifeq ($(DEBUG),1)
ASFLAGS += -g
CFLAGS += -g
CFLAGS += -g
LDFLAGS += -g
endif
@@ -269,10 +387,34 @@ LIBS =
DEPS = $(OBJS:.o=.d)
ifneq (, $(shell $(WHERE) python))
MY_PYTHON := python
else ifneq (, $(shell $(WHERE) python3))
MY_PYTHON := python3
endif
ifdef MY_PYTHON
HAS_CRCMOD := $(shell $(MY_PYTHON) -c "import crcmod" 2>&1)
endif
all: $(TARGET)
$(OBJCOPY) -O binary $< $<.bin
-python fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin
-python3 fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin
ifndef MY_PYTHON
$(info )
$(info !!!!!!!! PYTHON NOT FOUND, *.PACKED.BIN WON'T BE BUILT)
$(info )
else ifneq (,$(HAS_CRCMOD))
$(info )
$(info !!!!!!!! CRCMOD NOT INSTALLED, *.PACKED.BIN WON'T BE BUILT)
$(info !!!!!!!! run: pip install crcmod)
$(info )
else
-$(MY_PYTHON) fw-pack.py $<.bin $(AUTHOR_STRING) $(VERSION_STRING) $<.packed.bin
endif
$(SIZE) $<
debug:
@@ -299,4 +441,4 @@ bsp/dp32g030/%.h: hardware/dp32g030/%.def
-include $(DEPS)
clean:
rm -f $(TARGET).bin $(TARGET).packed.bin $(TARGET) $(OBJS) $(DEPS)
$(RM) $(call FixPath, $(TARGET).bin $(TARGET).packed.bin $(TARGET) $(OBJS) $(DEPS))

181
README.md
View File

@@ -1,12 +1,48 @@
# Main features:
- OneOfEleven mods, including AM fix
- fagci spectrum analyzer
- better battery percentage calculation (based on real measurement)
* many of OneOfEleven mods:
* AM fix, huge improvement in reception quality
* longpress buttons functions replicating F+ action
* fast scanning
* channel name editing in the menu
* channel name + frequency display option
* shortcut for scannlist assignment (longpress `5 NOAA`)
* scannlist toggle (longpress `* Scan` while scanning)
* configurable button function selectable from menu
* battery percentage/voltage on status bar, selectable from menu
* longer backlight times
* mic bar
* RSSI s-meter
* more frequency steps
* squelch more sensitive
* fagci spectrum analyzer (**F+5** to turn on)
* some other mods introduced by me:
* SSB demodulation (adopted from fagci)
* backlight dimming
* battery voltage callibration from menu
* better battery percentage calculation, selectable for 1600mAh or 2200mAh
* more configurable button functions
* longpress MENU as another configurable button
* better DCS/CTCSS scanning in the menu (`* SCAN` while in RX DCS/CTCSS menu item)
* Piotr022 s-meter style
* restore initial freq/channel when scanning stopped with EXIT, remember last found transmission with MENU button
* reordered and renamed menu entries
* LCD interference crash fix
# Manual
* [Radio operation](https://github.com/egzumer/uv-k5-firmware-custom/wiki/Radio-operation)
* [Menu](https://github.com/egzumer/uv-k5-firmware-custom/wiki/Menu)
* [Button functions](https://github.com/egzumer/uv-k5-firmware-custom/wiki/Button-functions)
* [Spectrum analyzer](https://github.com/egzumer/uv-k5-firmware-custom/wiki/Spectrum-analyzer)
* [Flashing the firmware](https://github.com/egzumer/uv-k5-firmware-custom/wiki/Flashing-the-firmware)
<img src="images/main.jpg" width=300 /><img src="images/spectrum.jpg" width=300 /><img src="images/audiobar.jpg" width=300 /><img src="images/rssibar.jpg" width=300 />
# Open reimplementation of the Quan Sheng UV-K5 v2.1.27 firmware
This repository is a merge of OneOfEleven custom firmware with fagci spectrum analizer plus my few changes.
@@ -16,69 +52,71 @@ https://github.com/fagci/uv-k5-firmware-fagci-mod/tree/refactor
All is a cloned and customized version of DualTachyon's open firmware found here ..
https://github.com/DualTachyon/uv-k5-firmware
https://github.com/DualTachyon/uv-k5-firmware .. a cool achievement !
A cool achievement
Use this firmware at your own risk (entirely). There is absolutely no guarantee that it will work in any way shape or form on your radio(s), it may even brick your radio(s), in which case, you'd need to buy another radio.
Anyway, have fun.
# Radio performance
Please note that the Quansheng uv-k radios are not professional quality transceivers, their
performance is strictly limited, somewhat below that of a decent transceiver. The RX front
end has no track-tuned band pass filtering at all, and so are wide band/wide open to any
and all signals over a wide frequency range. Using the radio in high intensity RF environments
will nearly always destroy your reception, the receiver simply doesn't have a great dynamic
range, though are quite sensitive (weak signal wise).
Please note that the Quansheng UV-Kx radios are not professional quality transceivers, their
performance is strictly limited. The RX front end has no track-tuned band pass filtering
at all, and so are wide band/wide open to any and all signals over a large frequency range.
Saying that, they are nice toys for the price, fun to play with.
Using the radio in high intensity RF environments will most likely make reception anything but
easy (AM mode will suffer far more than FM ever will), the receiver simply doesn't have a
great dynamic range, which results in distorted AM audio with stronger RX'ed signals.
There is nothing more anyone can do in firmware/software to improve that, once the RX gain
adjustment I do (AM fix) reaches the hardwares limit, your AM RX audio will be all but
non-existant (just like Quansheng's firmware).
On the other hand, FM RX audio will/should be fine.
But, they are nice toys for the price, fun to play with.
# User customization
You can customize the firmware by enabling/disabling various compile options.
You can customize the firmware by enabling/disabling various compile options, this allows
us to remove certain firmware features in order to make room in the flash for others.
You'll find the options at the top of "Makefile" ('0' = disable, '1' = enable) ..
```
ENABLE_CLANG := 0 **experimental, builds with clang instead of gcc (LTO will be disabled if you enable this)
ENABLE_SWD := 0 only needed if using CPU's SWD port (debugging/programming)
ENABLE_OVERLAY := 1 cpu FLASH stuff
ENABLE_UART := 1 without this you can't configure radio via PC
ENABLE_AIRCOPY := 0 easier to just enter frequency
ENABLE_FMRADIO := 1 WBFM VHF band 2 RX
ENABLE_NOAA := 0 everything NOAA
ENABLE_OVERLAY := 0 cpu FLASH stuff, not needed
ENABLE_LTO := 0 **experimental, reduces size of compiled firmware but might break EEPROM reads (OVERLAY will be disabled if you enable this)
ENABLE_UART := 1 without this you can't configure radio via PC !
ENABLE_AIRCOPY := 0 easier to just enter frequency with butts
ENABLE_FMRADIO := 0 WBFM VHF broadcast band receiver
ENABLE_NOAA := 0 everything NOAA (only of any use in the USA)
ENABLE_VOICE := 0 want to hear voices ?
ENABLE_VOX := 0
ENABLE_ALARM := 0 TX alarms
ENABLE_BIG_FREQ := 0 big font frequencies
ENABLE_1750HZ := 0 side key 1750Hz TX tone (older style repeater access)
ENABLE_PWRON_PASSWORD := 1 power-on password stuff
ENABLE_BIG_FREQ := 0 big font frequencies (like original QS firmware)
ENABLE_SMALL_BOLD := 1 bold channel name/no. (when name + freq channel display mode)
ENABLE_KEEP_MEM_NAME := 1 maintain channel name when (re)saving memory channel
ENABLE_WIDE_RX := 1 full 18MHz to 1300MHz RX (though frontend not tuned over full range)
ENABLE_WIDE_RX := 1 full 18MHz to 1300MHz RX (though front-end/PA not designed for full range)
ENABLE_TX_WHEN_AM := 0 allow TX (always FM) when RX is set to AM
ENABLE_F_CAL_MENU := 0 enable the radios hidden frequency calibration menu
ENABLE_CTCSS_TAIL_PHASE_SHIFT := 1 standard CTCSS tail phase shift rather than QS's own 55Hz tone method
ENABLE_MAIN_KEY_HOLD := 1 initial F-key press not needed, instead hold down keys 0-9 to access the functions
ENABLE_BOOT_BEEPS := 0 give user audio feedback on volume knob position at boot-up
ENABLE_COMPANDER := 1 compander option (per channel)
ENABLE_BOOT_BEEPS := 0 gives user audio feedback on volume knob position at boot-up
ENABLE_SHOW_CHARGE_LEVEL := 0 show the charge level when the radio is on charge
ENABLE_REVERSE_BAT_SYMBOL := 1 mirror the battery symbol on the status bar (+ pole on the right)
ENABLE_NO_SCAN_TIMEOUT := 1 remove the 32 sec timeout from the CTCSS/DCS scan (press exit butt to end scan)
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
#ENABLE_BAND_SCOPE := 1 not yet implemented - spectrum/pan-adapter
ENABLE_NO_CODE_SCAN_TIMEOUT := 1 disable 32-sec CTCSS/DCS scan timeout (press exit butt instead of time-out to end scan)
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 level (for now)
ENABLE_AM_FIX_SHOW_DATA := 1 show debug data for the AM fix (still tweaking it)
ENABLE_SQUELCH_MORE_SENSITIVE := 0 make squelch levels a little bit more sensitive - I plan to let user adjust the values themselves
ENABLE_FASTER_CHANNEL_SCAN := 0 increases the channel scan speed, but the squelch is also made more twitchy
ENABLE_RSSI_BAR := 1 enable a dBm/Sn RSSI bar graph level inplace of the little antenna symbols
ENABLE_AUDIO_BAR := 0 experimental, display an audio bar level when TX'ing
ENABLE_COPY_CHAN_TO_VFO := 1 copy current channel into the other VFO. Long press `1 BAND` when in channel mode
ENABLE_SPECTRUM := 1 fagci spectrum analizer, activated with `F` + `5 NOAA`
ENABLE_REDUCE_LOW_MID_TX_POWER:= 0 makes medium and low power settings even lower
ENABLE_BYP_RAW_DEMODULATORS := 0 additional BYP (bypass?) and RAW demodulation options, prooved not to be very usefull, but it is there if you want to experiment
ENABLE_BLMIN_TMP_OFF := 0 additional function for configurable buttons that toggles `BLMin` on and off wihout saving it to the EEPROM
```
# Some changes made from the Quansheng firmware
* Various Quansheng firmware bugs fixed
* Added new bugs
* Mic menu includes max gain possible
* AM RX everywhere (left the TX as is)
* An attempt to improve the AM RX audio (demodulator getting saturated/overloaded in Quansheng firmware)
* keypad-5/NOAA button now toggles scanlist-1 on/off for current channel when held down - IF NOAA not used
* Better backlight times (inc always on)
* Live DTMF decoder option, though the decoder needs some coeff tuning changes to decode other radios it seems
* Various menu re-wordings (trying to reduce 'WTH does that mean ?')
* ..
# Compiler
@@ -86,28 +124,38 @@ arm-none-eabi GCC version 10.3.1 is recommended, which is the current version on
Other versions may generate a flash file that is too big.
You can get an appropriate version from: https://developer.arm.com/downloads/-/gnu-rm
clang may be used but isn't fully supported. Resulting binaries may also be bigger.
You can get it from: https://releases.llvm.org/download.html
# Building
To build the firmware, you need to fetch the submodules and then run make:
```
git submodule update --init --recursive --depth=1
make
```
If you have docker installed you can use `compile-with-docker.bat`, the output files are created in `compiled-firmware` folder. This method gives significantly smaller binaries, I've seen differences up to 1kb, so it can fit more functionalities this way. The challange can be (or not) installing the docker itself.
To compile directly in windows without the need of a linux virtual machine:
```
1. Download and install "gcc-arm-none-eabi-10.3-2021.10-win32.exe" from https://developer.arm.com/downloads/-/gnu-rm
2. Download and install "gnu_make-3.81.exe" from https://gnuwin32.sourceforge.net/packages/make.htm
To compile directly in windows:
3. You may (or not) need to manualy add gcc path to you OS environment PATH.
ie add C:\Program Files (x86)\GNU Arm Embedded Toolchain\10 2021.10\bin
4. You may (or not) need to reboot your PC after installing the above
```
Then you can run 'win_make.bat' from the directory you saved this source code too.
You may need to edit the bat file (path to make.exe) depending on where you installed the above two packages too.
1. Open windows command line and run:
```
winget install -e -h git.git Python.Python.3.8 GnuWin32.Make
winget install -e -h Arm.GnuArmEmbeddedToolchain -v "10 2021.10"
```
2. Close command line, open a new one and run:
```
pip install --user --upgrade pip
pip install crcmod
mkdir c:\projects & cd /D c:/projects
git clone https://github.com/egzumer/uv-k5-firmware-custom.git
```
3. From now on you can build the firmware by going to `c:\projects\uv-k5-firmware-custom` and running `win_make.bat` or by running a command line:
```
cd /D c:\projects\uv-k5-firmware-custom
win_make.bat
```
4. To reset the repository and pull new changes run (!!! it will delete all your changes !!!):
```
cd /D c:\projects\uv-k5-firmware-custom
git reset --hard & git clean -fd & git pull
```
I've left some notes in the win_make.bat file to maybe help with stuff.
@@ -115,6 +163,7 @@ I've left some notes in the win_make.bat file to maybe help with stuff.
Many thanks to various people on Telegram for putting up with me during this effort and helping:
* [OneOfEleven](https://github.com/OneOfEleven)
* [DualTachyon](https://github.com/DualTachyon)
* [Mikhail](https://github.com/fagci)
* [Andrej](https://github.com/Tunas1337)
@@ -148,13 +197,13 @@ You may obtain a copy of the License at
# Example changes/updates
<p float="left">
<img src="/image1.png" width=300 />
<img src="/image2.png" width=300 />
<img src="/image3.png" width=300 />
<img src="/images/image1.png" width=300 />
<img src="/images/image2.png" width=300 />
<img src="/images/image3.png" width=300 />
</p>
Video showing the AM fix working ..
<video src="/AM_fix.mp4"></video>
<video src="/images/AM_fix.mp4"></video>
<video src="https://github.com/OneOfEleven/uv-k5-firmware-custom/assets/51590168/2a3a9cdc-97da-4966-bf0d-1ce6ad09779c"></video>

332
am_fix.c
View File

@@ -30,30 +30,13 @@
#include "functions.h"
#include "misc.h"
// original QS front end register settings
const uint8_t orig_lna_short = 3; // 0dB
const uint8_t orig_lna = 2; // -14dB
const uint8_t orig_mixer = 3; // 0dB
const uint8_t orig_pga = 6; // -3dB
#ifdef ENABLE_AM_FIX
typedef struct
{
#if 1
// bitfields take up less flash bytes
uint8_t lna_short:2; // 0 ~ 3
uint8_t lna:3; // 0 ~ 7
uint8_t mixer:2; // 0 ~ 3
uint8_t pga:3; // 0 ~ 7
#else
uint8_t lna_short; // 0 ~ 3
uint8_t lna; // 0 ~ 7
uint8_t mixer; // 0 ~ 3
uint8_t pga; // 0 ~ 7
#endif
} t_gain_table;
//} __attribute__((packed)) t_gain_table;
uint16_t reg_val;
int8_t gain_dB;
} __attribute__((packed)) t_gain_table;
// REG_10 AGC gain table
//
@@ -68,10 +51,10 @@ const uint8_t orig_pga = 6; // -3dB
// <7:5> = LNA Gain
// 7 = 0dB
// 6 = -2dB
// 5 = -4dB
// 5 = -4dB < original value
// 4 = -6dB
// 3 = -9dB
// 2 = -14dB < original value
// 2 = -14dB
// 1 = -19dB
// 0 = -24dB
//
@@ -103,141 +86,140 @@ const uint8_t orig_pga = 6; // -3dB
// if I don't add the brackets, reading the table returns unexpected/different values !!!
//
//
// static const int16_t lna_short_dB[] = { -19, -16, -11, 0}; // was (but wrong)
static const int16_t lna_short_dB[] = { (-33), (-30), (-24), 0}; // corrected'ish
static const int16_t lna_dB[] = { (-24), (-19), (-14), ( -9), (-6), (-4), (-2), 0};
static const int16_t mixer_dB[] = { ( -8), ( -6), ( -3), 0};
static const int16_t pga_dB[] = { (-33), (-27), (-21), (-15), (-9), (-6), (-3), 0};
//// static const int16_t lna_short_dB[] = { -19, -16, -11, 0}; // was (but wrong)
// static const int16_t lna_short_dB[] = { (-33), (-30), (-24), 0}; // corrected'ish
// static const int16_t lna_dB[] = { (-24), (-19), (-14), ( -9), (-6), (-4), (-2), 0};
// static const int16_t mixer_dB[] = { ( -8), ( -6), ( -3), 0};
// static const int16_t pga_dB[] = { (-33), (-27), (-21), (-15), (-9), (-6), (-3), 0};
// lookup table is hugely easier than writing code to do the same
//
static const t_gain_table gain_table[] =
{
{.lna_short = 3, .lna = 2, .mixer = 3, .pga = 6}, // 0 0dB -14dB 0dB -3dB .. -17dB original
{0x035E, -17}, // 0 .. 3 2 3 6 .. 0dB -14dB 0dB -3dB .. -17dB original
#ifdef ENABLE_AM_FIX_TEST1
// test table that lets me manually set the lna-short register
// to measure it's actual dB change using an RF signal generator
{0, 2, 3, 6}, // 1 .. -33dB -14dB 0dB -3dB .. -50dB
{1, 2, 3, 6}, // 2 .. -30dB -14dB 0dB -3dB .. -47dB
{2, 2, 3, 6}, // 3 .. -24dB -14dB 0dB -3dB .. -41dB
{3, 2, 3, 6} // 4 .. 0dB -14dB 0dB -3dB .. -17dB
{0x005E, -50}, // 1 .. 0 2 3 6 .. -33dB -14dB 0dB -3dB .. -50dB
{0x015E, -47}, // 2 .. 1 2 3 6 .. -30dB -14dB 0dB -3dB .. -47dB
{0x025E, -41}, // 3 .. 2 2 3 6 .. -24dB -14dB 0dB -3dB .. -41dB
{0x035E, -17} // 4 .. 3 2 3 6 .. 0dB -14dB 0dB -3dB .. -17dB original
};
const unsigned int original_index = 1;
static const unsigned int original_index = 1;
#else
{0, 0, 0, 0}, // 1 .. -33dB -24dB -8dB -33dB .. -98dB
{0, 0, 1, 0}, // 2 .. -33dB -24dB -6dB -33dB .. -96dB
{1, 0, 0, 0}, // 3 .. -30dB -24dB -8dB -33dB .. -95dB
{0, 1, 0, 0}, // 4 .. -33dB -19dB -8dB -33dB .. -93dB
{0, 0, 0, 1}, // 5 .. -33dB -24dB -8dB -27dB .. -92dB
{0, 1, 1, 0}, // 6 .. -33dB -19dB -6dB -33dB .. -91dB
{0, 0, 1, 1}, // 7 .. -33dB -24dB -6dB -27dB .. -90dB
{1, 0, 0, 1}, // 8 .. -30dB -24dB -8dB -27dB .. -89dB
{0, 1, 2, 0}, // 9 .. -33dB -19dB -3dB -33dB .. -88dB
{1, 0, 3, 0}, // 10 .. -30dB -24dB 0dB -33dB .. -87dB
{0, 0, 0, 2}, // 11 .. -33dB -24dB -8dB -21dB .. -86dB
{1, 1, 2, 0}, // 12 .. -30dB -19dB -3dB -33dB .. -85dB
{0, 0, 3, 1}, // 13 .. -33dB -24dB 0dB -27dB .. -84dB
{0, 3, 0, 0}, // 14 .. -33dB -9dB -8dB -33dB .. -83dB
{1, 1, 3, 0}, // 15 .. -30dB -19dB 0dB -33dB .. -82dB
{1, 0, 3, 1}, // 16 .. -30dB -24dB 0dB -27dB .. -81dB
{0, 2, 3, 0}, // 17 .. -33dB -14dB 0dB -33dB .. -80dB
{1, 2, 0, 1}, // 18 .. -30dB -14dB -8dB -27dB .. -79dB
{0, 3, 2, 0}, // 19 .. -33dB -9dB -3dB -33dB .. -78dB
{1, 4, 0, 0}, // 20 .. -30dB -6dB -8dB -33dB .. -77dB
{1, 1, 3, 1}, // 21 .. -30dB -19dB 0dB -27dB .. -76dB
{0, 0, 2, 3}, // 22 .. -33dB -24dB -3dB -15dB .. -75dB
{1, 3, 0, 1}, // 23 .. -30dB -9dB -8dB -27dB .. -74dB
{1, 6, 0, 0}, // 24 .. -30dB -2dB -8dB -33dB .. -73dB
{0, 7, 1, 0}, // 25 .. -33dB 0dB -6dB -33dB .. -72dB
{0, 6, 2, 0}, // 26 .. -33dB -2dB -3dB -33dB .. -71dB
{2, 1, 3, 1}, // 27 .. -24dB -19dB 0dB -27dB .. -70dB
{0, 3, 1, 2}, // 28 .. -33dB -9dB -6dB -21dB .. -69dB
{0, 0, 0, 6}, // 29 .. -33dB -24dB -8dB -3dB .. -68dB
{0, 5, 2, 1}, // 30 .. -33dB -4dB -3dB -27dB .. -67dB
{0, 0, 1, 6}, // 31 .. -33dB -24dB -6dB -3dB .. -66dB
{1, 2, 3, 2}, // 32 .. -30dB -14dB 0dB -21dB .. -65dB
{2, 1, 1, 3}, // 33 .. -24dB -19dB -6dB -15dB .. -64dB
{1, 7, 3, 0}, // 34 .. -30dB 0dB 0dB -33dB .. -63dB
{1, 3, 0, 3}, // 35 .. -30dB -9dB -8dB -15dB .. -62dB
{0, 1, 2, 5}, // 36 .. -33dB -19dB -3dB -6dB .. -61dB
{2, 0, 2, 4}, // 37 .. -24dB -24dB -3dB -9dB .. -60dB
{1, 6, 3, 1}, // 38 .. -30dB -2dB 0dB -27dB .. -59dB
{1, 2, 0, 5}, // 39 .. -30dB -14dB -8dB -6dB .. -58dB
{2, 5, 0, 2}, // 40 .. -24dB -4dB -8dB -21dB .. -57dB
{2, 6, 2, 1}, // 41 .. -24dB -2dB -3dB -27dB .. -56dB
{0, 5, 2, 3}, // 42 .. -33dB -4dB -3dB -15dB .. -55dB
{2, 0, 2, 6}, // 43 .. -24dB -24dB -3dB -3dB .. -54dB
{0, 3, 0, 6}, // 44 .. -33dB -9dB -8dB -3dB .. -53dB
{0, 6, 0, 4}, // 45 .. -33dB -2dB -8dB -9dB .. -52dB
{0, 3, 1, 6}, // 46 .. -33dB -9dB -6dB -3dB .. -51dB
{1, 2, 3, 5}, // 47 .. -30dB -14dB 0dB -6dB .. -50dB
{0, 5, 1, 5}, // 48 .. -33dB -4dB -6dB -6dB .. -49dB
{0, 3, 3, 5}, // 49 .. -33dB -9dB 0dB -6dB .. -48dB
{0, 6, 2, 4}, // 50 .. -33dB -2dB -3dB -9dB .. -47dB
{1, 5, 2, 4}, // 51 .. -30dB -4dB -3dB -9dB .. -46dB
{3, 0, 1, 3}, // 52 .. 0dB -24dB -6dB -15dB .. -45dB
{0, 6, 1, 6}, // 53 .. -33dB -2dB -6dB -3dB .. -44dB
{1, 5, 2, 5}, // 54 .. -30dB -4dB -3dB -6dB .. -43dB
{0, 4, 2, 7}, // 55 .. -33dB -6dB -3dB 0dB .. -42dB
{2, 2, 2, 7}, // 56 .. -24dB -14dB -3dB 0dB .. -41dB
{2, 5, 2, 4}, // 57 .. -24dB -4dB -3dB -9dB .. -40dB
{2, 3, 3, 5}, // 58 .. -24dB -9dB 0dB -6dB .. -39dB
{1, 6, 3, 5}, // 59 .. -30dB -2dB 0dB -6dB .. -38dB
{2, 5, 1, 6}, // 60 .. -24dB -4dB -6dB -3dB .. -37dB
{3, 3, 3, 1}, // 61 .. 0dB -9dB 0dB -27dB .. -36dB
{3, 2, 3, 2}, // 62 .. 0dB -14dB 0dB -21dB .. -35dB
{2, 5, 2, 6}, // 63 .. -24dB -4dB -3dB -3dB .. -34dB
{3, 0, 1, 6}, // 64 .. 0dB -24dB -6dB -3dB .. -33dB
{3, 0, 0, 7}, // 65 .. 0dB -24dB -8dB 0dB .. -32dB
{2, 5, 3, 6}, // 66 .. -24dB -4dB 0dB -3dB .. -31dB
{3, 3, 3, 2}, // 67 .. 0dB -9dB 0dB -21dB .. -30dB
{2, 6, 3, 6}, // 68 .. -24dB -2dB 0dB -3dB .. -29dB
{3, 2, 0, 5}, // 69 .. 0dB -14dB -8dB -6dB .. -28dB
{3, 5, 0, 3}, // 70 .. 0dB -4dB -8dB -15dB .. -27dB
{3, 3, 0, 4}, // 71 .. 0dB -9dB -8dB -9dB .. -26dB
{3, 1, 1, 7}, // 72 .. 0dB -19dB -6dB 0dB .. -25dB
{3, 4, 2, 3}, // 73 .. 0dB -6dB -3dB -15dB .. -24dB
{3, 4, 0, 4}, // 74 .. 0dB -6dB -8dB -9dB .. -23dB
{3, 2, 0, 7}, // 75 .. 0dB -14dB -8dB 0dB .. -22dB
{3, 7, 1, 3}, // 76 .. 0dB 0dB -6dB -15dB .. -21dB
{3, 6, 2, 3}, // 77 .. 0dB -2dB -3dB -15dB .. -20dB
{3, 5, 3, 3}, // 78 .. 0dB -4dB 0dB -15dB .. -19dB
{3, 3, 3, 4}, // 79 .. 0dB -9dB 0dB -9dB .. -18dB
{3, 2, 3, 6}, // 80 .. 0dB -14dB 0dB -3dB .. -17dB original
{3, 6, 0, 5}, // 81 .. 0dB -2dB -8dB -6dB .. -16dB
{3, 7, 1, 4}, // 82 .. 0dB 0dB -6dB -9dB .. -15dB
{3, 2, 3, 7}, // 83 .. 0dB -14dB 0dB 0dB .. -14dB
{3, 6, 0, 6}, // 84 .. 0dB -2dB -8dB -3dB .. -13dB
{3, 3, 2, 7}, // 85 .. 0dB -9dB -3dB 0dB .. -12dB
{3, 7, 0, 6}, // 86 .. 0dB 0dB -8dB -3dB .. -11dB
{3, 5, 3, 5}, // 87 .. 0dB -4dB 0dB -6dB .. -10dB
{3, 7, 2, 5}, // 88 .. 0dB 0dB -3dB -6dB .. -9dB
{3, 6, 3, 5}, // 89 .. 0dB -2dB 0dB -6dB .. -8dB
{3, 5, 2, 7}, // 90 .. 0dB -4dB -3dB 0dB .. -7dB
{3, 7, 2, 6}, // 91 .. 0dB 0dB -3dB -3dB .. -6dB
{3, 6, 2, 7}, // 92 .. 0dB -2dB -3dB 0dB .. -5dB
{3, 5, 3, 7}, // 93 .. 0dB -4dB 0dB 0dB .. -4dB
{3, 7, 2, 7}, // 94 .. 0dB 0dB -3dB 0dB .. -3dB
{3, 6, 3, 7}, // 95 .. 0dB -2dB 0dB 0dB .. -2dB
{3, 7, 3, 7} // 96 .. 0dB 0dB 0dB 0dB .. 0dB
{0x0000, -98}, // 1 .. 0 0 0 0 .. -33dB -24dB -8dB -33dB .. -98dB
{0x0008, -96}, // 2 .. 0 0 1 0 .. -33dB -24dB -6dB -33dB .. -96dB
{0x0100, -95}, // 3 .. 1 0 0 0 .. -30dB -24dB -8dB -33dB .. -95dB
{0x0020, -93}, // 4 .. 0 1 0 0 .. -33dB -19dB -8dB -33dB .. -93dB
{0x0001, -92}, // 5 .. 0 0 0 1 .. -33dB -24dB -8dB -27dB .. -92dB
{0x0028, -91}, // 6 .. 0 1 1 0 .. -33dB -19dB -6dB -33dB .. -91dB
{0x0009, -90}, // 7 .. 0 0 1 1 .. -33dB -24dB -6dB -27dB .. -90dB
{0x0101, -89}, // 8 .. 1 0 0 1 .. -30dB -24dB -8dB -27dB .. -89dB
{0x0030, -88}, // 9 .. 0 1 2 0 .. -33dB -19dB -3dB -33dB .. -88dB
{0x0118, -87}, // 10 .. 1 0 3 0 .. -30dB -24dB 0dB -33dB .. -87dB
{0x0002, -86}, // 11 .. 0 0 0 2 .. -33dB -24dB -8dB -21dB .. -86dB
{0x0130, -85}, // 12 .. 1 1 2 0 .. -30dB -19dB -3dB -33dB .. -85dB
{0x0019, -84}, // 13 .. 0 0 3 1 .. -33dB -24dB 0dB -27dB .. -84dB
{0x0060, -83}, // 14 .. 0 3 0 0 .. -33dB -9dB -8dB -33dB .. -83dB
{0x0138, -82}, // 15 .. 1 1 3 0 .. -30dB -19dB 0dB -33dB .. -82dB
{0x0119, -81}, // 16 .. 1 0 3 1 .. -30dB -24dB 0dB -27dB .. -81dB
{0x0058, -80}, // 17 .. 0 2 3 0 .. -33dB -14dB 0dB -33dB .. -80dB
{0x0141, -79}, // 18 .. 1 2 0 1 .. -30dB -14dB -8dB -27dB .. -79dB
{0x0070, -78}, // 19 .. 0 3 2 0 .. -33dB -9dB -3dB -33dB .. -78dB
{0x0180, -77}, // 20 .. 1 4 0 0 .. -30dB -6dB -8dB -33dB .. -77dB
{0x0139, -76}, // 21 .. 1 1 3 1 .. -30dB -19dB 0dB -27dB .. -76dB
{0x0013, -75}, // 22 .. 0 0 2 3 .. -33dB -24dB -3dB -15dB .. -75dB
{0x0161, -74}, // 23 .. 1 3 0 1 .. -30dB -9dB -8dB -27dB .. -74dB
{0x01C0, -73}, // 24 .. 1 6 0 0 .. -30dB -2dB -8dB -33dB .. -73dB
{0x00E8, -72}, // 25 .. 0 7 1 0 .. -33dB 0dB -6dB -33dB .. -72dB
{0x00D0, -71}, // 26 .. 0 6 2 0 .. -33dB -2dB -3dB -33dB .. -71dB
{0x0239, -70}, // 27 .. 2 1 3 1 .. -24dB -19dB 0dB -27dB .. -70dB
{0x006A, -69}, // 28 .. 0 3 1 2 .. -33dB -9dB -6dB -21dB .. -69dB
{0x0006, -68}, // 29 .. 0 0 0 6 .. -33dB -24dB -8dB -3dB .. -68dB
{0x00B1, -67}, // 30 .. 0 5 2 1 .. -33dB -4dB -3dB -27dB .. -67dB
{0x000E, -66}, // 31 .. 0 0 1 6 .. -33dB -24dB -6dB -3dB .. -66dB
{0x015A, -65}, // 32 .. 1 2 3 2 .. -30dB -14dB 0dB -21dB .. -65dB
{0x022B, -64}, // 33 .. 2 1 1 3 .. -24dB -19dB -6dB -15dB .. -64dB
{0x01F8, -63}, // 34 .. 1 7 3 0 .. -30dB 0dB 0dB -33dB .. -63dB
{0x0163, -62}, // 35 .. 1 3 0 3 .. -30dB -9dB -8dB -15dB .. -62dB
{0x0035, -61}, // 36 .. 0 1 2 5 .. -33dB -19dB -3dB -6dB .. -61dB
{0x0214, -60}, // 37 .. 2 0 2 4 .. -24dB -24dB -3dB -9dB .. -60dB
{0x01D9, -59}, // 38 .. 1 6 3 1 .. -30dB -2dB 0dB -27dB .. -59dB
{0x0145, -58}, // 39 .. 1 2 0 5 .. -30dB -14dB -8dB -6dB .. -58dB
{0x02A2, -57}, // 40 .. 2 5 0 2 .. -24dB -4dB -8dB -21dB .. -57dB
{0x02D1, -56}, // 41 .. 2 6 2 1 .. -24dB -2dB -3dB -27dB .. -56dB
{0x00B3, -55}, // 42 .. 0 5 2 3 .. -33dB -4dB -3dB -15dB .. -55dB
{0x0216, -54}, // 43 .. 2 0 2 6 .. -24dB -24dB -3dB -3dB .. -54dB
{0x0066, -53}, // 44 .. 0 3 0 6 .. -33dB -9dB -8dB -3dB .. -53dB
{0x00C4, -52}, // 45 .. 0 6 0 4 .. -33dB -2dB -8dB -9dB .. -52dB
{0x006E, -51}, // 46 .. 0 3 1 6 .. -33dB -9dB -6dB -3dB .. -51dB
{0x015D, -50}, // 47 .. 1 2 3 5 .. -30dB -14dB 0dB -6dB .. -50dB
{0x00AD, -49}, // 48 .. 0 5 1 5 .. -33dB -4dB -6dB -6dB .. -49dB
{0x007D, -48}, // 49 .. 0 3 3 5 .. -33dB -9dB 0dB -6dB .. -48dB
{0x00D4, -47}, // 50 .. 0 6 2 4 .. -33dB -2dB -3dB -9dB .. -47dB
{0x01B4, -46}, // 51 .. 1 5 2 4 .. -30dB -4dB -3dB -9dB .. -46dB
{0x030B, -45}, // 52 .. 3 0 1 3 .. 0dB -24dB -6dB -15dB .. -45dB
{0x00CE, -44}, // 53 .. 0 6 1 6 .. -33dB -2dB -6dB -3dB .. -44dB
{0x01B5, -43}, // 54 .. 1 5 2 5 .. -30dB -4dB -3dB -6dB .. -43dB
{0x0097, -42}, // 55 .. 0 4 2 7 .. -33dB -6dB -3dB 0dB .. -42dB
{0x0257, -41}, // 56 .. 2 2 2 7 .. -24dB -14dB -3dB 0dB .. -41dB
{0x02B4, -40}, // 57 .. 2 5 2 4 .. -24dB -4dB -3dB -9dB .. -40dB
{0x027D, -39}, // 58 .. 2 3 3 5 .. -24dB -9dB 0dB -6dB .. -39dB
{0x01DD, -38}, // 59 .. 1 6 3 5 .. -30dB -2dB 0dB -6dB .. -38dB
{0x02AE, -37}, // 60 .. 2 5 1 6 .. -24dB -4dB -6dB -3dB .. -37dB
{0x0379, -36}, // 61 .. 3 3 3 1 .. 0dB -9dB 0dB -27dB .. -36dB
{0x035A, -35}, // 62 .. 3 2 3 2 .. 0dB -14dB 0dB -21dB .. -35dB
{0x02B6, -34}, // 63 .. 2 5 2 6 .. -24dB -4dB -3dB -3dB .. -34dB
{0x030E, -33}, // 64 .. 3 0 1 6 .. 0dB -24dB -6dB -3dB .. -33dB
{0x0307, -32}, // 65 .. 3 0 0 7 .. 0dB -24dB -8dB 0dB .. -32dB
{0x02BE, -31}, // 66 .. 2 5 3 6 .. -24dB -4dB 0dB -3dB .. -31dB
{0x037A, -30}, // 67 .. 3 3 3 2 .. 0dB -9dB 0dB -21dB .. -30dB
{0x02DE, -29}, // 68 .. 2 6 3 6 .. -24dB -2dB 0dB -3dB .. -29dB
{0x0345, -28}, // 69 .. 3 2 0 5 .. 0dB -14dB -8dB -6dB .. -28dB
{0x03A3, -27}, // 70 .. 3 5 0 3 .. 0dB -4dB -8dB -15dB .. -27dB
{0x0364, -26}, // 71 .. 3 3 0 4 .. 0dB -9dB -8dB -9dB .. -26dB
{0x032F, -25}, // 72 .. 3 1 1 7 .. 0dB -19dB -6dB 0dB .. -25dB
{0x0393, -24}, // 73 .. 3 4 2 3 .. 0dB -6dB -3dB -15dB .. -24dB
{0x0384, -23}, // 74 .. 3 4 0 4 .. 0dB -6dB -8dB -9dB .. -23dB
{0x0347, -22}, // 75 .. 3 2 0 7 .. 0dB -14dB -8dB 0dB .. -22dB
{0x03EB, -21}, // 76 .. 3 7 1 3 .. 0dB 0dB -6dB -15dB .. -21dB
{0x03D3, -20}, // 77 .. 3 6 2 3 .. 0dB -2dB -3dB -15dB .. -20dB
{0x03BB, -19}, // 78 .. 3 5 3 3 .. 0dB -4dB 0dB -15dB .. -19dB
{0x037C, -18}, // 79 .. 3 3 3 4 .. 0dB -9dB 0dB -9dB .. -18dB
{0x03CC, -17}, // 80 .. 3 6 1 4 .. 0dB -2dB -6dB -9dB .. -17dB
{0x03C5, -16}, // 81 .. 3 6 0 5 .. 0dB -2dB -8dB -6dB .. -16dB
{0x03EC, -15}, // 82 .. 3 7 1 4 .. 0dB 0dB -6dB -9dB .. -15dB
{0x035F, -14}, // 83 .. 3 2 3 7 .. 0dB -14dB 0dB 0dB .. -14dB
{0x03BC, -13}, // 84 .. 3 5 3 4 .. 0dB -4dB 0dB -9dB .. -13dB
{0x038F, -12}, // 85 .. 3 4 1 7 .. 0dB -6dB -6dB 0dB .. -12dB
{0x03E6, -11}, // 86 .. 3 7 0 6 .. 0dB 0dB -8dB -3dB .. -11dB
{0x03AF, -10}, // 87 .. 3 5 1 7 .. 0dB -4dB -6dB 0dB .. -10dB
{0x03F5, -9 }, // 88 .. 3 7 2 5 .. 0dB 0dB -3dB -6dB .. -9dB
{0x03D6, -8 }, // 89 .. 3 6 2 6 .. 0dB -2dB -3dB -3dB .. -8dB
{0x03BE, -7 }, // 90 .. 3 5 3 6 .. 0dB -4dB 0dB -3dB .. -7dB original
{0x03F6, -6 }, // 91 .. 3 7 2 6 .. 0dB 0dB -3dB -3dB .. -6dB
{0x03DE, -5 }, // 92 .. 3 6 3 6 .. 0dB -2dB 0dB -3dB .. -5dB
{0x03BF, -4 }, // 93 .. 3 5 3 7 .. 0dB -4dB 0dB 0dB .. -4dB
{0x03F7, -3 }, // 94 .. 3 7 2 7 .. 0dB 0dB -3dB 0dB .. -3dB
{0x03DF, -2 }, // 95 .. 3 6 3 7 .. 0dB -2dB 0dB 0dB .. -2dB
{0x03FF, 0 }, // 96 .. 3 7 3 7 .. 0dB 0dB 0dB 0dB .. 0dB
};
const unsigned int original_index = 80;
static const unsigned int original_index = 90;
#endif
// total RF gain for each table index
int8_t gain_dB[ARRAY_SIZE(gain_table)] = {0};
// display update rate
const unsigned int display_update_rate = 250 / 10; // max 250ms display update rate
unsigned int counter = 0;
#ifdef ENABLE_AM_FIX_SHOW_DATA
// display update rate
static const unsigned int display_update_rate = 250 / 10; // max 250ms display update rate
unsigned int counter = 0;
#endif
#ifdef ENABLE_AM_FIX_TEST1
// user manually sets the table index .. used to calibrate the desired dB gain table
@@ -280,13 +262,6 @@ const uint8_t orig_pga = 6; // -3dB
#endif
}
// pre-compute the total gain for each table index .. saves doing it in real time
for (i = 0; i < ARRAY_SIZE(gain_table); i++)
{
const t_gain_table gains = gain_table[i];
gain_dB[i] = lna_short_dB[gains.lna_short] + lna_dB[gains.lna] + mixer_dB[gains.mixer] + pga_dB[gains.pga];
}
#if 0
{ // set a maximum gain to use
// const int16_t max_gain_dB = gain_dB[original_index];
@@ -294,7 +269,8 @@ const uint8_t orig_pga = 6; // -3dB
max_index = ARRAY_SIZE(gain_table);
while (--max_index > 1)
if (gain_dB[max_index] <= max_gain_dB)
// if (gain_dB[max_index] <= max_gain_dB)
if (gain_table[max_index].gain_dB <= max_gain_dB)
break;
}
#else
@@ -306,7 +282,9 @@ const uint8_t orig_pga = 6; // -3dB
void AM_fix_reset(const int vfo)
{ // reset the AM fixer upper
counter = 0;
#ifdef ENABLE_AM_FIX_SHOW_DATA
counter = 0;
#endif
prev_rssi[vfo] = 0;
@@ -340,7 +318,9 @@ const uint8_t orig_pga = 6; // -3dB
case FUNCTION_TRANSMIT:
case FUNCTION_BAND_SCOPE:
case FUNCTION_POWER_SAVE:
counter = display_update_rate; // queue up a display update as soon as we switch to RX mode
#ifdef ENABLE_AM_FIX_SHOW_DATA
counter = display_update_rate; // queue up a display update as soon as we switch to RX mode
#endif
return;
// only adjust stuff if we're in one of these modes
@@ -351,14 +331,16 @@ const uint8_t orig_pga = 6; // -3dB
break;
}
if (counter > 0)
{
if (++counter >= display_update_rate)
{ // trigger a display update
counter = 0;
gUpdateDisplay = true;
#ifdef ENABLE_AM_FIX_SHOW_DATA
if (counter > 0)
{
if (++counter >= display_update_rate)
{ // trigger a display update
counter = 0;
gUpdateDisplay = true;
}
}
}
#endif
{ // sample the current RSSI level
// average it with the previous rssi (a bit of noise/spike immunity)
@@ -367,11 +349,14 @@ const uint8_t orig_pga = 6; // -3dB
prev_rssi[vfo] = new_rssi;
}
{ // save the corrected RSSI level
// save the corrected RSSI level
#ifdef ENABLE_AM_FIX_SHOW_DATA
{
const int16_t new_rssi = rssi - rssi_gain_diff[vfo];
if (gCurrentRSSI[vfo] != new_rssi)
{
gCurrentRSSI[vfo] = new_rssi;
if (counter == 0)
{ // trigger a display update
counter = 1;
@@ -379,6 +364,9 @@ const uint8_t orig_pga = 6; // -3dB
}
}
}
#else
gCurrentRSSI[vfo] = rssi - rssi_gain_diff[vfo];
#endif
#ifdef ENABLE_AM_FIX_TEST1
// user is manually adjusting a gain register - don't do anything automatically
@@ -411,10 +399,12 @@ const uint8_t orig_pga = 6; // -3dB
if (diff_dB >= 10)
{ // jump immediately to a new gain setting
// this greatly speeds up initial gain reduction (but reduces noise/spike immunity)
const int16_t desired_gain_dB = (int16_t)gain_dB[index] - diff_dB + 8; // get no closer than 8dB (bit of noise/spike immunity)
const int16_t desired_gain_dB = (int16_t)gain_table[index].gain_dB - diff_dB + 8; // get no closer than 8dB (bit of noise/spike immunity)
// scan the table to see what index to jump straight too
while (index > 1)
if (gain_dB[--index] <= desired_gain_dB)
if (gain_table[--index].gain_dB <= desired_gain_dB)
break;
//index = (gain_table_index[vfo] + index) / 2; // easy does it
@@ -438,7 +428,7 @@ const uint8_t orig_pga = 6; // -3dB
}
}
if (diff_dB >= -4) // 4dB hysterisis (help reduce gain hunting)
if (diff_dB >= -6) // 6dB hysterisis (help reduce gain hunting)
hold_counter[vfo] = 30; // 300ms hold
if (hold_counter[vfo] == 0)
@@ -447,8 +437,10 @@ const uint8_t orig_pga = 6; // -3dB
gain_table_index[vfo] = (index <= max_index) ? index : max_index; // limit the gain index
}
if (gain_table_index[vfo] == gain_table_index_prev[vfo])
return; // no gain change
#if 0
if (gain_table_index[vfo] == gain_table_index_prev[vfo])
return; // no gain change - this is to reduce writing to the BK chip on ever call
#endif
#endif
@@ -459,33 +451,35 @@ const uint8_t orig_pga = 6; // -3dB
// remember the new table index
gain_table_index_prev[vfo] = index;
const t_gain_table gains = gain_table[index];
BK4819_WriteRegister(BK4819_REG_13, ((uint16_t)gains.lna_short << 8) | ((uint16_t)gains.lna << 5) | ((uint16_t)gains.mixer << 3) | ((uint16_t)gains.pga << 0));
BK4819_WriteRegister(BK4819_REG_13, gain_table[index].reg_val);
// offset the RSSI reading to the rest of the firmware to cancel out the gain adjustments we make
// RF gain difference from original QS setting
rssi_gain_diff[vfo] = ((int16_t)gain_dB[index] - gain_dB[original_index]) * 2;
rssi_gain_diff[vfo] = ((int16_t)gain_table[index].gain_dB - gain_table[original_index].gain_dB) * 2;
}
// save the corrected RSSI level
gCurrentRSSI[vfo] = rssi - rssi_gain_diff[vfo];
if (counter == 0)
{
counter = 1;
gUpdateDisplay = true;
}
#ifdef ENABLE_AM_FIX_SHOW_DATA
if (counter == 0)
{
counter = 1;
gUpdateDisplay = true;
}
#endif
}
#ifdef ENABLE_AM_FIX_SHOW_DATA
void AM_fix_print_data(const int vfo, char *s)
{
if (s != NULL)
if (s != NULL && vfo >= 0 && vfo < (int)ARRAY_SIZE(gain_table_index))
{
const unsigned int index = gain_table_index[vfo];
sprintf(s, "%2u.%u %4ddB %3u", index, ARRAY_SIZE(gain_table) - 1, gain_dB[index], prev_rssi[vfo]);
// sprintf(s, "%2u.%u %4ddB %3u", index, ARRAY_SIZE(gain_table) - 1, gain_table[index].gain_dB, prev_rssi[vfo]);
sprintf(s, "%2u %4ddB %3u", index, gain_table[index].gain_dB, prev_rssi[vfo]);
counter = 0;
}
}

View File

@@ -20,11 +20,6 @@
#include <stdint.h>
#include <stdbool.h>
extern const uint8_t orig_lna_short;
extern const uint8_t orig_lna;
extern const uint8_t orig_mixer;
extern const uint8_t orig_pga;
#ifdef ENABLE_AM_FIX
extern int16_t rssi_gain_diff[2];

View File

@@ -14,8 +14,12 @@
* limitations under the License.
*/
#include <string.h>
#include "app/action.h"
#include "app/app.h"
#include "app/chFrScanner.h"
#include "app/common.h"
#include "app/dtmf.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
@@ -28,6 +32,7 @@
#endif
#include "driver/bk4819.h"
#include "driver/gpio.h"
#include "driver/backlight.h"
#include "functions.h"
#include "misc.h"
#include "settings.h"
@@ -43,6 +48,7 @@ static void ACTION_FlashLight(void)
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
break;
case 1:
case 2:
gFlashLightState++;
break;
default:
@@ -57,24 +63,22 @@ void ACTION_Power(void)
gTxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW;
gRequestSaveChannel = 1;
//gRequestSaveChannel = 2; // auto save the channel
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_POWER;
#endif
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_POWER;
#endif
gRequestDisplayScreen = gScreenToDisplay;
}
void ACTION_Monitor(void)
{
if (gCurrentFunction != FUNCTION_MONITOR)
{ // enable the monitor
if (gCurrentFunction != FUNCTION_MONITOR) { // enable the monitor
RADIO_SelectVfos();
#ifdef ENABLE_NOAA
if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST && gIsNoaaMode)
gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
#endif
#ifdef ENABLE_NOAA
if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST && gIsNoaaMode)
gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
#endif
RADIO_SetupRegisters(true);
APP_StartListening(FUNCTION_MONITOR, false);
return;
@@ -82,110 +86,131 @@ void ACTION_Monitor(void)
gMonitor = false;
if (gScanState != SCAN_OFF)
{
ScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms;
gScheduleScanListen = false;
gScanPauseMode = true;
if (gScanStateDir != SCAN_OFF) {
gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms;
gScheduleScanListen = false;
gScanPauseMode = true;
}
#ifdef ENABLE_NOAA
if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode)
{
gNOAA_Countdown_10ms = NOAA_countdown_10ms;
gScheduleNOAA = false;
}
#endif
#ifdef ENABLE_NOAA
if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode) {
gNOAA_Countdown_10ms = NOAA_countdown_10ms;
gScheduleNOAA = false;
}
#endif
RADIO_SetupRegisters(true);
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
{
FM_Start();
gRequestDisplayScreen = DISPLAY_FM;
}
else
#endif
gRequestDisplayScreen = gScreenToDisplay;
#ifdef ENABLE_FMRADIO
if (gFmRadioMode) {
FM_Start();
gRequestDisplayScreen = DISPLAY_FM;
}
else
#endif
gRequestDisplayScreen = gScreenToDisplay;
}
void ACTION_Scan(bool bRestart)
{
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
(void)bRestart;
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
{
if (gCurrentFunction != FUNCTION_RECEIVE &&
gCurrentFunction != FUNCTION_MONITOR &&
gCurrentFunction != FUNCTION_TRANSMIT)
{
if (gCurrentFunction != FUNCTION_RECEIVE &&
gCurrentFunction != FUNCTION_MONITOR &&
gCurrentFunction != FUNCTION_TRANSMIT)
GUI_SelectNextDisplay(DISPLAY_FM);
gMonitor = false;
if (gFM_ScanState != FM_SCAN_OFF)
{
GUI_SelectNextDisplay(DISPLAY_FM);
FM_PlayAndUpdate();
gMonitor = false;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
else
{
uint16_t Frequency;
if (gFM_ScanState != FM_SCAN_OFF)
if (bRestart)
{
FM_PlayAndUpdate();
gFM_AutoScan = true;
gFM_ChannelPosition = 0;
FM_EraseChannels();
Frequency = gEeprom.FM_LowerLimit;
}
else
{
gFM_AutoScan = false;
gFM_ChannelPosition = 0;
Frequency = gEeprom.FM_FrequencyPlaying;
}
BK1080_GetFrequencyDeviation(Frequency);
FM_Tune(Frequency, 1, bRestart);
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;
#endif
}
}
return;
}
#endif
if (!SCANNER_IsScanning())
{ // not scanning
gMonitor = false;
#ifdef ENABLE_DTMF_CALLING
DTMF_clear_RX();
#endif
gDTMF_RX_live_timeout = 0;
memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live));
RADIO_SelectVfos();
#ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif
{
GUI_SelectNextDisplay(DISPLAY_MAIN);
if (gScanStateDir != SCAN_OFF)
{ // already scanning
if (IS_MR_CHANNEL(gNextMrChannel))
{ // channel mode
// keep scanning but toggle between scan lists
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3;
// jump to the next channel
CHFRSCANNER_Start(false, gScanStateDir);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;
gUpdateStatus = true;
}
else
{ // stop scanning
CHFRSCANNER_Stop();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
else
{
uint16_t Frequency;
if (bRestart)
{
gFM_AutoScan = true;
gFM_ChannelPosition = 0;
FM_EraseChannels();
Frequency = gEeprom.FM_LowerLimit;
}
else
{
gFM_AutoScan = false;
gFM_ChannelPosition = 0;
Frequency = gEeprom.FM_FrequencyPlaying;
}
BK1080_GetFrequencyDeviation(Frequency);
FM_Tune(Frequency, 1, bRestart);
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;
#endif
}
}
return;
}
#endif
if (gScreenToDisplay != DISPLAY_SCANNER)
{ // not scanning
gMonitor = false;
RADIO_SelectVfos();
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif
{
GUI_SelectNextDisplay(DISPLAY_MAIN);
if (gScanState != SCAN_OFF)
{
SCANNER_Stop();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
else
{
CHANNEL_Next(true, 1);
{ // start scanning
CHFRSCANNER_Start(true, SCAN_FWD);
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN);
@@ -193,7 +218,7 @@ void ACTION_Scan(bool bRestart)
#endif
// clear the other vfo's rssi level (to hide the antenna symbol)
gVFO_RSSI_bar_level[gEeprom.RX_CHANNEL == 0] = 0;
gVFO_RSSI_bar_level[(gEeprom.RX_VFO + 1) & 1u] = 0;
// let the user see DW is not active
gDualWatchActive = false;
@@ -201,44 +226,45 @@ void ACTION_Scan(bool bRestart)
}
}
}
else
if (!bRestart)
{ // scanning
gMonitor = false;
SCANNER_Stop();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
gRequestDisplayScreen = DISPLAY_MAIN;
}
}
void ACTION_Vox(void)
{
gEeprom.VOX_SWITCH = !gEeprom.VOX_SWITCH;
gRequestSaveSettings = true;
gFlagReconfigureVfos = true;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_VOX;
#endif
gUpdateStatus = true;
}
#ifdef ENABLE_ALARM
static void ACTION_AlarmOr1750(bool b1750)
#ifdef ENABLE_VOX
void ACTION_Vox(void)
{
gInputBoxIndex = 0;
gAlarmState = b1750 ? ALARM_STATE_TX1750 : ALARM_STATE_TXALARM;
gAlarmRunningCounter = 0;
gFlagPrepareTX = true;
gRequestDisplayScreen = DISPLAY_MAIN;
gEeprom.VOX_SWITCH = !gEeprom.VOX_SWITCH;
gRequestSaveSettings = true;
gFlagReconfigureVfos = true;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_VOX;
#endif
gUpdateStatus = true;
}
#endif
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
static void ACTION_AlarmOr1750(const bool b1750)
{
(void)b1750;
gInputBoxIndex = 0;
#if defined(ENABLE_ALARM) && defined(ENABLE_TX1750)
gAlarmState = b1750 ? ALARM_STATE_TX1750 : ALARM_STATE_TXALARM;
gAlarmRunningCounter = 0;
#elif defined(ENABLE_ALARM)
gAlarmState = ALARM_STATE_TXALARM;
gAlarmRunningCounter = 0;
#else
gAlarmState = ALARM_STATE_TX1750;
#endif
gFlagPrepareTX = true;
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
gRequestDisplayScreen = DISPLAY_MAIN;
}
#endif
#ifdef ENABLE_FMRADIO
void ACTION_FM(void)
{
@@ -249,8 +275,11 @@ void ACTION_Vox(void)
FM_TurnOff();
gInputBoxIndex = 0;
gVoxResumeCountdown = 80;
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
#endif
gFlagReconfigureVfos = true;
gRequestDisplayScreen = DISPLAY_MAIN;
return;
}
@@ -262,26 +291,47 @@ void ACTION_Vox(void)
FM_Start();
gInputBoxIndex = 0;
gInputBoxIndex = 0;
gRequestDisplayScreen = DISPLAY_FM;
}
}
#endif
void ACTION_SwitchDemodul(void)
{
gTxVfo->Modulation++;
if(gTxVfo->Modulation == MODULATION_UKNOWN)
gTxVfo->Modulation = MODULATION_FM;
gRequestSaveChannel = 1;
}
#ifdef ENABLE_BLMIN_TMP_OFF
void ACTION_BlminTmpOff(void)
{
if(++gEeprom.BACKLIGHT_MIN_STAT == BLMIN_STAT_UNKNOWN)
{
gEeprom.BACKLIGHT_MIN_STAT = BLMIN_STAT_ON;
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MIN);
} else
{
BACKLIGHT_SetBrightness(0);
}
}
#endif
void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
uint8_t Short = ACTION_OPT_NONE;
uint8_t Long = ACTION_OPT_NONE;
if (gScreenToDisplay == DISPLAY_MAIN && gDTMF_InputMode)
if (gScreenToDisplay == DISPLAY_MAIN && gDTMF_InputMode) // entering DTMF code
{
if (Key == KEY_SIDE1 && !bKeyHeld && bKeyPressed)
if (Key == KEY_SIDE1 && !bKeyHeld && bKeyPressed) // side1 btn pressed
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gDTMF_InputIndex > 0)
if (gDTMF_InputBox_Index > 0) // DTMF codes are in the input box
{
gDTMF_InputBox[--gDTMF_InputIndex] = '-';
if (gDTMF_InputIndex > 0)
gDTMF_InputBox[--gDTMF_InputBox_Index] = '-'; // delete one code
if (gDTMF_InputBox_Index > 0)
{
gPttWasReleased = true;
gRequestDisplayScreen = DISPLAY_MAIN;
@@ -294,43 +344,52 @@ void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
#endif
gRequestDisplayScreen = DISPLAY_MAIN;
gDTMF_InputMode = false;
gDTMF_InputMode = false; // turn off DTMF input box if no codes left
}
gPttWasReleased = true;
return;
}
if (Key == KEY_SIDE1)
{
Short = gEeprom.KEY_1_SHORT_PRESS_ACTION;
Long = gEeprom.KEY_1_LONG_PRESS_ACTION;
}
else
if (Key == KEY_SIDE2)
{
Short = gEeprom.KEY_2_SHORT_PRESS_ACTION;
Long = gEeprom.KEY_2_LONG_PRESS_ACTION;
uint8_t funcShort = ACTION_OPT_NONE;
uint8_t funcLong = ACTION_OPT_NONE;
switch(Key) {
case KEY_SIDE1:
funcShort = gEeprom.KEY_1_SHORT_PRESS_ACTION;
funcLong = gEeprom.KEY_1_LONG_PRESS_ACTION;
break;
case KEY_SIDE2:
funcShort = gEeprom.KEY_2_SHORT_PRESS_ACTION;
funcLong = gEeprom.KEY_2_LONG_PRESS_ACTION;
break;
case KEY_MENU:
funcLong = gEeprom.KEY_M_LONG_PRESS_ACTION;
break;
default:
break;
}
if (!bKeyHeld && bKeyPressed)
if (!bKeyHeld && bKeyPressed) // button pushed
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
if (bKeyHeld || bKeyPressed)
// held or released beyond this point
if(!(bKeyHeld && !bKeyPressed)) // don't beep on released after hold
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (bKeyHeld || bKeyPressed) // held
{
if (!bKeyHeld)
return;
funcShort = funcLong;
Short = Long;
if (!bKeyPressed)
if (!bKeyPressed) //ignore release if held
return;
}
switch (Short)
// held or released after short press beyond this point
switch (funcShort)
{
default:
case ACTION_OPT_NONE:
@@ -348,22 +407,41 @@ void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
ACTION_Scan(true);
break;
case ACTION_OPT_VOX:
#ifdef ENABLE_VOX
ACTION_Vox();
#endif
break;
case ACTION_OPT_ALARM:
#ifdef ENABLE_ALARM
ACTION_AlarmOr1750(false);
#endif
#ifdef ENABLE_ALARM
ACTION_AlarmOr1750(false);
#endif
break;
#ifdef ENABLE_FMRADIO
case ACTION_OPT_FM:
ACTION_FM();
break;
#endif
#ifdef ENABLE_FMRADIO
case ACTION_OPT_FM:
ACTION_FM();
break;
#endif
case ACTION_OPT_1750:
#ifdef ENABLE_ALARM
#ifdef ENABLE_TX1750
ACTION_AlarmOr1750(true);
#endif
break;
case ACTION_OPT_KEYLOCK:
COMMON_KeypadLockToggle();
break;
case ACTION_OPT_A_B:
COMMON_SwitchVFOs();
break;
case ACTION_OPT_VFO_MR:
COMMON_SwitchVFOMode();
break;
case ACTION_OPT_SWITCH_DEMODUL:
ACTION_SwitchDemodul();
break;
#ifdef ENABLE_BLMIN_TMP_OFF
case ACTION_OPT_BLMIN_TMP_OFF:
ACTION_BlminTmpOff();
break;
#endif
}
}

View File

@@ -22,14 +22,21 @@
//static void ACTION_FlashLight(void)
void ACTION_Power(void);
void ACTION_Monitor(void);
void ACTION_Scan(bool bFlag);
void ACTION_Vox(void);
void ACTION_Scan(bool bRestart);
#ifdef ENABLE_VOX
void ACTION_Vox(void);
#endif
#ifdef ENABLE_ALARM
//static void ACTION_AlarmOr1750(bool b1750)
#endif
#ifdef ENABLE_FMRADIO
void ACTION_FM(void);
#endif
void ACTION_SwitchDemodul(void);
#ifdef ENABLE_BLMIN_TMP_OFF
void ACTION_BlminTmpOff(void);
#endif
void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);

View File

@@ -57,7 +57,7 @@ void AIRCOPY_SendMessage(void)
BK4819_SendFSKData(g_FSK_Buffer);
BK4819_SetupPowerAmplifier(0, 0);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, false);
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
gAircopySendCountdown = 30;
}
@@ -131,19 +131,17 @@ static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
}
gInputBoxIndex = 0;
Frequency = StrToUL(INPUTBOX_GetAscii()) * 100;
NUMBER_Get(gInputBox, &Frequency);
for (i = 0; i < 7; i++)
for (i = 0; i < ARRAY_SIZE(frequencyBandTable); i++)
{
if (Frequency >= LowerLimitFrequencyBandTable[i] && Frequency <= UpperLimitFrequencyBandTable[i])
if (Frequency >= frequencyBandTable[i].lower && Frequency < frequencyBandTable[i].upper)
{
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gRxVfo->Band = i;
Frequency += 75;
Frequency = FREQUENCY_FloorToStep(Frequency, gRxVfo->StepFrequency, 0);
Frequency = FREQUENCY_RoundToStep(Frequency, gRxVfo->StepFrequency);
gRxVfo->freq_config_RX.Frequency = Frequency;
gRxVfo->freq_config_TX.Frequency = Frequency;
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);

2055
app/app.c

File diff suppressed because it is too large Load Diff

View File

@@ -20,12 +20,13 @@
#include <stdbool.h>
#include "functions.h"
#include "frequencies.h"
#include "radio.h"
void APP_EndTransmission(void);
void CHANNEL_Next(bool bFlag, int8_t Direction);
void APP_StartListening(FUNCTION_Type_t Function, const bool reset_am_fix);
uint32_t APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t Step);
uint32_t APP_SetFreqByStepAndLimits(VFO_Info_t *pInfo, int8_t direction, uint32_t lower, uint32_t upper);
uint32_t APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t direction);
void APP_Update(void);
void APP_TimeSlice10ms(void);
void APP_TimeSlice500ms(void);

274
app/chFrScanner.c Normal file
View File

@@ -0,0 +1,274 @@
#include "app/app.h"
#include "app/chFrScanner.h"
#include "functions.h"
#include "misc.h"
#include "settings.h"
int8_t gScanStateDir;
bool gScanKeepResult;
bool gScanPauseMode;
#ifdef ENABLE_SCAN_RANGES
uint32_t gScanRangeStart;
#endif
typedef enum {
SCAN_NEXT_CHAN_SCANLIST1 = 0,
SCAN_NEXT_CHAN_SCANLIST2,
SCAN_NEXT_CHAN_DUAL_WATCH,
SCAN_NEXT_CHAN_MR,
SCAN_NEXT_NUM
} scan_next_chan_t;
scan_next_chan_t currentScanList;
uint32_t initialFrqOrChan;
uint8_t initialCROSS_BAND_RX_TX;
uint32_t lastFoundFrqOrChan;
static void NextFreqChannel(void);
static void NextMemChannel(void);
void CHFRSCANNER_Start(const bool storeBackupSettings, const int8_t scan_direction)
{
if (storeBackupSettings) {
initialCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gScanKeepResult = false;
}
RADIO_SelectVfos();
gNextMrChannel = gRxVfo->CHANNEL_SAVE;
currentScanList = SCAN_NEXT_CHAN_SCANLIST1;
gScanStateDir = scan_direction;
if (IS_MR_CHANNEL(gNextMrChannel))
{ // channel mode
if (storeBackupSettings) {
initialFrqOrChan = gRxVfo->CHANNEL_SAVE;
lastFoundFrqOrChan = initialFrqOrChan;
}
NextMemChannel();
}
else
{ // frequency mode
if (storeBackupSettings) {
initialFrqOrChan = gRxVfo->freq_config_RX.Frequency;
lastFoundFrqOrChan = initialFrqOrChan;
}
NextFreqChannel();
}
gScanPauseDelayIn_10ms = scan_pause_delay_in_2_10ms;
gScheduleScanListen = false;
gRxReceptionMode = RX_MODE_NONE;
gScanPauseMode = false;
}
void CHFRSCANNER_ContinueScanning(void)
{
if (IS_FREQ_CHANNEL(gNextMrChannel))
{
if (gCurrentFunction == FUNCTION_INCOMING)
APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE, true);
else
NextFreqChannel(); // switch to next frequency
}
else
{
if (gCurrentCodeType == CODE_TYPE_OFF && gCurrentFunction == FUNCTION_INCOMING)
APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE, true);
else
NextMemChannel(); // switch to next channel
}
gScanPauseMode = false;
gRxReceptionMode = RX_MODE_NONE;
gScheduleScanListen = false;
}
void CHFRSCANNER_Found(void)
{
switch (gEeprom.SCAN_RESUME_MODE)
{
case SCAN_RESUME_TO:
if (!gScanPauseMode)
{
gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms;
gScheduleScanListen = false;
gScanPauseMode = true;
}
break;
case SCAN_RESUME_CO:
case SCAN_RESUME_SE:
gScanPauseDelayIn_10ms = 0;
gScheduleScanListen = false;
break;
}
if (IS_MR_CHANNEL(gRxVfo->CHANNEL_SAVE)) { //memory scan
lastFoundFrqOrChan = gRxVfo->CHANNEL_SAVE;
}
else { // frequency scan
lastFoundFrqOrChan = gRxVfo->freq_config_RX.Frequency;
}
gScanKeepResult = true;
}
void CHFRSCANNER_Stop(void)
{
if(initialCROSS_BAND_RX_TX != CROSS_BAND_OFF) {
gEeprom.CROSS_BAND_RX_TX = initialCROSS_BAND_RX_TX;
initialCROSS_BAND_RX_TX = CROSS_BAND_OFF;
}
gScanStateDir = SCAN_OFF;
const uint32_t chFr = gScanKeepResult ? lastFoundFrqOrChan : initialFrqOrChan;
const bool channelChanged = chFr != initialFrqOrChan;
if (IS_MR_CHANNEL(gNextMrChannel)) {
gEeprom.MrChannel[gEeprom.RX_VFO] = chFr;
gEeprom.ScreenChannel[gEeprom.RX_VFO] = chFr;
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
if(channelChanged) {
SETTINGS_SaveVfoIndices();
gUpdateStatus = true;
}
}
else {
gRxVfo->freq_config_RX.Frequency = chFr;
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
if(channelChanged) {
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_VFO, gRxVfo, 1);
}
}
RADIO_SetupRegisters(true);
gUpdateDisplay = true;
}
static void NextFreqChannel(void)
{
#ifdef ENABLE_SCAN_RANGES
if(gScanRangeStart) {
uint32_t start = gScanRangeStart;
uint32_t end = gEeprom.VfoInfo[(gEeprom.TX_VFO+1)%2].freq_config_RX.Frequency;
gRxVfo->freq_config_RX.Frequency = APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, MIN(start, end), MAX(start, end));
}
else
#endif
gRxVfo->freq_config_RX.Frequency = APP_SetFrequencyByStep(gRxVfo, gScanStateDir);
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
RADIO_SetupRegisters(true);
#ifdef ENABLE_FASTER_CHANNEL_SCAN
gScanPauseDelayIn_10ms = 9; // 90ms
#else
gScanPauseDelayIn_10ms = scan_pause_delay_in_6_10ms;
#endif
gUpdateDisplay = true;
}
static void NextMemChannel(void)
{
static unsigned int prev_mr_chan = 0;
const bool enabled = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCAN_LIST_ENABLED[gEeprom.SCAN_LIST_DEFAULT] : true;
const int chan1 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH1[gEeprom.SCAN_LIST_DEFAULT] : -1;
const int chan2 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH2[gEeprom.SCAN_LIST_DEFAULT] : -1;
const unsigned int prev_chan = gNextMrChannel;
unsigned int chan = 0;
if (enabled)
{
switch (currentScanList)
{
case SCAN_NEXT_CHAN_SCANLIST1:
prev_mr_chan = gNextMrChannel;
if (chan1 >= 0)
{
if (RADIO_CheckValidChannel(chan1, false, 0))
{
currentScanList = SCAN_NEXT_CHAN_SCANLIST1;
gNextMrChannel = chan1;
break;
}
}
[[fallthrough]];
case SCAN_NEXT_CHAN_SCANLIST2:
if (chan2 >= 0)
{
if (RADIO_CheckValidChannel(chan2, false, 0))
{
currentScanList = SCAN_NEXT_CHAN_SCANLIST2;
gNextMrChannel = chan2;
break;
}
}
[[fallthrough]];
// this bit doesn't yet work if the other VFO is a frequency
case SCAN_NEXT_CHAN_DUAL_WATCH:
// dual watch is enabled - include the other VFO in the scan
// if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
// {
// chan = (gEeprom.RX_VFO + 1) & 1u;
// chan = gEeprom.ScreenChannel[chan];
// if (IS_MR_CHANNEL(chan))
// {
// currentScanList = SCAN_NEXT_CHAN_DUAL_WATCH;
// gNextMrChannel = chan;
// break;
// }
// }
default:
case SCAN_NEXT_CHAN_MR:
currentScanList = SCAN_NEXT_CHAN_MR;
gNextMrChannel = prev_mr_chan;
chan = 0xff;
break;
}
}
if (!enabled || chan == 0xff)
{
chan = RADIO_FindNextChannel(gNextMrChannel + gScanStateDir, gScanStateDir, (gEeprom.SCAN_LIST_DEFAULT < 2) ? true : false, gEeprom.SCAN_LIST_DEFAULT);
if (chan == 0xFF)
{ // no valid channel found
chan = MR_CHANNEL_FIRST;
}
gNextMrChannel = chan;
}
if (gNextMrChannel != prev_chan)
{
gEeprom.MrChannel[ gEeprom.RX_VFO] = gNextMrChannel;
gEeprom.ScreenChannel[gEeprom.RX_VFO] = gNextMrChannel;
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
RADIO_SetupRegisters(true);
gUpdateDisplay = true;
}
#ifdef ENABLE_FASTER_CHANNEL_SCAN
gScanPauseDelayIn_10ms = 9; // 90ms .. <= ~60ms it misses signals (squelch response and/or PLL lock time) ?
#else
gScanPauseDelayIn_10ms = scan_pause_delay_in_3_10ms;
#endif
if (enabled)
if (++currentScanList >= SCAN_NEXT_NUM)
currentScanList = SCAN_NEXT_CHAN_SCANLIST1; // back round we go
}

22
app/chFrScanner.h Normal file
View File

@@ -0,0 +1,22 @@
#ifndef APP_CHFRSCANNER_H
#define APP_CHFRSCANNER_H
#include <stdbool.h>
#include <stdint.h>
// scan direction, if not equal SCAN_OFF indicates
// that we are in a process of scanning channels/frequencies
extern int8_t gScanStateDir;
extern bool gScanKeepResult;
extern bool gScanPauseMode;
#ifdef ENABLE_SCAN_RANGES
extern uint32_t gScanRangeStart;
#endif
void CHFRSCANNER_Found(void);
void CHFRSCANNER_Stop(void);
void CHFRSCANNER_Start(const bool storeBackupSettings, const int8_t scan_direction);
void CHFRSCANNER_ContinueScanning(void);
#endif

77
app/common.c Normal file
View File

@@ -0,0 +1,77 @@
#include "app/chFrScanner.h"
#include "audio.h"
#include "functions.h"
#include "misc.h"
#include "settings.h"
#include "ui/ui.h"
void COMMON_KeypadLockToggle()
{
if (gScreenToDisplay != DISPLAY_MENU &&
gCurrentFunction != FUNCTION_TRANSMIT)
{ // toggle the keyboad lock
#ifdef ENABLE_VOICE
gAnotherVoiceID = gEeprom.KEY_LOCK ? VOICE_ID_UNLOCK : VOICE_ID_LOCK;
#endif
gEeprom.KEY_LOCK = !gEeprom.KEY_LOCK;
gRequestSaveSettings = true;
}
}
void COMMON_SwitchVFOs()
{
#ifdef ENABLE_SCAN_RANGES
gScanRangeStart = 0;
#endif
gEeprom.TX_VFO ^= 1;
if (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF)
gEeprom.CROSS_BAND_RX_TX = gEeprom.TX_VFO + 1;
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
gEeprom.DUAL_WATCH = gEeprom.TX_VFO + 1;
gRequestSaveSettings = 1;
gFlagReconfigureVfos = true;
gScheduleDualWatch = true;
gRequestDisplayScreen = DISPLAY_MAIN;
}
void COMMON_SwitchVFOMode()
{
#ifdef ENABLE_NOAA
if (gEeprom.VFO_OPEN && !IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
#else
if (gEeprom.VFO_OPEN)
#endif
{
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // swap to frequency mode
gEeprom.ScreenChannel[gEeprom.TX_VFO] = gEeprom.FreqChannel[gEeprom.TX_VFO];
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
return;
}
uint8_t Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 0);
if (Channel != 0xFF)
{ // swap to channel mode
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel;
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
AUDIO_SetDigitVoice(1, Channel + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
return;
}
}
}

13
app/common.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef APP_COMMON_H
#define APP_COMMON_H
#include "functions.h"
#include "settings.h"
#include "ui/ui.h"
void COMMON_KeypadLockToggle();
void COMMON_SwitchVFOs();
void COMMON_SwitchVFOMode();
#endif

View File

@@ -17,11 +17,13 @@
#include <string.h>
#include <stdio.h> // NULL
#include "app/chFrScanner.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif
#include "app/scanner.h"
#include "bsp/dp32g030/gpio.h"
#include "audio.h"
#include "driver/bk4819.h"
#include "driver/eeprom.h"
#include "driver/gpio.h"
@@ -33,42 +35,57 @@
#include "ui/ui.h"
char gDTMF_String[15];
char gDTMF_InputBox[15];
char gDTMF_Received[16];
uint8_t gDTMF_WriteIndex = 0;
uint8_t gDTMF_PreviousIndex = 0;
uint8_t gDTMF_RecvTimeout = 0;
char gDTMF_InputBox[15];
uint8_t gDTMF_InputBox_Index = 0;
bool gDTMF_InputMode = false;
uint8_t gDTMF_PreviousIndex = 0;
char gDTMF_RX_live[20];
uint8_t gDTMF_RX_live_timeout = 0;
#ifdef ENABLE_DTMF_CALLING
char gDTMF_RX[17];
uint8_t gDTMF_RX_index = 0;
uint8_t gDTMF_RX_timeout = 0;
bool gDTMF_RX_pending = false;
bool gIsDtmfContactValid;
char gDTMF_ID[4];
char gDTMF_Caller[4];
char gDTMF_Callee[4];
DTMF_State_t gDTMF_State;
bool gDTMF_DecodeRing;
uint8_t gDTMF_DecodeRingCountdown_500ms;
uint8_t gDTMFChosenContact;
uint8_t gDTMF_AUTO_RESET_TIME;
uint8_t gDTMF_InputIndex;
bool gDTMF_InputMode;
uint8_t gDTMF_chosen_contact;
uint8_t gDTMF_auto_reset_time_500ms;
DTMF_CallState_t gDTMF_CallState;
DTMF_ReplyState_t gDTMF_ReplyState;
DTMF_CallMode_t gDTMF_CallMode;
bool gDTMF_IsTx;
uint8_t gDTMF_TxStopCountdown_500ms;
bool gDTMF_IsGroupCall;
#endif
DTMF_ReplyState_t gDTMF_ReplyState;
bool DTMF_ValidateCodes(char *pCode, uint8_t Size)
#ifdef ENABLE_DTMF_CALLING
void DTMF_clear_RX(void)
{
gDTMF_RX_timeout = 0;
gDTMF_RX_index = 0;
gDTMF_RX_pending = false;
memset(gDTMF_RX, 0, sizeof(gDTMF_RX));
}
#endif
bool DTMF_ValidateCodes(char *pCode, const unsigned int size)
{
unsigned int i;
if (pCode[0] == 0xFF || pCode[0] == 0)
return false;
for (i = 0; i < Size; i++)
for (i = 0; i < size; i++)
{
if (pCode[i] == 0xFF || pCode[i] == 0)
{
@@ -83,6 +100,7 @@ bool DTMF_ValidateCodes(char *pCode, uint8_t Size)
return true;
}
#ifdef ENABLE_DTMF_CALLING
bool DTMF_GetContact(const int Index, char *pContact)
{
int i = -1;
@@ -121,16 +139,36 @@ bool DTMF_FindContact(const char *pContact, char *pResult)
return false;
}
char DTMF_GetCharacter(const uint8_t code)
{
const char list[] = "0123456789ABCD*#";
return (code < ARRAY_SIZE(list)) ? list[code] : 0xFF;
}
#endif
bool DTMF_CompareMessage(const char *pMsg, const char *pTemplate, uint8_t Size, bool bCheckGroup)
char DTMF_GetCharacter(const unsigned int code)
{
switch (code)
{
case KEY_0: return '0';
case KEY_1: return '1';
case KEY_2: return '2';
case KEY_3: return '3';
case KEY_4: return '4';
case KEY_5: return '5';
case KEY_6: return '6';
case KEY_7: return '7';
case KEY_8: return '8';
case KEY_9: return '9';
case KEY_MENU: return 'A';
case KEY_UP: return 'B';
case KEY_DOWN: return 'C';
case KEY_EXIT: return 'D';
case KEY_STAR: return '*';
case KEY_F: return '#';
default: return 0xff;
}
}
#ifdef ENABLE_DTMF_CALLING
static bool CompareMessage(const char *pMsg, const char *pTemplate, const unsigned int size, const bool bCheckGroup)
{
unsigned int i;
for (i = 0; i < Size; i++)
for (i = 0; i < size; i++)
{
if (pMsg[i] != pTemplate[i])
{
@@ -140,58 +178,78 @@ bool DTMF_CompareMessage(const char *pMsg, const char *pTemplate, uint8_t Size,
}
}
return DTMF_CALL_MODE_NOT_GROUP;
return true;
}
DTMF_CallMode_t DTMF_CheckGroupCall(const char *pMsg, uint32_t Size)
DTMF_CallMode_t DTMF_CheckGroupCall(const char *pMsg, const unsigned int size)
{
uint32_t i;
for (i = 0; i < Size; i++)
unsigned int i;
for (i = 0; i < size; i++)
if (pMsg[i] == gEeprom.DTMF_GROUP_CALL_CODE)
break;
return (i != Size) ? DTMF_CALL_MODE_GROUP : DTMF_CALL_MODE_NOT_GROUP;
return (i < size) ? DTMF_CALL_MODE_GROUP : DTMF_CALL_MODE_NOT_GROUP;
}
#endif
void DTMF_clear_input_box(void)
{
memset(gDTMF_InputBox, 0, sizeof(gDTMF_InputBox));
gDTMF_InputBox_Index = 0;
gDTMF_InputMode = false;
}
void DTMF_Append(char Code)
void DTMF_Append(const char code)
{
if (gDTMF_InputIndex == 0)
if (gDTMF_InputBox_Index == 0)
{
memset(gDTMF_InputBox, '-', sizeof(gDTMF_InputBox));
memset(gDTMF_InputBox, '-', sizeof(gDTMF_InputBox) - 1);
gDTMF_InputBox[sizeof(gDTMF_InputBox) - 1] = 0;
}
else
if (gDTMF_InputIndex >= sizeof(gDTMF_InputBox))
return;
gDTMF_InputBox[gDTMF_InputIndex++] = Code;
if (gDTMF_InputBox_Index < (sizeof(gDTMF_InputBox) - 1))
gDTMF_InputBox[gDTMF_InputBox_Index++] = code;
}
#ifdef ENABLE_DTMF_CALLING
void DTMF_HandleRequest(void)
{
char String[20];
uint8_t Offset;
{ // proccess the RX'ed DTMF characters
if (!gDTMF_RequestPending)
return;
gDTMF_RequestPending = false;
if (gScanState != SCAN_OFF || gCssScanMode != CSS_SCAN_MODE_OFF)
char String[21];
unsigned int Offset;
if (!gDTMF_RX_pending)
return; // nothing new received
if (gScanStateDir != SCAN_OFF || gCssBackgroundScan)
{ // we're busy scanning
DTMF_clear_RX();
return;
}
if (!gRxVfo->DTMF_DECODING_ENABLE && !gSetting_KILLED)
{ // D-DCD is disabled or we're alive
DTMF_clear_RX();
return;
}
gDTMF_RX_pending = false;
if (gDTMF_RX_index >= 9)
{ // look for the KILL code
if (gDTMF_WriteIndex >= 9)
{
Offset = gDTMF_WriteIndex - 9;
sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, gEeprom.KILL_CODE);
if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 9, true))
{
Offset = gDTMF_RX_index - strlen(String);
if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
{ // bugger
if (gEeprom.PERMIT_REMOTE_KILL)
{
gSetting_KILLED = true;
gSetting_KILLED = true; // oooerr !
DTMF_clear_RX();
SETTINGS_SaveSettings();
@@ -212,82 +270,118 @@ void DTMF_HandleRequest(void)
gDTMF_CallState = DTMF_CALL_STATE_NONE;
gUpdateDisplay = true;
gUpdateStatus = true;
gUpdateDisplay = true;
gUpdateStatus = true;
return;
}
}
if (gDTMF_RX_index >= 9)
{ // look for the REVIVE code
sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, gEeprom.REVIVE_CODE);
if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 9, true))
{
Offset = gDTMF_RX_index - strlen(String);
if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
{ // shit, we're back !
gSetting_KILLED = false;
DTMF_clear_RX();
SETTINGS_SaveSettings();
gDTMF_ReplyState = DTMF_REPLY_AB;
gDTMF_CallState = DTMF_CALL_STATE_NONE;
gUpdateDisplay = true;
gUpdateStatus = true;
return;
}
}
if (gDTMF_WriteIndex >= 2)
{
if (DTMF_CompareMessage(gDTMF_Received + (gDTMF_WriteIndex - 2), "AB", 2, true))
{
gDTMF_State = DTMF_STATE_TX_SUCC;
gUpdateDisplay = true;
return;
if (gDTMF_RX_index >= 2)
{ // look for ACK reply
strcpy(String, "AB");
Offset = gDTMF_RX_index - strlen(String);
if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
{ // ends with "AB"
if (gDTMF_ReplyState != DTMF_REPLY_NONE) // 1of11
// if (gDTMF_CallState != DTMF_CALL_STATE_NONE) // 1of11
// if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT) // 1of11
{
gDTMF_State = DTMF_STATE_TX_SUCC;
DTMF_clear_RX();
gUpdateDisplay = true;
return;
}
}
}
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT && gDTMF_CallMode == DTMF_CALL_MODE_NOT_GROUP && gDTMF_WriteIndex >= 9)
{
Offset = gDTMF_WriteIndex - 9;
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT &&
gDTMF_CallMode == DTMF_CALL_MODE_NOT_GROUP &&
gDTMF_RX_index >= 9)
{ // waiting for a reply
sprintf(String, "%s%c%s", gDTMF_String, gEeprom.DTMF_SEPARATE_CODE, "AAAAA");
if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 9, false))
{
Offset = gDTMF_RX_index - strlen(String);
if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), false))
{ // we got a response
gDTMF_State = DTMF_STATE_CALL_OUT_RSP;
DTMF_clear_RX();
gUpdateDisplay = true;
}
}
if (gSetting_KILLED || gDTMF_CallState != DTMF_CALL_STATE_NONE)
{ // we've been killed or expecting a reply
return;
}
if (gDTMF_WriteIndex >= 7)
{
Offset = gDTMF_WriteIndex - 7;
sprintf(String, "%s%c", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE);
if (gDTMF_RX_index >= 7)
{ // see if we're being called
gDTMF_IsGroupCall = false;
if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 4, true))
{
sprintf(String, "%s%c", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE);
Offset = gDTMF_RX_index - strlen(String) - 3;
if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
{ // it's for us !
gDTMF_CallState = DTMF_CALL_STATE_RECEIVED;
memmove(gDTMF_Callee, gDTMF_Received + Offset + 0, 3);
memmove(gDTMF_Caller, gDTMF_Received + Offset + 4, 3);
memset(gDTMF_Callee, 0, sizeof(gDTMF_Callee));
memset(gDTMF_Caller, 0, sizeof(gDTMF_Caller));
memmove(gDTMF_Callee, gDTMF_RX + Offset + 0, 3);
memmove(gDTMF_Caller, gDTMF_RX + Offset + 4, 3);
DTMF_clear_RX();
gUpdateDisplay = true;
switch (gEeprom.DTMF_DECODE_RESPONSE)
{
case 3:
gDTMF_DecodeRing = true;
case DTMF_DEC_RESPONSE_BOTH:
gDTMF_DecodeRingCountdown_500ms = DTMF_decode_ring_countdown_500ms;
// Fallthrough
case 2:
[[fallthrough]];
case DTMF_DEC_RESPONSE_REPLY:
gDTMF_ReplyState = DTMF_REPLY_AAAAA;
break;
case 1:
gDTMF_DecodeRing = true;
case DTMF_DEC_RESPONSE_RING:
gDTMF_DecodeRingCountdown_500ms = DTMF_decode_ring_countdown_500ms;
break;
default:
gDTMF_DecodeRing = false;
case DTMF_DEC_RESPONSE_NONE:
gDTMF_DecodeRingCountdown_500ms = 0;
gDTMF_ReplyState = DTMF_REPLY_NONE;
break;
}
@@ -297,45 +391,57 @@ void DTMF_HandleRequest(void)
}
}
}
#endif
void DTMF_Reply(void)
{
uint16_t Delay;
char String[20];
#ifdef ENABLE_DTMF_CALLING
char String[23];
#endif
const char *pString = NULL;
switch (gDTMF_ReplyState)
{
case DTMF_REPLY_NONE:
return;
case DTMF_REPLY_ANI:
if (gDTMF_CallMode == DTMF_CALL_MODE_DTMF)
{
pString = gDTMF_String;
}
else
#ifdef ENABLE_DTMF_CALLING
if (gDTMF_CallMode != DTMF_CALL_MODE_DTMF)
{ // append our ID code onto the end of the DTMF code to send
sprintf(String, "%s%c%s", gDTMF_String, gEeprom.DTMF_SEPARATE_CODE, gEeprom.ANI_DTMF_ID);
pString = String;
}
else
#endif
{
pString = gDTMF_String;
}
break;
#ifdef ENABLE_DTMF_CALLING
case DTMF_REPLY_AB:
pString = "AB";
break;
case DTMF_REPLY_AAAAA:
sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, "AAAAA");
pString = String;
break;
#endif
default:
if (gDTMF_CallState != DTMF_CALL_STATE_NONE || (gCurrentVfo->DTMF_PTT_ID_TX_MODE != PTT_ID_BOT && gCurrentVfo->DTMF_PTT_ID_TX_MODE != PTT_ID_BOTH))
case DTMF_REPLY_NONE:
if (
#ifdef ENABLE_DTMF_CALLING
gDTMF_CallState != DTMF_CALL_STATE_NONE ||
#endif
gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO ||
gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_OFF ||
gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_TX_DOWN)
{
gDTMF_ReplyState = DTMF_REPLY_NONE;
return;
}
// send TX-UP DTMF
pString = gEeprom.DTMF_UP_CODE;
break;
}
@@ -344,14 +450,15 @@ void DTMF_Reply(void)
if (pString == NULL)
return;
Delay = gEeprom.DTMF_PRELOAD_TIME;
Delay = (gEeprom.DTMF_PRELOAD_TIME < 200) ? 200 : gEeprom.DTMF_PRELOAD_TIME;
if (gEeprom.DTMF_SIDE_TONE)
{
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
{ // the user will also hear the transmitted tones
AUDIO_AudioPathOn();
gEnableSpeaker = true;
Delay = (gEeprom.DTMF_PRELOAD_TIME < 60) ? 60 : gEeprom.DTMF_PRELOAD_TIME;
}
SYSTEM_DelayMs(Delay);
BK4819_EnterDTMF_TX(gEeprom.DTMF_SIDE_TONE);
@@ -364,7 +471,7 @@ void DTMF_Reply(void)
gEeprom.DTMF_CODE_PERSIST_TIME,
gEeprom.DTMF_CODE_INTERVAL_TIME);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
gEnableSpeaker = false;

View File

@@ -33,7 +33,15 @@ typedef enum DTMF_State_t DTMF_State_t;
enum DTMF_CallState_t {
DTMF_CALL_STATE_NONE = 0,
DTMF_CALL_STATE_CALL_OUT,
DTMF_CALL_STATE_RECEIVED
DTMF_CALL_STATE_RECEIVED,
DTMF_CALL_STATE_RECEIVED_STAY
};
enum DTMF_DecodeResponse_t {
DTMF_DEC_RESPONSE_NONE = 0,
DTMF_DEC_RESPONSE_RING,
DTMF_DEC_RESPONSE_REPLY,
DTMF_DEC_RESPONSE_BOTH
};
typedef enum DTMF_CallState_t DTMF_CallState_t;
@@ -53,44 +61,57 @@ enum DTMF_CallMode_t {
DTMF_CALL_MODE_DTMF
};
enum { // seconds
DTMF_HOLD_MIN = 5,
DTMF_HOLD_MAX = 60
};
typedef enum DTMF_CallMode_t DTMF_CallMode_t;
extern char gDTMF_String[15];
extern char gDTMF_InputBox[15];
extern char gDTMF_Received[16];
extern uint8_t gDTMF_WriteIndex;
extern char gDTMF_InputBox[15];
extern uint8_t gDTMF_InputBox_Index;
extern bool gDTMF_InputMode;
extern uint8_t gDTMF_PreviousIndex;
extern uint8_t gDTMF_RecvTimeout;
extern char gDTMF_RX_live[20];
extern uint8_t gDTMF_RX_live_timeout;
#ifdef ENABLE_DTMF_CALLING
extern char gDTMF_RX[17];
extern uint8_t gDTMF_RX_index;
extern uint8_t gDTMF_RX_timeout;
extern bool gDTMF_RX_pending;
extern bool gIsDtmfContactValid;
extern char gDTMF_ID[4];
extern char gDTMF_Caller[4];
extern char gDTMF_Callee[4];
extern DTMF_State_t gDTMF_State;
extern bool gDTMF_DecodeRing;
extern uint8_t gDTMF_DecodeRingCountdown_500ms;
extern uint8_t gDTMFChosenContact;
extern uint8_t gDTMF_AUTO_RESET_TIME;
extern uint8_t gDTMF_InputIndex;
extern bool gDTMF_InputMode;
extern uint8_t gDTMF_chosen_contact;
extern uint8_t gDTMF_auto_reset_time_500ms;
extern DTMF_CallState_t gDTMF_CallState;
extern DTMF_ReplyState_t gDTMF_ReplyState;
extern DTMF_CallMode_t gDTMF_CallMode;
extern bool gDTMF_IsTx;
extern uint8_t gDTMF_TxStopCountdown_500ms;
#endif
extern DTMF_ReplyState_t gDTMF_ReplyState;
bool DTMF_ValidateCodes(char *pCode, uint8_t Size);
bool DTMF_GetContact(const int Index, char *pContact);
bool DTMF_FindContact(const char *pContact, char *pResult);
char DTMF_GetCharacter(const uint8_t code);
bool DTMF_CompareMessage(const char *pDTMF, const char *pTemplate, uint8_t Size, bool bFlag);
DTMF_CallMode_t DTMF_CheckGroupCall(const char *pDTMF, uint32_t Size);
void DTMF_Append(char Code);
void DTMF_HandleRequest(void);
bool DTMF_ValidateCodes(char *pCode, const unsigned int size);
char DTMF_GetCharacter(const unsigned int code);
void DTMF_clear_input_box(void);
void DTMF_Append(const char vode);
void DTMF_Reply(void);
#ifdef ENABLE_DTMF_CALLING
void DTMF_clear_RX(void);
DTMF_CallMode_t DTMF_CheckGroupCall(const char *pDTMF, const unsigned int size);
bool DTMF_GetContact(const int Index, char *pContact);
bool DTMF_FindContact(const char *pContact, char *pResult);
void DTMF_HandleRequest(void);
#endif
#endif

195
app/fm.c
View File

@@ -45,9 +45,21 @@ bool gFM_AutoScan;
uint8_t gFM_ChannelPosition;
bool gFM_FoundFrequency;
bool gFM_AutoScan;
uint8_t gFM_ResumeCountdown_500ms;
uint16_t gFM_RestoreCountdown_10ms;
const uint8_t BUTTON_STATE_PRESSED = 1 << 0;
const uint8_t BUTTON_STATE_HELD = 1 << 1;
const uint8_t BUTTON_EVENT_PRESSED = BUTTON_STATE_PRESSED;
const uint8_t BUTTON_EVENT_HELD = BUTTON_STATE_PRESSED | BUTTON_STATE_HELD;
const uint8_t BUTTON_EVENT_SHORT = 0;
const uint8_t BUTTON_EVENT_LONG = BUTTON_STATE_HELD;
static void Key_FUNC(KEY_Code_t Key, uint8_t state);
bool FM_CheckValidChannel(uint8_t Channel)
{
return (Channel < ARRAY_SIZE(gFM_Channels) && (gFM_Channels[Channel] >= 760 && gFM_Channels[Channel] < 1080)) ? true : false;
@@ -97,7 +109,7 @@ void FM_TurnOff(void)
gFM_ScanState = FM_SCAN_OFF;
gFM_RestoreCountdown_10ms = 0;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
gEnableSpeaker = false;
@@ -120,7 +132,7 @@ void FM_EraseChannels(void)
void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag)
{
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
gEnableSpeaker = false;
@@ -167,7 +179,7 @@ void FM_PlayAndUpdate(void)
gScheduleFM = false;
gAskToSave = false;
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
gEnableSpeaker = true;
}
@@ -224,32 +236,23 @@ Bail:
return ret;
}
static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
static void Key_DIGITS(KEY_Code_t Key, uint8_t state)
{
#define STATE_FREQ_MODE 0
#define STATE_MR_MODE 1
#define STATE_SAVE 2
enum { STATE_FREQ_MODE, STATE_MR_MODE, STATE_SAVE };
if (!bKeyHeld && bKeyPressed)
{
if (!gWasFKeyPressed)
{
if (state == BUTTON_EVENT_SHORT && !gWasFKeyPressed) {
uint8_t State;
if (gAskToDelete)
{
if (gAskToDelete) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gAskToSave)
{
if (gAskToSave) {
State = STATE_SAVE;
}
else
{
if (gFM_ScanState != FM_SCAN_OFF)
{
else {
if (gFM_ScanState != FM_SCAN_OFF) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
@@ -261,60 +264,47 @@ static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gRequestDisplayScreen = DISPLAY_FM;
if (State == STATE_FREQ_MODE)
{
if (gInputBoxIndex == 1)
{
if (gInputBox[0] > 1)
{
if (State == STATE_FREQ_MODE) {
if (gInputBoxIndex == 1) {
if (gInputBox[0] > 1) {
gInputBox[1] = gInputBox[0];
gInputBox[0] = 0;
gInputBoxIndex = 2;
}
}
else
if (gInputBoxIndex > 3)
{
else if (gInputBoxIndex > 3) {
uint32_t Frequency;
gInputBoxIndex = 0;
NUMBER_Get(gInputBox, &Frequency);
Frequency /= 10000;
Frequency = StrToUL(INPUTBOX_GetAscii());
if (Frequency < gEeprom.FM_LowerLimit || gEeprom.FM_UpperLimit < Frequency)
{
if (Frequency < gEeprom.FM_LowerLimit || gEeprom.FM_UpperLimit < Frequency) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
gRequestDisplayScreen = DISPLAY_FM;
return;
}
gEeprom.FM_SelectedFrequency = (uint16_t)Frequency;
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency;
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
gRequestSaveFM = true;
return;
}
}
else
if (gInputBoxIndex == 2)
{
else if (gInputBoxIndex == 2) {
uint8_t Channel;
gInputBoxIndex = 0;
Channel = ((gInputBox[0] * 10) + gInputBox[1]) - 1;
if (State == STATE_MR_MODE)
{
if (FM_CheckValidChannel(Channel))
{
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
if (State == STATE_MR_MODE) {
if (FM_CheckValidChannel(Channel)) {
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gEeprom.FM_SelectedChannel = Channel;
gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel];
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
@@ -322,12 +312,10 @@ static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
return;
}
}
else
if (Channel < 20)
{
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
else if (Channel < 20) {
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gRequestDisplayScreen = DISPLAY_FM;
gInputBoxIndex = 0;
gFM_ChannelPosition = Channel;
@@ -338,25 +326,31 @@ static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
return;
}
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
}
else
Key_FUNC(Key, state);
}
return;
}
static void Key_FUNC(KEY_Code_t Key, uint8_t state)
{
if (state == BUTTON_EVENT_SHORT || state == BUTTON_EVENT_HELD)
{
bool autoScan = gWasFKeyPressed || (state == BUTTON_EVENT_HELD);
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gWasFKeyPressed = false;
gUpdateStatus = true;
gRequestDisplayScreen = DISPLAY_FM;
switch (Key)
{
switch (Key) {
case KEY_0:
ACTION_FM();
break;
case KEY_1:
case KEY_3:
gEeprom.FM_IsMrMode = !gEeprom.FM_IsMrMode;
if (!FM_ConfigureChannelState())
@@ -368,12 +362,8 @@ static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
break;
case KEY_2:
ACTION_Scan(true);
break;
case KEY_3:
ACTION_Scan(false);
case KEY_STAR:
ACTION_Scan(autoScan);
break;
default:
@@ -383,12 +373,9 @@ static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
}
}
static void FM_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
static void Key_EXIT(uint8_t state)
{
if (bKeyHeld)
return;
if (!bKeyPressed)
if (state != BUTTON_EVENT_SHORT)
return;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
@@ -443,13 +430,11 @@ static void FM_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
gRequestDisplayScreen = DISPLAY_FM;
}
static void FM_Key_MENU(bool bKeyPressed, bool bKeyHeld)
static void Key_MENU(uint8_t state)
{
if (bKeyHeld)
if (state != BUTTON_EVENT_SHORT)
return;
if (!bKeyPressed)
return;
gRequestDisplayScreen = DISPLAY_FM;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
@@ -503,38 +488,29 @@ static void FM_Key_MENU(bool bKeyPressed, bool bKeyHeld)
}
}
static void FM_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Step)
static void Key_UP_DOWN(uint8_t state, int8_t Step)
{
if (bKeyHeld || !bKeyPressed)
{
if (gInputBoxIndex)
return;
if (!bKeyPressed)
return;
}
else
{
if (gInputBoxIndex)
{
if (state == BUTTON_EVENT_PRESSED) {
if (gInputBoxIndex) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
}
else {
if (gInputBoxIndex || state!=BUTTON_EVENT_HELD)
return;
}
if (gAskToSave)
{
if (gAskToSave) {
gRequestDisplayScreen = DISPLAY_FM;
gFM_ChannelPosition = NUMBER_AddWithWraparound(gFM_ChannelPosition, Step, 0, 19);
return;
}
if (gFM_ScanState != FM_SCAN_OFF)
{
if (gFM_AutoScan)
{
if (gFM_ScanState != FM_SCAN_OFF) {
if (gFM_AutoScan) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
@@ -544,8 +520,7 @@ static void FM_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Step)
return;
}
if (gEeprom.FM_IsMrMode)
{
if (gEeprom.FM_IsMrMode) {
const uint8_t Channel = FM_FindNextChannel(gEeprom.FM_SelectedChannel + Step, Step);
if (Channel == 0xFF || gEeprom.FM_SelectedChannel == Channel)
goto Bail;
@@ -553,8 +528,7 @@ static void FM_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Step)
gEeprom.FM_SelectedChannel = Channel;
gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel];
}
else
{
else {
uint16_t Frequency = gEeprom.FM_SelectedFrequency + Step;
if (Frequency < gEeprom.FM_LowerLimit)
Frequency = gEeprom.FM_UpperLimit;
@@ -576,6 +550,10 @@ Bail:
void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
uint8_t state = bKeyPressed + 2 * bKeyHeld;
switch (Key)
{
case KEY_0:
@@ -588,19 +566,22 @@ void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
case KEY_7:
case KEY_8:
case KEY_9:
FM_Key_DIGITS(Key, bKeyPressed, bKeyHeld);
Key_DIGITS(Key, state);
break;
case KEY_STAR:
Key_FUNC(Key, state);
break;
case KEY_MENU:
FM_Key_MENU(bKeyPressed, bKeyHeld);
Key_MENU(state);
return;
case KEY_UP:
FM_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1);
Key_UP_DOWN(state, 1);
break;
case KEY_DOWN:
FM_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1);
Key_UP_DOWN(state, -1);
break;;
case KEY_EXIT:
FM_Key_EXIT(bKeyPressed, bKeyHeld);
Key_EXIT(state);
break;
case KEY_F:
GENERIC_Key_F(bKeyPressed, bKeyHeld);
@@ -627,7 +608,7 @@ void FM_Play(void)
if (!gEeprom.FM_IsMrMode)
gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying;
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
gEnableSpeaker = true;
GUI_SelectNextDisplay(DISPLAY_FM);
@@ -661,7 +642,7 @@ void FM_Start(void)
BK1080_Init(gEeprom.FM_FrequencyPlaying, true);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
gEnableSpeaker = true;
gUpdateStatus = true;

View File

@@ -39,7 +39,6 @@ extern uint8_t gFM_ChannelPosition;
extern uint16_t gFM_FrequencyDeviation;
extern bool gFM_FoundFrequency;
extern bool gFM_AutoScan;
extern uint8_t gFM_ResumeCountdown_500ms;
extern uint16_t gFM_RestoreCountdown_10ms;
bool FM_CheckValidChannel(uint8_t Channel);

View File

@@ -17,9 +17,13 @@
#include <string.h>
#include "app/app.h"
#include "app/chFrScanner.h"
#include "app/common.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif
#include "app/generic.h"
#include "app/menu.h"
#include "app/scanner.h"
@@ -37,29 +41,24 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
{
if (gInputBoxIndex > 0)
{
if (!bKeyHeld && bKeyPressed)
if (!bKeyHeld && bKeyPressed) // short pressed
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (bKeyHeld || !bKeyPressed)
if (bKeyHeld || !bKeyPressed) // held or released
{
if (bKeyHeld || bKeyPressed)
if (bKeyHeld || bKeyPressed) // held or pressed (cannot be held and not pressed I guess, so it checks only if HELD?)
{
if (!bKeyHeld)
if (!bKeyHeld) // won't ever pass
return;
if (!bKeyPressed)
if (!bKeyPressed) // won't ever pass
return;
#ifdef ENABLE_VOICE
gAnotherVoiceID = gEeprom.KEY_LOCK ? VOICE_ID_UNLOCK : VOICE_ID_LOCK;
#endif
gEeprom.KEY_LOCK = !gEeprom.KEY_LOCK;
gRequestSaveSettings = true;
COMMON_KeypadLockToggle();
}
else
else // released
{
#ifdef ENABLE_FMRADIO
if ((gFmRadioMode || gScreenToDisplay != DISPLAY_MAIN) && gScreenToDisplay != DISPLAY_FM)
@@ -69,7 +68,10 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
return;
#endif
gWasFKeyPressed = !gWasFKeyPressed;
gWasFKeyPressed = !gWasFKeyPressed; // toggle F function
if (gWasFKeyPressed)
gKeyInputCountdown = key_input_timeout_500ms;
#ifdef ENABLE_VOICE
if (!gWasFKeyPressed)
@@ -79,16 +81,16 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
gUpdateStatus = true;
}
}
else
else // short pressed
{
if (gScreenToDisplay != DISPLAY_FM)
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
#ifdef ENABLE_FMRADIO
if (gFM_ScanState == FM_SCAN_OFF)
if (gFM_ScanState == FM_SCAN_OFF) // not scanning
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
@@ -96,6 +98,7 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
#endif
gBeepToPlay = BEEP_440HZ_500MS;
gPttWasReleased = true;
}
}
@@ -104,154 +107,131 @@ void GENERIC_Key_PTT(bool bKeyPressed)
{
gInputBoxIndex = 0;
if (!bKeyPressed)
{
if (gScreenToDisplay == DISPLAY_MAIN)
{
if (gCurrentFunction == FUNCTION_TRANSMIT)
if (!bKeyPressed || gSerialConfigCountDown_500ms > 0)
{ // PTT released
if (gCurrentFunction == FUNCTION_TRANSMIT)
{ // we are transmitting .. stop
if (gFlagEndTransmission)
{
if (gFlagEndTransmission)
{
FUNCTION_Select(FUNCTION_FOREGROUND);
}
else
{
APP_EndTransmission();
if (gEeprom.REPEATER_TAIL_TONE_ELIMINATION == 0)
{
FUNCTION_Select(FUNCTION_FOREGROUND);
}
else
gRTTECountdown = gEeprom.REPEATER_TAIL_TONE_ELIMINATION * 10;
}
gFlagEndTransmission = false;
gVOX_NoiseDetected = false;
FUNCTION_Select(FUNCTION_FOREGROUND);
}
else
{
APP_EndTransmission();
if (gEeprom.REPEATER_TAIL_TONE_ELIMINATION == 0)
FUNCTION_Select(FUNCTION_FOREGROUND);
else
gRTTECountdown = gEeprom.REPEATER_TAIL_TONE_ELIMINATION * 10;
}
gFlagEndTransmission = false;
#ifdef ENABLE_VOX
gVOX_NoiseDetected = false;
#endif
RADIO_SetVfoState(VFO_STATE_NORMAL);
// beep when you release the PTT
//gBeepToPlay = BEEP_880HZ_40MS_OPTIONAL; // 1of11
gRequestDisplayScreen = DISPLAY_MAIN;
return;
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
gRequestDisplayScreen = DISPLAY_MAIN;
}
return;
}
// PTT pressed
if (SCANNER_IsScanning())
{ // CTCSS/CDCSS scanning .. stop
SCANNER_Stop();
goto cancel_tx;
}
if (gScanStateDir != SCAN_OFF)
{ // frequency/channel scanning . .stop
CHFRSCANNER_Stop();
goto cancel_tx;
}
#ifdef ENABLE_FMRADIO
if (gFM_ScanState != FM_SCAN_OFF)
{ // FM radio is scanning .. stop
FM_PlayAndUpdate();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
gRequestDisplayScreen = DISPLAY_FM;
goto cancel_tx;
}
#endif
#ifdef ENABLE_FMRADIO
if (gScreenToDisplay == DISPLAY_FM)
goto start_tx; // listening to the FM radio .. start TX'ing
#endif
if (gCurrentFunction == FUNCTION_TRANSMIT && gRTTECountdown == 0)
{ // already transmitting
gInputBoxIndex = 0;
return;
}
if (gScanState != SCAN_OFF)
{
SCANNER_Stop();
gPttDebounceCounter = 0;
gPttIsPressed = false;
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
gRequestDisplayScreen = DISPLAY_MAIN;
return;
if (!gDTMF_InputMode && gDTMF_InputBox_Index == 0)
goto start_tx; // wasn't entering a DTMF code .. start TX'ing (maybe)
// was entering a DTMF string
if (gDTMF_InputBox_Index > 0 || gDTMF_PreviousIndex > 0)
{ // going to transmit a DTMF string
if (gDTMF_InputBox_Index == 0 && gDTMF_PreviousIndex > 0)
gDTMF_InputBox_Index = gDTMF_PreviousIndex; // use the previous DTMF string
if (gDTMF_InputBox_Index < sizeof(gDTMF_InputBox))
gDTMF_InputBox[gDTMF_InputBox_Index] = 0; // NULL term the string
#ifdef ENABLE_DTMF_CALLING
// append our DTMF ID to the inputted DTMF code -
// IF the user inputted code is exactly 3 digits long and D-DCD is enabled
if (gDTMF_InputBox_Index == 3 && gTxVfo->DTMF_DECODING_ENABLE > 0)
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
else
gDTMF_CallMode = DTMF_CALL_MODE_DTMF;
gDTMF_State = DTMF_STATE_0;
#endif
// remember the DTMF string
gDTMF_PreviousIndex = gDTMF_InputBox_Index;
strcpy(gDTMF_String, gDTMF_InputBox);
gDTMF_ReplyState = DTMF_REPLY_ANI;
}
#ifdef ENABLE_FMRADIO
if (gFM_ScanState == FM_SCAN_OFF)
#endif
{
if (gCssScanMode == CSS_SCAN_MODE_OFF)
{
#ifdef ENABLE_FMRADIO
if (gScreenToDisplay == DISPLAY_MENU || gScreenToDisplay == DISPLAY_FM)
#else
if (gScreenToDisplay == DISPLAY_MENU)
#endif
{
gRequestDisplayScreen = DISPLAY_MAIN;
gInputBoxIndex = 0;
gPttIsPressed = false;
gPttDebounceCounter = 0;
return;
}
DTMF_clear_input_box();
if (gScreenToDisplay != DISPLAY_SCANNER)
{
if (gCurrentFunction == FUNCTION_TRANSMIT && gRTTECountdown == 0)
{
gInputBoxIndex = 0;
return;
}
gFlagPrepareTX = true;
if (gDTMF_InputMode)
{
if (gDTMF_InputIndex > 0 || gDTMF_PreviousIndex > 0)
{
if (gDTMF_InputIndex == 0)
gDTMF_InputIndex = gDTMF_PreviousIndex;
gDTMF_InputBox[gDTMF_InputIndex] = 0;
#if 0
// append our DTMF ID to the inputted DTMF code -
// IF the user inputted code is exactly 3 digits long
if (gDTMF_InputIndex == 3)
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
else
#else
// append our DTMF ID to the inputted DTMF code -
// IF the user inputted code is exactly 3 digits long and D-DCD is enabled
if (gDTMF_InputIndex == 3 && gTxVfo->DTMF_DECODING_ENABLE > 0)
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
else
#endif
gDTMF_CallMode = DTMF_CALL_MODE_DTMF;
strcpy(gDTMF_String, gDTMF_InputBox);
gDTMF_PreviousIndex = gDTMF_InputIndex;
gDTMF_ReplyState = DTMF_REPLY_ANI;
gDTMF_State = DTMF_STATE_0;
}
gRequestDisplayScreen = DISPLAY_MAIN;
gDTMF_InputMode = false;
gDTMF_InputIndex = 0;
return;
}
gRequestDisplayScreen = DISPLAY_MAIN;
gFlagPrepareTX = true;
gInputBoxIndex = 0;
return;
}
gRequestDisplayScreen = DISPLAY_MAIN;
gEeprom.CROSS_BAND_RX_TX = gBackupCROSS_BAND_RX_TX;
gUpdateStatus = true;
gFlagStopScan = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
gFlagResetVfos = true;
}
else
{
MENU_StopCssScan();
gRequestDisplayScreen = DISPLAY_MENU;
}
}
#ifdef ENABLE_FMRADIO
else
{
FM_PlayAndUpdate();
gRequestDisplayScreen = DISPLAY_FM;
}
#endif
start_tx:
// request start TX
gFlagPrepareTX = true;
goto done;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
cancel_tx:
if (gPttIsPressed)
{
gPttWasPressed = true;
}
gPttWasPressed = true;
done:
gPttDebounceCounter = 0;
if (gScreenToDisplay != DISPLAY_MENU && gRequestDisplayScreen != DISPLAY_FM) // 1of11 .. don't close the menu
gRequestDisplayScreen = DISPLAY_MAIN;
gUpdateStatus = true;
gUpdateDisplay = true;
}

View File

@@ -18,16 +18,21 @@
#include "app/action.h"
#include "app/app.h"
#include "app/chFrScanner.h"
#include "app/common.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif
#include "app/generic.h"
#include "app/main.h"
#include "app/scanner.h"
#ifdef ENABLE_SPECTRUM
#include "app/spectrum.h"
#endif
#include "audio.h"
#include "board.h"
#include "driver/bk4819.h"
#include "dtmf.h"
#include "frequencies.h"
@@ -36,11 +41,56 @@
#include "settings.h"
#include "ui/inputbox.h"
#include "ui/ui.h"
#include <stdlib.h>
void toggle_chan_scanlist(void)
{ // toggle the selected channels scanlist setting
if ( SCANNER_IsScanning())
return;
if(!IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
#ifdef ENABLE_SCAN_RANGES
gScanRangeStart = gScanRangeStart ? 0 : gTxVfo->pRX->Frequency;
#endif
return;
}
if (gTxVfo->SCANLIST1_PARTICIPATION)
{
if (gTxVfo->SCANLIST2_PARTICIPATION)
gTxVfo->SCANLIST1_PARTICIPATION = 0;
else
gTxVfo->SCANLIST2_PARTICIPATION = 1;
}
else
{
if (gTxVfo->SCANLIST2_PARTICIPATION)
gTxVfo->SCANLIST2_PARTICIPATION = 0;
else
gTxVfo->SCANLIST1_PARTICIPATION = 1;
}
SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true);
gVfoConfigureMode = VFO_CONFIGURE;
gFlagResetVfos = true;
}
static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
{
uint8_t Band;
uint8_t Vfo = gEeprom.TX_CHANNEL;
uint8_t Vfo = gEeprom.TX_VFO;
if (gScreenToDisplay == DISPLAY_MENU)
{
// if (beep)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
// if (beep)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
switch (Key)
{
@@ -50,36 +100,82 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
#else
// TODO: do something useful with the key
// TODO: make use of this function key
#endif
break;
case KEY_1:
if (!IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
if (!IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
gWasFKeyPressed = false;
gUpdateStatus = true;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
#ifdef ENABLE_COPY_CHAN_TO_VFO
if (gEeprom.VFO_OPEN && !gCssBackgroundScan)
{
if (gScanStateDir != SCAN_OFF)
{
if (gCurrentFunction != FUNCTION_INCOMING ||
gRxReceptionMode == RX_MODE_NONE ||
gScanPauseDelayIn_10ms == 0)
{ // scan is running (not paused)
return;
}
}
const uint8_t vfo = gEeprom.TX_VFO;
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo]))
{ // copy channel to VFO, then swap to the VFO
const unsigned int channel = FREQ_CHANNEL_FIRST + gEeprom.VfoInfo[vfo].Band;
gEeprom.ScreenChannel[vfo] = channel;
gEeprom.VfoInfo[vfo].CHANNEL_SAVE = channel;
RADIO_SelectVfos();
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
RADIO_SetupRegisters(true);
//SETTINGS_SaveChannel(channel, gEeprom.RX_VFO, gRxVfo, 1);
gUpdateDisplay = true;
}
}
else
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
#endif
return;
}
Band = gTxVfo->Band + 1;
if (gSetting_350EN || Band != BAND5_350MHz)
{
if (Band > BAND7_470MHz)
Band = BAND1_50MHz;
if(gTxVfo->Band == 6 && gTxVfo->pRX->Frequency < 100000000) {
gTxVfo->pRX->Frequency = 100000000;
return;
}
else
Band = BAND6_400MHz;
gTxVfo->Band = Band;
else {
Band = gTxVfo->Band + 1;
if (gSetting_350EN || Band != BAND5_350MHz) {
if (Band > BAND7_470MHz)
Band = BAND1_50MHz;
}
else
Band = BAND6_400MHz;
gEeprom.ScreenChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
gEeprom.FreqChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
gTxVfo->Band = Band;
gEeprom.ScreenChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
gEeprom.FreqChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
}
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
gRequestDisplayScreen = DISPLAY_MAIN;
if (beep)
@@ -88,63 +184,14 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break;
case KEY_2:
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_A)
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_CHAN_B;
else
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_B)
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_CHAN_A;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A)
gEeprom.DUAL_WATCH = DUAL_WATCH_CHAN_B;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B)
gEeprom.DUAL_WATCH = DUAL_WATCH_CHAN_A;
else
gEeprom.TX_CHANNEL = (Vfo == 0);
gRequestSaveSettings = 1;
gFlagReconfigureVfos = true;
gRequestDisplayScreen = DISPLAY_MAIN;
COMMON_SwitchVFOs();
if (beep)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
break;
case KEY_3:
#ifdef ENABLE_NOAA
if (gEeprom.VFO_OPEN && IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
#else
if (gEeprom.VFO_OPEN)
#endif
{
uint8_t Channel;
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_CHANNEL];
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
break;
}
Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_CHANNEL], 1, false, 0);
if (Channel != 0xFF)
{
gEeprom.ScreenChannel[Vfo] = Channel;
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
AUDIO_SetDigitVoice(1, Channel + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
break;
}
}
COMMON_SwitchVFOMode();
if (beep)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
@@ -153,58 +200,45 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
case KEY_4:
gWasFKeyPressed = false;
gFlagStartScan = true;
gScanSingleFrequency = false;
gBackupCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gUpdateStatus = true;
gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gUpdateStatus = true;
if (beep)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
SCANNER_Start(false);
gRequestDisplayScreen = DISPLAY_SCANNER;
break;
case KEY_5:
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
if(beep) {
#ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_CHANNEL];
gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_VFO];
}
else
{
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_CHANNEL];
#ifdef ENABLE_VOICE
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_VFO];
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif
#endif
}
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
#elif defined(ENABLE_SPECTRUM)
#elif defined(ENABLE_SPECTRUM)
APP_RunSpectrum();
gRequestDisplayScreen = DISPLAY_MAIN;
#else
// toggle scanlist-1 and scanlist 2
if (gScreenToDisplay != DISPLAY_SCANNER)
{
if (gTxVfo->SCANLIST1_PARTICIPATION)
{
if (gTxVfo->SCANLIST2_PARTICIPATION)
gTxVfo->SCANLIST1_PARTICIPATION = 0;
else
gTxVfo->SCANLIST2_PARTICIPATION = 1;
}
else
{
if (gTxVfo->SCANLIST2_PARTICIPATION)
gTxVfo->SCANLIST2_PARTICIPATION = 0;
else
gTxVfo->SCANLIST1_PARTICIPATION = 1;
}
SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true);
gVfoConfigureMode = VFO_CONFIGURE;
gFlagResetVfos = true;
}
#endif
#endif
}
else {
#ifdef ENABLE_VOX
toggle_chan_scanlist();
#endif
}
break;
case KEY_6:
@@ -212,7 +246,11 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break;
case KEY_7:
#ifdef ENABLE_VOX
ACTION_Vox();
#else
toggle_chan_scanlist();
#endif
break;
case KEY_8:
@@ -225,11 +263,11 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
{
gEeprom.MrChannel[Vfo] = gEeprom.CHAN_1_CALL;
gEeprom.ScreenChannel[Vfo] = gEeprom.CHAN_1_CALL;
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
AUDIO_SetDigitVoice(1, gEeprom.CHAN_1_CALL + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
AUDIO_SetDigitVoice(1, gEeprom.CHAN_1_CALL + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
break;
@@ -254,45 +292,36 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
if (bKeyHeld)
{ // key held down
#ifdef ENABLE_MAIN_KEY_HOLD
if (bKeyPressed)
if (bKeyPressed)
{
if (gScreenToDisplay == DISPLAY_MAIN)
{
if (gScreenToDisplay == DISPLAY_MAIN)
{
if (gInputBoxIndex > 0)
{ // delete any inputted chars
gInputBoxIndex = 0;
gRequestDisplayScreen = DISPLAY_MAIN;
}
gWasFKeyPressed = false;
gUpdateStatus = true;
processFKeyFunction(Key, false);
if (gInputBoxIndex > 0)
{ // delete any inputted chars
gInputBoxIndex = 0;
gRequestDisplayScreen = DISPLAY_MAIN;
}
gWasFKeyPressed = false;
gUpdateStatus = true;
processFKeyFunction(Key, false);
}
#endif
}
return;
}
#ifdef ENABLE_MAIN_KEY_HOLD
if (bKeyPressed)
{ // key is pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; // beep when key is pressed
return; // don't use the key till it's released
}
#else
if (!bKeyPressed)
return;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
#endif
if (bKeyPressed)
{ // key is pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; // beep when key is pressed
return; // don't use the key till it's released
}
if (!gWasFKeyPressed)
{ // F-key wasn't pressed
const uint8_t Vfo = gEeprom.TX_CHANNEL;
const uint8_t Vfo = gEeprom.TX_VFO;
gKeyInputCountdown = key_input_timeout_500ms;
@@ -302,7 +331,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // user is entering channel number
uint16_t Channel;
if (gInputBoxIndex != 3)
@@ -337,14 +366,14 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
}
// #ifdef ENABLE_NOAA
// if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
// if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
// #endif
if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // user is entering frequency
uint32_t Frequency;
{ // user is entering a frequency
if (gInputBoxIndex < 6)
uint32_t Frequency;
bool isGigaF = gTxVfo->pRX->Frequency >= 100000000;
if (gInputBoxIndex < 6 + isGigaF)
{
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
@@ -354,26 +383,25 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
}
gInputBoxIndex = 0;
NUMBER_Get(gInputBox, &Frequency);
Frequency = StrToUL(INPUTBOX_GetAscii()) * 100;
// clamp the frequency entered to some valid value
if (Frequency < LowerLimitFrequencyBandTable[0])
if (Frequency < frequencyBandTable[0].lower)
{
Frequency = LowerLimitFrequencyBandTable[0];
Frequency = frequencyBandTable[0].lower;
}
else
if (Frequency >= bx_stop1_Hz && Frequency < bx_start2_Hz)
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
{
const uint32_t center = (bx_stop1_Hz + bx_start2_Hz) / 2;
Frequency = (Frequency < center) ? bx_stop1_Hz : bx_start2_Hz;
const uint32_t center = (BX4819_band1.upper + BX4819_band2.lower) / 2;
Frequency = (Frequency < center) ? BX4819_band1.upper : BX4819_band2.lower;
}
else
if (Frequency > UpperLimitFrequencyBandTable[6])
if (Frequency > frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper)
{
Frequency = UpperLimitFrequencyBandTable[6];
Frequency = frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper;
}
{
const FREQUENCY_Band_t band = FREQUENCY_GetBand(Frequency);
@@ -386,35 +414,32 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gTxVfo->Band = band;
gEeprom.ScreenChannel[Vfo] = band + FREQ_CHANNEL_FIRST;
gEeprom.FreqChannel[Vfo] = band + FREQ_CHANNEL_FIRST;
SETTINGS_SaveVfoIndices();
RADIO_ConfigureChannel(Vfo, VFO_CONFIGURE_RELOAD);
}
// Frequency += 75; // is this meant to be rounding ?
Frequency += gTxVfo->StepFrequency / 2; // no idea, but this is
Frequency = FREQUENCY_FloorToStep(Frequency, gTxVfo->StepFrequency, LowerLimitFrequencyBandTable[gTxVfo->Band]);
if (Frequency >= bx_stop1_Hz && Frequency < bx_start2_Hz)
Frequency = FREQUENCY_RoundToStep(Frequency, gTxVfo->StepFrequency);
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
{ // clamp the frequency to the limit
const uint32_t center = (bx_stop1_Hz + bx_start2_Hz) / 2;
Frequency = (Frequency < center) ? bx_stop1_Hz - gTxVfo->StepFrequency : bx_start2_Hz;
const uint32_t center = (BX4819_band1.upper + BX4819_band2.lower) / 2;
Frequency = (Frequency < center) ? BX4819_band1.upper - gTxVfo->StepFrequency : BX4819_band2.lower;
}
gTxVfo->freq_config_RX.Frequency = Frequency;
gRequestSaveChannel = 1;
return;
}
}
#ifdef ENABLE_NOAA
else
if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // user is entering NOAA channel
uint8_t Channel;
if (gInputBoxIndex != 2)
@@ -458,14 +483,24 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
{ // exit key pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
#ifdef ENABLE_DTMF_CALLING
if (gDTMF_CallState != DTMF_CALL_STATE_NONE && gCurrentFunction != FUNCTION_TRANSMIT)
{ // clear CALL mode being displayed
gDTMF_CallState = DTMF_CALL_STATE_NONE;
gUpdateDisplay = true;
return;
}
#endif
#ifdef ENABLE_FMRADIO
if (!gFmRadioMode)
#endif
{
if (gScanState == SCAN_OFF)
if (gScanStateDir == SCAN_OFF)
{
if (gInputBoxIndex == 0)
return;
@@ -480,7 +515,8 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
}
else
{
SCANNER_Stop();
gScanKeepResult = false;
CHFRSCANNER_Stop();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
@@ -499,11 +535,12 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
}
if (bKeyHeld && bKeyPressed)
{
if (gInputBoxIndex > 0)
{ // exit key held down
if (gInputBoxIndex > 0 || gDTMF_InputBox_Index > 0 || gDTMF_InputMode)
{ // cancel key input mode (channel/frequency entry)
gDTMF_InputMode = false;
gDTMF_InputIndex = 0;
gDTMF_InputBox_Index = 0;
memset(gDTMF_String, 0, sizeof(gDTMF_String));
gInputBoxIndex = 0;
gRequestDisplayScreen = DISPLAY_MAIN;
@@ -514,11 +551,18 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
{
if (bKeyPressed && !bKeyHeld)
// menu key pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (bKeyHeld)
{ // key held down (long press)
{ // menu key held down (long press)
if (bKeyPressed)
{
{ // long press MENU key
gWasFKeyPressed = false;
if (gScreenToDisplay == DISPLAY_MAIN)
{
if (gInputBoxIndex > 0)
@@ -530,69 +574,26 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
gWasFKeyPressed = false;
gUpdateStatus = true;
// TODO: long press M-key
#ifdef ENABLE_COPY_CHAN_TO_VFO
{ // copy channel to VFO
int channel = -1;
int vfo = -1;
//int selected = -1;
if (IS_FREQ_CHANNEL(gRxVfo->CHANNEL_SAVE))
{ // VFO mode
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // other VFO is in channel mode
channel = gTxVfo->CHANNEL_SAVE;
vfo = gRxVfo->CHANNEL_SAVE;
}
}
else
if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // VFO mode
if (IS_MR_CHANNEL(gRxVfo->CHANNEL_SAVE))
{ // other VFO is in channel mode
channel = gRxVfo->CHANNEL_SAVE;
vfo = gTxVfo->CHANNEL_SAVE;
}
}
if (channel >= 0 && vfo >= 0)
{ // copy the channel into the VFO
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
//gEeprom.RX_CHANNEL = () & 1; // swap to the VFO
// gRequestSaveVFO = true;
// gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
// gRequestDisplayScreen = DISPLAY_MAIN;
}
}
#endif
ACTION_Handle(KEY_MENU, bKeyPressed, bKeyHeld);
}
}
return;
}
if (!bKeyPressed)
{
bool bFlag;
if (!bKeyPressed && !gDTMF_InputMode)
{ // menu key released
const bool bFlag = (gInputBoxIndex == 0);
gInputBoxIndex = 0;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
bFlag = (gInputBoxIndex == 0);
gInputBoxIndex = 0;
if (bFlag)
{
gFlagRefreshSetting = true;
if (gScanStateDir != SCAN_OFF) {
CHFRSCANNER_Stop();
return;
}
gFlagRefreshSetting = true;
gRequestDisplayScreen = DISPLAY_MENU;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_MENU;
@@ -607,6 +608,9 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
{
if (gCurrentFunction == FUNCTION_TRANSMIT)
return;
if (gInputBoxIndex)
{
if (!bKeyHeld && bKeyPressed)
@@ -614,72 +618,71 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
return;
}
if (bKeyHeld || !bKeyPressed)
{
if (bKeyHeld || bKeyPressed)
{
if (!bKeyHeld)
return;
if (bKeyHeld && !gWasFKeyPressed) // long press
{
if (!bKeyPressed) // released
return;
if (!bKeyPressed)
return;
ACTION_Scan(false);// toggle scanning
ACTION_Scan(false);
return;
}
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
if (bKeyPressed) // just pressed
{
// gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gBeepToPlay = BEEP_880HZ_40MS_OPTIONAL;
return;
}
// just released
if (!gWasFKeyPressed) // pressed without the F-key
{
#ifdef ENABLE_NOAA
if (gScanState == SCAN_OFF && IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
if (gScanStateDir == SCAN_OFF && !IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
#else
if (gScanState == SCAN_OFF)
if (gScanStateDir == SCAN_OFF)
#endif
{
gKeyInputCountdown = key_input_timeout_500ms;
{ // start entering a DTMF string
memmove(gDTMF_InputBox, gDTMF_String, MIN(sizeof(gDTMF_InputBox), sizeof(gDTMF_String) - 1));
gDTMF_InputBox_Index = 0;
gDTMF_InputMode = true;
memmove(gDTMF_InputBox, gDTMF_String, sizeof(gDTMF_InputBox));
gDTMF_InputIndex = 0;
gKeyInputCountdown = key_input_timeout_500ms;
gRequestDisplayScreen = DISPLAY_MAIN;
return;
}
}
else
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (!gWasFKeyPressed)
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
{ // with the F-key
gWasFKeyPressed = false;
gUpdateStatus = true;
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gFlagStartScan = true;
gScanSingleFrequency = true;
gBackupCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
}
else
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
#else
gFlagStartScan = true;
gScanSingleFrequency = true;
gBackupCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
#endif
#ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
#endif
gPttWasReleased = true;
// scan the CTCSS/DCS code
gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
SCANNER_Start(true);
gRequestDisplayScreen = DISPLAY_SCANNER;
}
gPttWasReleased = true;
gUpdateStatus = true;
}
static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
{
uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_CHANNEL];
uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO];
if (bKeyHeld || !bKeyPressed)
{
@@ -713,10 +716,10 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
}
if (gScanState == SCAN_OFF)
if (gScanStateDir == SCAN_OFF)
{
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(Channel))
if (!IS_NOAA_CHANNEL(Channel))
#endif
{
uint8_t Next;
@@ -725,14 +728,14 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
{ // step/down in frequency
const uint32_t frequency = APP_SetFrequencyByStep(gTxVfo, Direction);
if (RX_FREQUENCY_Check(frequency) < 0)
if (RX_freq_check(frequency) < 0)
{ // frequency not allowed
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
gTxVfo->freq_config_RX.Frequency = frequency;
gRequestSaveChannel = 1;
return;
}
@@ -744,8 +747,8 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
if (Channel == Next)
return;
gEeprom.MrChannel[gEeprom.TX_CHANNEL] = Next;
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Next;
gEeprom.MrChannel[gEeprom.TX_VFO] = Next;
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Next;
if (!bKeyHeld)
{
@@ -758,9 +761,9 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
#ifdef ENABLE_NOAA
else
{
Channel = NOAA_CHANNEL_FIRST + NUMBER_AddWithWraparound(gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] - NOAA_CHANNEL_FIRST, Direction, 0, 9);
gEeprom.NoaaChannel[gEeprom.TX_CHANNEL] = Channel;
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Channel;
Channel = NOAA_CHANNEL_FIRST + NUMBER_AddWithWraparound(gEeprom.ScreenChannel[gEeprom.TX_VFO] - NOAA_CHANNEL_FIRST, Direction, 0, 9);
gEeprom.NoaaChannel[gEeprom.TX_VFO] = Channel;
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel;
}
#endif
@@ -769,7 +772,10 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
return;
}
CHANNEL_Next(false, Direction);
// jump to the next channel
CHFRSCANNER_Start(false, Direction);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;
gPttWasReleased = true;
}
@@ -785,29 +791,25 @@ void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
}
#endif
if (gDTMF_InputMode && bKeyPressed)
if (gDTMF_InputMode && bKeyPressed && !bKeyHeld)
{
if (!bKeyHeld)
{
const char Character = DTMF_GetCharacter(Key);
if (Character != 0xFF)
{ // add key to DTMF string
DTMF_Append(Character);
gKeyInputCountdown = key_input_timeout_500ms;
gRequestDisplayScreen = DISPLAY_MAIN;
gPttWasReleased = true;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
const char Character = DTMF_GetCharacter(Key);
if (Character != 0xFF)
{ // add key to DTMF string
DTMF_Append(Character);
gKeyInputCountdown = key_input_timeout_500ms;
gRequestDisplayScreen = DISPLAY_MAIN;
gPttWasReleased = true;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
}
// TODO: ???
if (Key > KEY_PTT)
{
Key = KEY_SIDE2;
}
// if (Key > KEY_PTT)
// {
// Key = KEY_SIDE2; // what's this doing ???
// }
switch (Key)
{

File diff suppressed because it is too large Load Diff

View File

@@ -19,11 +19,17 @@
#include "driver/keyboard.h"
int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax);
#ifdef ENABLE_F_CAL_MENU
void writeXtalFreqCal(const int32_t value, const bool update_eeprom);
#endif
extern uint8_t gUnlockAllTxConfCnt;
int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax);
void MENU_AcceptSetting(void);
void MENU_SelectNextCode(void);
void MENU_ShowCurrentSetting(void);
void MENU_StartCssScan(int8_t Direction);
void MENU_StartCssScan(void);
void MENU_CssScanFound(void);
void MENU_StopCssScan(void);
void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);

View File

@@ -14,7 +14,10 @@
* limitations under the License.
*/
#include "app/app.h"
#include "app/dtmf.h"
#include "app/generic.h"
#include "app/menu.h"
#include "app/scanner.h"
#include "audio.h"
#include "driver/bk4819.h"
@@ -27,52 +30,45 @@
DCS_CodeType_t gScanCssResultType;
uint8_t gScanCssResultCode;
bool gFlagStartScan;
bool gFlagStopScan;
bool gScanSingleFrequency;
uint8_t gScannerEditState;
bool gScanSingleFrequency; // scan CTCSS/DCS codes for current frequency
SCAN_SaveState_t gScannerSaveState;
uint8_t gScanChannel;
uint32_t gScanFrequency;
bool gScanPauseMode;
SCAN_CssState_t gScanCssState;
volatile bool gScheduleScanListen = true;
volatile uint16_t ScanPauseDelayIn_10ms;
uint8_t gScanProgressIndicator;
uint8_t gScanHitCount;
bool gScanUseCssResult;
int8_t gScanState;
bool bScanKeepFrequency;
STEP_Setting_t stepSetting;
uint8_t scanHitCount;
static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
if (gScannerEditState == 1)
{
uint16_t Channel;
if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
INPUTBOX_Append(Key);
gRequestDisplayScreen = DISPLAY_SCANNER;
if (gInputBoxIndex < 3)
{
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
if (gInputBoxIndex < 3) {
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
return;
}
gInputBoxIndex = 0;
Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
if (IS_MR_CHANNEL(Channel))
{
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gShowChPrefix = RADIO_CheckValidChannel(Channel, false, 0);
gScanChannel = (uint8_t)Channel;
uint16_t chan = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
if (IS_MR_CHANNEL(chan)) {
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gShowChPrefix = RADIO_CheckValidChannel(chan, false, 0);
gScanChannel = (uint8_t)chan;
return;
}
}
@@ -83,27 +79,17 @@ static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
if (!bKeyHeld && bKeyPressed) { // short pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
switch (gScannerEditState)
{
case 0:
switch (gScannerSaveState) {
case SCAN_SAVE_NO_PROMPT:
SCANNER_Stop();
gRequestDisplayScreen = DISPLAY_MAIN;
gEeprom.CROSS_BAND_RX_TX = gBackupCROSS_BAND_RX_TX;
gUpdateStatus = true;
gFlagStopScan = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
gFlagResetVfos = true;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
break;
case 1:
if (gInputBoxIndex > 0)
{
case SCAN_SAVE_CHAN_SEL:
if (gInputBoxIndex > 0) {
gInputBox[--gInputBoxIndex] = 10;
gRequestDisplayScreen = DISPLAY_SCANNER;
break;
@@ -111,11 +97,11 @@ static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
// Fallthrough
case 2:
gScannerEditState = 0;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
case SCAN_SAVE_CHANNEL:
gScannerSaveState = SCAN_SAVE_NO_PROMPT;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
gRequestDisplayScreen = DISPLAY_SCANNER;
break;
}
@@ -124,118 +110,85 @@ static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
{
uint8_t Channel;
if (bKeyHeld)
if (bKeyHeld || !bKeyPressed) // ignore long press or release button events
return;
if (!bKeyPressed)
return;
if (gScanCssState == SCAN_CSS_STATE_OFF && !gScanSingleFrequency)
{
if (gScanCssState == SCAN_CSS_STATE_OFF && !gScanSingleFrequency) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gScanCssState == SCAN_CSS_STATE_SCANNING)
{
if (gScanSingleFrequency)
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gScanCssState == SCAN_CSS_STATE_SCANNING && gScanSingleFrequency) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gScanCssState == SCAN_CSS_STATE_FAILED)
{
if (gScanCssState == SCAN_CSS_STATE_FAILED) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
switch (gScannerEditState)
{
case 0:
switch (gScannerSaveState) {
case SCAN_SAVE_NO_PROMPT:
if (!gScanSingleFrequency)
{
int16_t Delta625;
uint32_t Freq250 = FREQUENCY_FloorToStep(gScanFrequency, 250, 0);
uint32_t Freq625 = FREQUENCY_FloorToStep(gScanFrequency, 625, 0);
int16_t Delta250 = (int16_t)gScanFrequency - (int16_t)Freq250;
uint32_t freq250 = FREQUENCY_RoundToStep(gScanFrequency, 250);
uint32_t freq625 = FREQUENCY_RoundToStep(gScanFrequency, 625);
if (125 < Delta250)
{
Delta250 = 250 - Delta250;
Freq250 += 250;
uint32_t diff250 = gScanFrequency > freq250 ? gScanFrequency - freq250 : freq250 - gScanFrequency;
uint32_t diff625 = gScanFrequency > freq625 ? gScanFrequency - freq625 : freq625 - gScanFrequency;
if(diff250 > diff625) {
stepSetting = STEP_6_25kHz;
gScanFrequency = freq625;
}
Delta625 = (int16_t)gScanFrequency - (int16_t)Freq625;
if (312 < Delta625)
{
Delta625 = 625 - Delta625;
Freq625 += 625;
}
if (Delta625 < Delta250)
{
gStepSetting = STEP_6_25kHz;
gScanFrequency = Freq625;
}
else
{
gStepSetting = STEP_2_5kHz;
gScanFrequency = Freq250;
else {
stepSetting = STEP_2_5kHz;
gScanFrequency = freq250;
}
}
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gScannerEditState = 1;
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
gScannerSaveState = SCAN_SAVE_CHAN_SEL;
gScanChannel = gTxVfo->CHANNEL_SAVE;
gShowChPrefix = RADIO_CheckValidChannel(gTxVfo->CHANNEL_SAVE, false, 0);
}
else
{
gScannerEditState = 2;
else {
gScannerSaveState = SCAN_SAVE_CHANNEL;
}
gScanCssState = SCAN_CSS_STATE_FOUND;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_MEMORY_CHANNEL;
#endif
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_MEMORY_CHANNEL;
#endif
gRequestDisplayScreen = DISPLAY_SCANNER;
gUpdateStatus = true;
break;
case 1:
if (gInputBoxIndex == 0)
{
case SCAN_SAVE_CHAN_SEL:
if (gInputBoxIndex == 0) {
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gRequestDisplayScreen = DISPLAY_SCANNER;
gScannerEditState = 2;
gScannerSaveState = SCAN_SAVE_CHANNEL;
}
break;
case 2:
if (!gScanSingleFrequency)
{
RADIO_InitInfo(gTxVfo, gTxVfo->CHANNEL_SAVE, FREQUENCY_GetBand(gScanFrequency), gScanFrequency);
case SCAN_SAVE_CHANNEL:
if (!gScanSingleFrequency) {
RADIO_InitInfo(gTxVfo, gTxVfo->CHANNEL_SAVE, gScanFrequency);
if (gScanUseCssResult)
{
if (gScanUseCssResult) {
gTxVfo->freq_config_RX.CodeType = gScanCssResultType;
gTxVfo->freq_config_RX.Code = gScanCssResultCode;
}
gTxVfo->freq_config_TX = gTxVfo->freq_config_RX;
gTxVfo->STEP_SETTING = gStepSetting;
gTxVfo->STEP_SETTING = stepSetting;
}
else
{
else {
RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD);
RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD);
@@ -245,25 +198,24 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
gTxVfo->freq_config_TX.Code = gScanCssResultCode;
}
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
Channel = gScanChannel;
gEeprom.MrChannel[gEeprom.TX_CHANNEL] = Channel;
uint8_t chan;
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
chan = gScanChannel;
gEeprom.MrChannel[gEeprom.TX_VFO] = chan;
}
else
{
Channel = gTxVfo->Band + FREQ_CHANNEL_FIRST;
gEeprom.FreqChannel[gEeprom.TX_CHANNEL] = Channel;
else {
chan = gTxVfo->Band + FREQ_CHANNEL_FIRST;
gEeprom.FreqChannel[gEeprom.TX_VFO] = chan;
}
gTxVfo->CHANNEL_SAVE = Channel;
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Channel;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CONFIRM;
#endif
gRequestDisplayScreen = DISPLAY_SCANNER;
gRequestSaveChannel = 2;
gScannerEditState = 0;
gTxVfo->CHANNEL_SAVE = chan;
gEeprom.ScreenChannel[gEeprom.TX_VFO] = chan;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CONFIRM;
#endif
gRequestDisplayScreen = DISPLAY_SCANNER;
gRequestSaveChannel = 2;
gScannerSaveState = SCAN_SAVE_NO_PROMPT;
break;
default:
@@ -274,23 +226,20 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
static void SCANNER_Key_STAR(bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
if (!bKeyHeld && bKeyPressed) {
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gFlagStartScan = true;
SCANNER_Start(gScanSingleFrequency);
}
return;
}
static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Direction)
{
if (pKeyHeld)
{
if (pKeyHeld) {
if (!bKeyPressed)
return;
}
else
{
else {
if (!bKeyPressed)
return;
@@ -298,8 +247,7 @@ static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Directio
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
}
if (gScannerEditState == 1)
{
if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
gScanChannel = NUMBER_AddWithWraparound(gScanChannel, Direction, 0, MR_CHANNEL_LAST);
gShowChPrefix = RADIO_CheckValidChannel(gScanChannel, false, 0);
gRequestDisplayScreen = DISPLAY_SCANNER;
@@ -310,8 +258,7 @@ static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Directio
void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
switch (Key)
{
switch (Key) {
case KEY_0:
case KEY_1:
case KEY_2:
@@ -349,107 +296,233 @@ void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
}
}
void SCANNER_Start(void)
void SCANNER_Start(bool singleFreq)
{
uint8_t BackupStep;
uint16_t BackupFrequency;
gScanSingleFrequency = singleFreq;
gMonitor = false;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;
#endif
BK4819_StopScan();
RADIO_SelectVfos();
#ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + BAND6_400MHz;
#endif
#ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + BAND6_400MHz;
#endif
BackupStep = gRxVfo->STEP_SETTING;
BackupFrequency = gRxVfo->StepFrequency;
uint8_t backupStep = gRxVfo->STEP_SETTING;
uint16_t backupFrequency = gRxVfo->StepFrequency;
RADIO_InitInfo(gRxVfo, gRxVfo->CHANNEL_SAVE, gRxVfo->Band, gRxVfo->pRX->Frequency);
RADIO_InitInfo(gRxVfo, gRxVfo->CHANNEL_SAVE, gRxVfo->pRX->Frequency);
gRxVfo->STEP_SETTING = BackupStep;
gRxVfo->StepFrequency = BackupFrequency;
gRxVfo->STEP_SETTING = backupStep;
gRxVfo->StepFrequency = backupFrequency;
RADIO_SetupRegisters(true);
#ifdef ENABLE_NOAA
gIsNoaaMode = false;
#endif
#ifdef ENABLE_NOAA
gIsNoaaMode = false;
#endif
if (gScanSingleFrequency)
{
if (gScanSingleFrequency) {
gScanCssState = SCAN_CSS_STATE_SCANNING;
gScanFrequency = gRxVfo->pRX->Frequency;
gStepSetting = gRxVfo->STEP_SETTING;
stepSetting = gRxVfo->STEP_SETTING;
BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency);
BK4819_SetScanFrequency(gScanFrequency);
gUpdateStatus = true;
}
else
{
else {
gScanCssState = SCAN_CSS_STATE_OFF;
gScanFrequency = 0xFFFFFFFF;
BK4819_PickRXFilterPathBasedOnFrequency(0xFFFFFFFF);
BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency);
BK4819_EnableFrequencyScan();
gUpdateStatus = true;
}
#ifdef ENABLE_DTMF_CALLING
DTMF_clear_RX();
#endif
gScanDelay_10ms = scan_delay_10ms;
gScanCssResultCode = 0xFF;
gScanCssResultType = 0xFF;
gScanHitCount = 0;
scanHitCount = 0;
gScanUseCssResult = false;
gDTMF_RequestPending = false;
g_CxCSS_TAIL_Found = false;
g_CDCSS_Lost = false;
gCDCSSCodeType = 0;
g_CTCSS_Lost = false;
g_VOX_Lost = false;
#ifdef ENABLE_VOX
g_VOX_Lost = false;
#endif
g_SquelchLost = false;
gScannerEditState = 0;
gScannerSaveState = SCAN_SAVE_NO_PROMPT;
gScanProgressIndicator = 0;
}
void SCANNER_Stop(void)
{
const uint8_t Previous = gRestoreMrChannel;
gScanState = SCAN_OFF;
if (!bScanKeepFrequency)
{
if (IS_MR_CHANNEL(gNextMrChannel))
{
gEeprom.MrChannel[gEeprom.RX_CHANNEL] = gRestoreMrChannel;
gEeprom.ScreenChannel[gEeprom.RX_CHANNEL] = Previous;
RADIO_ConfigureChannel(gEeprom.RX_CHANNEL, VFO_CONFIGURE_RELOAD);
}
else
{
gRxVfo->freq_config_RX.Frequency = gRestoreFrequency;
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
}
RADIO_SetupRegisters(true);
gUpdateDisplay = true;
return;
if(SCANNER_IsScanning()) {
gEeprom.CROSS_BAND_RX_TX = gBackup_CROSS_BAND_RX_TX;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
gFlagResetVfos = true;
gUpdateStatus = true;
gCssBackgroundScan = false;
gScanUseCssResult = false;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
BK4819_StopScan();
}
if (!IS_MR_CHANNEL(gRxVfo->CHANNEL_SAVE))
{
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_CHANNEL, gRxVfo, 1);
return;
}
SETTINGS_SaveVfoIndices();
gUpdateStatus = true;
}
void SCANNER_TimeSlice10ms(void)
{
if (!SCANNER_IsScanning())
return;
if (gScanDelay_10ms > 0) {
gScanDelay_10ms--;
return;
}
if (gScannerSaveState != SCAN_SAVE_NO_PROMPT) {
return;
}
switch (gScanCssState) {
case SCAN_CSS_STATE_OFF: {
// must be RF frequency scanning if we're here ?
uint32_t result;
if (!BK4819_GetFrequencyScanResult(&result))
break;
int32_t delta = result - gScanFrequency;
gScanFrequency = result;
if (delta < 0)
delta = -delta;
if (delta < 100)
scanHitCount++;
else
scanHitCount = 0;
BK4819_DisableFrequencyScan();
if (scanHitCount < 3) {
BK4819_EnableFrequencyScan();
}
else {
BK4819_SetScanFrequency(gScanFrequency);
gScanCssResultCode = 0xFF;
gScanCssResultType = 0xFF;
scanHitCount = 0;
gScanUseCssResult = false;
gScanProgressIndicator = 0;
gScanCssState = SCAN_CSS_STATE_SCANNING;
if(!gCssBackgroundScan)
GUI_SelectNextDisplay(DISPLAY_SCANNER);
gUpdateStatus = true;
}
gScanDelay_10ms = scan_delay_10ms;
//gScanDelay_10ms = 1; // 10ms
break;
}
case SCAN_CSS_STATE_SCANNING: {
uint32_t cdcssFreq;
uint16_t ctcssFreq;
BK4819_CssScanResult_t scanResult = BK4819_GetCxCSSScanResult(&cdcssFreq, &ctcssFreq);
if (scanResult == BK4819_CSS_RESULT_NOT_FOUND)
break;
BK4819_Disable();
if (scanResult == BK4819_CSS_RESULT_CDCSS) {
const uint8_t Code = DCS_GetCdcssCode(cdcssFreq);
if (Code != 0xFF)
{
gScanCssResultCode = Code;
gScanCssResultType = CODE_TYPE_DIGITAL;
gScanCssState = SCAN_CSS_STATE_FOUND;
gScanUseCssResult = true;
gUpdateStatus = true;
}
}
else if (scanResult == BK4819_CSS_RESULT_CTCSS) {
const uint8_t Code = DCS_GetCtcssCode(ctcssFreq);
if (Code != 0xFF) {
if (Code == gScanCssResultCode && gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) {
if (++scanHitCount >= 2) {
gScanCssState = SCAN_CSS_STATE_FOUND;
gScanUseCssResult = true;
gUpdateStatus = true;
}
}
else
scanHitCount = 0;
gScanCssResultType = CODE_TYPE_CONTINUOUS_TONE;
gScanCssResultCode = Code;
}
}
if (gScanCssState < SCAN_CSS_STATE_FOUND) { // scanning or off
BK4819_SetScanFrequency(gScanFrequency);
gScanDelay_10ms = scan_delay_10ms;
break;
}
if(gCssBackgroundScan) {
gCssBackgroundScan = false;
if(gScanUseCssResult)
MENU_CssScanFound();
}
else
GUI_SelectNextDisplay(DISPLAY_SCANNER);
break;
}
default:
gCssBackgroundScan = false;
break;
}
}
void SCANNER_TimeSlice500ms(void)
{
if (SCANNER_IsScanning() && gScannerSaveState == SCAN_SAVE_NO_PROMPT && gScanCssState < SCAN_CSS_STATE_FOUND) {
gScanProgressIndicator++;
#ifdef ENABLE_NO_CODE_SCAN_TIMEOUT
if (gScanProgressIndicator > 32) {
if (gScanCssState == SCAN_CSS_STATE_SCANNING && !gScanSingleFrequency)
gScanCssState = SCAN_CSS_STATE_FOUND;
else
gScanCssState = SCAN_CSS_STATE_FAILED;
gUpdateStatus = true;
}
#endif
gUpdateDisplay = true;
}
else if(gCssBackgroundScan) {
gUpdateDisplay = true;
}
}
bool SCANNER_IsScanning(void)
{
return gCssBackgroundScan || (gScreenToDisplay == DISPLAY_SCANNER);
}

View File

@@ -20,42 +20,38 @@
#include "dcs.h"
#include "driver/keyboard.h"
enum SCAN_CssState_t
typedef enum
{
SCAN_CSS_STATE_OFF = 0,
SCAN_CSS_STATE_OFF,
SCAN_CSS_STATE_SCANNING,
SCAN_CSS_STATE_FOUND,
SCAN_CSS_STATE_FAILED
};
} SCAN_CssState_t;
typedef enum SCAN_CssState_t SCAN_CssState_t;
enum
typedef enum
{
SCAN_OFF = 0,
};
SCAN_SAVE_NO_PROMPT, // saving process not initiated
SCAN_SAVE_CHAN_SEL, // "SAVE: ", channel select prompt, actives only in channel mode
SCAN_SAVE_CHANNEL, // "SAVE?" prompt, waits for confirmation to save settings to channel, or current VFO
} SCAN_SaveState_t;
extern DCS_CodeType_t gScanCssResultType;
extern uint8_t gScanCssResultCode;
extern bool gFlagStartScan;
extern bool gFlagStopScan;
extern bool gScanSingleFrequency;
extern uint8_t gScannerEditState;
extern SCAN_SaveState_t gScannerSaveState;
extern uint8_t gScanChannel;
extern uint32_t gScanFrequency;
extern bool gScanPauseMode;
extern SCAN_CssState_t gScanCssState;
extern volatile bool gScheduleScanListen;
extern volatile uint16_t ScanPauseDelayIn_10ms;
extern uint8_t gScanProgressIndicator;
extern uint8_t gScanHitCount;
extern bool gScanUseCssResult;
extern int8_t gScanState;
extern bool bScanKeepFrequency;
void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
void SCANNER_Start(void);
void SCANNER_Start(bool singleFreq);
void SCANNER_Stop(void);
void SCANNER_TimeSlice10ms(void);
void SCANNER_TimeSlice500ms(void);
bool SCANNER_IsScanning(void);
#endif

View File

@@ -14,7 +14,10 @@
* limitations under the License.
*/
#include "../app/spectrum.h"
#include "app/spectrum.h"
#include "driver/backlight.h"
#include "audio.h"
#include "ui/helper.h"
struct FrequencyBandInfo {
uint32_t lower;
@@ -22,19 +25,8 @@ struct FrequencyBandInfo {
uint32_t middle;
};
const struct FrequencyBandInfo FrequencyBandTable[7] = {
[BAND1_50MHz ] = {.lower = 1600000, .middle = 6500000, .upper = 7600000},
[BAND2_108MHz] = {.lower = 10800000, .middle = 12200000, .upper = 13599990},
[BAND3_136MHz] = {.lower = 13600000, .middle = 15000000, .upper = 17399990},
[BAND4_174MHz] = {.lower = 17400000, .middle = 26000000, .upper = 34999990},
[BAND5_350MHz] = {.lower = 35000000, .middle = 37000000, .upper = 39999990},
[BAND6_400MHz] = {.lower = 40000000, .middle = 43500000, .upper = 46999990},
[BAND7_470MHz] = {.lower = 47000000, .middle = 55000000, .upper = 130000000},
};
#define F_MIN FrequencyBandTable[0].lower
#define F_MAX FrequencyBandTable[ARRAY_SIZE(FrequencyBandTable) - 1].upper
#define F_MIN frequencyBandTable[0].lower
#define F_MAX frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper
const uint16_t RSSI_MAX_VALUE = 65535;
@@ -57,41 +49,40 @@ PeakInfo peak;
ScanInfo scanInfo;
KeyboardState kbd = {KEY_INVALID, KEY_INVALID, 0};
const char *bwOptions[] = {"25k", "12.5k", "6.25k"};
const char *modulationTypeOptions[] = {"FM", "AM", "USB"};
const char *bwOptions[] = {" 25k", "12.5k", "6.25k"};
const uint8_t modulationTypeTuneSteps[] = {100, 50, 10};
const uint8_t modTypeReg47Values[] = {1, 7, 5};
SpectrumSettings settings = {STEPS_64,
S_STEP_25_0kHz,
80000,
3200,
0,
true,
BK4819_FILTER_BW_WIDE,
BK4819_FILTER_BW_WIDE,
false,
-130,
-50};
SpectrumSettings settings = {stepsCount: STEPS_64,
scanStepIndex: S_STEP_25_0kHz,
frequencyChangeStep: 80000,
scanDelay: 3200,
rssiTriggerLevel: 150,
backlightState: true,
bw: BK4819_FILTER_BW_WIDE,
listenBw: BK4819_FILTER_BW_WIDE,
modulationType: false,
dbMin: -130,
dbMax: -50};
uint32_t fMeasure = 0;
uint32_t currentFreq, tempFreq;
uint16_t rssiHistory[128] = {};
uint16_t rssiHistory[128];
uint8_t freqInputIndex = 0;
uint8_t freqInputDotIndex = 0;
KEY_Code_t freqInputArr[10];
char freqInputString[11] = "----------\0"; // XXXX.XXXXX\0
char freqInputString[11];
uint8_t menuState = 0;
uint16_t listenT = 0;
RegisterSpec registerSpecs[] = {
{},
{"LNAs", 0x13, 8, 0b11, 1},
{"LNA", 0x13, 5, 0b111, 1},
{"PGA", 0x13, 0, 0b111, 1},
{"IF", 0x3D, 0, 0xFFFF, 0x2aaa},
{"LNAs", BK4819_REG_13, 8, 0b11, 1},
{"LNA", BK4819_REG_13, 5, 0b111, 1},
{"PGA", BK4819_REG_13, 0, 0b111, 1},
{"IF", BK4819_REG_3D, 0, 0xFFFF, 0x2aaa},
// {"MIX", 0x13, 3, 0b11, 1}, // TODO: hidden
};
@@ -112,7 +103,7 @@ static int Rssi2DBm(uint16_t rssi) { return (rssi >> 1) - 160; }
static uint16_t GetRegMenuValue(uint8_t st) {
RegisterSpec s = registerSpecs[st];
return (BK4819_ReadRegister(s.num) >> s.offset) & s.maxValue;
return (BK4819_ReadRegister(s.num) >> s.offset) & s.mask;
}
static void SetRegMenuValue(uint8_t st, bool add) {
@@ -120,14 +111,14 @@ static void SetRegMenuValue(uint8_t st, bool add) {
RegisterSpec s = registerSpecs[st];
uint16_t reg = BK4819_ReadRegister(s.num);
if (add && v <= s.maxValue - s.inc) {
if (add && v <= s.mask - s.inc) {
v += s.inc;
} else if (!add && v >= 0 + s.inc) {
v -= s.inc;
}
// TODO: use max value for bits count in max value, or reset by additional
// mask in spec
reg &= ~(s.maxValue << s.offset);
reg &= ~(s.mask << s.offset);
BK4819_WriteRegister(s.num, reg | (v << s.offset));
redrawScreen = true;
}
@@ -135,21 +126,13 @@ static void SetRegMenuValue(uint8_t st, bool add) {
// GUI functions
static void PutPixel(uint8_t x, uint8_t y, bool fill) {
if (fill) {
gFrameBuffer[y >> 3][x] |= 1 << (y & 7);
} else {
gFrameBuffer[y >> 3][x] &= ~(1 << (y & 7));
}
UI_DrawPixelBuffer(gFrameBuffer, x, y, fill);
}
static void PutPixelStatus(uint8_t x, uint8_t y, bool fill) {
if (fill) {
gStatusLine[x] |= 1 << y;
} else {
gStatusLine[x] &= ~(1 << y);
}
UI_DrawPixelBuffer(&gStatusLine, x, y, fill);
}
static void DrawHLine(int sy, int ey, int nx, bool fill) {
static void DrawVLine(int sy, int ey, int nx, bool fill) {
for (int i = sy; i <= ey; i++) {
if (i < 56 && nx < 128) {
PutPixel(nx, i, fill);
@@ -215,35 +198,23 @@ static void ToggleAFBit(bool on) {
}
static void BackupRegisters() {
R30 = BK4819_ReadRegister(0x30);
R37 = BK4819_ReadRegister(0x37);
R3D = BK4819_ReadRegister(0x3D);
R43 = BK4819_ReadRegister(0x43);
R47 = BK4819_ReadRegister(0x47);
R48 = BK4819_ReadRegister(0x48);
R7E = BK4819_ReadRegister(0x7E);
R30 = BK4819_ReadRegister(BK4819_REG_30);
R37 = BK4819_ReadRegister(BK4819_REG_37);
R3D = BK4819_ReadRegister(BK4819_REG_3D);
R43 = BK4819_ReadRegister(BK4819_REG_43);
R47 = BK4819_ReadRegister(BK4819_REG_47);
R48 = BK4819_ReadRegister(BK4819_REG_48);
R7E = BK4819_ReadRegister(BK4819_REG_7E);
}
static void RestoreRegisters() {
BK4819_WriteRegister(0x30, R30);
BK4819_WriteRegister(0x37, R37);
BK4819_WriteRegister(0x3D, R3D);
BK4819_WriteRegister(0x43, R43);
BK4819_WriteRegister(0x47, R47);
BK4819_WriteRegister(0x48, R48);
BK4819_WriteRegister(0x7E, R7E);
}
static void SetModulation(ModulationType type) {
RestoreRegisters();
uint16_t reg = BK4819_ReadRegister(BK4819_REG_47);
reg &= ~(0b111 << 8);
BK4819_WriteRegister(BK4819_REG_47, reg | (modTypeReg47Values[type] << 8));
if (type == MOD_USB) {
BK4819_WriteRegister(0x3D, 0b0010101101000101);
BK4819_WriteRegister(BK4819_REG_37, 0x160F);
BK4819_WriteRegister(0x48, 0b0000001110101000);
}
BK4819_WriteRegister(BK4819_REG_30, R30);
BK4819_WriteRegister(BK4819_REG_37, R37);
BK4819_WriteRegister(BK4819_REG_3D, R3D);
BK4819_WriteRegister(BK4819_REG_43, R43);
BK4819_WriteRegister(BK4819_REG_47, R47);
BK4819_WriteRegister(BK4819_REG_48, R48);
BK4819_WriteRegister(BK4819_REG_7E, R7E);
}
static void ToggleAFDAC(bool on) {
@@ -259,8 +230,9 @@ static void SetF(uint32_t f) {
BK4819_SetFrequency(fMeasure);
BK4819_PickRXFilterPathBasedOnFrequency(fMeasure);
uint16_t reg = BK4819_ReadRegister(BK4819_REG_30);
BK4819_WriteRegister(BK4819_REG_30, 0);
BK4819_WriteRegister(BK4819_REG_30, 0xbff1);
BK4819_WriteRegister(BK4819_REG_30, reg);
}
// Spectrum related
@@ -294,12 +266,16 @@ static void DeInitSpectrum() {
isInitialized = false;
}
uint8_t GetBWRegValueForScan() { return scanStepBWRegValues[0]; }
uint8_t GetBWRegValueForScan() {
return scanStepBWRegValues[settings.scanStepIndex];
}
uint16_t GetRssi() {
SYSTICK_DelayUs(settings.scanDelay);
/* while ((BK4819_ReadRegister(0x63) & 0b11111111) >= 255)
; */
// SYSTICK_DelayUs(800);
// testing autodelay based on Glitch value
while ((BK4819_ReadRegister(0x63) & 0b11111111) >= 255) {
SYSTICK_DelayUs(100);
}
return BK4819_GetRSSI();
}
@@ -309,16 +285,16 @@ static void ToggleAudio(bool on) {
}
audioState = on;
if (on) {
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
} else {
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
}
}
static void ToggleRX(bool on) {
isListening = on;
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, on);
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, on);
ToggleAudio(on);
ToggleAFDAC(on);
@@ -361,7 +337,9 @@ static void RelaunchScan() {
InitScan();
ResetPeak();
ToggleRX(false);
#ifdef SPECTRUM_AUTOMATIC_SQUELCH
settings.rssiTriggerLevel = RSSI_MAX_VALUE;
#endif
preventKeypress = true;
scanInfo.rssiMin = RSSI_MAX_VALUE;
}
@@ -403,12 +381,26 @@ static void Measure() { rssiHistory[scanInfo.i] = scanInfo.rssi = GetRssi(); }
// Update things by keypress
static uint16_t dbm2rssi(int dBm)
{
return (dBm + 160)*2;
}
static void ClampRssiTriggerLevel()
{
settings.rssiTriggerLevel = clamp(settings.rssiTriggerLevel, dbm2rssi(settings.dbMin), dbm2rssi(settings.dbMax));
}
static void UpdateRssiTriggerLevel(bool inc) {
if (inc)
settings.rssiTriggerLevel += 2;
settings.rssiTriggerLevel += 2;
else
settings.rssiTriggerLevel -= 2;
settings.rssiTriggerLevel -= 2;
ClampRssiTriggerLevel();
redrawScreen = true;
redrawStatus = true;
}
static void UpdateDBMax(bool inc) {
@@ -419,8 +411,10 @@ static void UpdateDBMax(bool inc) {
} else {
return;
}
// RelaunchScan();
ClampRssiTriggerLevel();
redrawStatus = true;
redrawScreen = true;
SYSTEM_DelayMs(20);
}
@@ -435,7 +429,7 @@ static void UpdateScanStep(bool inc) {
settings.frequencyChangeStep = GetBW() >> 1;
RelaunchScan();
ResetBlacklist();
redrawStatus = true;
redrawScreen = true;
}
static void UpdateCurrentFreq(bool inc) {
@@ -475,12 +469,12 @@ static void UpdateFreqChangeStep(bool inc) {
}
static void ToggleModulation() {
if (settings.modulationType < MOD_USB) {
if (settings.modulationType < MODULATION_UKNOWN - 1) {
settings.modulationType++;
} else {
settings.modulationType = MOD_FM;
settings.modulationType = MODULATION_FM;
}
SetModulation(settings.modulationType);
RADIO_SetModulation(settings.modulationType);
redrawScreen = true;
}
@@ -496,9 +490,9 @@ static void ToggleListeningBW() {
static void ToggleBacklight() {
settings.backlightState = !settings.backlightState;
if (settings.backlightState) {
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
BACKLIGHT_TurnOn();
} else {
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
BACKLIGHT_TurnOff();
}
}
@@ -511,7 +505,7 @@ static void ToggleStepsCount() {
settings.frequencyChangeStep = GetBW() >> 1;
RelaunchScan();
ResetBlacklist();
redrawStatus = true;
redrawScreen = true;
}
static void ResetFreqInput() {
@@ -540,6 +534,8 @@ static void UpdateFreqInput(KEY_Code_t key) {
}
if (key == KEY_EXIT) {
freqInputIndex--;
if(freqInputDotIndex==freqInputIndex)
freqInputDotIndex = 0;
} else {
freqInputArr[freqInputIndex++] = key;
}
@@ -553,7 +549,7 @@ static void UpdateFreqInput(KEY_Code_t key) {
for (int i = 0; i < 10; ++i) {
if (i < freqInputIndex) {
digitKey = freqInputArr[i];
freqInputString[i] = digitKey <= KEY_9 ? '0' + digitKey : '.';
freqInputString[i] = digitKey <= KEY_9 ? '0' + digitKey-KEY_0 : '.';
} else {
freqInputString[i] = '-';
}
@@ -561,14 +557,14 @@ static void UpdateFreqInput(KEY_Code_t key) {
uint32_t base = 100000; // 1MHz in BK units
for (int i = dotIndex - 1; i >= 0; --i) {
tempFreq += freqInputArr[i] * base;
tempFreq += (freqInputArr[i]-KEY_0) * base;
base *= 10;
}
base = 10000; // 0.1MHz in BK units
if (dotIndex < freqInputIndex) {
for (int i = dotIndex + 1; i < freqInputIndex; ++i) {
tempFreq += freqInputArr[i] * base;
tempFreq += (freqInputArr[i]-KEY_0) * base;
base /= 10;
}
}
@@ -584,14 +580,15 @@ static void Blacklist() {
// Draw things
// applied x2 to prevent initial rounding
uint8_t Rssi2PX(uint16_t rssi, uint8_t pxMin, uint8_t pxMax) {
const int DB_MIN = settings.dbMin;
const int DB_MAX = settings.dbMax;
const int DB_MIN = settings.dbMin << 1;
const int DB_MAX = settings.dbMax << 1;
const int DB_RANGE = DB_MAX - DB_MIN;
const uint8_t PX_RANGE = pxMax - pxMin;
int dbm = clamp(Rssi2DBm(rssi), DB_MIN, DB_MAX);
int dbm = clamp(rssi - (160 << 1), DB_MIN, DB_MAX);
return ((dbm - DB_MIN) * PX_RANGE + DB_RANGE / 2) / DB_RANGE + pxMin;
}
@@ -604,68 +601,55 @@ static void DrawSpectrum() {
for (uint8_t x = 0; x < 128; ++x) {
uint16_t rssi = rssiHistory[x >> settings.stepsCount];
if (rssi != RSSI_MAX_VALUE) {
DrawHLine(Rssi2Y(rssi), DrawingEndY, x, true);
DrawVLine(Rssi2Y(rssi), DrawingEndY, x, true);
}
}
}
static void DrawStatus() {
#ifdef SPECTRUM_EXTRA_VALUES
sprintf(String, "%d/%d P:%d T:%d", settings.dbMin, settings.dbMax,
Rssi2DBm(peak.rssi), Rssi2DBm(settings.rssiTriggerLevel));
#else
sprintf(String, "%d/%d", settings.dbMin, settings.dbMax);
GUI_DisplaySmallest(String, 0, 2, true, true);
for (int i = 0; i < 4; i++) {
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[i], &gBatteryCurrent);
}
#endif
GUI_DisplaySmallest(String, 0, 1, true, true);
uint16_t Voltage;
uint8_t v = 0;
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryCheckCounter++ % 4], &gBatteryCurrent);
Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] +
uint16_t voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] +
gBatteryVoltages[3]) /
4;
4 * 760 / gBatteryCalibration[3];
if (gBatteryCalibration[5] < Voltage) {
v = 5;
} else if (gBatteryCalibration[4] < Voltage) {
v = 5;
} else if (gBatteryCalibration[3] < Voltage) {
v = 4;
} else if (gBatteryCalibration[2] < Voltage) {
v = 3;
} else if (gBatteryCalibration[1] < Voltage) {
v = 2;
} else if (gBatteryCalibration[0] < Voltage) {
v = 1;
}
unsigned perc = BATTERY_VoltsToPercent(voltage);
gStatusLine[127] = 0b01111110;
for (int i = 126; i >= 116; i--) {
gStatusLine[i] = 0b01000010;
// sprintf(String, "%d %d", voltage, perc);
// GUI_DisplaySmallest(String, 48, 1, true, true);
gStatusLine[116] = 0b00011100;
gStatusLine[117] = 0b00111110;
for (int i = 118; i <= 126; i++) {
gStatusLine[i] = 0b00100010;
}
v <<= 1;
for (int i = 125; i >= 116; i--) {
if (126 - i <= v) {
gStatusLine[i + 2] = 0b01111110;
for (unsigned i = 127; i >= 118; i--) {
if (127 - i <= (perc+5)*9/100) {
gStatusLine[i] = 0b00111110;
}
}
gStatusLine[117] = 0b01111110;
gStatusLine[116] = 0b00011000;
}
static void DrawF(uint32_t f) {
sprintf(String, "%u.%05u", f / 100000, f % 100000);
UI_PrintStringSmall(String, 0, 127, 0);
UI_PrintStringSmall(String, 8, 127, 0);
sprintf(String, "%s", modulationTypeOptions[settings.modulationType]);
GUI_DisplaySmallest(String, 115, 1, false, true);
sprintf(String, "%3s", gModulationStr[settings.modulationType]);
GUI_DisplaySmallest(String, 116, 1, false, true);
sprintf(String, "%s", bwOptions[settings.listenBw]);
GUI_DisplaySmallest(String, 107, 7, false, true);
GUI_DisplaySmallest(String, 108, 7, false, true);
}
static void DrawNums() {
sprintf(String, "P:%d", Rssi2DBm(peak.rssi));
GUI_DisplaySmallest(String, 32, 8, false, true);
sprintf(String, "T:%d", Rssi2DBm(settings.rssiTriggerLevel));
GUI_DisplaySmallest(String, 64, 8, false, true);
if (currentState == SPECTRUM) {
sprintf(String, "%ux", GetStepsCount());
@@ -675,7 +659,7 @@ static void DrawNums() {
}
if (IsCenterMode()) {
sprintf(String, "%u.%05u \xB1%u.%02uk", currentFreq / 100000,
sprintf(String, "%u.%05u \x7F%u.%02uk", currentFreq / 100000,
currentFreq % 100000, settings.frequencyChangeStep / 100,
settings.frequencyChangeStep % 100);
GUI_DisplaySmallest(String, 36, 49, false, true);
@@ -683,7 +667,7 @@ static void DrawNums() {
sprintf(String, "%u.%05u", GetFStart() / 100000, GetFStart() % 100000);
GUI_DisplaySmallest(String, 0, 49, false, true);
sprintf(String, "\xB1%u.%02uk", settings.frequencyChangeStep / 100,
sprintf(String, "\x7F%u.%02uk", settings.frequencyChangeStep / 100,
settings.frequencyChangeStep % 100);
GUI_DisplaySmallest(String, 48, 49, false, true);
@@ -715,19 +699,13 @@ static void DrawTicks() {
// center
if (IsCenterMode()) {
gFrameBuffer[5][62] = 0x80;
gFrameBuffer[5][63] = 0x80;
memset(gFrameBuffer[5] + 62, 0x80, 5);
gFrameBuffer[5][64] = 0xff;
gFrameBuffer[5][65] = 0x80;
gFrameBuffer[5][66] = 0x80;
} else {
memset(gFrameBuffer[5] + 1, 0x80, 3);
memset(gFrameBuffer[5] + 124, 0x80, 3);
gFrameBuffer[5][0] = 0xff;
gFrameBuffer[5][1] = 0x80;
gFrameBuffer[5][2] = 0x80;
gFrameBuffer[5][3] = 0x80;
gFrameBuffer[5][124] = 0x80;
gFrameBuffer[5][125] = 0x80;
gFrameBuffer[5][126] = 0x80;
gFrameBuffer[5][127] = 0xff;
}
}
@@ -894,8 +872,8 @@ void OnKeyDownStill(KEY_Code_t key) {
break;
case KEY_PTT:
// TODO: start transmit
/* BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, false);
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, true); */
/* BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); */
break;
case KEY_MENU:
if (menuState == ARRAY_SIZE(registerSpecs) - 1) {
@@ -966,8 +944,6 @@ static void RenderStill() {
GUI_DisplaySmallest(String, 4, 25, false, true);
sprintf(String, "%d dBm", dbm);
GUI_DisplaySmallest(String, 28, 25, false, true);
sprintf(String, "V: %d", scanInfo.rssi);
GUI_DisplaySmallest(String, 64, 25, false, true);
if (!monitorMode) {
uint8_t x = Rssi2PX(settings.rssiTriggerLevel, 0, 121);
@@ -1022,17 +998,18 @@ bool HandleUserInput() {
kbd.prev = kbd.current;
kbd.current = GetKey();
if (kbd.current == KEY_INVALID) {
kbd.counter = 0;
return true;
}
if (kbd.current == kbd.prev && kbd.counter <= 16) {
kbd.counter++;
if (kbd.current != KEY_INVALID && kbd.current == kbd.prev) {
if(kbd.counter < 16)
kbd.counter++;
else
kbd.counter-=3;
SYSTEM_DelayMs(20);
}
else {
kbd.counter = 0;
}
if (kbd.counter == 3 || kbd.counter > 16) {
if (kbd.counter == 3 || kbd.counter == 16) {
switch (currentState) {
case SPECTRUM:
OnKeyDown(kbd.current);
@@ -1107,7 +1084,6 @@ static void UpdateListening() {
}
if (currentState == SPECTRUM) {
SetF(fMeasure);
BK4819_WriteRegister(0x43, GetBWRegValueForScan());
Measure();
BK4819_WriteRegister(0x43, listenBWRegValues[settings.listenBw]);
@@ -1158,7 +1134,7 @@ static void Tick() {
void APP_RunSpectrum() {
// TX here coz it always? set to active VFO
currentFreq = initialFreq =
gEeprom.VfoInfo[gEeprom.TX_CHANNEL].pRX->Frequency;
gEeprom.VfoInfo[gEeprom.TX_VFO].pRX->Frequency;
BackupRegisters();
@@ -1167,8 +1143,8 @@ void APP_RunSpectrum() {
redrawScreen = false; // we will wait until scan done
newScanStart = true;
ToggleRX(false);
SetModulation(settings.modulationType = MOD_FM);
ToggleRX(true), ToggleRX(false); // hack to prevent noise when squelch off
RADIO_SetModulation(settings.modulationType = MODULATION_FM);
BK4819_SetFilterBandwidth(settings.listenBw = BK4819_FILTER_BW_WIDE, false);
RelaunchScan();

View File

@@ -99,12 +99,6 @@ typedef enum StepsCount {
STEPS_16,
} StepsCount;
typedef enum ModulationType {
MOD_FM,
MOD_AM,
MOD_USB,
} ModulationType;
typedef enum ScanStep {
S_STEP_0_01kHz,
S_STEP_0_1kHz,
@@ -122,18 +116,17 @@ typedef enum ScanStep {
} ScanStep;
typedef struct SpectrumSettings {
uint32_t frequencyChangeStep;
StepsCount stepsCount;
ScanStep scanStepIndex;
uint32_t frequencyChangeStep;
uint16_t scanDelay;
uint16_t rssiTriggerLevel;
bool backlightState;
BK4819_FilterBandwidth_t bw;
BK4819_FilterBandwidth_t listenBw;
ModulationType modulationType;
int dbMin;
int dbMax;
int dbMax;
ModulationMode_t modulationType;
bool backlightState;
} SpectrumSettings;
typedef struct KeyboardState {
@@ -150,19 +143,11 @@ typedef struct ScanInfo {
uint8_t measurementsCount;
} ScanInfo;
typedef struct RegisterSpec {
char *name;
uint8_t num;
uint8_t offset;
uint16_t maxValue;
uint16_t inc;
} RegisterSpec;
typedef struct PeakInfo {
uint16_t t;
uint16_t rssi;
uint8_t i;
uint32_t f;
uint8_t i;
} PeakInfo;
void APP_RunSpectrum(void);

View File

@@ -27,6 +27,7 @@
#include "bsp/dp32g030/dma.h"
#include "bsp/dp32g030/gpio.h"
#include "driver/aes.h"
#include "driver/backlight.h"
#include "driver/bk4819.h"
#include "driver/crc.h"
#include "driver/eeprom.h"
@@ -48,7 +49,7 @@ typedef struct {
} Header_t;
typedef struct {
uint8_t Padding[2];
uint8_t Padding[2];
uint16_t ID;
} Footer_t;
@@ -60,10 +61,10 @@ typedef struct {
typedef struct {
Header_t Header;
struct {
char Version[16];
bool bHasCustomAesKey;
bool bIsInLockScreen;
uint8_t Padding[2];
char Version[16];
bool bHasCustomAesKey;
bool bIsInLockScreen;
uint8_t Padding[2];
uint32_t Challenge[4];
} Data;
} REPLY_0514_t;
@@ -71,8 +72,8 @@ typedef struct {
typedef struct {
Header_t Header;
uint16_t Offset;
uint8_t Size;
uint8_t Padding;
uint8_t Size;
uint8_t Padding;
uint32_t Timestamp;
} CMD_051B_t;
@@ -80,19 +81,19 @@ typedef struct {
Header_t Header;
struct {
uint16_t Offset;
uint8_t Size;
uint8_t Padding;
uint8_t Data[128];
uint8_t Size;
uint8_t Padding;
uint8_t Data[128];
} Data;
} REPLY_051B_t;
typedef struct {
Header_t Header;
uint16_t Offset;
uint8_t Size;
bool bAllowPassword;
uint8_t Size;
bool bAllowPassword;
uint32_t Timestamp;
uint8_t Data[0];
uint8_t Data[0];
} CMD_051D_t;
typedef struct {
@@ -106,8 +107,8 @@ typedef struct {
Header_t Header;
struct {
uint16_t RSSI;
uint8_t ExNoiseIndicator;
uint8_t GlitchIndicator;
uint8_t ExNoiseIndicator;
uint8_t GlitchIndicator;
} Data;
} REPLY_0527_t;
@@ -137,7 +138,10 @@ typedef struct {
uint32_t Timestamp;
} CMD_052F_t;
static const uint8_t Obfuscation[16] = { 0x16, 0x6C, 0x14, 0xE6, 0x2E, 0x91, 0x0D, 0x40, 0x21, 0x35, 0xD5, 0x40, 0x13, 0x03, 0xE9, 0x80 };
static const uint8_t Obfuscation[16] =
{
0x16, 0x6C, 0x14, 0xE6, 0x2E, 0x91, 0x0D, 0x40, 0x21, 0x35, 0xD5, 0x40, 0x13, 0x03, 0xE9, 0x80
};
static union
{
@@ -157,12 +161,11 @@ static void SendReply(void *pReply, uint16_t Size)
{
Header_t Header;
Footer_t Footer;
uint8_t *pBytes;
uint16_t i;
if (bIsEncrypted)
{
pBytes = (uint8_t *)pReply;
uint8_t *pBytes = (uint8_t *)pReply;
unsigned int i;
for (i = 0; i < Size; i++)
pBytes[i] ^= Obfuscation[i % 16];
}
@@ -171,6 +174,7 @@ static void SendReply(void *pReply, uint16_t Size)
Header.Size = Size;
UART_Send(&Header, sizeof(Header));
UART_Send(pReply, Size);
if (bIsEncrypted)
{
Footer.Padding[0] = Obfuscation[(Size + 0) % 16] ^ 0xFF;
@@ -205,14 +209,16 @@ static void SendVersion(void)
static bool IsBadChallenge(const uint32_t *pKey, const uint32_t *pIn, const uint32_t *pResponse)
{
uint8_t i;
uint32_t IV[4];
unsigned int i;
uint32_t IV[4];
IV[0] = 0;
IV[1] = 0;
IV[2] = 0;
IV[3] = 0;
AES_Encrypt(pKey, IV, pIn, IV, true);
for (i = 0; i < 4; i++)
if (IV[i] != pResponse[i])
return true;
@@ -225,10 +231,16 @@ static void CMD_0514(const uint8_t *pBuffer)
const CMD_0514_t *pCmd = (const CMD_0514_t *)pBuffer;
Timestamp = pCmd->Timestamp;
#ifdef ENABLE_FMRADIO
gFmRadioCountdown_500ms = fm_radio_countdown_500ms;
#endif
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
gSerialConfigCountDown_500ms = 12; // 6 sec
// turn the LCD backlight off
BACKLIGHT_TurnOff();
SendVersion();
}
@@ -241,14 +253,17 @@ static void CMD_051B(const uint8_t *pBuffer)
if (pCmd->Timestamp != Timestamp)
return;
gSerialConfigCountDown_500ms = 12; // 6 sec
#ifdef ENABLE_FMRADIO
gFmRadioCountdown_500ms = fm_radio_countdown_500ms;
#endif
memset(&Reply, 0, sizeof(Reply));
Reply.Header.ID = 0x051C;
Reply.Header.ID = 0x051C;
Reply.Header.Size = pCmd->Size + 4;
Reply.Data.Offset = pCmd->Offset;
Reply.Data.Size = pCmd->Size;
Reply.Data.Size = pCmd->Size;
if (bHasCustomAesKey)
bLocked = gIsLocked;
@@ -269,11 +284,14 @@ static void CMD_051D(const uint8_t *pBuffer)
if (pCmd->Timestamp != Timestamp)
return;
gSerialConfigCountDown_500ms = 12; // 6 sec
bReloadEeprom = false;
#ifdef ENABLE_FMRADIO
gFmRadioCountdown_500ms = fm_radio_countdown_500ms;
#endif
Reply.Header.ID = 0x051E;
Reply.Header.Size = sizeof(Reply.Data);
Reply.Data.Offset = pCmd->Offset;
@@ -282,7 +300,7 @@ static void CMD_051D(const uint8_t *pBuffer)
if (!bIsLocked)
{
uint16_t i;
unsigned int i;
for (i = 0; i < (pCmd->Size / 8); i++)
{
const uint16_t Offset = pCmd->Offset + (i * 8U);
@@ -319,23 +337,25 @@ static void CMD_0529(void)
{
REPLY_0529_t Reply;
Reply.Header.ID = 0x52A;
Reply.Header.ID = 0x52A;
Reply.Header.Size = sizeof(Reply.Data);
// Original doesn't actually send current!
BOARD_ADC_GetBatteryInfo(&Reply.Data.Voltage, &Reply.Data.Current);
SendReply(&Reply, sizeof(Reply));
}
static void CMD_052D(const uint8_t *pBuffer)
{
const CMD_052D_t *pCmd = (const CMD_052D_t *)pBuffer;
REPLY_052D_t Reply;
bool bIsLocked;
REPLY_052D_t Reply;
bool bIsLocked;
#ifdef ENABLE_FMRADIO
gFmRadioCountdown_500ms = fm_radio_countdown_500ms;
#endif
Reply.Header.ID = 0x052E;
Reply.Header.ID = 0x052E;
Reply.Header.Size = sizeof(Reply.Data);
bIsLocked = bHasCustomAesKey;
@@ -373,14 +393,16 @@ static void CMD_052F(const uint8_t *pBuffer)
gEeprom.DUAL_WATCH = DUAL_WATCH_OFF;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gEeprom.RX_CHANNEL = 0;
gEeprom.RX_VFO = 0;
gEeprom.DTMF_SIDE_TONE = false;
gEeprom.VfoInfo[0].FrequencyReverse = false;
gEeprom.VfoInfo[0].pRX = &gEeprom.VfoInfo[0].freq_config_RX;
gEeprom.VfoInfo[0].pTX = &gEeprom.VfoInfo[0].freq_config_TX;
gEeprom.VfoInfo[0].TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF;
gEeprom.VfoInfo[0].DTMF_PTT_ID_TX_MODE = PTT_ID_OFF;
#ifdef ENABLE_DTMF_CALLING
gEeprom.VfoInfo[0].DTMF_DECODING_ENABLE = false;
#endif
#ifdef ENABLE_NOAA
gIsNoaaMode = false;
@@ -389,24 +411,25 @@ static void CMD_052F(const uint8_t *pBuffer)
if (gCurrentFunction == FUNCTION_POWER_SAVE)
FUNCTION_Select(FUNCTION_FOREGROUND);
gSerialConfigCountDown_500ms = 12; // 6 sec
Timestamp = pCmd->Timestamp;
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
// turn the LCD backlight off
BACKLIGHT_TurnOff();
SendVersion();
}
bool UART_IsCommandAvailable(void)
{
uint16_t DmaLength;
uint16_t CommandLength;
uint16_t Index;
uint16_t TailIndex;
uint16_t Size;
uint16_t CRC;
uint16_t i;
uint16_t CommandLength;
uint16_t DmaLength = DMA_CH0->ST & 0xFFFU;
DmaLength = DMA_CH0->ST & 0xFFFU;
while (1)
{
if (gUART_WriteIndex == DmaLength)
@@ -435,7 +458,7 @@ bool UART_IsCommandAvailable(void)
Index = DMA_INDEX(gUART_WriteIndex, 2);
Size = (UART_DMA_Buffer[DMA_INDEX(Index, 1)] << 8) | UART_DMA_Buffer[Index];
if ((Size + 8) > sizeof(UART_DMA_Buffer))
if ((Size + 8u) > sizeof(UART_DMA_Buffer))
{
gUART_WriteIndex = DmaLength;
return false;
@@ -480,9 +503,12 @@ bool UART_IsCommandAvailable(void)
bIsEncrypted = true;
if (bIsEncrypted)
for (i = 0; i < Size + 2; i++)
{
unsigned int i;
for (i = 0; i < (Size + 2u); i++)
UART_Command.Buffer[i] ^= Obfuscation[i % 16];
}
CRC = UART_Command.Buffer[Size] | (UART_Command.Buffer[Size + 1] << 8);
return (CRC_Calculate(UART_Command.Buffer, Size) != CRC) ? false : true;

81
audio.c
View File

@@ -76,7 +76,12 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
uint16_t ToneFrequency;
uint16_t Duration;
if (Beep != BEEP_880HZ_60MS_TRIPLE_BEEP && Beep != BEEP_500HZ_60MS_DOUBLE_BEEP && Beep != BEEP_440HZ_500MS && !gEeprom.BEEP_CONTROL)
if (Beep != BEEP_880HZ_60MS_TRIPLE_BEEP &&
Beep != BEEP_500HZ_60MS_DOUBLE_BEEP &&
Beep != BEEP_440HZ_500MS &&
Beep != BEEP_880HZ_200MS &&
Beep != BEEP_880HZ_500MS &&
!gEeprom.BEEP_CONTROL)
return;
#ifdef ENABLE_AIRCOPY
@@ -92,7 +97,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
ToneConfig = BK4819_ReadRegister(BK4819_REG_71);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode)
BK4819_RX_TurnOn();
@@ -123,6 +128,8 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
break;
case BEEP_880HZ_40MS_OPTIONAL:
case BEEP_880HZ_60MS_TRIPLE_BEEP:
case BEEP_880HZ_200MS:
case BEEP_880HZ_500MS:
ToneFrequency = 880;
break;
}
@@ -131,7 +138,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
SYSTEM_DelayMs(2);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
SYSTEM_DelayMs(60);
@@ -142,14 +149,14 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
SYSTEM_DelayMs(60);
BK4819_EnterTxMute();
SYSTEM_DelayMs(20);
[[fallthrough]];
case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL:
case BEEP_500HZ_60MS_DOUBLE_BEEP:
BK4819_ExitTxMute();
SYSTEM_DelayMs(60);
BK4819_EnterTxMute();
SYSTEM_DelayMs(20);
[[fallthrough]];
case BEEP_1KHZ_60MS_OPTIONAL:
BK4819_ExitTxMute();
Duration = 60;
@@ -161,7 +168,13 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
Duration = 40;
break;
case BEEP_880HZ_200MS:
BK4819_ExitTxMute();
Duration = 200;
break;
case BEEP_440HZ_500MS:
case BEEP_880HZ_500MS:
default:
BK4819_ExitTxMute();
Duration = 500;
@@ -172,9 +185,11 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
BK4819_EnterTxMute();
SYSTEM_DelayMs(20);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
gVoxResumeCountdown = 80;
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
#endif
SYSTEM_DelayMs(5);
BK4819_TurnsOffTones_TurnsOnRX();
@@ -182,7 +197,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
BK4819_WriteRegister(BK4819_REG_71, ToneConfig);
if (gEnableSpeaker)
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
@@ -245,7 +260,9 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
VoiceID += VOICE_ID_ENG_BASE;
}
if (gCurrentFunction == FUNCTION_RECEIVE || gCurrentFunction == FUNCTION_MONITOR)
if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING) // 1of11
BK4819_SetAF(BK4819_AF_MUTE);
#ifdef ENABLE_FMRADIO
@@ -253,8 +270,12 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
BK1080_Mute(true);
#endif
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gVoxResumeCountdown = 2000;
AUDIO_AudioPathOn();
#ifdef ENABLE_VOX
gVoxResumeCountdown = 2000;
#endif
SYSTEM_DelayMs(5);
AUDIO_PlayVoice(VoiceID);
@@ -265,13 +286,10 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
{
SYSTEM_DelayMs(Delay * 10);
if (gCurrentFunction == FUNCTION_RECEIVE || gCurrentFunction == FUNCTION_MONITOR)
{
if (gRxVfo->AM_mode)
BK4819_SetAF(BK4819_AF_AM);
else
BK4819_SetAF(BK4819_AF_OPEN);
}
if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING) // 1of11
RADIO_SetModulation(gRxVfo->Modulation);
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
@@ -279,11 +297,15 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
#endif
if (!gEnableSpeaker)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
gVoxResumeCountdown = 80;
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
#endif
return;
}
@@ -396,14 +418,19 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
gCountdownToPlayNextVoice_10ms = Delay;
gFlagPlayQueuedVoice = false;
gVoxResumeCountdown = 2000;
#ifdef ENABLE_VOX
gVoxResumeCountdown = 2000;
#endif
return;
}
}
if (gCurrentFunction == FUNCTION_RECEIVE || gCurrentFunction == FUNCTION_MONITOR)
BK4819_SetAF(gRxVfo->AM_mode ? BK4819_AF_AM : BK4819_AF_OPEN);
if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING) // 1of11
RADIO_SetModulation(gRxVfo->Modulation);
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
@@ -411,11 +438,15 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
#endif
if (!gEnableSpeaker)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
gVoxResumeCountdown = 80;
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
#endif
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
}
#endif

13
audio.h
View File

@@ -20,12 +20,17 @@
#include <stdbool.h>
#include <stdint.h>
#include "bsp/dp32g030/gpio.h"
#include "driver/gpio.h"
enum BEEP_Type_t
{
BEEP_NONE = 0,
BEEP_1KHZ_60MS_OPTIONAL,
BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL,
BEEP_440HZ_500MS,
BEEP_880HZ_200MS,
BEEP_880HZ_500MS,
BEEP_500HZ_60MS_DOUBLE_BEEP,
BEEP_440HZ_40MS_OPTIONAL,
BEEP_880HZ_40MS_OPTIONAL,
@@ -128,6 +133,14 @@ enum VOICE_ID_t
typedef enum VOICE_ID_t VOICE_ID_t;
static inline void AUDIO_AudioPathOn(void) {
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
}
static inline void AUDIO_AudioPathOff(void) {
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
}
#ifdef ENABLE_VOICE
extern VOICE_ID_t gVoiceID[8];
extern uint8_t gVoiceReadIndex;

204
bitmaps.c
View File

@@ -4,7 +4,7 @@
// all these images are on their right sides
// turn your monitor 90-deg anti-clockwise to see the images
const uint8_t BITMAP_PowerSave[8] =
const uint8_t BITMAP_POWERSAVE[8] =
{
#if 0
// "S"
@@ -29,6 +29,30 @@ const uint8_t BITMAP_PowerSave[8] =
#endif
};
const uint8_t BITMAP_TX[8] =
{ // "TX"
0b00000000,
0b00000001,
0b00000001,
0b01111111,
0b00000001,
0b00000001,
0b00000000,
0b00000000
};
const uint8_t BITMAP_RX[8] =
{ // "RX"
0b00000000,
0b01111111,
0b00001001,
0b00011001,
0b01100110,
0b00000000,
0b00000000,
0b00000000
};
const uint8_t BITMAP_BatteryLevel[2] =
{
0b01011101,
@@ -114,27 +138,29 @@ const uint8_t BITMAP_F_Key[6] =
0b01000001
};
const uint8_t BITMAP_VOX[18] =
{ // "VOX"
0b00000000,
0b00011111,
0b00100000,
0b01000000,
0b00100000,
0b00011111,
0b00000000,
0b00111110,
0b01000001,
0b01000001,
0b01000001,
0b00111110,
0b00000000,
0b01100011,
0b00010100,
0b00001000,
0b00010100,
0b01100011
};
#ifdef ENABLE_VOX
const uint8_t BITMAP_VOX[18] =
{ // "VOX"
0b00000000,
0b00011111,
0b00100000,
0b01000000,
0b00100000,
0b00011111,
0b00000000,
0b00111110,
0b01000001,
0b01000001,
0b01000001,
0b00111110,
0b00000000,
0b01100011,
0b00010100,
0b00001000,
0b00010100,
0b01100011
};
#endif
#if 0
const uint8_t BITMAP_WX[12] =
@@ -171,26 +197,27 @@ const uint8_t BITMAP_VOX[18] =
};
#endif
const uint8_t BITMAP_TDR1[12] =
{ // "DW"
0b00000000,
const uint8_t BITMAP_TDR1[15] =
{ // "DWR"
0b01111111,
0b01000001,
0b01000001,
0b01000001,
0b00111110,
0b00000000,
0b01111111,
0b00100000,
0b00011000,
0b00100000,
0b01111111
0b01111111,
0b00000000,
0b01111111,
0b00011001,
0b00101001,
0b01000110
};
const uint8_t BITMAP_TDR2[12] =
const uint8_t BITMAP_TDR2[9] =
{ // "><" .. DW on hold
0b00000000,
0b00000000,
0b00100010,
0b00110110,
0b00011100,
@@ -200,7 +227,6 @@ const uint8_t BITMAP_TDR2[12] =
0b00011100,
0b00110110,
0b00100010,
0b00000000
};
#ifdef ENABLE_VOICE
@@ -218,27 +244,8 @@ const uint8_t BITMAP_TDR2[12] =
};
#endif
#ifdef ENABLE_FMRADIO
const uint8_t BITMAP_FM[12] =
{ // "FM"
0b00000000,
0b01111111,
0b00001001,
0b00001001,
0b00001001,
0b00000001,
0b00000000,
0b01111111,
0b00000010,
0b00001100,
0b00000010,
0b01111111
};
#endif
#ifdef ENABLE_NOAA
const uint8_t BITMAP_NOAA[12] =
const uint8_t BITMAP_NOAA[11] =
{ // "NS"
0b00000000,
0b01111111,
@@ -246,33 +253,14 @@ const uint8_t BITMAP_TDR2[12] =
0b00001000,
0b00010000,
0b01111111,
0b00000000,
0b01000110,
0b01001001,
0b01001001,
0b01001001,
0b00110001
};
#endif
const uint8_t BITMAP_SC[12] =
{ // "SC"
0b00000000,
0b01000110,
0b01001001,
0b01001001,
0b01001001,
0b00110001,
0b00000000,
0b00111110,
0b01000001,
0b01000001,
0b01000001,
0b00100010
};
const uint8_t BITMAP_Antenna[5] =
{
0b00000011,
@@ -282,49 +270,7 @@ const uint8_t BITMAP_Antenna[5] =
0b00000011
};
const uint8_t BITMAP_AntennaLevel1[3] =
{
0b01100000,
0b01100000,
0b00000000
};
const uint8_t BITMAP_AntennaLevel2[3] =
{
0b01110000,
0b01110000,
0b00000000
};
const uint8_t BITMAP_AntennaLevel3[3] =
{
0b01111000,
0b01111000,
0b00000000
};
const uint8_t BITMAP_AntennaLevel4[3] =
{
0b01111100,
0b01111100,
0b00000000
};
const uint8_t BITMAP_AntennaLevel5[3] =
{
0b01111110,
0b01111110,
0b00000000
};
const uint8_t BITMAP_AntennaLevel6[3] =
{
0b01111111,
0b01111111,
0b00000000
};
const uint8_t BITMAP_CurrentIndicator[8] =
const uint8_t BITMAP_MARKER[8] =
{
0b11111111,
0b11111111,
@@ -359,17 +305,7 @@ const uint8_t BITMAP_VFO_NotDefault[8] =
0b00010100,
0b00001000
};
/*
const uint8_t BITMAP_ScanList[6] =
{ // diamond symbol
0b00001000,
0b00011100,
0b00111110,
0b00111110,
0b00011100,
0b00001000
};
*/
const uint8_t BITMAP_ScanList1[6] =
{ // 'I' symbol
0b00000000,
@@ -390,14 +326,12 @@ const uint8_t BITMAP_ScanList2[6] =
0b01000010
};
#ifdef ENABLE_COMPANDER
const uint8_t BITMAP_compand[6] =
{
0b00000000,
0b00111100,
0b01000010,
0b01000010,
0b01000010,
0b00100100
};
#endif
const uint8_t BITMAP_compand[6] =
{
0b00000000,
0b00111100,
0b01000010,
0b01000010,
0b01000010,
0b00100100
};

View File

@@ -4,14 +4,12 @@
#include <stdint.h>
extern const uint8_t BITMAP_PowerSave[8];
extern const uint8_t BITMAP_POWERSAVE[8];
extern const uint8_t BITMAP_TX[8];
extern const uint8_t BITMAP_RX[8];
extern const uint8_t BITMAP_BatteryLevel[2];
extern const uint8_t BITMAP_BatteryLevel1[17];
extern const uint8_t BITMAP_BatteryLevel2[17];
extern const uint8_t BITMAP_BatteryLevel3[17];
extern const uint8_t BITMAP_BatteryLevel4[17];
extern const uint8_t BITMAP_BatteryLevel5[17];
extern const uint8_t BITMAP_USB_C[9];
@@ -19,51 +17,34 @@ extern const uint8_t BITMAP_KeyLock[6];
extern const uint8_t BITMAP_F_Key[6];
extern const uint8_t BITMAP_VOX[18];
#if 0
extern const uint8_t BITMAP_WX[12];
#else
extern const uint8_t BITMAP_XB[12];
#ifdef ENABLE_VOX
extern const uint8_t BITMAP_VOX[18];
#endif
extern const uint8_t BITMAP_TDR1[12];
extern const uint8_t BITMAP_TDR2[12];
extern const uint8_t BITMAP_XB[12];
extern const uint8_t BITMAP_TDR1[15];
extern const uint8_t BITMAP_TDR2[9];
#ifdef ENABLE_VOICE
extern const uint8_t BITMAP_VoicePrompt[9];
#endif
#ifdef ENABLE_FMRADIO
extern const uint8_t BITMAP_FM[12];
#endif
#ifdef ENABLE_NOAA
extern const uint8_t BITMAP_NOAA[12];
extern const uint8_t BITMAP_NOAA[11];
#endif
extern const uint8_t BITMAP_SC[12];
extern const uint8_t BITMAP_Antenna[5];
extern const uint8_t BITMAP_AntennaLevel1[3];
extern const uint8_t BITMAP_AntennaLevel2[3];
extern const uint8_t BITMAP_AntennaLevel3[3];
extern const uint8_t BITMAP_AntennaLevel4[3];
extern const uint8_t BITMAP_AntennaLevel5[3];
extern const uint8_t BITMAP_AntennaLevel6[3];
extern const uint8_t BITMAP_CurrentIndicator[8];
extern const uint8_t BITMAP_MARKER[8];
extern const uint8_t BITMAP_VFO_Default[8];
extern const uint8_t BITMAP_VFO_NotDefault[8];
//extern const uint8_t BITMAP_ScanList[6];
extern const uint8_t BITMAP_ScanList1[6];
extern const uint8_t BITMAP_ScanList2[6];
#ifdef ENABLE_COMPANDER
extern const uint8_t BITMAP_compand[6];
#endif
extern const uint8_t BITMAP_compand[6];
#endif

90
board.c
View File

@@ -26,7 +26,7 @@
#include "bsp/dp32g030/saradc.h"
#include "bsp/dp32g030/syscon.h"
#include "driver/adc.h"
//#include "driver/backlight.h"
#include "driver/backlight.h"
#ifdef ENABLE_FMRADIO
#include "driver/bk1080.h"
#endif
@@ -94,8 +94,6 @@ void BOARD_GPIO_Init(void)
| GPIO_DIR_6_MASK // INPUT
);
GPIOB->DIR |= 0
// Back light
| GPIO_DIR_6_BITS_OUTPUT
// ST7565
| GPIO_DIR_9_BITS_OUTPUT
// ST7565 + SWD IO
@@ -183,14 +181,10 @@ void BOARD_PORTCON_Init(void)
// PORT B pin selection
PORTCON_PORTB_SEL0 &= ~(0
// Back light
| PORTCON_PORTB_SEL0_B6_MASK
// SPI0 SSN
| PORTCON_PORTB_SEL0_B7_MASK
);
PORTCON_PORTB_SEL0 |= 0
// Back light
| PORTCON_PORTB_SEL0_B6_BITS_GPIOB6
// SPI0 SSN
| PORTCON_PORTB_SEL0_B7_BITS_SPI0_SSN
;
@@ -508,8 +502,9 @@ void BOARD_Init(void)
{
BOARD_PORTCON_Init();
BOARD_GPIO_Init();
BACKLIGHT_InitHardware();
BOARD_ADC_Init();
ST7565_Init();
ST7565_Init(true);
#ifdef ENABLE_FMRADIO
BK1080_Init(0, false);
#endif
@@ -532,18 +527,25 @@ void BOARD_EEPROM_Init(void)
gEeprom.NOAA_AUTO_SCAN = (Data[3] < 2) ? Data[3] : false;
#endif
gEeprom.KEY_LOCK = (Data[4] < 2) ? Data[4] : false;
gEeprom.VOX_SWITCH = (Data[5] < 2) ? Data[5] : false;
gEeprom.VOX_LEVEL = (Data[6] < 10) ? Data[6] : 1;
#ifdef ENABLE_VOX
gEeprom.VOX_SWITCH = (Data[5] < 2) ? Data[5] : false;
gEeprom.VOX_LEVEL = (Data[6] < 10) ? Data[6] : 1;
#endif
gEeprom.MIC_SENSITIVITY = (Data[7] < 5) ? Data[7] : 4;
// 0E78..0E7F
EEPROM_ReadBuffer(0x0E78, Data, 8);
gEeprom.BACKLIGHT_MAX = (Data[0] & 0xF) <= 10 ? (Data[0] & 0xF) : 10;
gEeprom.BACKLIGHT_MIN = (Data[0] >> 4) < gEeprom.BACKLIGHT_MAX ? (Data[0] >> 4) : 0;
#ifdef ENABLE_BLMIN_TMP_OFF
gEeprom.BACKLIGHT_MIN_STAT = BLMIN_STAT_ON;
#endif
gEeprom.CHANNEL_DISPLAY_MODE = (Data[1] < 4) ? Data[1] : MDF_FREQUENCY; // 4 instead of 3 - extra display mode
gEeprom.CROSS_BAND_RX_TX = (Data[2] < 3) ? Data[2] : CROSS_BAND_OFF;
gEeprom.BATTERY_SAVE = (Data[3] < 5) ? Data[3] : 4;
gEeprom.DUAL_WATCH = (Data[4] < 3) ? Data[4] : DUAL_WATCH_CHAN_A;
gEeprom.BACKLIGHT = (Data[5] < ARRAY_SIZE(gSubMenu_BACKLIGHT)) ? Data[5] : 3;
gEeprom.TAIL_NOTE_ELIMINATION = (Data[6] < 2) ? Data[6] : false;
gEeprom.BACKLIGHT_TIME = (Data[5] < ARRAY_SIZE(gSubMenu_BACKLIGHT)) ? Data[5] : 3;
gEeprom.TAIL_TONE_ELIMINATION = (Data[6] < 2) ? Data[6] : false;
gEeprom.VFO_OPEN = (Data[7] < 2) ? Data[7] : true;
// 0E80..0E87
@@ -588,7 +590,8 @@ void BOARD_EEPROM_Init(void)
// 0E90..0E97
EEPROM_ReadBuffer(0x0E90, Data, 8);
gEeprom.BEEP_CONTROL = (Data[0] < 2) ? Data[0] : true;
gEeprom.BEEP_CONTROL = Data[0] & 1;
gEeprom.KEY_M_LONG_PRESS_ACTION = ((Data[0] >> 1) < ACTION_OPT_LEN) ? (Data[0] >> 1) : ACTION_OPT_NONE;
gEeprom.KEY_1_SHORT_PRESS_ACTION = (Data[1] < ACTION_OPT_LEN) ? Data[1] : ACTION_OPT_MONITOR;
gEeprom.KEY_1_LONG_PRESS_ACTION = (Data[2] < ACTION_OPT_LEN) ? Data[2] : ACTION_OPT_FLASHLIGHT;
gEeprom.KEY_2_SHORT_PRESS_ACTION = (Data[3] < ACTION_OPT_LEN) ? Data[3] : ACTION_OPT_SCAN;
@@ -614,15 +617,19 @@ void BOARD_EEPROM_Init(void)
#endif
gEeprom.ROGER = (Data[1] < 3) ? Data[1] : ROGER_MODE_OFF;
gEeprom.REPEATER_TAIL_TONE_ELIMINATION = (Data[2] < 11) ? Data[2] : 0;
gEeprom.TX_CHANNEL = (Data[3] < 2) ? Data[3] : 0;
gEeprom.TX_VFO = (Data[3] < 2) ? Data[3] : 0;
gEeprom.BATTERY_TYPE = (Data[4] < BATTERY_TYPE_UNKNOWN) ? Data[4] : BATTERY_TYPE_1600_MAH;
// 0ED0..0ED7
EEPROM_ReadBuffer(0x0ED0, Data, 8);
gEeprom.DTMF_SIDE_TONE = (Data[0] < 2) ? Data[0] : true;
#ifdef ENABLE_DTMF_CALLING
gEeprom.DTMF_SEPARATE_CODE = DTMF_ValidateCodes((char *)(Data + 1), 1) ? Data[1] : '*';
gEeprom.DTMF_GROUP_CALL_CODE = DTMF_ValidateCodes((char *)(Data + 2), 1) ? Data[2] : '#';
gEeprom.DTMF_DECODE_RESPONSE = (Data[3] < 4) ? Data[3] : 0;
gEeprom.DTMF_AUTO_RESET_TIME = (Data[4] < 61) ? Data[4] : 5;
gEeprom.DTMF_auto_reset_time = (Data[4] < 61) ? Data[4] : (Data[4] >= 5) ? Data[4] : 10;
#endif
gEeprom.DTMF_PRELOAD_TIME = (Data[5] < 101) ? Data[5] * 10 : 300;
gEeprom.DTMF_FIRST_CODE_PERSIST_TIME = (Data[6] < 101) ? Data[6] * 10 : 100;
gEeprom.DTMF_HASH_CODE_PERSIST_TIME = (Data[7] < 101) ? Data[7] * 10 : 100;
@@ -631,9 +638,11 @@ void BOARD_EEPROM_Init(void)
EEPROM_ReadBuffer(0x0ED8, Data, 8);
gEeprom.DTMF_CODE_PERSIST_TIME = (Data[0] < 101) ? Data[0] * 10 : 100;
gEeprom.DTMF_CODE_INTERVAL_TIME = (Data[1] < 101) ? Data[1] * 10 : 100;
#ifdef ENABLE_DTMF_CALLING
gEeprom.PERMIT_REMOTE_KILL = (Data[2] < 2) ? Data[2] : true;
// 0EE0..0EE7
EEPROM_ReadBuffer(0x0EE0, Data, 8);
if (DTMF_ValidateCodes((char *)Data, 8))
memmove(gEeprom.ANI_DTMF_ID, Data, 8);
@@ -642,7 +651,8 @@ void BOARD_EEPROM_Init(void)
memset(gEeprom.ANI_DTMF_ID, 0, sizeof(gEeprom.ANI_DTMF_ID));
strcpy(gEeprom.ANI_DTMF_ID, "123");
}
// 0EE8..0EEF
EEPROM_ReadBuffer(0x0EE8, Data, 8);
if (DTMF_ValidateCodes((char *)Data, 8))
@@ -662,7 +672,8 @@ void BOARD_EEPROM_Init(void)
memset(gEeprom.REVIVE_CODE, 0, sizeof(gEeprom.REVIVE_CODE));
strcpy(gEeprom.REVIVE_CODE, "9DCBA");
}
#endif
// 0EF8..0F07
EEPROM_ReadBuffer(0x0EF8, Data, 16);
if (DTMF_ValidateCodes((char *)Data, 16))
@@ -685,7 +696,8 @@ void BOARD_EEPROM_Init(void)
// 0F18..0F1F
EEPROM_ReadBuffer(0x0F18, Data, 8);
gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 2) ? Data[0] : false;
// gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 2) ? Data[0] : false;
gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 3) ? Data[0] : false; // we now have 'all' channel scan option
for (i = 0; i < 2; i++)
{
const unsigned int j = 1 + (i * 3);
@@ -696,22 +708,25 @@ void BOARD_EEPROM_Init(void)
// 0F40..0F47
EEPROM_ReadBuffer(0x0F40, Data, 8);
gSetting_F_LOCK = (Data[0] < 6) ? Data[0] : F_LOCK_OFF;
gSetting_F_LOCK = (Data[0] < F_LOCK_LEN) ? Data[0] : F_LOCK_DEF;
gSetting_350TX = (Data[1] < 2) ? Data[1] : false; // was true
#ifdef ENABLE_DTMF_CALLING
gSetting_KILLED = (Data[2] < 2) ? Data[2] : false;
#endif
gSetting_200TX = (Data[3] < 2) ? Data[3] : false;
gSetting_500TX = (Data[4] < 2) ? Data[4] : false;
gSetting_350EN = (Data[5] < 2) ? Data[5] : true;
gSetting_ScrambleEnable = (Data[6] < 2) ? Data[6] : true;
gSetting_TX_EN = (Data[7] & (1u << 0)) ? true : false;
//gSetting_TX_EN = (Data[7] & (1u << 0)) ? true : false;
gSetting_live_DTMF_decoder = (Data[7] & (1u << 1)) ? true : false;
gSetting_battery_text = (((Data[7] >> 2) & 3u) <= 2) ? (Data[7] >> 2) & 3: 2;
gSetting_battery_text = (((Data[7] >> 2) & 3u) <= 2) ? (Data[7] >> 2) & 3 : 2;
#ifdef ENABLE_AUDIO_BAR
gSetting_mic_bar = (Data[7] & (1u << 4)) ? true : false;
#endif
#ifdef ENABLE_AM_FIX
gSetting_AM_fix = (Data[7] & (1u << 5)) ? true : false;
#endif
gSetting_backlight_on_tx_rx = (Data[7] >> 6) & 3u;
if (!gEeprom.VFO_OPEN)
{
@@ -721,6 +736,13 @@ void BOARD_EEPROM_Init(void)
// 0D60..0E27
EEPROM_ReadBuffer(0x0D60, gMR_ChannelAttributes, sizeof(gMR_ChannelAttributes));
for(uint16_t i = 0; i < sizeof(gMR_ChannelAttributes); i++) {
ChannelAttributes_t *att = &gMR_ChannelAttributes[i];
if(att->__val == 0xff){
att->__val = 0;
att->band = 0xf;
}
}
// 0F30..0F3F
EEPROM_ReadBuffer(0x0F30, gCustomAesKey, sizeof(gCustomAesKey));
@@ -735,18 +757,18 @@ void BOARD_EEPROM_Init(void)
}
}
void BOARD_EEPROM_LoadMoreSettings(void)
void BOARD_EEPROM_LoadCalibration(void)
{
// uint8_t Mic;
EEPROM_ReadBuffer(0x1EC0, gEEPROM_1EC0_0, 8);
memmove(gEEPROM_1EC0_1, gEEPROM_1EC0_0, 8);
memmove(gEEPROM_1EC0_2, gEEPROM_1EC0_0, 8);
memmove(gEEPROM_1EC0_3, gEEPROM_1EC0_0, 8);
EEPROM_ReadBuffer(0x1EC0, gEEPROM_RSSI_CALIB[3], 8);
memcpy(gEEPROM_RSSI_CALIB[4], gEEPROM_RSSI_CALIB[3], 8);
memcpy(gEEPROM_RSSI_CALIB[5], gEEPROM_RSSI_CALIB[3], 8);
memcpy(gEEPROM_RSSI_CALIB[6], gEEPROM_RSSI_CALIB[3], 8);
// 8 * 16-bit values
EEPROM_ReadBuffer(0x1EC0, gEEPROM_RSSI_CALIB[0], 8);
EEPROM_ReadBuffer(0x1EC8, gEEPROM_RSSI_CALIB[1], 8);
EEPROM_ReadBuffer(0x1EC8, gEEPROM_RSSI_CALIB[0], 8);
memcpy(gEEPROM_RSSI_CALIB[1], gEEPROM_RSSI_CALIB[0], 8);
memcpy(gEEPROM_RSSI_CALIB[2], gEEPROM_RSSI_CALIB[0], 8);
EEPROM_ReadBuffer(0x1F40, gBatteryCalibration, 12);
if (gBatteryCalibration[0] >= 5000)
@@ -756,9 +778,11 @@ void BOARD_EEPROM_LoadMoreSettings(void)
}
gBatteryCalibration[5] = 2300;
EEPROM_ReadBuffer(0x1F50 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX1_THRESHOLD, 2);
EEPROM_ReadBuffer(0x1F68 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX0_THRESHOLD, 2);
#ifdef ENABLE_VOX
EEPROM_ReadBuffer(0x1F50 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX1_THRESHOLD, 2);
EEPROM_ReadBuffer(0x1F68 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX0_THRESHOLD, 2);
#endif
//EEPROM_ReadBuffer(0x1F80 + gEeprom.MIC_SENSITIVITY, &Mic, 1);
//gEeprom.MIC_SENSITIVITY_TUNING = (Mic < 32) ? Mic : 15;
gEeprom.MIC_SENSITIVITY_TUNING = gMicGain_dB2[gEeprom.MIC_SENSITIVITY];
@@ -861,7 +885,7 @@ void BOARD_FactoryReset(bool bIsAll)
if (bIsAll)
{
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_FIRST + BAND6_400MHz, BAND6_400MHz, 43350000);
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_FIRST + BAND6_400MHz, 43350000);
// set the first few memory channels
for (i = 0; i < ARRAY_SIZE(gDefaultFrequencyTable); i++)

View File

@@ -27,7 +27,7 @@ void BOARD_ADC_Init(void);
void BOARD_ADC_GetBatteryInfo(uint16_t *pVoltage, uint16_t *pCurrent);
void BOARD_Init(void);
void BOARD_EEPROM_Init(void);
void BOARD_EEPROM_LoadMoreSettings(void);
void BOARD_EEPROM_LoadCalibration(void);
uint32_t BOARD_fetchChannelFrequency(const int channel);
void BOARD_fetchChannelName(char *s, const int channel);
void BOARD_FactoryReset(bool bIsAll);

146
bsp/dp32g030/pwmplus.h Normal file
View File

@@ -0,0 +1,146 @@
#ifndef HARDWARE_DP32G030_PWMPLUS_H
#define HARDWARE_DP32G030_PWMPLUS_H
#define PWM_PLUS0_BASE_ADDR 0x400B4000U
//---------------
#define PWMPLUS_CFG 0x00U
#define PWMPLUS_CFG_COUNTER_EN_SHIFT 0U
#define PWMPLUS_CFG_COUNTER_EN_WIDTH 1U
#define PWMPLUS_CFG_COUNTER_EN_MASK (((1U << PWMPLUS_CFG_COUNTER_EN_WIDTH) - 1U) << PWMPLUS_CFG_COUNTER_EN_SHIFT)
#define PWMPLUS_CFG_COUNTER_EN_VALUE_ENABLE 1U
#define PWMPLUS_CFG_COUNTER_EN_BITS_ENABLE (PWMPLUS_CFG_COUNTER_EN_VALUE_ENABLE << PWMPLUS_CFG_COUNTER_EN_SHIFT)
#define PWMPLUS_CFG_CNT_TYPE_SHIFT 1U
#define PWMPLUS_CFG_CNT_REP_SHIFT 2U
#define PWMPLUS_CFG_CNT_REP_WIDTH 1U
#define PWMPLUS_CFG_CNT_REP_VALUE_ENABLE 1U
#define PWMPLUS_CFG_CNT_REP_BITS_ENABLE (PWMPLUS_CFG_CNT_REP_VALUE_ENABLE << PWMPLUS_CFG_CNT_REP_SHIFT)
#define PWMPLUS_CFG_OUT_MODE_SHIFT 3U
#define PWMPLUS_CFG_OUT_MODE_VALUE_ENABLE 1U
#define PWMPLUS_CFG_OUT_MODE_BITS_ENABLE (PWMPLUS_CFG_OUT_MODE_VALUE_ENABLE << PWMPLUS_CFG_OUT_MODE_SHIFT)
#define PWMPLUS_CFG_AUTO_RELOAD_SHIFT 8U
//---------------
#define PWMPLUS_GEN 0x04U
#define PWMPLUS_GEN_CH0_OE_SHIFT 24U
#define PWMPLUS_GEN_CH0_OE_WIDTH 1U
#define PWMPLUS_GEN_CH0_OE_VALUE_ENABLE 1U
#define PWMPLUS_GEN_CH0_OE_BITS_ENABLE (PWMPLUS_GEN_CH0_OE_VALUE_ENABLE << PWMPLUS_GEN_CH0_OE_SHIFT)
#define PWMPLUS_GEN_CH0_OUTINV_SHIFT 16U
#define PWMPLUS_GEN_CH0_OUTINV_WIDTH 1U
#define PWMPLUS_GEN_CH0_OUTINV_VALUE_ENABLE 1U
#define PWMPLUS_GEN_CH0_OUTINV_BITS_ENABLE (PWMPLUS_GEN_CH0_OUTINV_VALUE_ENABLE << PWMPLUS_GEN_CH0_OUTINV_SHIFT)
#define PWMPLUS_GEN_CH0_START_SHIFT 8U
#define PWMPLUS_GEN_CH0_START_WIDTH 1U
#define PWMPLUS_GEN_CH0_START_VALUE_ENABLE 1U
#define PWMPLUS_GEN_CH0_START_BITS_ENABLE (PWMPLUS_GEN_CH0_START_VALUE_ENABLE << PWMPLUS_GEN_CH0_START_SHIFT)
#define PWMPLUS_GEN_CH0_IDLE_SHIFT 0U
#define PWMPLUS_GEN_CH0_IDLE_WIDTH 1U
#define PWMPLUS_GEN_CH0_IDLE_VALUE_ENABLE 1U
#define PWMPLUS_GEN_CH0_IDLE_BITS_ENABLE (PWMPLUS_GEN_CH0_IDLE_VALUE_ENABLE << PWMPLUS_GEN_CH0_IDLE_SHIFT)
//---------------
#define PWMPLUS_CLKSRC 0x08U
#define PWMPLUS_BRAKE_CFG 0x0CU
#define PWMPLUS_MASK_LEV 0x10U
#define PWMPLUS_PERIOD 0x1CU
#define PWMPLUS_CH0_COMP 0x20U
#define PWMPLUS_CH1_COMP 0x24U
#define PWMPLUS_CH2_COMP 0x28U
#define PWMPLUS_CH0_DT 0x30U
#define PWMPLUS_CH1_DT 0x34U
#define PWMPLUS_CH2_DT 0x38U
#define PWMPLUS_TRIG_COMP 0x40U
#define PWMPLUS_TRIG_CFG 0x44U
#define PWMPLUS_IE 0x60U
#define PWMPLUS_IF 0x64U
#define PWMPLUS_SWLOAD 0x84U
#define PWMPLUS_MASK_EN 0x88
#define PWMPLUS_CNT_ST 0xE0
#define PWMPLUS_BRAKE_ST 0xE4
#define PWM_PLUS0_CFG_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CFG)
#define PWM_PLUS0_CFG (*(volatile uint32_t *)PWM_PLUS0_CFG_ADDR)
#define PWM_PLUS0_GEN_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_GEN)
#define PWM_PLUS0_GEN (*(volatile uint32_t *)PWM_PLUS0_GEN_ADDR)
#define PWM_PLUS0_CLKSRC_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CLKSRC)
#define PWM_PLUS0_CLKSRC (*(volatile uint32_t *)PWM_PLUS0_CLKSRC_ADDR)
#define PWM_PLUS0_BRAKE_CFG_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_BRAKE_CFG)
#define PWM_PLUS0_BRAKE_CFG (*(volatile uint32_t *)PWM_PLUS0_BRAKE_CFG_ADDR)
#define PWM_PLUS0_MASK_LEV_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_MASK_LEV)
#define PWM_PLUS0_MASK_LEV (*(volatile uint32_t *)PWM_PLUS0_MASK_LEV_ADDR)
#define PWM_PLUS0_PERIOD_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_PERIOD)
#define PWM_PLUS0_PERIOD (*(volatile uint32_t *)PWM_PLUS0_PERIOD_ADDR)
#define PWM_PLUS0_CH0_COMP_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH0_COMP)
#define PWM_PLUS0_CH0_COMP (*(volatile uint32_t *)PWM_PLUS0_CH0_COMP_ADDR)
#define PWM_PLUS0_CH1_COMP_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH1_COMP)
#define PWM_PLUS0_CH1_COMP (*(volatile uint32_t *)PWM_PLUS0_CH1_COMP_ADDR)
#define PWM_PLUS0_CH2_COMP_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH2_COMP)
#define PWM_PLUS0_CH2_COMP (*(volatile uint32_t *)PWM_PLUS0_CH2_COMP_ADDR)
#define PWM_PLUS0_CH0_DT_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH0_DT)
#define PWM_PLUS0_CH0_DT (*(volatile uint32_t *)PWM_PLUS0_CH0_DT_ADDR)
#define PWM_PLUS0_CH1_DT_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH1_DT)
#define PWM_PLUS0_CH1_DT (*(volatile uint32_t *)PWM_PLUS0_CH1_DT_ADDR)
#define PWM_PLUS0_CH2_DT_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH2_DT)
#define PWM_PLUS0_CH2_DT (*(volatile uint32_t *)PWM_PLUS0_CH2_DT_ADDR)
#define PWM_PLUS0_TRIG_COMP_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_TRIG_COMP)
#define PWM_PLUS0_TRIG_COMP (*(volatile uint32_t *)PWM_PLUS0_TRIG_COMP_ADDR)
#define PWM_PLUS0_TRIG_CFG_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_TRIG_CFG)
#define PWM_PLUS0_TRIG_CFG (*(volatile uint32_t *)PWM_PLUS0_TRIG_CFG_ADDR)
#define PWM_PLUS0_IE_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_IE)
#define PWM_PLUS0_IE (*(volatile uint32_t *)PWM_PLUS0_IE_ADDR)
#define PWM_PLUS0_IF_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_IF)
#define PWM_PLUS0_IF (*(volatile uint32_t *)PWM_PLUS0_IF_ADDR)
#define PWM_PLUS0_SWLOAD_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_SWLOAD)
#define PWM_PLUS0_SWLOAD (*(volatile uint32_t *)PWM_PLUS0_SWLOAD_ADDR)
#define PWM_PLUS0_MASK_EN_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_MASK_EN)
#define PWM_PLUS0_MASK_EN (*(volatile uint32_t *)PWM_PLUS0_MASK_EN_ADDR)
#define PWM_PLUS0_CNT_ST_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CNT_ST)
#define PWM_PLUS0_CNT_ST (*(volatile uint32_t *)PWM_PLUS0_CNT_ST_ADDR)
#define PWM_PLUS0_BRAKE_ST_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_BRAKE_ST)
#define PWM_PLUS0_BRAKE_ST (*(volatile uint32_t *)PWM_PLUS0_BRAKE_ST_ADDR)
#endif

4
compile-with-docker.bat Normal file
View File

@@ -0,0 +1,4 @@
@echo off
docker build -t uvk5 .
docker run --rm -v %CD%\compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make clean && make && cp firmware* compiled-firmware/"
pause

3
compile-with-docker.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
docker build -t uvk5 .
docker run --rm -v ${PWD}/compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make && cp firmware* compiled-firmware/"

2
dcs.c
View File

@@ -91,7 +91,7 @@ uint8_t DCS_GetCdcssCode(uint32_t Code)
return 0xFF;
}
uint8_t DCS_GetCtcssCode(uint16_t Code)
uint8_t DCS_GetCtcssCode(int Code)
{
unsigned int i;
uint8_t Result = 0xFF;

2
dcs.h
View File

@@ -39,7 +39,7 @@ extern const uint16_t DCS_Options[104];
uint32_t DCS_GetGolayCodeWord(DCS_CodeType_t CodeType, uint8_t Option);
uint8_t DCS_GetCdcssCode(uint32_t Code);
uint8_t DCS_GetCtcssCode(uint16_t Code);
uint8_t DCS_GetCtcssCode(int Code);
#endif

18
debugging.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef DEBUGGING_H
#define DEBUGGING_H
#include "driver/uart.h"
#include "string.h"
#include "external/printf/printf.h"
static inline void LogUart(char * str)
{
UART_Send(str, strlen(str));
}
#endif

View File

@@ -134,9 +134,9 @@ void ADC_Configure(ADC_Config_t *pAdc)
;
if (SARADC_IE == 0) {
NVIC_DisableIRQ(DP32_SARADC_IRQn);
NVIC_DisableIRQ((IRQn_Type)DP32_SARADC_IRQn);
} else {
NVIC_EnableIRQ(DP32_SARADC_IRQn);
NVIC_EnableIRQ((IRQn_Type)DP32_SARADC_IRQn);
}
}

View File

@@ -42,8 +42,10 @@ enum ADC_CH_MASK {
typedef enum ADC_CH_MASK ADC_CH_MASK;
typedef struct {
uint8_t CLK_SEL;
uint16_t EXTTRIG_SEL;
uint16_t IE_CHx_EOC;
ADC_CH_MASK CH_SEL;
uint8_t CLK_SEL;
uint8_t AVG;
uint8_t CONT;
uint8_t MEM_MODE;
@@ -51,13 +53,12 @@ typedef struct {
uint8_t SMPL_SETUP;
uint8_t SMPL_WIN;
uint8_t ADC_TRIG;
uint16_t EXTTRIG_SEL;
bool CALIB_OFFSET_VALID;
bool CALIB_KD_VALID;
uint8_t DMA_EN;
uint16_t IE_CHx_EOC;
uint8_t IE_FIFO_HFULL;
uint8_t IE_FIFO_FULL;
bool CALIB_OFFSET_VALID;
bool CALIB_KD_VALID;
uint8_t _pad[1];
} ADC_Config_t;
uint8_t ADC_GetChannelNumber(ADC_CH_MASK Mask);

View File

@@ -24,6 +24,8 @@ static void AES_Setup_ENC_CBC(bool IsDecrypt, const void *pKey, const void *pIv)
const uint32_t *pK = (const uint32_t *)pKey;
const uint32_t *pI = (const uint32_t *)pIv;
(void)IsDecrypt; // unused
AES_CR = (AES_CR & ~AES_CR_EN_MASK) | AES_CR_EN_BITS_DISABLE;
AES_CR = AES_CR_CHMOD_BITS_CBC;
AES_KEYR3 = pK[0];

View File

@@ -16,21 +16,54 @@
#include "backlight.h"
#include "bsp/dp32g030/gpio.h"
#include "bsp/dp32g030/pwmplus.h"
#include "bsp/dp32g030/portcon.h"
#include "driver/gpio.h"
#include "settings.h"
// this is decremented once every 500ms
uint16_t gBacklightCountdown = 0;
bool backlightOn;
void BACKLIGHT_InitHardware()
{
// 48MHz / 94 / 1024 ~ 500Hz
const uint32_t PWM_FREQUENCY_HZ = 1000;
PWM_PLUS0_CLKSRC |= ((48000000 / 1024 / PWM_FREQUENCY_HZ) << 16);
PWM_PLUS0_PERIOD = 1023;
PORTCON_PORTB_SEL0 &= ~(0
// Back light
| PORTCON_PORTB_SEL0_B6_MASK
);
PORTCON_PORTB_SEL0 |= 0
// Back light PWM
| PORTCON_PORTB_SEL0_B6_BITS_PWMP0_CH0
;
PWM_PLUS0_GEN =
PWMPLUS_GEN_CH0_OE_BITS_ENABLE |
PWMPLUS_GEN_CH0_OUTINV_BITS_ENABLE |
0;
PWM_PLUS0_CFG =
PWMPLUS_CFG_CNT_REP_BITS_ENABLE |
PWMPLUS_CFG_COUNTER_EN_BITS_ENABLE |
0;
}
void BACKLIGHT_TurnOn(void)
{
if (gEeprom.BACKLIGHT == 0)
if (gEeprom.BACKLIGHT_TIME != 0) {
backlightOn = true;
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX);
}
else {
BACKLIGHT_TurnOff();
return;
// turn the backlight ON
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
}
switch (gEeprom.BACKLIGHT)
switch (gEeprom.BACKLIGHT_TIME)
{
default:
case 1: // 5 sec
@@ -58,3 +91,32 @@ void BACKLIGHT_TurnOn(void)
gBacklightCountdown *= 2;
}
void BACKLIGHT_TurnOff()
{
#ifdef ENABLE_BLMIN_TMP_OFF
register uint8_t tmp;
if (gEeprom.BACKLIGHT_MIN_STAT == BLMIN_STAT_ON)
tmp = gEeprom.BACKLIGHT_MIN;
else
tmp = 0;
BACKLIGHT_SetBrightness(tmp);
#else
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MIN);
#endif
gBacklightCountdown = 0;
backlightOn = false;
}
bool BACKLIGHT_IsOn()
{
return backlightOn;
}
void BACKLIGHT_SetBrightness(uint8_t brigtness)
{
PWM_PLUS0_CH0_COMP = (1 << brigtness) - 1;
//PWM_PLUS0_SWLOAD = 1;
}

View File

@@ -18,10 +18,24 @@
#define DRIVER_BACKLIGHT_H
#include <stdint.h>
#include <stdbool.h>
extern uint16_t gBacklightCountdown;
extern uint8_t gBacklightBrightness;
void BACKLIGHT_TurnOn(void);
#ifdef ENABLE_BLMIN_TMP_OFF
typedef enum {
BLMIN_STAT_ON,
BLMIN_STAT_OFF,
BLMIN_STAT_UNKNOWN
} BLMIN_STAT_t;
#endif
void BACKLIGHT_InitHardware();
void BACKLIGHT_TurnOn();
void BACKLIGHT_TurnOff();
bool BACKLIGHT_IsOn();
void BACKLIGHT_SetBrightness(uint8_t brigtness);
#endif

View File

@@ -17,6 +17,19 @@
#ifndef BK4819_REGS_H
#define BK4819_REGS_H
typedef struct {
const char *name;
uint8_t num;
uint8_t offset;
uint16_t mask;
uint16_t inc;
} RegisterSpec;
static const RegisterSpec afcDisableRegSpec = {"AFC Disable", 0x73, 4, 1, 1};
static const RegisterSpec afOutRegSpec = {"AF Output Select", 0x47, 8, 0xF, 1};
static const RegisterSpec afDacGainRegSpec = {"AF DAC Gain", 0x48, 0, 0xF, 1};
enum BK4819_REGISTER_t {
BK4819_REG_00 = 0x00U,
BK4819_REG_02 = 0x02U,
@@ -52,6 +65,7 @@ enum BK4819_REGISTER_t {
BK4819_REG_3A = 0x3AU,
BK4819_REG_3B = 0x3BU,
BK4819_REG_3C = 0x3CU,
BK4819_REG_3D = 0x3DU,
BK4819_REG_3E = 0x3EU,
BK4819_REG_3F = 0x3FU,
BK4819_REG_43 = 0x43U,
@@ -95,13 +109,12 @@ enum BK4819_REGISTER_t {
typedef enum BK4819_REGISTER_t BK4819_REGISTER_t;
enum BK4819_GPIO_PIN_t {
BK4819_GPIO6_PIN2 = 0,
BK4819_GPIO5_PIN1 = 1,
BK4819_GPIO4_PIN32 = 2,
BK4819_GPIO3_PIN31 = 3,
BK4819_GPIO2_PIN30 = 4,
BK4819_GPIO1_PIN29_RED = 5,
BK4819_GPIO0_PIN28_GREEN = 6,
BK4819_GPIO0_PIN28_RX_ENABLE = 0,
BK4819_GPIO1_PIN29_PA_ENABLE = 1,
BK4819_GPIO3_PIN31_UHF_LNA = 3,
BK4819_GPIO4_PIN32_VHF_LNA = 4,
BK4819_GPIO5_PIN1_RED = 5,
BK4819_GPIO6_PIN2_GREEN = 6,
};
typedef enum BK4819_GPIO_PIN_t BK4819_GPIO_PIN_t;

File diff suppressed because it is too large Load Diff

View File

@@ -24,22 +24,22 @@
enum BK4819_AF_Type_t
{
BK4819_AF_MUTE = 0u,
BK4819_AF_OPEN = 1u,
BK4819_AF_ALAM = 2u,
BK4819_AF_BEEP = 3u,
BK4819_AF_UNKNOWN1 = 4u,
BK4819_AF_UNKNOWN2 = 5u,
BK4819_AF_CTCO = 6u,
BK4819_AF_AM = 7u,
BK4819_AF_FSKO = 8u,
BK4819_AF_UNKNOWN3 = 9u,
BK4819_AF_UNKNOWN4 = 10u,
BK4819_AF_UNKNOWN5 = 11u,
BK4819_AF_UNKNOWN6 = 12u,
BK4819_AF_UNKNOWN7 = 13u,
BK4819_AF_UNKNOWN8 = 14u,
BK4819_AF_UNKNOWN9 = 15u
BK4819_AF_MUTE = 0u, //
BK4819_AF_FM = 1u, // FM
BK4819_AF_ALAM = 2u, //
BK4819_AF_BEEP = 3u, //
BK4819_AF_BASEBAND1 = 4u, // RAW
BK4819_AF_BASEBAND2 = 5u, // USB
BK4819_AF_CTCO = 6u, // strange LF audio .. maybe the CTCSS LF line ?
BK4819_AF_AM = 7u, // AM
BK4819_AF_FSKO = 8u, // nothing
BK4819_AF_UNKNOWN3 = 9u, // BYP
BK4819_AF_UNKNOWN4 = 10u, // nothing at all
BK4819_AF_UNKNOWN5 = 11u, // distorted
BK4819_AF_UNKNOWN6 = 12u, // distorted
BK4819_AF_UNKNOWN7 = 13u, // interesting
BK4819_AF_UNKNOWN8 = 14u, // interesting
BK4819_AF_UNKNOWN9 = 15u // not a lot
};
typedef enum BK4819_AF_Type_t BK4819_AF_Type_t;
@@ -62,15 +62,18 @@ enum BK4819_CssScanResult_t
typedef enum BK4819_CssScanResult_t BK4819_CssScanResult_t;
// radio is asleep, not listening
extern bool gRxIdleMode;
void BK4819_Init(void);
uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register);
void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data);
void BK4819_SetRegValue(RegisterSpec s, uint16_t v);
void BK4819_WriteU8(uint8_t Data);
void BK4819_WriteU16(uint16_t Data);
void BK4819_SetAGC(uint8_t Value);
void BK4819_EnableAGC();
void BK4819_DisableAGC();
void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet);
@@ -102,6 +105,7 @@ void BK4819_DisableVox(void);
void BK4819_DisableDTMF(void);
void BK4819_EnableDTMF(void);
void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch);
void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay, const unsigned int level, const bool play_speaker);
void BK4819_EnterTxMute(void);
void BK4819_ExitTxMute(void);
void BK4819_Sleep(void);

View File

@@ -14,6 +14,9 @@
* limitations under the License.
*/
#include <stddef.h>
#include <string.h>
#include "driver/eeprom.h"
#include "driver/i2c.h"
#include "driver/system.h"
@@ -38,16 +41,22 @@ void EEPROM_ReadBuffer(uint16_t Address, void *pBuffer, uint8_t Size)
void EEPROM_WriteBuffer(uint16_t Address, const void *pBuffer)
{
I2C_Start();
if (pBuffer == NULL || Address >= 0x2000)
return;
I2C_Write(0xA0);
I2C_Write((Address >> 8) & 0xFF);
I2C_Write((Address >> 0) & 0xFF);
uint8_t buffer[8];
EEPROM_ReadBuffer(Address, buffer, 8);
if (memcmp(pBuffer, buffer, 8) != 0)
{
I2C_Start();
I2C_Write(0xA0);
I2C_Write((Address >> 8) & 0xFF);
I2C_Write((Address >> 0) & 0xFF);
I2C_WriteBuffer(pBuffer, 8);
I2C_Stop();
}
I2C_WriteBuffer(pBuffer, 8);
I2C_Stop();
SYSTEM_DelayMs(10);
// give the EEPROM time to burn the data in (apparently takes 5ms)
SYSTEM_DelayMs(8);
}

View File

@@ -14,25 +14,5 @@
* limitations under the License.
*/
#include "driver/gpio.h"
void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit)
{
*pReg &= ~(1U << Bit);
}
uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit)
{
return (*pReg >> Bit) & 1U;
}
void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit)
{
*pReg ^= 1U << Bit;
}
void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit)
{
*pReg |= 1U << Bit;
}

View File

@@ -58,10 +58,21 @@ enum GPIOC_PINS {
GPIOC_PIN_PTT = 5
};
void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit);
uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit);
void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit);
void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit);
static inline void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit) {
*pReg &= ~(1U << Bit);
}
static inline uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit) {
return (*pReg >> Bit) & 1U;
}
static inline void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit) {
*pReg ^= 1U << Bit;
}
static inline void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit) {
*pReg |= 1U << Bit;
}
#endif

View File

@@ -19,182 +19,141 @@
#include "driver/gpio.h"
#include "driver/keyboard.h"
#include "driver/systick.h"
#include "driver/i2c.h"
#include "misc.h"
KEY_Code_t gKeyReading0 = KEY_INVALID;
KEY_Code_t gKeyReading1 = KEY_INVALID;
uint16_t gDebounceCounter;
bool gWasFKeyPressed;
KEY_Code_t gKeyReading0 = KEY_INVALID;
KEY_Code_t gKeyReading1 = KEY_INVALID;
uint16_t gDebounceCounter = 0;
bool gWasFKeyPressed = false;
static const struct {
// Using a 16 bit pre-calculated shift and invert is cheaper
// than using 8 bit and doing shift and invert in code.
uint16_t set_to_zero_mask;
// We are very fortunate.
// The key and pin defines fit together in a single u8, making this very efficient
struct {
KEY_Code_t key : 5;
uint8_t pin : 3; // Pin 6 is highest
} pins[4];
} keyboard[] = {
{ // Zero row
// Set to zero to handle special case of nothing pulled down
.set_to_zero_mask = 0xffff,
.pins = {
{ .key = KEY_SIDE1, .pin = GPIOA_PIN_KEYBOARD_0},
{ .key = KEY_SIDE2, .pin = GPIOA_PIN_KEYBOARD_1},
// Duplicate to fill the array with valid values
{ .key = KEY_INVALID, .pin = GPIOA_PIN_KEYBOARD_1},
{ .key = KEY_INVALID, .pin = GPIOA_PIN_KEYBOARD_1}
}
},
{ // First row
.set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_4) & 0xffff,
.pins = {
{ .key = KEY_MENU, .pin = GPIOA_PIN_KEYBOARD_0},
{ .key = KEY_1, .pin = GPIOA_PIN_KEYBOARD_1},
{ .key = KEY_4, .pin = GPIOA_PIN_KEYBOARD_2},
{ .key = KEY_7, .pin = GPIOA_PIN_KEYBOARD_3}
}
},
{ // Second row
.set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_5) & 0xffff,
.pins = {
{ .key = KEY_UP, .pin = GPIOA_PIN_KEYBOARD_0},
{ .key = KEY_2 , .pin = GPIOA_PIN_KEYBOARD_1},
{ .key = KEY_5 , .pin = GPIOA_PIN_KEYBOARD_2},
{ .key = KEY_8 , .pin = GPIOA_PIN_KEYBOARD_3}
}
},
{ // Third row
.set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_6) & 0xffff,
.pins = {
{ .key = KEY_DOWN, .pin = GPIOA_PIN_KEYBOARD_0},
{ .key = KEY_3 , .pin = GPIOA_PIN_KEYBOARD_1},
{ .key = KEY_6 , .pin = GPIOA_PIN_KEYBOARD_2},
{ .key = KEY_9 , .pin = GPIOA_PIN_KEYBOARD_3}
}
},
{ // Fourth row
.set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_7) & 0xffff,
.pins = {
{ .key = KEY_EXIT, .pin = GPIOA_PIN_KEYBOARD_0},
{ .key = KEY_STAR, .pin = GPIOA_PIN_KEYBOARD_1},
{ .key = KEY_0 , .pin = GPIOA_PIN_KEYBOARD_2},
{ .key = KEY_F , .pin = GPIOA_PIN_KEYBOARD_3}
}
}
};
KEY_Code_t KEYBOARD_Poll(void)
{
KEY_Code_t Key = KEY_INVALID;
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_5);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_7);
SYSTICK_DelayUs(1);
// if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT))
// return KEY_PTT;
// *****************
// Keys connected to gnd
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0))
for (unsigned int j = 0; j < ARRAY_SIZE(keyboard); j++)
{
Key = KEY_SIDE1;
goto Bye;
uint16_t reg;
unsigned int i;
unsigned int k;
// Set all high
GPIOA->DATA |= 1u << GPIOA_PIN_KEYBOARD_4 |
1u << GPIOA_PIN_KEYBOARD_5 |
1u << GPIOA_PIN_KEYBOARD_6 |
1u << GPIOA_PIN_KEYBOARD_7;
// Clear the pin we are selecting
GPIOA->DATA &= keyboard[j].set_to_zero_mask;
// Read all 4 GPIO pins at once .. with de-noise, max of 8 sample loops
for (i = 0, k = 0, reg = 0; i < 3 && k < 8; i++, k++)
{
uint16_t reg2;
SYSTICK_DelayUs(1);
reg2 = GPIOA->DATA;
if (reg != reg2)
{ // noise
reg = reg2;
i = 0;
}
}
if (i < 3)
break; // noise is too bad
for (unsigned int i = 0; i < ARRAY_SIZE(keyboard[j].pins); i++)
{
const uint16_t mask = 1u << keyboard[j].pins[i].pin;
if (!(reg & mask))
{
Key = keyboard[j].pins[i].key;
break;
}
}
if (Key != KEY_INVALID)
break;
}
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))
{
Key = KEY_MENU;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1))
{
Key = KEY_1;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2))
{
Key = KEY_4;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3))
{
Key = KEY_7;
goto Bye;
}
// *****************
// Second row
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_5);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4);
SYSTICK_DelayUs(1);
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0))
{
Key = KEY_UP;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1))
{
Key = KEY_2;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2))
{
Key = KEY_5;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3))
{
Key = KEY_8;
goto Bye;
}
// *****************
// Third row
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_5);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4);
SYSTICK_DelayUs(1);
// Create I2C stop condition since we might have toggled I2C pins
// This leaves GPIOA_PIN_KEYBOARD_4 and GPIOA_PIN_KEYBOARD_5 high
I2C_Stop();
// Reset VOICE pins
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6);
SYSTICK_DelayUs(1);
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0))
{
Key = KEY_DOWN;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1))
{
Key = KEY_3;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2))
{
Key = KEY_6;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3))
{
Key = KEY_9;
goto Bye;
}
// *****************
// Fourth row
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_7);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6);
SYSTICK_DelayUs(1);
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0))
{
Key = KEY_EXIT;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1))
{
Key = KEY_STAR;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2))
{
Key = KEY_0;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3))
{
Key = KEY_F;
goto Bye;
}
// *****************
Bye:
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_5);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_7);
GPIO_SetBit( &GPIOA->DATA, GPIOA_PIN_KEYBOARD_7);
return Key;
}

View File

@@ -21,30 +21,29 @@
#include <stdbool.h>
#include <stdint.h>
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
enum KEY_Code_e {
KEY_0 = 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, // A
KEY_UP, // B
KEY_DOWN, // C
KEY_EXIT, // D
KEY_STAR, // *
KEY_F, // #
KEY_PTT, //
KEY_SIDE2, //
KEY_SIDE1, //
KEY_INVALID //
};
typedef enum KEY_Code_t KEY_Code_t;
typedef enum KEY_Code_e KEY_Code_t;
extern KEY_Code_t gKeyReading0;
extern KEY_Code_t gKeyReading1;

View File

@@ -93,9 +93,9 @@ void SPI_Configure(volatile SPI_Port_t *pPort, SPI_Config_t *pConfig)
if (pPort->IE) {
if (pPort == SPI0) {
NVIC_EnableIRQ(DP32_SPI0_IRQn);
NVIC_EnableIRQ((IRQn_Type)DP32_SPI0_IRQn);
} else if (pPort == SPI1) {
NVIC_EnableIRQ(DP32_SPI1_IRQn);
NVIC_EnableIRQ((IRQn_Type)DP32_SPI1_IRQn);
}
}
}

View File

@@ -82,10 +82,10 @@ void ST7565_BlitFullScreen(void)
}
#if 0
// whats the delay for I wonder ? .. it slows down scanning :(
// whats the delay for I wonder, it holds things up :(
SYSTEM_DelayMs(20);
#else
SYSTEM_DelayMs(1);
// SYSTEM_DelayMs(1);
#endif
SPI_ToggleMasterMode(&SPI0->CR, true);
@@ -119,7 +119,11 @@ void ST7565_FillScreen(uint8_t Value)
{
unsigned int i;
// reset some of the displays settings to try and overcome the radios hardware problem - RF corrupting the display
ST7565_Init(false);
SPI_ToggleMasterMode(&SPI0->CR, false);
for (i = 0; i < 8; i++)
{
unsigned int j;
@@ -132,58 +136,121 @@ void ST7565_FillScreen(uint8_t Value)
}
SPI_WaitForUndocumentedTxFifoStatusBit();
}
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_Init(void)
// Software reset
const uint8_t ST7565_CMD_SOFTWARE_RESET = 0xE2;
// Bias Select
// 1 0 1 0 0 0 1 BS
// Select bias setting 0=1/9; 1=1/7 (at 1/65 duty)
const uint8_t ST7565_CMD_BIAS_SELECT = 0xA2;
// COM Direction
// 1 1 0 0 MY - - -
// Set output direction of COM
// MY=1, reverse direction
// MY=0, normal direction
const uint8_t ST7565_CMD_COM_DIRECTION = 0xC0;
// SEG Direction
// 1 0 1 0 0 0 0 MX
// Set scan direction of SEG
// MX=1, reverse direction
// MX=0, normal direction
const uint8_t ST7565_CMD_SEG_DIRECTION = 0xA0;
// Inverse Display
// 1 0 1 0 0 1 1 INV
// INV =1, inverse display
// INV =0, normal display
const uint8_t ST7565_CMD_INVERSE_DISPLAY = 0xA6;
// All Pixel ON
// 1 0 1 0 0 1 0 AP
// AP=1, set all pixel ON
// AP=0, normal display
const uint8_t ST7565_CMD_ALL_PIXEL_ON = 0xA4;
// Regulation Ratio
// 0 0 1 0 0 RR2 RR1 RR0
// This instruction controls the regulation ratio of the built-in regulator
const uint8_t ST7565_CMD_REGULATION_RATIO = 0x20;
// Double command!! Set electronic volume (EV) level
// Send next: 0 0 EV5 EV4 EV3 EV2 EV1 EV0 contrast 0-63
const uint8_t ST7565_CMD_SET_EV = 0x81;
// Control built-in power circuit ON/OFF - 0 0 1 0 1 VB VR VF
// VB: Built-in Booster
// VR: Built-in Regulator
// VF: Built-in Follower
const uint8_t ST7565_CMD_POWER_CIRCUIT = 0x28;
// Set display start line 0-63
// 0 0 0 1 S5 S4 S3 S2 S1 S0
const uint8_t ST7565_CMD_SET_START_LINE = 0x40;
// Display ON/OFF
// 0 0 1 0 1 0 1 1 1 D
// D=1, display ON
// D=0, display OFF
const uint8_t ST7565_CMD_DISPLAY_ON_OFF = 0xAE;
uint8_t cmds[] = {
ST7565_CMD_BIAS_SELECT | 0, // Select bias setting: 1/9
ST7565_CMD_COM_DIRECTION | (0 << 3), // Set output direction of COM: normal
ST7565_CMD_SEG_DIRECTION | 1, // Set scan direction of SEG: reverse
ST7565_CMD_INVERSE_DISPLAY | 0, // Inverse Display: false
ST7565_CMD_ALL_PIXEL_ON | 0, // All Pixel ON: false - normal display
ST7565_CMD_REGULATION_RATIO | (4 << 0), // Regulation Ratio 5.0
ST7565_CMD_SET_EV, // Set contrast
31,
ST7565_CMD_POWER_CIRCUIT | 0b111, // Built-in power circuit ON/OFF: VB=1 VR=1 VF=1
ST7565_CMD_SET_START_LINE | 0, // Set Start Line: 0
ST7565_CMD_DISPLAY_ON_OFF | 1, // Display ON/OFF: ON
};
void ST7565_Init(const bool full)
{
SPI0_Init();
if (full) {
SPI0_Init();
ST7565_HardwareReset();
SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_WriteByte(ST7565_CMD_SOFTWARE_RESET); // software reset
SYSTEM_DelayMs(120);
}
else
SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_Configure_GPIO_B11();
for(uint8_t i = 0; i < 8; i++)
ST7565_WriteByte(cmds[i]);
SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_WriteByte(0xE2); // internal reset
SYSTEM_DelayMs(120);
ST7565_WriteByte(0xA2); // bias 9
ST7565_WriteByte(0xC0); // com normal
ST7565_WriteByte(0xA1); // reverse ?
if (full) {
ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b011); // VB=0 VR=1 VF=1
SYSTEM_DelayMs(1);
ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b110); // VB=1 VR=1 VF=0
SYSTEM_DelayMs(1);
ST7565_WriteByte(0xA6); // normal screen ?
// ST7565_WriteByte(0xA7); // inverse screen ?
for(uint8_t i = 0; i < 4; i++) // why 4 times?
ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b111); // VB=1 VR=1 VF=1
ST7565_WriteByte(0xA4); // all points normal
ST7565_WriteByte(0x24); //
ST7565_WriteByte(0x81); // volume first ?
ST7565_WriteByte(0x1f); // contrast ?
ST7565_WriteByte(0x2B); // power control ?
SYSTEM_DelayMs(1);
ST7565_WriteByte(0x2E); // power control ?
SYSTEM_DelayMs(1);
ST7565_WriteByte(0x2F); //
ST7565_WriteByte(0x2F); //
ST7565_WriteByte(0x2F); //
ST7565_WriteByte(0x2F); //
SYSTEM_DelayMs(40);
ST7565_WriteByte(0x40); // start line ?
ST7565_WriteByte(0xAF); // display on ?
SYSTEM_DelayMs(40);
}
ST7565_WriteByte(ST7565_CMD_SET_START_LINE | 0); // line 0
ST7565_WriteByte(ST7565_CMD_DISPLAY_ON_OFF | 1); // D=1
SPI_WaitForUndocumentedTxFifoStatusBit();
SPI_ToggleMasterMode(&SPI0->CR, true);
ST7565_FillScreen(0x00);
if (full)
ST7565_FillScreen(0x00);
}
void ST7565_Configure_GPIO_B11(void)
void ST7565_FixInterfGlitch(void)
{
SPI_ToggleMasterMode(&SPI0->CR, false);
for(uint8_t i = 0; i < ARRAY_SIZE(cmds); i++)
ST7565_WriteByte(cmds[i]);
SPI_WaitForUndocumentedTxFifoStatusBit();
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_HardwareReset(void)
{
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES);
SYSTEM_DelayMs(1);

View File

@@ -30,8 +30,9 @@ void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const u
void ST7565_BlitFullScreen(void);
void ST7565_BlitStatusLine(void);
void ST7565_FillScreen(uint8_t Value);
void ST7565_Init(void);
void ST7565_Configure_GPIO_B11(void);
void ST7565_Init(const bool full);
void ST7565_FixInterfGlitch(void);
void ST7565_HardwareReset(void);
void ST7565_SelectColumnAndLine(uint8_t Column, uint8_t Line);
void ST7565_WriteByte(uint8_t Value);

View File

@@ -29,26 +29,17 @@ void SYSTICK_Init(void)
void SYSTICK_DelayUs(uint32_t Delay)
{
uint32_t i;
uint32_t Start;
uint32_t Previous;
uint32_t Current;
uint32_t Delta;
i = 0;
Start = SysTick->LOAD;
Previous = SysTick->VAL;
const uint32_t ticks = Delay * gTickMultiplier;
uint32_t i = 0;
uint32_t Start = SysTick->LOAD;
uint32_t Previous = SysTick->VAL;
do {
do {
Current = SysTick->VAL;
} while (Current == Previous);
if (Current < Previous) {
Delta = -Current;
} else {
Delta = Start - Current;
}
i += Delta + Previous;
uint32_t Current;
uint32_t Delta;
while ((Current = SysTick->VAL) == Previous) {}
Delta = (Current < Previous) ? -Current : Start - Current;
i += Delta + Previous;
Previous = Current;
} while (i < Delay * gTickMultiplier);
} while (i < ticks);
}

View File

@@ -17,7 +17,7 @@ SECTIONS
.text :
{
. = ALIGN(4);
*(.text.isr) /* .text sections of code */
KEEP(*(.text.isr)) /* .text sections of code */
*(.text) /* .text sections of code */
*(.text*) /* .text* sections of code */
*(.rodata) /* .rodata sections */

698
font.c
View File

@@ -16,105 +16,204 @@
#include "font.h"
//const uint8_t gFontBig[95][16] =
const uint8_t gFontBig[95][15] =
// removed last and middle column which was all 0x00
// also the space char is not needed
const uint8_t gFontBig[95 - 1][16 - 2] =
{
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // ' '
{0x00, 0x00, 0x70, 0xF8, 0xF8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '!'
{0x00, 0x1E, 0x3E, 0x00, 0x00, 0x3E, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '"'
{0x40, 0xF0, 0xF0, 0x40, 0xF0, 0xF0, 0x40, 0x00, 0x04, 0x1F, 0x1F, 0x04, 0x1F, 0x1F, 0x04}, // , 0x00}, // '#'
{0x70, 0xF8, 0x88, 0x8F, 0x8F, 0x98, 0x30, 0x00, 0x06, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // , 0x00}, // '$'
{0x60, 0x60, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x00, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x18, 0x18}, // , 0x00}, // '%'
{0x00, 0xB0, 0xF8, 0xC8, 0x78, 0xB0, 0x80, 0x00, 0x0F, 0x1F, 0x10, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // '&'
{0x00, 0x20, 0x3E, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '''
{0x00, 0x00, 0xE0, 0xF0, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x00}, // , 0x00}, // '('
{0x00, 0x00, 0x08, 0x18, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x0F, 0x07, 0x00}, // , 0x00}, // ')'
{0x00, 0x40, 0xC0, 0x80, 0x80, 0xC0, 0x40, 0x00, 0x01, 0x05, 0x07, 0x03, 0x03, 0x07, 0x05}, // , 0x01}, // '*'
{0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x07, 0x07, 0x01, 0x01}, // , 0x00}, // '+'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x1C, 0x00, 0x00}, // , 0x00}, // ','
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, // , 0x00}, // '-'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, // , 0x00}, // '.'
{0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x00, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00}, // , 0x00}, // '/'
{0xF0, 0xF8, 0x08, 0x88, 0x48, 0xF8, 0xF0, 0x00, 0x0F, 0x1F, 0x12, 0x11, 0x10, 0x1F, 0x0F}, // , 0x00}, // '0'
{0x00, 0x20, 0x30, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10}, // , 0x00}, // '1'
{0x10, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x30, 0x00, 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x18}, // , 0x00}, // '2'
{0x10, 0x18, 0x88, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x08, 0x18, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '3'
{0x80, 0xC0, 0x60, 0x30, 0xF8, 0xF8, 0x00, 0x00, 0x01, 0x01, 0x01, 0x11, 0x1F, 0x1F, 0x11}, // , 0x00}, // '4'
{0xF8, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x08, 0x00, 0x08, 0x18, 0x10, 0x10, 0x11, 0x1F, 0x0F}, // , 0x00}, // '5'
{0xE0, 0xF0, 0x98, 0x88, 0x88, 0x80, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '6'
{0x18, 0x18, 0x08, 0x08, 0x88, 0xF8, 0x78, 0x00, 0x00, 0x00, 0x1E, 0x1F, 0x01, 0x00, 0x00}, // , 0x00}, // '7'
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '8'
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0xF0, 0x00, 0x00, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // '9'
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // , 0x00}, // ':'
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1C, 0x0C, 0x00, 0x00}, // , 0x00}, // ';'
{0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x10, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18, 0x10}, // , 0x00}, // '<'
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, // , 0x00}, // '='
{0x00, 0x10, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x10, 0x18, 0x0C, 0x06, 0x03, 0x01}, // , 0x00}, // '>'
{0x30, 0x38, 0x08, 0x88, 0xC8, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '?'
{0xE0, 0xF0, 0x10, 0x90, 0x90, 0xF0, 0xE0, 0x00, 0x0F, 0x1F, 0x10, 0x17, 0x17, 0x17, 0x03}, // , 0x00}, // '@'
{0xC0, 0xE0, 0x30, 0x18, 0x30, 0xE0, 0xC0, 0x00, 0x1F, 0x1F, 0x01, 0x01, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'A'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'B'
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x10, 0x18, 0x0C}, // , 0x00}, // 'C'
{0x08, 0xF8, 0xF8, 0x08, 0x18, 0xF0, 0xE0, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'D'
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x11, 0x18, 0x1C}, // , 0x00}, // 'E'
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x01, 0x00, 0x00}, // , 0x00}, // 'F'
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, 0x00, 0x07, 0x0F, 0x18, 0x11, 0x11, 0x0F, 0x1F}, // , 0x00}, // 'G'
{0xF8, 0xF8, 0x80, 0x80, 0x80, 0xF8, 0xF8, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'H'
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'I'
{0x00, 0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, 0x00, 0x0E, 0x1E, 0x10, 0x10, 0x1F, 0x0F, 0x00}, // , 0x00}, // 'J'
{0x08, 0xF8, 0xF8, 0x80, 0xE0, 0x78, 0x18, 0x00, 0x10, 0x1F, 0x1F, 0x01, 0x03, 0x1E, 0x1C}, // , 0x00}, // 'K'
{0x08, 0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x18, 0x1C}, // , 0x00}, // 'L'
{0xF8, 0xF8, 0x70, 0xE0, 0x70, 0xF8, 0xF8, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'M'
{0xF8, 0xF8, 0x70, 0xE0, 0xC0, 0xF8, 0xF8, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'N'
{0xE0, 0xF0, 0x18, 0x08, 0x18, 0xF0, 0xE0, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'O'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'P'
{0xF0, 0xF8, 0x08, 0x08, 0x08, 0xF8, 0xF0, 0x00, 0x0F, 0x1F, 0x10, 0x1C, 0x78, 0x7F, 0x4F}, // , 0x00}, // 'Q'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x10, 0x1F, 0x1F, 0x00, 0x01, 0x1F, 0x1E}, // , 0x00}, // 'R'
{0x30, 0x78, 0xC8, 0x88, 0x88, 0x38, 0x30, 0x00, 0x0C, 0x1C, 0x10, 0x10, 0x11, 0x1F, 0x0E}, // , 0x00}, // 'S'
{0x00, 0x38, 0x18, 0xF8, 0xF8, 0x18, 0x38, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'T'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'U'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x03, 0x07, 0x0C, 0x18, 0x0C, 0x07, 0x03}, // , 0x00}, // 'V'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x07, 0x1F, 0x1C, 0x07, 0x1C, 0x1F, 0x07}, // , 0x00}, // 'W'
{0x18, 0x78, 0xE0, 0x80, 0xE0, 0x78, 0x18, 0x00, 0x18, 0x1E, 0x07, 0x01, 0x07, 0x1E, 0x18}, // , 0x00}, // 'X'
{0x00, 0x78, 0xF8, 0x80, 0x80, 0xF8, 0x78, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'Y'
{0x38, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x38, 0x00, 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x1C}, // , 0x00}, // 'Z'
{0x00, 0x00, 0xF8, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x00}, // , 0x00}, // '['
{0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x1C}, // , 0x00}, // '"\'
{0x00, 0x00, 0x08, 0x08, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x00}, // , 0x00}, // ']'
{0x10, 0x18, 0x0E, 0x07, 0x0E, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '^'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, // , 0x40}, // '_'
{0x00, 0x00, 0x07, 0x0F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '`'
{0x00, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x00, 0x0E, 0x1F, 0x11, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'a'
{0x08, 0xF8, 0xF8, 0x40, 0xC0, 0x80, 0x00, 0x00, 0x10, 0x1F, 0x0F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'b'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x18, 0x08}, // , 0x00}, // 'c'
{0x00, 0x80, 0xC0, 0x48, 0xF8, 0xF8, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'd'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x0F, 0x1F, 0x11, 0x11, 0x11, 0x19, 0x09}, // , 0x00}, // 'e'
{0x80, 0xF0, 0xF8, 0x88, 0x18, 0x30, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'f'
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, 0x00, 0x4F, 0xDF, 0x90, 0x90, 0xFF, 0x7F, 0x00}, // , 0x00}, // 'g'
{0x08, 0xF8, 0xF8, 0x80, 0x40, 0xC0, 0x80, 0x00, 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'h'
{0x00, 0x00, 0x40, 0xD8, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'i'
{0x00, 0x00, 0x00, 0x00, 0x40, 0xD8, 0xD8, 0x00, 0x00, 0x60, 0xE0, 0x80, 0x80, 0xFF, 0x7F}, // , 0x00}, // 'j'
{0x08, 0xF8, 0xF8, 0x00, 0x80, 0xC0, 0x40, 0x00, 0x10, 0x1F, 0x1F, 0x03, 0x07, 0x1C, 0x18}, // , 0x00}, // 'k'
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'l'
{0xC0, 0xC0, 0xC0, 0x80, 0xC0, 0xC0, 0x80, 0x00, 0x1F, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'm'
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'n'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'o'
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x80, 0xFF, 0xFF, 0x90, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'p'
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, 0x00, 0x0F, 0x1F, 0x10, 0x90, 0xFF, 0xFF, 0x80}, // , 0x00}, // 'q'
{0x40, 0xC0, 0x80, 0xC0, 0x40, 0xC0, 0x80, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x01}, // , 0x00}, // 'r'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x08, 0x19, 0x13, 0x12, 0x16, 0x1C, 0x08}, // , 0x00}, // 's'
{0x40, 0x40, 0xF0, 0xF8, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x18, 0x08}, // , 0x00}, // 't'
{0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'u'
{0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x07, 0x0F, 0x18, 0x18, 0x0F, 0x07}, // , 0x00}, // 'v'
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x0F, 0x1F, 0x18, 0x0E, 0x18, 0x1F, 0x0F}, // , 0x00}, // 'w'
{0x40, 0xC0, 0x80, 0x00, 0x80, 0xC0, 0x40, 0x00, 0x10, 0x18, 0x0F, 0x07, 0x0F, 0x18, 0x10}, // , 0x00}, // 'x'
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x8F, 0x9F, 0x90, 0x90, 0xD0, 0x7F, 0x3F}, // , 0x00}, // 'y'
{0xC0, 0xC0, 0x40, 0x40, 0xC0, 0xC0, 0x40, 0x00, 0x18, 0x1C, 0x16, 0x13, 0x11, 0x18, 0x18}, // , 0x00}, // 'z'
{0x00, 0x80, 0x80, 0xF0, 0x78, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10}, // , 0x00}, // '{'
{0x00, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00}, // , 0x00}, // '|'
{0x00, 0x08, 0x08, 0x78, 0xF0, 0x80, 0x80, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x0F, 0x00, 0x00}, // , 0x00}, // '}'
{0x10, 0x18, 0x08, 0x18, 0x10, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // , 0x00} // '->'
};
#if 0
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // ' '
{0x00, 0x00, 0x70, 0xF8, 0xF8, 0x70, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '!'
{0x00, 0x1E, 0x3E, 0x00, 0x00, 0x3E, 0x1E, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '"'
{0x40, 0xF0, 0xF0, 0x40, 0xF0, 0xF0, 0x40, /*0x00,*/ 0x04, 0x1F, 0x1F, 0x04, 0x1F, 0x1F, 0x04}, // , 0x00}, // '#'
{0x70, 0xF8, 0x88, 0x8F, 0x8F, 0x98, 0x30, /*0x00,*/ 0x06, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // , 0x00}, // '$'
{0x60, 0x60, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x18, 0x18}, // , 0x00}, // '%'
{0x00, 0xB0, 0xF8, 0xC8, 0x78, 0xB0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // '&'
{0x00, 0x20, 0x3E, 0x1E, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '''
{0x00, 0x00, 0xE0, 0xF0, 0x18, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x00}, // , 0x00}, // '('
{0x00, 0x00, 0x08, 0x18, 0xF0, 0xE0, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x18, 0x0F, 0x07, 0x00}, // , 0x00}, // ')'
{0x00, 0x40, 0xC0, 0x80, 0x80, 0xC0, 0x40, /*0x00,*/ 0x01, 0x05, 0x07, 0x03, 0x03, 0x07, 0x05}, // , 0x01}, // '*'
{0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, /*0x00,*/ 0x00, 0x01, 0x01, 0x07, 0x07, 0x01, 0x01}, // , 0x00}, // '+'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x20, 0x3C, 0x1C, 0x00, 0x00}, // , 0x00}, // ','
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, // , 0x00}, // '-'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, // , 0x00}, // '.'
{0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00}, // , 0x00}, // '/'
{0xF0, 0xF8, 0x08, 0x88, 0x48, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x12, 0x11, 0x10, 0x1F, 0x0F}, // , 0x00}, // '0'
{0x00, 0x20, 0x30, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10}, // , 0x00}, // '1'
{0x10, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x18}, // , 0x00}, // '2'
{0x10, 0x18, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '3'
{0x80, 0xC0, 0x60, 0x30, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x11, 0x1F, 0x1F, 0x11}, // , 0x00}, // '4'
{0xF8, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x08, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x11, 0x1F, 0x0F}, // , 0x00}, // '5'
{0xE0, 0xF0, 0x98, 0x88, 0x88, 0x80, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '6'
{0x18, 0x18, 0x08, 0x08, 0x88, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x1E, 0x1F, 0x01, 0x00, 0x00}, // , 0x00}, // '7'
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '8'
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0xF0, /*0x00,*/ 0x00, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // '9'
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // , 0x00}, // ':'
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1C, 0x0C, 0x00, 0x00}, // , 0x00}, // ';'
{0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x10, /*0x00,*/ 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18, 0x10}, // , 0x00}, // '<'
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, // , 0x00}, // '='
{0x00, 0x10, 0x30, 0x60, 0xC0, 0x80, 0x00, /*0x00,*/ 0x00, 0x10, 0x18, 0x0C, 0x06, 0x03, 0x01}, // , 0x00}, // '>'
{0x30, 0x38, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '?'
{0xE0, 0xF0, 0x10, 0x90, 0x90, 0xF0, 0xE0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x17, 0x17, 0x17, 0x03}, // , 0x00}, // '@'
{0xC0, 0xE0, 0x30, 0x18, 0x30, 0xE0, 0xC0, /*0x00,*/ 0x1F, 0x1F, 0x01, 0x01, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'A'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'B'
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x10, 0x18, 0x0C}, // , 0x00}, // 'C'
{0x08, 0xF8, 0xF8, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'D'
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x11, 0x18, 0x1C}, // , 0x00}, // 'E'
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x01, 0x00, 0x00}, // , 0x00}, // 'F'
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x11, 0x11, 0x0F, 0x1F}, // , 0x00}, // 'G'
{0xF8, 0xF8, 0x80, 0x80, 0x80, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'H'
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'I'
{0x00, 0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, /*0x00,*/ 0x0E, 0x1E, 0x10, 0x10, 0x1F, 0x0F, 0x00}, // , 0x00}, // 'J'
{0x08, 0xF8, 0xF8, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x01, 0x03, 0x1E, 0x1C}, // , 0x00}, // 'K'
{0x08, 0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x18, 0x1C}, // , 0x00}, // 'L'
{0xF8, 0xF8, 0x70, 0xE0, 0x70, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'M'
{0xF8, 0xF8, 0x70, 0xE0, 0xC0, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'N'
{0xE0, 0xF0, 0x18, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'O'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'P'
{0xF0, 0xF8, 0x08, 0x08, 0x08, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x1C, 0x78, 0x7F, 0x4F}, // , 0x00}, // 'Q'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x01, 0x1F, 0x1E}, // , 0x00}, // 'R'
{0x30, 0x78, 0xC8, 0x88, 0x88, 0x38, 0x30, /*0x00,*/ 0x0C, 0x1C, 0x10, 0x10, 0x11, 0x1F, 0x0E}, // , 0x00}, // 'S'
{0x00, 0x38, 0x18, 0xF8, 0xF8, 0x18, 0x38, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'T'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'U'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x03, 0x07, 0x0C, 0x18, 0x0C, 0x07, 0x03}, // , 0x00}, // 'V'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x07, 0x1F, 0x1C, 0x07, 0x1C, 0x1F, 0x07}, // , 0x00}, // 'W'
{0x18, 0x78, 0xE0, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x18, 0x1E, 0x07, 0x01, 0x07, 0x1E, 0x18}, // , 0x00}, // 'X'
{0x00, 0x78, 0xF8, 0x80, 0x80, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'Y'
{0x38, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x38, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x1C}, // , 0x00}, // 'Z'
{0x00, 0x00, 0xF8, 0xF8, 0x08, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x00}, // , 0x00}, // '['
{0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x1C}, // , 0x00}, // '"\'
{0x00, 0x00, 0x08, 0x08, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x00}, // , 0x00}, // ']'
{0x10, 0x18, 0x0E, 0x07, 0x0E, 0x18, 0x10, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '^'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, // , 0x40}, // '_'
{0x00, 0x00, 0x07, 0x0F, 0x08, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '`'
{0x00, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x0E, 0x1F, 0x11, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'a'
{0x08, 0xF8, 0xF8, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x10, 0x1F, 0x0F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'b'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x18, 0x08}, // , 0x00}, // 'c'
{0x00, 0x80, 0xC0, 0x48, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'd'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x11, 0x11, 0x11, 0x19, 0x09}, // , 0x00}, // 'e'
{0x80, 0xF0, 0xF8, 0x88, 0x18, 0x30, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'f'
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x4F, 0xDF, 0x90, 0x90, 0xFF, 0x7F, 0x00}, // , 0x00}, // 'g'
{0x08, 0xF8, 0xF8, 0x80, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'h'
{0x00, 0x00, 0x40, 0xD8, 0xD8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'i'
{0x00, 0x00, 0x00, 0x00, 0x40, 0xD8, 0xD8, /*0x00,*/ 0x00, 0x60, 0xE0, 0x80, 0x80, 0xFF, 0x7F}, // , 0x00}, // 'j'
{0x08, 0xF8, 0xF8, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x03, 0x07, 0x1C, 0x18}, // , 0x00}, // 'k'
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'l'
{0xC0, 0xC0, 0xC0, 0x80, 0xC0, 0xC0, 0x80, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'm'
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'n'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'o'
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x80, 0xFF, 0xFF, 0x90, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'p'
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x90, 0xFF, 0xFF, 0x80}, // , 0x00}, // 'q'
{0x40, 0xC0, 0x80, 0xC0, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x01}, // , 0x00}, // 'r'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x08, 0x19, 0x13, 0x12, 0x16, 0x1C, 0x08}, // , 0x00}, // 's'
{0x40, 0x40, 0xF0, 0xF8, 0x40, 0x40, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x18, 0x08}, // , 0x00}, // 't'
{0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'u'
{0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x00, 0x07, 0x0F, 0x18, 0x18, 0x0F, 0x07}, // , 0x00}, // 'v'
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x0F, 0x1F, 0x18, 0x0E, 0x18, 0x1F, 0x0F}, // , 0x00}, // 'w'
{0x40, 0xC0, 0x80, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x18, 0x0F, 0x07, 0x0F, 0x18, 0x10}, // , 0x00}, // 'x'
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x8F, 0x9F, 0x90, 0x90, 0xD0, 0x7F, 0x3F}, // , 0x00}, // 'y'
{0xC0, 0xC0, 0x40, 0x40, 0xC0, 0xC0, 0x40, /*0x00,*/ 0x18, 0x1C, 0x16, 0x13, 0x11, 0x18, 0x18}, // , 0x00}, // 'z'
{0x00, 0x80, 0x80, 0xF0, 0x78, 0x08, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10}, // , 0x00}, // '{'
{0x00, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00}, // , 0x00}, // '|'
{0x00, 0x08, 0x08, 0x78, 0xF0, 0x80, 0x80, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x0F, 0x00, 0x00}, // , 0x00}, // '}'
{0x10, 0x18, 0x08, 0x18, 0x10, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // , 0x00} // '->'
#else
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' '
{0x00, 0x00, 0x00, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '!'
{0x00, 0x0F, 0x1F, 0x00, 0x00, 0x1F, 0x0F, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '"'
{0x20, 0xF8, 0xF8, 0x20, 0xF8, 0xF8, 0x20, /*0x00,*/ 0x02, 0x0F, 0x0F, 0x02, 0x0F, 0x0F, 0x02}, // '#'
{0x70, 0xF8, 0x88, 0x8E, 0x8E, 0x98, 0x10, /*0x00,*/ 0x04, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // '$'
{0x30, 0x30, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x0C, 0x0C}, // '%'
{0x80, 0xD8, 0x7C, 0xE4, 0xBC, 0xD8, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x07, 0x0F, 0x08}, // '&'
{0x00, 0x10, 0x1F, 0x0F, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '''
{0x00, 0x00, 0xF0, 0xF8, 0x0C, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x03, 0x07, 0x0C, 0x08, 0x00}, // '('
{0x00, 0x00, 0x04, 0x0C, 0xF8, 0xF0, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0C, 0x07, 0x03, 0x00}, // ')'
{0x00, 0x80, 0xA0, 0xE0, 0xC0, 0xE0, 0xA0, /*0x80,*/ 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x02}, // '*'
{0x00, 0x80, 0x80, 0xE0, 0xE0, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00}, // '+'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1E, 0x0E, 0x00, 0x00}, // ','
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '-'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // '.'
{0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00}, // '/'
{0xF8, 0xFC, 0x84, 0xC4, 0x64, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x09, 0x08, 0x08, 0x0F, 0x07}, // '0'
{0x00, 0x10, 0x18, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08}, // '1'
{0x18, 0x1C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // '2'
{0x18, 0x1C, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '3'
{0x80, 0xC0, 0x60, 0x30, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x0F}, // '4'
{0x7C, 0x7C, 0x44, 0x44, 0x44, 0xC4, 0x84, /*0x00,*/ 0x04, 0x0C, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '5'
{0xF0, 0xF8, 0x4C, 0x44, 0x44, 0xC4, 0x80, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '6'
{0x04, 0x04, 0x04, 0x84, 0xE4, 0x7C, 0x1C, /*0x00,*/ 0x00, 0x00, 0x0E, 0x0F, 0x01, 0x00, 0x00}, // '7'
{0xB8, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '8'
{0x78, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x00, 0x08, 0x08, 0x08, 0x0C, 0x07, 0x03}, // '9'
{0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00}, // ':'
{0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0E, 0x06, 0x00, 0x00}, // ';'
{0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x08}, // '<'
{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /*0x00,*/ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}, // '='
{0x00, 0x08, 0x18, 0x30, 0x60, 0xC0, 0x80, /*0x00,*/ 0x00, 0x08, 0x0C, 0x06, 0x03, 0x01, 0x00}, // '>'
{0x38, 0x3C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '?'
{0xF0, 0xF8, 0x08, 0xC8, 0xC8, 0xF8, 0xF0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x01}, // '@'
{0xF8, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'A'
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'B'
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0x1C, 0x18, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0E, 0x06}, // 'C'
{0xFC, 0xFC, 0x04, 0x04, 0x0C, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x0C, 0x07, 0x03}, // 'D'
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'E'
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'F'
{0xF8, 0xFC, 0x04, 0x84, 0x84, 0x9C, 0x98, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'G'
{0xFC, 0xFC, 0x40, 0x40, 0x40, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'H'
{0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'I'
{0x00, 0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x0F, 0x07, 0x00}, // 'J'
{0xFC, 0xFC, 0xE0, 0x30, 0x18, 0x0C, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'K'
{0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'L'
{0xFC, 0xFC, 0x18, 0x70, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'M'
{0xFC, 0xFC, 0x60, 0xC0, 0x80, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0F}, // 'N'
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'O'
{0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'P'
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0C, 0x0C, 0x1F, 0x17}, // 'Q'
{0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'R'
{0x38, 0x7C, 0x44, 0x44, 0x44, 0xCC, 0x88, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'S'
{0x00, 0x04, 0x04, 0xFC, 0xFC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'T'
{0xFC, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'U'
{0x7C, 0xFC, 0x80, 0x00, 0x80, 0xFC, 0x7C, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'V'
{0xFC, 0xFC, 0x00, 0x80, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x06, 0x03, 0x06, 0x0F, 0x0F}, // 'W'
{0x0C, 0x3C, 0xF0, 0xC0, 0xF0, 0x3C, 0x0C, /*0x00,*/ 0x0C, 0x0F, 0x03, 0x00, 0x03, 0x0F, 0x0C}, // 'X'
{0x00, 0x3C, 0x7C, 0xC0, 0xC0, 0x7C, 0x3C, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'Y'
{0x04, 0x04, 0x84, 0xC4, 0x64, 0x3C, 0x1C, /*0x00,*/ 0x0E, 0x0F, 0x09, 0x08, 0x08, 0x08, 0x08}, // 'Z'
{0x00, 0x00, 0xFC, 0xFC, 0x04, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x00}, // '['
{0x38, 0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E}, // '"\'
{0x00, 0x00, 0x04, 0x04, 0xFC, 0xFC, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x00}, // ']'
{0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '^'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, // '_'
{0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '`'
{0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'a'
{0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'b'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0x60, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0C, 0x04}, // 'c'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'd'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x09, 0x09, 0x09, 0x09, 0x01}, // 'e'
{0x20, 0x20, 0xF8, 0xFC, 0x24, 0x24, 0x04, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00}, // 'f'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'g'
{0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'h'
{0x00, 0x00, 0x20, 0xEC, 0xEC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'i'
{0x00, 0x00, 0x00, 0x00, 0x20, 0xEC, 0xEC, /*0x00,*/ 0x00, 0x30, 0x70, 0x40, 0x40, 0x7F, 0x3F}, // 'j'
{0xFC, 0xFC, 0x00, 0x80, 0xC0, 0x60, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'k'
{0x00, 0x00, 0x04, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'l'
{0xE0, 0xE0, 0x20, 0xE0, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x0F}, // 'm'
{0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'n'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'o'
{0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x7F, 0x7F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'p'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x7F, 0x7F}, // 'q'
{0xE0, 0xE0, 0x60, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'r'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x08, 0x09, 0x09, 0x09, 0x09, 0x0F, 0x06}, // 's'
{0x20, 0x20, 0xFC, 0xFC, 0x20, 0x20, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08}, // 't'
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'u'
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'v'
{0xE0, 0xE0, 0x00, 0x80, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0F, 0x08, 0x0F, 0x07}, // 'w'
{0x60, 0xE0, 0x80, 0x00, 0x80, 0xE0, 0x60, /*0x00,*/ 0x0C, 0x0E, 0x03, 0x01, 0x03, 0x0E, 0x0C}, // 'x'
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'y'
{0x20, 0x20, 0x20, 0xA0, 0xE0, 0x60, 0x20, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // 'z'
{0x00, 0x00, 0x40, 0xF8, 0xBC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08}, // '{'
{0x00, 0x00, 0x00, 0xBC, 0xBC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // '|'
{0x00, 0x04, 0x04, 0xBC, 0xF8, 0x40, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x07, 0x00, 0x00}, // '}'
{0x08, 0x0C, 0x04, 0x0C, 0x08, 0x0C, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // '->'
#endif
};
#if 0
// original font
@@ -132,21 +231,40 @@ const uint8_t gFontBig[95][15] =
{0x00, 0xF0, 0xF8, 0xB8, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1C, 0xB8, 0xF0, 0xE0, 0x00, 0x11, 0x33, 0x77, 0x67, 0x66, 0x66, 0x66, 0x76, 0x33, 0x3F, 0x1F, 0x07},
{0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00}
};
#else
// 6 Empty columns removed
#elif 0
// VCR font
const uint8_t gFontBigDigits[11][26] =
const uint8_t gFontBigDigits[11][26 - 6] =
{
{0x00, 0x00, 0xF8, 0xFC, 0x06, 0x86, 0xC6, 0xE6, 0xF6, 0x76, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x77, 0x67, 0x63, 0x61, 0x60, 0x70, 0x3F, 0x1F, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x60, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x1C, 0x86, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, 0x00, 0x00, 0x00, 0x7E, 0x7F, 0x63, 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x18, 0x1C, 0x06, 0x06, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, 0x00, 0x00, 0x00, 0x18, 0x38, 0x70, 0x60, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, 0x00},
{0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x7F, 0x7F, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x7E, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x66, 0xE6, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x18, 0x38, 0x70, 0x60, 0x60, 0x60, 0x60, 0x70, 0x3F, 0x1F, 0x00},
{0x00, 0x00, 0xF8, 0xFC, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x1C, 0x18, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x71, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x86, 0xC6, 0xE6, 0x7E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, 0x00, 0x00, 0x00, 0x1E, 0x3F, 0x73, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, 0x00},
{0x00, 0x00, 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0x86, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x18, 0x38, 0x71, 0x61, 0x61, 0x61, 0x61, 0x71, 0x3F, 0x1F, 0x00},
{0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}
{/*0x00, 0x00,*/ 0xF8, 0xFC, 0x06, 0x86, 0xC6, 0xE6, 0xF6, 0x76, 0xFC, 0xF8, /*0x00,*/ /*0x00, 0x00,*/ 0x1F, 0x3F, 0x77, 0x67, 0x63, 0x61, 0x60, 0x70, 0x3F, 0x1F, /*0x00*/},
{/*0x00, 0x00,*/ 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x60, 0x60, 0x00, 0x00, /*0x00*/},
{/*0x00, 0x00,*/ 0x18, 0x1C, 0x86, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x7E, 0x7F, 0x63, 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x60, /*0x00*/},
{/*0x00, 0x00,*/ 0x18, 0x1C, 0x06, 0x06, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x70, 0x60, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/},
{/*0x00, 0x00,*/ 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0xFE, 0xFE, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x7F, 0x7F, 0x06, 0x06, /*0x00*/},
{/*0x00, 0x00,*/ 0x7E, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x66, 0xE6, 0xC6, 0x86, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x70, 0x60, 0x60, 0x60, 0x60, 0x70, 0x3F, 0x1F, /*0x00*/},
{/*0x00, 0x00,*/ 0xF8, 0xFC, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x1C, 0x18, /*0x00,*/ /*0x00, 0x00,*/ 0x1F, 0x3F, 0x71, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/},
{/*0x00, 0x00,*/ 0x06, 0x06, 0x06, 0x06, 0x06, 0x86, 0xC6, 0xE6, 0x7E, 0x3E, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, /*0x00*/},
{/*0x00, 0x00,*/ 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x1E, 0x3F, 0x73, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/},
{/*0x00, 0x00,*/ 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0x86, 0xFC, 0xF8, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x71, 0x61, 0x61, 0x61, 0x61, 0x71, 0x3F, 0x1F, /*0x00*/},
{/*0x00, 0x00,*/ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, /*0x00*/}
};
#else
// Terminus font
const uint8_t gFontBigDigits[11][26 - 6] =
{
{/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x86, 0xC6, 0xE6, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x67, 0x63, 0x61, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/},
{/*0x00, 0x00,*/ 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x7F, 0x60, 0x60, 0x00, /*0x00*/},
{/*0x00, 0x00,*/ 0x1C, 0x1E, 0x1E, 0x06, 0x06, 0x06, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x60, 0x70, 0x78, 0x7C, 0x6E, 0x67, 0x63, 0x61, 0x60, 0x60, /*0x00*/},
{/*0x00, 0x00,*/ 0x0C, 0x0E, 0x0E, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3E, /*0x00*/},
{/*0x00, 0x00,*/ 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0xFE, 0xFE, 0xFE, /*0x00,*/ /*0x00, 0x00,*/ 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x7F, 0x7F, 0x7F, /*0x00*/},
{/*0x00, 0x00,*/ 0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x86, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/},
{/*0x00, 0x00,*/ 0xF8, 0xFC, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x80, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/},
{/*0x00, 0x00,*/ 0x0E, 0x0E, 0x0E, 0x06, 0x06, 0x86, 0xE6, 0xFE, 0x7E, 0x1E, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7F, 0x7F, 0x03, 0x00, 0x00, /*0x00*/},
{/*0x00, 0x00,*/ 0x7C, 0xFE, 0xFE, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3F, /*0x00*/},
{/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x01, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7F, 0x3F, 0x1F, /*0x00*/},
{/*0x00, 0x00,*/ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, /*0x00*/}
};
#endif
/*
@@ -165,177 +283,9 @@ const uint8_t gFontSmallDigits[11][7] =
{0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00} // '-'
};
*/
#ifdef ENABLE_SPECTRUM
const uint8_t gFont3x5[160][3] = {
{0x00, 0x00, 0x00}, // 32 - space
{0x00, 0x17, 0x00}, // 33 - exclam
{0x03, 0x00, 0x03}, // 34 - quotedbl
{0x1f, 0x0a, 0x1f}, // 35 - numbersign
{0x0a, 0x1f, 0x05}, // 36 - dollar
{0x09, 0x04, 0x12}, // 37 - percent
{0x0f, 0x17, 0x1c}, // 38 - ampersand
{0x00, 0x03, 0x00}, // 39 - quotesingle
{0x00, 0x0e, 0x11}, // 40 - parenleft
{0x11, 0x0e, 0x00}, // 41 - parenright
{0x05, 0x02, 0x05}, // 42 - asterisk
{0x04, 0x0e, 0x04}, // 43 - plus
{0x10, 0x08, 0x00}, // 44 - comma
{0x04, 0x04, 0x04}, // 45 - hyphen
{0x00, 0x10, 0x00}, // 46 - period
{0x18, 0x04, 0x03}, // 47 - slash
{0x1e, 0x11, 0x0f}, // 48 - zero
{0x02, 0x1f, 0x00}, // 49 - one
{0x19, 0x15, 0x12}, // 50 - two
{0x11, 0x15, 0x0a}, // 51 - three
{0x07, 0x04, 0x1f}, // 52 - four
{0x17, 0x15, 0x09}, // 53 - five
{0x1e, 0x15, 0x1d}, // 54 - six
{0x19, 0x05, 0x03}, // 55 - seven
{0x1f, 0x15, 0x1f}, // 56 - eight
{0x17, 0x15, 0x0f}, // 57 - nine
{0x00, 0x0a, 0x00}, // 58 - colon
{0x10, 0x0a, 0x00}, // 59 - semicolon
{0x04, 0x0a, 0x11}, // 60 - less
{0x0a, 0x0a, 0x0a}, // 61 - equal
{0x11, 0x0a, 0x04}, // 62 - greater
{0x01, 0x15, 0x03}, // 63 - question
{0x0e, 0x15, 0x16}, // 64 - at
{0x1e, 0x05, 0x1e}, // 65 - A
{0x1f, 0x15, 0x0a}, // 66 - B
{0x0e, 0x11, 0x11}, // 67 - C
{0x1f, 0x11, 0x0e}, // 68 - D
{0x1f, 0x15, 0x15}, // 69 - E
{0x1f, 0x05, 0x05}, // 70 - F
{0x0e, 0x15, 0x1d}, // 71 - G
{0x1f, 0x04, 0x1f}, // 72 - H
{0x11, 0x1f, 0x11}, // 73 - I
{0x08, 0x10, 0x0f}, // 74 - J
{0x1f, 0x04, 0x1b}, // 75 - K
{0x1f, 0x10, 0x10}, // 76 - L
{0x1f, 0x06, 0x1f}, // 77 - M
{0x1f, 0x0e, 0x1f}, // 78 - N
{0x0e, 0x11, 0x0e}, // 79 - O
{0x1f, 0x05, 0x02}, // 80 - P
{0x0e, 0x19, 0x1e}, // 81 - Q
{0x1f, 0x0d, 0x16}, // 82 - R
{0x12, 0x15, 0x09}, // 83 - S
{0x01, 0x1f, 0x01}, // 84 - T
{0x0f, 0x10, 0x1f}, // 85 - U
{0x07, 0x18, 0x07}, // 86 - V
{0x1f, 0x0c, 0x1f}, // 87 - W
{0x1b, 0x04, 0x1b}, // 88 - X
{0x03, 0x1c, 0x03}, // 89 - Y
{0x19, 0x15, 0x13}, // 90 - Z
{0x1f, 0x11, 0x11}, // 91 - bracketleft
{0x02, 0x04, 0x08}, // 92 - backslash
{0x11, 0x11, 0x1f}, // 93 - bracketright
{0x02, 0x01, 0x02}, // 94 - asciicircum
{0x10, 0x10, 0x10}, // 95 - underscore
{0x01, 0x02, 0x00}, // 96 - grave
{0x1a, 0x16, 0x1c}, // 97 - a
{0x1f, 0x12, 0x0c}, // 98 - b
{0x0c, 0x12, 0x12}, // 99 - c
{0x0c, 0x12, 0x1f}, // 100 - d
{0x0c, 0x1a, 0x16}, // 101 - e
{0x04, 0x1e, 0x05}, // 102 - f
{0x0c, 0x2a, 0x1e}, // 103 - g
{0x1f, 0x02, 0x1c}, // 104 - h
{0x00, 0x1d, 0x00}, // 105 - i
{0x10, 0x20, 0x1d}, // 106 - j
{0x1f, 0x0c, 0x12}, // 107 - k
{0x11, 0x1f, 0x10}, // 108 - l
{0x1e, 0x0e, 0x1e}, // 109 - m
{0x1e, 0x02, 0x1c}, // 110 - n
{0x0c, 0x12, 0x0c}, // 111 - o
{0x3e, 0x12, 0x0c}, // 112 - p
{0x0c, 0x12, 0x3e}, // 113 - q
{0x1c, 0x02, 0x02}, // 114 - r
{0x14, 0x1e, 0x0a}, // 115 - s
{0x02, 0x1f, 0x12}, // 116 - t
{0x0e, 0x10, 0x1e}, // 117 - u
{0x0e, 0x18, 0x0e}, // 118 - v
{0x1e, 0x1c, 0x1e}, // 119 - w
{0x12, 0x0c, 0x12}, // 120 - x
{0x06, 0x28, 0x1e}, // 121 - y
{0x1a, 0x1e, 0x16}, // 122 - z
{0x04, 0x1b, 0x11}, // 123 - braceleft
{0x00, 0x1b, 0x00}, // 124 - bar
{0x11, 0x1b, 0x04}, // 125 - braceright
{0x02, 0x03, 0x01}, // 126 - asciitilde
{0x00, 0x00, 0x00}, // 127 - empty
{0x00, 0x00, 0x00}, // 128 - empty
{0x00, 0x00, 0x00}, // 129 - empty
{0x00, 0x00, 0x00}, // 130 - empty
{0x00, 0x00, 0x00}, // 131 - empty
{0x00, 0x00, 0x00}, // 132 - empty
{0x00, 0x00, 0x00}, // 133 - empty
{0x00, 0x00, 0x00}, // 134 - empty
{0x00, 0x00, 0x00}, // 135 - empty
{0x00, 0x00, 0x00}, // 136 - empty
{0x00, 0x00, 0x00}, // 137 - empty
{0x00, 0x00, 0x00}, // 138 - empty
{0x00, 0x00, 0x00}, // 139 - empty
{0x00, 0x00, 0x00}, // 140 - empty
{0x00, 0x00, 0x00}, // 141 - empty
{0x00, 0x00, 0x00}, // 142 - empty
{0x00, 0x00, 0x00}, // 143 - empty
{0x00, 0x00, 0x00}, // 144 - empty
{0x00, 0x00, 0x00}, // 145 - empty
{0x00, 0x00, 0x00}, // 146 - empty
{0x00, 0x00, 0x00}, // 147 - empty
{0x00, 0x00, 0x00}, // 148 - empty
{0x00, 0x00, 0x00}, // 149 - empty
{0x00, 0x00, 0x00}, // 150 - empty
{0x00, 0x00, 0x00}, // 151 - empty
{0x00, 0x00, 0x00}, // 152 - empty
{0x00, 0x00, 0x00}, // 153 - empty
{0x00, 0x00, 0x00}, // 154 - empty
{0x00, 0x00, 0x00}, // 155 - empty
{0x00, 0x00, 0x00}, // 156 - empty
{0x00, 0x00, 0x00}, // 157 - empty
{0x00, 0x00, 0x00}, // 158 - empty
{0x00, 0x00, 0x00}, // 159 - empty
{0x00, 0x00, 0x00}, // 160 - empty
{0x00, 0x1d, 0x00}, // 161 - exclamdown
{0x0e, 0x1b, 0x0a}, // 162 - cent
{0x14, 0x1f, 0x15}, // 163 - sterling
{0x15, 0x0e, 0x15}, // 164 - currency
{0x0b, 0x1c, 0x0b}, // 165 - yen
{0x00, 0x1b, 0x00}, // 166 - brokenbar
{0x14, 0x1b, 0x05}, // 167 - section
{0x01, 0x00, 0x01}, // 168 - dieresis
{0x02, 0x05, 0x05}, // 169 - copyright
{0x16, 0x15, 0x17}, // 170 - ordfeminine
{0x02, 0x05, 0x00}, // 171 - guillemotleft
{0x02, 0x02, 0x06}, // 172 - logicalnot
{0x04, 0x04, 0x00}, // 173 - softhyphen
{0x07, 0x03, 0x04}, // 174 - registered
{0x01, 0x01, 0x01}, // 175 - macron
{0x02, 0x05, 0x02}, // 176 - degree
{0x12, 0x17, 0x12}, // 177 - plusminus
{0x01, 0x07, 0x04}, // 178 - twosuperior
{0x05, 0x07, 0x07}, // 179 - threesuperior
{0x00, 0x02, 0x01}, // 180 - acute
{0x1f, 0x08, 0x07}, // 181 - mu
{0x02, 0x1d, 0x1f}, // 182 - paragraph
{0x0e, 0x0e, 0x0e}, // 183 - periodcentered
{0x10, 0x14, 0x08}, // 184 - cedilla
{0x00, 0x07, 0x00}, // 185 - onesuperior
{0x12, 0x15, 0x12}, // 186 - ordmasculine
{0x00, 0x05, 0x02}, // 187 - guillemotright
{0x03, 0x08, 0x18}, // 188 - onequarter
{0x0b, 0x18, 0x10}, // 189 - onehalf
{0x03, 0x0b, 0x18}, // 190 - threequarters
{0x18, 0x15, 0x10}, // 191 - questiondown
};
#endif
const uint8_t gFontSmall[95][6] =
const uint8_t gFontSmall[95-1][6] =
{
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' '
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' '
{0x00, 0x00, 0x5E, 0x00, 0x00, 0x00}, // '!'
{0x00, 0x06, 0x00, 0x06, 0x00, 0x00}, // '"'
{0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00}, // '#'
@@ -433,9 +383,9 @@ const uint8_t gFontSmall[95][6] =
};
#ifdef ENABLE_SMALL_BOLD
const uint8_t gFontSmallBold[95][6] =
const uint8_t gFontSmallBold[95 - 1][6] =
{
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x5E, 0x5E, 0x00, 0x00},
{0x06, 0x06, 0x00, 0x06, 0x06, 0x00},
{0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00},
@@ -502,10 +452,10 @@ const uint8_t gFontSmall[95][6] =
{0x00, 0x03, 0x07, 0x06, 0x00, 0x00},
{0x20, 0x76, 0x56, 0x56, 0x7E, 0x3C},
{0x7F, 0x7F, 0x6C, 0x6C, 0x7C, 0x38},
{0x3C, 0x7E, 0x66, 0x66, 0x66, 0x24},
{0x38, 0x7C, 0x6C, 0x6C, 0x6C, 0x00},
{0x38, 0x7C, 0x6C, 0x6C, 0x7F, 0x7F},
{0x3C, 0x7E, 0x56, 0x56, 0x5E, 0x0C},
{0x7C, 0x7E, 0x36, 0x36, 0x06, 0x00},
{0x7E, 0x7F, 0x1B, 0x1B, 0x02, 0x00},
{0x0C, 0x5E, 0x56, 0x56, 0x7E, 0x3C},
{0x7F, 0x7F, 0x0C, 0x0C, 0x7C, 0x78},
{0x00, 0x00, 0x7A, 0x7A, 0x00, 0x00},
@@ -516,7 +466,7 @@ const uint8_t gFontSmall[95][6] =
{0x7C, 0x7C, 0x0C, 0x0C, 0x7C, 0x78},
{0x3C, 0x7E, 0x66, 0x66, 0x7E, 0x3C},
{0x7E, 0x7E, 0x36, 0x36, 0x3E, 0x1C},
{0x1C, 0x3E, 0x36, 0x3E, 0x7E, 0x40},
{0x1C, 0x3E, 0x36, 0x7E, 0x7E, 0x60},
{0x7C, 0x7C, 0x0C, 0x0C, 0x18, 0x00},
{0x4C, 0x5E, 0x56, 0x56, 0x76, 0x20},
{0x3F, 0x7F, 0x6C, 0x6C, 0x60, 0x00},
@@ -524,11 +474,181 @@ const uint8_t gFontSmall[95][6] =
{0x0C, 0x3C, 0x70, 0x70, 0x3C, 0x0C},
{0x3C, 0x7C, 0x30, 0x30, 0x7C, 0x3C},
{0x44, 0x6C, 0x38, 0x38, 0x6C, 0x44},
{0x06, 0x6E, 0x6C, 0x6C, 0x7E, 0x3E},
{0x06, 0x6E, 0x68, 0x68, 0x7E, 0x3E},
{0x66, 0x76, 0x7E, 0x6E, 0x66, 0x00},
{0x08, 0x3E, 0x77, 0x41, 0x00, 0x00},
{0x00, 0x00, 0x7F, 0x00, 0x00, 0x00},
{0x00, 0x41, 0x77, 0x3E, 0x08, 0x00},
{0x0C, 0x06, 0x0C, 0x18, 0x0C, 0x00},
{0x0C, 0x06, 0x0C, 0x18, 0x0C, 0x00}
};
#endif
#endif
#ifdef ENABLE_SPECTRUM
const uint8_t gFont3x5[][3] =
{
{0x00, 0x00, 0x00}, // 32 - space
{0x00, 0x17, 0x00}, // 33 - exclam
{0x03, 0x00, 0x03}, // 34 - quotedbl
{0x1f, 0x0a, 0x1f}, // 35 - numbersign
{0x0a, 0x1f, 0x05}, // 36 - dollar
{0x09, 0x04, 0x12}, // 37 - percent
{0x0f, 0x17, 0x1c}, // 38 - ampersand
{0x00, 0x03, 0x00}, // 39 - quotesingle
{0x00, 0x0e, 0x11}, // 40 - parenleft
{0x11, 0x0e, 0x00}, // 41 - parenright
{0x05, 0x02, 0x05}, // 42 - asterisk
{0x04, 0x0e, 0x04}, // 43 - plus
{0x10, 0x08, 0x00}, // 44 - comma
{0x04, 0x04, 0x04}, // 45 - hyphen
{0x00, 0x10, 0x00}, // 46 - period
{0x18, 0x04, 0x03}, // 47 - slash
{0x1e, 0x11, 0x0f}, // 48 - zero
{0x02, 0x1f, 0x00}, // 49 - one
{0x19, 0x15, 0x12}, // 50 - two
{0x11, 0x15, 0x0a}, // 51 - three
{0x07, 0x04, 0x1f}, // 52 - four
{0x17, 0x15, 0x09}, // 53 - five
{0x1e, 0x15, 0x1d}, // 54 - six
{0x19, 0x05, 0x03}, // 55 - seven
{0x1f, 0x15, 0x1f}, // 56 - eight
{0x17, 0x15, 0x0f}, // 57 - nine
{0x00, 0x0a, 0x00}, // 58 - colon
{0x10, 0x0a, 0x00}, // 59 - semicolon
{0x04, 0x0a, 0x11}, // 60 - less
{0x0a, 0x0a, 0x0a}, // 61 - equal
{0x11, 0x0a, 0x04}, // 62 - greater
{0x01, 0x15, 0x03}, // 63 - question
{0x0e, 0x15, 0x16}, // 64 - at
{0x1e, 0x05, 0x1e}, // 65 - A
{0x1f, 0x15, 0x0a}, // 66 - B
{0x0e, 0x11, 0x11}, // 67 - C
{0x1f, 0x11, 0x0e}, // 68 - D
{0x1f, 0x15, 0x15}, // 69 - E
{0x1f, 0x05, 0x05}, // 70 - F
{0x0e, 0x15, 0x1d}, // 71 - G
{0x1f, 0x04, 0x1f}, // 72 - H
{0x11, 0x1f, 0x11}, // 73 - I
{0x08, 0x10, 0x0f}, // 74 - J
{0x1f, 0x04, 0x1b}, // 75 - K
{0x1f, 0x10, 0x10}, // 76 - L
{0x1f, 0x06, 0x1f}, // 77 - M
{0x1f, 0x0e, 0x1f}, // 78 - N
{0x0e, 0x11, 0x0e}, // 79 - O
{0x1f, 0x05, 0x02}, // 80 - P
{0x0e, 0x19, 0x1e}, // 81 - Q
{0x1f, 0x0d, 0x16}, // 82 - R
{0x12, 0x15, 0x09}, // 83 - S
{0x01, 0x1f, 0x01}, // 84 - T
{0x0f, 0x10, 0x1f}, // 85 - U
{0x07, 0x18, 0x07}, // 86 - V
{0x1f, 0x0c, 0x1f}, // 87 - W
{0x1b, 0x04, 0x1b}, // 88 - X
{0x03, 0x1c, 0x03}, // 89 - Y
{0x19, 0x15, 0x13}, // 90 - Z
{0x1f, 0x11, 0x11}, // 91 - bracketleft
{0x02, 0x04, 0x08}, // 92 - backslash
{0x11, 0x11, 0x1f}, // 93 - bracketright
{0x02, 0x01, 0x02}, // 94 - asciicircum
{0x10, 0x10, 0x10}, // 95 - underscore
{0x01, 0x02, 0x00}, // 96 - grave
{0x1a, 0x16, 0x1c}, // 97 - a
{0x1f, 0x12, 0x0c}, // 98 - b
{0x0c, 0x12, 0x12}, // 99 - c
{0x0c, 0x12, 0x1f}, // 100 - d
{0x0c, 0x1a, 0x16}, // 101 - e
{0x04, 0x1e, 0x05}, // 102 - f
{0x0c, 0x2a, 0x1e}, // 103 - g
{0x1f, 0x02, 0x1c}, // 104 - h
{0x00, 0x1d, 0x00}, // 105 - i
{0x10, 0x20, 0x1d}, // 106 - j
{0x1f, 0x0c, 0x12}, // 107 - k
{0x11, 0x1f, 0x10}, // 108 - l
{0x1e, 0x0e, 0x1e}, // 109 - m
{0x1e, 0x02, 0x1c}, // 110 - n
{0x0c, 0x12, 0x0c}, // 111 - o
{0x3e, 0x12, 0x0c}, // 112 - p
{0x0c, 0x12, 0x3e}, // 113 - q
{0x1c, 0x02, 0x02}, // 114 - r
{0x14, 0x1e, 0x0a}, // 115 - s
{0x02, 0x1f, 0x12}, // 116 - t
{0x0e, 0x10, 0x1e}, // 117 - u
{0x0e, 0x18, 0x0e}, // 118 - v
{0x1e, 0x1c, 0x1e}, // 119 - w
{0x12, 0x0c, 0x12}, // 120 - x
{0x06, 0x28, 0x1e}, // 121 - y
{0x1a, 0x1e, 0x16}, // 122 - z
{0x04, 0x1b, 0x11}, // 123 - braceleft
{0x00, 0x1b, 0x00}, // 124 - bar
{0x11, 0x1b, 0x04}, // 125 - braceright
{0x02, 0x03, 0x01}, // 126 - asciitilde
{0x12, 0x17, 0x12}, // 127 - plusminus
// {0x00, 0x00, 0x00}, // 127 - empty
// {0x00, 0x00, 0x00}, // 128 - empty
// {0x00, 0x00, 0x00}, // 129 - empty
// {0x00, 0x00, 0x00}, // 130 - empty
// {0x00, 0x00, 0x00}, // 131 - empty
// {0x00, 0x00, 0x00}, // 132 - empty
// {0x00, 0x00, 0x00}, // 133 - empty
// {0x00, 0x00, 0x00}, // 134 - empty
// {0x00, 0x00, 0x00}, // 135 - empty
// {0x00, 0x00, 0x00}, // 136 - empty
// {0x00, 0x00, 0x00}, // 137 - empty
// {0x00, 0x00, 0x00}, // 138 - empty
// {0x00, 0x00, 0x00}, // 139 - empty
// {0x00, 0x00, 0x00}, // 140 - empty
// {0x00, 0x00, 0x00}, // 141 - empty
// {0x00, 0x00, 0x00}, // 142 - empty
// {0x00, 0x00, 0x00}, // 143 - empty
// {0x00, 0x00, 0x00}, // 144 - empty
// {0x00, 0x00, 0x00}, // 145 - empty
// {0x00, 0x00, 0x00}, // 146 - empty
// {0x00, 0x00, 0x00}, // 147 - empty
// {0x00, 0x00, 0x00}, // 148 - empty
// {0x00, 0x00, 0x00}, // 149 - empty
// {0x00, 0x00, 0x00}, // 150 - empty
// {0x00, 0x00, 0x00}, // 151 - empty
// {0x00, 0x00, 0x00}, // 152 - empty
// {0x00, 0x00, 0x00}, // 153 - empty
// {0x00, 0x00, 0x00}, // 154 - empty
// {0x00, 0x00, 0x00}, // 155 - empty
// {0x00, 0x00, 0x00}, // 156 - empty
// {0x00, 0x00, 0x00}, // 157 - empty
// {0x00, 0x00, 0x00}, // 158 - empty
// {0x00, 0x00, 0x00}, // 159 - empty
// {0x00, 0x00, 0x00}, // 160 - empty
// {0x00, 0x1d, 0x00}, // 161 - exclamdown
// {0x0e, 0x1b, 0x0a}, // 162 - cent
// {0x14, 0x1f, 0x15}, // 163 - sterling
// {0x15, 0x0e, 0x15}, // 164 - currency
// {0x0b, 0x1c, 0x0b}, // 165 - yen
// {0x00, 0x1b, 0x00}, // 166 - brokenbar
// {0x14, 0x1b, 0x05}, // 167 - section
// {0x01, 0x00, 0x01}, // 168 - dieresis
// {0x02, 0x05, 0x05}, // 169 - copyright
// {0x16, 0x15, 0x17}, // 170 - ordfeminine
// {0x02, 0x05, 0x00}, // 171 - guillemotleft
// {0x02, 0x02, 0x06}, // 172 - logicalnot
// {0x04, 0x04, 0x00}, // 173 - softhyphen
// {0x07, 0x03, 0x04}, // 174 - registered
// {0x01, 0x01, 0x01}, // 175 - macron
// {0x02, 0x05, 0x02}, // 176 - degree
// {0x12, 0x17, 0x12}, // 177 - plusminus
// {0x01, 0x07, 0x04}, // 178 - twosuperior
// {0x05, 0x07, 0x07}, // 179 - threesuperior
// {0x00, 0x02, 0x01}, // 180 - acute
// {0x1f, 0x08, 0x07}, // 181 - mu
// {0x02, 0x1d, 0x1f}, // 182 - paragraph
// {0x0e, 0x0e, 0x0e}, // 183 - periodcentered
// {0x10, 0x14, 0x08}, // 184 - cedilla
// {0x00, 0x07, 0x00}, // 185 - onesuperior
// {0x12, 0x15, 0x12}, // 186 - ordmasculine
// {0x00, 0x05, 0x02}, // 187 - guillemotright
// {0x03, 0x08, 0x18}, // 188 - onequarter
// {0x0b, 0x18, 0x10}, // 189 - onehalf
// {0x03, 0x0b, 0x18}, // 190 - threequarters
// {0x18, 0x15, 0x10}, // 191 - questiondown
};
#endif

13
font.h
View File

@@ -19,14 +19,13 @@
#include <stdint.h>
//extern const uint8_t gFontBig[95][16];
extern const uint8_t gFontBig[95][15];
extern const uint8_t gFontBigDigits[11][26];
//extern const uint8_t gFontSmallDigits[11][7];
extern const uint8_t gFont3x5[160][3];
extern const uint8_t gFontSmall[95][6];
extern const uint8_t gFontBig[95 - 1][16 - 2];
extern const uint8_t gFontBigDigits[11][26 - 6];
extern const uint8_t gFont3x5[96][3];
extern const uint8_t gFontSmall[95 - 1][6];
#ifdef ENABLE_SMALL_BOLD
extern const uint8_t gFontSmallBold[95][6];
extern const uint8_t gFontSmallBold[95 - 1][6];
#endif
#endif

View File

@@ -19,52 +19,29 @@
#include "settings.h"
// the BK4819 has 2 bands it covers, 18MHz ~ 630MHz and 760MHz ~ 1300MHz
const freq_band_table_t BX4819_band1 = { 1800000, 63000000};
const freq_band_table_t BX4819_band2 = {84000000, 130000000};
const uint32_t bx_start1_Hz = 1800000; // 18MHz
const uint32_t bx_stop1_Hz = 63000000; // 630MHz
//const uint32_t bx_start2_Hz = 76000000; // 760MHz // my one radio the BK chip managed to lock down to this frequency
const uint32_t bx_start2_Hz = 84000000; // 840MHz // but best to go with datasheet specification really
const uint32_t bx_stop2_Hz = 130000000; // 1300MHz
const uint32_t LowerLimitFrequencyBandTable[7] =
const freq_band_table_t frequencyBandTable[7] =
{
#ifndef ENABLE_WIDE_RX
5000000,
// QS original
{.lower = 5000000, .upper = 7600000},
{.lower = 10800000, .upper = 13700000},
{.lower = 13700000, .upper = 17400000},
{.lower = 17400000, .upper = 35000000},
{.lower = 35000000, .upper = 40000000},
{.lower = 40000000, .upper = 47000000},
{.lower = 47000000, .upper = 60000000}
#else
1800000,
#endif
10800000,
13600000,
17400000,
35000000,
40000000,
47000000
};
const uint32_t MiddleFrequencyBandTable[7] =
{
6500000,
12200000,
15000000,
26000000,
37000000,
43500000,
55000000
};
const uint32_t UpperLimitFrequencyBandTable[7] =
{
7600000,
13599990,
17399990,
34999990,
39999990,
46999990,
#ifndef ENABLE_WIDE_RX
60000000
#else
130000000
// extended range
{.lower = BX4819_band1.lower, .upper = 10800000},
{.lower = 10800000, .upper = 13700000},
{.lower = 13700000, .upper = 17400000},
{.lower = 17400000, .upper = 35000000},
{.lower = 35000000, .upper = 40000000},
{.lower = 40000000, .upper = 47000000},
{.lower = 47000000, .upper = BX4819_band2.upper}
#endif
};
@@ -84,37 +61,40 @@ const uint32_t UpperLimitFrequencyBandTable[7] =
};
#endif
#if 0
const uint16_t StepFrequencyTable[7] =
{
250,
500,
625,
1000,
1250,
2500,
833
const uint16_t gStepFrequencyTable[] = {
250, 500, 625, 1000, 1250, 2500, 833,
1, 5, 10, 25, 50, 100, 125, 1500, 3000, 5000, 10000, 12500, 25000, 50000
};
#else
const uint16_t StepFrequencyTable[7] =
{
125,
250,
625,
1000,
1250,
2500,
833
};
#endif
const uint8_t StepSortedIndexes[] = {
STEP_0_01kHz, STEP_0_05kHz, STEP_0_1kHz, STEP_0_25kHz, STEP_0_5kHz, STEP_1kHz, STEP_1_25kHz, STEP_2_5kHz, STEP_5kHz, STEP_6_25kHz,
STEP_8_33kHz, STEP_10kHz, STEP_12_5kHz, STEP_15kHz, STEP_25kHz, STEP_30kHz, STEP_50kHz, STEP_100kHz,
STEP_125kHz, STEP_250kHz, STEP_500kHz
};
uint8_t FREQUENCY_GetStepIdxFromSortedIdx(uint8_t sortedIdx)
{
return StepSortedIndexes[sortedIdx];
}
uint8_t FREQUENCY_GetSortedIdxFromStepIdx(uint8_t stepIdx)
{
for(uint8_t i = 0; i < ARRAY_SIZE(gStepFrequencyTable); i++)
if(StepSortedIndexes[i] == stepIdx)
return i;
return 0;
}
FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency)
{
int band;
for (band = BAND7_470MHz; band >= BAND1_50MHz; band--)
if (Frequency >= LowerLimitFrequencyBandTable[band])
return band;
for (band = ARRAY_SIZE(frequencyBandTable) - 1; band >= 0; band--)
if (Frequency >= frequencyBandTable[band].lower)
// if (Frequency < frequencyBandTable[band].upper)
return (FREQUENCY_Band_t)band;
return BAND1_50MHz;
// return BAND_NONE;
}
uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, int32_t LowerLimit, int32_t Middle, int32_t UpperLimit, int32_t Frequency)
@@ -136,61 +116,43 @@ uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t T
return TxpMid;
}
uint32_t FREQUENCY_FloorToStep(uint32_t Upper, uint32_t Step, uint32_t Lower)
uint32_t FREQUENCY_RoundToStep(uint32_t freq, uint16_t step)
{
uint32_t Index;
if (Step == 833)
{
const uint32_t Delta = Upper - Lower;
uint32_t Base = (Delta / 2500) * 2500;
const uint32_t Index = ((Delta - Base) % 2500) / 833;
if (Index == 2)
Base++;
return Lower + Base + (Index * 833);
if(step == 833) {
uint32_t base = freq/2500*2500;
int chno = (freq - base) / 700; // convert entered aviation 8.33Khz channel number scheme to actual frequency.
return base + (chno * 833) + (chno == 3);
}
Index = (Upper - Lower) / Step;
return Lower + (Step * Index);
if(step == 1)
return freq;
return (freq + (step + 1) / 2) / step * step;
}
/*
int TX_FREQUENCY_Check(VFO_Info_t *pInfo)
{ // return '0' if TX frequency is allowed
// otherwise return '-1'
const uint32_t Frequency = pInfo->pTX->Frequency;
#ifdef ENABLE_NOAA
if (pInfo->CHANNEL_SAVE > FREQ_CHANNEL_LAST)
return -1;
#endif
*/
int TX_FREQUENCY_Check(const uint32_t Frequency)
int TX_freq_check(const uint32_t Frequency)
{ // return '0' if TX frequency is allowed
// otherwise return '-1'
if (Frequency < LowerLimitFrequencyBandTable[0] || Frequency > UpperLimitFrequencyBandTable[6])
return -1;
if (Frequency >= bx_stop1_Hz && Frequency < bx_start2_Hz)
return -1;
if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper)
return -1; // not allowed outside this range
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
return -1; // BX chip does not work in this range
switch (gSetting_F_LOCK)
{
case F_LOCK_OFF:
if (Frequency >= 13600000 && Frequency < 17400000)
case F_LOCK_DEF:
if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < frequencyBandTable[BAND3_137MHz].upper)
return 0;
if (Frequency >= 17400000 && Frequency < 35000000)
if (Frequency >= frequencyBandTable[BAND4_174MHz].lower && Frequency < frequencyBandTable[BAND4_174MHz].upper)
if (gSetting_200TX)
return 0;
if (Frequency >= 35000000 && Frequency < 40000000)
if (Frequency >= frequencyBandTable[BAND5_350MHz].lower && Frequency < frequencyBandTable[BAND5_350MHz].upper)
if (gSetting_350TX && gSetting_350EN)
return 0;
if (Frequency >= 40000000 && Frequency < 47000000)
if (Frequency >= frequencyBandTable[BAND6_400MHz].lower && Frequency < frequencyBandTable[BAND6_400MHz].upper)
return 0;
if (Frequency >= 47000000 && Frequency <= 60000000)
if (Frequency >= frequencyBandTable[BAND7_470MHz].lower && Frequency <= 60000000)
if (gSetting_500TX)
return 0;
break;
@@ -205,6 +167,8 @@ int TX_FREQUENCY_Check(const uint32_t Frequency)
case F_LOCK_CE:
if (Frequency >= 14400000 && Frequency < 14600000)
return 0;
if (Frequency >= 43000000 && Frequency < 44000000)
return 0;
break;
case F_LOCK_GB:
@@ -215,31 +179,41 @@ int TX_FREQUENCY_Check(const uint32_t Frequency)
break;
case F_LOCK_430:
if (Frequency >= 13600000 && Frequency < 17400000)
if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000)
return 0;
if (Frequency >= 40000000 && Frequency < 43000000)
return 0;
break;
case F_LOCK_438:
if (Frequency >= 13600000 && Frequency < 17400000)
if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000)
return 0;
if (Frequency >= 40000000 && Frequency < 43800000)
return 0;
break;
case F_LOCK_ALL:
break;
case F_LOCK_NONE:
for (uint8_t i = 0; i < ARRAY_SIZE(frequencyBandTable); i++)
if (Frequency >= frequencyBandTable[i].lower && Frequency < frequencyBandTable[i].upper)
return 0;
break;
}
// dis-allowed TX frequency
return -1;
}
int RX_FREQUENCY_Check(const uint32_t Frequency)
int RX_freq_check(const uint32_t Frequency)
{ // return '0' if RX frequency is allowed
// otherwise return '-1'
if (Frequency < LowerLimitFrequencyBandTable[0] || Frequency > UpperLimitFrequencyBandTable[6])
if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper)
return -1;
if (Frequency >= bx_stop1_Hz && Frequency < bx_start2_Hz)
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
return -1;
return 0; // OK frequency

View File

@@ -19,45 +19,67 @@
#include <stdint.h>
#include "radio.h"
typedef struct {
const uint32_t lower;
const uint32_t upper;
} freq_band_table_t;
extern const uint32_t bx_start1_Hz;
extern const uint32_t bx_stop1_Hz;
extern const freq_band_table_t BX4819_band1;
extern const freq_band_table_t BX4819_band2;
extern const uint32_t bx_start2_Hz;
extern const uint32_t bx_stop2_Hz;
extern const freq_band_table_t frequencyBandTable[7];
enum FREQUENCY_Band_t
{
BAND1_NONE = -1,
typedef enum {
BAND_NONE = -1,
BAND1_50MHz = 0,
BAND2_108MHz,
BAND3_136MHz,
BAND3_137MHz,
BAND4_174MHz,
BAND5_350MHz,
BAND6_400MHz,
BAND7_470MHz
};
} FREQUENCY_Band_t;
typedef enum FREQUENCY_Band_t FREQUENCY_Band_t;
extern const uint32_t LowerLimitFrequencyBandTable[7];
extern const uint32_t MiddleFrequencyBandTable[7];
extern const uint32_t UpperLimitFrequencyBandTable[7];
typedef enum {
STEP_2_5kHz,
STEP_5kHz,
STEP_6_25kHz,
STEP_10kHz,
STEP_12_5kHz,
STEP_25kHz,
STEP_8_33kHz,
STEP_0_01kHz,
STEP_0_05kHz,
STEP_0_1kHz,
STEP_0_25kHz,
STEP_0_5kHz,
STEP_1kHz,
STEP_1_25kHz,
STEP_15kHz,
STEP_30kHz,
STEP_50kHz,
STEP_100kHz,
STEP_125kHz,
STEP_250kHz,
STEP_500kHz,
} STEP_Setting_t;
extern const uint16_t gStepFrequencyTable[21];
#ifdef ENABLE_NOAA
extern const uint32_t NoaaFrequencyTable[10];
extern const uint32_t NoaaFrequencyTable[10];
#endif
extern const uint16_t StepFrequencyTable[7];
FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency);
uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, int32_t LowerLimit, int32_t Middle, int32_t UpperLimit, int32_t Frequency);
uint32_t FREQUENCY_FloorToStep(uint32_t Upper, uint32_t Step, uint32_t Lower);
uint32_t FREQUENCY_RoundToStep(uint32_t freq, uint16_t step);
//int TX_FREQUENCY_Check(VFO_Info_t *pInfo);
int TX_FREQUENCY_Check(const uint32_t Frequency);
int RX_FREQUENCY_Check(const uint32_t Frequency);
uint8_t FREQUENCY_GetStepIdxFromSortedIdx(uint8_t sortedIdx);
uint8_t FREQUENCY_GetSortedIdxFromStepIdx(uint8_t step);
int TX_freq_check(const uint32_t Frequency);
int RX_freq_check(const uint32_t Frequency);
#endif

View File

@@ -20,14 +20,18 @@
#if defined(ENABLE_FMRADIO)
#include "app/fm.h"
#endif
#include "audio.h"
#include "bsp/dp32g030/gpio.h"
#include "dcs.h"
#include "driver/backlight.h"
#if defined(ENABLE_FMRADIO)
#include "driver/bk1080.h"
#endif
#include "driver/bk4819.h"
#include "driver/gpio.h"
#include "driver/system.h"
#include "driver/st7565.h"
#include "frequencies.h"
#include "functions.h"
#include "helper/battery.h"
#include "misc.h"
@@ -40,33 +44,29 @@ FUNCTION_Type_t gCurrentFunction;
void FUNCTION_Init(void)
{
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif
#ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif
{
gCurrentCodeType = gSelectedCodeType;
if (gCssScanMode == CSS_SCAN_MODE_OFF)
gCurrentCodeType = gRxVfo->AM_mode ? CODE_TYPE_OFF : gRxVfo->pRX->CodeType;
gCurrentCodeType = (gRxVfo->Modulation != MODULATION_FM) ? CODE_TYPE_OFF : gRxVfo->pRX->CodeType;
}
#ifdef ENABLE_NOAA
else
gCurrentCodeType = CODE_TYPE_CONTINUOUS_TONE;
#endif
#ifdef ENABLE_NOAA
else
gCurrentCodeType = CODE_TYPE_CONTINUOUS_TONE;
#endif
gDTMF_RequestPending = false;
#ifdef ENABLE_DTMF_CALLING
DTMF_clear_RX();
#endif
gDTMF_RecvTimeout = 0;
gDTMF_WriteIndex = 0;
memset(gDTMF_Received, 0, sizeof(gDTMF_Received));
// gDTMF_RX_timeout_live = 0;
// gDTMF_RX_timeout_live[0] = '\0';
g_CxCSS_TAIL_Found = false;
g_CDCSS_Lost = false;
g_CTCSS_Lost = false;
g_VOX_Lost = false;
#ifdef ENABLE_VOX
g_VOX_Lost = false;
#endif
g_SquelchLost = false;
gFlagTailNoteEliminationComplete = false;
@@ -80,6 +80,8 @@ void FUNCTION_Init(void)
#ifdef ENABLE_NOAA
gNOAACountdown_10ms = 0;
#endif
gUpdateStatus = true;
}
void FUNCTION_Select(FUNCTION_Type_t Function)
@@ -93,17 +95,19 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
{
BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable();
gRxIdleMode = false;
UI_DisplayStatus(false);
UI_DisplayStatus();
}
switch (Function)
{
case FUNCTION_FOREGROUND:
#ifdef ENABLE_DTMF_CALLING
if (gDTMF_ReplyState != DTMF_REPLY_NONE)
RADIO_PrepareCssTX();
#endif
if (PreviousFunction == FUNCTION_TRANSMIT)
{
ST7565_FixInterfGlitch();
gVFO_RSSI_bar_level[0] = 0;
gVFO_RSSI_bar_level[1] = 0;
}
@@ -115,46 +119,61 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
if (gFmRadioMode)
gFM_RestoreCountdown_10ms = fm_restore_countdown_10ms;
#endif
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT || gDTMF_CallState == DTMF_CALL_STATE_RECEIVED)
gDTMF_AUTO_RESET_TIME = 1 + (gEeprom.DTMF_AUTO_RESET_TIME * 2);
#ifdef ENABLE_DTMF_CALLING
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT ||
gDTMF_CallState == DTMF_CALL_STATE_RECEIVED ||
gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY)
{
gDTMF_auto_reset_time_500ms = gEeprom.DTMF_auto_reset_time * 2;
}
#endif
gUpdateStatus = true;
return;
case FUNCTION_MONITOR:
gMonitor = true;
break;
case FUNCTION_INCOMING:
case FUNCTION_RECEIVE:
break;
case FUNCTION_POWER_SAVE:
gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10;
gPowerSaveCountdownExpired = false;
gRxIdleMode = true;
gMonitor = false;
BK4819_DisableVox();
BK4819_DisableVox();
BK4819_Sleep();
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, false);
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false);
gUpdateStatus = true;
GUI_SelectNextDisplay(DISPLAY_MAIN);
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
GUI_SelectNextDisplay(DISPLAY_MAIN);
return;
case FUNCTION_TRANSMIT:
// if DTMF is enabled when TX'ing, it changes the TX audio filtering !! .. 1of11
BK4819_DisableDTMF();
#ifdef ENABLE_DTMF_CALLING
// clear the DTMF RX buffer
DTMF_clear_RX();
#endif
// clear the DTMF RX live decoder buffer
gDTMF_RX_live_timeout = 0;
gDTMF_RX_live[0] = 0;
gDTMF_RX_live_timeout = 0;
memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live));
#if defined(ENABLE_FMRADIO)
if (gFmRadioMode)
BK1080_Init(0, false);
@@ -167,13 +186,13 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
GUI_DisplayScreen();
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
SYSTEM_DelayMs(20);
BK4819_PlayTone(500, 0);
SYSTEM_DelayMs(2);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
gEnableSpeaker = true;
@@ -184,33 +203,51 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
break;
}
#endif
gUpdateStatus = true;
GUI_DisplayScreen();
RADIO_SetTxParameters();
// turn the LED on RED
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, true);
// turn the RED LED on
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true);
DTMF_Reply();
#ifdef ENABLE_ALARM
if (gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO)
BK4819_PlaySingleTone(2525, 250, 0, gEeprom.DTMF_SIDE_TONE);
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
if (gAlarmState != ALARM_STATE_OFF)
{
BK4819_TransmitTone(true, (gAlarmState == ALARM_STATE_TX1750) ? 1750 : 500);
#ifdef ENABLE_TX1750
if (gAlarmState == ALARM_STATE_TX1750)
BK4819_TransmitTone(true, 1750);
#endif
#ifdef ENABLE_ALARM
if (gAlarmState == ALARM_STATE_TXALARM)
BK4819_TransmitTone(true, 500);
#endif
SYSTEM_DelayMs(2);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gAlarmToneCounter = 0;
gEnableSpeaker = true;
AUDIO_AudioPathOn();
#ifdef ENABLE_ALARM
gAlarmToneCounter = 0;
#endif
gEnableSpeaker = true;
break;
}
#endif
if (gCurrentVfo->SCRAMBLING_TYPE > 0 && gSetting_ScrambleEnable)
BK4819_EnableScramble(gCurrentVfo->SCRAMBLING_TYPE - 1);
else
BK4819_DisableScramble();
if (gSetting_backlight_on_tx_rx == BACKLIGHT_ON_TR_TX ||
gSetting_backlight_on_tx_rx == BACKLIGHT_ON_TR_TXRX)
BACKLIGHT_TurnOn();
break;
case FUNCTION_BAND_SCOPE:

View File

@@ -21,11 +21,10 @@ def obfuscate(fw):
return bytes([a^b for a, b in zip(fw, cycle(OBFUSCATION))])
plain = open(sys.argv[1], 'rb').read()
if len(sys.argv[2]) > 10:
print('Version suffix is too big!')
sys.exit(1)
version = b'*OEFW-' + bytes(sys.argv[2], 'ascii')
version = b'*' + bytes(sys.argv[2], 'ascii') + b' ' + bytes(sys.argv[3], 'ascii')
version = version[0:16]
if len(version) < 16:
version += b'\x00' * (16 - len(version))
@@ -36,5 +35,5 @@ crc.update(packed)
digest = crc.digest()
digest = bytes([digest[1], digest[0]])
open(sys.argv[3], 'wb').write(packed + digest)
open(sys.argv[4], 'wb').write(packed + digest)

View File

@@ -16,7 +16,10 @@
#include "battery.h"
#include "driver/backlight.h"
#include "driver/st7565.h"
#include "functions.h"
#include "misc.h"
#include "settings.h"
#include "ui/battery.h"
#include "ui/menu.h"
#include "ui/ui.h"
@@ -28,101 +31,96 @@ uint16_t gBatteryVoltages[4];
uint16_t gBatteryVoltageAverage;
uint8_t gBatteryDisplayLevel;
bool gChargingWithTypeC;
bool gLowBattery;
bool gLowBatteryBlink;
bool gLowBattery;
bool gLowBatteryConfirmed;
uint16_t gBatteryCheckCounter;
typedef enum {
BATTERY_LOW_INACTIVE,
BATTERY_LOW_ACTIVE,
BATTERY_LOW_CONFIRMED
} BatteryLow_t;
uint16_t lowBatteryCountdown;
const uint16_t lowBatteryPeriod = 30;
volatile uint16_t gPowerSave_10ms;
/*
Based on real measurement
Volts Percent Volts Percent Volts Percent Volts Percent
8.28 100 7.95099 73 7.7184 46 7.48116 19
8.22 99 7.94188 72 7.71091 45 7.46364 18
8.17 98 7.9338 71 7.70911 44 7.44789 17
8.13632 97 7.92684 70 7.70098 43 7.43318 16
8.12308 96 7.9178 69 7.69619 42 7.41864 15
8.09688 95 7.90823 68 7.69018 41 7.40579 14
8.08124 94 7.89858 67 7.68473 40 7.39289 13
8.06912 93 7.88667 66 7.67911 39 7.37839 12
8.05826 92 7.87673 65 7.67087 38 7.36017 11
8.05008 91 7.86864 64 7.66601 37 7.33704 10
8.04192 90 7.85802 63 7.6599 36 7.3079 9
8.03866 89 7.84816 62 7.65418 35 7.26793 8
8.03089 88 7.83744 61 7.64775 34 7.21291 7
8.0284 87 7.82748 60 7.64065 33 7.13416 6
8.02044 86 7.81983 59 7.63136 32 7.02785 5
8.01832 85 7.80929 58 7.6244 31 6.89448 4
8.01072 84 7.79955 57 7.61636 30 6.72912 3
8.00965 83 7.79017 56 7.60738 29 6.5164 2
8.00333 82 7.78107 55 7.597 28 6.19272 1
7.99973 81 7.77167 54 7.5876 27 5.63138 0
7.99218 80 7.76509 53 7.57732 26
7.98999 79 7.75649 52 7.56563 25
7.98234 78 7.74939 51 7.55356 24
7.97892 77 7.7411 50 7.54088 23
7.97043 76 7.73648 49 7.52683 22
7.96478 75 7.72911 48 7.51285 21
7.95983 74 7.72097 47 7.49832 20
*/
uint8_t BATTERY_VoltsToPercent(uint16_t voltage_10mV)
unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV)
{
if(voltage_10mV>814)
return 100;
else if(voltage_10mV>756)
return 132*voltage_10mV/100-974;
else if(voltage_10mV>729)
return 63*voltage_10mV/100-452;
else if(voltage_10mV>600)
return 52*voltage_10mV/1000-31;
else
return 0;
const uint16_t crv1600[][2] = {
{828, 100},
{814, 97 },
{760, 25 },
{729, 6 },
{630, 0 },
{0, 0 }
};
const uint16_t crv2200[][2] = {
{832, 100},
{813, 95 },
{740, 60 },
{707, 21 },
{682, 5 },
{630, 0 },
{0, 0 }
};
const BATTERY_Type_t type = gEeprom.BATTERY_TYPE;
const uint16_t(*crv)[2];
uint8_t size;
if (type == BATTERY_TYPE_2200_MAH) {
crv = crv2200;
size = ARRAY_SIZE(crv2200);
}
else {
crv = crv1600;
size = ARRAY_SIZE(crv1600);
}
const int mulipl = 1000;
for (int i = 1; i < size; i++) {
if (voltage_10mV > crv[i][0]) {
int a = (crv[i - 1][1] - crv[i][1]) * mulipl / (crv[i - 1][0] - crv[i][0]);
int b = crv[i][1] - a * crv[i][0] / mulipl;
int p = a * voltage_10mV / mulipl + b;
return MIN(p, 100);
}
}
return 0;
}
void BATTERY_GetReadings(bool bDisplayBatteryLevel)
void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
{
const uint8_t PreviousBatteryLevel = gBatteryDisplayLevel;
const uint16_t Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] + gBatteryVoltages[3]) / 4;
gBatteryDisplayLevel = 0;
if (Voltage >= gBatteryCalibration[5])
gBatteryDisplayLevel = 11;
else
if (Voltage >= ((gBatteryCalibration[4] + gBatteryCalibration[5]) / 2))
gBatteryDisplayLevel = 10;
else
if (Voltage >= gBatteryCalibration[4])
gBatteryDisplayLevel = 9;
else
if (Voltage >= ((gBatteryCalibration[3] + gBatteryCalibration[4]) / 2))
gBatteryDisplayLevel = 8;
else
if (Voltage >= gBatteryCalibration[3])
gBatteryDisplayLevel = 7;
else
if (Voltage >= ((gBatteryCalibration[2] + gBatteryCalibration[3]) / 2))
gBatteryDisplayLevel = 6;
else
if (Voltage >= gBatteryCalibration[2])
gBatteryDisplayLevel = 5;
else
if (Voltage >= ((gBatteryCalibration[1] + gBatteryCalibration[2]) / 2))
gBatteryDisplayLevel = 4;
else
if (Voltage >= gBatteryCalibration[1])
gBatteryDisplayLevel = 3;
else
if (Voltage >= ((gBatteryCalibration[0] + gBatteryCalibration[1]) / 2))
gBatteryDisplayLevel = 2;
else
if (Voltage >= gBatteryCalibration[0])
gBatteryDisplayLevel = 1;
gBatteryVoltageAverage = (Voltage * 760) / gBatteryCalibration[3];
if ((gScreenToDisplay == DISPLAY_MENU) && gMenuCursor == MENU_VOL)
if(gBatteryVoltageAverage > 890)
gBatteryDisplayLevel = 7; // battery overvoltage
else if(gBatteryVoltageAverage < 630)
gBatteryDisplayLevel = 0; // battery critical
else {
gBatteryDisplayLevel = 1;
const uint8_t levels[] = {5,17,41,65,88};
uint8_t perc = BATTERY_VoltsToPercent(gBatteryVoltageAverage);
for(uint8_t i = 6; i >= 1; i--){
if (perc > levels[i-2]) {
gBatteryDisplayLevel = i;
break;
}
}
}
if ((gScreenToDisplay == DISPLAY_MENU) && UI_MENU_GetCurrentMenuId() == MENU_VOL)
gUpdateDisplay = true;
if (gBatteryCurrent < 501)
@@ -149,7 +147,9 @@ void BATTERY_GetReadings(bool bDisplayBatteryLevel)
if (PreviousBatteryLevel != gBatteryDisplayLevel)
{
if (gBatteryDisplayLevel < 2)
if(gBatteryDisplayLevel > 2)
gLowBatteryConfirmed = false;
else if (gBatteryDisplayLevel < 2)
{
gLowBattery = true;
}
@@ -160,7 +160,64 @@ void BATTERY_GetReadings(bool bDisplayBatteryLevel)
if (bDisplayBatteryLevel)
UI_DisplayBattery(gBatteryDisplayLevel, gLowBatteryBlink);
}
if(!gLowBatteryConfirmed)
gUpdateDisplay = true;
gLowBatteryCountdown = 0;
lowBatteryCountdown = 0;
}
}
void BATTERY_TimeSlice500ms(void)
{
if (gLowBattery)
{
gLowBatteryBlink = ++lowBatteryCountdown & 1;
UI_DisplayBattery(0, gLowBatteryBlink);
if (gCurrentFunction != FUNCTION_TRANSMIT)
{ // not transmitting
if (lowBatteryCountdown < lowBatteryPeriod)
{
if (lowBatteryCountdown == lowBatteryPeriod-1 && !gChargingWithTypeC && !gLowBatteryConfirmed)
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP);
}
else
{
lowBatteryCountdown = 0;
if (!gChargingWithTypeC)
{ // not on charge
if(!gLowBatteryConfirmed) {
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP);
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_LOW_VOLTAGE);
#endif
}
if (gBatteryDisplayLevel == 0)
{
#ifdef ENABLE_VOICE
AUDIO_PlaySingleVoice(true);
#endif
gReducedService = true;
//if (gCurrentFunction != FUNCTION_POWER_SAVE)
FUNCTION_Select(FUNCTION_POWER_SAVE);
ST7565_HardwareReset();
if (gEeprom.BACKLIGHT_TIME < (ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1))
BACKLIGHT_TurnOff(); // turn the backlight off
}
#ifdef ENABLE_VOICE
else
AUDIO_PlaySingleVoice(false);
#endif
}
}
}
}
}

View File

@@ -27,14 +27,22 @@ extern uint16_t gBatteryVoltages[4];
extern uint16_t gBatteryVoltageAverage;
extern uint8_t gBatteryDisplayLevel;
extern bool gChargingWithTypeC;
extern bool gLowBattery;
extern bool gLowBatteryBlink;
extern bool gLowBattery;
extern bool gLowBatteryConfirmed;
extern uint16_t gBatteryCheckCounter;
extern volatile uint16_t gPowerSave_10ms;
uint8_t BATTERY_VoltsToPercent(uint16_t voltage_10mV);
void BATTERY_GetReadings(bool bDisplayBatteryLevel);
typedef enum {
BATTERY_TYPE_1600_MAH,
BATTERY_TYPE_2200_MAH,
BATTERY_TYPE_UNKNOWN
} BATTERY_Type_t;
unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV);
void BATTERY_GetReadings(const bool bDisplayBatteryLevel);
void BATTERY_TimeSlice500ms(void);
#endif

View File

@@ -39,15 +39,16 @@ BOOT_Mode_t BOOT_GetMode(void)
for (i = 0; i < 2; i++)
{
if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT))
return BOOT_MODE_NORMAL;
return BOOT_MODE_NORMAL; // PTT not pressed
Keys[i] = KEYBOARD_Poll();
SYSTEM_DelayMs(20);
}
if (Keys[0] == Keys[1])
{
gKeyReading0 = Keys[0];
gKeyReading1 = Keys[0];
gKeyReading0 = Keys[0];
gKeyReading1 = Keys[0];
gDebounceCounter = 2;
if (Keys[0] == KEY_SIDE1)
@@ -66,16 +67,7 @@ void BOOT_ProcessMode(BOOT_Mode_t Mode)
{
if (Mode == BOOT_MODE_F_LOCK)
{
// enable all the menu items
gMenuListCount = 0;
// while (MenuList[gMenuListCount].name != NULL)
while (MenuList[gMenuListCount].name[0] != '\0')
gMenuListCount++;
gMenuCursor = MENU_350TX;
gSubMenuSelection = gSetting_350TX;
GUI_SelectNextDisplay(DISPLAY_MENU);
gF_LOCK = true;
}
#ifdef ENABLE_AIRCOPY
else
@@ -83,18 +75,21 @@ void BOOT_ProcessMode(BOOT_Mode_t Mode)
{
gEeprom.DUAL_WATCH = DUAL_WATCH_OFF;
gEeprom.BATTERY_SAVE = 0;
gEeprom.VOX_SWITCH = false;
#ifdef ENABLE_VOX
gEeprom.VOX_SWITCH = false;
#endif
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gEeprom.AUTO_KEYPAD_LOCK = false;
gEeprom.KEY_1_SHORT_PRESS_ACTION = 0;
gEeprom.KEY_1_LONG_PRESS_ACTION = 0;
gEeprom.KEY_2_SHORT_PRESS_ACTION = 0;
gEeprom.KEY_2_LONG_PRESS_ACTION = 0;
gEeprom.KEY_1_SHORT_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_1_LONG_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_2_SHORT_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_2_LONG_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_M_LONG_PRESS_ACTION = ACTION_OPT_NONE;
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_LAST - 1, 5, 41002500);
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_LAST - 1, 41002500);
gRxVfo->CHANNEL_BANDWIDTH = BANDWIDTH_NARROW;
gRxVfo->OUTPUT_POWER = 0;
gRxVfo->CHANNEL_BANDWIDTH = BANDWIDTH_WIDE;
gRxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW;
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
@@ -105,6 +100,7 @@ void BOOT_ProcessMode(BOOT_Mode_t Mode)
BK4819_ResetFSK();
gAircopyState = AIRCOPY_READY;
GUI_SelectNextDisplay(DISPLAY_AIRCOPY);
}
#endif

BIN
images/batcal.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

14
init.c
View File

@@ -30,21 +30,17 @@ void DATA_Init(void);
void BSS_Init(void)
{
uint32_t *pBss;
for (pBss = __bss_start__; pBss < __bss_end__; pBss++) {
for (pBss = __bss_start__; pBss < __bss_end__; pBss++)
*pBss = 0;
}
}
void DATA_Init(void)
{
volatile uint32_t *pDataRam = (volatile uint32_t *)sram_data_start;
volatile uint32_t *pDataRam = (volatile uint32_t *)sram_data_start;
volatile uint32_t *pDataFlash = (volatile uint32_t *)flash_data_start;
uint32_t Size = (uint32_t)sram_data_end - (uint32_t)sram_data_start;
uint32_t i;
uint32_t Size = (uint32_t)sram_data_end - (uint32_t)sram_data_start;
unsigned int i;
for (i = 0; i < Size / 4; i++) {
for (i = 0; i < (Size / 4); i++)
*pDataRam++ = *pDataFlash++;
}
}

88
main.c
View File

@@ -50,6 +50,7 @@ void _putchar(char c)
void Main(void)
{
unsigned int i;
BOOT_Mode_t BootMode;
// Enable clock gating of blocks we need
SYSCON_DEV_CLK_GATE = 0
@@ -60,14 +61,15 @@ void Main(void)
| SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE
| SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE
| SYSCON_DEV_CLK_GATE_CRC_BITS_ENABLE
| SYSCON_DEV_CLK_GATE_AES_BITS_ENABLE;
| SYSCON_DEV_CLK_GATE_AES_BITS_ENABLE
| SYSCON_DEV_CLK_GATE_PWM_PLUS0_BITS_ENABLE;
SYSTICK_Init();
BOARD_Init();
UART_Init();
boot_counter_10ms = 250; // 2.5 sec
UART_Send(UART_Version, strlen(UART_Version));
// Not implementing authentic device checks
@@ -83,7 +85,7 @@ void Main(void)
BOARD_EEPROM_Init();
BOARD_EEPROM_LoadMoreSettings();
BOARD_EEPROM_LoadCalibration();
RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD);
RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD);
@@ -101,28 +103,55 @@ void Main(void)
AM_fix_init();
#endif
// count the number of menu list items
gMenuListCount = 0;
while (MenuList[gMenuListCount].name[0] != '\0')
gMenuListCount++;
gMenuListCount -= 8; // disable the last 'n' items
BootMode = BOOT_GetMode();
if (!gChargingWithTypeC && !gBatteryDisplayLevel)
if (BootMode == BOOT_MODE_F_LOCK)
{
gF_LOCK = true; // flag to say include the hidden menu items
}
// count the number of menu items
gMenuListCount = 0;
while (MenuList[gMenuListCount].name[0] != '\0') {
if(!gF_LOCK && MenuList[gMenuListCount].menu_id == FIRST_HIDDEN_MENU_ITEM)
break;
gMenuListCount++;
}
// wait for user to release all butts before moving on
if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) ||
KEYBOARD_Poll() != KEY_INVALID ||
BootMode != BOOT_MODE_NORMAL)
{ // keys are pressed
UI_DisplayReleaseKeys();
BACKLIGHT_TurnOn();
i = 0;
while (i < 50) // 500ms
{
i = (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && KEYBOARD_Poll() == KEY_INVALID) ? i + 1 : 0;
SYSTEM_DelayMs(10);
}
gKeyReading0 = KEY_INVALID;
gKeyReading1 = KEY_INVALID;
gDebounceCounter = 0;
}
if (!gChargingWithTypeC && gBatteryDisplayLevel == 0)
{
FUNCTION_Select(FUNCTION_POWER_SAVE);
if (gEeprom.BACKLIGHT < (ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1))
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight OFF
if (gEeprom.BACKLIGHT_TIME < (ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1)) // backlight is not set to be always on
BACKLIGHT_TurnOff(); // turn the backlight OFF
else
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight ON
BACKLIGHT_TurnOn(); // turn the backlight ON
gReducedService = true;
}
else
{
BOOT_Mode_t BootMode;
UI_DisplayWelcome();
BACKLIGHT_TurnOn();
if (gEeprom.POWER_ON_DISPLAY_MODE != POWER_ON_DISPLAY_MODE_NONE)
@@ -131,24 +160,24 @@ void Main(void)
{
if (KEYBOARD_Poll() != KEY_INVALID)
{ // halt boot beeps
boot_counter_10ms = 0;
boot_counter_10ms = 0;
break;
}
#ifdef ENABLE_BOOT_BEEPS
if ((boot_counter_10ms % 25) == 0)
AUDIO_PlayBeep(BEEP_880HZ_40MS_OPTIONAL);
#endif
#ifdef ENABLE_BOOT_BEEPS
if ((boot_counter_10ms % 25) == 0)
AUDIO_PlayBeep(BEEP_880HZ_40MS_OPTIONAL);
#endif
}
}
BootMode = BOOT_GetMode();
#ifdef ENABLE_PWRON_PASSWORD
if (gEeprom.POWER_ON_PASSWORD < 1000000)
{
bIsInLockScreen = true;
UI_DisplayLock();
bIsInLockScreen = false;
}
#endif
BOOT_ProcessMode(BootMode);
@@ -156,29 +185,30 @@ void Main(void)
gUpdateStatus = true;
#ifdef ENABLE_VOICE
#ifdef ENABLE_VOICE
{
uint8_t Channel;
AUDIO_SetVoiceID(0, VOICE_ID_WELCOME);
Channel = gEeprom.ScreenChannel[gEeprom.TX_CHANNEL];
Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO];
if (IS_MR_CHANNEL(Channel))
{
AUDIO_SetVoiceID(1, VOICE_ID_CHANNEL_MODE);
AUDIO_SetDigitVoice(2, Channel + 1);
}
else
if (IS_FREQ_CHANNEL(Channel))
else if (IS_FREQ_CHANNEL(Channel))
AUDIO_SetVoiceID(1, VOICE_ID_FREQUENCY_MODE);
AUDIO_PlaySingleVoice(0);
}
#endif
#endif
#ifdef ENABLE_NOAA
RADIO_ConfigureNOAA();
#endif
#ifdef ENABLE_NOAA
RADIO_ConfigureNOAA();
#endif
// ******************
}
while (1)

122
misc.c
View File

@@ -17,19 +17,24 @@
#include <string.h>
#include "misc.h"
#include "settings.h"
const uint8_t fm_resume_countdown_500ms = 2500 / 500; // 2.5 seconds
const uint8_t fm_radio_countdown_500ms = 2000 / 500; // 2 seconds
const uint16_t fm_play_countdown_scan_10ms = 100 / 10; // 100ms
const uint16_t fm_play_countdown_noscan_10ms = 1200 / 10; // 1.2 seconds
const uint16_t fm_restore_countdown_10ms = 5000 / 10; // 5 seconds
const uint8_t menu_timeout_500ms = 20000 / 500; // 20 seconds
const uint8_t vfo_state_resume_countdown_500ms = 2500 / 500; // 2.5 seconds
const uint8_t menu_timeout_500ms = 20000 / 500; // 20 seconds
const uint16_t menu_timeout_long_500ms = 120000 / 500; // 2 minutes
const uint8_t DTMF_RX_live_timeout_500ms = 6000 / 500; // 6 seconds live decoder on screen
#ifdef ENABLE_DTMF_CALLING
const uint8_t DTMF_RX_timeout_500ms = 10000 / 500; // 10 seconds till we wipe the DTMF receiver
const uint8_t DTMF_decode_ring_countdown_500ms = 15000 / 500; // 15 seconds
const uint8_t DTMF_decode_ring_countdown_500ms = 15000 / 500; // 15 seconds .. time we sound the ringing for
const uint8_t DTMF_txstop_countdown_500ms = 3000 / 500; // 6 seconds
#endif
const uint8_t key_input_timeout_500ms = 8000 / 500; // 8 seconds
@@ -44,20 +49,27 @@ const uint16_t dual_watch_count_after_rx_10ms = 1000 / 10; // 1 sec afte
const uint16_t dual_watch_count_after_1_10ms = 5000 / 10; // 5 sec
const uint16_t dual_watch_count_after_2_10ms = 3600 / 10; // 3.6 sec
const uint16_t dual_watch_count_noaa_10ms = 70 / 10; // 70ms
const uint16_t dual_watch_count_after_vox_10ms = 200 / 10; // 200ms
#ifdef ENABLE_VOX
const uint16_t dual_watch_count_after_vox_10ms = 200 / 10; // 200ms
#endif
const uint16_t dual_watch_count_toggle_10ms = 100 / 10; // 100ms between VFO toggles
const uint16_t scan_pause_delay_in_1_10ms = 5000 / 10; // 5 seconds
const uint16_t scan_pause_delay_in_2_10ms = 500 / 10; // 500ms
const uint16_t scan_pause_delay_in_3_10ms = 200 / 10; // 200ms
const uint16_t scan_pause_delay_in_4_10ms = 300 / 10; // 300ms
const uint16_t scan_pause_delay_in_5_10ms = 1000 / 10; // 1 sec
const uint16_t scan_pause_delay_in_6_10ms = 100 / 10; // 100ms
const uint16_t scan_pause_delay_in_7_10ms = 3600 / 10; // 3.6 seconds
const uint16_t battery_save_count_10ms = 10000 / 10; // 10 seconds
const uint16_t power_save1_10ms = 100 / 10; // 100ms
const uint16_t power_save2_10ms = 200 / 10; // 200ms
const uint16_t vox_stop_count_down_10ms = 1000 / 10; // 1 second
#ifdef ENABLE_VOX
const uint16_t vox_stop_count_down_10ms = 1000 / 10; // 1 second
#endif
const uint16_t NOAA_countdown_10ms = 5000 / 10; // 5 seconds
const uint16_t NOAA_countdown_2_10ms = 500 / 10; // 500ms
@@ -68,14 +80,17 @@ const uint32_t gDefaultAesKey[4] = {0x4AA5CC60, 0x0312CC5F, 0x
const uint8_t gMicGain_dB2[5] = {3, 8, 16, 24, 31};
bool gSetting_350TX;
#ifdef ENABLE_DTMF_CALLING
bool gSetting_KILLED;
#endif
bool gSetting_200TX;
bool gSetting_500TX;
bool gSetting_350EN;
bool gSetting_TX_EN;
uint8_t gSetting_F_LOCK;
bool gSetting_ScrambleEnable;
uint8_t gSetting_backlight_on_tx_rx;
#ifdef ENABLE_AM_FIX
bool gSetting_AM_fix;
#endif
@@ -95,17 +110,12 @@ bool bHasCustomAesKey;
uint32_t gChallenge[4];
uint8_t gTryCount;
uint8_t gEEPROM_1EC0_0[8];
uint8_t gEEPROM_1EC0_1[8];
uint8_t gEEPROM_1EC0_2[8];
uint8_t gEEPROM_1EC0_3[8];
uint16_t gEEPROM_RSSI_CALIB[2][4];
uint16_t gEEPROM_RSSI_CALIB[7][4];
uint16_t gEEPROM_1F8A;
uint16_t gEEPROM_1F8C;
uint8_t gMR_ChannelAttributes[FREQ_CHANNEL_LAST + 1];
ChannelAttributes_t gMR_ChannelAttributes[FREQ_CHANNEL_LAST + 1];
volatile uint16_t gBatterySaveCountdown_10ms = battery_save_count_10ms;
@@ -115,9 +125,10 @@ volatile bool gSchedulePowerSave;
volatile bool gScheduleDualWatch = true;
volatile uint16_t gDualWatchCountdown_10ms;
volatile bool gDualWatchCountdownExpired = true;
bool gDualWatchActive = false;
volatile uint8_t gSerialConfigCountDown_500ms;
volatile bool gNextTimeslice_500ms;
volatile uint16_t gTxTimerCountdown_500ms;
@@ -125,6 +136,8 @@ volatile bool gTxTimeoutReached;
volatile uint16_t gTailNoteEliminationCountdown_10ms;
volatile uint8_t gVFOStateResumeCountdown_500ms;
#ifdef ENABLE_NOAA
volatile uint16_t gNOAA_Countdown_10ms;
#endif
@@ -144,12 +157,16 @@ uint8_t gVFO_RSSI_bar_level[2];
uint8_t gReducedService;
uint8_t gBatteryVoltageIndex;
CssScanMode_t gCssScanMode;
bool gCssBackgroundScan;
volatile bool gScheduleScanListen = true;
volatile uint16_t gScanPauseDelayIn_10ms;
bool gUpdateRSSI;
#ifdef ENABLE_ALARM
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
AlarmState_t gAlarmState;
#endif
uint8_t gVoltageMenuCountdown;
uint16_t gMenuCountdown;
bool gPttWasReleased;
bool gPttWasPressed;
uint8_t gKeypadLocked;
@@ -163,35 +180,34 @@ bool gRequestSaveSettings;
bool gRequestSaveFM;
#endif
bool gFlagPrepareTX;
bool gFlagAcceptSetting;
bool gFlagRefreshSetting;
bool gFlagSaveVfo;
bool gFlagSaveSettings;
bool gFlagSaveChannel;
#ifdef ENABLE_FMRADIO
bool gFlagSaveFM;
#endif
uint8_t gDTMF_RequestPending;
bool g_CDCSS_Lost;
uint8_t gCDCSSCodeType;
bool g_CTCSS_Lost;
bool g_CxCSS_TAIL_Found;
bool g_VOX_Lost;
#ifdef ENABLE_VOX
bool g_VOX_Lost;
bool gVOX_NoiseDetected;
uint16_t gVoxResumeCountdown;
uint16_t gVoxPauseCountdown;
#endif
bool g_SquelchLost;
uint8_t gFlashLightState;
bool gVOX_NoiseDetected;
uint16_t gVoxResumeCountdown;
uint16_t gVoxPauseCountdown;
volatile uint16_t gFlashLightBlinkCounter;
bool gFlagEndTransmission;
uint16_t gLowBatteryCountdown;
uint8_t gNextMrChannel;
ReceptionMode_t gRxReceptionMode;
uint8_t gRestoreMrChannel;
uint8_t gCurrentScanList;
uint8_t gPreviousMrChannel;
uint32_t gRestoreFrequency;
uint8_t gRxVfoIsActive;
bool gRxVfoIsActive;
#ifdef ENABLE_ALARM
uint8_t gAlarmToneCounter;
uint16_t gAlarmRunningCounter;
@@ -200,13 +216,12 @@ bool gKeyBeingHeld;
bool gPttIsPressed;
uint8_t gPttDebounceCounter;
uint8_t gMenuListCount;
uint8_t gBackupCROSS_BAND_RX_TX;
uint8_t gBackup_CROSS_BAND_RX_TX;
uint8_t gScanDelay_10ms;
#ifdef ENABLE_AIRCOPY
uint8_t gAircopySendCountdown;
#endif
uint8_t gFSKWriteIndex;
uint8_t gNeverUsed;
#ifdef ENABLE_NOAA
bool gIsNoaaMode;
@@ -214,13 +229,17 @@ uint8_t gNeverUsed;
#endif
bool gUpdateDisplay;
bool gF_LOCK;
bool gF_LOCK = false;
uint8_t gShowChPrefix;
volatile bool gNextTimeslice;
volatile uint8_t gFoundCDCSSCountdown_10ms;
volatile uint8_t gFoundCTCSSCountdown_10ms;
volatile uint16_t gVoxStopCountdown_10ms;
#ifdef ENABLE_VOX
volatile uint16_t gVoxStopCountdown_10ms;
#endif
volatile bool gNextTimeslice40ms;
#ifdef ENABLE_NOAA
volatile uint16_t gNOAACountdown_10ms = 0;
@@ -237,34 +256,7 @@ int16_t gCurrentRSSI[2] = {0, 0}; // now one per VFO
uint8_t gIsLocked = 0xFF;
// --------
void NUMBER_Get(char *pDigits, uint32_t *pInteger)
{
unsigned int i;
uint32_t Multiplier = 10000000;
uint32_t Value = 0;
for (i = 0; i < 8; i++)
{
if (pDigits[i] > 9)
break;
Value += pDigits[i] * Multiplier;
Multiplier /= 10U;
}
*pInteger = Value;
}
void NUMBER_ToDigits(uint32_t Value, char *pDigits)
{
unsigned int i;
for (i = 0; i < 8; i++)
{
const uint32_t Result = Value / 10U;
pDigits[7 - i] = Value - (Result * 10U);
Value = Result;
}
pDigits[8] = 0;
}
int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit)
{
@@ -278,3 +270,15 @@ int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit,
return Base;
}
unsigned long StrToUL(const char * str)
{
unsigned long ul = 0;
for(uint8_t i = 0; i < strlen(str); i++){
char c = str[i];
if(c < '0' || c > '9')
break;
ul = ul * 10 + (uint8_t)(c-'0');
}
return ul;
}

149
misc.h
View File

@@ -24,31 +24,34 @@
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#endif
#define IS_MR_CHANNEL(x) ((x) >= MR_CHANNEL_FIRST && (x) <= MR_CHANNEL_LAST)
#define IS_FREQ_CHANNEL(x) ((x) >= FREQ_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST)
#define IS_VALID_CHANNEL(x) ((x) < LAST_CHANNEL)
#ifdef ENABLE_NOAA
#define IS_NOAA_CHANNEL(x) ((x) >= NOAA_CHANNEL_FIRST && (x) <= NOAA_CHANNEL_LAST)
#define IS_NOT_NOAA_CHANNEL(x) ((x) >= MR_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST)
#ifndef MAX
#define MAX(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; })
#endif
#ifndef MIN
#define MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
#endif
#define IS_MR_CHANNEL(x) ((x) <= MR_CHANNEL_LAST)
#define IS_FREQ_CHANNEL(x) ((x) >= FREQ_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST)
#define IS_VALID_CHANNEL(x) ((x) < LAST_CHANNEL)
#define IS_NOAA_CHANNEL(x) ((x) >= NOAA_CHANNEL_FIRST && (x) <= NOAA_CHANNEL_LAST)
enum {
MR_CHANNEL_FIRST = 0,
MR_CHANNEL_LAST = 199u,
FREQ_CHANNEL_FIRST = 200u,
FREQ_CHANNEL_LAST = 206u,
#ifdef ENABLE_NOAA
NOAA_CHANNEL_FIRST = 207u,
NOAA_CHANNEL_LAST = 216u,
#endif
NOAA_CHANNEL_FIRST = 207u,
NOAA_CHANNEL_LAST = 216u,
LAST_CHANNEL
};
enum {
FLASHLIGHT_OFF = 0,
FLASHLIGHT_ON,
FLASHLIGHT_BLINK
FLASHLIGHT_BLINK,
FLASHLIGHT_SOS
};
enum {
@@ -63,7 +66,6 @@ enum AlarmState_t {
ALARM_STATE_ALARM,
ALARM_STATE_TX1750
};
typedef enum AlarmState_t AlarmState_t;
enum ReceptionMode_t {
@@ -71,30 +73,31 @@ enum ReceptionMode_t {
RX_MODE_DETECTED, // signal detected
RX_MODE_LISTENING //
};
typedef enum ReceptionMode_t ReceptionMode_t;
enum CssScanMode_t
{
CSS_SCAN_MODE_OFF = 0,
CSS_SCAN_MODE_SCANNING,
CSS_SCAN_MODE_FOUND,
enum BacklightOnRxTx_t {
BACKLIGHT_ON_TR_OFF,
BACKLIGHT_ON_TR_TX,
BACKLIGHT_ON_TR_RX,
BACKLIGHT_ON_TR_TXRX
};
typedef enum CssScanMode_t CssScanMode_t;
extern const uint8_t fm_resume_countdown_500ms;
extern const uint8_t fm_radio_countdown_500ms;
extern const uint16_t fm_play_countdown_scan_10ms;
extern const uint16_t fm_play_countdown_noscan_10ms;
extern const uint16_t fm_restore_countdown_10ms;
extern const uint8_t vfo_state_resume_countdown_500ms;
extern const uint8_t menu_timeout_500ms;
extern const uint16_t menu_timeout_long_500ms;
extern const uint8_t DTMF_RX_live_timeout_500ms;
#ifdef ENABLE_DTMF_CALLING
extern const uint8_t DTMF_RX_timeout_500ms;
extern const uint8_t DTMF_decode_ring_countdown_500ms;
extern const uint8_t DTMF_txstop_countdown_500ms;
#endif
extern const uint8_t key_input_timeout_500ms;
@@ -109,7 +112,9 @@ extern const uint16_t battery_save_count_10ms;
extern const uint16_t power_save1_10ms;
extern const uint16_t power_save2_10ms;
extern const uint16_t vox_stop_count_down_10ms;
#ifdef ENABLE_VOX
extern const uint16_t vox_stop_count_down_10ms;
#endif
extern const uint16_t NOAA_countdown_10ms;
extern const uint16_t NOAA_countdown_2_10ms;
@@ -121,24 +126,35 @@ extern const uint16_t dual_watch_count_after_1_10ms;
extern const uint16_t dual_watch_count_after_2_10ms;
extern const uint16_t dual_watch_count_toggle_10ms;
extern const uint16_t dual_watch_count_noaa_10ms;
extern const uint16_t dual_watch_count_after_vox_10ms;
#ifdef ENABLE_VOX
extern const uint16_t dual_watch_count_after_vox_10ms;
#endif
extern const uint16_t scan_pause_delay_in_1_10ms;
extern const uint16_t scan_pause_delay_in_2_10ms;
extern const uint16_t scan_pause_delay_in_3_10ms;
extern const uint16_t scan_pause_delay_in_4_10ms;
extern const uint16_t scan_pause_delay_in_5_10ms;
extern const uint16_t scan_pause_delay_in_6_10ms;
extern const uint16_t scan_pause_delay_in_7_10ms;
//extern const uint16_t gMax_bat_v;
//extern const uint16_t gMin_bat_v;
extern const uint8_t gMicGain_dB2[5];
extern bool gSetting_350TX;
#ifdef ENABLE_DTMF_CALLING
extern bool gSetting_KILLED;
#endif
extern bool gSetting_200TX;
extern bool gSetting_500TX;
extern bool gSetting_350EN;
extern bool gSetting_TX_EN;
extern uint8_t gSetting_F_LOCK;
extern bool gSetting_ScrambleEnable;
extern uint8_t gSetting_backlight_on_tx_rx;
#ifdef ENABLE_AM_FIX
extern bool gSetting_AM_fix;
#endif
@@ -159,17 +175,23 @@ extern bool bHasCustomAesKey;
extern uint32_t gChallenge[4];
extern uint8_t gTryCount;
extern uint8_t gEEPROM_1EC0_0[8];
extern uint8_t gEEPROM_1EC0_1[8];
extern uint8_t gEEPROM_1EC0_2[8];
extern uint8_t gEEPROM_1EC0_3[8];
extern uint16_t gEEPROM_RSSI_CALIB[2][4];
extern uint16_t gEEPROM_RSSI_CALIB[7][4];
extern uint16_t gEEPROM_1F8A;
extern uint16_t gEEPROM_1F8C;
extern uint8_t gMR_ChannelAttributes[207];
typedef union {
struct {
uint8_t
band : 4,
compander : 2,
scanlist2 : 1,
scanlist1 : 1;
};
uint8_t __val;
} ChannelAttributes_t;
extern ChannelAttributes_t gMR_ChannelAttributes[207];
extern volatile uint16_t gBatterySaveCountdown_10ms;
@@ -179,9 +201,10 @@ extern volatile bool gSchedulePowerSave;
extern volatile bool gScheduleDualWatch;
extern volatile uint16_t gDualWatchCountdown_10ms;
extern volatile bool gDualWatchCountdownExpired;
extern bool gDualWatchActive;
extern volatile uint8_t gSerialConfigCountDown_500ms;
extern volatile bool gNextTimeslice_500ms;
extern volatile uint16_t gTxTimerCountdown_500ms;
@@ -208,12 +231,27 @@ extern bool gEndOfRxDetectedMaybe;
extern int16_t gVFO_RSSI[2];
extern uint8_t gVFO_RSSI_bar_level[2];
// battery critical, limit functionality to minimum
extern uint8_t gReducedService;
extern uint8_t gBatteryVoltageIndex;
extern CssScanMode_t gCssScanMode;
// we are searching CTCSS/DCS inside RX ctcss/dcs menu
extern bool gCssBackgroundScan;
enum
{
SCAN_REV = -1,
SCAN_OFF = 0,
SCAN_FWD = +1
};
extern volatile bool gScheduleScanListen;
extern volatile uint16_t gScanPauseDelayIn_10ms;
extern bool gUpdateRSSI;
extern AlarmState_t gAlarmState;
extern uint8_t gVoltageMenuCountdown;
extern uint16_t gMenuCountdown;
extern bool gPttWasReleased;
extern bool gPttWasPressed;
extern bool gFlagReconfigureVfos;
@@ -227,68 +265,72 @@ extern bool gRequestSaveSettings;
#endif
extern uint8_t gKeypadLocked;
extern bool gFlagPrepareTX;
extern bool gFlagAcceptSetting;
extern bool gFlagRefreshSetting;
extern bool gFlagAcceptSetting; // accept menu setting
extern bool gFlagRefreshSetting; // refresh menu display
extern bool gFlagSaveVfo;
extern bool gFlagSaveSettings;
extern bool gFlagSaveChannel;
#ifdef ENABLE_FMRADIO
extern bool gFlagSaveFM;
#endif
extern uint8_t gDTMF_RequestPending;
extern bool g_CDCSS_Lost;
extern uint8_t gCDCSSCodeType;
extern bool g_CTCSS_Lost;
extern bool g_CxCSS_TAIL_Found;
extern bool g_VOX_Lost;
#ifdef ENABLE_VOX
extern bool g_VOX_Lost;
extern bool gVOX_NoiseDetected;
extern uint16_t gVoxResumeCountdown;
extern uint16_t gVoxPauseCountdown;
#endif
// true means we are receiving signal
extern bool g_SquelchLost;
extern uint8_t gFlashLightState;
extern bool gVOX_NoiseDetected;
extern uint16_t gVoxResumeCountdown;
extern uint16_t gVoxPauseCountdown;
extern volatile uint16_t gFlashLightBlinkCounter;
extern bool gFlagEndTransmission;
extern uint16_t gLowBatteryCountdown;
extern uint8_t gNextMrChannel;
extern ReceptionMode_t gRxReceptionMode;
extern uint8_t gRestoreMrChannel;
extern uint8_t gCurrentScanList;
extern uint8_t gPreviousMrChannel;
extern uint32_t gRestoreFrequency;
extern uint8_t gRxVfoIsActive;
//TRUE when dual watch is momentarly suspended and RX_VFO is locked to either last TX or RX
extern bool gRxVfoIsActive;
extern uint8_t gAlarmToneCounter;
extern uint16_t gAlarmRunningCounter;
extern bool gKeyBeingHeld;
extern bool gPttIsPressed;
extern uint8_t gPttDebounceCounter;
extern uint8_t gMenuListCount;
extern uint8_t gBackupCROSS_BAND_RX_TX;
extern uint8_t gBackup_CROSS_BAND_RX_TX;
extern uint8_t gScanDelay_10ms;
#ifdef ENABLE_AIRCOPY
extern uint8_t gAircopySendCountdown;
#endif
extern uint8_t gFSKWriteIndex;
extern uint8_t gNeverUsed;
#ifdef ENABLE_NOAA
extern bool gIsNoaaMode;
extern uint8_t gNoaaChannel;
#endif
extern volatile bool gNextTimeslice;
extern bool gUpdateDisplay;
extern bool gF_LOCK;
#ifdef ENABLE_FMRADIO
extern uint8_t gFM_ChannelPosition;
#endif
extern bool gF_LOCK;
extern uint8_t gShowChPrefix;
extern volatile uint8_t gFoundCDCSSCountdown_10ms;
extern volatile uint8_t gFoundCTCSSCountdown_10ms;
extern volatile uint16_t gVoxStopCountdown_10ms;
#ifdef ENABLE_VOX
extern volatile uint16_t gVoxStopCountdown_10ms;
#endif
extern volatile bool gNextTimeslice40ms;
#ifdef ENABLE_NOAA
extern volatile uint16_t gNOAACountdown_10ms;
extern volatile bool gScheduleNOAA;
#endif
extern volatile bool gFlagTailNoteEliminationComplete;
extern volatile uint8_t gVFOStateResumeCountdown_500ms;
#ifdef ENABLE_FMRADIO
extern volatile bool gScheduleFM;
#endif
@@ -296,9 +338,8 @@ extern int16_t gCurrentRSSI[2]; // now one per VFO
extern uint8_t gIsLocked;
extern volatile uint8_t boot_counter_10ms;
void NUMBER_Get(char *pDigits, uint32_t *pInteger);
void NUMBER_ToDigits(uint32_t Value, char *pDigits);
int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit);
unsigned long StrToUL(const char * str);
#endif

865
radio.c

File diff suppressed because it is too large Load Diff

95
radio.h
View File

@@ -21,15 +21,7 @@
#include <stdint.h>
#include "dcs.h"
enum {
MR_CH_BAND_MASK = 0x0F << 0,
#ifdef ENABLE_COMPANDER
MR_CH_COMPAND = 3u << 4, // new
#endif
MR_CH_SCANLIST2 = 1u << 6,
MR_CH_SCANLIST1 = 1u << 7
};
#include "frequencies.h"
enum {
RADIO_CHANNEL_UP = 0x01u,
@@ -42,40 +34,14 @@ enum {
};
enum PTT_ID_t {
PTT_ID_OFF = 0,
PTT_ID_BOT,
PTT_ID_EOT,
PTT_ID_BOTH
PTT_ID_OFF = 0, // OFF
PTT_ID_TX_UP, // BEGIN OF TX
PTT_ID_TX_DOWN, // END OF TX
PTT_ID_BOTH, // BOTH
PTT_ID_APOLLO // Apolo quindar tones
};
typedef enum PTT_ID_t PTT_ID_t;
#if 0
enum STEP_Setting_t
{
STEP_2_5kHz,
STEP_5_0kHz,
STEP_6_25kHz,
STEP_10_0kHz,
STEP_12_5kHz,
STEP_25_0kHz,
STEP_8_33kHz
};
#else
enum STEP_Setting_t
{
STEP_1_25kHz,
STEP_2_5kHz,
STEP_6_25kHz,
STEP_10_0kHz,
STEP_12_5kHz,
STEP_25_0kHz,
STEP_8_33kHz
};
#endif
typedef enum STEP_Setting_t STEP_Setting_t;
enum VfoState_t
{
VFO_STATE_NORMAL = 0,
@@ -86,9 +52,23 @@ enum VfoState_t
VFO_STATE_ALARM,
VFO_STATE_VOLTAGE_HIGH
};
typedef enum VfoState_t VfoState_t;
typedef enum {
MODULATION_FM,
MODULATION_AM,
MODULATION_USB,
#ifdef ENABLE_BYP_RAW_DEMODULATORS
MODULATION_BYP,
MODULATION_RAW,
#endif
MODULATION_UKNOWN
} ModulationMode_t;
extern const char gModulationStr[MODULATION_UKNOWN][4];
typedef struct
{
uint32_t Frequency;
@@ -101,7 +81,14 @@ typedef struct VFO_Info_t
{
FREQ_Config_t freq_config_RX;
FREQ_Config_t freq_config_TX;
// this is for a purpose of the FrequencyReverse function
// it points to freq_config_RX normally and to freq_config_TX if reverse function is active
//
FREQ_Config_t *pRX;
// this is for a purpose of the FrequencyReverse function
// it points to freq_config_TX normally and to freq_config_RX if reverse function is active
FREQ_Config_t *pTX;
uint32_t TX_OFFSET_FREQUENCY;
@@ -130,36 +117,39 @@ typedef struct VFO_Info_t
uint8_t SCANLIST2_PARTICIPATION;
uint8_t Band;
#ifdef ENABLE_DTMF_CALLING
uint8_t DTMF_DECODING_ENABLE;
#endif
PTT_ID_t DTMF_PTT_ID_TX_MODE;
uint8_t BUSY_CHANNEL_LOCK;
uint8_t AM_mode;
ModulationMode_t Modulation;
#ifdef ENABLE_COMPANDER
uint8_t Compander;
#endif
uint8_t Compander;
char Name[16];
} VFO_Info_t;
// Settings of the main VFO that is selected by the user
// The pointer follows gEeprom.TX_VFO index
extern VFO_Info_t *gTxVfo;
// Settings of the actual VFO that is now used for RX,
// It is being alternated by dual watch, and flipped by crossband
// The pointer follows gEeprom.RX_VFO
extern VFO_Info_t *gRxVfo;
// Equal to gTxVfo unless dual watch changes it on incomming transmition (this can only happen when XB off and DW on)
extern VFO_Info_t *gCurrentVfo;
extern DCS_CodeType_t gSelectedCodeType;
extern DCS_CodeType_t gCurrentCodeType;
extern uint8_t gSelectedCode;
extern STEP_Setting_t gStepSetting;
extern VfoState_t VfoState[2];
bool RADIO_CheckValidChannel(uint16_t ChNum, bool bCheckScanList, uint8_t RadioNum);
uint8_t RADIO_FindNextChannel(uint8_t ChNum, int8_t Direction, bool bCheckScanList, uint8_t RadioNum);
void RADIO_InitInfo(VFO_Info_t *pInfo, uint8_t ChannelSave, uint8_t ChIndex, uint32_t Frequency);
void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t Frequency);
void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure);
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo);
void RADIO_ApplyOffset(VFO_Info_t *pInfo);
@@ -169,11 +159,12 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0);
void RADIO_ConfigureNOAA(void);
#endif
void RADIO_SetTxParameters(void);
void RADIO_SetModulation(ModulationMode_t modulation);
void RADIO_SetVfoState(VfoState_t State);
void RADIO_PrepareTX(void);
void RADIO_EnableCxCSS(void);
void RADIO_PrepareCssTX(void);
void RADIO_SendEndOfTransmission(void);
#endif

View File

@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include "app/chFrScanner.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif
@@ -57,6 +58,7 @@ void SystickHandler(void)
gNextTimeslice_500ms = true;
DECREMENT_AND_TRIGGER(gTxTimerCountdown_500ms, gTxTimeoutReached);
DECREMENT(gSerialConfigCountDown_500ms);
}
if ((gGlobalSysTickCounter & 3) == 0)
@@ -76,20 +78,20 @@ void SystickHandler(void)
if (gCurrentFunction == FUNCTION_POWER_SAVE)
DECREMENT_AND_TRIGGER(gPowerSave_10ms, gPowerSaveCountdownExpired);
if (gScanState == SCAN_OFF && gCssScanMode == CSS_SCAN_MODE_OFF && gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
if (gScanStateDir == SCAN_OFF && !gCssBackgroundScan && gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_RECEIVE)
DECREMENT_AND_TRIGGER(gDualWatchCountdown_10ms, gScheduleDualWatch);
#ifdef ENABLE_NOAA
if (gScanState == SCAN_OFF && gCssScanMode == CSS_SCAN_MODE_OFF && gEeprom.DUAL_WATCH == DUAL_WATCH_OFF)
if (gScanStateDir == SCAN_OFF && !gCssBackgroundScan && gEeprom.DUAL_WATCH == DUAL_WATCH_OFF)
if (gIsNoaaMode && gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT)
if (gCurrentFunction != FUNCTION_RECEIVE)
DECREMENT_AND_TRIGGER(gNOAA_Countdown_10ms, gScheduleNOAA);
#endif
if (gScanState != SCAN_OFF || gCssScanMode == CSS_SCAN_MODE_SCANNING)
if (gScanStateDir != SCAN_OFF)
if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT)
DECREMENT_AND_TRIGGER(ScanPauseDelayIn_10ms, gScheduleScanListen);
DECREMENT_AND_TRIGGER(gScanPauseDelayIn_10ms, gScheduleScanListen);
DECREMENT_AND_TRIGGER(gTailNoteEliminationCountdown_10ms, gFlagTailNoteEliminationComplete);
@@ -103,7 +105,9 @@ void SystickHandler(void)
DECREMENT_AND_TRIGGER(gFmPlayCountdown_10ms, gScheduleFM);
#endif
DECREMENT(gVoxStopCountdown_10ms);
#ifdef ENABLE_VOX
DECREMENT(gVoxStopCountdown_10ms);
#endif
DECREMENT(boot_counter_10ms);
}

View File

@@ -86,22 +86,28 @@ void SETTINGS_SaveSettings(void)
State[3] = false;
#endif
State[4] = gEeprom.KEY_LOCK;
State[5] = gEeprom.VOX_SWITCH;
State[6] = gEeprom.VOX_LEVEL;
#ifdef ENABLE_VOX
State[5] = gEeprom.VOX_SWITCH;
State[6] = gEeprom.VOX_LEVEL;
#else
State[5] = false;
State[6] = 0;
#endif
State[7] = gEeprom.MIC_SENSITIVITY;
EEPROM_WriteBuffer(0x0E70, State);
State[0] = 0xFF;
State[0] = (gEeprom.BACKLIGHT_MIN << 4) + gEeprom.BACKLIGHT_MAX;
State[1] = gEeprom.CHANNEL_DISPLAY_MODE;
State[2] = gEeprom.CROSS_BAND_RX_TX;
State[3] = gEeprom.BATTERY_SAVE;
State[4] = gEeprom.DUAL_WATCH;
State[5] = gEeprom.BACKLIGHT;
State[6] = gEeprom.TAIL_NOTE_ELIMINATION;
State[5] = gEeprom.BACKLIGHT_TIME;
State[6] = gEeprom.TAIL_TONE_ELIMINATION;
State[7] = gEeprom.VFO_OPEN;
EEPROM_WriteBuffer(0x0E78, State);
State[0] = gEeprom.BEEP_CONTROL;
State[0] |= gEeprom.KEY_M_LONG_PRESS_ACTION << 1;
State[1] = gEeprom.KEY_1_SHORT_PRESS_ACTION;
State[2] = gEeprom.KEY_1_LONG_PRESS_ACTION;
State[3] = gEeprom.KEY_2_SHORT_PRESS_ACTION;
@@ -112,30 +118,35 @@ void SETTINGS_SaveSettings(void)
EEPROM_WriteBuffer(0x0E90, State);
memset(Password, 0xFF, sizeof(Password));
Password[0] = gEeprom.POWER_ON_PASSWORD;
EEPROM_WriteBuffer(0x0E98, State);
#ifdef ENABLE_VOICE
memset(State, 0xFF, sizeof(State));
State[0] = gEeprom.VOICE_PROMPT;
EEPROM_WriteBuffer(0x0EA0, State);
#ifdef ENABLE_PWRON_PASSWORD
Password[0] = gEeprom.POWER_ON_PASSWORD;
#endif
EEPROM_WriteBuffer(0x0E98, Password);
#ifdef ENABLE_ALARM
memset(State, 0xFF, sizeof(State));
#ifdef ENABLE_VOICE
State[0] = gEeprom.VOICE_PROMPT;
EEPROM_WriteBuffer(0x0EA0, State);
#endif
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
State[0] = gEeprom.ALARM_MODE;
#else
State[0] = false;
#endif
State[1] = gEeprom.ROGER;
State[2] = gEeprom.REPEATER_TAIL_TONE_ELIMINATION;
State[3] = gEeprom.TX_CHANNEL;
State[3] = gEeprom.TX_VFO;
State[4] = gEeprom.BATTERY_TYPE;
EEPROM_WriteBuffer(0x0EA8, State);
State[0] = gEeprom.DTMF_SIDE_TONE;
#ifdef ENABLE_DTMF_CALLING
State[1] = gEeprom.DTMF_SEPARATE_CODE;
State[2] = gEeprom.DTMF_GROUP_CALL_CODE;
State[3] = gEeprom.DTMF_DECODE_RESPONSE;
State[4] = gEeprom.DTMF_AUTO_RESET_TIME;
State[4] = gEeprom.DTMF_auto_reset_time;
#endif
State[5] = gEeprom.DTMF_PRELOAD_TIME / 10U;
State[6] = gEeprom.DTMF_FIRST_CODE_PERSIST_TIME / 10U;
State[7] = gEeprom.DTMF_HASH_CODE_PERSIST_TIME / 10U;
@@ -144,7 +155,9 @@ void SETTINGS_SaveSettings(void)
memset(State, 0xFF, sizeof(State));
State[0] = gEeprom.DTMF_CODE_PERSIST_TIME / 10U;
State[1] = gEeprom.DTMF_CODE_INTERVAL_TIME / 10U;
#ifdef ENABLE_DTMF_CALLING
State[2] = gEeprom.PERMIT_REMOTE_KILL;
#endif
EEPROM_WriteBuffer(0x0ED8, State);
State[0] = gEeprom.SCAN_LIST_DEFAULT;
@@ -160,12 +173,14 @@ void SETTINGS_SaveSettings(void)
memset(State, 0xFF, sizeof(State));
State[0] = gSetting_F_LOCK;
State[1] = gSetting_350TX;
#ifdef ENABLE_DTMF_CALLING
State[2] = gSetting_KILLED;
#endif
State[3] = gSetting_200TX;
State[4] = gSetting_500TX;
State[5] = gSetting_350EN;
State[6] = gSetting_ScrambleEnable;
if (!gSetting_TX_EN) State[7] &= ~(1u << 0);
//if (!gSetting_TX_EN) State[7] &= ~(1u << 0);
if (!gSetting_live_DTMF_decoder) State[7] &= ~(1u << 1);
State[7] = (State[7] & ~(3u << 2)) | ((gSetting_battery_text & 3u) << 2);
#ifdef ENABLE_AUDIO_BAR
@@ -174,17 +189,15 @@ void SETTINGS_SaveSettings(void)
#ifdef ENABLE_AM_FIX
if (!gSetting_AM_fix) State[7] &= ~(1u << 5);
#endif
State[7] = (State[7] & ~(3u << 6)) | ((gSetting_backlight_on_tx_rx & 3u) << 6);
EEPROM_WriteBuffer(0x0F40, State);
}
void SETTINGS_LoadChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO)
{
}
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode)
{
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(Channel))
if (!IS_NOAA_CHANNEL(Channel))
#endif
{
const uint16_t OffsetMR = Channel * 16;
@@ -208,13 +221,17 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
State[0] = pVFO->freq_config_RX.Code;
State[1] = pVFO->freq_config_TX.Code;
State[2] = (pVFO->freq_config_TX.CodeType << 4) | pVFO->freq_config_RX.CodeType;
State[3] = ((pVFO->AM_mode & 1u) << 4) | pVFO->TX_OFFSET_FREQUENCY_DIRECTION;
State[3] = (pVFO->Modulation << 4) | pVFO->TX_OFFSET_FREQUENCY_DIRECTION;
State[4] = 0
| (pVFO->BUSY_CHANNEL_LOCK << 4)
| (pVFO->OUTPUT_POWER << 2)
| (pVFO->CHANNEL_BANDWIDTH << 1)
| (pVFO->FrequencyReverse << 0);
State[5] = (pVFO->DTMF_PTT_ID_TX_MODE << 1) | (pVFO->DTMF_DECODING_ENABLE < 0);
State[5] = ((pVFO->DTMF_PTT_ID_TX_MODE & 7u) << 1)
#ifdef ENABLE_DTMF_CALLING
| ((pVFO->DTMF_DECODING_ENABLE & 1u) << 0)
#endif
;
State[6] = pVFO->STEP_SETTING;
State[7] = pVFO->SCRAMBLING_TYPE;
EEPROM_WriteBuffer(OffsetVFO + 8, State);
@@ -222,8 +239,9 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
SETTINGS_UpdateChannel(Channel, pVFO, true);
if (IS_MR_CHANNEL(Channel))
{
#ifndef KEEP_MEM_NAME
{ // it's a memory channel
#ifndef ENABLE_KEEP_MEM_NAME
// clear/reset the channel name
//memset(&State, 0xFF, sizeof(State));
memset(&State, 0x00, sizeof(State)); // follow the QS way
@@ -245,59 +263,55 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
}
}
void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep)
void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration)
{
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(Channel))
#endif
uint16_t buf[4];
EEPROM_WriteBuffer(0x1F40, batteryCalibration);
EEPROM_ReadBuffer( 0x1F48, buf, sizeof(buf));
buf[0] = batteryCalibration[4];
buf[1] = batteryCalibration[5];
EEPROM_WriteBuffer(0x1F48, buf);
}
void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep)
{
#ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(channel))
#endif
{
uint8_t State[8];
uint8_t Attributes = 0xFF; // default attributes
#ifdef ENABLE_COMPANDER
Attributes &= ~MR_CH_COMPAND; // default to '0' = compander disabled
#endif
uint16_t Offset = 0x0D60 + (Channel & ~7u);
uint8_t state[8];
ChannelAttributes_t att = {
.band = 0xf,
.compander = 0,
.scanlist1 = 0,
.scanlist2 = 0,
}; // default attributes
EEPROM_ReadBuffer(Offset, State, sizeof(State));
uint16_t offset = 0x0D60 + (channel & ~7u);
EEPROM_ReadBuffer(offset, state, sizeof(state));
if (keep)
{
#ifdef ENABLE_COMPANDER
Attributes = (pVFO->SCANLIST1_PARTICIPATION << 7) | (pVFO->SCANLIST2_PARTICIPATION << 6) | (pVFO->Compander << 4) | (pVFO->Band << 0);
#else
Attributes = (pVFO->SCANLIST1_PARTICIPATION << 7) | (pVFO->SCANLIST2_PARTICIPATION << 6) | (pVFO->Band << 0);
#endif
if (State[Channel & 7u] == Attributes)
if (keep) {
att.band = pVFO->Band;
att.scanlist1 = pVFO->SCANLIST1_PARTICIPATION;
att.scanlist2 = pVFO->SCANLIST2_PARTICIPATION;
att.compander = pVFO->Compander;
if (state[channel & 7u] == att.__val)
return; // no change in the attributes
}
State[Channel & 7u] = Attributes;
state[channel & 7u] = att.__val;
EEPROM_WriteBuffer(offset, state);
EEPROM_WriteBuffer(Offset, State);
gMR_ChannelAttributes[channel] = att;
gMR_ChannelAttributes[Channel] = Attributes;
// #ifndef KEEP_MEM_NAME
if (IS_MR_CHANNEL(Channel))
{
const uint16_t OffsetMR = Channel * 16;
if (!keep)
{ // clear/reset the channel name
//memset(&State, 0xFF, sizeof(State));
memset(&State, 0x00, sizeof(State)); // follow the QS way
EEPROM_WriteBuffer(0x0F50 + OffsetMR, State);
EEPROM_WriteBuffer(0x0F58 + OffsetMR, State);
}
// else
// { // update the channel name
// memmove(State, pVFO->Name + 0, 8);
// EEPROM_WriteBuffer(0x0F50 + OffsetMR, State);
// //memset(State, 0xFF, sizeof(State));
// memset(State, 0x00, sizeof(State)); // follow the QS way
// memmove(State, pVFO->Name + 8, 2);
// EEPROM_WriteBuffer(0x0F58 + OffsetMR, State);
// }
if (IS_MR_CHANNEL(channel)) { // it's a memory channel
const uint16_t OffsetMR = channel * 16;
if (!keep) {
// clear/reset the channel name
memset(&state, 0x00, sizeof(state));
EEPROM_WriteBuffer(0x0F50 + OffsetMR, state);
EEPROM_WriteBuffer(0x0F58 + OffsetMR, state);
}
// #endif
}
}
}

View File

@@ -20,7 +20,10 @@
#include <stdbool.h>
#include <stdint.h>
#include "frequencies.h"
#include <helper/battery.h>
#include "radio.h"
#include <driver/backlight.h>
enum POWER_OnDisplayMode_t {
POWER_ON_DISPLAY_MODE_FULL_SCREEN = 0,
@@ -28,16 +31,18 @@ enum POWER_OnDisplayMode_t {
POWER_ON_DISPLAY_MODE_VOLTAGE,
POWER_ON_DISPLAY_MODE_NONE
};
typedef enum POWER_OnDisplayMode_t POWER_OnDisplayMode_t;
enum {
F_LOCK_OFF = 0,
F_LOCK_DEF, //all default frequencies + configurable
F_LOCK_FCC,
F_LOCK_CE,
F_LOCK_GB,
F_LOCK_430,
F_LOCK_438
F_LOCK_438,
F_LOCK_ALL, // disable TX on all frequencies
F_LOCK_NONE, // enable TX on all frequencies
F_LOCK_LEN
};
enum {
@@ -80,6 +85,13 @@ enum {
ACTION_OPT_ALARM,
ACTION_OPT_FM,
ACTION_OPT_1750,
ACTION_OPT_KEYLOCK,
ACTION_OPT_A_B,
ACTION_OPT_VFO_MR,
ACTION_OPT_SWITCH_DEMODUL,
#ifdef ENABLE_BLMIN_TMP_OFF
ACTION_OPT_BLMIN_TMP_OFF, //BackLight Minimum Temporay OFF
#endif
ACTION_OPT_LEN
};
@@ -90,7 +102,6 @@ enum {
VOICE_PROMPT_CHINESE,
VOICE_PROMPT_ENGLISH
};
typedef enum VOICE_Prompt_t VOICE_Prompt_t;
#endif
@@ -98,7 +109,6 @@ enum ALARM_Mode_t {
ALARM_MODE_SITE = 0,
ALARM_MODE_TONE
};
typedef enum ALARM_Mode_t ALARM_Mode_t;
enum ROGER_Mode_t {
@@ -106,7 +116,6 @@ enum ROGER_Mode_t {
ROGER_MODE_ROGER,
ROGER_MODE_MDC
};
typedef enum ROGER_Mode_t ROGER_Mode_t;
enum CHANNEL_DisplayMode_t {
@@ -115,23 +124,36 @@ enum CHANNEL_DisplayMode_t {
MDF_NAME,
MDF_NAME_FREQ
};
typedef enum CHANNEL_DisplayMode_t CHANNEL_DisplayMode_t;
typedef struct {
uint8_t ScreenChannel[2];
uint8_t FreqChannel[2];
uint8_t MrChannel[2];
uint8_t ScreenChannel[2]; // current channels set in the radio (memory or frequency channels)
uint8_t FreqChannel[2]; // last frequency channels used
uint8_t MrChannel[2]; // last memory channels used
#ifdef ENABLE_NOAA
uint8_t NoaaChannel[2];
#endif
uint8_t RX_CHANNEL;
uint8_t TX_CHANNEL;
// The actual VFO index (0-upper/1-lower) that is now used for RX,
// It is being alternated by dual watch, and flipped by crossband
uint8_t RX_VFO;
// The main VFO index (0-upper/1-lower) selected by the user
//
uint8_t TX_VFO;
uint8_t field7_0xa;
uint8_t field8_0xb;
uint32_t POWER_ON_PASSWORD;
#ifdef ENABLE_FMRADIO
uint16_t FM_SelectedFrequency;
uint8_t FM_SelectedChannel;
bool FM_IsMrMode;
uint16_t FM_FrequencyPlaying;
uint16_t FM_LowerLimit;
uint16_t FM_UpperLimit;
#endif
uint8_t SQUELCH_LEVEL;
uint8_t TX_TIMEOUT_TIMER;
bool KEY_LOCK;
@@ -142,12 +164,12 @@ typedef struct {
#endif
bool BEEP_CONTROL;
uint8_t CHANNEL_DISPLAY_MODE;
bool TAIL_NOTE_ELIMINATION;
bool TAIL_TONE_ELIMINATION;
bool VFO_OPEN;
uint8_t DUAL_WATCH;
uint8_t CROSS_BAND_RX_TX;
uint8_t BATTERY_SAVE;
uint8_t BACKLIGHT;
uint8_t BACKLIGHT_TIME;
uint8_t SCAN_RESUME_MODE;
uint8_t SCAN_LIST_DEFAULT;
bool SCAN_LIST_ENABLED[2];
@@ -156,27 +178,12 @@ typedef struct {
uint8_t field29_0x26;
uint8_t field30_0x27;
uint16_t VOX1_THRESHOLD;
uint16_t VOX0_THRESHOLD;
#ifdef ENABLE_FMRADIO
uint16_t FM_SelectedFrequency;
uint8_t FM_SelectedChannel;
bool FM_IsMrMode;
uint16_t FM_FrequencyPlaying;
#endif
uint8_t field37_0x32;
uint8_t field38_0x33;
#ifdef ENABLE_FMRADIO
uint16_t FM_LowerLimit;
uint16_t FM_UpperLimit;
#endif
bool AUTO_KEYPAD_LOCK;
#ifdef ENABLE_ALARM
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
ALARM_Mode_t ALARM_MODE;
#endif
POWER_OnDisplayMode_t POWER_ON_DISPLAY_MODE;
@@ -189,9 +196,11 @@ typedef struct {
uint8_t MIC_SENSITIVITY;
uint8_t MIC_SENSITIVITY_TUNING;
uint8_t CHAN_1_CALL;
#ifdef ENABLE_DTMF_CALLING
char ANI_DTMF_ID[8];
char KILL_CODE[8];
char REVIVE_CODE[8];
#endif
char DTMF_UP_CODE[16];
uint8_t field57_0x6c;
@@ -202,17 +211,21 @@ typedef struct {
uint8_t field60_0x7e;
uint8_t field61_0x7f;
#ifdef ENABLE_DTMF_CALLING
char DTMF_SEPARATE_CODE;
char DTMF_GROUP_CALL_CODE;
uint8_t DTMF_DECODE_RESPONSE;
uint8_t DTMF_AUTO_RESET_TIME;
uint8_t DTMF_auto_reset_time;
#endif
uint16_t DTMF_PRELOAD_TIME;
uint16_t DTMF_FIRST_CODE_PERSIST_TIME;
uint16_t DTMF_HASH_CODE_PERSIST_TIME;
uint16_t DTMF_CODE_PERSIST_TIME;
uint16_t DTMF_CODE_INTERVAL_TIME;
bool DTMF_SIDE_TONE;
#ifdef ENABLE_DTMF_CALLING
bool PERMIT_REMOTE_KILL;
#endif
int16_t BK4819_XTAL_FREQ_LOW;
#ifdef ENABLE_NOAA
bool NOAA_AUTO_SCAN;
@@ -220,11 +233,22 @@ typedef struct {
uint8_t VOLUME_GAIN;
uint8_t DAC_GAIN;
VFO_Info_t VfoInfo[2];
uint32_t POWER_ON_PASSWORD;
uint16_t VOX1_THRESHOLD;
uint16_t VOX0_THRESHOLD;
uint8_t field77_0x95;
uint8_t field78_0x96;
uint8_t field79_0x97;
VFO_Info_t VfoInfo[2];
uint8_t KEY_M_LONG_PRESS_ACTION;
uint8_t BACKLIGHT_MIN;
#ifdef ENABLE_BLMIN_TMP_OFF
BLMIN_STAT_t BACKLIGHT_MIN_STAT;
#endif
uint8_t BACKLIGHT_MAX;
BATTERY_Type_t BATTERY_TYPE;
} EEPROM_Config_t;
extern EEPROM_Config_t gEeprom;
@@ -235,6 +259,7 @@ extern EEPROM_Config_t gEeprom;
void SETTINGS_SaveVfoIndices(void);
void SETTINGS_SaveSettings(void);
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode);
void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep);
void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration);
void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep);
#endif

View File

@@ -44,12 +44,19 @@ void UI_DisplayAircopy(void)
if (gInputBoxIndex == 0)
{
NUMBER_ToDigits(gRxVfo->freq_config_RX.Frequency, String);
UI_DisplayFrequency(String, 16, 2, 0, 0);
UI_DisplaySmallDigits(2, String + 6, 97, 3, true);
uint32_t frequency = gRxVfo->freq_config_RX.Frequency;
sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000);
// show the remaining 2 small frequency digits
UI_PrintStringSmall(String + 7, 97, 0, 3);
String[7] = 0;
// show the main large frequency digits
UI_DisplayFrequency(String, 16, 2, false);
}
else {
const char * ascii = INPUTBOX_GetAscii();
sprintf(String, "%.3s.%.3s",ascii, ascii + 3);
UI_DisplayFrequency(String, 16, 2, false);
}
else
UI_DisplayFrequency(gInputBox, 16, 2, 1, 0);
memset(String, 0, sizeof(String));
if (gAirCopyIsSendMode == 0)

View File

@@ -22,66 +22,35 @@
#include "functions.h"
#include "ui/battery.h"
void UI_DisplayBattery(const uint8_t level, const uint8_t blink)
void UI_DrawBattery(uint8_t* bitmap, uint8_t level, uint8_t blink)
{
// if (gCurrentFunction != FUNCTION_TRANSMIT)
if (level < 2 && blink == 1) {
memset(bitmap, 0, sizeof(BITMAP_BatteryLevel1));
}
else
{
uint8_t bitmap[sizeof(BITMAP_BatteryLevel1)];
#if 1
if (level >= 2)
memmove(bitmap, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
if (level > 2)
{
memmove(bitmap, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
#ifndef ENABLE_REVERSE_BAT_SYMBOL
uint8_t *pb = bitmap + sizeof(BITMAP_BatteryLevel1);
if (level >= 2)
memmove(pb - 4, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
if (level >= 5)
memmove(pb - 7, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
if (level >= 7)
memmove(pb - 10, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
if (level >= 9)
memmove(pb - 13, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
#else
if (level >= 2)
memmove(bitmap + 3, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
if (level >= 5)
memmove(bitmap + 6, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
if (level >= 7)
memmove(bitmap + 9, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
if (level >= 9)
memmove(bitmap + 12, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
#endif
unsigned int i;
uint8_t bars = level - 2;
if (bars > 4)
bars = 4;
for (i = 0; i < bars; i++)
{
#ifndef ENABLE_REVERSE_BAT_SYMBOL
memcpy(bitmap + sizeof(BITMAP_BatteryLevel1) - 4 - (i * 3), BITMAP_BatteryLevel, 2);
#else
memcpy(bitmap + 3 + (i * 3) + 0, BITMAP_BatteryLevel, 2);
#endif
}
}
else
if (blink == 1)
memmove(bitmap, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
else
memset(bitmap, 0, sizeof(bitmap));
#else
if (level > 0)
{
const uint8_t lev = (level <= 11) ? level : 11;
memmove(bitmap, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
#ifdef ENABLE_REVERSE_BAT_SYMBOL
for (uint8_t i = 0; i < lev; i++)
bitmap[3 + i] = (i & 1u) ? 0b01011101 : 0b01011101;
#else
for (uint8_t i = 0; i < lev; i++)
bitmap[sizeof(bitmap) - 3 - i] = (i & 1u) ? 0b01011101 : 0b01011101;
#endif
}
else
memset(bitmap, 0, sizeof(bitmap));
#endif
// col lne, siz, bm
ST7565_DrawLine(LCD_WIDTH - sizeof(bitmap), 0, sizeof(bitmap), bitmap);
}
}
void UI_DisplayBattery(uint8_t level, uint8_t blink)
{
uint8_t bitmap[sizeof(BITMAP_BatteryLevel1)];
UI_DrawBattery(bitmap, level, blink);
ST7565_DrawLine(LCD_WIDTH - sizeof(bitmap), 0, sizeof(bitmap), bitmap);
}

View File

@@ -18,8 +18,8 @@
#define UI_BATTERY_H
#include <stdint.h>
void UI_DisplayBattery(const uint8_t Level, const uint8_t blink);
void UI_DrawBattery(uint8_t* bitmap, uint8_t level, uint8_t blink);
void UI_DisplayBattery(uint8_t Level, uint8_t blink);
#endif

View File

@@ -90,11 +90,14 @@ void UI_DisplayFM(void)
{
if (gInputBoxIndex == 0)
{
NUMBER_ToDigits(gEeprom.FM_FrequencyPlaying * 10000, String);
UI_DisplayFrequency(String, 23, 4, false, true);
sprintf(String, "%3d.%d", gEeprom.FM_FrequencyPlaying / 10, gEeprom.FM_FrequencyPlaying % 10);
UI_DisplayFrequency(String, 32, 4, true);
}
else {
const char * ascii = INPUTBOX_GetAscii();
sprintf(String, "%.3s.%.1s",ascii, ascii + 3);
UI_DisplayFrequency(String, 32, 4, false);
}
else
UI_DisplayFrequency(gInputBox, 23, 4, true, false);
ST7565_BlitFullScreen();
return;

View File

@@ -21,6 +21,7 @@
#include "font.h"
#include "ui/helper.h"
#include "ui/inputbox.h"
#include "misc.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]))
@@ -72,12 +73,12 @@ void UI_PrintString(const char *pString, uint8_t Start, uint8_t End, uint8_t Lin
for (i = 0; i < Length; i++)
{
if (pString[i] >= ' ' && pString[i] < 127)
const unsigned int ofs = (unsigned int)Start + (i * Width);
if (pString[i] > ' ' && pString[i] < 127)
{
const unsigned int index = pString[i] - ' ';
const unsigned int ofs = (unsigned int)Start + (i * Width);
memmove(gFrameBuffer[Line + 0] + ofs, &gFontBig[index][0], 8);
memmove(gFrameBuffer[Line + 1] + ofs, &gFontBig[index][8], 7);
const unsigned int index = pString[i] - ' ' - 1;
memmove(gFrameBuffer[Line + 0] + ofs, &gFontBig[index][0], 7);
memmove(gFrameBuffer[Line + 1] + ofs, &gFontBig[index][7], 7);
}
}
}
@@ -87,17 +88,19 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_
const size_t Length = strlen(pString);
size_t i;
if (End > Start)
Start += (((End - Start) - (Length * 8)) + 1) / 2;
const unsigned int char_width = ARRAY_SIZE(gFontSmall[0]);
const unsigned int char_spacing = char_width + 1;
if (End > Start)
Start += (((End - Start) - (Length * char_spacing)) + 1) / 2;
uint8_t *pFb = gFrameBuffer[Line] + Start;
for (i = 0; i < Length; i++)
{
if (pString[i] >= 32)
if (pString[i] > ' ')
{
const unsigned int index = (unsigned int)pString[i] - 32;
const unsigned int index = (unsigned int)pString[i] - ' ' - 1;
if (index < ARRAY_SIZE(gFontSmall))
memmove(pFb + (i * char_spacing) + 1, &gFontSmall[index], char_width);
}
@@ -118,9 +121,9 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_
uint8_t *pFb = gFrameBuffer[Line] + Start;
for (i = 0; i < Length; i++)
{
if (pString[i] >= 32)
if (pString[i] > ' ')
{
const unsigned int index = (unsigned int)pString[i] - 32;
const unsigned int index = (unsigned int)pString[i] - ' ' - 1;
if (index < ARRAY_SIZE(gFontSmallBold))
memmove(pFb + (i * char_spacing) + 1, &gFontSmallBold[index], char_width);
}
@@ -135,126 +138,115 @@ void UI_PrintStringSmallBuffer(const char *pString, uint8_t *buffer)
const unsigned int char_spacing = char_width + 1;
for (i = 0; i < strlen(pString); i++)
{
if (pString[i] >= 32)
if (pString[i] > ' ')
{
const unsigned int index = (unsigned int)pString[i] - 32;
const unsigned int index = (unsigned int)pString[i] - ' ' - 1;
if (index < ARRAY_SIZE(gFontSmall))
memmove(buffer + (i * char_spacing) + 1, &gFontSmall[index], char_width);
}
}
}
void UI_DisplayFrequency(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero, bool bFlag)
void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center)
{
const unsigned int char_width = 13;
uint8_t *pFb0 = gFrameBuffer[Y] + X;
uint8_t *pFb1 = pFb0 + 128;
bool bCanDisplay = false;
unsigned int i = 0;
// MHz
while (i < 3)
{
const unsigned int Digit = pDigits[i++];
if (bDisplayLeadingZero || bCanDisplay || Digit > 0)
uint8_t len = strlen(string);
for(int i = 0; i < len; i++) {
char c = string[i];
if(c=='-') c = '9' + 1;
if (bCanDisplay || c != ' ')
{
bCanDisplay = true;
memmove(pFb0, gFontBigDigits[Digit], char_width);
memmove(pFb1, gFontBigDigits[Digit] + char_width, char_width);
if(c>='0' && c<='9' + 1) {
memcpy(pFb0 + 2, gFontBigDigits[c-'0'], char_width - 3);
memcpy(pFb1 + 2, gFontBigDigits[c-'0'] + char_width - 3, char_width - 3);
}
else if(c=='.') {
*pFb1 = 0x60; pFb0++; pFb1++;
*pFb1 = 0x60; pFb0++; pFb1++;
*pFb1 = 0x60; pFb0++; pFb1++;
continue;
}
}
else
if (bFlag)
{
else if (center) {
pFb0 -= 6;
pFb1 -= 6;
}
pFb0 += char_width;
pFb1 += char_width;
}
}
// decimal point
*pFb1 = 0x60; pFb0++; pFb1++;
*pFb1 = 0x60; pFb0++; pFb1++;
*pFb1 = 0x60; pFb0++; pFb1++;
// kHz
while (i < 6)
{
const unsigned int Digit = pDigits[i++];
memmove(pFb0, gFontBigDigits[Digit], char_width);
memmove(pFb1, gFontBigDigits[Digit] + char_width, char_width);
pFb0 += char_width;
pFb1 += char_width;
void UI_DrawPixelBuffer(uint8_t (*buffer)[128], uint8_t x, uint8_t y, bool black)
{
if(black)
buffer[y/8][x] |= 1 << (y%8);
else
buffer[y/8][x] &= ~(1 << (y%8));
}
static void sort(int16_t *a, int16_t *b)
{
if(*a > *b) {
int16_t t = *a;
*a = *b;
*b = t;
}
}
void UI_DisplayFrequencySmall(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero)
void UI_DrawLineBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black)
{
const unsigned int char_width = ARRAY_SIZE(gFontSmall[0]);
const unsigned int spacing = 1 + char_width;
uint8_t *pFb = gFrameBuffer[Y] + X;
bool bCanDisplay = false;
unsigned int i = 0;
// MHz
while (i < 3)
{
const unsigned int c = pDigits[i++];
if (bDisplayLeadingZero || bCanDisplay || c > 0)
{
#if 0
memmove(pFb + 1, gFontSmallDigits[c], char_width);
#else
const unsigned int index = (c < 10) ? '0' - 32 + c : '-' - 32;
memmove(pFb + 1, gFontSmall[index], char_width);
#endif
pFb += spacing;
bCanDisplay = true;
if(x2==x1) {
sort(&y1, &y2);
for(int16_t i = y1; i <= y2; i++) {
UI_DrawPixelBuffer(buffer, x1, i, black);
}
}
} else {
const int multipl = 1000;
int a = (y2-y1)*multipl / (x2-x1);
int b = y1 - a * x1 / multipl;
// decimal point
pFb++;
pFb++;
*pFb++ = 0x60;
*pFb++ = 0x60;
pFb++;
// kHz
while (i < 8)
{
const unsigned int c = pDigits[i++];
#if 0
memmove(pFb + 1, gFontSmallDigits[c], char_width);
#else
const unsigned int index = (c < 10) ? '0' - 32 + c : '-' - 32;
memmove(pFb + 1, gFontSmall[index], char_width);
#endif
pFb += spacing;
}
}
void UI_DisplaySmallDigits(const uint8_t size, const char *str, const uint8_t x, const uint8_t y, const bool display_leading_zeros)
{
const unsigned int char_width = ARRAY_SIZE(gFontSmall[0]);
const unsigned int spacing = 1 + char_width;
bool display = display_leading_zeros;
unsigned int xx;
unsigned int i;
for (i = 0, xx = x; i < size; i++)
{
const unsigned int c = (unsigned int)str[i];
if (c > 0)
display = true; // non '0'
if (display && c < 11)
sort(&x1, &x2);
for(int i = x1; i<= x2; i++)
{
#if 0
memmove(gFrameBuffer[y] + xx, gFontSmallDigits[c], char_width);
#else
const unsigned int index = (c < 10) ? '0' - 32 + c : '-' - 32;
memmove(gFrameBuffer[y] + xx + 1, gFontSmall[index], char_width);
#endif
xx += spacing;
UI_DrawPixelBuffer(buffer, i, i*a/multipl +b, black);
}
}
}
void UI_DrawRectangleBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black)
{
UI_DrawLineBuffer(buffer, x1,y1, x1,y2, black);
UI_DrawLineBuffer(buffer, x1,y1, x2,y1, black);
UI_DrawLineBuffer(buffer, x2,y1, x2,y2, black);
UI_DrawLineBuffer(buffer, x1,y2, x2,y2, black);
}
void UI_DisplayPopup(const char *string)
{
for(uint8_t i = 0; i < 7; i++) {
memset(gFrameBuffer[i], 0x00, 128);
}
// for(uint8_t i = 1; i < 5; i++) {
// memset(gFrameBuffer[i]+8, 0x00, 111);
// }
// for(uint8_t x = 10; x < 118; x++) {
// UI_DrawPixelBuffer(x, 10, true);
// UI_DrawPixelBuffer(x, 46-9, true);
// }
// for(uint8_t y = 11; y < 37; y++) {
// UI_DrawPixelBuffer(10, y, true);
// UI_DrawPixelBuffer(117, y, true);
// }
// DrawRectangle(9,9, 118,38, true);
UI_PrintString(string, 9, 118, 2, 8);
UI_PrintStringSmall("Press EXIT", 9, 118, 6);
}

View File

@@ -28,9 +28,12 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_
void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line);
#endif
void UI_PrintStringSmallBuffer(const char *pString, uint8_t *buffer);
void UI_DisplayFrequency(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero, bool bFlag);
void UI_DisplayFrequencySmall(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero);
void UI_DisplaySmallDigits(const uint8_t size, const char *str, const uint8_t x, const uint8_t y, const bool display_leading_zeros);
void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center);
#endif
void UI_DisplayPopup(const char *string);
void UI_DrawPixelBuffer(uint8_t (*buffer)[128], uint8_t x, uint8_t y, bool black);
void UI_DrawLineBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black);
void UI_DrawRectangleBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black);

View File

@@ -19,9 +19,10 @@
#include "ui/inputbox.h"
char gInputBox[8];
char inputBoxAscii[9];
uint8_t gInputBoxIndex;
void INPUTBOX_Append(char Digit)
void INPUTBOX_Append(const KEY_Code_t Digit)
{
if (gInputBoxIndex >= sizeof(gInputBox))
return;
@@ -29,6 +30,15 @@ void INPUTBOX_Append(char Digit)
if (gInputBoxIndex == 0)
memset(gInputBox, 10, sizeof(gInputBox));
gInputBox[gInputBoxIndex++] = Digit;
if (Digit != KEY_INVALID)
gInputBox[gInputBoxIndex++] = (char)(Digit - KEY_0);
}
const char* INPUTBOX_GetAscii()
{
for(int i = 0; i < 8; i++) {
char c = gInputBox[i];
inputBoxAscii[i] = (c==10)? '-' : '0' + c;
}
return inputBoxAscii;
}

View File

@@ -19,10 +19,13 @@
#include <stdint.h>
#include "driver/keyboard.h"
extern char gInputBox[8];
extern uint8_t gInputBoxIndex;
void INPUTBOX_Append(char Digit);
void INPUTBOX_Append(const KEY_Code_t Digit);
const char* INPUTBOX_GetAscii();
#endif

View File

@@ -14,6 +14,8 @@
* limitations under the License.
*/
#ifdef ENABLE_PWRON_PASSWORD
#include <string.h>
#include "ARMCM0.h"
@@ -100,10 +102,9 @@ void UI_DisplayLock(void)
uint32_t Password;
gInputBoxIndex = 0;
Password = StrToUL(INPUTBOX_GetAscii());
NUMBER_Get(gInputBox, &Password);
if ((gEeprom.POWER_ON_PASSWORD * 100) == Password)
if ((gEeprom.POWER_ON_PASSWORD) == Password)
{
AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL);
return;
@@ -156,3 +157,5 @@ void UI_DisplayLock(void)
}
}
}
#endif

View File

@@ -17,7 +17,9 @@
#ifndef UI_LOCK_H
#define UI_LOCK_H
void UI_DisplayLock(void);
#ifdef ENABLE_PWRON_PASSWORD
void UI_DisplayLock(void);
#endif
#endif

950
ui/main.c

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,19 @@
#ifndef UI_MAIN_H
#define UI_MAIN_H
enum center_line_t {
CENTER_LINE_NONE = 0,
CENTER_LINE_IN_USE,
CENTER_LINE_AUDIO_BAR,
CENTER_LINE_RSSI,
CENTER_LINE_AM_FIX_DATA,
CENTER_LINE_DTMF_DEC,
CENTER_LINE_CHARGE_DATA
};
typedef enum center_line_t center_line_t;
extern center_line_t center_line;
void UI_DisplayAudioBar(void);
void UI_UpdateRSSI(const int16_t rssi, const int vfo);
void UI_DisplayMain(void);

692
ui/menu.c

File diff suppressed because it is too large Load Diff

103
ui/menu.h
View File

@@ -21,6 +21,7 @@
#include <stdint.h>
#include "audio.h" // VOICE_ID_t
#include "settings.h"
typedef struct {
const char name[7]; // menu display area only has room for 6 characters
@@ -39,7 +40,6 @@ enum
MENU_T_CTCS,
MENU_SFT_D,
MENU_OFFSET,
MENU_XB,
MENU_TOT,
MENU_W_N,
MENU_SCR,
@@ -49,13 +49,18 @@ enum
MENU_MEM_NAME,
MENU_MDF,
MENU_SAVE,
#ifdef ENABLE_VOX
MENU_VOX,
#endif
MENU_ABR,
MENU_ABR_ON_TX_RX,
MENU_ABR_MIN,
MENU_ABR_MAX,
MENU_TDR,
MENU_BEEP,
#ifdef ENABLE_VOICE
MENU_VOICE,
#endif
#ifdef ENABLE_VOICE
MENU_VOICE,
#endif
MENU_SC_REV,
MENU_AUTOLK,
MENU_S_ADD1,
@@ -63,59 +68,68 @@ enum
MENU_STE,
MENU_RP_STE,
MENU_MIC,
#ifdef ENABLE_AUDIO_BAR
MENU_MIC_BAR,
#endif
#ifdef ENABLE_COMPANDER
MENU_COMPAND,
#endif
#ifdef ENABLE_AUDIO_BAR
MENU_MIC_BAR,
#endif
MENU_COMPAND,
MENU_1_CALL,
MENU_S_LIST,
MENU_SLIST1,
MENU_SLIST2,
#ifdef ENABLE_ALARM
MENU_AL_MOD,
#endif
#ifdef ENABLE_ALARM
MENU_AL_MOD,
#endif
#ifdef ENABLE_DTMF_CALLING
MENU_ANI_ID,
#endif
MENU_UPCODE,
MENU_DWCODE,
MENU_PTT_ID,
MENU_D_ST,
#ifdef ENABLE_DTMF_CALLING
MENU_D_RSP,
MENU_D_HOLD,
#endif
MENU_D_PRE,
MENU_PTT_ID,
#ifdef ENABLE_DTMF_CALLING
MENU_D_DCD,
MENU_D_LIST,
#endif
MENU_D_LIVE_DEC,
MENU_PONMSG,
MENU_ROGER,
MENU_VOL,
MENU_BAT_TXT,
MENU_AM,
#ifdef ENABLE_AM_FIX
MENU_AM_FIX,
#endif
#ifdef ENABLE_AM_FIX_TEST1
MENU_AM_FIX_TEST1,
#endif
#ifdef ENABLE_NOAA
MENU_NOAA_S,
#endif
#ifdef ENABLE_AM_FIX
MENU_AM_FIX,
#endif
#ifdef ENABLE_AM_FIX_TEST1
MENU_AM_FIX_TEST1,
#endif
#ifdef ENABLE_NOAA
MENU_NOAA_S,
#endif
MENU_RESET,
// items after here are normally hidden
MENU_F_LOCK,
MENU_200TX,
MENU_350TX,
MENU_500TX,
MENU_350EN,
MENU_SCREN,
MENU_TX_EN, // enable TX
MENU_F_CALI // reference xtal calibration
#ifdef ENABLE_F_CAL_MENU
MENU_F_CALI, // reference xtal calibration
#endif
MENU_BATCAL, // battery voltage calibration
MENU_F1SHRT,
MENU_F1LONG,
MENU_F2SHRT,
MENU_F2LONG,
MENU_MLONG,
MENU_BATTYP
};
extern const uint8_t FIRST_HIDDEN_MENU_ITEM;
extern const t_menu_item MenuList[];
extern const char gSubMenu_TXP[3][5];
@@ -124,36 +138,41 @@ extern const char gSubMenu_W_N[2][7];
extern const char gSubMenu_OFF_ON[2][4];
extern const char gSubMenu_SAVE[5][4];
extern const char gSubMenu_TOT[11][7];
extern const char gSubMenu_CHAN[3][7];
extern const char* gSubMenu_RXMode[4];
#ifdef ENABLE_VOICE
extern const char gSubMenu_VOICE[3][4];
#endif
extern const char gSubMenu_SC_REV[3][3];
extern const char gSubMenu_MDF[4][8];
extern const char gSubMenu_SC_REV[3][8];
extern const char* gSubMenu_MDF[4];
#ifdef ENABLE_ALARM
extern const char gSubMenu_AL_MOD[2][5];
#endif
extern const char gSubMenu_D_RSP[4][6];
extern const char gSubMenu_PTT_ID[4][5];
extern const char gSubMenu_PONMSG[4][5];
#ifdef ENABLE_DTMF_CALLING
extern const char gSubMenu_D_RSP[4][11];
#endif
extern const char* gSubMenu_PTT_ID[5];
extern const char gSubMenu_PONMSG[4][8];
extern const char gSubMenu_ROGER[3][6];
extern const char gSubMenu_RESET[2][4];
extern const char gSubMenu_F_LOCK[6][4];
extern const char* gSubMenu_F_LOCK[F_LOCK_LEN];
extern const char gSubMenu_BACKLIGHT[8][7];
#ifdef ENABLE_COMPANDER
extern const char gSubMenu_Compand[4][6];
#endif
extern const char gSubMenu_RX_TX[4][6];
#ifdef ENABLE_AM_FIX_TEST1
extern const char gSubMenu_AM_fix_test1[4][8];
#endif
extern const char gSubMenu_BAT_TXT[3][8];
extern const char gSubMenu_BATTYP[2][9];
extern const char gSubMenu_SCRAMBLER[11][7];
typedef struct {char* name; uint8_t id;} t_sidefunction;
extern const uint8_t gSubMenu_SIDEFUNCTIONS_size;
extern const t_sidefunction* gSubMenu_SIDEFUNCTIONS;
extern bool gIsInSubMenu;
extern uint8_t gMenuCursor;
extern int8_t gMenuScrollDirection;
extern int32_t gSubMenuSelection;
extern char edit_original[17];
@@ -161,5 +180,7 @@ extern char edit[17];
extern int edit_index;
void UI_DisplayMenu(void);
int UI_MENU_GetCurrentMenuId();
uint8_t UI_MENU_GetMenuIdx(uint8_t id);
#endif

View File

@@ -50,7 +50,7 @@ void UI_DisplayScanner(void)
UI_PrintString(String, 2, 0, 3, 8);
memset(String, 0, sizeof(String));
if (gScannerEditState == 2)
if (gScannerSaveState == SCAN_SAVE_CHANNEL)
{
strcpy(String, "SAVE?");
@@ -59,19 +59,15 @@ void UI_DisplayScanner(void)
}
else
{
if (gScannerEditState == 1)
{
if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
strcpy(String, "SAVE:");
UI_GenerateChannelStringEx(String + 5, gShowChPrefix, gScanChannel);
}
else
if (gScanCssState < SCAN_CSS_STATE_FOUND)
{
else if (gScanCssState < SCAN_CSS_STATE_FOUND) {
strcpy(String, "SCAN");
memset(String + 4, '.', (gScanProgressIndicator & 7) + 1);
}
else
if (gScanCssState == SCAN_CSS_STATE_FOUND)
else if (gScanCssState == SCAN_CSS_STATE_FOUND)
strcpy(String, "SCAN CMP.");
else
strcpy(String, "SCAN FAIL.");

View File

@@ -16,10 +16,11 @@
#include <string.h>
#include "app/scanner.h"
#include "app/chFrScanner.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif
#include "app/scanner.h"
#include "bitmaps.h"
#include "driver/keyboard.h"
#include "driver/st7565.h"
@@ -28,11 +29,12 @@
#include "helper/battery.h"
#include "misc.h"
#include "settings.h"
#include "ui/battery.h"
#include "ui/helper.h"
#include "ui/ui.h"
#include "ui/status.h"
void UI_DisplayStatus(const bool test_display)
void UI_DisplayStatus()
{
uint8_t *line = gStatusLine;
unsigned int x = 0;
@@ -45,16 +47,30 @@ void UI_DisplayStatus(const bool test_display)
// **************
// POWER-SAVE indicator
if (gCurrentFunction == FUNCTION_POWER_SAVE || test_display)
if (gCurrentFunction == FUNCTION_TRANSMIT)
{
memmove(line + x, BITMAP_PowerSave, sizeof(BITMAP_PowerSave));
x1 = x + sizeof(BITMAP_PowerSave);
memmove(line + x, BITMAP_TX, sizeof(BITMAP_TX));
x1 = x + sizeof(BITMAP_TX);
}
x += sizeof(BITMAP_PowerSave);
else
if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING)
{
memmove(line + x, BITMAP_RX, sizeof(BITMAP_RX));
x1 = x + sizeof(BITMAP_RX);
}
else
if (gCurrentFunction == FUNCTION_POWER_SAVE)
{
memmove(line + x, BITMAP_POWERSAVE, sizeof(BITMAP_POWERSAVE));
x1 = x + sizeof(BITMAP_POWERSAVE);
}
x += sizeof(BITMAP_POWERSAVE);
#ifdef ENABLE_NOAA
// NOASS SCAN indicator
if (gIsNoaaMode || test_display)
if (gIsNoaaMode)
{
memmove(line + x, BITMAP_NOAA, sizeof(BITMAP_NOAA));
x1 = x + sizeof(BITMAP_NOAA);
@@ -63,70 +79,80 @@ void UI_DisplayStatus(const bool test_display)
#else
// hmmm, what to put in it's place
#endif
#ifdef ENABLE_DTMF_CALLING
if (gSetting_KILLED)
{
memset(line + x, 0xFF, 10);
x1 = x + 10;
}
else
#ifdef ENABLE_FMRADIO
// FM indicator
if (gFmRadioMode || test_display)
{
memmove(line + x, BITMAP_FM, sizeof(BITMAP_FM));
x1 = x + sizeof(BITMAP_FM);
}
else
#endif
else
#endif
{
// SCAN indicator
if (gScanState != SCAN_OFF || gScreenToDisplay == DISPLAY_SCANNER || test_display)
if (gScanStateDir != SCAN_OFF || SCANNER_IsScanning())
{
memmove(line + x, BITMAP_SC, sizeof(BITMAP_SC));
x1 = x + sizeof(BITMAP_SC);
char * s = "";
if (IS_MR_CHANNEL(gNextMrChannel) && !SCANNER_IsScanning())
{ // channel mode
switch(gEeprom.SCAN_LIST_DEFAULT) {
case 0: s = "1"; break;
case 1: s = "2"; break;
case 2: s = "*"; break;
}
}
else
{ // frequency mode
s = "S";
}
UI_PrintStringSmallBuffer(s, line + x);
x1 = x + 7;
}
x += sizeof(BITMAP_SC);
}
x += 7; // font character width
#ifdef ENABLE_VOICE
// VOICE indicator
if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF || test_display)
if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF)
{
memmove(line + x, BITMAP_VoicePrompt, sizeof(BITMAP_VoicePrompt));
x1 = x + sizeof(BITMAP_VoicePrompt);
}
x += sizeof(BITMAP_VoicePrompt);
x += sizeof(BITMAP_VoicePrompt) + 1;
#else
// hmmm, what to put in it's place
#endif
// DUAL-WATCH indicator
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF || test_display)
{
if (gDualWatchActive || test_display)
memmove(line + x, BITMAP_TDR1, sizeof(BITMAP_TDR1));
else
memmove(line + x, BITMAP_TDR2, sizeof(BITMAP_TDR2));
x++;
if(!SCANNER_IsScanning()) {
uint8_t dw = (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2;
if(dw == 1 || dw == 3) { // DWR - dual watch + respond
if(gDualWatchActive)
memmove(line + x, BITMAP_TDR1, sizeof(BITMAP_TDR1) - (dw==1?0:5));
else
memmove(line + x + 3, BITMAP_TDR2, sizeof(BITMAP_TDR2));
}
else if(dw == 2) { // XB - crossband
memmove(line + x, BITMAP_XB, sizeof(BITMAP_XB));
}
}
x += sizeof(BITMAP_TDR1);
// CROSS-VFO indicator
if (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF || test_display)
{
memmove(line + x, BITMAP_XB, sizeof(BITMAP_XB));
x1 = x + sizeof(BITMAP_XB);
}
x += sizeof(BITMAP_XB);
x += sizeof(BITMAP_TDR1) + 2;
// VOX indicator
if (gEeprom.VOX_SWITCH || test_display)
{
memmove(line + x, BITMAP_VOX, sizeof(BITMAP_VOX));
x1 = x + sizeof(BITMAP_VOX);
}
x += sizeof(BITMAP_VOX);
#ifdef ENABLE_VOX
// VOX indicator
if (gEeprom.VOX_SWITCH)
{
memmove(line + x, BITMAP_VOX, sizeof(BITMAP_VOX));
x1 = x + sizeof(BITMAP_VOX);
}
x += sizeof(BITMAP_VOX) + 2;
#endif
x = MAX(x, 61u);
x1 = x;
// KEY-LOCK indicator
if (gEeprom.KEY_LOCK || test_display)
if (gEeprom.KEY_LOCK)
{
memmove(line + x, BITMAP_KeyLock, sizeof(BITMAP_KeyLock));
x += sizeof(BITMAP_KeyLock);
@@ -144,7 +170,7 @@ void UI_DisplayStatus(const bool test_display)
char s[8];
unsigned int space_needed;
unsigned int x2 = LCD_WIDTH - sizeof(BITMAP_BatteryLevel5) - 3;
unsigned int x2 = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - 3;
if (gChargingWithTypeC)
x2 -= sizeof(BITMAP_USB_C); // the radio is on charge
@@ -169,8 +195,7 @@ void UI_DisplayStatus(const bool test_display)
case 2: // percentage
{
const uint16_t percent = BATTERY_VoltsToPercent(gBatteryVoltageAverage);
sprintf(s, "%u%%", percent);
sprintf(s, "%u%%", BATTERY_VoltsToPercent(gBatteryVoltageAverage));
space_needed = (7 * strlen(s));
if (x2 >= (x1 + space_needed))
UI_PrintStringSmallBuffer(s, line + x2 - space_needed);
@@ -183,60 +208,13 @@ void UI_DisplayStatus(const bool test_display)
x = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - sizeof(BITMAP_USB_C);
// USB-C charge indicator
if (gChargingWithTypeC || test_display)
if (gChargingWithTypeC)
memmove(line + x, BITMAP_USB_C, sizeof(BITMAP_USB_C));
x += sizeof(BITMAP_USB_C);
// BATTERY LEVEL indicator
#if 1
if (gBatteryDisplayLevel >= 2 && !gLowBattery)
{
line += x;
memmove(line, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
#ifndef ENABLE_REVERSE_BAT_SYMBOL
line += sizeof(BITMAP_BatteryLevel1);
if (gBatteryDisplayLevel >= 2)
memmove(line - 4, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
if (gBatteryDisplayLevel >= 5)
memmove(line - 7, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
if (gBatteryDisplayLevel >= 7)
memmove(line - 10, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
if (gBatteryDisplayLevel >= 9)
memmove(line - 13, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
#else
if (gBatteryDisplayLevel >= 2)
memmove(line + 3, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
if (gBatteryDisplayLevel >= 5)
memmove(line + 6, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
if (gBatteryDisplayLevel >= 7)
memmove(line + 9, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
if (gBatteryDisplayLevel >= 9)
memmove(line + 12, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
#endif
}
else
if (gLowBatteryBlink == 1)
memmove(line + x, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
#else
// UI_DisplayBattery(gBatteryDisplayLevel);
line += x;
if (gBatteryDisplayLevel > 0)
{
const uint8_t level = (gBatteryDisplayLevel <= 11) ? gBatteryDisplayLevel : 11;
memmove(line, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
#ifdef ENABLE_REVERSE_BAT_SYMBOL
for (uint8_t i = 0; i < level; i++)
line[3 + i] = (i & 1u) ? 0b01011101 : 0b01011101;
#else
for (uint8_t i = 0; i < level; i++)
line[sizeof(BITMAP_BatteryLevel1) - 3 - i] = (i & 1u) ? 0b01011101 : 0b01011101;
#endif
}
else
memset(line, 0, sizeof(BITMAP_BatteryLevel1));
#endif
UI_DrawBattery(line + x, gBatteryDisplayLevel, gLowBatteryBlink);
// **************
ST7565_BlitStatusLine();

View File

@@ -17,7 +17,7 @@
#ifndef UI_STATUS_H
#define UI_STATUS_H
void UI_DisplayStatus(const bool test_display);
void UI_DisplayStatus();
#endif

48
ui/ui.c
View File

@@ -16,11 +16,11 @@
#include <string.h>
#include "app/chFrScanner.h"
#include "app/dtmf.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif
#include "app/scanner.h"
#include "driver/keyboard.h"
#include "misc.h"
#ifdef ENABLE_AIRCOPY
@@ -77,34 +77,28 @@ void GUI_DisplayScreen(void)
void GUI_SelectNextDisplay(GUI_DisplayType_t Display)
{
if (Display != DISPLAY_INVALID)
if (Display == DISPLAY_INVALID)
return;
if (gScreenToDisplay != Display)
{
if (gScreenToDisplay != Display)
{
gInputBoxIndex = 0;
gIsInSubMenu = false;
gCssScanMode = CSS_SCAN_MODE_OFF;
gScanState = SCAN_OFF;
#ifdef ENABLE_FMRADIO
gFM_ScanState = FM_SCAN_OFF;
#endif
gAskForConfirmation = 0;
gDTMF_InputMode = false;
gDTMF_InputIndex = 0;
gF_LOCK = false;
gAskToSave = false;
gAskToDelete = false;
DTMF_clear_input_box();
if (gWasFKeyPressed)
{
gWasFKeyPressed = false;
gUpdateStatus = true;
}
gInputBoxIndex = 0;
gIsInSubMenu = false;
gCssBackgroundScan = false;
gScanStateDir = SCAN_OFF;
#ifdef ENABLE_FMRADIO
gFM_ScanState = FM_SCAN_OFF;
#endif
gAskForConfirmation = 0;
gAskToSave = false;
gAskToDelete = false;
gWasFKeyPressed = false;
gUpdateStatus = true;
}
gUpdateDisplay = true;
gScreenToDisplay = Display;
gUpdateStatus = true;
}
gScreenToDisplay = Display;
gUpdateDisplay = true;
}

Some files were not shown because too many files have changed in this diff Show More