106 Commits
v0.12 ... v0.18

Author SHA1 Message Date
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
77 changed files with 3959 additions and 3480 deletions

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

@@ -0,0 +1,33 @@
on:
push:
jobs:
build:
runs-on: ubuntu-22.04
steps:
- name: arm-none-eabi-gcc
uses: carlosperate/arm-none-eabi-gcc-action@v1
with:
release: '10.3-2021.10'
- name: Install Python dependencies
run: python -m pip install --upgrade pip crcmod
- name: Checkout
uses: actions/checkout@v3
- name: Submodules
run: git submodule update --init --recursive --depth 1
- 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

45
.github/workflows/release.yaml vendored Normal file
View File

@@ -0,0 +1,45 @@
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-22.04
steps:
- name: arm-none-eabi-gcc
uses: carlosperate/arm-none-eabi-gcc-action@v1
with:
release: '10.3-2021.10'
- name: Install Python dependencies
run: python3 -m pip install --upgrade pip crcmod
- name: Checkout
uses: actions/checkout@v3
- name: Submodules
run: git submodule update --init --recursive --depth 1
- 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
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 }}

View File

@@ -22,11 +22,11 @@ ENABLE_KEEP_MEM_NAME := 1
ENABLE_WIDE_RX := 1 ENABLE_WIDE_RX := 1
ENABLE_TX_WHEN_AM := 0 ENABLE_TX_WHEN_AM := 0
ENABLE_F_CAL_MENU := 0 ENABLE_F_CAL_MENU := 0
ENABLE_CTCSS_TAIL_PHASE_SHIFT := 1 ENABLE_CTCSS_TAIL_PHASE_SHIFT := 0
ENABLE_BOOT_BEEPS := 0 ENABLE_BOOT_BEEPS := 0
ENABLE_SHOW_CHARGE_LEVEL := 1 ENABLE_SHOW_CHARGE_LEVEL := 1
ENABLE_REVERSE_BAT_SYMBOL := 0 ENABLE_REVERSE_BAT_SYMBOL := 0
ENABLE_CODE_SCAN_TIMEOUT := 0 ENABLE_NO_CODE_SCAN_TIMEOUT := 1
ENABLE_AM_FIX := 1 ENABLE_AM_FIX := 1
ENABLE_AM_FIX_SHOW_DATA := 0 ENABLE_AM_FIX_SHOW_DATA := 0
ENABLE_SQUELCH_MORE_SENSITIVE := 1 ENABLE_SQUELCH_MORE_SENSITIVE := 1
@@ -35,9 +35,9 @@ ENABLE_RSSI_BAR := 1
ENABLE_AUDIO_BAR := 1 ENABLE_AUDIO_BAR := 1
ENABLE_COPY_CHAN_TO_VFO := 1 ENABLE_COPY_CHAN_TO_VFO := 1
ENABLE_SPECTRUM := 1 ENABLE_SPECTRUM := 1
#ENABLE_SINGLE_VFO_CHAN := 1 ENABLE_REDUCE_LOW_MID_TX_POWER:= 0
#ENABLE_BAND_SCOPE := 1 ENABLE_BYP_RAW_DEMODULATORS := 0
ENABLE_BLMIN_TMP_OFF := 0
############################################################# #############################################################
TARGET = firmware TARGET = firmware
@@ -99,6 +99,8 @@ ifeq ($(ENABLE_AIRCOPY),1)
OBJS += app/aircopy.o OBJS += app/aircopy.o
endif endif
OBJS += app/app.o OBJS += app/app.o
OBJS += app/chFrScanner.o
OBJS += app/common.o
OBJS += app/dtmf.o OBJS += app/dtmf.o
ifeq ($(ENABLE_FMRADIO),1) ifeq ($(ENABLE_FMRADIO),1)
OBJS += app/fm.o OBJS += app/fm.o
@@ -210,6 +212,7 @@ endif
# catch any and all warnings # catch any and all warnings
CFLAGS += -Wextra CFLAGS += -Wextra
#CFLAGS += -Wpedantic
CFLAGS += -DPRINTF_INCLUDE_CONFIG_H CFLAGS += -DPRINTF_INCLUDE_CONFIG_H
CFLAGS += -DGIT_HASH=\"$(GIT_HASH)\" CFLAGS += -DGIT_HASH=\"$(GIT_HASH)\"
@@ -280,7 +283,7 @@ endif
ifeq ($(ENABLE_REVERSE_BAT_SYMBOL),1) ifeq ($(ENABLE_REVERSE_BAT_SYMBOL),1)
CFLAGS += -DENABLE_REVERSE_BAT_SYMBOL CFLAGS += -DENABLE_REVERSE_BAT_SYMBOL
endif endif
ifeq ($(ENABLE_CODE_SCAN_TIMEOUT),1) ifeq ($(ENABLE_NO_CODE_SCAN_TIMEOUT),1)
CFLAGS += -DENABLE_CODE_SCAN_TIMEOUT CFLAGS += -DENABLE_CODE_SCAN_TIMEOUT
endif endif
ifeq ($(ENABLE_AM_FIX),1) ifeq ($(ENABLE_AM_FIX),1)
@@ -316,6 +319,15 @@ endif
ifeq ($(ENABLE_BAND_SCOPE),1) ifeq ($(ENABLE_BAND_SCOPE),1)
CFLAGS += -DENABLE_BAND_SCOPE CFLAGS += -DENABLE_BAND_SCOPE
endif 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
LDFLAGS = LDFLAGS =
ifeq ($(ENABLE_CLANG),0) ifeq ($(ENABLE_CLANG),0)
@@ -348,10 +360,44 @@ LIBS =
DEPS = $(OBJS:.o=.d) DEPS = $(OBJS:.o=.d)
ifdef OS
RM = del /Q
FixPath = $(subst /,\,$1)
WHERE = where
else
ifeq ($(shell uname), Linux)
RM = rm -f
FixPath = $1
WHERE = which
endif
endif
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) all: $(TARGET)
$(OBJCOPY) -O binary $< $<.bin $(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 $(GIT_HASH) $<.packed.bin
endif
$(SIZE) $< $(SIZE) $<
debug: debug:
@@ -378,4 +424,4 @@ bsp/dp32g030/%.h: hardware/dp32g030/%.def
-include $(DEPS) -include $(DEPS)
clean: clean:
rm -f $(TARGET).bin $(TARGET).packed.bin $(TARGET) $(OBJS) $(DEPS) $(RM) $(call FixPath, $(TARGET).bin $(TARGET).packed.bin $(TARGET) $(OBJS) $(DEPS))

View File

@@ -1,21 +1,47 @@
# Main features: # Main features:
- OneOfEleven mods, including AM fix * many of OneOfEleven mods:
- fagci spectrum analyzer (**F+5** to turn on) * AM fix, huge improvement in reception quality
- better battery percentage calculation (based on real measurement, battery calibration recommended) * longpress buttons functions replicating F+ action
- battery calibration option available available in the menu (instructions below) * 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 /> <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 />
❗❗❗You can now calibrate the battery voltage reading in the radio menu.
<img src="images/batcal.jpg" width=300 />
To enter the calibration:
1. turn the radio on while holding PTT and the first side button
2. go to BATCAL option and adjust the voltage with UP/DOWN buttons
3. confirm the setting, calibration will be saved to EEPROM
# Open reimplementation of the Quan Sheng UV-K5 v2.1.27 firmware # Open reimplementation of the Quan Sheng UV-K5 v2.1.27 firmware
@@ -72,45 +98,25 @@ ENABLE_SMALL_BOLD := 1 bold channel name/no. (when name + freq
ENABLE_KEEP_MEM_NAME := 1 maintain channel name when (re)saving memory channel ENABLE_KEEP_MEM_NAME := 1 maintain channel name when (re)saving memory channel
ENABLE_WIDE_RX := 1 full 18MHz to 1300MHz RX (though front-end/PA not designed for 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_TX_WHEN_AM := 0 allow TX (always FM) when RX is set to AM
ENABLE_F_CAL_MENU := 0 enable/disable the radios hidden frequency calibration menu 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_CTCSS_TAIL_PHASE_SHIFT := 1 standard CTCSS tail phase shift rather than QS's own 55Hz tone method
ENABLE_BOOT_BEEPS := 0 gives user audio feedback on volume knob position at boot-up 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_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_REVERSE_BAT_SYMBOL := 1 mirror the battery symbol on the status bar (+ pole on the right)
ENABLE_CODE_SCAN_TIMEOUT := 0 enable/disable 32-sec CTCSS/DCS scan timeout (press exit butt instead of time-out to end scan) 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 := 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_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_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_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_RSSI_BAR := 1 enable a dBm/Sn RSSI bar graph level inplace of the little antenna symbols
ENABLE_AUDIO_BAR := 0 experimental, display an audo bar level when TX'ing 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 Menu key ('M') ENABLE_COPY_CHAN_TO_VFO := 1 copy current channel into the other VFO. Long press `1 BAND` when in channel mode
#ENABLE_SINGLE_VFO_CHAN := 1 not yet implemented - single VFO on display when possible ENABLE_SPECTRUM := 1 fagci spectrum analizer, activated with `F` + `5 NOAA`
#ENABLE_BAND_SCOPE := 1 not yet implemented - spectrum/pan-adapter 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
``` ```
# New/modified function keys
* Long-press 'M' .. Copy selected channel into same VFO, then switch VFO to frequency mode
*
* Long-press '7' .. Toggle selected channel scanlist setting .. if VOX is disabled in Makefile
* or
* Long-press '5' .. Toggle selected channel scanlist setting .. if NOAA is disabled in Makefile
*
* Long-press '*' .. Start scanning, then toggles the scanning between scanlists 1, 2 or ALL channels
# 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 # Compiler

View File

@@ -51,10 +51,10 @@
// <7:5> = LNA Gain // <7:5> = LNA Gain
// 7 = 0dB // 7 = 0dB
// 6 = -2dB // 6 = -2dB
// 5 = -4dB // 5 = -4dB < original value
// 4 = -6dB // 4 = -6dB
// 3 = -9dB // 3 = -9dB
// 2 = -14dB < original value // 2 = -14dB
// 1 = -19dB // 1 = -19dB
// 0 = -24dB // 0 = -24dB
// //
@@ -192,26 +192,26 @@
{0x03D3, -20}, // 77 .. 3 6 2 3 .. 0dB -2dB -3dB -15dB .. -20dB {0x03D3, -20}, // 77 .. 3 6 2 3 .. 0dB -2dB -3dB -15dB .. -20dB
{0x03BB, -19}, // 78 .. 3 5 3 3 .. 0dB -4dB 0dB -15dB .. -19dB {0x03BB, -19}, // 78 .. 3 5 3 3 .. 0dB -4dB 0dB -15dB .. -19dB
{0x037C, -18}, // 79 .. 3 3 3 4 .. 0dB -9dB 0dB -9dB .. -18dB {0x037C, -18}, // 79 .. 3 3 3 4 .. 0dB -9dB 0dB -9dB .. -18dB
{0x035E, -17}, // 80 .. 3 2 3 6 .. 0dB -14dB 0dB -3dB .. -17dB original {0x03CC, -17}, // 80 .. 3 6 1 4 .. 0dB -2dB -6dB -9dB .. -17dB
{0x03C5, -16}, // 81 .. 3 6 0 5 .. 0dB -2dB -8dB -6dB .. -16dB {0x03C5, -16}, // 81 .. 3 6 0 5 .. 0dB -2dB -8dB -6dB .. -16dB
{0x03EC, -15}, // 82 .. 3 7 1 4 .. 0dB 0dB -6dB -9dB .. -15dB {0x03EC, -15}, // 82 .. 3 7 1 4 .. 0dB 0dB -6dB -9dB .. -15dB
{0x035F, -14}, // 83 .. 3 2 3 7 .. 0dB -14dB 0dB 0dB .. -14dB {0x035F, -14}, // 83 .. 3 2 3 7 .. 0dB -14dB 0dB 0dB .. -14dB
{0x03C6, -13}, // 84 .. 3 6 0 6 .. 0dB -2dB -8dB -3dB .. -13dB {0x03BC, -13}, // 84 .. 3 5 3 4 .. 0dB -4dB 0dB -9dB .. -13dB
{0x0377, -12}, // 85 .. 3 3 2 7 .. 0dB -9dB -3dB 0dB .. -12dB {0x038F, -12}, // 85 .. 3 4 1 7 .. 0dB -6dB -6dB 0dB .. -12dB
{0x03E6, -11}, // 86 .. 3 7 0 6 .. 0dB 0dB -8dB -3dB .. -11dB {0x03E6, -11}, // 86 .. 3 7 0 6 .. 0dB 0dB -8dB -3dB .. -11dB
{0x03BD, -10}, // 87 .. 3 5 3 5 .. 0dB -4dB 0dB -6dB .. -10dB {0x03AF, -10}, // 87 .. 3 5 1 7 .. 0dB -4dB -6dB 0dB .. -10dB
{0x03F5, -9}, // 88 .. 3 7 2 5 .. 0dB 0dB -3dB -6dB .. -9dB {0x03F5, -9 }, // 88 .. 3 7 2 5 .. 0dB 0dB -3dB -6dB .. -9dB
{0x03DD, -8}, // 89 .. 3 6 3 5 .. 0dB -2dB 0dB -6dB .. -8dB {0x03D6, -8 }, // 89 .. 3 6 2 6 .. 0dB -2dB -3dB -3dB .. -8dB
{0x03B7, -7}, // 90 .. 3 5 2 7 .. 0dB -4dB -3dB 0dB .. -7dB {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 {0x03F6, -6 }, // 91 .. 3 7 2 6 .. 0dB 0dB -3dB -3dB .. -6dB
{0x03D7, -5}, // 92 .. 3 6 2 7 .. 0dB -2dB -3dB 0dB .. -5dB {0x03DE, -5 }, // 92 .. 3 6 3 6 .. 0dB -2dB 0dB -3dB .. -5dB
{0x03BF, -4}, // 93 .. 3 5 3 7 .. 0dB -4dB 0dB 0dB .. -4dB {0x03BF, -4 }, // 93 .. 3 5 3 7 .. 0dB -4dB 0dB 0dB .. -4dB
{0x03F7, -3}, // 94 .. 3 7 2 7 .. 0dB 0dB -3dB 0dB .. -3dB {0x03F7, -3 }, // 94 .. 3 7 2 7 .. 0dB 0dB -3dB 0dB .. -3dB
{0x03DF, -2}, // 95 .. 3 6 3 7 .. 0dB -2dB 0dB 0dB .. -2dB {0x03DF, -2 }, // 95 .. 3 6 3 7 .. 0dB -2dB 0dB 0dB .. -2dB
{0x03FF, 0} // 96 .. 3 7 3 7 .. 0dB 0dB 0dB 0dB .. 0dB {0x03FF, 0 }, // 96 .. 3 7 3 7 .. 0dB 0dB 0dB 0dB .. 0dB
}; };
static const unsigned int original_index = 80; static const unsigned int original_index = 90;
#endif #endif

View File

@@ -18,6 +18,8 @@
#include "app/action.h" #include "app/action.h"
#include "app/app.h" #include "app/app.h"
#include "app/chFrScanner.h"
#include "app/common.h"
#include "app/dtmf.h" #include "app/dtmf.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h" #include "app/fm.h"
@@ -30,6 +32,7 @@
#endif #endif
#include "driver/bk4819.h" #include "driver/bk4819.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "driver/backlight.h"
#include "functions.h" #include "functions.h"
#include "misc.h" #include "misc.h"
#include "settings.h" #include "settings.h"
@@ -60,24 +63,22 @@ void ACTION_Power(void)
gTxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW; gTxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW;
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
//gRequestSaveChannel = 2; // auto save the channel
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_POWER; gAnotherVoiceID = VOICE_ID_POWER;
#endif #endif
gRequestDisplayScreen = gScreenToDisplay; gRequestDisplayScreen = gScreenToDisplay;
} }
void ACTION_Monitor(void) void ACTION_Monitor(void)
{ {
if (gCurrentFunction != FUNCTION_MONITOR) if (gCurrentFunction != FUNCTION_MONITOR) { // enable the monitor
{ // enable the monitor
RADIO_SelectVfos(); RADIO_SelectVfos();
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST && gIsNoaaMode) if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST && gIsNoaaMode)
gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST; gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
#endif #endif
RADIO_SetupRegisters(true); RADIO_SetupRegisters(true);
APP_StartListening(FUNCTION_MONITOR, false); APP_StartListening(FUNCTION_MONITOR, false);
return; return;
@@ -85,87 +86,83 @@ void ACTION_Monitor(void)
gMonitor = false; gMonitor = false;
if (gScanStateDir != SCAN_OFF) if (gScanStateDir != SCAN_OFF) {
{
gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms; gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms;
gScheduleScanListen = false; gScheduleScanListen = false;
gScanPauseMode = true; gScanPauseMode = true;
} }
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode) if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode) {
{ gNOAA_Countdown_10ms = NOAA_countdown_10ms;
gNOAA_Countdown_10ms = NOAA_countdown_10ms; gScheduleNOAA = false;
gScheduleNOAA = false; }
} #endif
#endif
RADIO_SetupRegisters(true); RADIO_SetupRegisters(true);
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (gFmRadioMode) if (gFmRadioMode) {
{ FM_Start();
FM_Start(); gRequestDisplayScreen = DISPLAY_FM;
gRequestDisplayScreen = DISPLAY_FM; }
} else
else #endif
#endif gRequestDisplayScreen = gScreenToDisplay;
gRequestDisplayScreen = gScreenToDisplay;
} }
void ACTION_Scan(bool bRestart) void ACTION_Scan(bool bRestart)
{ {
#ifdef ENABLE_FMRADIO (void)bRestart;
if (gFmRadioMode) #ifdef ENABLE_FMRADIO
if (gFmRadioMode)
{
if (gCurrentFunction != FUNCTION_RECEIVE &&
gCurrentFunction != FUNCTION_MONITOR &&
gCurrentFunction != FUNCTION_TRANSMIT)
{ {
if (gCurrentFunction != FUNCTION_RECEIVE && GUI_SelectNextDisplay(DISPLAY_FM);
gCurrentFunction != FUNCTION_MONITOR &&
gCurrentFunction != FUNCTION_TRANSMIT) 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;
#ifdef ENABLE_VOICE FM_EraseChannels();
gAnotherVoiceID = VOICE_ID_SCANNING_STOP; Frequency = gEeprom.FM_LowerLimit;
#endif
} }
else else
{ {
uint16_t Frequency; gFM_AutoScan = false;
gFM_ChannelPosition = 0;
if (bRestart) Frequency = gEeprom.FM_FrequencyPlaying;
{
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
} }
BK1080_GetFrequencyDeviation(Frequency);
FM_Tune(Frequency, 1, bRestart);
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;
#endif
} }
return;
} }
#endif return;
}
#endif
if (gScreenToDisplay != DISPLAY_SCANNER) if (!SCANNER_IsScanning())
{ // not scanning { // not scanning
gMonitor = false; gMonitor = false;
@@ -177,23 +174,23 @@ void ACTION_Scan(bool bRestart)
RADIO_SelectVfos(); RADIO_SelectVfos();
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif #endif
{ {
GUI_SelectNextDisplay(DISPLAY_MAIN); GUI_SelectNextDisplay(DISPLAY_MAIN);
if (gScanStateDir != SCAN_OFF) if (gScanStateDir != SCAN_OFF)
{ // already scanning { // already scanning
if (gNextMrChannel <= MR_CHANNEL_LAST) if (IS_MR_CHANNEL(gNextMrChannel))
{ // channel mode { // channel mode
// keep scanning but toggle between scan lists // keep scanning but toggle between scan lists
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3; gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3;
// jump to the next channel // jump to the next channel
SCANNER_NextChannel(false, gScanStateDir); CHFRSCANNER_Start(false, gScanStateDir);
gScanPauseDelayIn_10ms = 1; gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false; gScheduleScanListen = false;
@@ -202,7 +199,7 @@ void ACTION_Scan(bool bRestart)
else else
{ // stop scanning { // stop scanning
SCANNER_Stop(); CHFRSCANNER_Stop();
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP; gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
@@ -212,7 +209,7 @@ void ACTION_Scan(bool bRestart)
else else
{ // start scanning { // start scanning
SCANNER_NextChannel(true, SCAN_FWD); CHFRSCANNER_Start(true, SCAN_FWD);
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN); AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN);
@@ -228,31 +225,6 @@ void ACTION_Scan(bool bRestart)
} }
} }
} }
else
// if (!bRestart)
if (!bRestart && gNextMrChannel <= MR_CHANNEL_LAST)
{ // channel mode, keep scanning but toggle between scan lists
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3;
// jump to the next channel
SCANNER_NextChannel(false, gScanStateDir);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;
gUpdateStatus = true;
}
else
{ // stop scanning
gMonitor = false;
SCANNER_Stop();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
gRequestDisplayScreen = DISPLAY_MAIN;
}
} }
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
@@ -271,6 +243,7 @@ void ACTION_Scan(bool bRestart)
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
static void ACTION_AlarmOr1750(const bool b1750) static void ACTION_AlarmOr1750(const bool b1750)
{ {
(void)b1750;
gInputBoxIndex = 0; gInputBoxIndex = 0;
#if defined(ENABLE_ALARM) && defined(ENABLE_TX1750) #if defined(ENABLE_ALARM) && defined(ENABLE_TX1750)
@@ -324,6 +297,28 @@ void ACTION_Scan(bool bRestart)
} }
#endif #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) void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{ {
if (gScreenToDisplay == DISPLAY_MAIN && gDTMF_InputMode) // entering DTMF code if (gScreenToDisplay == DISPLAY_MAIN && gDTMF_InputMode) // entering DTMF code
@@ -357,26 +352,31 @@ void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
uint8_t funcShort = ACTION_OPT_NONE; uint8_t funcShort = ACTION_OPT_NONE;
uint8_t funcLong = ACTION_OPT_NONE; uint8_t funcLong = ACTION_OPT_NONE;
if (Key == KEY_SIDE1) switch(Key) {
{ case KEY_SIDE1:
funcShort = gEeprom.KEY_1_SHORT_PRESS_ACTION; funcShort = gEeprom.KEY_1_SHORT_PRESS_ACTION;
funcLong = gEeprom.KEY_1_LONG_PRESS_ACTION; funcLong = gEeprom.KEY_1_LONG_PRESS_ACTION;
} break;
else if (Key == KEY_SIDE2) case KEY_SIDE2:
{ funcShort = gEeprom.KEY_2_SHORT_PRESS_ACTION;
funcShort = gEeprom.KEY_2_SHORT_PRESS_ACTION; funcLong = gEeprom.KEY_2_LONG_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) // button pushed if (!bKeyHeld && bKeyPressed) // button pushed
{ {
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return; return;
} }
// held or released beyond this point // 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 || bKeyPressed) // held
{ {
@@ -406,24 +406,41 @@ void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
ACTION_Scan(true); ACTION_Scan(true);
break; break;
case ACTION_OPT_VOX: case ACTION_OPT_VOX:
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
ACTION_Vox(); ACTION_Vox();
#endif #endif
break; break;
case ACTION_OPT_ALARM: case ACTION_OPT_ALARM:
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
ACTION_AlarmOr1750(false); ACTION_AlarmOr1750(false);
#endif #endif
break; break;
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
case ACTION_OPT_FM: case ACTION_OPT_FM:
ACTION_FM(); ACTION_FM();
break; break;
#endif #endif
case ACTION_OPT_1750: case ACTION_OPT_1750:
#ifdef ENABLE_TX1750 #ifdef ENABLE_TX1750
ACTION_AlarmOr1750(true); ACTION_AlarmOr1750(true);
#endif #endif
break; 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

@@ -32,6 +32,11 @@ void ACTION_Scan(bool bRestart);
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
void ACTION_FM(void); void ACTION_FM(void);
#endif #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); 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_SendFSKData(g_FSK_Buffer);
BK4819_SetupPowerAmplifier(0, 0); BK4819_SetupPowerAmplifier(0, 0);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, false); BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
gAircopySendCountdown = 30; gAircopySendCountdown = 30;
} }
@@ -131,8 +131,7 @@ static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
} }
gInputBoxIndex = 0; gInputBoxIndex = 0;
Frequency = StrToUL(INPUTBOX_GetAscii()) * 100;
NUMBER_Get(gInputBox, &Frequency);
for (i = 0; i < ARRAY_SIZE(frequencyBandTable); i++) for (i = 0; i < ARRAY_SIZE(frequencyBandTable); i++)
{ {
@@ -142,8 +141,7 @@ static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
#endif #endif
gRxVfo->Band = i; gRxVfo->Band = i;
Frequency += 75; Frequency = FREQUENCY_RoundToStep(Frequency, gRxVfo->StepFrequency);
Frequency = FREQUENCY_FloorToStep(Frequency, gRxVfo->StepFrequency, 0);
gRxVfo->freq_config_RX.Frequency = Frequency; gRxVfo->freq_config_RX.Frequency = Frequency;
gRxVfo->freq_config_TX.Frequency = Frequency; gRxVfo->freq_config_TX.Frequency = Frequency;
RADIO_ConfigureSquelchAndOutputPower(gRxVfo); RADIO_ConfigureSquelchAndOutputPower(gRxVfo);

819
app/app.c

File diff suppressed because it is too large Load Diff

View File

@@ -23,14 +23,9 @@
#include "frequencies.h" #include "frequencies.h"
#include "radio.h" #include "radio.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;
void APP_EndTransmission(void); void APP_EndTransmission(void);
void APP_StartListening(FUNCTION_Type_t Function, const bool reset_am_fix); 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_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t direction);
void APP_Update(void); void APP_Update(void);
void APP_TimeSlice10ms(void); void APP_TimeSlice10ms(void);
void APP_TimeSlice500ms(void); void APP_TimeSlice500ms(void);

262
app/chFrScanner.c Normal file
View File

@@ -0,0 +1,262 @@
#include "app/app.h"
#include "app/chFrScanner.h"
#include "functions.h"
#include "misc.h"
#include "settings.h"
int8_t gScanStateDir;
bool gScanKeepResult;
bool gScanPauseMode;
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)
{
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
}

18
app/chFrScanner.h Normal file
View File

@@ -0,0 +1,18 @@
#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;
void CHFRSCANNER_Found(void);
void CHFRSCANNER_Stop(void);
void CHFRSCANNER_Start(const bool storeBackupSettings, const int8_t scan_direction);
void CHFRSCANNER_ContinueScanning(void);
#endif

73
app/common.c Normal file
View File

@@ -0,0 +1,73 @@
#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()
{
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,6 +17,7 @@
#include <string.h> #include <string.h>
#include <stdio.h> // NULL #include <stdio.h> // NULL
#include "app/chFrScanner.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h" #include "app/fm.h"
#endif #endif
@@ -203,13 +204,13 @@ void DTMF_Append(const char code)
void DTMF_HandleRequest(void) void DTMF_HandleRequest(void)
{ // proccess the RX'ed DTMF characters { // proccess the RX'ed DTMF characters
char String[20]; char String[21];
unsigned int Offset; unsigned int Offset;
if (!gDTMF_RX_pending) if (!gDTMF_RX_pending)
return; // nothing new received return; // nothing new received
if (gScanStateDir != SCAN_OFF || gCssScanMode != CSS_SCAN_MODE_OFF) if (gScanStateDir != SCAN_OFF || gCssBackgroundScan)
{ // we're busy scanning { // we're busy scanning
DTMF_clear_RX(); DTMF_clear_RX();
return; return;
@@ -383,7 +384,7 @@ void DTMF_HandleRequest(void)
void DTMF_Reply(void) void DTMF_Reply(void)
{ {
uint16_t Delay; uint16_t Delay;
char String[20]; char String[23];
const char *pString = NULL; const char *pString = NULL;
switch (gDTMF_ReplyState) switch (gDTMF_ReplyState)
@@ -434,7 +435,7 @@ void DTMF_Reply(void)
if (gEeprom.DTMF_SIDE_TONE) if (gEeprom.DTMF_SIDE_TONE)
{ // the user will also hear the transmitted tones { // the user will also hear the transmitted tones
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOn();
gEnableSpeaker = true; gEnableSpeaker = true;
} }
@@ -450,7 +451,7 @@ void DTMF_Reply(void)
gEeprom.DTMF_CODE_PERSIST_TIME, gEeprom.DTMF_CODE_PERSIST_TIME,
gEeprom.DTMF_CODE_INTERVAL_TIME); gEeprom.DTMF_CODE_INTERVAL_TIME);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOff();
gEnableSpeaker = false; gEnableSpeaker = false;

View File

@@ -96,7 +96,7 @@ void FM_TurnOff(void)
gFM_ScanState = FM_SCAN_OFF; gFM_ScanState = FM_SCAN_OFF;
gFM_RestoreCountdown_10ms = 0; gFM_RestoreCountdown_10ms = 0;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOff();
gEnableSpeaker = false; gEnableSpeaker = false;
@@ -119,7 +119,7 @@ void FM_EraseChannels(void)
void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag) void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag)
{ {
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOff();
gEnableSpeaker = false; gEnableSpeaker = false;
@@ -166,7 +166,7 @@ void FM_PlayAndUpdate(void)
gScheduleFM = false; gScheduleFM = false;
gAskToSave = false; gAskToSave = false;
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOn();
gEnableSpeaker = true; gEnableSpeaker = true;
} }
@@ -277,8 +277,7 @@ static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
uint32_t Frequency; uint32_t Frequency;
gInputBoxIndex = 0; gInputBoxIndex = 0;
NUMBER_Get(gInputBox, &Frequency); Frequency = StrToUL(INPUTBOX_GetAscii());
Frequency /= 10000;
if (Frequency < gEeprom.FM_LowerLimit || gEeprom.FM_UpperLimit < Frequency) if (Frequency < gEeprom.FM_LowerLimit || gEeprom.FM_UpperLimit < Frequency)
{ {
@@ -626,7 +625,7 @@ void FM_Play(void)
if (!gEeprom.FM_IsMrMode) if (!gEeprom.FM_IsMrMode)
gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying; gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying;
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOn();
gEnableSpeaker = true; gEnableSpeaker = true;
GUI_SelectNextDisplay(DISPLAY_FM); GUI_SelectNextDisplay(DISPLAY_FM);
@@ -660,7 +659,7 @@ void FM_Start(void)
BK1080_Init(gEeprom.FM_FrequencyPlaying, true); BK1080_Init(gEeprom.FM_FrequencyPlaying, true);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOn();
gEnableSpeaker = true; gEnableSpeaker = true;
gUpdateStatus = true; gUpdateStatus = true;

View File

@@ -17,9 +17,13 @@
#include <string.h> #include <string.h>
#include "app/app.h" #include "app/app.h"
#include "app/chFrScanner.h"
#include "app/common.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h" #include "app/fm.h"
#endif #endif
#include "app/generic.h" #include "app/generic.h"
#include "app/menu.h" #include "app/menu.h"
#include "app/scanner.h" #include "app/scanner.h"
@@ -52,18 +56,7 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
if (!bKeyPressed) // won't ever pass if (!bKeyPressed) // won't ever pass
return; return;
if (gScreenToDisplay != DISPLAY_MENU && COMMON_KeypadLockToggle();
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;
}
} }
else // released else // released
{ {
@@ -150,36 +143,21 @@ void GENERIC_Key_PTT(bool bKeyPressed)
// PTT pressed // PTT pressed
if (gScanStateDir != SCAN_OFF || // frequency/channel scanning
gScreenToDisplay == DISPLAY_SCANNER || // CTCSS/CDCSS scanning
gCssScanMode != CSS_SCAN_MODE_OFF) // " "
{ // we're scanning .. stop
if (gScreenToDisplay == DISPLAY_SCANNER)
{ // CTCSS/CDCSS scanning .. stop
gEeprom.CROSS_BAND_RX_TX = gBackup_CROSS_BAND_RX_TX;
gFlagStopScan = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
gFlagResetVfos = true;
}
else
if (gScanStateDir != SCAN_OFF)
{ // frequency/channel scanning . .stop
SCANNER_Stop();
}
else
if (gCssScanMode != CSS_SCAN_MODE_OFF)
{ // CTCSS/CDCSS scanning .. stop
MENU_StopCssScan();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
if (SCANNER_IsScanning())
{ // CTCSS/CDCSS scanning .. stop
SCANNER_Stop();
goto cancel_tx; goto cancel_tx;
} }
if (gScanStateDir != SCAN_OFF)
{ // frequency/channel scanning . .stop
CHFRSCANNER_Stop();
goto cancel_tx;
}
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (gFM_ScanState != FM_SCAN_OFF) if (gFM_ScanState != FM_SCAN_OFF)
{ // FM radio is scanning .. stop { // FM radio is scanning .. stop
@@ -220,21 +198,12 @@ void GENERIC_Key_PTT(bool bKeyPressed)
if (gDTMF_InputBox_Index < sizeof(gDTMF_InputBox)) if (gDTMF_InputBox_Index < sizeof(gDTMF_InputBox))
gDTMF_InputBox[gDTMF_InputBox_Index] = 0; // NULL term the string gDTMF_InputBox[gDTMF_InputBox_Index] = 0; // NULL term the string
#if 0 // append our DTMF ID to the inputted DTMF code -
// 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 the user inputted code is exactly 3 digits long if (gDTMF_InputBox_Index == 3 && gTxVfo->DTMF_DECODING_ENABLE > 0)
if (gDTMF_InputBox_Index == 3) gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3); else
else gDTMF_CallMode = DTMF_CALL_MODE_DTMF;
gDTMF_CallMode = DTMF_CALL_MODE_DTMF;
#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_InputBox_Index == 3 && gTxVfo->DTMF_DECODING_ENABLE > 0)
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
else
gDTMF_CallMode = DTMF_CALL_MODE_DTMF;
#endif
// remember the DTMF string // remember the DTMF string
gDTMF_PreviousIndex = gDTMF_InputBox_Index; gDTMF_PreviousIndex = gDTMF_InputBox_Index;

View File

@@ -18,15 +18,19 @@
#include "app/action.h" #include "app/action.h"
#include "app/app.h" #include "app/app.h"
#include "app/chFrScanner.h"
#include "app/common.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h" #include "app/fm.h"
#endif #endif
#include "app/generic.h" #include "app/generic.h"
#include "app/main.h" #include "app/main.h"
#include "app/scanner.h" #include "app/scanner.h"
#ifdef ENABLE_SPECTRUM #ifdef ENABLE_SPECTRUM
#include "app/spectrum.h" #include "app/spectrum.h"
#endif #endif
#include "audio.h" #include "audio.h"
#include "board.h" #include "board.h"
#include "driver/bk4819.h" #include "driver/bk4819.h"
@@ -37,14 +41,12 @@
#include "settings.h" #include "settings.h"
#include "ui/inputbox.h" #include "ui/inputbox.h"
#include "ui/ui.h" #include "ui/ui.h"
#ifdef ENABLE_SPECTRUM #include <stdlib.h>
// #include "app/spectrum.h"
#endif
void toggle_chan_scanlist(void) void toggle_chan_scanlist(void)
{ // toggle the selected channels scanlist setting { // toggle the selected channels scanlist setting
if (gScreenToDisplay == DISPLAY_SCANNER || !IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) if ( SCANNER_IsScanning() || !IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
return; return;
if (gTxVfo->SCANLIST1_PARTICIPATION) if (gTxVfo->SCANLIST1_PARTICIPATION)
@@ -98,26 +100,71 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break; break;
case KEY_1: case KEY_1:
if (!IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (!IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
{
gWasFKeyPressed = false; gWasFKeyPressed = false;
gUpdateStatus = true; gUpdateStatus = true;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; 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; return;
} }
Band = gTxVfo->Band + 1; if(gTxVfo->Band == 6 && gTxVfo->pRX->Frequency < 100000000) {
if (gSetting_350EN || Band != BAND5_350MHz) gTxVfo->pRX->Frequency = 100000000;
{ return;
if (Band > BAND7_470MHz)
Band = BAND1_50MHz;
} }
else else {
Band = BAND6_400MHz; Band = gTxVfo->Band + 1;
gTxVfo->Band = Band; if (gSetting_350EN || Band != BAND5_350MHz) {
if (Band > BAND7_470MHz)
Band = BAND1_50MHz;
}
else
Band = BAND6_400MHz;
gEeprom.ScreenChannel[Vfo] = FREQ_CHANNEL_FIRST + Band; gTxVfo->Band = Band;
gEeprom.FreqChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
gEeprom.ScreenChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
gEeprom.FreqChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
}
gRequestSaveVFO = true; gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD; gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
@@ -130,57 +177,14 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break; break;
case KEY_2: case KEY_2:
gEeprom.TX_VFO ^= 1; COMMON_SwitchVFOs();
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;
gRequestDisplayScreen = DISPLAY_MAIN;
if (beep) if (beep)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
break; break;
case KEY_3: case KEY_3:
#ifdef ENABLE_NOAA COMMON_SwitchVFOMode();
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))
{ // swap to frequency mode
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_VFO];
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
break;
}
Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 0);
if (Channel != 0xFF)
{ // swap to channel mode
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;
}
}
if (beep) if (beep)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
@@ -189,22 +193,22 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
case KEY_4: case KEY_4:
gWasFKeyPressed = false; gWasFKeyPressed = false;
gFlagStartScan = true;
gScanSingleFrequency = false;
gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX; gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF; gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gUpdateStatus = true; gUpdateStatus = true;
if (beep) if (beep)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
SCANNER_Start(false);
gRequestDisplayScreen = DISPLAY_SCANNER;
break; break;
case KEY_5: case KEY_5:
if(beep) { if(beep) {
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ {
gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_VFO]; gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_VFO];
} }
@@ -355,14 +359,14 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
} }
// #ifdef ENABLE_NOAA // #ifdef ENABLE_NOAA
// if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) // if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
// #endif // #endif
if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // user is entering a frequency { // user is entering a frequency
uint32_t Frequency; uint32_t Frequency;
bool isGigaF = gTxVfo->pRX->Frequency >= 100000000;
if (gInputBoxIndex < 6) if (gInputBoxIndex < 6 + isGigaF)
{ {
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
@@ -372,8 +376,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
} }
gInputBoxIndex = 0; gInputBoxIndex = 0;
Frequency = StrToUL(INPUTBOX_GetAscii()) * 100;
NUMBER_Get(gInputBox, &Frequency);
// clamp the frequency entered to some valid value // clamp the frequency entered to some valid value
if (Frequency < frequencyBandTable[0].lower) if (Frequency < frequencyBandTable[0].lower)
@@ -410,10 +413,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
RADIO_ConfigureChannel(Vfo, VFO_CONFIGURE_RELOAD); RADIO_ConfigureChannel(Vfo, VFO_CONFIGURE_RELOAD);
} }
// Frequency += 75; // is this meant to be rounding ? Frequency = FREQUENCY_RoundToStep(Frequency, gTxVfo->StepFrequency);
Frequency += gTxVfo->StepFrequency / 2; // no idea, but this is
Frequency = FREQUENCY_FloorToStep(Frequency, gTxVfo->StepFrequency, frequencyBandTable[gTxVfo->Band].lower);
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
{ // clamp the frequency to the limit { // clamp the frequency to the limit
@@ -506,8 +506,8 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
} }
else else
{ {
bScanKeepFrequency = false; gScanKeepResult = false;
SCANNER_Stop(); CHFRSCANNER_Stop();
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP; gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
@@ -565,51 +565,7 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
gWasFKeyPressed = false; gWasFKeyPressed = false;
gUpdateStatus = true; gUpdateStatus = true;
#ifdef ENABLE_COPY_CHAN_TO_VFO ACTION_Handle(KEY_MENU, bKeyPressed, bKeyHeld);
if (gEeprom.VFO_OPEN && gCssScanMode == CSS_SCAN_MODE_OFF)
{
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;
gEeprom.TX_VFO = vfo;
RADIO_SelectVfos();
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
RADIO_SetupRegisters(true);
//SETTINGS_SaveChannel(channel, gEeprom.RX_VFO, gRxVfo, 1);
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gUpdateStatus = true;
gUpdateDisplay = true;
}
}
else
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
#endif
} }
} }
@@ -623,6 +579,11 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
if (bFlag) if (bFlag)
{ {
if (gScanStateDir != SCAN_OFF) {
CHFRSCANNER_Stop();
return;
}
gFlagRefreshSetting = true; gFlagRefreshSetting = true;
gRequestDisplayScreen = DISPLAY_MENU; gRequestDisplayScreen = DISPLAY_MENU;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
@@ -672,7 +633,7 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
{ {
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (gScanStateDir == SCAN_OFF && IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (gScanStateDir == SCAN_OFF && !IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
#else #else
if (gScanStateDir == SCAN_OFF) if (gScanStateDir == SCAN_OFF)
#endif #endif
@@ -691,19 +652,18 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
{ // with the F-key { // with the F-key
gWasFKeyPressed = false; gWasFKeyPressed = false;
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
{ gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; return;
return; }
} #endif
#endif
// scan the CTCSS/DCS code // scan the CTCSS/DCS code
gFlagStartScan = true;
gScanSingleFrequency = true;
gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX; gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF; gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
SCANNER_Start(true);
gRequestDisplayScreen = DISPLAY_SCANNER;
} }
gPttWasReleased = true; gPttWasReleased = true;
@@ -750,7 +710,7 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
if (gScanStateDir == SCAN_OFF) if (gScanStateDir == SCAN_OFF)
{ {
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(Channel)) if (!IS_NOAA_CHANNEL(Channel))
#endif #endif
{ {
uint8_t Next; uint8_t Next;
@@ -804,7 +764,7 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
} }
// jump to the next channel // jump to the next channel
SCANNER_NextChannel(false, Direction); CHFRSCANNER_Start(false, Direction);
gScanPauseDelayIn_10ms = 1; gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false; gScheduleScanListen = false;

View File

@@ -47,6 +47,8 @@
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#endif #endif
uint8_t gUnlockAllTxConfCnt;
#ifdef ENABLE_F_CAL_MENU #ifdef ENABLE_F_CAL_MENU
void writeXtalFreqCal(const int32_t value, const bool update_eeprom) void writeXtalFreqCal(const int32_t value, const bool update_eeprom)
{ {
@@ -75,27 +77,39 @@
} }
#endif #endif
void MENU_StartCssScan(int8_t Direction) void MENU_StartCssScan(void)
{ {
gCssScanMode = CSS_SCAN_MODE_SCANNING; SCANNER_Start(true);
gUpdateStatus = true; gUpdateStatus = true;
gCssBackgroundScan = true;
gMenuScrollDirection = Direction; gRequestDisplayScreen = DISPLAY_MENU;
}
RADIO_SelectVfos(); void MENU_CssScanFound(void)
{
if(gScanCssResultType == CODE_TYPE_DIGITAL || gScanCssResultType == CODE_TYPE_REVERSE_DIGITAL) {
gMenuCursor = UI_MENU_GetMenuIdx(MENU_R_DCS);
}
else if(gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) {
gMenuCursor = UI_MENU_GetMenuIdx(MENU_R_CTCS);
}
MENU_SelectNextCode(); MENU_ShowCurrentSetting();
gScanPauseDelayIn_10ms = scan_pause_delay_in_2_10ms; gUpdateStatus = true;
gScheduleScanListen = false; gUpdateDisplay = true;
} }
void MENU_StopCssScan(void) void MENU_StopCssScan(void)
{ {
gCssScanMode = CSS_SCAN_MODE_OFF; gCssBackgroundScan = false;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
gUpdateDisplay = true;
gUpdateStatus = true; gUpdateStatus = true;
RADIO_SetupRegisters(true);
} }
int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax) int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
@@ -109,7 +123,7 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
case MENU_STEP: case MENU_STEP:
*pMin = 0; *pMin = 0;
*pMax = ARRAY_SIZE(StepFrequencyTable) - 1; *pMax = ARRAY_SIZE(gStepFrequencyTable) - 1;
break; break;
case MENU_ABR: case MENU_ABR:
@@ -117,6 +131,16 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
*pMax = ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1; *pMax = ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1;
break; break;
case MENU_ABR_MIN:
*pMin = 0;
*pMax = 9;
break;
case MENU_ABR_MAX:
*pMin = 1;
*pMax = 10;
break;
case MENU_F_LOCK: case MENU_F_LOCK:
*pMin = 0; *pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_F_LOCK) - 1; *pMax = ARRAY_SIZE(gSubMenu_F_LOCK) - 1;
@@ -222,7 +246,6 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
case MENU_D_ST: case MENU_D_ST:
case MENU_D_DCD: case MENU_D_DCD:
case MENU_D_LIVE_DEC: case MENU_D_LIVE_DEC:
case MENU_AM:
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
case MENU_NOAA_S: case MENU_NOAA_S:
#endif #endif
@@ -231,11 +254,15 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
case MENU_500TX: case MENU_500TX:
case MENU_350EN: case MENU_350EN:
case MENU_SCREN: case MENU_SCREN:
case MENU_TX_EN:
*pMin = 0; *pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_OFF_ON) - 1; *pMax = ARRAY_SIZE(gSubMenu_OFF_ON) - 1;
break; break;
case MENU_AM:
*pMin = 0;
*pMax = ARRAY_SIZE(gModulationStr) - 1;
break;
case MENU_SCR: case MENU_SCR:
*pMin = 0; *pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1; *pMax = ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1;
@@ -321,14 +348,20 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
#endif #endif
case MENU_BATCAL: case MENU_BATCAL:
*pMin = 1600; // 0 *pMin = 1600;
*pMax = 2200; // 2300 *pMax = 2200;
break;
case MENU_BATTYP:
*pMin = 0;
*pMax = 1;
break; break;
case MENU_F1SHRT: case MENU_F1SHRT:
case MENU_F1LONG: case MENU_F1LONG:
case MENU_F2SHRT: case MENU_F2SHRT:
case MENU_F2LONG: case MENU_F2LONG:
case MENU_MLONG:
*pMin = 0; *pMin = 0;
*pMax = gSubMenu_SIDEFUNCTIONS_size-1; *pMax = gSubMenu_SIDEFUNCTIONS_size-1;
break; break;
@@ -347,14 +380,14 @@ void MENU_AcceptSetting(void)
uint8_t Code; uint8_t Code;
FREQ_Config_t *pConfig = &gTxVfo->freq_config_RX; FREQ_Config_t *pConfig = &gTxVfo->freq_config_RX;
if (!MENU_GetLimits(GetCurrentMenuId(), &Min, &Max)) if (!MENU_GetLimits(UI_MENU_GetCurrentMenuId(), &Min, &Max))
{ {
if (gSubMenuSelection < Min) gSubMenuSelection = Min; if (gSubMenuSelection < Min) gSubMenuSelection = Min;
else else
if (gSubMenuSelection > Max) gSubMenuSelection = Max; if (gSubMenuSelection > Max) gSubMenuSelection = Max;
} }
switch (GetCurrentMenuId()) switch (UI_MENU_GetCurrentMenuId())
{ {
default: default:
return; return;
@@ -365,7 +398,7 @@ void MENU_AcceptSetting(void)
break; break;
case MENU_STEP: case MENU_STEP:
gTxVfo->STEP_SETTING = gSubMenuSelection; gTxVfo->STEP_SETTING = FREQUENCY_GetStepIdxFromSortedIdx(gSubMenuSelection);
if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ {
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
@@ -515,9 +548,19 @@ void MENU_AcceptSetting(void)
#endif #endif
case MENU_ABR: case MENU_ABR:
gEeprom.BACKLIGHT = gSubMenuSelection; gEeprom.BACKLIGHT_TIME = gSubMenuSelection;
break; break;
case MENU_ABR_MIN:
gEeprom.BACKLIGHT_MIN = gSubMenuSelection;
gEeprom.BACKLIGHT_MAX = MAX(gSubMenuSelection + 1 , gEeprom.BACKLIGHT_MAX);
break;
case MENU_ABR_MAX:
gEeprom.BACKLIGHT_MAX = gSubMenuSelection;
gEeprom.BACKLIGHT_MIN = MIN(gSubMenuSelection - 1, gEeprom.BACKLIGHT_MIN);
break;
case MENU_ABR_ON_TX_RX: case MENU_ABR_ON_TX_RX:
gSetting_backlight_on_tx_rx = gSubMenuSelection; gSetting_backlight_on_tx_rx = gSubMenuSelection;
break; break;
@@ -573,7 +616,7 @@ void MENU_AcceptSetting(void)
return; return;
case MENU_STE: case MENU_STE:
gEeprom.TAIL_NOTE_ELIMINATION = gSubMenuSelection; gEeprom.TAIL_TONE_ELIMINATION = gSubMenuSelection;
break; break;
case MENU_RP_STE: case MENU_RP_STE:
@@ -676,7 +719,7 @@ void MENU_AcceptSetting(void)
break; break;
case MENU_AM: case MENU_AM:
gTxVfo->AM_mode = gSubMenuSelection; gTxVfo->Modulation = gSubMenuSelection;
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
return; return;
@@ -717,10 +760,18 @@ void MENU_AcceptSetting(void)
gSetting_350TX = gSubMenuSelection; gSetting_350TX = gSubMenuSelection;
break; break;
case MENU_F_LOCK: case MENU_F_LOCK: {
if(gSubMenuSelection == F_LOCK_NONE) { // select 10 times to enable
gUnlockAllTxConfCnt++;
if(gUnlockAllTxConfCnt < 10)
return;
}
else
gUnlockAllTxConfCnt = 0;
gSetting_F_LOCK = gSubMenuSelection; gSetting_F_LOCK = gSubMenuSelection;
break; break;
}
case MENU_200TX: case MENU_200TX:
gSetting_200TX = gSubMenuSelection; gSetting_200TX = gSubMenuSelection;
break; break;
@@ -740,10 +791,6 @@ void MENU_AcceptSetting(void)
gFlagReconfigureVfos = true; gFlagReconfigureVfos = true;
break; break;
case MENU_TX_EN:
gSetting_TX_EN = gSubMenuSelection;
break;
#ifdef ENABLE_F_CAL_MENU #ifdef ENABLE_F_CAL_MENU
case MENU_F_CALI: case MENU_F_CALI:
writeXtalFreqCal(gSubMenuSelection, true); writeXtalFreqCal(gSubMenuSelection, true);
@@ -751,28 +798,34 @@ void MENU_AcceptSetting(void)
#endif #endif
case MENU_BATCAL: case MENU_BATCAL:
{ { // voltages are averages between discharge curves of 1600 and 2200 mAh
gBatteryCalibration[0] = (520ul * gSubMenuSelection) / 760; // 5.20V empty, blinking above this value, reduced functionality below // gBatteryCalibration[0] = (520ul * gSubMenuSelection) / 760; // 5.20V empty, blinking above this value, reduced functionality below
gBatteryCalibration[1] = (700ul * gSubMenuSelection) / 760; // 7.00V, ~5%, 1 bars above this value // gBatteryCalibration[1] = (689ul * gSubMenuSelection) / 760; // 6.89V, ~5%, 1 bars above this value
gBatteryCalibration[2] = (745ul * gSubMenuSelection) / 760; // 7.45V, ~17%, 2 bars above this value // gBatteryCalibration[2] = (724ul * gSubMenuSelection) / 760; // 7.24V, ~17%, 2 bars above this value
gBatteryCalibration[3] = gSubMenuSelection; // 7.6V, ~29%, 3 bars above this value gBatteryCalibration[3] = gSubMenuSelection; // 7.6V, ~29%, 3 bars above this value
gBatteryCalibration[4] = (788ul * gSubMenuSelection) / 760; // 7.88V, ~65%, 4 bars above this value // gBatteryCalibration[4] = (771ul * gSubMenuSelection) / 760; // 7.71V, ~65%, 4 bars above this value
gBatteryCalibration[5] = 2300; // gBatteryCalibration[5] = 2300;
SETTINGS_SaveBatteryCalibration(gBatteryCalibration); SETTINGS_SaveBatteryCalibration(gBatteryCalibration);
return; return;
} }
case MENU_BATTYP:
gEeprom.BATTERY_TYPE = gSubMenuSelection;
break;
case MENU_F1SHRT: case MENU_F1SHRT:
case MENU_F1LONG: case MENU_F1LONG:
case MENU_F2SHRT: case MENU_F2SHRT:
case MENU_F2LONG: case MENU_F2LONG:
case MENU_MLONG:
{ {
uint8_t * fun[]= { uint8_t * fun[]= {
&gEeprom.KEY_1_SHORT_PRESS_ACTION, &gEeprom.KEY_1_SHORT_PRESS_ACTION,
&gEeprom.KEY_1_LONG_PRESS_ACTION, &gEeprom.KEY_1_LONG_PRESS_ACTION,
&gEeprom.KEY_2_SHORT_PRESS_ACTION, &gEeprom.KEY_2_SHORT_PRESS_ACTION,
&gEeprom.KEY_2_LONG_PRESS_ACTION}; &gEeprom.KEY_2_LONG_PRESS_ACTION,
*fun[GetCurrentMenuId()-MENU_F1SHRT] = gSubMenu_SIDEFUNCTIONS[gSubMenuSelection].id; &gEeprom.KEY_M_LONG_PRESS_ACTION};
*fun[UI_MENU_GetCurrentMenuId()-MENU_F1SHRT] = gSubMenu_SIDEFUNCTIONS[gSubMenuSelection].id;
} }
break; break;
@@ -781,53 +834,12 @@ void MENU_AcceptSetting(void)
gRequestSaveSettings = true; gRequestSaveSettings = true;
} }
void MENU_SelectNextCode(void)
{
int32_t UpperLimit;
if (GetCurrentMenuId() == MENU_R_DCS)
UpperLimit = 208;
//UpperLimit = ARRAY_SIZE(DCS_Options);
else if (GetCurrentMenuId() == MENU_R_CTCS)
UpperLimit = ARRAY_SIZE(CTCSS_Options) - 1;
else
return;
gSubMenuSelection = NUMBER_AddWithWraparound(gSubMenuSelection, gMenuScrollDirection, 1, UpperLimit);
if (GetCurrentMenuId() == MENU_R_DCS)
{
if (gSubMenuSelection > 104)
{
gSelectedCodeType = CODE_TYPE_REVERSE_DIGITAL;
gSelectedCode = gSubMenuSelection - 105;
}
else
{
gSelectedCodeType = CODE_TYPE_DIGITAL;
gSelectedCode = gSubMenuSelection - 1;
}
}
else
{
gSelectedCodeType = CODE_TYPE_CONTINUOUS_TONE;
gSelectedCode = gSubMenuSelection - 1;
}
RADIO_SetupRegisters(true);
gScanPauseDelayIn_10ms = (gSelectedCodeType == CODE_TYPE_CONTINUOUS_TONE) ? scan_pause_delay_in_3_10ms : scan_pause_delay_in_4_10ms;
gUpdateDisplay = true;
}
static void MENU_ClampSelection(int8_t Direction) static void MENU_ClampSelection(int8_t Direction)
{ {
int32_t Min; int32_t Min;
int32_t Max; int32_t Max;
if (!MENU_GetLimits(GetCurrentMenuId(), &Min, &Max)) if (!MENU_GetLimits(UI_MENU_GetCurrentMenuId(), &Min, &Max))
{ {
int32_t Selection = gSubMenuSelection; int32_t Selection = gSubMenuSelection;
if (Selection < Min) Selection = Min; if (Selection < Min) Selection = Min;
@@ -839,42 +851,55 @@ static void MENU_ClampSelection(int8_t Direction)
void MENU_ShowCurrentSetting(void) void MENU_ShowCurrentSetting(void)
{ {
switch (GetCurrentMenuId()) switch (UI_MENU_GetCurrentMenuId())
{ {
case MENU_SQL: case MENU_SQL:
gSubMenuSelection = gEeprom.SQUELCH_LEVEL; gSubMenuSelection = gEeprom.SQUELCH_LEVEL;
break; break;
case MENU_STEP: case MENU_STEP:
gSubMenuSelection = gTxVfo->STEP_SETTING; gSubMenuSelection = FREQUENCY_GetSortedIdxFromStepIdx(gTxVfo->STEP_SETTING);
break; break;
case MENU_TXP: case MENU_TXP:
gSubMenuSelection = gTxVfo->OUTPUT_POWER; gSubMenuSelection = gTxVfo->OUTPUT_POWER;
break; break;
case MENU_R_DCS: case MENU_RESET:
switch (gTxVfo->freq_config_RX.CodeType) gSubMenuSelection = 0;
{ break;
case MENU_R_DCS:
case MENU_R_CTCS:
{
DCS_CodeType_t type = gTxVfo->freq_config_RX.CodeType;
uint8_t code = gTxVfo->freq_config_RX.Code;
int menuid = UI_MENU_GetCurrentMenuId();
if(gScanUseCssResult) {
gScanUseCssResult = false;
type = gScanCssResultType;
code = gScanCssResultCode;
}
if((menuid==MENU_R_CTCS) ^ (type==CODE_TYPE_CONTINUOUS_TONE)) { //not the same type
gSubMenuSelection = 0;
break;
}
switch (type) {
case CODE_TYPE_CONTINUOUS_TONE:
case CODE_TYPE_DIGITAL: case CODE_TYPE_DIGITAL:
gSubMenuSelection = gTxVfo->freq_config_RX.Code + 1; gSubMenuSelection = code + 1;
break; break;
case CODE_TYPE_REVERSE_DIGITAL: case CODE_TYPE_REVERSE_DIGITAL:
gSubMenuSelection = gTxVfo->freq_config_RX.Code + 105; gSubMenuSelection = code + 105;
break; break;
default: default:
gSubMenuSelection = 0; gSubMenuSelection = 0;
break; break;
} }
break; break;
}
case MENU_RESET:
gSubMenuSelection = 0;
break;
case MENU_R_CTCS:
gSubMenuSelection = (gTxVfo->freq_config_RX.CodeType == CODE_TYPE_CONTINUOUS_TONE) ? gTxVfo->freq_config_RX.Code + 1 : 0;
break;
case MENU_T_DCS: case MENU_T_DCS:
switch (gTxVfo->freq_config_TX.CodeType) switch (gTxVfo->freq_config_TX.CodeType)
@@ -931,19 +956,24 @@ void MENU_ShowCurrentSetting(void)
gSubMenuSelection = gEeprom.BATTERY_SAVE; gSubMenuSelection = gEeprom.BATTERY_SAVE;
break; break;
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
case MENU_VOX: case MENU_VOX:
gSubMenuSelection = gEeprom.VOX_SWITCH ? gEeprom.VOX_LEVEL + 1 : 0; gSubMenuSelection = gEeprom.VOX_SWITCH ? gEeprom.VOX_LEVEL + 1 : 0;
break; break;
#endif #endif
case MENU_ABR: case MENU_ABR:
gSubMenuSelection = gEeprom.BACKLIGHT; gSubMenuSelection = gEeprom.BACKLIGHT_TIME;
gBacklightCountdown = 0;
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight ON while in backlight menu
break; break;
case MENU_ABR_MIN:
gSubMenuSelection = gEeprom.BACKLIGHT_MIN;
break;
case MENU_ABR_MAX:
gSubMenuSelection = gEeprom.BACKLIGHT_MAX;
break;
case MENU_ABR_ON_TX_RX: case MENU_ABR_ON_TX_RX:
gSubMenuSelection = gSetting_backlight_on_tx_rx; gSubMenuSelection = gSetting_backlight_on_tx_rx;
break; break;
@@ -960,11 +990,11 @@ void MENU_ShowCurrentSetting(void)
gSubMenuSelection = gEeprom.TX_TIMEOUT_TIMER; gSubMenuSelection = gEeprom.TX_TIMEOUT_TIMER;
break; break;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
case MENU_VOICE: case MENU_VOICE:
gSubMenuSelection = gEeprom.VOICE_PROMPT; gSubMenuSelection = gEeprom.VOICE_PROMPT;
break; break;
#endif #endif
case MENU_SC_REV: case MENU_SC_REV:
gSubMenuSelection = gEeprom.SCAN_RESUME_MODE; gSubMenuSelection = gEeprom.SCAN_RESUME_MODE;
@@ -987,7 +1017,7 @@ void MENU_ShowCurrentSetting(void)
break; break;
case MENU_STE: case MENU_STE:
gSubMenuSelection = gEeprom.TAIL_NOTE_ELIMINATION; gSubMenuSelection = gEeprom.TAIL_TONE_ELIMINATION;
break; break;
case MENU_RP_STE: case MENU_RP_STE:
@@ -998,11 +1028,11 @@ void MENU_ShowCurrentSetting(void)
gSubMenuSelection = gEeprom.MIC_SENSITIVITY; gSubMenuSelection = gEeprom.MIC_SENSITIVITY;
break; break;
#ifdef ENABLE_AUDIO_BAR #ifdef ENABLE_AUDIO_BAR
case MENU_MIC_BAR: case MENU_MIC_BAR:
gSubMenuSelection = gSetting_mic_bar; gSubMenuSelection = gSetting_mic_bar;
break; break;
#endif #endif
case MENU_COMPAND: case MENU_COMPAND:
gSubMenuSelection = gTxVfo->Compander; gSubMenuSelection = gTxVfo->Compander;
@@ -1075,14 +1105,14 @@ void MENU_ShowCurrentSetting(void)
break; break;
case MENU_AM: case MENU_AM:
gSubMenuSelection = gTxVfo->AM_mode; gSubMenuSelection = gTxVfo->Modulation;
break; break;
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
case MENU_AM_FIX: case MENU_AM_FIX:
gSubMenuSelection = gSetting_AM_fix; gSubMenuSelection = gSetting_AM_fix;
break; break;
#endif #endif
#ifdef ENABLE_AM_FIX_TEST1 #ifdef ENABLE_AM_FIX_TEST1
case MENU_AM_FIX_TEST1: case MENU_AM_FIX_TEST1:
@@ -1128,10 +1158,6 @@ void MENU_ShowCurrentSetting(void)
gSubMenuSelection = gSetting_ScrambleEnable; gSubMenuSelection = gSetting_ScrambleEnable;
break; break;
case MENU_TX_EN:
gSubMenuSelection = gSetting_TX_EN;
break;
#ifdef ENABLE_F_CAL_MENU #ifdef ENABLE_F_CAL_MENU
case MENU_F_CALI: case MENU_F_CALI:
gSubMenuSelection = gEeprom.BK4819_XTAL_FREQ_LOW; gSubMenuSelection = gEeprom.BK4819_XTAL_FREQ_LOW;
@@ -1142,17 +1168,23 @@ void MENU_ShowCurrentSetting(void)
gSubMenuSelection = gBatteryCalibration[3]; gSubMenuSelection = gBatteryCalibration[3];
break; break;
case MENU_BATTYP:
gSubMenuSelection = gEeprom.BATTERY_TYPE;
break;
case MENU_F1SHRT: case MENU_F1SHRT:
case MENU_F1LONG: case MENU_F1LONG:
case MENU_F2SHRT: case MENU_F2SHRT:
case MENU_F2LONG: case MENU_F2LONG:
case MENU_MLONG:
{ {
uint8_t * fun[]= { uint8_t * fun[]= {
&gEeprom.KEY_1_SHORT_PRESS_ACTION, &gEeprom.KEY_1_SHORT_PRESS_ACTION,
&gEeprom.KEY_1_LONG_PRESS_ACTION, &gEeprom.KEY_1_LONG_PRESS_ACTION,
&gEeprom.KEY_2_SHORT_PRESS_ACTION, &gEeprom.KEY_2_SHORT_PRESS_ACTION,
&gEeprom.KEY_2_LONG_PRESS_ACTION}; &gEeprom.KEY_2_LONG_PRESS_ACTION,
uint8_t id = *fun[GetCurrentMenuId()-MENU_F1SHRT]; &gEeprom.KEY_M_LONG_PRESS_ACTION};
uint8_t id = *fun[UI_MENU_GetCurrentMenuId()-MENU_F1SHRT];
for(int i = 0; i < gSubMenu_SIDEFUNCTIONS_size; i++) { for(int i = 0; i < gSubMenu_SIDEFUNCTIONS_size; i++) {
if(gSubMenu_SIDEFUNCTIONS[i].id==id) { if(gSubMenu_SIDEFUNCTIONS[i].id==id) {
@@ -1181,7 +1213,7 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0) if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0)
{ // currently editing the channel name { // currently editing the channel name
if (edit_index < 10) if (edit_index < 10)
@@ -1246,7 +1278,7 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
return; return;
} }
if (GetCurrentMenuId() == MENU_OFFSET) if (UI_MENU_GetCurrentMenuId() == MENU_OFFSET)
{ {
uint32_t Frequency; uint32_t Frequency;
@@ -1261,18 +1293,18 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
#endif #endif
NUMBER_Get(gInputBox, &Frequency); Frequency = StrToUL(INPUTBOX_GetAscii())*100;
gSubMenuSelection = FREQUENCY_FloorToStep(Frequency + 75, gTxVfo->StepFrequency, 0); gSubMenuSelection = FREQUENCY_RoundToStep(Frequency, gTxVfo->StepFrequency);
gInputBoxIndex = 0; gInputBoxIndex = 0;
return; return;
} }
if (GetCurrentMenuId() == MENU_MEM_CH || if (UI_MENU_GetCurrentMenuId() == MENU_MEM_CH ||
GetCurrentMenuId() == MENU_DEL_CH || UI_MENU_GetCurrentMenuId() == MENU_DEL_CH ||
GetCurrentMenuId() == MENU_1_CALL || UI_MENU_GetCurrentMenuId() == MENU_1_CALL ||
GetCurrentMenuId() == MENU_MEM_NAME) UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME)
{ // enter 3-digit channel number { // enter 3-digit channel number
if (gInputBoxIndex < 3) if (gInputBoxIndex < 3)
@@ -1288,7 +1320,7 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
Value = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1; Value = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
if (Value <= MR_CHANNEL_LAST) if (IS_MR_CHANNEL(Value))
{ {
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
@@ -1301,7 +1333,7 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
return; return;
} }
if (MENU_GetLimits(GetCurrentMenuId(), &Min, &Max)) if (MENU_GetLimits(UI_MENU_GetCurrentMenuId(), &Min, &Max))
{ {
gInputBoxIndex = 0; gInputBoxIndex = 0;
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
@@ -1342,11 +1374,11 @@ static void MENU_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gCssScanMode == CSS_SCAN_MODE_OFF) if (!gCssBackgroundScan)
{ {
if (gIsInSubMenu) if (gIsInSubMenu)
{ {
if (gInputBoxIndex == 0 || GetCurrentMenuId() != MENU_OFFSET) if (gInputBoxIndex == 0 || UI_MENU_GetCurrentMenuId() != MENU_OFFSET)
{ {
gAskForConfirmation = 0; gAskForConfirmation = 0;
gIsInSubMenu = false; gIsInSubMenu = false;
@@ -1372,10 +1404,9 @@ static void MENU_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
if (gEeprom.BACKLIGHT == 0) if (gEeprom.BACKLIGHT_TIME == 0) // backlight set to always off
{ {
gBacklightCountdown = 0; BACKLIGHT_TurnOff(); // turn the backlight OFF
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight OFF
} }
} }
else else
@@ -1403,12 +1434,12 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
if (!gIsInSubMenu) if (!gIsInSubMenu)
{ {
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
if (GetCurrentMenuId() != MENU_SCR) if (UI_MENU_GetCurrentMenuId() != MENU_SCR)
gAnotherVoiceID = MenuList[gMenuCursor].voice_id; gAnotherVoiceID = MenuList[gMenuCursor].voice_id;
#endif #endif
#if 1 #if 1
if (GetCurrentMenuId() == MENU_DEL_CH || GetCurrentMenuId() == MENU_MEM_NAME) if (UI_MENU_GetCurrentMenuId() == MENU_DEL_CH || UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME)
if (!RADIO_CheckValidChannel(gSubMenuSelection, false, 0)) if (!RADIO_CheckValidChannel(gSubMenuSelection, false, 0))
return; // invalid channel return; // invalid channel
#endif #endif
@@ -1416,7 +1447,7 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
gAskForConfirmation = 0; gAskForConfirmation = 0;
gIsInSubMenu = true; gIsInSubMenu = true;
// if (GetCurrentMenuId() != MENU_D_LIST) // if (UI_MENU_GetCurrentMenuId() != MENU_D_LIST)
{ {
gInputBoxIndex = 0; gInputBoxIndex = 0;
edit_index = -1; edit_index = -1;
@@ -1425,7 +1456,7 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
return; return;
} }
if (GetCurrentMenuId() == MENU_MEM_NAME) if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME)
{ {
if (edit_index < 0) if (edit_index < 0)
{ // enter channel name edit mode { // enter channel name edit mode
@@ -1472,10 +1503,10 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
if (gIsInSubMenu) if (gIsInSubMenu)
{ {
if (GetCurrentMenuId() == MENU_RESET || if (UI_MENU_GetCurrentMenuId() == MENU_RESET ||
GetCurrentMenuId() == MENU_MEM_CH || UI_MENU_GetCurrentMenuId() == MENU_MEM_CH ||
GetCurrentMenuId() == MENU_DEL_CH || UI_MENU_GetCurrentMenuId() == MENU_DEL_CH ||
GetCurrentMenuId() == MENU_MEM_NAME) UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME)
{ {
switch (gAskForConfirmation) switch (gAskForConfirmation)
{ {
@@ -1488,7 +1519,7 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
UI_DisplayMenu(); UI_DisplayMenu();
if (GetCurrentMenuId() == MENU_RESET) if (UI_MENU_GetCurrentMenuId() == MENU_RESET)
{ {
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_CONFIRM); AUDIO_SetVoiceID(0, VOICE_ID_CONFIRM);
@@ -1516,14 +1547,10 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
} }
} }
if (gCssScanMode != CSS_SCAN_MODE_OFF) SCANNER_Stop();
{
gCssScanMode = CSS_SCAN_MODE_OFF;
gUpdateStatus = true;
}
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
if (GetCurrentMenuId() == MENU_SCR) if (UI_MENU_GetCurrentMenuId() == MENU_SCR)
gAnotherVoiceID = (gSubMenuSelection == 0) ? VOICE_ID_SCRAMBLER_OFF : VOICE_ID_SCRAMBLER_ON; gAnotherVoiceID = (gSubMenuSelection == 0) ? VOICE_ID_SCRAMBLER_OFF : VOICE_ID_SCRAMBLER_ON;
else else
gAnotherVoiceID = VOICE_ID_CONFIRM; gAnotherVoiceID = VOICE_ID_CONFIRM;
@@ -1539,7 +1566,7 @@ static void MENU_Key_STAR(const bool bKeyPressed, const bool bKeyHeld)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0) if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0)
{ // currently editing the channel name { // currently editing the channel name
if (edit_index < 10) if (edit_index < 10)
@@ -1561,31 +1588,17 @@ static void MENU_Key_STAR(const bool bKeyPressed, const bool bKeyHeld)
RADIO_SelectVfos(); RADIO_SelectVfos();
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gRxVfo->AM_mode == 0) if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gRxVfo->Modulation == MODULATION_FM)
#else #else
if (gRxVfo->AM_mode == 0) if (gRxVfo->Modulation == MODULATION_FM)
#endif #endif
{ {
if (GetCurrentMenuId() == MENU_R_CTCS || GetCurrentMenuId() == MENU_R_DCS) if ((UI_MENU_GetCurrentMenuId() == MENU_R_CTCS || UI_MENU_GetCurrentMenuId() == MENU_R_DCS) && gIsInSubMenu)
{ // scan CTCSS or DCS to find the tone/code of the incoming signal { // scan CTCSS or DCS to find the tone/code of the incoming signal
if (!SCANNER_IsScanning())
if (gCssScanMode == CSS_SCAN_MODE_OFF) MENU_StartCssScan();
{
MENU_StartCssScan(1);
gRequestDisplayScreen = DISPLAY_MENU;
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN);
AUDIO_PlaySingleVoice(1);
#endif
}
else else
{
MENU_StopCssScan(); MENU_StopCssScan();
gRequestDisplayScreen = DISPLAY_MENU;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
} }
gPttWasReleased = true; gPttWasReleased = true;
@@ -1601,7 +1614,7 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
uint8_t Channel; uint8_t Channel;
bool bCheckScanList; bool bCheckScanList;
if (GetCurrentMenuId() == MENU_MEM_NAME && gIsInSubMenu && edit_index >= 0) if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && gIsInSubMenu && edit_index >= 0)
{ // change the character { // change the character
if (bKeyPressed && edit_index < 10 && Direction != 0) if (bKeyPressed && edit_index < 10 && Direction != 0)
{ {
@@ -1636,12 +1649,7 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
if (!bKeyPressed) if (!bKeyPressed)
return; return;
if (gCssScanMode != CSS_SCAN_MODE_OFF) if (SCANNER_IsScanning()) {
{
MENU_StartCssScan(Direction);
gPttWasReleased = true;
gRequestDisplayScreen = DISPLAY_MENU;
return; return;
} }
@@ -1653,16 +1661,15 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
gRequestDisplayScreen = DISPLAY_MENU; gRequestDisplayScreen = DISPLAY_MENU;
if (GetCurrentMenuId() != MENU_ABR && gEeprom.BACKLIGHT == 0) if (UI_MENU_GetCurrentMenuId() != MENU_ABR && gEeprom.BACKLIGHT_TIME == 0) // backlight always off and not in the backlight menu
{ {
gBacklightCountdown = 0; BACKLIGHT_TurnOff();
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight OFF
} }
return; return;
} }
if (GetCurrentMenuId() == MENU_OFFSET) if (UI_MENU_GetCurrentMenuId() == MENU_OFFSET)
{ {
int32_t Offset = (Direction * gTxVfo->StepFrequency) + gSubMenuSelection; int32_t Offset = (Direction * gTxVfo->StepFrequency) + gSubMenuSelection;
if (Offset < 99999990) if (Offset < 99999990)
@@ -1673,14 +1680,14 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
else else
Offset = 0; Offset = 0;
gSubMenuSelection = FREQUENCY_FloorToStep(Offset, gTxVfo->StepFrequency, 0); gSubMenuSelection = FREQUENCY_RoundToStep(Offset, gTxVfo->StepFrequency);
gRequestDisplayScreen = DISPLAY_MENU; gRequestDisplayScreen = DISPLAY_MENU;
return; return;
} }
VFO = 0; VFO = 0;
switch (GetCurrentMenuId()) switch (UI_MENU_GetCurrentMenuId())
{ {
case MENU_DEL_CH: case MENU_DEL_CH:
case MENU_1_CALL: case MENU_1_CALL:
@@ -1740,7 +1747,7 @@ void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
MENU_Key_STAR(bKeyPressed, bKeyHeld); MENU_Key_STAR(bKeyPressed, bKeyHeld);
break; break;
case KEY_F: case KEY_F:
if (GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0) if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0)
{ // currently editing the channel name { // currently editing the channel name
if (!bKeyHeld && bKeyPressed) if (!bKeyHeld && bKeyPressed)
{ {
@@ -1772,11 +1779,11 @@ void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
if (gScreenToDisplay == DISPLAY_MENU) if (gScreenToDisplay == DISPLAY_MENU)
{ {
if (GetCurrentMenuId() == MENU_VOL || if (UI_MENU_GetCurrentMenuId() == MENU_VOL ||
#ifdef ENABLE_F_CAL_MENU #ifdef ENABLE_F_CAL_MENU
GetCurrentMenuId() == MENU_F_CALI || UI_MENU_GetCurrentMenuId() == MENU_F_CALI ||
#endif #endif
GetCurrentMenuId() == MENU_BATCAL) UI_MENU_GetCurrentMenuId() == MENU_BATCAL)
{ {
gMenuCountdown = menu_timeout_long_500ms; gMenuCountdown = menu_timeout_long_500ms;
} }

View File

@@ -23,11 +23,13 @@
void writeXtalFreqCal(const int32_t value, const bool update_eeprom); void writeXtalFreqCal(const int32_t value, const bool update_eeprom);
#endif #endif
extern uint8_t gUnlockAllTxConfCnt;
int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax); int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax);
void MENU_AcceptSetting(void); void MENU_AcceptSetting(void);
void MENU_SelectNextCode(void);
void MENU_ShowCurrentSetting(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_StopCssScan(void);
void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);

View File

@@ -17,6 +17,7 @@
#include "app/app.h" #include "app/app.h"
#include "app/dtmf.h" #include "app/dtmf.h"
#include "app/generic.h" #include "app/generic.h"
#include "app/menu.h"
#include "app/scanner.h" #include "app/scanner.h"
#include "audio.h" #include "audio.h"
#include "driver/bk4819.h" #include "driver/bk4819.h"
@@ -29,56 +30,45 @@
DCS_CodeType_t gScanCssResultType; DCS_CodeType_t gScanCssResultType;
uint8_t gScanCssResultCode; uint8_t gScanCssResultCode;
bool gFlagStartScan; bool gScanSingleFrequency; // scan CTCSS/DCS codes for current frequency
bool gFlagStopScan; SCAN_SaveState_t gScannerSaveState;
bool gScanSingleFrequency;
uint8_t gScannerEditState;
uint8_t gScanChannel; uint8_t gScanChannel;
uint32_t gScanFrequency; uint32_t gScanFrequency;
bool gScanPauseMode;
SCAN_CssState_t gScanCssState; SCAN_CssState_t gScanCssState;
volatile bool gScheduleScanListen = true;
volatile uint16_t gScanPauseDelayIn_10ms;
uint8_t gScanProgressIndicator; uint8_t gScanProgressIndicator;
uint8_t gScanHitCount;
bool gScanUseCssResult; bool gScanUseCssResult;
int8_t gScanStateDir;
bool bScanKeepFrequency; STEP_Setting_t stepSetting;
uint8_t gRestoreMrChannel; uint8_t scanHitCount;
uint8_t gRestoreCROSS_BAND_RX_TX;
static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{ {
if (!bKeyHeld && bKeyPressed) if (!bKeyHeld && bKeyPressed)
{ {
if (gScannerEditState == 1) if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
{
uint16_t Channel;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
INPUTBOX_Append(Key); INPUTBOX_Append(Key);
gRequestDisplayScreen = DISPLAY_SCANNER; gRequestDisplayScreen = DISPLAY_SCANNER;
if (gInputBoxIndex < 3) if (gInputBoxIndex < 3) {
{ #ifdef ENABLE_VOICE
#ifdef ENABLE_VOICE gAnotherVoiceID = (VOICE_ID_t)Key;
gAnotherVoiceID = (VOICE_ID_t)Key; #endif
#endif
return; return;
} }
gInputBoxIndex = 0; gInputBoxIndex = 0;
Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1; uint16_t chan = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
if (Channel <= MR_CHANNEL_LAST) if (IS_MR_CHANNEL(chan)) {
{ #ifdef ENABLE_VOICE
#ifdef ENABLE_VOICE gAnotherVoiceID = (VOICE_ID_t)Key;
gAnotherVoiceID = (VOICE_ID_t)Key; #endif
#endif gShowChPrefix = RADIO_CheckValidChannel(chan, false, 0);
gShowChPrefix = RADIO_CheckValidChannel(Channel, false, 0); gScanChannel = (uint8_t)chan;
gScanChannel = (uint8_t)Channel;
return; return;
} }
} }
@@ -89,28 +79,17 @@ static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
static void SCANNER_Key_EXIT(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; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
switch (gScannerEditState) switch (gScannerSaveState) {
{ case SCAN_SAVE_NO_PROMPT:
case 0: SCANNER_Stop();
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
gEeprom.CROSS_BAND_RX_TX = gBackup_CROSS_BAND_RX_TX;
gUpdateStatus = true;
gFlagStopScan = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
gFlagResetVfos = true;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
break; break;
case 1: case SCAN_SAVE_CHAN_SEL:
if (gInputBoxIndex > 0) if (gInputBoxIndex > 0) {
{
gInputBox[--gInputBoxIndex] = 10; gInputBox[--gInputBoxIndex] = 10;
gRequestDisplayScreen = DISPLAY_SCANNER; gRequestDisplayScreen = DISPLAY_SCANNER;
break; break;
@@ -118,11 +97,11 @@ static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
// Fallthrough // Fallthrough
case 2: case SCAN_SAVE_CHANNEL:
gScannerEditState = 0; gScannerSaveState = SCAN_SAVE_NO_PROMPT;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL; gAnotherVoiceID = VOICE_ID_CANCEL;
#endif #endif
gRequestDisplayScreen = DISPLAY_SCANNER; gRequestDisplayScreen = DISPLAY_SCANNER;
break; break;
} }
@@ -131,118 +110,85 @@ static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld) static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
{ {
uint8_t Channel; if (bKeyHeld || !bKeyPressed) // ignore long press or release button events
if (bKeyHeld)
return; return;
if (!bKeyPressed) if (gScanCssState == SCAN_CSS_STATE_OFF && !gScanSingleFrequency) {
return;
if (gScanCssState == SCAN_CSS_STATE_OFF && !gScanSingleFrequency)
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return; return;
} }
if (gScanCssState == SCAN_CSS_STATE_SCANNING) if (gScanCssState == SCAN_CSS_STATE_SCANNING && gScanSingleFrequency) {
{ gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
if (gScanSingleFrequency) return;
{
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; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return; return;
} }
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
switch (gScannerEditState) switch (gScannerSaveState) {
{ case SCAN_SAVE_NO_PROMPT:
case 0:
if (!gScanSingleFrequency) if (!gScanSingleFrequency)
{ {
int16_t Delta625; uint32_t freq250 = FREQUENCY_RoundToStep(gScanFrequency, 250);
uint32_t Freq250 = FREQUENCY_FloorToStep(gScanFrequency, 250, 0); uint32_t freq625 = FREQUENCY_RoundToStep(gScanFrequency, 625);
uint32_t Freq625 = FREQUENCY_FloorToStep(gScanFrequency, 625, 0);
int16_t Delta250 = (int16_t)gScanFrequency - (int16_t)Freq250;
if (125 < Delta250) uint32_t diff250 = gScanFrequency > freq250 ? gScanFrequency - freq250 : freq250 - gScanFrequency;
{ uint32_t diff625 = gScanFrequency > freq625 ? gScanFrequency - freq625 : freq625 - gScanFrequency;
Delta250 = 250 - Delta250;
Freq250 += 250; if(diff250 > diff625) {
stepSetting = STEP_6_25kHz;
gScanFrequency = freq625;
} }
else {
Delta625 = (int16_t)gScanFrequency - (int16_t)Freq625; stepSetting = STEP_2_5kHz;
gScanFrequency = freq250;
if (312 < Delta625)
{
Delta625 = 625 - Delta625;
Freq625 += 625;
}
if (Delta625 < Delta250)
{
gStepSetting = STEP_6_25kHz;
gScanFrequency = Freq625;
}
else
{
gStepSetting = STEP_2_5kHz;
gScanFrequency = Freq250;
} }
} }
if (gTxVfo->CHANNEL_SAVE <= MR_CHANNEL_LAST) if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
{ gScannerSaveState = SCAN_SAVE_CHAN_SEL;
gScannerEditState = 1;
gScanChannel = gTxVfo->CHANNEL_SAVE; gScanChannel = gTxVfo->CHANNEL_SAVE;
gShowChPrefix = RADIO_CheckValidChannel(gTxVfo->CHANNEL_SAVE, false, 0); gShowChPrefix = RADIO_CheckValidChannel(gTxVfo->CHANNEL_SAVE, false, 0);
} }
else else {
{ gScannerSaveState = SCAN_SAVE_CHANNEL;
gScannerEditState = 2;
} }
gScanCssState = SCAN_CSS_STATE_FOUND; gScanCssState = SCAN_CSS_STATE_FOUND;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_MEMORY_CHANNEL; gAnotherVoiceID = VOICE_ID_MEMORY_CHANNEL;
#endif #endif
gRequestDisplayScreen = DISPLAY_SCANNER; gRequestDisplayScreen = DISPLAY_SCANNER;
gUpdateStatus = true; gUpdateStatus = true;
break; break;
case 1: case SCAN_SAVE_CHAN_SEL:
if (gInputBoxIndex == 0) if (gInputBoxIndex == 0) {
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gRequestDisplayScreen = DISPLAY_SCANNER; gRequestDisplayScreen = DISPLAY_SCANNER;
gScannerEditState = 2; gScannerSaveState = SCAN_SAVE_CHANNEL;
} }
break; break;
case 2: case SCAN_SAVE_CHANNEL:
if (!gScanSingleFrequency) if (!gScanSingleFrequency) {
{
RADIO_InitInfo(gTxVfo, gTxVfo->CHANNEL_SAVE, gScanFrequency); RADIO_InitInfo(gTxVfo, gTxVfo->CHANNEL_SAVE, gScanFrequency);
if (gScanUseCssResult) if (gScanUseCssResult) {
{
gTxVfo->freq_config_RX.CodeType = gScanCssResultType; gTxVfo->freq_config_RX.CodeType = gScanCssResultType;
gTxVfo->freq_config_RX.Code = gScanCssResultCode; gTxVfo->freq_config_RX.Code = gScanCssResultCode;
} }
gTxVfo->freq_config_TX = gTxVfo->freq_config_RX; 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(0, VFO_CONFIGURE_RELOAD);
RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD); RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD);
@@ -252,25 +198,24 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
gTxVfo->freq_config_TX.Code = gScanCssResultCode; gTxVfo->freq_config_TX.Code = gScanCssResultCode;
} }
if (gTxVfo->CHANNEL_SAVE <= MR_CHANNEL_LAST) uint8_t chan;
{ if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
Channel = gScanChannel; chan = gScanChannel;
gEeprom.MrChannel[gEeprom.TX_VFO] = Channel; gEeprom.MrChannel[gEeprom.TX_VFO] = chan;
} }
else else {
{ chan = gTxVfo->Band + FREQ_CHANNEL_FIRST;
Channel = gTxVfo->Band + FREQ_CHANNEL_FIRST; gEeprom.FreqChannel[gEeprom.TX_VFO] = chan;
gEeprom.FreqChannel[gEeprom.TX_VFO] = Channel;
} }
gTxVfo->CHANNEL_SAVE = Channel; gTxVfo->CHANNEL_SAVE = chan;
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel; gEeprom.ScreenChannel[gEeprom.TX_VFO] = chan;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CONFIRM; gAnotherVoiceID = VOICE_ID_CONFIRM;
#endif #endif
gRequestDisplayScreen = DISPLAY_SCANNER; gRequestDisplayScreen = DISPLAY_SCANNER;
gRequestSaveChannel = 2; gRequestSaveChannel = 2;
gScannerEditState = 0; gScannerSaveState = SCAN_SAVE_NO_PROMPT;
break; break;
default: default:
@@ -281,23 +226,20 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
static void SCANNER_Key_STAR(bool bKeyPressed, bool bKeyHeld) static void SCANNER_Key_STAR(bool bKeyPressed, bool bKeyHeld)
{ {
if (!bKeyHeld && bKeyPressed) if (!bKeyHeld && bKeyPressed) {
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gFlagStartScan = true; SCANNER_Start(gScanSingleFrequency);
} }
return; return;
} }
static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Direction) static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Direction)
{ {
if (pKeyHeld) if (pKeyHeld) {
{
if (!bKeyPressed) if (!bKeyPressed)
return; return;
} }
else else {
{
if (!bKeyPressed) if (!bKeyPressed)
return; return;
@@ -305,8 +247,7 @@ static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Directio
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
} }
if (gScannerEditState == 1) if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
{
gScanChannel = NUMBER_AddWithWraparound(gScanChannel, Direction, 0, MR_CHANNEL_LAST); gScanChannel = NUMBER_AddWithWraparound(gScanChannel, Direction, 0, MR_CHANNEL_LAST);
gShowChPrefix = RADIO_CheckValidChannel(gScanChannel, false, 0); gShowChPrefix = RADIO_CheckValidChannel(gScanChannel, false, 0);
gRequestDisplayScreen = DISPLAY_SCANNER; gRequestDisplayScreen = DISPLAY_SCANNER;
@@ -317,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) void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{ {
switch (Key) switch (Key) {
{
case KEY_0: case KEY_0:
case KEY_1: case KEY_1:
case KEY_2: case KEY_2:
@@ -356,13 +296,16 @@ void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
} }
} }
void SCANNER_Start(void) void SCANNER_Start(bool singleFreq)
{ {
uint8_t BackupStep; gScanSingleFrequency = singleFreq;
uint16_t BackupFrequency; gMonitor = false;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;
#endif
BK4819_StopScan(); BK4819_StopScan();
RADIO_SelectVfos(); RADIO_SelectVfos();
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
@@ -370,13 +313,13 @@ void SCANNER_Start(void)
gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + BAND6_400MHz; gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + BAND6_400MHz;
#endif #endif
BackupStep = gRxVfo->STEP_SETTING; uint8_t backupStep = gRxVfo->STEP_SETTING;
BackupFrequency = gRxVfo->StepFrequency; uint16_t backupFrequency = gRxVfo->StepFrequency;
RADIO_InitInfo(gRxVfo, gRxVfo->CHANNEL_SAVE, gRxVfo->pRX->Frequency); RADIO_InitInfo(gRxVfo, gRxVfo->CHANNEL_SAVE, gRxVfo->pRX->Frequency);
gRxVfo->STEP_SETTING = BackupStep; gRxVfo->STEP_SETTING = backupStep;
gRxVfo->StepFrequency = BackupFrequency; gRxVfo->StepFrequency = backupFrequency;
RADIO_SetupRegisters(true); RADIO_SetupRegisters(true);
@@ -384,23 +327,21 @@ void SCANNER_Start(void)
gIsNoaaMode = false; gIsNoaaMode = false;
#endif #endif
if (gScanSingleFrequency) if (gScanSingleFrequency) {
{
gScanCssState = SCAN_CSS_STATE_SCANNING; gScanCssState = SCAN_CSS_STATE_SCANNING;
gScanFrequency = gRxVfo->pRX->Frequency; gScanFrequency = gRxVfo->pRX->Frequency;
gStepSetting = gRxVfo->STEP_SETTING; stepSetting = gRxVfo->STEP_SETTING;
BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency); BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency);
BK4819_SetScanFrequency(gScanFrequency); BK4819_SetScanFrequency(gScanFrequency);
gUpdateStatus = true; gUpdateStatus = true;
} }
else else {
{
gScanCssState = SCAN_CSS_STATE_OFF; gScanCssState = SCAN_CSS_STATE_OFF;
gScanFrequency = 0xFFFFFFFF; gScanFrequency = 0xFFFFFFFF;
BK4819_PickRXFilterPathBasedOnFrequency(0xFFFFFFFF); BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency);
BK4819_EnableFrequencyScan(); BK4819_EnableFrequencyScan();
gUpdateStatus = true; gUpdateStatus = true;
@@ -411,7 +352,7 @@ void SCANNER_Start(void)
gScanDelay_10ms = scan_delay_10ms; gScanDelay_10ms = scan_delay_10ms;
gScanCssResultCode = 0xFF; gScanCssResultCode = 0xFF;
gScanCssResultType = 0xFF; gScanCssResultType = 0xFF;
gScanHitCount = 0; scanHitCount = 0;
gScanUseCssResult = false; gScanUseCssResult = false;
g_CxCSS_TAIL_Found = false; g_CxCSS_TAIL_Found = false;
g_CDCSS_Lost = false; g_CDCSS_Lost = false;
@@ -421,220 +362,165 @@ void SCANNER_Start(void)
g_VOX_Lost = false; g_VOX_Lost = false;
#endif #endif
g_SquelchLost = false; g_SquelchLost = false;
gScannerEditState = 0; gScannerSaveState = SCAN_SAVE_NO_PROMPT;
gScanProgressIndicator = 0; gScanProgressIndicator = 0;
} }
void SCANNER_Stop(void) void SCANNER_Stop(void)
{ {
if(gRestoreCROSS_BAND_RX_TX != CROSS_BAND_OFF) { if(SCANNER_IsScanning()) {
gEeprom.CROSS_BAND_RX_TX = gRestoreCROSS_BAND_RX_TX; gEeprom.CROSS_BAND_RX_TX = gBackup_CROSS_BAND_RX_TX;
gRestoreCROSS_BAND_RX_TX = CROSS_BAND_OFF; gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
} gFlagResetVfos = true;
gUpdateStatus = true;
gScanStateDir = SCAN_OFF; gCssBackgroundScan = false;
gScanUseCssResult = false;
if (!bScanKeepFrequency) #ifdef ENABLE_VOICE
{ gAnotherVoiceID = VOICE_ID_CANCEL;
if (gNextMrChannel <= MR_CHANNEL_LAST)
{
gEeprom.MrChannel[gEeprom.RX_VFO] = gRestoreMrChannel;
gEeprom.ScreenChannel[gEeprom.RX_VFO] = gRestoreMrChannel;
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
}
else
{
gRxVfo->freq_config_RX.Frequency = gRestoreFrequency;
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
}
RADIO_SetupRegisters(true);
gUpdateDisplay = true;
return;
}
if (gRxVfo->CHANNEL_SAVE > MR_CHANNEL_LAST)
{
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_VFO, gRxVfo, 1);
return;
}
SETTINGS_SaveVfoIndices();
gUpdateStatus = true;
}
static void SCANNER_NextFreqChannel(void)
{
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 #endif
BK4819_StopScan();
bScanKeepFrequency = false; }
gUpdateDisplay = true;
} }
static void SCANNER_NextMemChannel(void) void SCANNER_TimeSlice10ms(void)
{ {
static unsigned int prev_mr_chan = 0; if (!SCANNER_IsScanning())
const bool enabled = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCAN_LIST_ENABLED[gEeprom.SCAN_LIST_DEFAULT] : true; return;
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) if (gScanDelay_10ms > 0) {
{ gScanDelay_10ms--;
switch (gCurrentScanList) return;
{ }
case SCAN_NEXT_CHAN_SCANLIST1:
prev_mr_chan = gNextMrChannel;
if (chan1 >= 0)
{
if (RADIO_CheckValidChannel(chan1, false, 0))
{
gCurrentScanList = SCAN_NEXT_CHAN_SCANLIST1;
gNextMrChannel = chan1;
break;
}
}
[[fallthrough]];
case SCAN_NEXT_CHAN_SCANLIST2:
if (chan2 >= 0)
{
if (RADIO_CheckValidChannel(chan2, false, 0))
{
gCurrentScanList = 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 (chan <= MR_CHANNEL_LAST)
// {
// gCurrentScanList = SCAN_NEXT_CHAN_DUAL_WATCH;
// gNextMrChannel = chan;
// break;
// }
// }
default: if (gScannerSaveState != SCAN_SAVE_NO_PROMPT) {
case SCAN_NEXT_CHAN_MR: return;
gCurrentScanList = SCAN_NEXT_CHAN_MR; }
gNextMrChannel = prev_mr_chan;
chan = 0xff; switch (gScanCssState) {
case SCAN_CSS_STATE_OFF: {
// must be RF frequency scanning if we're here ?
uint32_t result;
if (!BK4819_GetFrequencyScanResult(&result))
break; 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;
} }
if (!enabled || chan == 0xff) }
{
chan = RADIO_FindNextChannel(gNextMrChannel + gScanStateDir, gScanStateDir, (gEeprom.SCAN_LIST_DEFAULT < 2) ? true : false, gEeprom.SCAN_LIST_DEFAULT); void SCANNER_TimeSlice500ms(void)
if (chan == 0xFF) {
{ // no valid channel found if (SCANNER_IsScanning() && gScannerSaveState == SCAN_SAVE_NO_PROMPT && gScanCssState < SCAN_CSS_STATE_FOUND) {
gScanProgressIndicator++;
chan = MR_CHANNEL_FIRST; #ifdef ENABLE_NO_CODE_SCAN_TIMEOUT
// return; if (gScanProgressIndicator > 32) {
if (gScanCssState == SCAN_CSS_STATE_SCANNING && !gScanSingleFrequency)
gScanCssState = SCAN_CSS_STATE_FOUND;
else
gScanCssState = SCAN_CSS_STATE_FAILED;
gUpdateStatus = true;
} }
#endif
gNextMrChannel = chan; gUpdateDisplay = true;
} }
else if(gCssBackgroundScan) {
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; 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
bScanKeepFrequency = false;
if (enabled)
if (++gCurrentScanList >= SCAN_NEXT_NUM)
gCurrentScanList = SCAN_NEXT_CHAN_SCANLIST1; // back round we go
} }
void SCANNER_NextChannel(const bool storeBackupSettings, const int8_t scan_direction) bool SCANNER_IsScanning(void)
{ {
if (storeBackupSettings) { return gCssBackgroundScan || (gScreenToDisplay == DISPLAY_SCANNER);
gRestoreCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
}
RADIO_SelectVfos();
gNextMrChannel = gRxVfo->CHANNEL_SAVE;
gCurrentScanList = SCAN_NEXT_CHAN_SCANLIST1;
gScanStateDir = scan_direction;
if (gNextMrChannel <= MR_CHANNEL_LAST)
{ // channel mode
if (storeBackupSettings)
gRestoreMrChannel = gNextMrChannel;
SCANNER_NextMemChannel();
}
else
{ // frequency mode
if (storeBackupSettings)
gRestoreFrequency = gRxVfo->freq_config_RX.Frequency;
SCANNER_NextFreqChannel();
}
gScanPauseDelayIn_10ms = scan_pause_delay_in_2_10ms;
gScheduleScanListen = false;
gRxReceptionMode = RX_MODE_NONE;
gScanPauseMode = false;
bScanKeepFrequency = false;
}
void SCANNER_ContinueScanning()
{
if (IS_FREQ_CHANNEL(gNextMrChannel))
{
if (gCurrentFunction == FUNCTION_INCOMING)
APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE, true);
else
SCANNER_NextFreqChannel(); // switch to next frequency
}
else
{
if (gCurrentCodeType == CODE_TYPE_OFF && gCurrentFunction == FUNCTION_INCOMING)
APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE, true);
else
SCANNER_NextMemChannel(); // switch to next channel
}
gScanPauseMode = false;
gRxReceptionMode = RX_MODE_NONE;
gScheduleScanListen = false;
} }

View File

@@ -20,46 +20,38 @@
#include "dcs.h" #include "dcs.h"
#include "driver/keyboard.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_SCANNING,
SCAN_CSS_STATE_FOUND, SCAN_CSS_STATE_FOUND,
SCAN_CSS_STATE_FAILED SCAN_CSS_STATE_FAILED
}; } SCAN_CssState_t;
typedef enum SCAN_CssState_t SCAN_CssState_t; typedef enum
enum
{ {
SCAN_REV = -1, SCAN_SAVE_NO_PROMPT, // saving process not initiated
SCAN_OFF = 0, SCAN_SAVE_CHAN_SEL, // "SAVE: ", channel select prompt, actives only in channel mode
SCAN_FWD = +1 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 DCS_CodeType_t gScanCssResultType;
extern uint8_t gScanCssResultCode; extern uint8_t gScanCssResultCode;
extern bool gFlagStartScan;
extern bool gFlagStopScan;
extern bool gScanSingleFrequency; extern bool gScanSingleFrequency;
extern uint8_t gScannerEditState; extern SCAN_SaveState_t gScannerSaveState;
extern uint8_t gScanChannel; extern uint8_t gScanChannel;
extern uint32_t gScanFrequency; extern uint32_t gScanFrequency;
extern bool gScanPauseMode;
extern SCAN_CssState_t gScanCssState; extern SCAN_CssState_t gScanCssState;
extern volatile bool gScheduleScanListen;
extern volatile uint16_t gScanPauseDelayIn_10ms;
extern uint8_t gScanProgressIndicator; extern uint8_t gScanProgressIndicator;
extern uint8_t gScanHitCount;
extern bool gScanUseCssResult; extern bool gScanUseCssResult;
extern int8_t gScanStateDir;
extern bool bScanKeepFrequency;
void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); 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_Stop(void);
void SCANNER_NextChannel(const bool storeBackupSettings, const int8_t scan_direction); void SCANNER_TimeSlice10ms(void);
void SCANNER_ContinueScanning(); void SCANNER_TimeSlice500ms(void);
bool SCANNER_IsScanning(void);
#endif #endif

View File

@@ -14,7 +14,10 @@
* limitations under the License. * 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 { struct FrequencyBandInfo {
uint32_t lower; uint32_t lower;
@@ -22,19 +25,8 @@ struct FrequencyBandInfo {
uint32_t middle; uint32_t middle;
}; };
const struct FrequencyBandInfo FrequencyBandTable[7] = { #define F_MIN frequencyBandTable[0].lower
[BAND1_50MHz ] = {.lower = 1600000, .middle = 6500000, .upper = 7600000}, #define F_MAX frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper
[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
const uint16_t RSSI_MAX_VALUE = 65535; const uint16_t RSSI_MAX_VALUE = 65535;
@@ -58,7 +50,6 @@ ScanInfo scanInfo;
KeyboardState kbd = {KEY_INVALID, KEY_INVALID, 0}; KeyboardState kbd = {KEY_INVALID, KEY_INVALID, 0};
const char *bwOptions[] = {" 25k", "12.5k", "6.25k"}; const char *bwOptions[] = {" 25k", "12.5k", "6.25k"};
const char *modulationTypeOptions[] = {" FM", " AM", "USB"};
const uint8_t modulationTypeTuneSteps[] = {100, 50, 10}; const uint8_t modulationTypeTuneSteps[] = {100, 50, 10};
const uint8_t modTypeReg47Values[] = {1, 7, 5}; const uint8_t modTypeReg47Values[] = {1, 7, 5};
@@ -76,22 +67,22 @@ SpectrumSettings settings = {stepsCount: STEPS_64,
uint32_t fMeasure = 0; uint32_t fMeasure = 0;
uint32_t currentFreq, tempFreq; uint32_t currentFreq, tempFreq;
uint16_t rssiHistory[128] = {}; uint16_t rssiHistory[128];
uint8_t freqInputIndex = 0; uint8_t freqInputIndex = 0;
uint8_t freqInputDotIndex = 0; uint8_t freqInputDotIndex = 0;
KEY_Code_t freqInputArr[10]; KEY_Code_t freqInputArr[10];
char freqInputString[11] = "----------\0"; // XXXX.XXXXX\0 char freqInputString[11];
uint8_t menuState = 0; uint8_t menuState = 0;
uint16_t listenT = 0; uint16_t listenT = 0;
RegisterSpec registerSpecs[] = { RegisterSpec registerSpecs[] = {
{}, {},
{"LNAs", 0x13, 8, 0b11, 1}, {"LNAs", BK4819_REG_13, 8, 0b11, 1},
{"LNA", 0x13, 5, 0b111, 1}, {"LNA", BK4819_REG_13, 5, 0b111, 1},
{"PGA", 0x13, 0, 0b111, 1}, {"PGA", BK4819_REG_13, 0, 0b111, 1},
{"IF", 0x3D, 0, 0xFFFF, 0x2aaa}, {"IF", BK4819_REG_3D, 0, 0xFFFF, 0x2aaa},
// {"MIX", 0x13, 3, 0b11, 1}, // TODO: hidden // {"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) { static uint16_t GetRegMenuValue(uint8_t st) {
RegisterSpec s = registerSpecs[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) { static void SetRegMenuValue(uint8_t st, bool add) {
@@ -120,14 +111,14 @@ static void SetRegMenuValue(uint8_t st, bool add) {
RegisterSpec s = registerSpecs[st]; RegisterSpec s = registerSpecs[st];
uint16_t reg = BK4819_ReadRegister(s.num); uint16_t reg = BK4819_ReadRegister(s.num);
if (add && v <= s.maxValue - s.inc) { if (add && v <= s.mask - s.inc) {
v += s.inc; v += s.inc;
} else if (!add && v >= 0 + s.inc) { } else if (!add && v >= 0 + s.inc) {
v -= s.inc; v -= s.inc;
} }
// TODO: use max value for bits count in max value, or reset by additional // TODO: use max value for bits count in max value, or reset by additional
// mask in spec // mask in spec
reg &= ~(s.maxValue << s.offset); reg &= ~(s.mask << s.offset);
BK4819_WriteRegister(s.num, reg | (v << s.offset)); BK4819_WriteRegister(s.num, reg | (v << s.offset));
redrawScreen = true; redrawScreen = true;
} }
@@ -135,21 +126,13 @@ static void SetRegMenuValue(uint8_t st, bool add) {
// GUI functions // GUI functions
static void PutPixel(uint8_t x, uint8_t y, bool fill) { static void PutPixel(uint8_t x, uint8_t y, bool fill) {
if (fill) { UI_DrawPixelBuffer(gFrameBuffer, x, y, fill);
gFrameBuffer[y >> 3][x] |= 1 << (y & 7);
} else {
gFrameBuffer[y >> 3][x] &= ~(1 << (y & 7));
}
} }
static void PutPixelStatus(uint8_t x, uint8_t y, bool fill) { static void PutPixelStatus(uint8_t x, uint8_t y, bool fill) {
if (fill) { UI_DrawPixelBuffer(&gStatusLine, x, y, fill);
gStatusLine[x] |= 1 << y;
} else {
gStatusLine[x] &= ~(1 << y);
}
} }
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++) { for (int i = sy; i <= ey; i++) {
if (i < 56 && nx < 128) { if (i < 56 && nx < 128) {
PutPixel(nx, i, fill); PutPixel(nx, i, fill);
@@ -215,35 +198,23 @@ static void ToggleAFBit(bool on) {
} }
static void BackupRegisters() { static void BackupRegisters() {
R30 = BK4819_ReadRegister(0x30); R30 = BK4819_ReadRegister(BK4819_REG_30);
R37 = BK4819_ReadRegister(0x37); R37 = BK4819_ReadRegister(BK4819_REG_37);
R3D = BK4819_ReadRegister(0x3D); R3D = BK4819_ReadRegister(BK4819_REG_3D);
R43 = BK4819_ReadRegister(0x43); R43 = BK4819_ReadRegister(BK4819_REG_43);
R47 = BK4819_ReadRegister(0x47); R47 = BK4819_ReadRegister(BK4819_REG_47);
R48 = BK4819_ReadRegister(0x48); R48 = BK4819_ReadRegister(BK4819_REG_48);
R7E = BK4819_ReadRegister(0x7E); R7E = BK4819_ReadRegister(BK4819_REG_7E);
} }
static void RestoreRegisters() { static void RestoreRegisters() {
BK4819_WriteRegister(0x30, R30); BK4819_WriteRegister(BK4819_REG_30, R30);
BK4819_WriteRegister(0x37, R37); BK4819_WriteRegister(BK4819_REG_37, R37);
BK4819_WriteRegister(0x3D, R3D); BK4819_WriteRegister(BK4819_REG_3D, R3D);
BK4819_WriteRegister(0x43, R43); BK4819_WriteRegister(BK4819_REG_43, R43);
BK4819_WriteRegister(0x47, R47); BK4819_WriteRegister(BK4819_REG_47, R47);
BK4819_WriteRegister(0x48, R48); BK4819_WriteRegister(BK4819_REG_48, R48);
BK4819_WriteRegister(0x7E, R7E); BK4819_WriteRegister(BK4819_REG_7E, 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);
}
} }
static void ToggleAFDAC(bool on) { static void ToggleAFDAC(bool on) {
@@ -314,16 +285,16 @@ static void ToggleAudio(bool on) {
} }
audioState = on; audioState = on;
if (on) { if (on) {
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOn();
} else { } else {
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOff();
} }
} }
static void ToggleRX(bool on) { static void ToggleRX(bool on) {
isListening = on; isListening = on;
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, on); BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, on);
ToggleAudio(on); ToggleAudio(on);
ToggleAFDAC(on); ToggleAFDAC(on);
@@ -410,11 +381,24 @@ static void Measure() { rssiHistory[scanInfo.i] = scanInfo.rssi = GetRssi(); }
// Update things by keypress // 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) { static void UpdateRssiTriggerLevel(bool inc) {
if (inc) if (inc)
settings.rssiTriggerLevel += 2; settings.rssiTriggerLevel += 2;
else else
settings.rssiTriggerLevel -= 2; settings.rssiTriggerLevel -= 2;
ClampRssiTriggerLevel();
redrawScreen = true; redrawScreen = true;
redrawStatus = true; redrawStatus = true;
} }
@@ -427,6 +411,8 @@ static void UpdateDBMax(bool inc) {
} else { } else {
return; return;
} }
ClampRssiTriggerLevel();
redrawStatus = true; redrawStatus = true;
redrawScreen = true; redrawScreen = true;
SYSTEM_DelayMs(20); SYSTEM_DelayMs(20);
@@ -483,12 +469,12 @@ static void UpdateFreqChangeStep(bool inc) {
} }
static void ToggleModulation() { static void ToggleModulation() {
if (settings.modulationType < MOD_USB) { if (settings.modulationType < MODULATION_UKNOWN - 1) {
settings.modulationType++; settings.modulationType++;
} else { } else {
settings.modulationType = MOD_FM; settings.modulationType = MODULATION_FM;
} }
SetModulation(settings.modulationType); RADIO_SetModulation(settings.modulationType);
redrawScreen = true; redrawScreen = true;
} }
@@ -504,9 +490,9 @@ static void ToggleListeningBW() {
static void ToggleBacklight() { static void ToggleBacklight() {
settings.backlightState = !settings.backlightState; settings.backlightState = !settings.backlightState;
if (settings.backlightState) { if (settings.backlightState) {
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); BACKLIGHT_TurnOn();
} else { } else {
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); BACKLIGHT_TurnOff();
} }
} }
@@ -613,7 +599,7 @@ static void DrawSpectrum() {
for (uint8_t x = 0; x < 128; ++x) { for (uint8_t x = 0; x < 128; ++x) {
uint16_t rssi = rssiHistory[x >> settings.stepsCount]; uint16_t rssi = rssiHistory[x >> settings.stepsCount];
if (rssi != RSSI_MAX_VALUE) { if (rssi != RSSI_MAX_VALUE) {
DrawHLine(Rssi2Y(rssi), DrawingEndY, x, true); DrawVLine(Rssi2Y(rssi), DrawingEndY, x, true);
} }
} }
} }
@@ -627,50 +613,35 @@ static void DrawStatus() {
#endif #endif
GUI_DisplaySmallest(String, 0, 1, true, true); GUI_DisplaySmallest(String, 0, 1, true, true);
for (int i = 0; i < 4; i++) { BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryCheckCounter++ % 4], &gBatteryCurrent);
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[i], &gBatteryCurrent);
}
uint16_t Voltage; uint16_t voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] +
uint8_t v = 0;
Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] +
gBatteryVoltages[3]) / gBatteryVoltages[3]) /
4; 4 * 760 / gBatteryCalibration[3];
if (gBatteryCalibration[5] < Voltage) { unsigned perc = BATTERY_VoltsToPercent(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;
}
gStatusLine[127] = 0b01111110; // sprintf(String, "%d %d", voltage, perc);
for (int i = 126; i >= 116; i--) { // GUI_DisplaySmallest(String, 48, 1, true, true);
gStatusLine[i] = 0b01000010;
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--) { for (unsigned i = 127; i >= 118; i--) {
if (126 - i <= v) { if (127 - i <= (perc+5)*9/100) {
gStatusLine[i + 2] = 0b01111110; gStatusLine[i] = 0b00111110;
} }
} }
gStatusLine[117] = 0b01111110;
gStatusLine[116] = 0b00011000;
} }
static void DrawF(uint32_t f) { static void DrawF(uint32_t f) {
sprintf(String, "%u.%05u", f / 100000, f % 100000); sprintf(String, "%u.%05u", f / 100000, f % 100000);
UI_PrintStringSmall(String, 8, 127, 0); UI_PrintStringSmall(String, 8, 127, 0);
sprintf(String, "%s", modulationTypeOptions[settings.modulationType]); sprintf(String, "%3s", gModulationStr[settings.modulationType]);
GUI_DisplaySmallest(String, 116, 1, false, true); GUI_DisplaySmallest(String, 116, 1, false, true);
sprintf(String, "%s", bwOptions[settings.listenBw]); sprintf(String, "%s", bwOptions[settings.listenBw]);
GUI_DisplaySmallest(String, 108, 7, false, true); GUI_DisplaySmallest(String, 108, 7, false, true);
@@ -686,7 +657,7 @@ static void DrawNums() {
} }
if (IsCenterMode()) { 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, currentFreq % 100000, settings.frequencyChangeStep / 100,
settings.frequencyChangeStep % 100); settings.frequencyChangeStep % 100);
GUI_DisplaySmallest(String, 36, 49, false, true); GUI_DisplaySmallest(String, 36, 49, false, true);
@@ -694,7 +665,7 @@ static void DrawNums() {
sprintf(String, "%u.%05u", GetFStart() / 100000, GetFStart() % 100000); sprintf(String, "%u.%05u", GetFStart() / 100000, GetFStart() % 100000);
GUI_DisplaySmallest(String, 0, 49, false, true); 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); settings.frequencyChangeStep % 100);
GUI_DisplaySmallest(String, 48, 49, false, true); GUI_DisplaySmallest(String, 48, 49, false, true);
@@ -726,19 +697,13 @@ static void DrawTicks() {
// center // center
if (IsCenterMode()) { if (IsCenterMode()) {
gFrameBuffer[5][62] = 0x80; memset(gFrameBuffer[5] + 62, 0x80, 5);
gFrameBuffer[5][63] = 0x80;
gFrameBuffer[5][64] = 0xff; gFrameBuffer[5][64] = 0xff;
gFrameBuffer[5][65] = 0x80;
gFrameBuffer[5][66] = 0x80;
} else { } else {
memset(gFrameBuffer[5] + 1, 0x80, 3);
memset(gFrameBuffer[5] + 124, 0x80, 3);
gFrameBuffer[5][0] = 0xff; 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; gFrameBuffer[5][127] = 0xff;
} }
} }
@@ -905,8 +870,8 @@ void OnKeyDownStill(KEY_Code_t key) {
break; break;
case KEY_PTT: case KEY_PTT:
// TODO: start transmit // TODO: start transmit
/* BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, false); /* BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, true); */ BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); */
break; break;
case KEY_MENU: case KEY_MENU:
if (menuState == ARRAY_SIZE(registerSpecs) - 1) { if (menuState == ARRAY_SIZE(registerSpecs) - 1) {
@@ -1176,7 +1141,7 @@ void APP_RunSpectrum() {
newScanStart = true; newScanStart = true;
ToggleRX(true), ToggleRX(false); // hack to prevent noise when squelch off ToggleRX(true), ToggleRX(false); // hack to prevent noise when squelch off
SetModulation(settings.modulationType = MOD_FM); RADIO_SetModulation(settings.modulationType = MODULATION_FM);
BK4819_SetFilterBandwidth(settings.listenBw = BK4819_FILTER_BW_WIDE, false); BK4819_SetFilterBandwidth(settings.listenBw = BK4819_FILTER_BW_WIDE, false);
RelaunchScan(); RelaunchScan();

View File

@@ -99,12 +99,6 @@ typedef enum StepsCount {
STEPS_16, STEPS_16,
} StepsCount; } StepsCount;
typedef enum ModulationType {
MOD_FM,
MOD_AM,
MOD_USB,
} ModulationType;
typedef enum ScanStep { typedef enum ScanStep {
S_STEP_0_01kHz, S_STEP_0_01kHz,
S_STEP_0_1kHz, S_STEP_0_1kHz,
@@ -131,7 +125,7 @@ typedef struct SpectrumSettings {
BK4819_FilterBandwidth_t listenBw; BK4819_FilterBandwidth_t listenBw;
int dbMin; int dbMin;
int dbMax; int dbMax;
ModulationType modulationType; ModulationMode_t modulationType;
bool backlightState; bool backlightState;
} SpectrumSettings; } SpectrumSettings;
@@ -149,14 +143,6 @@ typedef struct ScanInfo {
uint8_t measurementsCount; uint8_t measurementsCount;
} ScanInfo; } ScanInfo;
typedef struct RegisterSpec {
char *name;
uint8_t num;
uint8_t offset;
uint16_t maxValue;
uint16_t inc;
} RegisterSpec;
typedef struct PeakInfo { typedef struct PeakInfo {
uint16_t t; uint16_t t;
uint16_t rssi; uint16_t rssi;

View File

@@ -27,6 +27,7 @@
#include "bsp/dp32g030/dma.h" #include "bsp/dp32g030/dma.h"
#include "bsp/dp32g030/gpio.h" #include "bsp/dp32g030/gpio.h"
#include "driver/aes.h" #include "driver/aes.h"
#include "driver/backlight.h"
#include "driver/bk4819.h" #include "driver/bk4819.h"
#include "driver/crc.h" #include "driver/crc.h"
#include "driver/eeprom.h" #include "driver/eeprom.h"
@@ -238,7 +239,7 @@ static void CMD_0514(const uint8_t *pBuffer)
gSerialConfigCountDown_500ms = 12; // 6 sec gSerialConfigCountDown_500ms = 12; // 6 sec
// turn the LCD backlight off // turn the LCD backlight off
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); BACKLIGHT_TurnOff();
SendVersion(); SendVersion();
} }
@@ -413,7 +414,7 @@ static void CMD_052F(const uint8_t *pBuffer)
Timestamp = pCmd->Timestamp; Timestamp = pCmd->Timestamp;
// turn the LCD backlight off // turn the LCD backlight off
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); BACKLIGHT_TurnOff();
SendVersion(); SendVersion();
} }

19
audio.c
View File

@@ -97,7 +97,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
ToneConfig = BK4819_ReadRegister(BK4819_REG_71); ToneConfig = BK4819_ReadRegister(BK4819_REG_71);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOff();
if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode) if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode)
BK4819_RX_TurnOn(); BK4819_RX_TurnOn();
@@ -138,7 +138,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
SYSTEM_DelayMs(2); SYSTEM_DelayMs(2);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOn();
SYSTEM_DelayMs(60); SYSTEM_DelayMs(60);
@@ -185,7 +185,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
BK4819_EnterTxMute(); BK4819_EnterTxMute();
SYSTEM_DelayMs(20); SYSTEM_DelayMs(20);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOff();
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
gVoxResumeCountdown = 80; gVoxResumeCountdown = 80;
@@ -197,7 +197,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
BK4819_WriteRegister(BK4819_REG_71, ToneConfig); BK4819_WriteRegister(BK4819_REG_71, ToneConfig);
if (gEnableSpeaker) if (gEnableSpeaker)
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOn();
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (gFmRadioMode) if (gFmRadioMode)
@@ -270,7 +270,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
BK1080_Mute(true); BK1080_Mute(true);
#endif #endif
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOn();
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
gVoxResumeCountdown = 2000; gVoxResumeCountdown = 2000;
@@ -289,7 +289,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
if (gCurrentFunction == FUNCTION_RECEIVE || if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR || gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING) // 1of11 gCurrentFunction == FUNCTION_INCOMING) // 1of11
BK4819_SetAF(gRxVfo->AM_mode ? BK4819_AF_AM : BK4819_AF_FM); RADIO_SetModulation(gRxVfo->Modulation);
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (gFmRadioMode) if (gFmRadioMode)
@@ -297,7 +297,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
#endif #endif
if (!gEnableSpeaker) if (!gEnableSpeaker)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOff();
gVoiceWriteIndex = 0; gVoiceWriteIndex = 0;
gVoiceReadIndex = 0; gVoiceReadIndex = 0;
@@ -430,7 +430,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
if (gCurrentFunction == FUNCTION_RECEIVE || if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR || gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING) // 1of11 gCurrentFunction == FUNCTION_INCOMING) // 1of11
BK4819_SetAF(gRxVfo->AM_mode ? BK4819_AF_AM : BK4819_AF_FM); RADIO_SetModulation(gRxVfo->Modulation);
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (gFmRadioMode) if (gFmRadioMode)
@@ -438,7 +438,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
#endif #endif
if (!gEnableSpeaker) if (!gEnableSpeaker)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOff();
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
gVoxResumeCountdown = 80; gVoxResumeCountdown = 80;
@@ -449,3 +449,4 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
} }
#endif #endif

11
audio.h
View File

@@ -20,6 +20,9 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "bsp/dp32g030/gpio.h"
#include "driver/gpio.h"
enum BEEP_Type_t enum BEEP_Type_t
{ {
BEEP_NONE = 0, BEEP_NONE = 0,
@@ -130,6 +133,14 @@ enum VOICE_ID_t
typedef enum VOICE_ID_t 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 #ifdef ENABLE_VOICE
extern VOICE_ID_t gVoiceID[8]; extern VOICE_ID_t gVoiceID[8];
extern uint8_t gVoiceReadIndex; extern uint8_t gVoiceReadIndex;

View File

@@ -270,48 +270,6 @@ const uint8_t BITMAP_Antenna[5] =
0b00000011 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_MARKER[8] = const uint8_t BITMAP_MARKER[8] =
{ {
0b11111111, 0b11111111,

View File

@@ -10,10 +10,6 @@ extern const uint8_t BITMAP_RX[8];
extern const uint8_t BITMAP_BatteryLevel[2]; extern const uint8_t BITMAP_BatteryLevel[2];
extern const uint8_t BITMAP_BatteryLevel1[17]; 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]; extern const uint8_t BITMAP_USB_C[9];
@@ -39,12 +35,6 @@ extern const uint8_t BITMAP_TDR2[9];
#endif #endif
extern const uint8_t BITMAP_Antenna[5]; 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_MARKER[8]; extern const uint8_t BITMAP_MARKER[8];

41
board.c
View File

@@ -26,7 +26,7 @@
#include "bsp/dp32g030/saradc.h" #include "bsp/dp32g030/saradc.h"
#include "bsp/dp32g030/syscon.h" #include "bsp/dp32g030/syscon.h"
#include "driver/adc.h" #include "driver/adc.h"
//#include "driver/backlight.h" #include "driver/backlight.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "driver/bk1080.h" #include "driver/bk1080.h"
#endif #endif
@@ -94,8 +94,6 @@ void BOARD_GPIO_Init(void)
| GPIO_DIR_6_MASK // INPUT | GPIO_DIR_6_MASK // INPUT
); );
GPIOB->DIR |= 0 GPIOB->DIR |= 0
// Back light
| GPIO_DIR_6_BITS_OUTPUT
// ST7565 // ST7565
| GPIO_DIR_9_BITS_OUTPUT | GPIO_DIR_9_BITS_OUTPUT
// ST7565 + SWD IO // ST7565 + SWD IO
@@ -183,14 +181,10 @@ void BOARD_PORTCON_Init(void)
// PORT B pin selection // PORT B pin selection
PORTCON_PORTB_SEL0 &= ~(0 PORTCON_PORTB_SEL0 &= ~(0
// Back light
| PORTCON_PORTB_SEL0_B6_MASK
// SPI0 SSN // SPI0 SSN
| PORTCON_PORTB_SEL0_B7_MASK | PORTCON_PORTB_SEL0_B7_MASK
); );
PORTCON_PORTB_SEL0 |= 0 PORTCON_PORTB_SEL0 |= 0
// Back light
| PORTCON_PORTB_SEL0_B6_BITS_GPIOB6
// SPI0 SSN // SPI0 SSN
| PORTCON_PORTB_SEL0_B7_BITS_SPI0_SSN | PORTCON_PORTB_SEL0_B7_BITS_SPI0_SSN
; ;
@@ -508,6 +502,7 @@ void BOARD_Init(void)
{ {
BOARD_PORTCON_Init(); BOARD_PORTCON_Init();
BOARD_GPIO_Init(); BOARD_GPIO_Init();
BACKLIGHT_InitHardware();
BOARD_ADC_Init(); BOARD_ADC_Init();
ST7565_Init(true); ST7565_Init(true);
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
@@ -540,12 +535,17 @@ void BOARD_EEPROM_Init(void)
// 0E78..0E7F // 0E78..0E7F
EEPROM_ReadBuffer(0x0E78, Data, 8); 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.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.CROSS_BAND_RX_TX = (Data[2] < 3) ? Data[2] : CROSS_BAND_OFF;
gEeprom.BATTERY_SAVE = (Data[3] < 5) ? Data[3] : 4; gEeprom.BATTERY_SAVE = (Data[3] < 5) ? Data[3] : 4;
gEeprom.DUAL_WATCH = (Data[4] < 3) ? Data[4] : DUAL_WATCH_CHAN_A; gEeprom.DUAL_WATCH = (Data[4] < 3) ? Data[4] : DUAL_WATCH_CHAN_A;
gEeprom.BACKLIGHT = (Data[5] < ARRAY_SIZE(gSubMenu_BACKLIGHT)) ? Data[5] : 3; gEeprom.BACKLIGHT_TIME = (Data[5] < ARRAY_SIZE(gSubMenu_BACKLIGHT)) ? Data[5] : 3;
gEeprom.TAIL_NOTE_ELIMINATION = (Data[6] < 2) ? Data[6] : false; gEeprom.TAIL_TONE_ELIMINATION = (Data[6] < 2) ? Data[6] : false;
gEeprom.VFO_OPEN = (Data[7] < 2) ? Data[7] : true; gEeprom.VFO_OPEN = (Data[7] < 2) ? Data[7] : true;
// 0E80..0E87 // 0E80..0E87
@@ -590,7 +590,8 @@ void BOARD_EEPROM_Init(void)
// 0E90..0E97 // 0E90..0E97
EEPROM_ReadBuffer(0x0E90, Data, 8); 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_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_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; gEeprom.KEY_2_SHORT_PRESS_ACTION = (Data[3] < ACTION_OPT_LEN) ? Data[3] : ACTION_OPT_SCAN;
@@ -616,7 +617,8 @@ void BOARD_EEPROM_Init(void)
#endif #endif
gEeprom.ROGER = (Data[1] < 3) ? Data[1] : ROGER_MODE_OFF; gEeprom.ROGER = (Data[1] < 3) ? Data[1] : ROGER_MODE_OFF;
gEeprom.REPEATER_TAIL_TONE_ELIMINATION = (Data[2] < 11) ? Data[2] : 0; gEeprom.REPEATER_TAIL_TONE_ELIMINATION = (Data[2] < 11) ? Data[2] : 0;
gEeprom.TX_VFO = (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 // 0ED0..0ED7
EEPROM_ReadBuffer(0x0ED0, Data, 8); EEPROM_ReadBuffer(0x0ED0, Data, 8);
@@ -699,14 +701,14 @@ void BOARD_EEPROM_Init(void)
// 0F40..0F47 // 0F40..0F47
EEPROM_ReadBuffer(0x0F40, Data, 8); 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 gSetting_350TX = (Data[1] < 2) ? Data[1] : false; // was true
gSetting_KILLED = (Data[2] < 2) ? Data[2] : false; gSetting_KILLED = (Data[2] < 2) ? Data[2] : false;
gSetting_200TX = (Data[3] < 2) ? Data[3] : false; gSetting_200TX = (Data[3] < 2) ? Data[3] : false;
gSetting_500TX = (Data[4] < 2) ? Data[4] : false; gSetting_500TX = (Data[4] < 2) ? Data[4] : false;
gSetting_350EN = (Data[5] < 2) ? Data[5] : true; gSetting_350EN = (Data[5] < 2) ? Data[5] : true;
gSetting_ScrambleEnable = (Data[6] < 2) ? Data[6] : 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_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 #ifdef ENABLE_AUDIO_BAR
@@ -725,6 +727,13 @@ void BOARD_EEPROM_Init(void)
// 0D60..0E27 // 0D60..0E27
EEPROM_ReadBuffer(0x0D60, gMR_ChannelAttributes, sizeof(gMR_ChannelAttributes)); 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 // 0F30..0F3F
EEPROM_ReadBuffer(0x0F30, gCustomAesKey, sizeof(gCustomAesKey)); EEPROM_ReadBuffer(0x0F30, gCustomAesKey, sizeof(gCustomAesKey));
@@ -748,9 +757,9 @@ void BOARD_EEPROM_LoadCalibration(void)
memcpy(gEEPROM_RSSI_CALIB[5], 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); memcpy(gEEPROM_RSSI_CALIB[6], gEEPROM_RSSI_CALIB[3], 8);
// 8 * 16-bit values EEPROM_ReadBuffer(0x1EC8, gEEPROM_RSSI_CALIB[0], 8);
EEPROM_ReadBuffer(0x1EC0, gEEPROM_RSSI_CALIB[0], 8); memcpy(gEEPROM_RSSI_CALIB[1], gEEPROM_RSSI_CALIB[0], 8);
EEPROM_ReadBuffer(0x1EC8, gEEPROM_RSSI_CALIB[1], 8); memcpy(gEEPROM_RSSI_CALIB[2], gEEPROM_RSSI_CALIB[0], 8);
EEPROM_ReadBuffer(0x1F40, gBatteryCalibration, 12); EEPROM_ReadBuffer(0x1F40, gBatteryCalibration, 12);
if (gBatteryCalibration[0] >= 5000) if (gBatteryCalibration[0] >= 5000)

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

View File

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

View File

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

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

@@ -16,21 +16,54 @@
#include "backlight.h" #include "backlight.h"
#include "bsp/dp32g030/gpio.h" #include "bsp/dp32g030/gpio.h"
#include "bsp/dp32g030/pwmplus.h"
#include "bsp/dp32g030/portcon.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "settings.h" #include "settings.h"
// this is decremented once every 500ms // this is decremented once every 500ms
uint16_t gBacklightCountdown = 0; 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) void BACKLIGHT_TurnOn(void)
{ {
if (gEeprom.BACKLIGHT == 0) if (gEeprom.BACKLIGHT_TIME != 0) {
backlightOn = true;
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX);
}
else {
BACKLIGHT_TurnOff();
return; return;
}
// turn the backlight ON
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
switch (gEeprom.BACKLIGHT) switch (gEeprom.BACKLIGHT_TIME)
{ {
default: default:
case 1: // 5 sec case 1: // 5 sec
@@ -58,3 +91,32 @@ void BACKLIGHT_TurnOn(void)
gBacklightCountdown *= 2; 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 #define DRIVER_BACKLIGHT_H
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
extern uint16_t gBacklightCountdown; 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 #endif

View File

@@ -17,6 +17,19 @@
#ifndef BK4819_REGS_H #ifndef BK4819_REGS_H
#define 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 { enum BK4819_REGISTER_t {
BK4819_REG_00 = 0x00U, BK4819_REG_00 = 0x00U,
BK4819_REG_02 = 0x02U, BK4819_REG_02 = 0x02U,
@@ -52,6 +65,7 @@ enum BK4819_REGISTER_t {
BK4819_REG_3A = 0x3AU, BK4819_REG_3A = 0x3AU,
BK4819_REG_3B = 0x3BU, BK4819_REG_3B = 0x3BU,
BK4819_REG_3C = 0x3CU, BK4819_REG_3C = 0x3CU,
BK4819_REG_3D = 0x3DU,
BK4819_REG_3E = 0x3EU, BK4819_REG_3E = 0x3EU,
BK4819_REG_3F = 0x3FU, BK4819_REG_3F = 0x3FU,
BK4819_REG_43 = 0x43U, BK4819_REG_43 = 0x43U,
@@ -95,13 +109,12 @@ enum BK4819_REGISTER_t {
typedef enum BK4819_REGISTER_t BK4819_REGISTER_t; typedef enum BK4819_REGISTER_t BK4819_REGISTER_t;
enum BK4819_GPIO_PIN_t { enum BK4819_GPIO_PIN_t {
BK4819_GPIO6_PIN2 = 0, BK4819_GPIO0_PIN28_RX_ENABLE = 0,
BK4819_GPIO5_PIN1 = 1, BK4819_GPIO1_PIN29_PA_ENABLE = 1,
BK4819_GPIO4_PIN32 = 2, BK4819_GPIO3_PIN31_UHF_LNA = 3,
BK4819_GPIO3_PIN31 = 3, BK4819_GPIO4_PIN32_VHF_LNA = 4,
BK4819_GPIO2_PIN30 = 4, BK4819_GPIO5_PIN1_RED = 5,
BK4819_GPIO1_PIN29_RED = 5, BK4819_GPIO6_PIN2_GREEN = 6,
BK4819_GPIO0_PIN28_GREEN = 6,
}; };
typedef enum BK4819_GPIO_PIN_t BK4819_GPIO_PIN_t; typedef enum BK4819_GPIO_PIN_t BK4819_GPIO_PIN_t;

View File

@@ -16,6 +16,7 @@
#include <stdio.h> // NULL #include <stdio.h> // NULL
#include "audio.h"
#include "bk4819.h" #include "bk4819.h"
#include "bsp/dp32g030/gpio.h" #include "bsp/dp32g030/gpio.h"
#include "bsp/dp32g030/portcon.h" #include "bsp/dp32g030/portcon.h"
@@ -29,6 +30,9 @@
static const uint16_t FSK_RogerTable[7] = {0xF1A2, 0x7446, 0x61A4, 0x6544, 0x4E8A, 0xE044, 0xEA84}; static const uint16_t FSK_RogerTable[7] = {0xF1A2, 0x7446, 0x61A4, 0x6544, 0x4E8A, 0xE044, 0xEA84};
static const uint8_t DTMF_TONE1_GAIN = 65;
static const uint8_t DTMF_TONE2_GAIN = 93;
static uint16_t gBK4819_GpioOutState; static uint16_t gBK4819_GpioOutState;
bool gRxIdleMode; bool gRxIdleMode;
@@ -51,8 +55,8 @@ void BK4819_Init(void)
BK4819_WriteRegister(BK4819_REG_37, 0x1D0F); BK4819_WriteRegister(BK4819_REG_37, 0x1D0F);
BK4819_WriteRegister(BK4819_REG_36, 0x0022); BK4819_WriteRegister(BK4819_REG_36, 0x0022);
BK4819_SetAGC(0); BK4819_DisableAGC();
// BK4819_SetAGC(1); // BK4819_EnableAGC();
BK4819_WriteRegister(BK4819_REG_19, 0b0001000001000001); // <15> MIC AGC 1 = disable 0 = enable BK4819_WriteRegister(BK4819_REG_19, 0b0001000001000001); // <15> MIC AGC 1 = disable 0 = enable
@@ -232,118 +236,113 @@ void BK4819_WriteU16(uint16_t Data)
} }
} }
void BK4819_SetAGC(uint8_t Value) void BK4819_DisableAGC()
{ {
if (Value == 0) // REG_10
{ //
// REG_10 // 0x0038 Rx AGC Gain Table[0]. (Index Max->Min is 3,2,1,0,-1)
// //
// 0x0038 Rx AGC Gain Table[0]. (Index Max->Min is 3,2,1,0,-1) // <15:10> ???
// //
// <15:10> ??? // <9:8> LNA Gain Short
// // 3 = 0dB <<<
// <9:8> LNA Gain Short // 2 = -24dB // was -11
// 3 = 0dB <<< // 1 = -30dB // was -16
// 2 = -24dB // was -11 // 0 = -33dB // was -19
// 1 = -30dB // was -16 //
// 0 = -33dB // was -19 // <7:5> LNA Gain
// // 7 = 0dB
// <7:5> LNA Gain // 6 = -2dB
// 7 = 0dB // 5 = -4dB
// 6 = -2dB // 4 = -6dB
// 5 = -4dB // 3 = -9dB
// 4 = -6dB // 2 = -14dB <<<
// 3 = -9dB // 1 = -19dB
// 2 = -14dB <<< // 0 = -24dB
// 1 = -19dB //
// 0 = -24dB // <4:3> MIXER Gain
// // 3 = 0dB <<<
// <4:3> MIXER Gain // 2 = -3dB
// 3 = 0dB <<< // 1 = -6dB
// 2 = -3dB // 0 = -8dB
// 1 = -6dB //
// 0 = -8dB // <2:0> PGA Gain
// // 7 = 0dB
// <2:0> PGA Gain // 6 = -3dB <<<
// 7 = 0dB // 5 = -6dB
// 6 = -3dB <<< // 4 = -9dB
// 5 = -6dB // 3 = -15dB
// 4 = -9dB // 2 = -21dB
// 3 = -15dB // 1 = -27dB
// 2 = -21dB // 0 = -33dB
// 1 = -27dB //
// 0 = -33dB BK4819_WriteRegister(BK4819_REG_13, (3u << 8) | (5u << 5) | (3u << 3) | (6u << 0)); // 000000 11 101 11 110
//
BK4819_WriteRegister(BK4819_REG_13, (3u << 8) | (2u << 5) | (3u << 3) | (6u << 0)); // 000000 11 101 11 110
BK4819_WriteRegister(BK4819_REG_12, 0x037B); // 000000 11 011 11 011 BK4819_WriteRegister(BK4819_REG_12, 0x037B); // 000000 11 011 11 011
BK4819_WriteRegister(BK4819_REG_11, 0x027B); // 000000 10 011 11 011 BK4819_WriteRegister(BK4819_REG_11, 0x027B); // 000000 10 011 11 011
BK4819_WriteRegister(BK4819_REG_10, 0x007A); // 000000 00 011 11 010 BK4819_WriteRegister(BK4819_REG_10, 0x007A); // 000000 00 011 11 010
BK4819_WriteRegister(BK4819_REG_14, 0x0019); // 000000 00 000 11 001 BK4819_WriteRegister(BK4819_REG_14, 0x0019); // 000000 00 000 11 001
BK4819_WriteRegister(BK4819_REG_49, 0x2A38); BK4819_WriteRegister(BK4819_REG_49, 0x2A38);
BK4819_WriteRegister(BK4819_REG_7B, 0x8420); BK4819_WriteRegister(BK4819_REG_7B, 0x8420);
} }
else
if (Value == 1)
{ // what does this do ???
unsigned int i; void BK4819_EnableAGC()
{
// REG_10
//
// 0x0038 Rx AGC Gain Table[0]. (Index Max->Min is 3,2,1,0,-1)
//
// (15:10> ???
//
// <9:8> LNA Gain Short
// 3 = 0dB << original
// 2 = -24dB // was -11
// 1 = -30dB // was -16
// 0 = -33dB // was -19
//
// <7:5> LNA Gain
// 7 = 0dB
// 6 = -2dB
// 5 = -4dB
// 4 = -6dB
// 3 = -9dB
// 2 = -14dB << original
// 1 = -19dB
// 0 = -24dB
//
// <4:3> MIXER Gain
// 3 = 0dB << original
// 2 = -3dB
// 1 = -6dB
// 0 = -8dB
//
// <2:0> PGA Gain
// 7 = 0dB
// 6 = -3dB << original
// 5 = -6dB
// 4 = -9dB
// 3 = -15dB
// 2 = -21dB
// 1 = -27dB
// 0 = -33dB
//
BK4819_WriteRegister(BK4819_REG_13, (3u << 8) | (5u << 5) | (3u << 3) | (6u << 0));
// REG_10 BK4819_WriteRegister(BK4819_REG_12, 0x037C); // 000000 11 011 11 100
// BK4819_WriteRegister(BK4819_REG_11, 0x027B); // 000000 10 011 11 011
// 0x0038 Rx AGC Gain Table[0]. (Index Max->Min is 3,2,1,0,-1) BK4819_WriteRegister(BK4819_REG_10, 0x007A); // 000000 00 011 11 010
// BK4819_WriteRegister(BK4819_REG_14, 0x0018); // 000000 00 000 11 000
// (15:10> ???
//
// <9:8> LNA Gain Short
// 3 = 0dB << original
// 2 = -24dB // was -11
// 1 = -30dB // was -16
// 0 = -33dB // was -19
//
// <7:5> LNA Gain
// 7 = 0dB
// 6 = -2dB
// 5 = -4dB
// 4 = -6dB
// 3 = -9dB
// 2 = -14dB << original
// 1 = -19dB
// 0 = -24dB
//
// <4:3> MIXER Gain
// 3 = 0dB << original
// 2 = -3dB
// 1 = -6dB
// 0 = -8dB
//
// <2:0> PGA Gain
// 7 = 0dB
// 6 = -3dB << original
// 5 = -6dB
// 4 = -9dB
// 3 = -15dB
// 2 = -21dB
// 1 = -27dB
// 0 = -33dB
//
BK4819_WriteRegister(BK4819_REG_13, (3u << 8) | (2u << 5) | (3u << 3) | (6u << 0));
BK4819_WriteRegister(BK4819_REG_12, 0x037C); // 000000 11 011 11 100 BK4819_WriteRegister(BK4819_REG_49, 0x2A38);
BK4819_WriteRegister(BK4819_REG_11, 0x027B); // 000000 10 011 11 011 BK4819_WriteRegister(BK4819_REG_7B, 0x318C);
BK4819_WriteRegister(BK4819_REG_10, 0x007A); // 000000 00 011 11 010
BK4819_WriteRegister(BK4819_REG_14, 0x0018); // 000000 00 000 11 000
BK4819_WriteRegister(BK4819_REG_49, 0x2A38); BK4819_WriteRegister(BK4819_REG_7C, 0x595E);
BK4819_WriteRegister(BK4819_REG_7B, 0x318C); BK4819_WriteRegister(BK4819_REG_20, 0x8DEF);
BK4819_WriteRegister(BK4819_REG_7C, 0x595E); for (uint8_t i = 0; i < 8; i++) {
BK4819_WriteRegister(BK4819_REG_20, 0x8DEF); //BK4819_WriteRegister(BK4819_REG_06, ((i << 13) | 0x2500u) + 0x036u);
BK4819_WriteRegister(BK4819_REG_06, (i & 7) << 13 | 0x4A << 7 | 0x36);
for (i = 0; i < 8; i++)
// Bug? The bit 0x2000 below overwrites the (i << 13)
BK4819_WriteRegister(BK4819_REG_06, ((i << 13) | 0x2500u) + 0x036u);
} }
} }
@@ -760,19 +759,13 @@ void BK4819_SetupSquelch(
// 0 ~ 255 // 0 ~ 255
// //
BK4819_WriteRegister(BK4819_REG_4E, // 01 101 11 1 00000000 BK4819_WriteRegister(BK4819_REG_4E, // 01 101 11 1 00000000
#ifndef ENABLE_FASTER_CHANNEL_SCAN
// original (*) // original (*)
(1u << 14) | // 1 ??? (1u << 14) | // 1 ???
(3u << 11) | // *5 squelch = open delay .. 0 ~ 7 (5u << 11) | // *5 squelch = open delay .. 0 ~ 7
(2u << 9) | // *3 squelch = close delay .. 0 ~ 3 (6u << 9) | // *3 squelch = close delay .. 0 ~ 3
SquelchOpenGlitchThresh); // 0 ~ 255 SquelchOpenGlitchThresh); // 0 ~ 255
#else
// faster (but twitchier)
(1u << 14) | // 1 ???
(2u << 11) | // *5 squelch = open delay .. 0 ~ 7
(1u << 9) | // *3 squelch = close delay .. 0 ~ 3
SquelchOpenGlitchThresh); // 0 ~ 255
#endif
// REG_4F // REG_4F
// //
@@ -804,7 +797,14 @@ void BK4819_SetAF(BK4819_AF_Type_t AF)
// AF Output Inverse Mode = Inverse // AF Output Inverse Mode = Inverse
// Undocumented bits 0x2040 // Undocumented bits 0x2040
// //
BK4819_WriteRegister(BK4819_REG_47, 0x6040 | (AF << 8)); // BK4819_WriteRegister(BK4819_REG_47, 0x6040 | (AF << 8));
BK4819_WriteRegister(BK4819_REG_47, (6u << 12) | (AF << 8) | (1u << 6));
}
void BK4819_SetRegValue(RegisterSpec s, uint16_t v) {
uint16_t reg = BK4819_ReadRegister(s.num);
reg &= ~(s.mask << s.offset);
BK4819_WriteRegister(s.num, reg | (v << s.offset));
} }
void BK4819_RX_TurnOn(void) void BK4819_RX_TurnOn(void)
@@ -843,20 +843,20 @@ void BK4819_RX_TurnOn(void)
void BK4819_PickRXFilterPathBasedOnFrequency(uint32_t Frequency) void BK4819_PickRXFilterPathBasedOnFrequency(uint32_t Frequency)
{ {
if (Frequency < 28000000) if (Frequency < 28000000)
{ { // VHF
BK4819_ToggleGpioOut(BK4819_GPIO2_PIN30, true); BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, true);
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31, false); BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, false);
} }
else else
if (Frequency == 0xFFFFFFFF) if (Frequency == 0xFFFFFFFF)
{ { // OFF
BK4819_ToggleGpioOut(BK4819_GPIO2_PIN30, false); BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, false);
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31, false); BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, false);
} }
else else
{ { // UHF
BK4819_ToggleGpioOut(BK4819_GPIO2_PIN30, false); BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, false);
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31, true); BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, true);
} }
} }
@@ -975,27 +975,27 @@ void BK4819_EnableDTMF(void)
// <3:0> 14 Max symbol number for SelCall detection // <3:0> 14 Max symbol number for SelCall detection
// //
// const uint16_t threshold = 24; // default, but doesn't decode non-QS radios // const uint16_t threshold = 24; // default, but doesn't decode non-QS radios
const uint16_t threshold = 160; // but 128 ~ 247 does const uint16_t threshold = 130; // but 128 ~ 247 does
BK4819_WriteRegister(BK4819_REG_24, // 1 00011000 1 1 1 1110 BK4819_WriteRegister(BK4819_REG_24, // 1 00011000 1 1 1 1110
(1u << BK4819_REG_24_SHIFT_UNKNOWN_15) | (1u << BK4819_REG_24_SHIFT_UNKNOWN_15) |
(threshold << BK4819_REG_24_SHIFT_THRESHOLD) | // 0 ~ 255 (threshold << BK4819_REG_24_SHIFT_THRESHOLD) | // 0 ~ 255
(1u << BK4819_REG_24_SHIFT_UNKNOWN_6) | (1u << BK4819_REG_24_SHIFT_UNKNOWN_6) |
BK4819_REG_24_ENABLE | BK4819_REG_24_ENABLE |
BK4819_REG_24_SELECT_DTMF | BK4819_REG_24_SELECT_DTMF |
(14u << BK4819_REG_24_SHIFT_MAX_SYMBOLS)); // 0 ~ 15 (15u << BK4819_REG_24_SHIFT_MAX_SYMBOLS)); // 0 ~ 15
} }
void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch) void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch)
{ {
uint16_t ToneConfig; uint16_t ToneConfig = BK4819_REG_70_ENABLE_TONE1;
BK4819_EnterTxMute(); BK4819_EnterTxMute();
BK4819_SetAF(BK4819_AF_BEEP); BK4819_SetAF(BK4819_AF_BEEP);
if (bTuningGainSwitch == 0) if (bTuningGainSwitch == 0)
ToneConfig = BK4819_REG_70_ENABLE_TONE1 | (96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN); ToneConfig |= 96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN;
else else
ToneConfig = BK4819_REG_70_ENABLE_TONE1 | (28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN); ToneConfig |= 28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN;
BK4819_WriteRegister(BK4819_REG_70, ToneConfig); BK4819_WriteRegister(BK4819_REG_70, ToneConfig);
BK4819_WriteRegister(BK4819_REG_30, 0); BK4819_WriteRegister(BK4819_REG_30, 0);
@@ -1004,21 +1004,20 @@ void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch)
BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency)); BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency));
} }
// level 0 ~ 127
void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay, const unsigned int level, const bool play_speaker) void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay, const unsigned int level, const bool play_speaker)
{ {
BK4819_EnterTxMute(); BK4819_EnterTxMute();
if (play_speaker) if (play_speaker)
{ {
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOn();
BK4819_SetAF(BK4819_AF_BEEP); BK4819_SetAF(BK4819_AF_BEEP);
} }
else else
BK4819_SetAF(BK4819_AF_MUTE); BK4819_SetAF(BK4819_AF_MUTE);
// level 0 ~ 127
// BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
// BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | ((level & 0x7f) << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN)); BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | ((level & 0x7f) << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
BK4819_EnableTXLink(); BK4819_EnableTXLink();
@@ -1032,12 +1031,13 @@ void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay,
if (play_speaker) if (play_speaker)
{ {
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOff();
BK4819_SetAF(BK4819_AF_MUTE); BK4819_SetAF(BK4819_AF_MUTE);
} }
BK4819_WriteRegister(BK4819_REG_70, 0x0000); BK4819_WriteRegister(BK4819_REG_70, 0x0000);
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); BK4819_WriteRegister(BK4819_REG_30, 0xC1FE);
BK4819_ExitTxMute();
} }
void BK4819_EnterTxMute(void) void BK4819_EnterTxMute(void)
@@ -1198,7 +1198,7 @@ void BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable(void)
{ {
if (gRxIdleMode) if (gRxIdleMode)
{ {
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, true); BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, true);
BK4819_RX_TurnOn(); BK4819_RX_TurnOn();
} }
} }
@@ -1211,9 +1211,9 @@ void BK4819_EnterDTMF_TX(bool bLocalLoopback)
BK4819_WriteRegister(BK4819_REG_70, BK4819_WriteRegister(BK4819_REG_70,
BK4819_REG_70_MASK_ENABLE_TONE1 | BK4819_REG_70_MASK_ENABLE_TONE1 |
(83u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) | (DTMF_TONE1_GAIN << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) |
BK4819_REG_70_MASK_ENABLE_TONE2 | BK4819_REG_70_MASK_ENABLE_TONE2 |
(83u << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN)); (DTMF_TONE2_GAIN << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN));
BK4819_EnableTXLink(); BK4819_EnableTXLink();
} }
@@ -1249,30 +1249,30 @@ void BK4819_PlayDTMF(char Code)
uint16_t tone1 = 0; uint16_t tone1 = 0;
uint16_t tone2 = 0; uint16_t tone2 = 0;
switch (Code) // Hz Hz switch (Code)
{ // {
case '0': tone1 = 9715; tone2 = 13793; break; // 941 1336 case '0': tone1 = 941; tone2 = 1336; break;
case '1': tone1 = 7196; tone2 = 12482; break; // 679 1209 case '1': tone1 = 697; tone2 = 1209; break;
case '2': tone1 = 7196; tone2 = 13793; break; // 697 1336 case '2': tone1 = 697; tone2 = 1336; break;
case '3': tone1 = 7196; tone2 = 15249; break; // 679 1477 case '3': tone1 = 697; tone2 = 1477; break;
case '4': tone1 = 7950; tone2 = 12482; break; // 770 1209 case '4': tone1 = 770; tone2 = 1209; break;
case '5': tone1 = 7950; tone2 = 13793; break; // 770 1336 case '5': tone1 = 770; tone2 = 1336; break;
case '6': tone1 = 7950; tone2 = 15249; break; // 770 1477 case '6': tone1 = 770; tone2 = 1477; break;
case '7': tone1 = 8796; tone2 = 12482; break; // 852 1209 case '7': tone1 = 852; tone2 = 1209; break;
case '8': tone1 = 8796; tone2 = 13793; break; // 852 1336 case '8': tone1 = 852; tone2 = 1336; break;
case '9': tone1 = 8796; tone2 = 15249; break; // 852 1477 case '9': tone1 = 852; tone2 = 1477; break;
case 'A': tone1 = 7196; tone2 = 16860; break; // 679 1633 case 'A': tone1 = 697; tone2 = 1633; break;
case 'B': tone1 = 7950; tone2 = 16860; break; // 770 1633 case 'B': tone1 = 770; tone2 = 1633; break;
case 'C': tone1 = 8796; tone2 = 16860; break; // 852 1633 case 'C': tone1 = 852; tone2 = 1633; break;
case 'D': tone1 = 9715; tone2 = 16860; break; // 941 1633 case 'D': tone1 = 941; tone2 = 1633; break;
case '*': tone1 = 9715; tone2 = 12482; break; // 941 1209 case '*': tone1 = 941; tone2 = 1209; break;
case '#': tone1 = 9715; tone2 = 15249; break; // 941 1477 case '#': tone1 = 941; tone2 = 1477; break;
} }
if (tone1 > 0) if (tone1 > 0)
BK4819_WriteRegister(BK4819_REG_71, tone1); BK4819_WriteRegister(BK4819_REG_71, (((uint32_t)tone1 * 103244) + 5000) / 10000); // with rounding
if (tone2 > 0) if (tone2 > 0)
BK4819_WriteRegister(BK4819_REG_72, tone2); BK4819_WriteRegister(BK4819_REG_72, (((uint32_t)tone2 * 103244) + 5000) / 10000); // with rounding
} }
void BK4819_PlayDTMFString(const char *pString, bool bDelayFirst, uint16_t FirstCodePersistTime, uint16_t HashCodePersistTime, uint16_t CodePersistTime, uint16_t CodeInternalTime) void BK4819_PlayDTMFString(const char *pString, bool bDelayFirst, uint16_t FirstCodePersistTime, uint16_t HashCodePersistTime, uint16_t CodePersistTime, uint16_t CodeInternalTime)
@@ -1322,8 +1322,7 @@ void BK4819_TransmitTone(bool bLocalLoopback, uint32_t Frequency)
// //
// set the tone amplitude // set the tone amplitude
// //
// BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_MASK_ENABLE_TONE1 | (96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN)); BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_MASK_ENABLE_TONE1 | (66u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_MASK_ENABLE_TONE1 | (28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency)); BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency));
@@ -1513,12 +1512,46 @@ BK4819_CssScanResult_t BK4819_GetCxCSSScanResult(uint32_t *pCdcssFreq, uint16_t
void BK4819_DisableFrequencyScan(void) void BK4819_DisableFrequencyScan(void)
{ {
BK4819_WriteRegister(BK4819_REG_32, 0x0244); // REG_32
//
// <15:14> 0 frequency scan time
// 0 = 0.2 sec
// 1 = 0.4 sec
// 2 = 0.8 sec
// 3 = 1.6 sec
//
// <13:1> ???
//
// <0> 0 frequency scan enable
// 1 = enable
// 0 = disable
//
BK4819_WriteRegister(BK4819_REG_32, // 0x0244); // 00 0000100100010 0
( 0u << 14) | // 0 frequency scan Time
(290u << 1) | // ???
( 0u << 0)); // 0 frequency scan enable
} }
void BK4819_EnableFrequencyScan(void) void BK4819_EnableFrequencyScan(void)
{ {
BK4819_WriteRegister(BK4819_REG_32, 0x0245); // 00 0000100100010 1 // REG_32
//
// <15:14> 0 frequency scan time
// 0 = 0.2 sec
// 1 = 0.4 sec
// 2 = 0.8 sec
// 3 = 1.6 sec
//
// <13:1> ???
//
// <0> 0 frequency scan enable
// 1 = enable
// 0 = disable
//
BK4819_WriteRegister(BK4819_REG_32, // 0x0245); // 00 0000100100010 1
( 0u << 14) | // 0 frequency scan time
(290u << 1) | // ???
( 1u << 0)); // 1 frequency scan enable
} }
void BK4819_SetScanFrequency(uint32_t Frequency) void BK4819_SetScanFrequency(uint32_t Frequency)
@@ -1668,8 +1701,7 @@ void BK4819_PlayRoger(void)
BK4819_EnterTxMute(); BK4819_EnterTxMute();
BK4819_SetAF(BK4819_AF_MUTE); BK4819_SetAF(BK4819_AF_MUTE);
// BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN)); BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (66u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
BK4819_EnableTXLink(); BK4819_EnableTXLink();
SYSTEM_DelayMs(50); SYSTEM_DelayMs(50);
@@ -1750,7 +1782,12 @@ void BK4819_PlayDTMFEx(bool bLocalLoopback, char Code)
BK4819_EnterTxMute(); BK4819_EnterTxMute();
BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE); BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE);
BK4819_WriteRegister(BK4819_REG_70, 0xD3D3);
BK4819_WriteRegister(BK4819_REG_70,
BK4819_REG_70_MASK_ENABLE_TONE1 |
(DTMF_TONE1_GAIN << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) |
BK4819_REG_70_MASK_ENABLE_TONE2 |
(DTMF_TONE2_GAIN << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN));
BK4819_EnableTXLink(); BK4819_EnableTXLink();

View File

@@ -28,12 +28,12 @@ enum BK4819_AF_Type_t
BK4819_AF_FM = 1u, // FM BK4819_AF_FM = 1u, // FM
BK4819_AF_ALAM = 2u, // BK4819_AF_ALAM = 2u, //
BK4819_AF_BEEP = 3u, // BK4819_AF_BEEP = 3u, //
BK4819_AF_BASEBAND1 = 4u, // SSB BK4819_AF_BASEBAND1 = 4u, // RAW
BK4819_AF_BASEBAND2 = 5u, // SSB BK4819_AF_BASEBAND2 = 5u, // USB
BK4819_AF_CTCO = 6u, // strange LF audio .. maybe the CTCSS LF line ? BK4819_AF_CTCO = 6u, // strange LF audio .. maybe the CTCSS LF line ?
BK4819_AF_AM = 7u, // AM BK4819_AF_AM = 7u, // AM
BK4819_AF_FSKO = 8u, // nothing BK4819_AF_FSKO = 8u, // nothing
BK4819_AF_UNKNOWN3 = 9u, // distorted BK4819_AF_UNKNOWN3 = 9u, // BYP
BK4819_AF_UNKNOWN4 = 10u, // nothing at all BK4819_AF_UNKNOWN4 = 10u, // nothing at all
BK4819_AF_UNKNOWN5 = 11u, // distorted BK4819_AF_UNKNOWN5 = 11u, // distorted
BK4819_AF_UNKNOWN6 = 12u, // distorted BK4819_AF_UNKNOWN6 = 12u, // distorted
@@ -62,15 +62,18 @@ enum BK4819_CssScanResult_t
typedef enum BK4819_CssScanResult_t BK4819_CssScanResult_t; typedef enum BK4819_CssScanResult_t BK4819_CssScanResult_t;
// radio is asleep, not listening
extern bool gRxIdleMode; extern bool gRxIdleMode;
void BK4819_Init(void); void BK4819_Init(void);
uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register); uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register);
void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data); 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_WriteU8(uint8_t Data);
void BK4819_WriteU16(uint16_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); void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet);

View File

@@ -14,6 +14,9 @@
* limitations under the License. * limitations under the License.
*/ */
#include <stddef.h>
#include <string.h>
#include "driver/eeprom.h" #include "driver/eeprom.h"
#include "driver/i2c.h" #include "driver/i2c.h"
#include "driver/system.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) 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); uint8_t buffer[8];
I2C_Write((Address >> 0) & 0xFF); 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); // give the EEPROM time to burn the data in (apparently takes 5ms)
SYSTEM_DelayMs(8);
I2C_Stop();
SYSTEM_DelayMs(10);
} }

View File

@@ -14,25 +14,5 @@
* limitations under the License. * 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 GPIOC_PIN_PTT = 5
}; };
void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit); static inline void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit) {
uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit); *pReg &= ~(1U << Bit);
void GPIO_FlipBit( volatile uint32_t *pReg, uint8_t Bit); }
void GPIO_SetBit( volatile uint32_t *pReg, uint8_t 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 #endif

View File

@@ -140,65 +140,116 @@ void ST7565_FillScreen(uint8_t Value)
SPI_ToggleMasterMode(&SPI0->CR, true); SPI_ToggleMasterMode(&SPI0->CR, true);
} }
// 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) void ST7565_Init(const bool full)
{ {
if (full) if (full) {
{
SPI0_Init(); SPI0_Init();
ST7565_HardwareReset(); ST7565_HardwareReset();
SPI_ToggleMasterMode(&SPI0->CR, false); SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_WriteByte(ST7565_CMD_SOFTWARE_RESET); // software reset
ST7565_WriteByte(0xE2); // internal reset
SYSTEM_DelayMs(120); SYSTEM_DelayMs(120);
} }
else else
SPI_ToggleMasterMode(&SPI0->CR, false); SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_WriteByte(0xA2); // bias 9
ST7565_WriteByte(0xC0); // com normal
ST7565_WriteByte(0xA1); // reverse ?
ST7565_WriteByte(0xA6); // normal screen ?
// ST7565_WriteByte(0xA7); // inverse screen ?
ST7565_WriteByte(0xA4); // all points normal for(uint8_t i = 0; i < 8; i++)
ST7565_WriteByte(0x24); // ST7565_WriteByte(cmds[i]);
ST7565_WriteByte(0x81); // volume first ?
ST7565_WriteByte(0x1f); // contrast ? if (full) {
ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b011); // VB=0 VR=1 VF=1
if (full) SYSTEM_DelayMs(1);
{ ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b110); // VB=1 VR=1 VF=0
ST7565_WriteByte(0x2B); // power control ?
SYSTEM_DelayMs(1); SYSTEM_DelayMs(1);
ST7565_WriteByte(0x2E); // power control ? for(uint8_t i = 0; i < 4; i++) // why 4 times?
ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b111); // VB=1 VR=1 VF=1
SYSTEM_DelayMs(1);
ST7565_WriteByte(0x2F); //
ST7565_WriteByte(0x2F); //
ST7565_WriteByte(0x2F); //
ST7565_WriteByte(0x2F); //
SYSTEM_DelayMs(40); SYSTEM_DelayMs(40);
} }
ST7565_WriteByte(0x40); // start line ?
ST7565_WriteByte(0xAF); // display on ?
SPI_WaitForUndocumentedTxFifoStatusBit();
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); SPI_ToggleMasterMode(&SPI0->CR, true);
if (full) if (full)
ST7565_FillScreen(0x00); ST7565_FillScreen(0x00);
} }
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) void ST7565_HardwareReset(void)
{ {
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES); GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES);

View File

@@ -31,6 +31,7 @@ void ST7565_BlitFullScreen(void);
void ST7565_BlitStatusLine(void); void ST7565_BlitStatusLine(void);
void ST7565_FillScreen(uint8_t Value); void ST7565_FillScreen(uint8_t Value);
void ST7565_Init(const bool full); void ST7565_Init(const bool full);
void ST7565_FixInterfGlitch(void);
void ST7565_HardwareReset(void); void ST7565_HardwareReset(void);
void ST7565_SelectColumnAndLine(uint8_t Column, uint8_t Line); void ST7565_SelectColumnAndLine(uint8_t Column, uint8_t Line);
void ST7565_WriteByte(uint8_t Value); void ST7565_WriteByte(uint8_t Value);

580
font.c
View File

@@ -16,201 +16,202 @@
#include "font.h" #include "font.h"
//const uint8_t gFontBig[95][16] = // removed last and middle column which was all 0x00
const uint8_t gFontBig[95][15] = // also the space char is not needed
const uint8_t gFontBig[95 - 1][16 - 2] =
{ {
#if 0 #if 0
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // ' ' // {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, 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}, // '"' {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}, // '#' {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}, // '$' {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}, // '%' {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, 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, 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, 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, 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, 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, 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,*/ 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,*/ 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, 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}, // '/' {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' {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' {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, 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' {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' {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' {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' {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' {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, 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' {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, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // , 0x00}, // ':'
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1C, 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}, // '<' {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}, // '=' {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}, // '>' {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}, // '?' {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}, // '@' {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' {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' {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' {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, 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, 0x11, 0x18, 0x1C}, // , 0x00}, // 'E'
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x01, 0x00, 0x00}, // , 0x00}, // 'F' {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' {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' {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, 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' {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, 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' {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, 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' {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' {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' {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' {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' {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' {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' {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,*/ 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,*/ 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' {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' {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' {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' {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}, // '[' {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}, // '"\' {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}, // ']' {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}, // '^' {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, 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, 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' {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' {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' {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' {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, 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, 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' {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' {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, 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' {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' {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' {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' {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' {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' {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' {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' {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' {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' {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' {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' {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' {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' {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' {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, 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' {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, 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, 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}, // '}' {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} // '->' {0x10, 0x18, 0x08, 0x18, 0x10, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // , 0x00} // '->'
#else #else
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // {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, 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}, {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}, {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}, {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}, {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}, {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, 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, 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, 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, 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, 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}, {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}, {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, 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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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, 0x00, 0x06, 0x06, 0x00, 0x00}, // ':'
{0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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, 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, 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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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, 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, 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}, {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} {0x08, 0x0C, 0x04, 0x0C, 0x08, 0x0C, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // '->'
#endif #endif
}; };
@@ -230,37 +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, 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} {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}
}; };
// 6 Empty columns removed
#elif 0 #elif 0
// VCR font // 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,*/ 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,*/ 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, 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,*/ 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,*/ 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,*/ 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,*/ 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,*/ 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, 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,*/ 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,*/ 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 #else
// Terminus font // Terminus font
const uint8_t gFontBigDigits[11][26] =
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,*/ 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,*/ 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,*/ 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,*/ 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,*/ 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,*/ 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,*/ 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,*/ 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,*/ 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,*/ 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} {/*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 #endif
/* /*
@@ -279,9 +283,9 @@ const uint8_t gFontSmallDigits[11][7] =
{0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00} // '-' {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00} // '-'
}; };
*/ */
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, 0x00, 0x5E, 0x00, 0x00, 0x00}, // '!'
{0x00, 0x06, 0x00, 0x06, 0x00, 0x00}, // '"' {0x00, 0x06, 0x00, 0x06, 0x00, 0x00}, // '"'
{0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00}, // '#' {0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00}, // '#'
@@ -379,9 +383,9 @@ const uint8_t gFontSmall[95][6] =
}; };
#ifdef ENABLE_SMALL_BOLD #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}, {0x00, 0x00, 0x5E, 0x5E, 0x00, 0x00},
{0x06, 0x06, 0x00, 0x06, 0x06, 0x00}, {0x06, 0x06, 0x00, 0x06, 0x06, 0x00},
{0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00}, {0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00},
@@ -480,7 +484,7 @@ const uint8_t gFontSmall[95][6] =
#endif #endif
#ifdef ENABLE_SPECTRUM #ifdef ENABLE_SPECTRUM
const uint8_t gFont3x5[160][3] = const uint8_t gFont3x5[][3] =
{ {
{0x00, 0x00, 0x00}, // 32 - space {0x00, 0x00, 0x00}, // 32 - space
{0x00, 0x17, 0x00}, // 33 - exclam {0x00, 0x17, 0x00}, // 33 - exclam
@@ -577,70 +581,74 @@ const uint8_t gFontSmall[95][6] =
{0x00, 0x1b, 0x00}, // 124 - bar {0x00, 0x1b, 0x00}, // 124 - bar
{0x11, 0x1b, 0x04}, // 125 - braceright {0x11, 0x1b, 0x04}, // 125 - braceright
{0x02, 0x03, 0x01}, // 126 - asciitilde {0x02, 0x03, 0x01}, // 126 - asciitilde
{0x00, 0x00, 0x00}, // 127 - empty
{0x00, 0x00, 0x00}, // 128 - empty {0x12, 0x17, 0x12}, // 127 - plusminus
{0x00, 0x00, 0x00}, // 129 - empty
{0x00, 0x00, 0x00}, // 130 - empty
{0x00, 0x00, 0x00}, // 131 - empty // {0x00, 0x00, 0x00}, // 127 - empty
{0x00, 0x00, 0x00}, // 132 - empty // {0x00, 0x00, 0x00}, // 128 - empty
{0x00, 0x00, 0x00}, // 133 - empty // {0x00, 0x00, 0x00}, // 129 - empty
{0x00, 0x00, 0x00}, // 134 - empty // {0x00, 0x00, 0x00}, // 130 - empty
{0x00, 0x00, 0x00}, // 135 - empty // {0x00, 0x00, 0x00}, // 131 - empty
{0x00, 0x00, 0x00}, // 136 - empty // {0x00, 0x00, 0x00}, // 132 - empty
{0x00, 0x00, 0x00}, // 137 - empty // {0x00, 0x00, 0x00}, // 133 - empty
{0x00, 0x00, 0x00}, // 138 - empty // {0x00, 0x00, 0x00}, // 134 - empty
{0x00, 0x00, 0x00}, // 139 - empty // {0x00, 0x00, 0x00}, // 135 - empty
{0x00, 0x00, 0x00}, // 140 - empty // {0x00, 0x00, 0x00}, // 136 - empty
{0x00, 0x00, 0x00}, // 141 - empty // {0x00, 0x00, 0x00}, // 137 - empty
{0x00, 0x00, 0x00}, // 142 - empty // {0x00, 0x00, 0x00}, // 138 - empty
{0x00, 0x00, 0x00}, // 143 - empty // {0x00, 0x00, 0x00}, // 139 - empty
{0x00, 0x00, 0x00}, // 144 - empty // {0x00, 0x00, 0x00}, // 140 - empty
{0x00, 0x00, 0x00}, // 145 - empty // {0x00, 0x00, 0x00}, // 141 - empty
{0x00, 0x00, 0x00}, // 146 - empty // {0x00, 0x00, 0x00}, // 142 - empty
{0x00, 0x00, 0x00}, // 147 - empty // {0x00, 0x00, 0x00}, // 143 - empty
{0x00, 0x00, 0x00}, // 148 - empty // {0x00, 0x00, 0x00}, // 144 - empty
{0x00, 0x00, 0x00}, // 149 - empty // {0x00, 0x00, 0x00}, // 145 - empty
{0x00, 0x00, 0x00}, // 150 - empty // {0x00, 0x00, 0x00}, // 146 - empty
{0x00, 0x00, 0x00}, // 151 - empty // {0x00, 0x00, 0x00}, // 147 - empty
{0x00, 0x00, 0x00}, // 152 - empty // {0x00, 0x00, 0x00}, // 148 - empty
{0x00, 0x00, 0x00}, // 153 - empty // {0x00, 0x00, 0x00}, // 149 - empty
{0x00, 0x00, 0x00}, // 154 - empty // {0x00, 0x00, 0x00}, // 150 - empty
{0x00, 0x00, 0x00}, // 155 - empty // {0x00, 0x00, 0x00}, // 151 - empty
{0x00, 0x00, 0x00}, // 156 - empty // {0x00, 0x00, 0x00}, // 152 - empty
{0x00, 0x00, 0x00}, // 157 - empty // {0x00, 0x00, 0x00}, // 153 - empty
{0x00, 0x00, 0x00}, // 158 - empty // {0x00, 0x00, 0x00}, // 154 - empty
{0x00, 0x00, 0x00}, // 159 - empty // {0x00, 0x00, 0x00}, // 155 - empty
{0x00, 0x00, 0x00}, // 160 - empty // {0x00, 0x00, 0x00}, // 156 - empty
{0x00, 0x1d, 0x00}, // 161 - exclamdown // {0x00, 0x00, 0x00}, // 157 - empty
{0x0e, 0x1b, 0x0a}, // 162 - cent // {0x00, 0x00, 0x00}, // 158 - empty
{0x14, 0x1f, 0x15}, // 163 - sterling // {0x00, 0x00, 0x00}, // 159 - empty
{0x15, 0x0e, 0x15}, // 164 - currency // {0x00, 0x00, 0x00}, // 160 - empty
{0x0b, 0x1c, 0x0b}, // 165 - yen // {0x00, 0x1d, 0x00}, // 161 - exclamdown
{0x00, 0x1b, 0x00}, // 166 - brokenbar // {0x0e, 0x1b, 0x0a}, // 162 - cent
{0x14, 0x1b, 0x05}, // 167 - section // {0x14, 0x1f, 0x15}, // 163 - sterling
{0x01, 0x00, 0x01}, // 168 - dieresis // {0x15, 0x0e, 0x15}, // 164 - currency
{0x02, 0x05, 0x05}, // 169 - copyright // {0x0b, 0x1c, 0x0b}, // 165 - yen
{0x16, 0x15, 0x17}, // 170 - ordfeminine // {0x00, 0x1b, 0x00}, // 166 - brokenbar
{0x02, 0x05, 0x00}, // 171 - guillemotleft // {0x14, 0x1b, 0x05}, // 167 - section
{0x02, 0x02, 0x06}, // 172 - logicalnot // {0x01, 0x00, 0x01}, // 168 - dieresis
{0x04, 0x04, 0x00}, // 173 - softhyphen // {0x02, 0x05, 0x05}, // 169 - copyright
{0x07, 0x03, 0x04}, // 174 - registered // {0x16, 0x15, 0x17}, // 170 - ordfeminine
{0x01, 0x01, 0x01}, // 175 - macron // {0x02, 0x05, 0x00}, // 171 - guillemotleft
{0x02, 0x05, 0x02}, // 176 - degree // {0x02, 0x02, 0x06}, // 172 - logicalnot
{0x12, 0x17, 0x12}, // 177 - plusminus // {0x04, 0x04, 0x00}, // 173 - softhyphen
{0x01, 0x07, 0x04}, // 178 - twosuperior // {0x07, 0x03, 0x04}, // 174 - registered
{0x05, 0x07, 0x07}, // 179 - threesuperior // {0x01, 0x01, 0x01}, // 175 - macron
{0x00, 0x02, 0x01}, // 180 - acute // {0x02, 0x05, 0x02}, // 176 - degree
{0x1f, 0x08, 0x07}, // 181 - mu // {0x12, 0x17, 0x12}, // 177 - plusminus
{0x02, 0x1d, 0x1f}, // 182 - paragraph // {0x01, 0x07, 0x04}, // 178 - twosuperior
{0x0e, 0x0e, 0x0e}, // 183 - periodcentered // {0x05, 0x07, 0x07}, // 179 - threesuperior
{0x10, 0x14, 0x08}, // 184 - cedilla // {0x00, 0x02, 0x01}, // 180 - acute
{0x00, 0x07, 0x00}, // 185 - onesuperior // {0x1f, 0x08, 0x07}, // 181 - mu
{0x12, 0x15, 0x12}, // 186 - ordmasculine // {0x02, 0x1d, 0x1f}, // 182 - paragraph
{0x00, 0x05, 0x02}, // 187 - guillemotright // {0x0e, 0x0e, 0x0e}, // 183 - periodcentered
{0x03, 0x08, 0x18}, // 188 - onequarter // {0x10, 0x14, 0x08}, // 184 - cedilla
{0x0b, 0x18, 0x10}, // 189 - onehalf // {0x00, 0x07, 0x00}, // 185 - onesuperior
{0x03, 0x0b, 0x18}, // 190 - threequarters // {0x12, 0x15, 0x12}, // 186 - ordmasculine
{0x18, 0x15, 0x10}, // 191 - questiondown // {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 #endif

13
font.h
View File

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

View File

@@ -26,22 +26,22 @@ const freq_band_table_t frequencyBandTable[7] =
{ {
#ifndef ENABLE_WIDE_RX #ifndef ENABLE_WIDE_RX
// QS original // QS original
{ 5000000, 7600000}, {.lower = 5000000, .upper = 7600000},
{10800000, 13600000}, {.lower = 10800000, .upper = 13700000},
{13600000, 17400000}, {.lower = 13700000, .upper = 17400000},
{17400000, 35000000}, {.lower = 17400000, .upper = 35000000},
{35000000, 40000000}, {.lower = 35000000, .upper = 40000000},
{40000000, 47000000}, {.lower = 40000000, .upper = 47000000},
{47000000, 60000000} {.lower = 47000000, .upper = 60000000}
#else #else
// extended range // extended range
{ 1800000, 10800000}, {.lower = BX4819_band1.lower, .upper = 10800000},
{10800000, 13600000}, {.lower = 10800000, .upper = 13700000},
{13600000, 17400000}, {.lower = 13700000, .upper = 17400000},
{17400000, 35000000}, {.lower = 17400000, .upper = 35000000},
{35000000, 40000000}, {.lower = 35000000, .upper = 40000000},
{40000000, 47000000}, {.lower = 40000000, .upper = 47000000},
{47000000, 130000000} {.lower = 47000000, .upper = BX4819_band2.upper}
#endif #endif
}; };
@@ -61,13 +61,29 @@ const freq_band_table_t frequencyBandTable[7] =
}; };
#endif #endif
#ifndef ENABLE_12_5KHZ_STEP
// QS steps (*10 Hz) const uint16_t gStepFrequencyTable[] = {
const uint16_t StepFrequencyTable[7] = {250, 500, 625, 1000, 1250, 2500, 833}; 250, 500, 625, 1000, 1250, 2500, 833,
#else 1, 5, 10, 25, 50, 100, 125, 1500, 3000, 5000, 10000, 12500, 25000, 50000
// includes 1.25kHz step };
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) FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency)
{ {
@@ -100,25 +116,23 @@ uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t T
return TxpMid; return TxpMid;
} }
uint32_t FREQUENCY_FloorToStep(uint32_t Upper, uint32_t Step, uint32_t Lower) static int32_t rnd(int32_t freq, uint16_t step)
{ {
uint32_t Index; if(step == 1)
return freq;
return (freq + (step + 1) / 2) / step * step;
}
if (Step == 833) uint32_t FREQUENCY_RoundToStep(uint32_t freq, uint16_t step)
{ {
const uint32_t Delta = Upper - Lower; if(step == 833) {
uint32_t Base = (Delta / 2500) * 2500; uint32_t base = freq/2500*2500;
const uint32_t Index = ((Delta - Base) % 2500) / 833; int f = rnd(freq - base, step);
int x = f / step;
if (Index == 2) return base + f + (x == 3);
Base++;
return Lower + Base + (Index * 833);
} }
Index = (Upper - Lower) / Step; return rnd(freq, step);
return Lower + (Step * Index);
} }
int TX_freq_check(const uint32_t Frequency) int TX_freq_check(const uint32_t Frequency)
@@ -133,18 +147,18 @@ int TX_freq_check(const uint32_t Frequency)
switch (gSetting_F_LOCK) switch (gSetting_F_LOCK)
{ {
case F_LOCK_OFF: case F_LOCK_DEF:
if (Frequency >= 13600000 && Frequency < 17400000) if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < frequencyBandTable[BAND3_137MHz].upper)
return 0; return 0;
if (Frequency >= 17400000 && Frequency < 35000000) if (Frequency >= frequencyBandTable[BAND4_174MHz].lower && Frequency < frequencyBandTable[BAND4_174MHz].upper)
if (gSetting_200TX) if (gSetting_200TX)
return 0; return 0;
if (Frequency >= 35000000 && Frequency < 40000000) if (Frequency >= frequencyBandTable[BAND5_350MHz].lower && Frequency < frequencyBandTable[BAND5_350MHz].upper)
if (gSetting_350TX && gSetting_350EN) if (gSetting_350TX && gSetting_350EN)
return 0; return 0;
if (Frequency >= 40000000 && Frequency < 47000000) if (Frequency >= frequencyBandTable[BAND6_400MHz].lower && Frequency < frequencyBandTable[BAND6_400MHz].upper)
return 0; return 0;
if (Frequency >= 47000000 && Frequency <= 60000000) if (Frequency >= frequencyBandTable[BAND7_470MHz].lower && Frequency <= 60000000)
if (gSetting_500TX) if (gSetting_500TX)
return 0; return 0;
break; break;
@@ -171,18 +185,27 @@ int TX_freq_check(const uint32_t Frequency)
break; break;
case F_LOCK_430: case F_LOCK_430:
if (Frequency >= 13600000 && Frequency < 17400000) if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000)
return 0; return 0;
if (Frequency >= 40000000 && Frequency < 43000000) if (Frequency >= 40000000 && Frequency < 43000000)
return 0; return 0;
break; break;
case F_LOCK_438: case F_LOCK_438:
if (Frequency >= 13600000 && Frequency < 17400000) if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000)
return 0; return 0;
if (Frequency >= 40000000 && Frequency < 43800000) if (Frequency >= 40000000 && Frequency < 43800000)
return 0; return 0;
break; 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 // dis-allowed TX frequency

View File

@@ -19,8 +19,6 @@
#include <stdint.h> #include <stdint.h>
#define ENABLE_12_5KHZ_STEP
typedef struct { typedef struct {
const uint32_t lower; const uint32_t lower;
const uint32_t upper; const uint32_t upper;
@@ -31,44 +29,44 @@ extern const freq_band_table_t BX4819_band2;
extern const freq_band_table_t frequencyBandTable[7]; extern const freq_band_table_t frequencyBandTable[7];
enum FREQUENCY_Band_t { typedef enum {
BAND_NONE = -1, BAND_NONE = -1,
BAND1_50MHz = 0, BAND1_50MHz = 0,
BAND2_108MHz, BAND2_108MHz,
BAND3_136MHz, BAND3_137MHz,
BAND4_174MHz, BAND4_174MHz,
BAND5_350MHz, BAND5_350MHz,
BAND6_400MHz, BAND6_400MHz,
BAND7_470MHz BAND7_470MHz
}; } FREQUENCY_Band_t;
typedef enum FREQUENCY_Band_t FREQUENCY_Band_t;
#ifndef ENABLE_12_5KHZ_STEP
// QS steps
enum STEP_Setting_t {
STEP_2_5kHz = 0,
STEP_5_0kHz,
STEP_6_25kHz,
STEP_10_0kHz,
STEP_12_5kHz,
STEP_25_0kHz,
STEP_8_33kHz
};
#else
// includes 1.25kHz step
enum STEP_Setting_t {
STEP_1_25kHz = 0,
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;
extern const uint16_t StepFrequencyTable[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 #ifdef ENABLE_NOAA
extern const uint32_t NoaaFrequencyTable[10]; extern const uint32_t NoaaFrequencyTable[10];
@@ -76,7 +74,10 @@ extern const uint16_t StepFrequencyTable[7];
FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency); 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); 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);
uint8_t FREQUENCY_GetStepIdxFromSortedIdx(uint8_t sortedIdx);
uint8_t FREQUENCY_GetSortedIdxFromStepIdx(uint8_t step);
int TX_freq_check(const uint32_t Frequency); int TX_freq_check(const uint32_t Frequency);
int RX_freq_check(const uint32_t Frequency); int RX_freq_check(const uint32_t Frequency);

View File

@@ -20,6 +20,7 @@
#if defined(ENABLE_FMRADIO) #if defined(ENABLE_FMRADIO)
#include "app/fm.h" #include "app/fm.h"
#endif #endif
#include "audio.h"
#include "bsp/dp32g030/gpio.h" #include "bsp/dp32g030/gpio.h"
#include "dcs.h" #include "dcs.h"
#include "driver/backlight.h" #include "driver/backlight.h"
@@ -29,6 +30,7 @@
#include "driver/bk4819.h" #include "driver/bk4819.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "driver/system.h" #include "driver/system.h"
#include "driver/st7565.h"
#include "frequencies.h" #include "frequencies.h"
#include "functions.h" #include "functions.h"
#include "helper/battery.h" #include "helper/battery.h"
@@ -42,18 +44,16 @@ FUNCTION_Type_t gCurrentFunction;
void FUNCTION_Init(void) void FUNCTION_Init(void)
{ {
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif #endif
{ {
gCurrentCodeType = gSelectedCodeType; gCurrentCodeType = (gRxVfo->Modulation != MODULATION_FM) ? CODE_TYPE_OFF : gRxVfo->pRX->CodeType;
if (gCssScanMode == CSS_SCAN_MODE_OFF)
gCurrentCodeType = gRxVfo->AM_mode ? CODE_TYPE_OFF : gRxVfo->pRX->CodeType;
} }
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
else else
gCurrentCodeType = CODE_TYPE_CONTINUOUS_TONE; gCurrentCodeType = CODE_TYPE_CONTINUOUS_TONE;
#endif #endif
DTMF_clear_RX(); DTMF_clear_RX();
@@ -93,7 +93,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
{ {
BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable(); BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable();
gRxIdleMode = false; gRxIdleMode = false;
UI_DisplayStatus(false); UI_DisplayStatus();
} }
switch (Function) switch (Function)
@@ -104,6 +104,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
if (PreviousFunction == FUNCTION_TRANSMIT) if (PreviousFunction == FUNCTION_TRANSMIT)
{ {
ST7565_FixInterfGlitch();
gVFO_RSSI_bar_level[0] = 0; gVFO_RSSI_bar_level[0] = 0;
gVFO_RSSI_bar_level[1] = 0; gVFO_RSSI_bar_level[1] = 0;
} }
@@ -145,7 +146,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
BK4819_DisableVox(); BK4819_DisableVox();
BK4819_Sleep(); BK4819_Sleep();
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, false); BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false);
gUpdateStatus = true; gUpdateStatus = true;
@@ -179,13 +180,13 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
GUI_DisplayScreen(); GUI_DisplayScreen();
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOff();
SYSTEM_DelayMs(20); SYSTEM_DelayMs(20);
BK4819_PlayTone(500, 0); BK4819_PlayTone(500, 0);
SYSTEM_DelayMs(2); SYSTEM_DelayMs(2);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOn();
gEnableSpeaker = true; gEnableSpeaker = true;
@@ -204,7 +205,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
RADIO_SetTxParameters(); RADIO_SetTxParameters();
// turn the RED LED on // turn the RED LED on
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, true); BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true);
DTMF_Reply(); DTMF_Reply();
@@ -223,7 +224,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
BK4819_TransmitTone(true, 500); BK4819_TransmitTone(true, 500);
#endif #endif
SYSTEM_DelayMs(2); SYSTEM_DelayMs(2);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOn();
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
gAlarmToneCounter = 0; gAlarmToneCounter = 0;
#endif #endif
@@ -237,7 +238,8 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
else else
BK4819_DisableScramble(); BK4819_DisableScramble();
if (gSetting_backlight_on_tx_rx == 1 || gSetting_backlight_on_tx_rx == 3) if (gSetting_backlight_on_tx_rx == BACKLIGHT_ON_TR_TX ||
gSetting_backlight_on_tx_rx == BACKLIGHT_ON_TR_TXRX)
BACKLIGHT_TurnOn(); BACKLIGHT_TurnOn();
break; break;

View File

@@ -16,7 +16,10 @@
#include "battery.h" #include "battery.h"
#include "driver/backlight.h" #include "driver/backlight.h"
#include "driver/st7565.h"
#include "functions.h"
#include "misc.h" #include "misc.h"
#include "settings.h"
#include "ui/battery.h" #include "ui/battery.h"
#include "ui/menu.h" #include "ui/menu.h"
#include "ui/ui.h" #include "ui/ui.h"
@@ -28,54 +31,66 @@ uint16_t gBatteryVoltages[4];
uint16_t gBatteryVoltageAverage; uint16_t gBatteryVoltageAverage;
uint8_t gBatteryDisplayLevel; uint8_t gBatteryDisplayLevel;
bool gChargingWithTypeC; bool gChargingWithTypeC;
bool gLowBattery;
bool gLowBatteryBlink; bool gLowBatteryBlink;
bool gLowBattery;
bool gLowBatteryConfirmed;
uint16_t gBatteryCheckCounter; 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; 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
*/
unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV) unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV)
{ {
if (voltage_10mV > 814) const uint16_t crv1600[][2] = {
return 100; {828, 100},
if (voltage_10mV > 756) {814, 97 },
return ((132ul * voltage_10mV) / 100) - 974u; {760, 25 },
if (voltage_10mV > 729) {729, 6 },
return ((63ul * voltage_10mV) / 100) - 452u; {630, 0 },
if (voltage_10mV > 600) {0, 0 }
return ((52ul * voltage_10mV) / 1000) - 31u; };
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; return 0;
} }
@@ -84,29 +99,28 @@ void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
const uint8_t PreviousBatteryLevel = gBatteryDisplayLevel; const uint8_t PreviousBatteryLevel = gBatteryDisplayLevel;
const uint16_t Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] + gBatteryVoltages[3]) / 4; const uint16_t Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] + gBatteryVoltages[3]) / 4;
gBatteryDisplayLevel = 0;
if (gBatteryCalibration[5] < Voltage)
gBatteryDisplayLevel = 6;
else
if (gBatteryCalibration[4] < Voltage)
gBatteryDisplayLevel = 5;
else
if (gBatteryCalibration[3] < Voltage)
gBatteryDisplayLevel = 4;
else
if (gBatteryCalibration[2] < Voltage)
gBatteryDisplayLevel = 3;
else
if (gBatteryCalibration[1] < Voltage)
gBatteryDisplayLevel = 2;
else
if (gBatteryCalibration[0] < Voltage)
gBatteryDisplayLevel = 1;
gBatteryVoltageAverage = (Voltage * 760) / gBatteryCalibration[3]; gBatteryVoltageAverage = (Voltage * 760) / gBatteryCalibration[3];
if ((gScreenToDisplay == DISPLAY_MENU) && GetCurrentMenuId() == 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; gUpdateDisplay = true;
if (gBatteryCurrent < 501) if (gBatteryCurrent < 501)
@@ -133,7 +147,9 @@ void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
if (PreviousBatteryLevel != gBatteryDisplayLevel) if (PreviousBatteryLevel != gBatteryDisplayLevel)
{ {
if (gBatteryDisplayLevel < 2) if(gBatteryDisplayLevel > 2)
gLowBatteryConfirmed = false;
else if (gBatteryDisplayLevel < 2)
{ {
gLowBattery = true; gLowBattery = true;
} }
@@ -144,7 +160,64 @@ void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
if (bDisplayBatteryLevel) if (bDisplayBatteryLevel)
UI_DisplayBattery(gBatteryDisplayLevel, gLowBatteryBlink); 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 uint16_t gBatteryVoltageAverage;
extern uint8_t gBatteryDisplayLevel; extern uint8_t gBatteryDisplayLevel;
extern bool gChargingWithTypeC; extern bool gChargingWithTypeC;
extern bool gLowBattery;
extern bool gLowBatteryBlink; extern bool gLowBatteryBlink;
extern bool gLowBattery;
extern bool gLowBatteryConfirmed;
extern uint16_t gBatteryCheckCounter; extern uint16_t gBatteryCheckCounter;
extern volatile uint16_t gPowerSave_10ms; extern volatile uint16_t gPowerSave_10ms;
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); unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV);
void BATTERY_GetReadings(const bool bDisplayBatteryLevel); void BATTERY_GetReadings(const bool bDisplayBatteryLevel);
void BATTERY_TimeSlice500ms(void);
#endif #endif

View File

@@ -84,6 +84,7 @@ void BOOT_ProcessMode(BOOT_Mode_t Mode)
gEeprom.KEY_1_LONG_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_SHORT_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_2_LONG_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, 41002500); RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_LAST - 1, 41002500);

9
main.c
View File

@@ -61,7 +61,8 @@ void Main(void)
| SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE | SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE
| SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE | SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE
| SYSCON_DEV_CLK_GATE_CRC_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(); SYSTICK_Init();
BOARD_Init(); BOARD_Init();
@@ -140,10 +141,10 @@ void Main(void)
{ {
FUNCTION_Select(FUNCTION_POWER_SAVE); FUNCTION_Select(FUNCTION_POWER_SAVE);
if (gEeprom.BACKLIGHT < (ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1)) if (gEeprom.BACKLIGHT_TIME < (ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1)) // backlight is not set to be always on
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight OFF BACKLIGHT_TurnOff(); // turn the backlight OFF
else else
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight ON BACKLIGHT_TurnOn(); // turn the backlight ON
gReducedService = true; gReducedService = true;
} }

54
misc.c
View File

@@ -73,9 +73,6 @@ const uint16_t NOAA_countdown_10ms = 5000 / 10; // 5 seconds
const uint16_t NOAA_countdown_2_10ms = 500 / 10; // 500ms const uint16_t NOAA_countdown_2_10ms = 500 / 10; // 500ms
const uint16_t NOAA_countdown_3_10ms = 200 / 10; // 200ms const uint16_t NOAA_countdown_3_10ms = 200 / 10; // 200ms
//const uint16_t gMax_bat_v = 840; // 8.4V
//const uint16_t gMin_bat_v = 660; // 6.6V
const uint32_t gDefaultAesKey[4] = {0x4AA5CC60, 0x0312CC5F, 0xFFD2DABB, 0x6BBA7F92}; const uint32_t gDefaultAesKey[4] = {0x4AA5CC60, 0x0312CC5F, 0xFFD2DABB, 0x6BBA7F92};
const uint8_t gMicGain_dB2[5] = {3, 8, 16, 24, 31}; const uint8_t gMicGain_dB2[5] = {3, 8, 16, 24, 31};
@@ -85,7 +82,6 @@ bool gSetting_KILLED;
bool gSetting_200TX; bool gSetting_200TX;
bool gSetting_500TX; bool gSetting_500TX;
bool gSetting_350EN; bool gSetting_350EN;
bool gSetting_TX_EN;
uint8_t gSetting_F_LOCK; uint8_t gSetting_F_LOCK;
bool gSetting_ScrambleEnable; bool gSetting_ScrambleEnable;
@@ -115,7 +111,7 @@ uint16_t gEEPROM_RSSI_CALIB[7][4];
uint16_t gEEPROM_1F8A; uint16_t gEEPROM_1F8A;
uint16_t gEEPROM_1F8C; 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; volatile uint16_t gBatterySaveCountdown_10ms = battery_save_count_10ms;
@@ -125,7 +121,6 @@ volatile bool gSchedulePowerSave;
volatile bool gScheduleDualWatch = true; volatile bool gScheduleDualWatch = true;
volatile uint16_t gDualWatchCountdown_10ms; volatile uint16_t gDualWatchCountdown_10ms;
volatile bool gDualWatchCountdownExpired = true;
bool gDualWatchActive = false; bool gDualWatchActive = false;
volatile uint8_t gSerialConfigCountDown_500ms; volatile uint8_t gSerialConfigCountDown_500ms;
@@ -158,7 +153,11 @@ uint8_t gVFO_RSSI_bar_level[2];
uint8_t gReducedService; uint8_t gReducedService;
uint8_t gBatteryVoltageIndex; uint8_t gBatteryVoltageIndex;
CssScanMode_t gCssScanMode; bool gCssBackgroundScan;
volatile bool gScheduleScanListen = true;
volatile uint16_t gScanPauseDelayIn_10ms;
bool gUpdateRSSI; bool gUpdateRSSI;
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
AlarmState_t gAlarmState; AlarmState_t gAlarmState;
@@ -201,13 +200,9 @@ bool g_SquelchLost;
uint8_t gFlashLightState; uint8_t gFlashLightState;
volatile uint16_t gFlashLightBlinkCounter; volatile uint16_t gFlashLightBlinkCounter;
bool gFlagEndTransmission; bool gFlagEndTransmission;
uint16_t gLowBatteryCountdown;
uint8_t gNextMrChannel; uint8_t gNextMrChannel;
ReceptionMode_t gRxReceptionMode; ReceptionMode_t gRxReceptionMode;
enum scan_next_chan_t gCurrentScanList;
uint32_t gRestoreFrequency;
bool gRxVfoIsActive; bool gRxVfoIsActive;
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
uint8_t gAlarmToneCounter; uint8_t gAlarmToneCounter;
@@ -257,32 +252,7 @@ int16_t gCurrentRSSI[2] = {0, 0}; // now one per VFO
uint8_t gIsLocked = 0xFF; 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) int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit)
{ {
@@ -296,3 +266,15 @@ int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit,
return Base; 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;
}

64
misc.h
View File

@@ -35,9 +35,7 @@
#define IS_MR_CHANNEL(x) ((x) <= MR_CHANNEL_LAST) #define IS_MR_CHANNEL(x) ((x) <= MR_CHANNEL_LAST)
#define IS_FREQ_CHANNEL(x) ((x) >= FREQ_CHANNEL_FIRST && (x) <= FREQ_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_VALID_CHANNEL(x) ((x) < LAST_CHANNEL)
#define IS_NOAA_CHANNEL(x) ((x) >= NOAA_CHANNEL_FIRST && (x) <= NOAA_CHANNEL_LAST) #define IS_NOAA_CHANNEL(x) ((x) >= NOAA_CHANNEL_FIRST && (x) <= NOAA_CHANNEL_LAST)
#define IS_NOT_NOAA_CHANNEL(x) ((x) <= FREQ_CHANNEL_LAST)
enum { enum {
MR_CHANNEL_FIRST = 0, MR_CHANNEL_FIRST = 0,
@@ -77,22 +75,12 @@ enum ReceptionMode_t {
}; };
typedef enum ReceptionMode_t ReceptionMode_t; typedef enum ReceptionMode_t ReceptionMode_t;
enum CssScanMode_t enum BacklightOnRxTx_t {
{ BACKLIGHT_ON_TR_OFF,
CSS_SCAN_MODE_OFF = 0, BACKLIGHT_ON_TR_TX,
CSS_SCAN_MODE_SCANNING, BACKLIGHT_ON_TR_RX,
CSS_SCAN_MODE_FOUND, BACKLIGHT_ON_TR_TXRX
}; };
typedef enum CssScanMode_t CssScanMode_t;
enum scan_next_chan_t {
SCAN_NEXT_CHAN_SCANLIST1 = 0,
SCAN_NEXT_CHAN_SCANLIST2,
SCAN_NEXT_CHAN_DUAL_WATCH,
SCAN_NEXT_CHAN_MR,
SCAN_NEXT_NUM
};
typedef enum scan_next_chan_t scan_next_chan_t;
extern const uint8_t fm_radio_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_scan_10ms;
@@ -158,7 +146,6 @@ extern bool gSetting_KILLED;
extern bool gSetting_200TX; extern bool gSetting_200TX;
extern bool gSetting_500TX; extern bool gSetting_500TX;
extern bool gSetting_350EN; extern bool gSetting_350EN;
extern bool gSetting_TX_EN;
extern uint8_t gSetting_F_LOCK; extern uint8_t gSetting_F_LOCK;
extern bool gSetting_ScrambleEnable; extern bool gSetting_ScrambleEnable;
@@ -189,7 +176,18 @@ extern uint16_t gEEPROM_RSSI_CALIB[7][4];
extern uint16_t gEEPROM_1F8A; extern uint16_t gEEPROM_1F8A;
extern uint16_t gEEPROM_1F8C; 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; extern volatile uint16_t gBatterySaveCountdown_10ms;
@@ -199,7 +197,6 @@ extern volatile bool gSchedulePowerSave;
extern volatile bool gScheduleDualWatch; extern volatile bool gScheduleDualWatch;
extern volatile uint16_t gDualWatchCountdown_10ms; extern volatile uint16_t gDualWatchCountdown_10ms;
extern volatile bool gDualWatchCountdownExpired;
extern bool gDualWatchActive; extern bool gDualWatchActive;
extern volatile uint8_t gSerialConfigCountDown_500ms; extern volatile uint8_t gSerialConfigCountDown_500ms;
@@ -230,9 +227,24 @@ extern bool gEndOfRxDetectedMaybe;
extern int16_t gVFO_RSSI[2]; extern int16_t gVFO_RSSI[2];
extern uint8_t gVFO_RSSI_bar_level[2]; extern uint8_t gVFO_RSSI_bar_level[2];
// battery critical, limit functionality to minimum
extern uint8_t gReducedService; extern uint8_t gReducedService;
extern uint8_t gBatteryVoltageIndex; 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 bool gUpdateRSSI;
extern AlarmState_t gAlarmState; extern AlarmState_t gAlarmState;
extern uint16_t gMenuCountdown; extern uint16_t gMenuCountdown;
@@ -269,17 +281,16 @@ extern bool g_CxCSS_TAIL_Found;
extern uint16_t gVoxResumeCountdown; extern uint16_t gVoxResumeCountdown;
extern uint16_t gVoxPauseCountdown; extern uint16_t gVoxPauseCountdown;
#endif #endif
// true means we are receiving signal
extern bool g_SquelchLost; extern bool g_SquelchLost;
extern uint8_t gFlashLightState; extern uint8_t gFlashLightState;
extern volatile uint16_t gFlashLightBlinkCounter; extern volatile uint16_t gFlashLightBlinkCounter;
extern bool gFlagEndTransmission; extern bool gFlagEndTransmission;
extern uint16_t gLowBatteryCountdown;
extern uint8_t gNextMrChannel; extern uint8_t gNextMrChannel;
extern ReceptionMode_t gRxReceptionMode; extern ReceptionMode_t gRxReceptionMode;
extern scan_next_chan_t gCurrentScanList; //TRUE when dual watch is momentarly suspended and RX_VFO is locked to either last TX or RX
extern uint32_t gRestoreFrequency;
extern bool gRxVfoIsActive; extern bool gRxVfoIsActive;
extern uint8_t gAlarmToneCounter; extern uint8_t gAlarmToneCounter;
extern uint16_t gAlarmRunningCounter; extern uint16_t gAlarmRunningCounter;
@@ -323,9 +334,8 @@ extern int16_t gCurrentRSSI[2]; // now one per VFO
extern uint8_t gIsLocked; extern uint8_t gIsLocked;
extern volatile uint8_t boot_counter_10ms; 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); int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit);
unsigned long StrToUL(const char * str);
#endif #endif

517
radio.c
View File

@@ -38,33 +38,40 @@
VFO_Info_t *gTxVfo; VFO_Info_t *gTxVfo;
VFO_Info_t *gRxVfo; VFO_Info_t *gRxVfo;
VFO_Info_t *gCurrentVfo; VFO_Info_t *gCurrentVfo;
DCS_CodeType_t gSelectedCodeType;
DCS_CodeType_t gCurrentCodeType; DCS_CodeType_t gCurrentCodeType;
uint8_t gSelectedCode;
STEP_Setting_t gStepSetting;
VfoState_t VfoState[2]; VfoState_t VfoState[2];
const char gModulationStr[][4] =
{
"FM",
"AM",
"USB",
#ifdef ENABLE_BYP_RAW_DEMODULATORS
"BYP",
"RAW"
#endif
};
bool RADIO_CheckValidChannel(uint16_t Channel, bool bCheckScanList, uint8_t VFO) bool RADIO_CheckValidChannel(uint16_t Channel, bool bCheckScanList, uint8_t VFO)
{ // return true if the channel appears valid { // return true if the channel appears valid
uint8_t Attributes; ChannelAttributes_t att;
uint8_t PriorityCh1; uint8_t PriorityCh1;
uint8_t PriorityCh2; uint8_t PriorityCh2;
if (Channel > MR_CHANNEL_LAST) if (!IS_MR_CHANNEL(Channel))
return false; return false;
Attributes = gMR_ChannelAttributes[Channel]; att = gMR_ChannelAttributes[Channel];
if ((Attributes & MR_CH_BAND_MASK) > BAND7_470MHz) if (att.band > BAND7_470MHz)
return false; return false;
if (bCheckScanList) if (bCheckScanList) {
{ switch (VFO) {
switch (VFO)
{
case 0: case 0:
if ((Attributes & MR_CH_SCANLIST1) == 0) if (!att.scanlist1)
return false; return false;
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[0]; PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[0];
@@ -72,7 +79,7 @@ bool RADIO_CheckValidChannel(uint16_t Channel, bool bCheckScanList, uint8_t VFO)
break; break;
case 1: case 1:
if ((Attributes & MR_CH_SCANLIST2) == 0) if (!att.scanlist2)
return false; return false;
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[1]; PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[1];
@@ -97,12 +104,12 @@ uint8_t RADIO_FindNextChannel(uint8_t Channel, int8_t Direction, bool bCheckScan
{ {
unsigned int i; unsigned int i;
for (i = 0; i <= MR_CHANNEL_LAST; i++) for (i = 0; IS_MR_CHANNEL(i); i++)
{ {
if (Channel == 0xFF) if (Channel == 0xFF)
Channel = MR_CHANNEL_LAST; Channel = MR_CHANNEL_LAST;
else else
if (Channel > MR_CHANNEL_LAST) if (!IS_MR_CHANNEL(Channel))
Channel = MR_CHANNEL_FIRST; Channel = MR_CHANNEL_FIRST;
if (RADIO_CheckValidChannel(Channel, bCheckScanList, VFO)) if (RADIO_CheckValidChannel(Channel, bCheckScanList, VFO))
@@ -119,10 +126,10 @@ void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t
memset(pInfo, 0, sizeof(*pInfo)); memset(pInfo, 0, sizeof(*pInfo));
pInfo->Band = FREQUENCY_GetBand(Frequency); pInfo->Band = FREQUENCY_GetBand(Frequency);
pInfo->SCANLIST1_PARTICIPATION = true; pInfo->SCANLIST1_PARTICIPATION = false;
pInfo->SCANLIST2_PARTICIPATION = true; pInfo->SCANLIST2_PARTICIPATION = false;
pInfo->STEP_SETTING = STEP_12_5kHz; pInfo->STEP_SETTING = STEP_12_5kHz;
pInfo->StepFrequency = StepFrequencyTable[pInfo->STEP_SETTING]; pInfo->StepFrequency = gStepFrequencyTable[pInfo->STEP_SETTING];
pInfo->CHANNEL_SAVE = ChannelSave; pInfo->CHANNEL_SAVE = ChannelSave;
pInfo->FrequencyReverse = false; pInfo->FrequencyReverse = false;
pInfo->OUTPUT_POWER = OUTPUT_POWER_LOW; pInfo->OUTPUT_POWER = OUTPUT_POWER_LOW;
@@ -133,38 +140,32 @@ void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t
pInfo->Compander = 0; // off pInfo->Compander = 0; // off
if (ChannelSave == (FREQ_CHANNEL_FIRST + BAND2_108MHz)) if (ChannelSave == (FREQ_CHANNEL_FIRST + BAND2_108MHz))
pInfo->AM_mode = 1; pInfo->Modulation = MODULATION_AM;
else
pInfo->Modulation = MODULATION_FM;
RADIO_ConfigureSquelchAndOutputPower(pInfo); RADIO_ConfigureSquelchAndOutputPower(pInfo);
} }
void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure) void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure)
{ {
uint8_t Channel; VFO_Info_t *pVfo = &gEeprom.VfoInfo[VFO];
uint8_t Attributes;
uint8_t Band;
bool bParticipation2;
uint16_t Base;
uint32_t Frequency;
VFO_Info_t *pRadio = &gEeprom.VfoInfo[VFO];
if (!gSetting_350EN) if (!gSetting_350EN) {
{ if (gEeprom.FreqChannel[VFO] == FREQ_CHANNEL_FIRST + BAND5_350MHz)
if (gEeprom.FreqChannel[VFO] == (FREQ_CHANNEL_LAST - 2)) gEeprom.FreqChannel[VFO] = FREQ_CHANNEL_FIRST + BAND6_400MHz;
gEeprom.FreqChannel[VFO] = FREQ_CHANNEL_LAST - 1;
if (gEeprom.ScreenChannel[VFO] == (FREQ_CHANNEL_LAST - 2)) if (gEeprom.ScreenChannel[VFO] == FREQ_CHANNEL_FIRST + BAND5_350MHz)
gEeprom.ScreenChannel[VFO] = FREQ_CHANNEL_LAST - 1; gEeprom.ScreenChannel[VFO] = FREQ_CHANNEL_FIRST + BAND6_400MHz;
} }
Channel = gEeprom.ScreenChannel[VFO]; uint8_t channel = gEeprom.ScreenChannel[VFO];
if (IS_VALID_CHANNEL(Channel)) if (IS_VALID_CHANNEL(channel)) {
{
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (Channel >= NOAA_CHANNEL_FIRST) if (channel >= NOAA_CHANNEL_FIRST)
{ {
RADIO_InitInfo(pRadio, gEeprom.ScreenChannel[VFO], NoaaFrequencyTable[Channel - NOAA_CHANNEL_FIRST]); RADIO_InitInfo(pVfo, gEeprom.ScreenChannel[VFO], NoaaFrequencyTable[channel - NOAA_CHANNEL_FIRST]);
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF)
return; return;
@@ -176,251 +177,240 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
} }
#endif #endif
if (Channel <= MR_CHANNEL_LAST) if (IS_MR_CHANNEL(channel)) {
{ channel = RADIO_FindNextChannel(channel, RADIO_CHANNEL_UP, false, VFO);
Channel = RADIO_FindNextChannel(Channel, RADIO_CHANNEL_UP, false, VFO); if (channel == 0xFF) {
if (Channel == 0xFF) channel = gEeprom.FreqChannel[VFO];
{
Channel = gEeprom.FreqChannel[VFO];
gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO]; gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO];
} }
else else {
{ gEeprom.ScreenChannel[VFO] = channel;
gEeprom.ScreenChannel[VFO] = Channel; gEeprom.MrChannel[VFO] = channel;
gEeprom.MrChannel[VFO] = Channel;
} }
} }
} }
else else
Channel = FREQ_CHANNEL_LAST - 1; channel = FREQ_CHANNEL_LAST - 1;
Attributes = gMR_ChannelAttributes[Channel]; ChannelAttributes_t att = gMR_ChannelAttributes[channel];
if (Attributes == 0xFF) if (att.__val == 0xFF) { // invalid/unused channel
{ // invalid/unused channel if (IS_MR_CHANNEL(channel)) {
channel = gEeprom.FreqChannel[VFO];
uint8_t Index; gEeprom.ScreenChannel[VFO] = channel;
if (Channel <= MR_CHANNEL_LAST)
{
Channel = gEeprom.FreqChannel[VFO];
gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO];
} }
Index = Channel - FREQ_CHANNEL_FIRST; uint8_t bandIdx = channel - FREQ_CHANNEL_FIRST;
RADIO_InitInfo(pVfo, channel, frequencyBandTable[bandIdx].lower);
RADIO_InitInfo(pRadio, Channel, frequencyBandTable[Index].lower);
return; return;
} }
Band = Attributes & MR_CH_BAND_MASK; uint8_t band = att.band;
if (Band > BAND7_470MHz) if (band > BAND7_470MHz) {
{ band = BAND6_400MHz;
Band = BAND6_400MHz;
} }
if (Channel <= MR_CHANNEL_LAST) bool bParticipation1;
{ bool bParticipation2;
gEeprom.VfoInfo[VFO].Band = Band; if (IS_MR_CHANNEL(channel)) {
gEeprom.VfoInfo[VFO].SCANLIST1_PARTICIPATION = !!(Attributes & MR_CH_SCANLIST1); bParticipation1 = att.scanlist1;
bParticipation2 = !!(Attributes & MR_CH_SCANLIST2); bParticipation2 = att.scanlist2;
} }
else {
band = channel - FREQ_CHANNEL_FIRST;
bParticipation1 = true;
bParticipation2 = true;
}
pVfo->Band = band;
pVfo->SCANLIST1_PARTICIPATION = bParticipation1;
pVfo->SCANLIST2_PARTICIPATION = bParticipation2;
pVfo->CHANNEL_SAVE = channel;
uint16_t base;
if (IS_MR_CHANNEL(channel))
base = channel * 16;
else else
base = 0x0C80 + ((channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16);
if (configure == VFO_CONFIGURE_RELOAD || IS_FREQ_CHANNEL(channel))
{ {
Band = Channel - FREQ_CHANNEL_FIRST; uint8_t tmp;
gEeprom.VfoInfo[VFO].Band = Band; uint8_t data[8];
bParticipation2 = true;
gEeprom.VfoInfo[VFO].SCANLIST1_PARTICIPATION = true;
}
gEeprom.VfoInfo[VFO].SCANLIST2_PARTICIPATION = bParticipation2;
gEeprom.VfoInfo[VFO].CHANNEL_SAVE = Channel;
if (Channel <= MR_CHANNEL_LAST)
Base = Channel * 16;
else
Base = 0x0C80 + ((Channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16);
if (configure == VFO_CONFIGURE_RELOAD || Channel >= FREQ_CHANNEL_FIRST)
{
uint8_t Tmp;
uint8_t Data[8];
// *************** // ***************
EEPROM_ReadBuffer(Base + 8, Data, sizeof(Data)); EEPROM_ReadBuffer(base + 8, data, sizeof(data));
Tmp = Data[3] & 0x0F; tmp = data[3] & 0x0F;
if (Tmp > TX_OFFSET_FREQUENCY_DIRECTION_SUB) if (tmp > TX_OFFSET_FREQUENCY_DIRECTION_SUB)
Tmp = 0; tmp = 0;
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY_DIRECTION = Tmp; pVfo->TX_OFFSET_FREQUENCY_DIRECTION = tmp;
gEeprom.VfoInfo[VFO].AM_mode = (Data[3] >> 4) & 1u; tmp = data[3] >> 4;
if (tmp >= MODULATION_UKNOWN)
tmp = MODULATION_FM;
pVfo->Modulation = tmp;
Tmp = Data[6]; tmp = data[6];
if (Tmp >= ARRAY_SIZE(StepFrequencyTable)) if (tmp >= ARRAY_SIZE(gStepFrequencyTable))
Tmp = STEP_12_5kHz; tmp = STEP_12_5kHz;
gEeprom.VfoInfo[VFO].STEP_SETTING = Tmp; pVfo->STEP_SETTING = tmp;
gEeprom.VfoInfo[VFO].StepFrequency = StepFrequencyTable[Tmp]; pVfo->StepFrequency = gStepFrequencyTable[tmp];
Tmp = Data[7]; tmp = data[7];
if (Tmp > (ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1)) if (tmp > (ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1))
Tmp = 0; tmp = 0;
gEeprom.VfoInfo[VFO].SCRAMBLING_TYPE = Tmp; pVfo->SCRAMBLING_TYPE = tmp;
gEeprom.VfoInfo[VFO].freq_config_RX.CodeType = (Data[2] >> 0) & 0x0F; pVfo->freq_config_RX.CodeType = (data[2] >> 0) & 0x0F;
gEeprom.VfoInfo[VFO].freq_config_TX.CodeType = (Data[2] >> 4) & 0x0F; pVfo->freq_config_TX.CodeType = (data[2] >> 4) & 0x0F;
Tmp = Data[0]; tmp = data[0];
switch (gEeprom.VfoInfo[VFO].freq_config_RX.CodeType) switch (pVfo->freq_config_RX.CodeType)
{ {
default: default:
case CODE_TYPE_OFF: case CODE_TYPE_OFF:
gEeprom.VfoInfo[VFO].freq_config_RX.CodeType = CODE_TYPE_OFF; pVfo->freq_config_RX.CodeType = CODE_TYPE_OFF;
Tmp = 0; tmp = 0;
break; break;
case CODE_TYPE_CONTINUOUS_TONE: case CODE_TYPE_CONTINUOUS_TONE:
if (Tmp > (ARRAY_SIZE(CTCSS_Options) - 1)) if (tmp > (ARRAY_SIZE(CTCSS_Options) - 1))
Tmp = 0; tmp = 0;
break; break;
case CODE_TYPE_DIGITAL: case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL: case CODE_TYPE_REVERSE_DIGITAL:
if (Tmp > (ARRAY_SIZE(DCS_Options) - 1)) if (tmp > (ARRAY_SIZE(DCS_Options) - 1))
Tmp = 0; tmp = 0;
break; break;
} }
gEeprom.VfoInfo[VFO].freq_config_RX.Code = Tmp; pVfo->freq_config_RX.Code = tmp;
Tmp = Data[1]; tmp = data[1];
switch (gEeprom.VfoInfo[VFO].freq_config_TX.CodeType) switch (pVfo->freq_config_TX.CodeType)
{ {
default: default:
case CODE_TYPE_OFF: case CODE_TYPE_OFF:
gEeprom.VfoInfo[VFO].freq_config_TX.CodeType = CODE_TYPE_OFF; pVfo->freq_config_TX.CodeType = CODE_TYPE_OFF;
Tmp = 0; tmp = 0;
break; break;
case CODE_TYPE_CONTINUOUS_TONE: case CODE_TYPE_CONTINUOUS_TONE:
if (Tmp > (ARRAY_SIZE(CTCSS_Options) - 1)) if (tmp > (ARRAY_SIZE(CTCSS_Options) - 1))
Tmp = 0; tmp = 0;
break; break;
case CODE_TYPE_DIGITAL: case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL: case CODE_TYPE_REVERSE_DIGITAL:
if (Tmp > (ARRAY_SIZE(DCS_Options) - 1)) if (tmp > (ARRAY_SIZE(DCS_Options) - 1))
Tmp = 0; tmp = 0;
break; break;
} }
gEeprom.VfoInfo[VFO].freq_config_TX.Code = Tmp; pVfo->freq_config_TX.Code = tmp;
if (Data[4] == 0xFF) if (data[4] == 0xFF)
{ {
gEeprom.VfoInfo[VFO].FrequencyReverse = false; pVfo->FrequencyReverse = false;
gEeprom.VfoInfo[VFO].CHANNEL_BANDWIDTH = BK4819_FILTER_BW_WIDE; pVfo->CHANNEL_BANDWIDTH = BK4819_FILTER_BW_WIDE;
gEeprom.VfoInfo[VFO].OUTPUT_POWER = OUTPUT_POWER_LOW; pVfo->OUTPUT_POWER = OUTPUT_POWER_LOW;
gEeprom.VfoInfo[VFO].BUSY_CHANNEL_LOCK = false; pVfo->BUSY_CHANNEL_LOCK = false;
} }
else else
{ {
const uint8_t d4 = Data[4]; const uint8_t d4 = data[4];
gEeprom.VfoInfo[VFO].FrequencyReverse = !!((d4 >> 0) & 1u); pVfo->FrequencyReverse = !!((d4 >> 0) & 1u);
gEeprom.VfoInfo[VFO].CHANNEL_BANDWIDTH = !!((d4 >> 1) & 1u); pVfo->CHANNEL_BANDWIDTH = !!((d4 >> 1) & 1u);
gEeprom.VfoInfo[VFO].OUTPUT_POWER = ((d4 >> 2) & 3u); pVfo->OUTPUT_POWER = ((d4 >> 2) & 3u);
gEeprom.VfoInfo[VFO].BUSY_CHANNEL_LOCK = !!((d4 >> 4) & 1u); pVfo->BUSY_CHANNEL_LOCK = !!((d4 >> 4) & 1u);
} }
if (Data[5] == 0xFF) if (data[5] == 0xFF)
{ {
gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = false; pVfo->DTMF_DECODING_ENABLE = false;
gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = PTT_ID_OFF; pVfo->DTMF_PTT_ID_TX_MODE = PTT_ID_OFF;
} }
else else
{ {
gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = ((Data[5] >> 0) & 1u) ? true : false; pVfo->DTMF_DECODING_ENABLE = ((data[5] >> 0) & 1u) ? true : false;
gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = ((Data[5] >> 1) & 7u); pVfo->DTMF_PTT_ID_TX_MODE = ((data[5] >> 1) & 7u);
} }
// *************** // ***************
struct struct {
{
uint32_t Frequency; uint32_t Frequency;
uint32_t Offset; uint32_t Offset;
} __attribute__((packed)) Info; } __attribute__((packed)) info;
EEPROM_ReadBuffer(base, &info, sizeof(info));
if(info.Frequency==0xFFFFFFFF)
pVfo->freq_config_RX.Frequency = frequencyBandTable[band].lower;
else
pVfo->freq_config_RX.Frequency = info.Frequency;
EEPROM_ReadBuffer(Base, &Info, sizeof(Info)); if (info.Offset >= 100000000)
info.Offset = 1000000;
pRadio->freq_config_RX.Frequency = Info.Frequency; pVfo->TX_OFFSET_FREQUENCY = info.Offset;
if (Info.Offset >= 100000000)
Info.Offset = 1000000;
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY = Info.Offset;
// *************** // ***************
} }
Frequency = pRadio->freq_config_RX.Frequency; uint32_t frequency = pVfo->freq_config_RX.Frequency;
#if 1
// fix previously set incorrect band // fix previously set incorrect band
Band = FREQUENCY_GetBand(Frequency); band = FREQUENCY_GetBand(frequency);
#endif
if (Frequency < frequencyBandTable[Band].lower) if (frequency < frequencyBandTable[band].lower)
Frequency = frequencyBandTable[Band].lower; frequency = frequencyBandTable[band].lower;
else else if (frequency > frequencyBandTable[band].upper)
if (Frequency > frequencyBandTable[Band].upper) frequency = frequencyBandTable[band].upper;
Frequency = frequencyBandTable[Band].upper; else if (channel >= FREQ_CHANNEL_FIRST)
else frequency = FREQUENCY_RoundToStep(frequency, pVfo->StepFrequency);
if (Channel >= FREQ_CHANNEL_FIRST)
Frequency = FREQUENCY_FloorToStep(Frequency, gEeprom.VfoInfo[VFO].StepFrequency, frequencyBandTable[Band].lower);
pRadio->freq_config_RX.Frequency = Frequency; pVfo->freq_config_RX.Frequency = frequency;
if (Frequency >= 10800000 && Frequency < 13600000) if (frequency >= frequencyBandTable[BAND2_108MHz].upper && frequency < frequencyBandTable[BAND2_108MHz].upper)
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF; pVfo->TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF;
else else if (!IS_MR_CHANNEL(channel))
if (Channel > MR_CHANNEL_LAST) pVfo->TX_OFFSET_FREQUENCY = FREQUENCY_RoundToStep(pVfo->TX_OFFSET_FREQUENCY, pVfo->StepFrequency);
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY = FREQUENCY_FloorToStep(gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY, gEeprom.VfoInfo[VFO].StepFrequency, 0);
RADIO_ApplyOffset(pRadio); RADIO_ApplyOffset(pVfo);
memset(gEeprom.VfoInfo[VFO].Name, 0, sizeof(gEeprom.VfoInfo[VFO].Name)); memset(pVfo->Name, 0, sizeof(pVfo->Name));
if (Channel < MR_CHANNEL_LAST) if (IS_MR_CHANNEL(channel))
{ // 16 bytes allocated to the channel name but only 10 used, the rest are 0's { // 16 bytes allocated to the channel name but only 10 used, the rest are 0's
EEPROM_ReadBuffer(0x0F50 + (Channel * 16), gEeprom.VfoInfo[VFO].Name + 0, 8); EEPROM_ReadBuffer(0x0F50 + (channel * 16), pVfo->Name + 0, 8);
EEPROM_ReadBuffer(0x0F58 + (Channel * 16), gEeprom.VfoInfo[VFO].Name + 8, 2); EEPROM_ReadBuffer(0x0F58 + (channel * 16), pVfo->Name + 8, 2);
} }
if (!gEeprom.VfoInfo[VFO].FrequencyReverse) if (!pVfo->FrequencyReverse)
{ {
gEeprom.VfoInfo[VFO].pRX = &gEeprom.VfoInfo[VFO].freq_config_RX; pVfo->pRX = &pVfo->freq_config_RX;
gEeprom.VfoInfo[VFO].pTX = &gEeprom.VfoInfo[VFO].freq_config_TX; pVfo->pTX = &pVfo->freq_config_TX;
} }
else else
{ {
gEeprom.VfoInfo[VFO].pRX = &gEeprom.VfoInfo[VFO].freq_config_TX; pVfo->pRX = &pVfo->freq_config_TX;
gEeprom.VfoInfo[VFO].pTX = &gEeprom.VfoInfo[VFO].freq_config_RX; pVfo->pTX = &pVfo->freq_config_RX;
} }
if (!gSetting_350EN) if (!gSetting_350EN)
{ {
FREQ_Config_t *pConfig = gEeprom.VfoInfo[VFO].pRX; FREQ_Config_t *pConfig = pVfo->pRX;
if (pConfig->Frequency >= 35000000 && pConfig->Frequency < 40000000) if (pConfig->Frequency >= 35000000 && pConfig->Frequency < 40000000)
pConfig->Frequency = 43300000; pConfig->Frequency = 43300000;
} }
if (gEeprom.VfoInfo[VFO].AM_mode) if (pVfo->Modulation != MODULATION_FM)
{ // freq/chan is in AM mode { // freq/chan is in AM mode
gEeprom.VfoInfo[VFO].SCRAMBLING_TYPE = 0; pVfo->SCRAMBLING_TYPE = 0;
// gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = false; // no reason to disable DTMF decoding, aircraft use it on SSB // pVfo->DTMF_DECODING_ENABLE = false; // no reason to disable DTMF decoding, aircraft use it on SSB
gEeprom.VfoInfo[VFO].freq_config_RX.CodeType = CODE_TYPE_OFF; pVfo->freq_config_RX.CodeType = CODE_TYPE_OFF;
gEeprom.VfoInfo[VFO].freq_config_TX.CodeType = CODE_TYPE_OFF; pVfo->freq_config_TX.CodeType = CODE_TYPE_OFF;
} }
gEeprom.VfoInfo[VFO].Compander = (Attributes & MR_CH_COMPAND) >> 4; pVfo->Compander = att.compander;
RADIO_ConfigureSquelchAndOutputPower(pRadio); RADIO_ConfigureSquelchAndOutputPower(pVfo);
} }
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo) void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
@@ -516,6 +506,21 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
EEPROM_ReadBuffer(0x1ED0 + (Band * 16) + (pInfo->OUTPUT_POWER * 3), Txp, 3); EEPROM_ReadBuffer(0x1ED0 + (Band * 16) + (pInfo->OUTPUT_POWER * 3), Txp, 3);
#ifdef ENABLE_REDUCE_LOW_MID_TX_POWER
// make low and mid even lower
if (pInfo->OUTPUT_POWER == OUTPUT_POWER_LOW) {
Txp[0] /= 5;
Txp[1] /= 5;
Txp[2] /= 5;
}
else if (pInfo->OUTPUT_POWER == OUTPUT_POWER_MID){
Txp[0] /= 3;
Txp[1] /= 3;
Txp[2] /= 3;
}
#endif
pInfo->TXP_CalculatedSetting = FREQUENCY_CalculateOutputPower( pInfo->TXP_CalculatedSetting = FREQUENCY_CalculateOutputPower(
Txp[0], Txp[0],
Txp[1], Txp[1],
@@ -555,12 +560,17 @@ void RADIO_ApplyOffset(VFO_Info_t *pInfo)
static void RADIO_SelectCurrentVfo(void) static void RADIO_SelectCurrentVfo(void)
{ {
gCurrentVfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gRxVfo : &gEeprom.VfoInfo[gEeprom.TX_VFO]; // if crossband is active and DW not the gCurrentVfo is gTxVfo (gTxVfo/TX_VFO is only ever changed by the user)
// otherwise it is set to gRxVfo which is set to gTxVfo in RADIO_SelectVfos
// so in the end gCurrentVfo is equal to gTxVfo unless dual watch changes it on incomming transmition (again, this can only happen when XB off)
// note: it is called only in certain situations so could be not up-to-date
gCurrentVfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF || gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) ? gRxVfo : gTxVfo;
} }
void RADIO_SelectVfos(void) void RADIO_SelectVfos(void)
{ {
gEeprom.RX_VFO = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.TX_VFO : !gEeprom.TX_VFO; // if crossband without DW is used then RX_VFO is the opposite to the TX_VFO
gEeprom.RX_VFO = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF || gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) ? gEeprom.TX_VFO : !gEeprom.TX_VFO;
gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_VFO]; gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_VFO];
gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO]; gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO];
@@ -568,17 +578,17 @@ void RADIO_SelectVfos(void)
RADIO_SelectCurrentVfo(); RADIO_SelectCurrentVfo();
} }
void RADIO_SetupRegisters(bool bSwitchToFunction0) void RADIO_SetupRegisters(bool switchToForeground)
{ {
BK4819_FilterBandwidth_t Bandwidth = gRxVfo->CHANNEL_BANDWIDTH; BK4819_FilterBandwidth_t Bandwidth = gRxVfo->CHANNEL_BANDWIDTH;
uint16_t InterruptMask; uint16_t InterruptMask;
uint32_t Frequency; uint32_t Frequency;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOff();
gEnableSpeaker = false; gEnableSpeaker = false;
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, false); BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
switch (Bandwidth) switch (Bandwidth)
{ {
@@ -588,7 +598,7 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
case BK4819_FILTER_BW_WIDE: case BK4819_FILTER_BW_WIDE:
case BK4819_FILTER_BW_NARROW: case BK4819_FILTER_BW_NARROW:
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
// BK4819_SetFilterBandwidth(Bandwidth, gRxVfo->AM_mode && gSetting_AM_fix); // BK4819_SetFilterBandwidth(Bandwidth, gRxVfo->Modulation == MODULATION_AM && gSetting_AM_fix);
BK4819_SetFilterBandwidth(Bandwidth, true); BK4819_SetFilterBandwidth(Bandwidth, true);
#else #else
BK4819_SetFilterBandwidth(Bandwidth, false); BK4819_SetFilterBandwidth(Bandwidth, false);
@@ -596,11 +606,11 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
break; break;
} }
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, false); BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false);
BK4819_SetupPowerAmplifier(0, 0); BK4819_SetupPowerAmplifier(0, 0);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, false); BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
while (1) while (1)
{ {
@@ -617,7 +627,7 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
BK4819_WriteRegister(BK4819_REG_7D, 0xE940 | (gEeprom.MIC_SENSITIVITY_TUNING & 0x1f)); BK4819_WriteRegister(BK4819_REG_7D, 0xE940 | (gEeprom.MIC_SENSITIVITY_TUNING & 0x1f));
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) || !gIsNoaaMode) if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) || !gIsNoaaMode)
Frequency = gRxVfo->pRX->Frequency; Frequency = gRxVfo->pRX->Frequency;
else else
Frequency = NoaaFrequencyTable[gNoaaChannel]; Frequency = NoaaFrequencyTable[gNoaaChannel];
@@ -634,26 +644,27 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
BK4819_PickRXFilterPathBasedOnFrequency(Frequency); BK4819_PickRXFilterPathBasedOnFrequency(Frequency);
// what does this in do ? // what does this in do ?
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, true); BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, true);
// AF RX Gain and DAC // AF RX Gain and DAC
BK4819_WriteRegister(BK4819_REG_48, 0xB3A8); // 1011 00 111010 1000 //BK4819_WriteRegister(BK4819_REG_48, 0xB3A8); // 1011 00 111010 1000
BK4819_WriteRegister(BK4819_REG_48,
(11u << 12) | // ??? .. 0 ~ 15, doesn't seem to make any difference
( 0u << 10) | // AF Rx Gain-1
(gEeprom.VOLUME_GAIN << 4) | // AF Rx Gain-2
(gEeprom.DAC_GAIN << 0)); // AF DAC Gain (after Gain-1 and Gain-2)
InterruptMask = BK4819_REG_3F_SQUELCH_FOUND | BK4819_REG_3F_SQUELCH_LOST; InterruptMask = BK4819_REG_3F_SQUELCH_FOUND | BK4819_REG_3F_SQUELCH_LOST;
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif #endif
{ {
if (gRxVfo->AM_mode == 0) if (gRxVfo->Modulation == MODULATION_FM)
{ // FM { // FM
uint8_t CodeType = gSelectedCodeType; uint8_t CodeType = gRxVfo->pRX->CodeType;
uint8_t Code = gSelectedCode; uint8_t Code = gRxVfo->pRX->Code;
if (gCssScanMode == CSS_SCAN_MODE_OFF)
{
CodeType = gRxVfo->pRX->CodeType;
Code = gRxVfo->pRX->Code;
}
switch (CodeType) switch (CodeType)
{ {
@@ -721,15 +732,15 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (gEeprom.VOX_SWITCH && !gFmRadioMode && IS_NOT_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE) && gCurrentVfo->AM_mode == 0) if (gEeprom.VOX_SWITCH && !gFmRadioMode && !IS_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE) && gCurrentVfo->Modulation == MODULATION_FM)
#else #else
if (gEeprom.VOX_SWITCH && IS_NOT_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE) && gCurrentVfo->AM_mode == 0) if (gEeprom.VOX_SWITCH && !IS_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE) && gCurrentVfo->Modulation == MODULATION_FM)
#endif #endif
#else #else
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (gEeprom.VOX_SWITCH && !gFmRadioMode && gCurrentVfo->AM_mode == 0) if (gEeprom.VOX_SWITCH && !gFmRadioMode && gCurrentVfo->Modulation == MODULATION_FM)
#else #else
if (gEeprom.VOX_SWITCH && gCurrentVfo->AM_mode == 0) if (gEeprom.VOX_SWITCH && gCurrentVfo->Modulation == MODULATION_FM)
#endif #endif
#endif #endif
{ {
@@ -741,7 +752,7 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
BK4819_DisableVox(); BK4819_DisableVox();
// RX expander // RX expander
BK4819_SetCompander((gRxVfo->AM_mode == 0 && gRxVfo->Compander >= 2) ? gRxVfo->Compander : 0); BK4819_SetCompander((gRxVfo->Modulation == MODULATION_FM && gRxVfo->Compander >= 2) ? gRxVfo->Compander : 0);
#if 0 #if 0
if (!gRxVfo->DTMF_DECODING_ENABLE && !gSetting_KILLED) if (!gRxVfo->DTMF_DECODING_ENABLE && !gSetting_KILLED)
@@ -771,7 +782,7 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
FUNCTION_Init(); FUNCTION_Init();
if (bSwitchToFunction0) if (switchToForeground)
FUNCTION_Select(FUNCTION_FOREGROUND); FUNCTION_Select(FUNCTION_FOREGROUND);
} }
@@ -786,9 +797,9 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
{ {
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
{ {
if (IS_NOT_NOAA_CHANNEL(gEeprom.ScreenChannel[0])) if (!IS_NOAA_CHANNEL(gEeprom.ScreenChannel[0]))
{ {
if (IS_NOT_NOAA_CHANNEL(gEeprom.ScreenChannel[1])) if (!IS_NOAA_CHANNEL(gEeprom.ScreenChannel[1]))
{ {
gIsNoaaMode = false; gIsNoaaMode = false;
return; return;
@@ -824,11 +835,11 @@ void RADIO_SetTxParameters(void)
{ {
BK4819_FilterBandwidth_t Bandwidth = gCurrentVfo->CHANNEL_BANDWIDTH; BK4819_FilterBandwidth_t Bandwidth = gCurrentVfo->CHANNEL_BANDWIDTH;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOff();
gEnableSpeaker = false; gEnableSpeaker = false;
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, false); BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false);
switch (Bandwidth) switch (Bandwidth)
{ {
@@ -838,7 +849,7 @@ void RADIO_SetTxParameters(void)
case BK4819_FILTER_BW_WIDE: case BK4819_FILTER_BW_WIDE:
case BK4819_FILTER_BW_NARROW: case BK4819_FILTER_BW_NARROW:
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
// BK4819_SetFilterBandwidth(Bandwidth, gCurrentVfo->AM_mode && gSetting_AM_fix); // BK4819_SetFilterBandwidth(Bandwidth, gCurrentVfo->Modulation == MODULATION_AM && gSetting_AM_fix);
BK4819_SetFilterBandwidth(Bandwidth, true); BK4819_SetFilterBandwidth(Bandwidth, true);
#else #else
BK4819_SetFilterBandwidth(Bandwidth, false); BK4819_SetFilterBandwidth(Bandwidth, false);
@@ -849,7 +860,7 @@ void RADIO_SetTxParameters(void)
BK4819_SetFrequency(gCurrentVfo->pTX->Frequency); BK4819_SetFrequency(gCurrentVfo->pTX->Frequency);
// TX compressor // TX compressor
BK4819_SetCompander((gRxVfo->AM_mode == 0 && (gRxVfo->Compander == 1 || gRxVfo->Compander >= 3)) ? gRxVfo->Compander : 0); BK4819_SetCompander((gRxVfo->Modulation == MODULATION_FM && (gRxVfo->Compander == 1 || gRxVfo->Compander >= 3)) ? gRxVfo->Compander : 0);
BK4819_PrepareTransmit(); BK4819_PrepareTransmit();
@@ -857,7 +868,7 @@ void RADIO_SetTxParameters(void)
BK4819_PickRXFilterPathBasedOnFrequency(gCurrentVfo->pTX->Frequency); BK4819_PickRXFilterPathBasedOnFrequency(gCurrentVfo->pTX->Frequency);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, true); BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, true);
SYSTEM_DelayMs(5); SYSTEM_DelayMs(5);
@@ -883,6 +894,37 @@ void RADIO_SetTxParameters(void)
} }
} }
void RADIO_SetModulation(ModulationMode_t modulation)
{
BK4819_AF_Type_t mod;
switch(modulation) {
default:
case MODULATION_FM:
mod = BK4819_AF_FM;
break;
case MODULATION_AM:
mod = BK4819_AF_AM;
break;
case MODULATION_USB:
mod = BK4819_AF_BASEBAND2;
break;
#ifdef ENABLE_BYP_RAW_DEMODULATORS
case MODULATION_BYP:
mod = BK4819_AF_UNKNOWN3;
break;
case MODULATION_RAW:
mod = BK4819_AF_BASEBAND1;
break;
#endif
}
BK4819_SetAF(mod);
BK4819_SetRegValue(afDacGainRegSpec, 0xF);
BK4819_WriteRegister(BK4819_REG_3D, modulation == MODULATION_USB ? 0 : 0x2AAB);
BK4819_SetRegValue(afcDisableRegSpec, modulation != MODULATION_FM);
}
void RADIO_SetVfoState(VfoState_t State) void RADIO_SetVfoState(VfoState_t State)
{ {
if (State == VFO_STATE_NORMAL) if (State == VFO_STATE_NORMAL)
@@ -923,10 +965,9 @@ void RADIO_PrepareTX(void)
if (!gRxVfoIsActive) if (!gRxVfoIsActive)
{ // use the current RX vfo { // use the current RX vfo
gEeprom.RX_VFO = gEeprom.TX_VFO; gEeprom.RX_VFO = gEeprom.TX_VFO;
gRxVfo = &gEeprom.VfoInfo[gEeprom.TX_VFO]; gRxVfo = gTxVfo;
gRxVfoIsActive = true; gRxVfoIsActive = true;
} }
gCurrentVfo = gRxVfo;
// let the user see that DW is not active // let the user see that DW is not active
gDualWatchActive = false; gDualWatchActive = false;
@@ -948,13 +989,13 @@ void RADIO_PrepareTX(void)
#endif #endif
{ {
#ifndef ENABLE_TX_WHEN_AM #ifndef ENABLE_TX_WHEN_AM
if (gCurrentVfo->AM_mode) if (gCurrentVfo->Modulation != MODULATION_FM)
{ // not allowed to TX if in AM mode { // not allowed to TX if in AM mode
State = VFO_STATE_TX_DISABLE; State = VFO_STATE_TX_DISABLE;
} }
else else
#endif #endif
if (!gSetting_TX_EN || gSerialConfigCountDown_500ms > 0) if (gSerialConfigCountDown_500ms > 0)
{ // TX is disabled or config upload/download in progress { // TX is disabled or config upload/download in progress
State = VFO_STATE_TX_DISABLE; State = VFO_STATE_TX_DISABLE;
} }
@@ -967,7 +1008,7 @@ void RADIO_PrepareTX(void)
if (gBatteryDisplayLevel == 0) if (gBatteryDisplayLevel == 0)
State = VFO_STATE_BAT_LOW; // charge your battery ! State = VFO_STATE_BAT_LOW; // charge your battery !
else else
if (gBatteryDisplayLevel >= 6) if (gBatteryDisplayLevel > 6)
State = VFO_STATE_VOLTAGE_HIGH; // over voltage .. this is being a pain State = VFO_STATE_VOLTAGE_HIGH; // over voltage .. this is being a pain
} }
else else
@@ -1030,23 +1071,17 @@ void RADIO_PrepareTX(void)
void RADIO_EnableCxCSS(void) void RADIO_EnableCxCSS(void)
{ {
switch (gCurrentVfo->pTX->CodeType) switch (gCurrentVfo->pTX->CodeType) {
{ case CODE_TYPE_DIGITAL:
default: case CODE_TYPE_REVERSE_DIGITAL:
case CODE_TYPE_OFF: BK4819_EnableCDCSS();
break; break;
default:
case CODE_TYPE_CONTINUOUS_TONE: BK4819_EnableCTCSS();
BK4819_EnableCTCSS(); break;
SYSTEM_DelayMs(200);
break;
case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL:
BK4819_EnableCDCSS();
SYSTEM_DelayMs(200);
break;
} }
SYSTEM_DelayMs(200);
} }
void RADIO_PrepareCssTX(void) void RADIO_PrepareCssTX(void)
@@ -1076,7 +1111,7 @@ void RADIO_SendEndOfTransmission(void)
{ // end-of-tx { // end-of-tx
if (gEeprom.DTMF_SIDE_TONE) if (gEeprom.DTMF_SIDE_TONE)
{ {
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOn();
gEnableSpeaker = true; gEnableSpeaker = true;
SYSTEM_DelayMs(60); SYSTEM_DelayMs(60);
} }
@@ -1091,7 +1126,7 @@ void RADIO_SendEndOfTransmission(void)
gEeprom.DTMF_CODE_PERSIST_TIME, gEeprom.DTMF_CODE_PERSIST_TIME,
gEeprom.DTMF_CODE_INTERVAL_TIME); gEeprom.DTMF_CODE_INTERVAL_TIME);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); AUDIO_AudioPathOff();
gEnableSpeaker = false; gEnableSpeaker = false;
} }

46
radio.h
View File

@@ -23,13 +23,6 @@
#include "dcs.h" #include "dcs.h"
#include "frequencies.h" #include "frequencies.h"
enum {
MR_CH_BAND_MASK = 0x0F << 0,
MR_CH_COMPAND = 3u << 4, // new
MR_CH_SCANLIST2 = 1u << 6,
MR_CH_SCANLIST1 = 1u << 7
};
enum { enum {
RADIO_CHANNEL_UP = 0x01u, RADIO_CHANNEL_UP = 0x01u,
RADIO_CHANNEL_DOWN = 0xFFu, RADIO_CHANNEL_DOWN = 0xFFu,
@@ -61,6 +54,21 @@ enum VfoState_t
}; };
typedef enum VfoState_t VfoState_t; 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 typedef struct
{ {
uint32_t Frequency; uint32_t Frequency;
@@ -73,7 +81,14 @@ typedef struct VFO_Info_t
{ {
FREQ_Config_t freq_config_RX; FREQ_Config_t freq_config_RX;
FREQ_Config_t freq_config_TX; 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; 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; FREQ_Config_t *pTX;
uint32_t TX_OFFSET_FREQUENCY; uint32_t TX_OFFSET_FREQUENCY;
@@ -108,22 +123,26 @@ typedef struct VFO_Info_t
uint8_t BUSY_CHANNEL_LOCK; uint8_t BUSY_CHANNEL_LOCK;
uint8_t AM_mode; ModulationMode_t Modulation;
uint8_t Compander; uint8_t Compander;
char Name[16]; char Name[16];
} VFO_Info_t; } VFO_Info_t;
// Settings of the main VFO that is selected by the user
// The pointer follows gEeprom.RX_VFO index
extern VFO_Info_t *gTxVfo; 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; 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 VFO_Info_t *gCurrentVfo;
extern DCS_CodeType_t gSelectedCodeType;
extern DCS_CodeType_t gCurrentCodeType; extern DCS_CodeType_t gCurrentCodeType;
extern uint8_t gSelectedCode;
extern STEP_Setting_t gStepSetting;
extern VfoState_t VfoState[2]; extern VfoState_t VfoState[2];
@@ -139,11 +158,12 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0);
void RADIO_ConfigureNOAA(void); void RADIO_ConfigureNOAA(void);
#endif #endif
void RADIO_SetTxParameters(void); void RADIO_SetTxParameters(void);
void RADIO_SetModulation(ModulationMode_t modulation);
void RADIO_SetVfoState(VfoState_t State); void RADIO_SetVfoState(VfoState_t State);
void RADIO_PrepareTX(void); void RADIO_PrepareTX(void);
void RADIO_EnableCxCSS(void); void RADIO_EnableCxCSS(void);
void RADIO_PrepareCssTX(void); void RADIO_PrepareCssTX(void);
void RADIO_SendEndOfTransmission(void); void RADIO_SendEndOfTransmission(void);
#endif #endif

View File

@@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "app/chFrScanner.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h" #include "app/fm.h"
#endif #endif
@@ -77,18 +78,18 @@ void SystickHandler(void)
if (gCurrentFunction == FUNCTION_POWER_SAVE) if (gCurrentFunction == FUNCTION_POWER_SAVE)
DECREMENT_AND_TRIGGER(gPowerSave_10ms, gPowerSaveCountdownExpired); DECREMENT_AND_TRIGGER(gPowerSave_10ms, gPowerSaveCountdownExpired);
if (gScanStateDir == 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) if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_RECEIVE)
DECREMENT_AND_TRIGGER(gDualWatchCountdown_10ms, gScheduleDualWatch); DECREMENT_AND_TRIGGER(gDualWatchCountdown_10ms, gScheduleDualWatch);
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (gScanStateDir == 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 (gIsNoaaMode && gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT)
if (gCurrentFunction != FUNCTION_RECEIVE) if (gCurrentFunction != FUNCTION_RECEIVE)
DECREMENT_AND_TRIGGER(gNOAA_Countdown_10ms, gScheduleNOAA); DECREMENT_AND_TRIGGER(gNOAA_Countdown_10ms, gScheduleNOAA);
#endif #endif
if (gScanStateDir != SCAN_OFF || gCssScanMode == CSS_SCAN_MODE_SCANNING) if (gScanStateDir != SCAN_OFF)
if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT) if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT)
DECREMENT_AND_TRIGGER(gScanPauseDelayIn_10ms, gScheduleScanListen); DECREMENT_AND_TRIGGER(gScanPauseDelayIn_10ms, gScheduleScanListen);

View File

@@ -96,17 +96,18 @@ void SETTINGS_SaveSettings(void)
State[7] = gEeprom.MIC_SENSITIVITY; State[7] = gEeprom.MIC_SENSITIVITY;
EEPROM_WriteBuffer(0x0E70, State); EEPROM_WriteBuffer(0x0E70, State);
State[0] = 0xFF; State[0] = (gEeprom.BACKLIGHT_MIN << 4) + gEeprom.BACKLIGHT_MAX;
State[1] = gEeprom.CHANNEL_DISPLAY_MODE; State[1] = gEeprom.CHANNEL_DISPLAY_MODE;
State[2] = gEeprom.CROSS_BAND_RX_TX; State[2] = gEeprom.CROSS_BAND_RX_TX;
State[3] = gEeprom.BATTERY_SAVE; State[3] = gEeprom.BATTERY_SAVE;
State[4] = gEeprom.DUAL_WATCH; State[4] = gEeprom.DUAL_WATCH;
State[5] = gEeprom.BACKLIGHT; State[5] = gEeprom.BACKLIGHT_TIME;
State[6] = gEeprom.TAIL_NOTE_ELIMINATION; State[6] = gEeprom.TAIL_TONE_ELIMINATION;
State[7] = gEeprom.VFO_OPEN; State[7] = gEeprom.VFO_OPEN;
EEPROM_WriteBuffer(0x0E78, State); EEPROM_WriteBuffer(0x0E78, State);
State[0] = gEeprom.BEEP_CONTROL; State[0] = gEeprom.BEEP_CONTROL;
State[0] |= gEeprom.KEY_M_LONG_PRESS_ACTION << 1;
State[1] = gEeprom.KEY_1_SHORT_PRESS_ACTION; State[1] = gEeprom.KEY_1_SHORT_PRESS_ACTION;
State[2] = gEeprom.KEY_1_LONG_PRESS_ACTION; State[2] = gEeprom.KEY_1_LONG_PRESS_ACTION;
State[3] = gEeprom.KEY_2_SHORT_PRESS_ACTION; State[3] = gEeprom.KEY_2_SHORT_PRESS_ACTION;
@@ -122,11 +123,11 @@ void SETTINGS_SaveSettings(void)
#endif #endif
EEPROM_WriteBuffer(0x0E98, Password); EEPROM_WriteBuffer(0x0E98, Password);
#ifdef ENABLE_VOICE memset(State, 0xFF, sizeof(State));
memset(State, 0xFF, sizeof(State)); #ifdef ENABLE_VOICE
State[0] = gEeprom.VOICE_PROMPT; State[0] = gEeprom.VOICE_PROMPT;
EEPROM_WriteBuffer(0x0EA0, State); EEPROM_WriteBuffer(0x0EA0, State);
#endif #endif
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
State[0] = gEeprom.ALARM_MODE; State[0] = gEeprom.ALARM_MODE;
@@ -136,6 +137,7 @@ void SETTINGS_SaveSettings(void)
State[1] = gEeprom.ROGER; State[1] = gEeprom.ROGER;
State[2] = gEeprom.REPEATER_TAIL_TONE_ELIMINATION; State[2] = gEeprom.REPEATER_TAIL_TONE_ELIMINATION;
State[3] = gEeprom.TX_VFO; State[3] = gEeprom.TX_VFO;
State[4] = gEeprom.BATTERY_TYPE;
EEPROM_WriteBuffer(0x0EA8, State); EEPROM_WriteBuffer(0x0EA8, State);
State[0] = gEeprom.DTMF_SIDE_TONE; State[0] = gEeprom.DTMF_SIDE_TONE;
@@ -172,7 +174,7 @@ void SETTINGS_SaveSettings(void)
State[4] = gSetting_500TX; State[4] = gSetting_500TX;
State[5] = gSetting_350EN; State[5] = gSetting_350EN;
State[6] = gSetting_ScrambleEnable; 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); if (!gSetting_live_DTMF_decoder) State[7] &= ~(1u << 1);
State[7] = (State[7] & ~(3u << 2)) | ((gSetting_battery_text & 3u) << 2); State[7] = (State[7] & ~(3u << 2)) | ((gSetting_battery_text & 3u) << 2);
#ifdef ENABLE_AUDIO_BAR #ifdef ENABLE_AUDIO_BAR
@@ -189,19 +191,19 @@ void SETTINGS_SaveSettings(void)
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode) void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode)
{ {
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(Channel)) if (!IS_NOAA_CHANNEL(Channel))
#endif #endif
{ {
const uint16_t OffsetMR = Channel * 16; const uint16_t OffsetMR = Channel * 16;
uint16_t OffsetVFO = OffsetMR; uint16_t OffsetVFO = OffsetMR;
if (Channel > MR_CHANNEL_LAST) if (!IS_MR_CHANNEL(Channel))
{ // it's a VFO, not a channel { // it's a VFO, not a channel
OffsetVFO = (VFO == 0) ? 0x0C80 : 0x0C90; OffsetVFO = (VFO == 0) ? 0x0C80 : 0x0C90;
OffsetVFO += (Channel - FREQ_CHANNEL_FIRST) * 32; OffsetVFO += (Channel - FREQ_CHANNEL_FIRST) * 32;
} }
if (Mode >= 2 || Channel > MR_CHANNEL_LAST) if (Mode >= 2 || !IS_MR_CHANNEL(Channel))
{ // copy VFO to a channel { // copy VFO to a channel
uint8_t State[8]; uint8_t State[8];
@@ -213,7 +215,7 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
State[0] = pVFO->freq_config_RX.Code; State[0] = pVFO->freq_config_RX.Code;
State[1] = pVFO->freq_config_TX.Code; State[1] = pVFO->freq_config_TX.Code;
State[2] = (pVFO->freq_config_TX.CodeType << 4) | pVFO->freq_config_RX.CodeType; 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 State[4] = 0
| (pVFO->BUSY_CHANNEL_LOCK << 4) | (pVFO->BUSY_CHANNEL_LOCK << 4)
| (pVFO->OUTPUT_POWER << 2) | (pVFO->OUTPUT_POWER << 2)
@@ -226,7 +228,7 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
SETTINGS_UpdateChannel(Channel, pVFO, true); SETTINGS_UpdateChannel(Channel, pVFO, true);
if (Channel <= MR_CHANNEL_LAST) if (IS_MR_CHANNEL(Channel))
{ // it's a memory channel { // it's a memory channel
#ifndef ENABLE_KEEP_MEM_NAME #ifndef ENABLE_KEEP_MEM_NAME
@@ -261,55 +263,45 @@ void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration)
EEPROM_WriteBuffer(0x1F48, buf); EEPROM_WriteBuffer(0x1F48, buf);
} }
void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep) void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep)
{ {
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(Channel)) if (!IS_NOAA_CHANNEL(channel))
#endif #endif
{ {
uint8_t State[8]; uint8_t state[8];
uint8_t Attributes = 0xFF; // default attributes ChannelAttributes_t att = {
uint16_t Offset = 0x0D60 + (Channel & ~7u); .band = 0xf,
.compander = 0,
Attributes &= (uint8_t)(~MR_CH_COMPAND); // default to '0' = compander disabled .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) if (keep) {
{ att.band = pVFO->Band;
Attributes = (pVFO->SCANLIST1_PARTICIPATION << 7) | (pVFO->SCANLIST2_PARTICIPATION << 6) | (pVFO->Compander << 4) | (pVFO->Band << 0); att.scanlist1 = pVFO->SCANLIST1_PARTICIPATION;
if (State[Channel & 7u] == Attributes) att.scanlist2 = pVFO->SCANLIST2_PARTICIPATION;
att.compander = pVFO->Compander;
if (state[channel & 7u] == att.__val)
return; // no change in the attributes 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; if (IS_MR_CHANNEL(channel)) { // it's a memory channel
const uint16_t OffsetMR = channel * 16;
// #ifndef ENABLE_KEEP_MEM_NAME if (!keep) {
if (Channel <= MR_CHANNEL_LAST) // clear/reset the channel name
{ // it's a memory channel memset(&state, 0x00, sizeof(state));
EEPROM_WriteBuffer(0x0F50 + OffsetMR, state);
const uint16_t OffsetMR = Channel * 16; EEPROM_WriteBuffer(0x0F58 + OffsetMR, state);
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);
// }
} }
// #endif }
} }
} }

View File

@@ -21,7 +21,9 @@
#include <stdint.h> #include <stdint.h>
#include "frequencies.h" #include "frequencies.h"
#include <helper/battery.h>
#include "radio.h" #include "radio.h"
#include <driver/backlight.h>
enum POWER_OnDisplayMode_t { enum POWER_OnDisplayMode_t {
POWER_ON_DISPLAY_MODE_FULL_SCREEN = 0, POWER_ON_DISPLAY_MODE_FULL_SCREEN = 0,
@@ -32,12 +34,15 @@ enum POWER_OnDisplayMode_t {
typedef enum POWER_OnDisplayMode_t POWER_OnDisplayMode_t; typedef enum POWER_OnDisplayMode_t POWER_OnDisplayMode_t;
enum { enum {
F_LOCK_OFF = 0, F_LOCK_DEF, //all default frequencies + configurable
F_LOCK_FCC, F_LOCK_FCC,
F_LOCK_CE, F_LOCK_CE,
F_LOCK_GB, F_LOCK_GB,
F_LOCK_430, 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 { enum {
@@ -80,6 +85,13 @@ enum {
ACTION_OPT_ALARM, ACTION_OPT_ALARM,
ACTION_OPT_FM, ACTION_OPT_FM,
ACTION_OPT_1750, 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 ACTION_OPT_LEN
}; };
@@ -115,13 +127,19 @@ enum CHANNEL_DisplayMode_t {
typedef enum CHANNEL_DisplayMode_t CHANNEL_DisplayMode_t; typedef enum CHANNEL_DisplayMode_t CHANNEL_DisplayMode_t;
typedef struct { typedef struct {
uint8_t ScreenChannel[2]; uint8_t ScreenChannel[2]; // current channels set in the radio (memory or frequency channels)
uint8_t FreqChannel[2]; uint8_t FreqChannel[2]; // last frequency channels used
uint8_t MrChannel[2]; uint8_t MrChannel[2]; // last memory channels used
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
uint8_t NoaaChannel[2]; uint8_t NoaaChannel[2];
#endif #endif
// 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; uint8_t RX_VFO;
// The main VFO index (0-upper/1-lower) selected by the user
//
uint8_t TX_VFO; uint8_t TX_VFO;
uint8_t field7_0xa; uint8_t field7_0xa;
@@ -146,12 +164,12 @@ typedef struct {
#endif #endif
bool BEEP_CONTROL; bool BEEP_CONTROL;
uint8_t CHANNEL_DISPLAY_MODE; uint8_t CHANNEL_DISPLAY_MODE;
bool TAIL_NOTE_ELIMINATION; bool TAIL_TONE_ELIMINATION;
bool VFO_OPEN; bool VFO_OPEN;
uint8_t DUAL_WATCH; uint8_t DUAL_WATCH;
uint8_t CROSS_BAND_RX_TX; uint8_t CROSS_BAND_RX_TX;
uint8_t BATTERY_SAVE; uint8_t BATTERY_SAVE;
uint8_t BACKLIGHT; uint8_t BACKLIGHT_TIME;
uint8_t SCAN_RESUME_MODE; uint8_t SCAN_RESUME_MODE;
uint8_t SCAN_LIST_DEFAULT; uint8_t SCAN_LIST_DEFAULT;
bool SCAN_LIST_ENABLED[2]; bool SCAN_LIST_ENABLED[2];
@@ -218,7 +236,13 @@ typedef struct {
uint8_t field78_0x96; uint8_t field78_0x96;
uint8_t field79_0x97; uint8_t field79_0x97;
uint8_t _pad[1]; 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; } EEPROM_Config_t;
extern EEPROM_Config_t gEeprom; extern EEPROM_Config_t gEeprom;
@@ -230,6 +254,6 @@ void SETTINGS_SaveVfoIndices(void);
void SETTINGS_SaveSettings(void); void SETTINGS_SaveSettings(void);
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode); void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode);
void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration); void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration);
void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep); void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep);
#endif #endif

View File

@@ -44,12 +44,19 @@ void UI_DisplayAircopy(void)
if (gInputBoxIndex == 0) if (gInputBoxIndex == 0)
{ {
NUMBER_ToDigits(gRxVfo->freq_config_RX.Frequency, String); uint32_t frequency = gRxVfo->freq_config_RX.Frequency;
UI_DisplayFrequency(String, 16, 2, 0, 0); sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000);
UI_DisplaySmallDigits(2, String + 6, 97, 3, true); // 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)); memset(String, 0, sizeof(String));
if (gAirCopyIsSendMode == 0) if (gAirCopyIsSendMode == 0)

View File

@@ -30,10 +30,10 @@ void UI_DrawBattery(uint8_t* bitmap, uint8_t level, uint8_t blink)
else else
{ {
memmove(bitmap, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1)); memmove(bitmap, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
if (level > 1) if (level > 2)
{ {
unsigned int i; unsigned int i;
uint8_t bars = level - 1; uint8_t bars = level - 2;
if (bars > 4) if (bars > 4)
bars = 4; bars = 4;
for (i = 0; i < bars; i++) for (i = 0; i < bars; i++)

View File

@@ -90,11 +90,14 @@ void UI_DisplayFM(void)
{ {
if (gInputBoxIndex == 0) if (gInputBoxIndex == 0)
{ {
NUMBER_ToDigits(gEeprom.FM_FrequencyPlaying * 10000, String); sprintf(String, "%3d.%d", gEeprom.FM_FrequencyPlaying / 10, gEeprom.FM_FrequencyPlaying % 10);
UI_DisplayFrequency(String, 23, 4, false, true); 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(); ST7565_BlitFullScreen();
return; return;

View File

@@ -21,6 +21,7 @@
#include "font.h" #include "font.h"
#include "ui/helper.h" #include "ui/helper.h"
#include "ui/inputbox.h" #include "ui/inputbox.h"
#include "misc.h"
#ifndef ARRAY_SIZE #ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0])) #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++) 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 index = pString[i] - ' ' - 1;
const unsigned int ofs = (unsigned int)Start + (i * Width); memmove(gFrameBuffer[Line + 0] + ofs, &gFontBig[index][0], 7);
memmove(gFrameBuffer[Line + 0] + ofs, &gFontBig[index][0], 8); memmove(gFrameBuffer[Line + 1] + ofs, &gFontBig[index][7], 7);
memmove(gFrameBuffer[Line + 1] + ofs, &gFontBig[index][8], 7);
} }
} }
} }
@@ -95,9 +96,9 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_
uint8_t *pFb = gFrameBuffer[Line] + Start; uint8_t *pFb = gFrameBuffer[Line] + Start;
for (i = 0; i < Length; i++) 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)) if (index < ARRAY_SIZE(gFontSmall))
memmove(pFb + (i * char_spacing) + 1, &gFontSmall[index], char_width); memmove(pFb + (i * char_spacing) + 1, &gFontSmall[index], char_width);
} }
@@ -118,9 +119,9 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_
uint8_t *pFb = gFrameBuffer[Line] + Start; uint8_t *pFb = gFrameBuffer[Line] + Start;
for (i = 0; i < Length; i++) 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)) if (index < ARRAY_SIZE(gFontSmallBold))
memmove(pFb + (i * char_spacing) + 1, &gFontSmallBold[index], char_width); memmove(pFb + (i * char_spacing) + 1, &gFontSmallBold[index], char_width);
} }
@@ -135,126 +136,115 @@ void UI_PrintStringSmallBuffer(const char *pString, uint8_t *buffer)
const unsigned int char_spacing = char_width + 1; const unsigned int char_spacing = char_width + 1;
for (i = 0; i < strlen(pString); i++) 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)) if (index < ARRAY_SIZE(gFontSmall))
memmove(buffer + (i * char_spacing) + 1, &gFontSmall[index], char_width); 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; const unsigned int char_width = 13;
uint8_t *pFb0 = gFrameBuffer[Y] + X; uint8_t *pFb0 = gFrameBuffer[Y] + X;
uint8_t *pFb1 = pFb0 + 128; uint8_t *pFb1 = pFb0 + 128;
bool bCanDisplay = false; bool bCanDisplay = false;
unsigned int i = 0;
uint8_t len = strlen(string);
// MHz for(int i = 0; i < len; i++) {
while (i < 3) char c = string[i];
{ if(c=='-') c = '9' + 1;
const unsigned int Digit = pDigits[i++]; if (bCanDisplay || c != ' ')
if (bDisplayLeadingZero || bCanDisplay || Digit > 0)
{ {
bCanDisplay = true; bCanDisplay = true;
memmove(pFb0, gFontBigDigits[Digit], char_width); if(c>='0' && c<='9' + 1) {
memmove(pFb1, gFontBigDigits[Digit] + char_width, char_width); 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 else if (center) {
if (bFlag)
{
pFb0 -= 6; pFb0 -= 6;
pFb1 -= 6; pFb1 -= 6;
} }
pFb0 += char_width; pFb0 += char_width;
pFb1 += char_width; pFb1 += char_width;
} }
}
// decimal point void UI_DrawPixelBuffer(uint8_t (*buffer)[128], uint8_t x, uint8_t y, bool black)
*pFb1 = 0x60; pFb0++; pFb1++; {
*pFb1 = 0x60; pFb0++; pFb1++; if(black)
*pFb1 = 0x60; pFb0++; pFb1++; buffer[y/8][x] |= 1 << (y%8);
else
// kHz buffer[y/8][x] &= ~(1 << (y%8));
while (i < 6) }
{
const unsigned int Digit = pDigits[i++]; static void sort(int16_t *a, int16_t *b)
memmove(pFb0, gFontBigDigits[Digit], char_width); {
memmove(pFb1, gFontBigDigits[Digit] + char_width, char_width); if(*a > *b) {
pFb0 += char_width; int16_t t = *a;
pFb1 += char_width; *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]); if(x2==x1) {
const unsigned int spacing = 1 + char_width; sort(&y1, &y2);
uint8_t *pFb = gFrameBuffer[Y] + X; for(int16_t i = y1; i <= y2; i++) {
bool bCanDisplay = false; UI_DrawPixelBuffer(buffer, x1, i, black);
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;
} }
} } else {
const int multipl = 1000;
int a = (y2-y1)*multipl / (x2-x1);
int b = y1 - a * x1 / multipl;
// decimal point sort(&x1, &x2);
pFb++; for(int i = x1; i<= x2; i++)
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)
{ {
#if 0 UI_DrawPixelBuffer(buffer, i, i*a/multipl +b, black);
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;
} }
} }
} }
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); void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line);
#endif #endif
void UI_PrintStringSmallBuffer(const char *pString, uint8_t *buffer); 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_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center);
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);
#endif #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,6 +19,7 @@
#include "ui/inputbox.h" #include "ui/inputbox.h"
char gInputBox[8]; char gInputBox[8];
char inputBoxAscii[9];
uint8_t gInputBoxIndex; uint8_t gInputBoxIndex;
void INPUTBOX_Append(const KEY_Code_t Digit) void INPUTBOX_Append(const KEY_Code_t Digit)
@@ -33,3 +34,11 @@ void INPUTBOX_Append(const KEY_Code_t Digit)
gInputBox[gInputBoxIndex++] = (char)(Digit - KEY_0); 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

@@ -25,6 +25,7 @@ extern char gInputBox[8];
extern uint8_t gInputBoxIndex; extern uint8_t gInputBoxIndex;
void INPUTBOX_Append(const KEY_Code_t Digit); void INPUTBOX_Append(const KEY_Code_t Digit);
const char* INPUTBOX_GetAscii();
#endif #endif

View File

@@ -102,10 +102,9 @@ void UI_DisplayLock(void)
uint32_t Password; uint32_t Password;
gInputBoxIndex = 0; gInputBoxIndex = 0;
Password = StrToUL(INPUTBOX_GetAscii());
NUMBER_Get(gInputBox, &Password); if ((gEeprom.POWER_ON_PASSWORD) == Password)
if ((gEeprom.POWER_ON_PASSWORD * 100) == Password)
{ {
AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL); AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL);
return; return;

700
ui/main.c
View File

@@ -40,230 +40,205 @@ center_line_t center_line = CENTER_LINE_NONE;
// *************************************************************************** // ***************************************************************************
void UI_drawBars(uint8_t *p, const unsigned int level) static void DrawSmallAntennaAndBars(uint8_t *p, unsigned int level)
{ {
switch (level) if(level>6)
{ level = 6;
default:
case 7: memmove(p + 20, BITMAP_AntennaLevel6, sizeof(BITMAP_AntennaLevel6)); [[fallthrough]]; memcpy(p, BITMAP_Antenna, ARRAY_SIZE(BITMAP_Antenna));
case 6: memmove(p + 17, BITMAP_AntennaLevel5, sizeof(BITMAP_AntennaLevel5)); [[fallthrough]];
case 5: memmove(p + 14, BITMAP_AntennaLevel4, sizeof(BITMAP_AntennaLevel4)); [[fallthrough]]; for(uint8_t i = 1; i <= level; i++) {
case 4: memmove(p + 11, BITMAP_AntennaLevel3, sizeof(BITMAP_AntennaLevel3)); [[fallthrough]]; char bar = (0xff << (6-i)) & 0x7F;
case 3: memmove(p + 8, BITMAP_AntennaLevel2, sizeof(BITMAP_AntennaLevel2)); [[fallthrough]]; memset(p + 2 + i*3, bar, 2);
case 2: memmove(p + 5, BITMAP_AntennaLevel1, sizeof(BITMAP_AntennaLevel1)); [[fallthrough]];
case 1: memmove(p + 0, BITMAP_Antenna, sizeof(BITMAP_Antenna)); break;
case 0: memset( p + 0, 0, sizeof(BITMAP_Antenna)); break;
} }
} }
#if defined ENABLE_AUDIO_BAR || defined ENABLE_RSSI_BAR
static void DrawLevelBar(uint8_t xpos, uint8_t line, uint8_t level)
{
const char hollowBar[] = {
0b01111111,
0b01000001,
0b01000001,
0b01111111
};
uint8_t *p_line = gFrameBuffer[line];
level = MIN(level, 13);
for(uint8_t i = 0; i < level; i++) {
if(i < 9) {
for(uint8_t j = 0; j < 4; j++)
p_line[xpos + i * 5 + j] = (~(0x7F >> (i+1))) & 0x7F;
}
else {
memcpy(p_line + (xpos + i * 5), &hollowBar, ARRAY_SIZE(hollowBar));
}
}
}
#endif
#ifdef ENABLE_AUDIO_BAR #ifdef ENABLE_AUDIO_BAR
unsigned int sqrt16(unsigned int value) unsigned int sqrt16(unsigned int value)
{ // return square root of 'value' { // return square root of 'value'
unsigned int shift = 16; // number of bits supplied in 'value' .. 2 ~ 32 unsigned int shift = 16; // number of bits supplied in 'value' .. 2 ~ 32
unsigned int bit = 1u << --shift; unsigned int bit = 1u << --shift;
unsigned int sqrti = 0; unsigned int sqrti = 0;
while (bit) while (bit)
{
const unsigned int temp = ((sqrti << 1) | bit) << shift--;
if (value >= temp)
{
value -= temp;
sqrti |= bit;
}
bit >>= 1;
}
return sqrti;
}
void UI_DisplayAudioBar(void)
{ {
if (gSetting_mic_bar) const unsigned int temp = ((sqrti << 1) | bit) << shift--;
{ if (value >= temp) {
const unsigned int line = 3; value -= temp;
const unsigned int bar_x = 2; sqrti |= bit;
const unsigned int bar_width = LCD_WIDTH - 2 - bar_x; }
unsigned int i; bit >>= 1;
}
return sqrti;
}
if (gCurrentFunction != FUNCTION_TRANSMIT || void UI_DisplayAudioBar(void)
gScreenToDisplay != DISPLAY_MAIN || {
gDTMF_CallState != DTMF_CALL_STATE_NONE) if (gSetting_mic_bar)
{ {
return; // screen is in use if(gLowBattery && !gLowBatteryConfirmed)
} return;
const unsigned int line = 3;
if (gCurrentFunction != FUNCTION_TRANSMIT ||
gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE)
{
return; // screen is in use
}
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
if (gAlarmState != ALARM_STATE_OFF) if (gAlarmState != ALARM_STATE_OFF)
return; return;
#endif #endif
const unsigned int voice_amp = BK4819_GetVoiceAmplitudeOut(); // 15:0 const unsigned int voice_amp = BK4819_GetVoiceAmplitudeOut(); // 15:0
// make non-linear to make more sensitive at low values
const unsigned int level = voice_amp * 8;
const unsigned int sqrt_level = sqrt16((level < 65535) ? level : 65535);
const unsigned int len = (sqrt_level <= bar_width) ? sqrt_level : bar_width;
uint8_t *p_line = gFrameBuffer[line]; // make non-linear to make more sensitive at low values
const unsigned int level = MIN(voice_amp * 8, 65535u);
memset(p_line, 0, LCD_WIDTH); const unsigned int sqrt_level = MIN(sqrt16(level), 124u);
uint8_t bars = 13 * sqrt_level / 124;
for (i = 0; i < bar_width; i++)
p_line[bar_x + i] = (i > len) ? ((i & 1) == 0) ? 0x41 : 0x00 : ((i & 1) == 0) ? 0x7f : 0x3e;
if (gCurrentFunction == FUNCTION_TRANSMIT) uint8_t *p_line = gFrameBuffer[line];
ST7565_BlitFullScreen(); memset(p_line, 0, LCD_WIDTH);
}
DrawLevelBar(62, line, bars);
if (gCurrentFunction == FUNCTION_TRANSMIT)
ST7565_BlitFullScreen();
} }
}
#endif #endif
static void DisplayRSSIBar(const int16_t rssi, const bool now)
{
#if defined(ENABLE_RSSI_BAR) #if defined(ENABLE_RSSI_BAR)
void UI_DisplayRSSIBar(const int16_t rssi, const bool now)
{
// const int16_t s0_dBm = -127; // S0 .. base level
const int16_t s0_dBm = -147; // S0 .. base level
const int16_t s9_dBm = s0_dBm + (6 * 9); // S9 .. 6dB/S-Point
const int16_t bar_max_dBm = s9_dBm + 30; // S9+30dB
// const int16_t bar_min_dBm = s0_dBm + (6 * 0); // S0
const int16_t bar_min_dBm = s0_dBm + (6 * 4); // S4
// ************
if (center_line == CENTER_LINE_RSSI) {
const unsigned int txt_width = 7 * 8; // 8 text chars const unsigned int txt_width = 7 * 8; // 8 text chars
const unsigned int bar_x = 2 + txt_width + 4; // X coord of bar graph const unsigned int bar_x = 2 + txt_width + 4; // X coord of bar graph
const unsigned int bar_width = LCD_WIDTH - 1 - bar_x;
const int16_t rssi_dBm = (rssi / 2) - 160;
const int16_t clamped_dBm = (rssi_dBm <= bar_min_dBm) ? bar_min_dBm : (rssi_dBm >= bar_max_dBm) ? bar_max_dBm : rssi_dBm;
const unsigned int bar_range_dB = bar_max_dBm - bar_min_dBm;
const unsigned int len = ((clamped_dBm - bar_min_dBm) * bar_width) / bar_range_dB;
const unsigned int line = 3; const unsigned int line = 3;
uint8_t *p_line = gFrameBuffer[line]; uint8_t *p_line = gFrameBuffer[line];
char str[16];
char s[16]; const char plus[] = {
unsigned int i; 0b00011000,
0b00011000,
0b01111110,
0b01111110,
0b01111110,
0b00011000,
0b00011000,
};
if (gEeprom.KEY_LOCK && gKeypadLocked > 0) if (gEeprom.KEY_LOCK && gKeypadLocked > 0)
return; // display is in use return; // display is in use
if (gCurrentFunction == FUNCTION_TRANSMIT || if (gCurrentFunction == FUNCTION_TRANSMIT ||
gScreenToDisplay != DISPLAY_MAIN || gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE) gDTMF_CallState != DTMF_CALL_STATE_NONE)
return; // display is in use return; // display is in use
if (now) if (now)
memset(p_line, 0, LCD_WIDTH); memset(p_line, 0, LCD_WIDTH);
const int8_t dBmCorrTable[7] = {
-15, // band 1
-15, // band 2
-25, // band 3
-20, // band 4
-20, // band 5
-20, // band 6
-7 // band 7
};
if (rssi_dBm >= (s9_dBm + 6)) const int16_t s0_dBm = -147; // S0 .. base level
{ // S9+XXdB, 1dB increment const int16_t rssi_dBm = (rssi / 2) - 160 + dBmCorrTable[gRxVfo->Band];
const char *fmt[] = {"%3d 9+%u ", "%3d 9+%2u "};
const unsigned int s9_dB = ((rssi_dBm - s9_dBm) <= 99) ? rssi_dBm - s9_dBm : 99; const uint8_t s_level = MIN(MAX((rssi_dBm - s0_dBm) / 6, 0), 9); // S0 - S9
sprintf(s, (s9_dB < 10) ? fmt[0] : fmt[1], rssi_dBm, s9_dB); uint8_t overS9dBm = MIN(MAX(rssi_dBm - (s0_dBm + 9*6), 0), 99);
uint8_t overS9Bars = MIN(overS9dBm/10, 4);
if(overS9Bars == 0) {
sprintf(str, "% 4d S%d", rssi_dBm, s_level);
} }
else else {
{ // S0 ~ S9, 6dB per S-point sprintf(str, "% 4d %2d", rssi_dBm, overS9dBm);
const unsigned int s_level = (rssi_dBm >= s0_dBm) ? (rssi_dBm - s0_dBm) / 6 : 0; memcpy(p_line + 2 + 7*5, &plus, ARRAY_SIZE(plus));
sprintf(s, "%4d S%u ", rssi_dBm, s_level);
} }
UI_PrintStringSmall(s, 2, 0, line);
#if 1 UI_PrintStringSmall(str, 2, 0, line);
// solid bar
for (i = 0; i < bar_width; i++)
p_line[bar_x + i] = (i > len) ? ((i & 1) == 0) ? 0x41 : 0x00 : ((i & 1) == 0) ? 0x7f : 0x3e;
#else
// knuled bar
for (i = 0; i < bar_width; i += 2)
p_line[bar_x + i] = (i <= len) ? 0x7f : 0x41;
#endif
if (now) DrawLevelBar(bar_x, line, s_level + overS9Bars);
ST7565_BlitFullScreen();
} }
#else
uint8_t Level;
if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][3]) {
Level = 6;
} else if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][2]) {
Level = 4;
} else if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][1]) {
Level = 2;
} else if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][0]) {
Level = 1;
} else {
Level = 0;
}
uint8_t *pLine = (gEeprom.RX_VFO == 0)? gFrameBuffer[2] : gFrameBuffer[6];
if (now)
memset(pLine, 0, 23);
DrawSmallAntennaAndBars(pLine, Level);
#endif #endif
if (now)
ST7565_BlitFullScreen();
}
void UI_UpdateRSSI(const int16_t rssi, const int vfo) void UI_UpdateRSSI(const int16_t rssi, const int vfo)
{ {
#ifdef ENABLE_RSSI_BAR (void)vfo; // unused
// optional larger RSSI dBm, S-point and bar level
(void)vfo; // unused if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING)
{
// optional larger RSSI dBm, S-point and bar level DisplayRSSIBar(rssi, true);
}
if (center_line != CENTER_LINE_RSSI)
return;
if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING)
{
UI_DisplayRSSIBar(rssi, true);
}
#else
// original little RS bars
// const int16_t dBm = (rssi / 2) - 160;
const uint8_t Line = (vfo == 0) ? 3 : 7;
uint8_t *p_line = gFrameBuffer[Line - 1];
const unsigned int band = gRxVfo->Band;
const int16_t level0 = gEEPROM_RSSI_CALIB[band][0];
const int16_t level1 = gEEPROM_RSSI_CALIB[band][1];
const int16_t level2 = gEEPROM_RSSI_CALIB[band][2];
const int16_t level3 = gEEPROM_RSSI_CALIB[band][3];
const int16_t level01 = (level0 + level1) / 2;
const int16_t level12 = (level1 + level2) / 2;
const int16_t level23 = (level2 + level3) / 2;
gVFO_RSSI[vfo] = rssi;
uint8_t rssi_level = 0;
if (rssi >= level3) rssi_level = 7;
else
if (rssi >= level23) rssi_level = 6;
else
if (rssi >= level2) rssi_level = 5;
else
if (rssi >= level12) rssi_level = 4;
else
if (rssi >= level1) rssi_level = 3;
else
if (rssi >= level01) rssi_level = 2;
else
if (rssi >= level0) rssi_level = 1;
if (gVFO_RSSI_bar_level[vfo] == rssi_level)
return;
gVFO_RSSI_bar_level[vfo] = rssi_level;
// **********************************************************
if (gEeprom.KEY_LOCK && gKeypadLocked > 0)
return; // display is in use
if (gCurrentFunction == FUNCTION_TRANSMIT || gScreenToDisplay != DISPLAY_MAIN)
return; // display is in use
p_line = gFrameBuffer[Line - 1];
memset(p_line, 0, 23);
// untested !!!
if (rssi_level == 0)
p_line = NULL;
else
UI_drawBars(p_line, rssi_level);
ST7565_DrawLine(0, Line, 23, p_line);
#endif
} }
// *************************************************************************** // ***************************************************************************
@@ -272,20 +247,20 @@ void UI_DisplayMain(void)
{ {
const unsigned int line0 = 0; // text screen line const unsigned int line0 = 0; // text screen line
const unsigned int line1 = 4; const unsigned int line1 = 4;
char String[16]; char String[22];
unsigned int vfo_num; unsigned int vfo_num;
center_line = CENTER_LINE_NONE; center_line = CENTER_LINE_NONE;
// #ifdef SINGLE_VFO_CHAN
// const bool single_vfo = (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? true : false;
// #else
const bool single_vfo = false;
// #endif
// clear the screen // clear the screen
memset(gFrameBuffer, 0, sizeof(gFrameBuffer)); memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
if(gLowBattery && !gLowBatteryConfirmed) {
UI_DisplayPopup("LOW BATTERY");
ST7565_BlitFullScreen();
return;
}
if (gEeprom.KEY_LOCK && gKeypadLocked > 0) if (gEeprom.KEY_LOCK && gKeypadLocked > 0)
{ // tell user how to unlock the keyboard { // tell user how to unlock the keyboard
UI_PrintString("Long press #", 0, LCD_WIDTH, 1, 8); UI_PrintString("Long press #", 0, LCD_WIDTH, 1, 8);
@@ -293,24 +268,18 @@ void UI_DisplayMain(void)
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
return; return;
} }
unsigned int activeTxVFO = (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF && gRxVfoIsActive) ? gEeprom.RX_VFO : gEeprom.TX_VFO; unsigned int activeTxVFO = gRxVfoIsActive ? gEeprom.RX_VFO : gEeprom.TX_VFO;
for (vfo_num = 0; vfo_num < 2; vfo_num++) for (vfo_num = 0; vfo_num < 2; vfo_num++)
{ {
const unsigned int line = (vfo_num == 0) ? line0 : line1; const unsigned int line = (vfo_num == 0) ? line0 : line1;
const bool isTxVFO = (vfo_num == gEeprom.TX_VFO); const bool isMainVFO = (vfo_num == gEeprom.TX_VFO);
uint8_t *p_line0 = gFrameBuffer[line + 0]; uint8_t *p_line0 = gFrameBuffer[line + 0];
uint8_t *p_line1 = gFrameBuffer[line + 1]; uint8_t *p_line1 = gFrameBuffer[line + 1];
unsigned int mode = 0; unsigned int mode = 0;
if (single_vfo) if (activeTxVFO != vfo_num) // this is not active TX VFO
{ // we're in single VFO mode - screen is dedicated to just one VFO
if (!isTxVFO)
continue; // skip the unused vfo
}
if (activeTxVFO != vfo_num)
{ {
if (gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_IsTx || gDTMF_InputMode) if (gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_IsTx || gDTMF_InputMode)
{ // show DTMF stuff { // show DTMF stuff
@@ -355,12 +324,12 @@ void UI_DisplayMain(void)
} }
// highlight the selected/used VFO with a marker // highlight the selected/used VFO with a marker
if (!single_vfo && isTxVFO) if (isMainVFO)
memmove(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default)); memmove(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default));
} }
else if (!single_vfo) else // active TX VFO
{ // highlight the selected/used VFO with a marker { // highlight the selected/used VFO with a marker
if (isTxVFO) if (isMainVFO)
memmove(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default)); memmove(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default));
else else
memmove(p_line0 + 0, BITMAP_VFO_NotDefault, sizeof(BITMAP_VFO_NotDefault)); memmove(p_line0 + 0, BITMAP_VFO_NotDefault, sizeof(BITMAP_VFO_NotDefault));
@@ -369,21 +338,20 @@ void UI_DisplayMain(void)
if (gCurrentFunction == FUNCTION_TRANSMIT) if (gCurrentFunction == FUNCTION_TRANSMIT)
{ // transmitting { // transmitting
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
if (gAlarmState == ALARM_STATE_ALARM) if (gAlarmState == ALARM_STATE_ALARM)
mode = 2; mode = 2;
else else
#endif #endif
{ {
activeTxVFO = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
if (activeTxVFO == vfo_num) if (activeTxVFO == vfo_num)
{ // show the TX symbol { // show the TX symbol
mode = 1; mode = 1;
#ifdef ENABLE_SMALL_BOLD #ifdef ENABLE_SMALL_BOLD
UI_PrintStringSmallBold("TX", 14, 0, line); UI_PrintStringSmallBold("TX", 14, 0, line);
#else #else
UI_PrintStringSmall("TX", 14, 0, line); UI_PrintStringSmall("TX", 14, 0, line);
#endif #endif
} }
} }
} }
@@ -395,61 +363,59 @@ void UI_DisplayMain(void)
gCurrentFunction == FUNCTION_INCOMING) && gCurrentFunction == FUNCTION_INCOMING) &&
gEeprom.RX_VFO == vfo_num) gEeprom.RX_VFO == vfo_num)
{ {
#ifdef ENABLE_SMALL_BOLD #ifdef ENABLE_SMALL_BOLD
UI_PrintStringSmallBold("RX", 14, 0, line); UI_PrintStringSmallBold("RX", 14, 0, line);
#else #else
UI_PrintStringSmall("RX", 14, 0, line); UI_PrintStringSmall("RX", 14, 0, line);
#endif #endif
} }
} }
if (gEeprom.ScreenChannel[vfo_num] <= MR_CHANNEL_LAST) if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num]))
{ // channel mode { // channel mode
const unsigned int x = 2; const unsigned int x = 2;
const bool inputting = (gInputBoxIndex == 0 || gEeprom.TX_VFO != vfo_num) ? false : true; const bool inputting = (gInputBoxIndex == 0 || gEeprom.TX_VFO != vfo_num) ? false : true;
if (!inputting) if (!inputting)
NUMBER_ToDigits(gEeprom.ScreenChannel[vfo_num] + 1, String); // show the memory channel number sprintf(String, "M%u", gEeprom.ScreenChannel[vfo_num] + 1);
else else
memmove(String + 5, gInputBox, 3); // show the input text sprintf(String, "M%.3s", INPUTBOX_GetAscii()); // show the input text
UI_PrintStringSmall("M", x, 0, line + 1);
UI_DisplaySmallDigits(3, String + 5, x + 7, line + 1, inputting);
}
else
if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]))
{ // frequency mode
// show the frequency band number
const unsigned int x = 2; // was 14
// sprintf(String, "FB%u", 1 + gEeprom.ScreenChannel[vfo_num] - FREQ_CHANNEL_FIRST);
sprintf(String, "VFO%u", 1 + gEeprom.ScreenChannel[vfo_num] - FREQ_CHANNEL_FIRST);
UI_PrintStringSmall(String, x, 0, line + 1); UI_PrintStringSmall(String, x, 0, line + 1);
} }
#ifdef ENABLE_NOAA else if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]))
else { // frequency mode
{ // show the frequency band number
if (gInputBoxIndex == 0 || gEeprom.TX_VFO != vfo_num) const unsigned int x = 2;
{ // channel number char * buf = gEeprom.VfoInfo[vfo_num].pRX->Frequency < 100000000 ? "" : "+";
sprintf(String, "N%u", 1 + gEeprom.ScreenChannel[vfo_num] - NOAA_CHANNEL_FIRST); sprintf(String, "F%u%s", 1 + gEeprom.ScreenChannel[vfo_num] - FREQ_CHANNEL_FIRST, buf);
} UI_PrintStringSmall(String, x, 0, line + 1);
else }
{ // user entering channel number #ifdef ENABLE_NOAA
sprintf(String, "N%u%u", '0' + gInputBox[0], '0' + gInputBox[1]); else
} {
UI_PrintStringSmall(String, 7, 0, line + 1); if (gInputBoxIndex == 0 || gEeprom.TX_VFO != vfo_num)
{ // channel number
sprintf(String, "N%u", 1 + gEeprom.ScreenChannel[vfo_num] - NOAA_CHANNEL_FIRST);
} }
#endif else
{ // user entering channel number
sprintf(String, "N%u%u", '0' + gInputBox[0], '0' + gInputBox[1]);
}
UI_PrintStringSmall(String, 7, 0, line + 1);
}
#endif
// ************ // ************
unsigned int state = VfoState[vfo_num]; unsigned int state = VfoState[vfo_num];
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
if (gCurrentFunction == FUNCTION_TRANSMIT && gAlarmState == ALARM_STATE_ALARM) if (gCurrentFunction == FUNCTION_TRANSMIT && gAlarmState == ALARM_STATE_ALARM) {
{ if (activeTxVFO == vfo_num)
uint8_t channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO; state = VFO_STATE_ALARM;
if (channel == vfo_num) }
state = VFO_STATE_ALARM; #endif
}
#endif uint32_t frequency = gEeprom.VfoInfo[vfo_num].pRX->Frequency;
if (state != VFO_STATE_NORMAL) if (state != VFO_STATE_NORMAL)
{ {
@@ -457,56 +423,73 @@ void UI_DisplayMain(void)
if (state < ARRAY_SIZE(state_list)) if (state < ARRAY_SIZE(state_list))
UI_PrintString(state_list[state], 31, 0, line, 8); UI_PrintString(state_list[state], 31, 0, line, 8);
} }
else else if (gInputBoxIndex > 0 && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]) && gEeprom.TX_VFO == vfo_num)
if (gInputBoxIndex > 0 && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]) && gEeprom.TX_VFO == vfo_num)
{ // user entering a frequency { // user entering a frequency
UI_DisplayFrequency(gInputBox, 32, line, true, false); const char * ascii = INPUTBOX_GetAscii();
bool isGigaF = frequency>=100000000;
sprintf(String, "%.*s.%.3s", 3 + isGigaF, ascii, ascii + 3 + isGigaF);
#ifdef ENABLE_BIG_FREQ
if(!isGigaF) {
// show the remaining 2 small frequency digits
UI_PrintStringSmall(String + 7, 113, 0, line + 1);
String[7] = 0;
// show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false);
}
else
#endif
{
// show the frequency in the main font
UI_PrintString(String, 32, 0, line, 8);
}
// center_line = CENTER_LINE_IN_USE; continue;
} }
else else
{ {
uint32_t frequency = gEeprom.VfoInfo[vfo_num].pRX->Frequency;
if (gCurrentFunction == FUNCTION_TRANSMIT) if (gCurrentFunction == FUNCTION_TRANSMIT)
{ // transmitting { // transmitting
activeTxVFO = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
if (activeTxVFO == vfo_num) if (activeTxVFO == vfo_num)
frequency = gEeprom.VfoInfo[vfo_num].pTX->Frequency; frequency = gEeprom.VfoInfo[vfo_num].pTX->Frequency;
} }
if (gEeprom.ScreenChannel[vfo_num] <= MR_CHANNEL_LAST) if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num]))
{ // it's a channel { // it's a channel
// show the channel symbols // show the scan list assigment symbols
const uint8_t attributes = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
if (attributes & MR_CH_SCANLIST1) if (att.scanlist1)
memmove(p_line0 + 113, BITMAP_ScanList1, sizeof(BITMAP_ScanList1)); memmove(p_line0 + 113, BITMAP_ScanList1, sizeof(BITMAP_ScanList1));
if (attributes & MR_CH_SCANLIST2) if (att.scanlist2)
memmove(p_line0 + 120, BITMAP_ScanList2, sizeof(BITMAP_ScanList2)); memmove(p_line0 + 120, BITMAP_ScanList2, sizeof(BITMAP_ScanList2));
#ifndef ENABLE_BIG_FREQ
if ((attributes & MR_CH_COMPAND) > 0)
memmove(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
#else
// TODO: // find somewhere else to put the symbol
#endif
// compander symbol
#ifndef ENABLE_BIG_FREQ
if (att.compander)
memmove(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
#else
// TODO: // find somewhere else to put the symbol
#endif
switch (gEeprom.CHANNEL_DISPLAY_MODE) switch (gEeprom.CHANNEL_DISPLAY_MODE)
{ {
case MDF_FREQUENCY: // show the channel frequency case MDF_FREQUENCY: // show the channel frequency
#ifdef ENABLE_BIG_FREQ sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000);
NUMBER_ToDigits(frequency, String); #ifdef ENABLE_BIG_FREQ
// show the main large frequency digits if(frequency < 100000000) {
UI_DisplayFrequency(String, 32, line, false, false);
// show the remaining 2 small frequency digits // show the remaining 2 small frequency digits
UI_DisplaySmallDigits(2, String + 6, 113, line + 1, true); UI_PrintStringSmall(String + 7, 113, 0, line + 1);
#else String[7] = 0;
// show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false);
}
else
#endif
{
// show the frequency in the main font // show the frequency in the main font
sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000);
UI_PrintString(String, 32, 0, line, 8); UI_PrintString(String, 32, 0, line, 8);
#endif }
break; break;
case MDF_CHANNEL: // show the channel number case MDF_CHANNEL: // show the channel number
@@ -523,18 +506,15 @@ void UI_DisplayMain(void)
sprintf(String, "CH-%03u", gEeprom.ScreenChannel[vfo_num] + 1); sprintf(String, "CH-%03u", gEeprom.ScreenChannel[vfo_num] + 1);
} }
if (gEeprom.CHANNEL_DISPLAY_MODE == MDF_NAME) if (gEeprom.CHANNEL_DISPLAY_MODE == MDF_NAME) {
{
UI_PrintString(String, 32, 0, line, 8); UI_PrintString(String, 32, 0, line, 8);
} }
else else {
{ #ifdef ENABLE_SMALL_BOLD
#ifdef ENABLE_SMALL_BOLD UI_PrintStringSmallBold(String, 32 + 4, 0, line);
UI_PrintStringSmallBold(String, 32 + 4, 0, line); #else
#else UI_PrintStringSmall(String, 32 + 4, 0, line);
UI_PrintStringSmall(String, 32 + 4, 0, line); #endif
#endif
// show the channel frequency below the channel number/name // show the channel frequency below the channel number/name
sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000); sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000);
UI_PrintStringSmall(String, 32 + 4, 0, line + 1); UI_PrintStringSmall(String, 32 + 4, 0, line + 1);
@@ -545,26 +525,31 @@ void UI_DisplayMain(void)
} }
else else
{ // frequency mode { // frequency mode
#ifdef ENABLE_BIG_FREQ sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000);
NUMBER_ToDigits(frequency, String); // 8 digits
// show the main large frequency digits #ifdef ENABLE_BIG_FREQ
UI_DisplayFrequency(String, 32, line, false, false); if(frequency < 100000000) {
// show the remaining 2 small frequency digits // show the remaining 2 small frequency digits
UI_DisplaySmallDigits(2, String + 6, 113, line + 1, true); UI_PrintStringSmall(String + 7, 113, 0, line + 1);
#else String[7] = 0;
// show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false);
}
else
#endif
{
// show the frequency in the main font // show the frequency in the main font
sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000);
UI_PrintString(String, 32, 0, line, 8); UI_PrintString(String, 32, 0, line, 8);
#endif }
// show the channel symbols // show the channel symbols
const uint8_t attributes = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
if ((attributes & MR_CH_COMPAND) > 0) if (att.compander)
#ifdef ENABLE_BIG_FREQ #ifdef ENABLE_BIG_FREQ
memmove(p_line0 + 120, BITMAP_compand, sizeof(BITMAP_compand)); memmove(p_line0 + 120, BITMAP_compand, sizeof(BITMAP_compand));
#else #else
memmove(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand)); memmove(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
#endif #endif
} }
} }
@@ -591,26 +576,31 @@ void UI_DisplayMain(void)
Level = gVFO_RSSI_bar_level[vfo_num]; Level = gVFO_RSSI_bar_level[vfo_num];
#endif #endif
} }
if(Level)
UI_drawBars(p_line1 + LCD_WIDTH, Level); DrawSmallAntennaAndBars(p_line1 + LCD_WIDTH, Level);
} }
// ************ // ************
String[0] = '\0'; String[0] = '\0';
if (gEeprom.VfoInfo[vfo_num].AM_mode)
{ // show the AM symbol // show the modulation symbol
strcpy(String, "AM"); const char * s = "";
} const ModulationMode_t mod = gEeprom.VfoInfo[vfo_num].Modulation;
else switch (mod){
{ // or show the CTCSS/DCS symbol case MODULATION_FM: {
const FREQ_Config_t *pConfig = (mode == 1) ? gEeprom.VfoInfo[vfo_num].pTX : gEeprom.VfoInfo[vfo_num].pRX; const FREQ_Config_t *pConfig = (mode == 1) ? gEeprom.VfoInfo[vfo_num].pTX : gEeprom.VfoInfo[vfo_num].pRX;
const unsigned int code_type = pConfig->CodeType; const unsigned int code_type = pConfig->CodeType;
const char *code_list[] = {"", "CT", "DCS", "DCR"}; const char *code_list[] = {"", "CT", "DCS", "DCR"};
if (code_type < ARRAY_SIZE(code_list)) if (code_type < ARRAY_SIZE(code_list))
strcpy(String, code_list[code_type]); s = code_list[code_type];
} break;
UI_PrintStringSmall(String, LCD_WIDTH + 24, 0, line + 1); }
default:
s = gModulationStr[mod];
break;
}
UI_PrintStringSmall(s, LCD_WIDTH + 24, 0, line + 1);
if (state == VFO_STATE_NORMAL || state == VFO_STATE_ALARM) if (state == VFO_STATE_NORMAL || state == VFO_STATE_ALARM)
{ // show the TX power { // show the TX power
@@ -660,38 +650,35 @@ void UI_DisplayMain(void)
gCurrentFunction == FUNCTION_MONITOR || gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING); gCurrentFunction == FUNCTION_INCOMING);
#ifdef ENABLE_AUDIO_BAR #ifdef ENABLE_AUDIO_BAR
if (gSetting_mic_bar && gCurrentFunction == FUNCTION_TRANSMIT) if (gSetting_mic_bar && gCurrentFunction == FUNCTION_TRANSMIT) {
{ center_line = CENTER_LINE_AUDIO_BAR;
center_line = CENTER_LINE_AUDIO_BAR; UI_DisplayAudioBar();
UI_DisplayAudioBar(); }
} else
else #endif
#endif
#if defined(ENABLE_AM_FIX) && defined(ENABLE_AM_FIX_SHOW_DATA) #if defined(ENABLE_AM_FIX) && defined(ENABLE_AM_FIX_SHOW_DATA)
if (rx && gEeprom.VfoInfo[gEeprom.RX_VFO].AM_mode && gSetting_AM_fix) if (rx && gEeprom.VfoInfo[gEeprom.RX_VFO].Modulation == MODULATION_AM && gSetting_AM_fix)
{ {
if (gScreenToDisplay != DISPLAY_MAIN || if (gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE) gDTMF_CallState != DTMF_CALL_STATE_NONE)
return; return;
center_line = CENTER_LINE_AM_FIX_DATA; center_line = CENTER_LINE_AM_FIX_DATA;
AM_fix_print_data(gEeprom.RX_VFO, String); AM_fix_print_data(gEeprom.RX_VFO, String);
UI_PrintStringSmall(String, 2, 0, 3); UI_PrintStringSmall(String, 2, 0, 3);
} }
else else
#endif #endif
#ifdef ENABLE_RSSI_BAR
if (rx)
{
center_line = CENTER_LINE_RSSI;
UI_DisplayRSSIBar(gCurrentRSSI[gEeprom.RX_VFO], false);
}
else
#endif
#ifdef ENABLE_RSSI_BAR
if (rx) {
center_line = CENTER_LINE_RSSI;
DisplayRSSIBar(gCurrentRSSI[gEeprom.RX_VFO], false);
}
else
#endif
if (rx || gCurrentFunction == FUNCTION_FOREGROUND || gCurrentFunction == FUNCTION_POWER_SAVE) if (rx || gCurrentFunction == FUNCTION_FOREGROUND || gCurrentFunction == FUNCTION_POWER_SAVE)
{ {
#if 1 #if 1
@@ -728,22 +715,21 @@ void UI_DisplayMain(void)
} }
#endif #endif
#ifdef ENABLE_SHOW_CHARGE_LEVEL #ifdef ENABLE_SHOW_CHARGE_LEVEL
else else if (gChargingWithTypeC)
if (gChargingWithTypeC) { // charging .. show the battery state
{ // charging .. show the battery state if (gScreenToDisplay != DISPLAY_MAIN ||
if (gScreenToDisplay != DISPLAY_MAIN || gDTMF_CallState != DTMF_CALL_STATE_NONE)
gDTMF_CallState != DTMF_CALL_STATE_NONE) return;
return;
center_line = CENTER_LINE_CHARGE_DATA; center_line = CENTER_LINE_CHARGE_DATA;
sprintf(String, "Charge %u.%02uV %u%%", sprintf(String, "Charge %u.%02uV %u%%",
gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100, gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100,
BATTERY_VoltsToPercent(gBatteryVoltageAverage)); BATTERY_VoltsToPercent(gBatteryVoltageAverage));
UI_PrintStringSmall(String, 2, 0, 3); UI_PrintStringSmall(String, 2, 0, 3);
} }
#endif #endif
} }
} }

230
ui/menu.c
View File

@@ -70,6 +70,7 @@ const t_menu_item MenuList[] =
{"F1Long", VOICE_ID_INVALID, MENU_F1LONG }, {"F1Long", VOICE_ID_INVALID, MENU_F1LONG },
{"F2Shrt", VOICE_ID_INVALID, MENU_F2SHRT }, {"F2Shrt", VOICE_ID_INVALID, MENU_F2SHRT },
{"F2Long", VOICE_ID_INVALID, MENU_F2LONG }, {"F2Long", VOICE_ID_INVALID, MENU_F2LONG },
{"M Long", VOICE_ID_INVALID, MENU_MLONG },
{"KeyLck", VOICE_ID_INVALID, MENU_AUTOLK }, // was "AUTOLk" {"KeyLck", VOICE_ID_INVALID, MENU_AUTOLK }, // was "AUTOLk"
{"TxTOut", VOICE_ID_TRANSMIT_OVER_TIME, MENU_TOT }, // was "TOT" {"TxTOut", VOICE_ID_TRANSMIT_OVER_TIME, MENU_TOT }, // was "TOT"
@@ -82,6 +83,8 @@ const t_menu_item MenuList[] =
{"POnMsg", VOICE_ID_INVALID, MENU_PONMSG }, {"POnMsg", VOICE_ID_INVALID, MENU_PONMSG },
{"BatTxt", VOICE_ID_INVALID, MENU_BAT_TXT }, {"BatTxt", VOICE_ID_INVALID, MENU_BAT_TXT },
{"BackLt", VOICE_ID_INVALID, MENU_ABR }, // was "ABR" {"BackLt", VOICE_ID_INVALID, MENU_ABR }, // was "ABR"
{"BLMin", VOICE_ID_INVALID, MENU_ABR_MIN },
{"BLMax", VOICE_ID_INVALID, MENU_ABR_MAX },
{"BltTRX", VOICE_ID_INVALID, MENU_ABR_ON_TX_RX }, {"BltTRX", VOICE_ID_INVALID, MENU_ABR_ON_TX_RX },
{"Beep", VOICE_ID_BEEP_PROMPT, MENU_BEEP }, {"Beep", VOICE_ID_BEEP_PROMPT, MENU_BEEP },
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
@@ -126,11 +129,11 @@ const t_menu_item MenuList[] =
{"Tx 500", VOICE_ID_INVALID, MENU_500TX }, // was "500TX" {"Tx 500", VOICE_ID_INVALID, MENU_500TX }, // was "500TX"
{"350 En", VOICE_ID_INVALID, MENU_350EN }, // was "350EN" {"350 En", VOICE_ID_INVALID, MENU_350EN }, // was "350EN"
{"ScraEn", VOICE_ID_INVALID, MENU_SCREN }, // was "SCREN" {"ScraEn", VOICE_ID_INVALID, MENU_SCREN }, // was "SCREN"
{"TxEnab", VOICE_ID_INVALID, MENU_TX_EN }, // enable TX
#ifdef ENABLE_F_CAL_MENU #ifdef ENABLE_F_CAL_MENU
{"FrCali", VOICE_ID_INVALID, MENU_F_CALI }, // reference xtal calibration {"FrCali", VOICE_ID_INVALID, MENU_F_CALI }, // reference xtal calibration
#endif #endif
{"BatCal", VOICE_ID_INVALID, MENU_BATCAL }, // battery voltage calibration {"BatCal", VOICE_ID_INVALID, MENU_BATCAL }, // battery voltage calibration
{"BatTyp", VOICE_ID_INVALID, MENU_BATTYP }, // battery type 1600/2200mAh
{"Reset", VOICE_ID_INITIALISATION, MENU_RESET }, // might be better to move this to the hidden menu items ? {"Reset", VOICE_ID_INITIALISATION, MENU_RESET }, // might be better to move this to the hidden menu items ?
{"", VOICE_ID_INVALID, 0xff } // end of list - DO NOT delete or move this this {"", VOICE_ID_INVALID, 0xff } // end of list - DO NOT delete or move this this
@@ -138,33 +141,33 @@ const t_menu_item MenuList[] =
const uint8_t FIRST_HIDDEN_MENU_ITEM = MENU_F_LOCK; const uint8_t FIRST_HIDDEN_MENU_ITEM = MENU_F_LOCK;
const char gSubMenu_TXP[3][5] = const char gSubMenu_TXP[][5] =
{ {
"LOW", "LOW",
"MID", "MID",
"HIGH" "HIGH"
}; };
const char gSubMenu_SFT_D[3][4] = const char gSubMenu_SFT_D[][4] =
{ {
"OFF", "OFF",
"+", "+",
"-" "-"
}; };
const char gSubMenu_W_N[2][7] = const char gSubMenu_W_N[][7] =
{ {
"WIDE", "WIDE",
"NARROW" "NARROW"
}; };
const char gSubMenu_OFF_ON[2][4] = const char gSubMenu_OFF_ON[][4] =
{ {
"OFF", "OFF",
"ON" "ON"
}; };
const char gSubMenu_SAVE[5][4] = const char gSubMenu_SAVE[][4] =
{ {
"OFF", "OFF",
"1:1", "1:1",
@@ -173,7 +176,7 @@ const char gSubMenu_SAVE[5][4] =
"1:4" "1:4"
}; };
const char gSubMenu_TOT[11][7] = const char gSubMenu_TOT[][7] =
{ {
"30 sec", "30 sec",
"1 min", "1 min",
@@ -188,7 +191,7 @@ const char gSubMenu_TOT[11][7] =
"15 min" "15 min"
}; };
const char* gSubMenu_RXMode[4] = const char* gSubMenu_RXMode[] =
{ {
"MAIN\nONLY", // TX and RX on main only "MAIN\nONLY", // TX and RX on main only
"DUAL RX\nRESPOND", // Watch both and respond "DUAL RX\nRESPOND", // Watch both and respond
@@ -197,7 +200,7 @@ const char* gSubMenu_RXMode[4] =
}; };
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
const char gSubMenu_VOICE[3][4] = const char gSubMenu_VOICE[][4] =
{ {
"OFF", "OFF",
"CHI", "CHI",
@@ -205,14 +208,14 @@ const char* gSubMenu_RXMode[4] =
}; };
#endif #endif
const char gSubMenu_SC_REV[3][8] = const char gSubMenu_SC_REV[][8] =
{ {
"TIME", "TIMEOUT",
"CARRIER", "CARRIER",
"SEARCH" "STOP"
}; };
const char* gSubMenu_MDF[4] = const char* gSubMenu_MDF[] =
{ {
"FREQ", "FREQ",
"CHANNEL\nNUMBER", "CHANNEL\nNUMBER",
@@ -221,14 +224,14 @@ const char* gSubMenu_MDF[4] =
}; };
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
const char gSubMenu_AL_MOD[2][5] = const char gSubMenu_AL_MOD[][5] =
{ {
"SITE", "SITE",
"TONE" "TONE"
}; };
#endif #endif
const char gSubMenu_D_RSP[4][11] = const char gSubMenu_D_RSP[][11] =
{ {
"DO\nNOTHING", "DO\nNOTHING",
"RING", "RING",
@@ -236,16 +239,16 @@ const char gSubMenu_D_RSP[4][11] =
"BOTH" "BOTH"
}; };
const char* gSubMenu_PTT_ID[5] = const char* gSubMenu_PTT_ID[] =
{ {
"OFF", "OFF",
"KEY\nUP", "UP CODE",
"KEY\nDOWN", "DOWN CODE",
"KEY\nUP+DOWN", "UP+DOWN\nCODE",
"APOLLO\nQUINDAR" "APOLLO\nQUINDAR"
}; };
const char gSubMenu_PONMSG[4][8] = const char gSubMenu_PONMSG[][8] =
{ {
"FULL", "FULL",
"MESSAGE", "MESSAGE",
@@ -253,30 +256,32 @@ const char gSubMenu_PONMSG[4][8] =
"NONE" "NONE"
}; };
const char* gSubMenu_ROGER[3] = const char gSubMenu_ROGER[][6] =
{ {
"OFF", "OFF",
"ROGER", "ROGER",
"MDC\n1200" "MDC"
}; };
const char gSubMenu_RESET[2][4] = const char gSubMenu_RESET[][4] =
{ {
"VFO", "VFO",
"ALL" "ALL"
}; };
const char gSubMenu_F_LOCK[6][4] = const char * gSubMenu_F_LOCK[] =
{ {
"OFF", "DEFAULT+\n137-174\n400-470",
"FCC", "FCC HAM\n144-148\n420-450",
"CE", "CE HAM\n144-146\n430-440",
"GB", "GB HAM\n144-148\n430-440",
"430", "137-174\n400-430",
"438" "137-174\n400-438",
"DISABLE\nALL",
"UNLOCK\nALL",
}; };
const char gSubMenu_BACKLIGHT[8][7] = const char gSubMenu_BACKLIGHT[][7] =
{ {
"OFF", "OFF",
"5 sec", "5 sec",
@@ -288,7 +293,7 @@ const char gSubMenu_BACKLIGHT[8][7] =
"ON" "ON"
}; };
const char gSubMenu_RX_TX[4][6] = const char gSubMenu_RX_TX[][6] =
{ {
"OFF", "OFF",
"TX", "TX",
@@ -297,7 +302,7 @@ const char gSubMenu_RX_TX[4][6] =
}; };
#ifdef ENABLE_AM_FIX_TEST1 #ifdef ENABLE_AM_FIX_TEST1
const char gSubMenu_AM_fix_test1[4][8] = const char gSubMenu_AM_fix_test1[][8] =
{ {
"LNA-S 0", "LNA-S 0",
"LNA-S 1", "LNA-S 1",
@@ -306,14 +311,20 @@ const char gSubMenu_RX_TX[4][6] =
}; };
#endif #endif
const char gSubMenu_BAT_TXT[3][8] = const char gSubMenu_BAT_TXT[][8] =
{ {
"NONE", "NONE",
"VOLTAGE", "VOLTAGE",
"PERCENT" "PERCENT"
}; };
const char gSubMenu_SCRAMBLER[11][7] = const char gSubMenu_BATTYP[][9] =
{
"1600mAh",
"2200mAh"
};
const char gSubMenu_SCRAMBLER[][7] =
{ {
"OFF", "OFF",
"2600Hz", "2600Hz",
@@ -328,7 +339,6 @@ const char gSubMenu_SCRAMBLER[11][7] =
"3500Hz" "3500Hz"
}; };
const t_sidefunction SIDEFUNCTIONS[] = const t_sidefunction SIDEFUNCTIONS[] =
{ {
{"NONE", ACTION_OPT_NONE}, {"NONE", ACTION_OPT_NONE},
@@ -347,6 +357,13 @@ const t_sidefunction SIDEFUNCTIONS[] =
#endif #endif
#ifdef ENABLE_TX1750 #ifdef ENABLE_TX1750
{"1750HZ", ACTION_OPT_1750}, {"1750HZ", ACTION_OPT_1750},
#endif
{"LOCK\nKEYPAD", ACTION_OPT_KEYLOCK},
{"SWITCH\nVFO", ACTION_OPT_A_B},
{"VFO/MR", ACTION_OPT_VFO_MR},
{"SWITCH\nDEMODUL", ACTION_OPT_SWITCH_DEMODUL},
#ifdef ENABLE_BLMIN_TMP_OFF
{"BLMIN\nTMP OFF", ACTION_OPT_BLMIN_TMP_OFF}, //BackLight Minimum Temporay OFF
#endif #endif
}; };
const t_sidefunction* gSubMenu_SIDEFUNCTIONS = SIDEFUNCTIONS; const t_sidefunction* gSubMenu_SIDEFUNCTIONS = SIDEFUNCTIONS;
@@ -354,13 +371,21 @@ const uint8_t gSubMenu_SIDEFUNCTIONS_size = ARRAY_SIZE(SIDEFUNCTIONS);
bool gIsInSubMenu; bool gIsInSubMenu;
uint8_t gMenuCursor; uint8_t gMenuCursor;
int GetCurrentMenuId() { int UI_MENU_GetCurrentMenuId() {
if(gMenuCursor < ARRAY_SIZE(MenuList)) if(gMenuCursor < ARRAY_SIZE(MenuList))
return MenuList[gMenuCursor].menu_id; return MenuList[gMenuCursor].menu_id;
else else
return MenuList[ARRAY_SIZE(MenuList)-1].menu_id; return MenuList[ARRAY_SIZE(MenuList)-1].menu_id;
} }
int8_t gMenuScrollDirection;
uint8_t UI_MENU_GetMenuIdx(uint8_t id)
{
for(uint8_t i = 0; i < ARRAY_SIZE(MenuList); i++)
if(MenuList[i].menu_id == id)
return i;
return 0;
}
int32_t gSubMenuSelection; int32_t gSubMenuSelection;
// edit box // edit box
@@ -463,7 +488,7 @@ void UI_DisplayMenu(void)
bool already_printed = false; bool already_printed = false;
switch (GetCurrentMenuId()) switch (UI_MENU_GetCurrentMenuId())
{ {
case MENU_SQL: case MENU_SQL:
sprintf(String, "%d", gSubMenuSelection); sprintf(String, "%d", gSubMenuSelection);
@@ -482,9 +507,11 @@ void UI_DisplayMenu(void)
break; break;
#endif #endif
case MENU_STEP: case MENU_STEP: {
sprintf(String, "%d.%02ukHz", StepFrequencyTable[gSubMenuSelection] / 100, abs(StepFrequencyTable[gSubMenuSelection]) % 100); uint16_t step = gStepFrequencyTable[FREQUENCY_GetStepIdxFromSortedIdx(gSubMenuSelection)];
sprintf(String, "%d.%02ukHz", step / 100, step % 100);
break; break;
}
case MENU_TXP: case MENU_TXP:
strcpy(String, gSubMenu_TXP[gSubMenuSelection]); strcpy(String, gSubMenu_TXP[gSubMenuSelection]);
@@ -494,8 +521,7 @@ void UI_DisplayMenu(void)
case MENU_T_DCS: case MENU_T_DCS:
if (gSubMenuSelection == 0) if (gSubMenuSelection == 0)
strcpy(String, "OFF"); strcpy(String, "OFF");
else else if (gSubMenuSelection < 105)
if (gSubMenuSelection < 105)
sprintf(String, "D%03oN", DCS_Options[gSubMenuSelection - 1]); sprintf(String, "D%03oN", DCS_Options[gSubMenuSelection - 1]);
else else
sprintf(String, "D%03oI", DCS_Options[gSubMenuSelection - 105]); sprintf(String, "D%03oI", DCS_Options[gSubMenuSelection - 105]);
@@ -504,38 +530,10 @@ void UI_DisplayMenu(void)
case MENU_R_CTCS: case MENU_R_CTCS:
case MENU_T_CTCS: case MENU_T_CTCS:
{ {
#if 1 if (gSubMenuSelection == 0)
unsigned int Code; strcpy(String, "OFF");
FREQ_Config_t *pConfig = (GetCurrentMenuId() == MENU_R_CTCS) ? &gTxVfo->freq_config_RX : &gTxVfo->freq_config_TX; else
if (gSubMenuSelection == 0) sprintf(String, "%u.%uHz", CTCSS_Options[gSubMenuSelection - 1] / 10, CTCSS_Options[gSubMenuSelection - 1] % 10);
{
strcpy(String, "OFF");
if (pConfig->CodeType != CODE_TYPE_CONTINUOUS_TONE)
break;
Code = 0;
pConfig->CodeType = CODE_TYPE_OFF;
pConfig->Code = Code;
BK4819_ExitSubAu();
}
else
{
sprintf(String, "%u.%uHz", CTCSS_Options[gSubMenuSelection - 1] / 10, CTCSS_Options[gSubMenuSelection - 1] % 10);
pConfig->CodeType = CODE_TYPE_CONTINUOUS_TONE;
Code = gSubMenuSelection - 1;
pConfig->Code = Code;
BK4819_SetCTCSSFrequency(CTCSS_Options[Code]);
}
#else
if (gSubMenuSelection == 0)
strcpy(String, "OFF");
else
sprintf(String, "%u.%uHz", CTCSS_Options[gSubMenuSelection - 1] / 10, CTCSS_Options[gSubMenuSelection - 1] % 10);
#endif
break; break;
} }
@@ -546,21 +544,13 @@ void UI_DisplayMenu(void)
case MENU_OFFSET: case MENU_OFFSET:
if (!gIsInSubMenu || gInputBoxIndex == 0) if (!gIsInSubMenu || gInputBoxIndex == 0)
{ {
sprintf(String, "%d.%05u", gSubMenuSelection / 100000, abs(gSubMenuSelection) % 100000); sprintf(String, "%3d.%05u", gSubMenuSelection / 100000, abs(gSubMenuSelection) % 100000);
UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8); UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8);
} }
else else
{ {
for (i = 0; i < 3; i++) const char * ascii = INPUTBOX_GetAscii();
String[i ] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0'; sprintf(String, "%.3s.%.3s ",ascii, ascii + 3);
String[3] = '.';
for (i = 3; i < 6; i++)
String[i + 1] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0';
String[ 7] = '-';
String[ 8] = '-';
String[ 9] = 0;
String[10] = 0;
String[11] = 0;
UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8); UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8);
} }
@@ -594,10 +584,20 @@ void UI_DisplayMenu(void)
case MENU_ABR: case MENU_ABR:
strcpy(String, gSubMenu_BACKLIGHT[gSubMenuSelection]); strcpy(String, gSubMenu_BACKLIGHT[gSubMenuSelection]);
BACKLIGHT_SetBrightness(-1);
break; break;
case MENU_ABR_MIN:
case MENU_ABR_MAX:
sprintf(String, "%d", gSubMenuSelection);
if(gIsInSubMenu)
BACKLIGHT_SetBrightness(gSubMenuSelection);
else
BACKLIGHT_SetBrightness(-1);
break;
case MENU_AM: case MENU_AM:
strcpy(String, (gSubMenuSelection == 0) ? "FM" : "AM"); strcpy(String, gModulationStr[gSubMenuSelection]);
break; break;
#ifdef ENABLE_AM_FIX_TEST1 #ifdef ENABLE_AM_FIX_TEST1
@@ -635,7 +635,6 @@ void UI_DisplayMenu(void)
case MENU_500TX: case MENU_500TX:
case MENU_350EN: case MENU_350EN:
case MENU_SCREN: case MENU_SCREN:
case MENU_TX_EN:
strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]); strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]);
break; break;
@@ -803,7 +802,10 @@ void UI_DisplayMenu(void)
break; break;
case MENU_F_LOCK: case MENU_F_LOCK:
strcpy(String, gSubMenu_F_LOCK[gSubMenuSelection]); if(!gIsInSubMenu && gUnlockAllTxConfCnt>0 && gUnlockAllTxConfCnt<10)
strcpy(String, "READ\nMANUAL");
else
strcpy(String, gSubMenu_F_LOCK[gSubMenuSelection]);
break; break;
#ifdef ENABLE_F_CAL_MENU #ifdef ENABLE_F_CAL_MENU
@@ -827,11 +829,16 @@ void UI_DisplayMenu(void)
sprintf(String, "%u.%02uV\n%u", vol / 100, vol % 100, gSubMenuSelection); sprintf(String, "%u.%02uV\n%u", vol / 100, vol % 100, gSubMenuSelection);
break; break;
} }
case MENU_BATTYP:
strcpy(String, gSubMenu_BATTYP[gSubMenuSelection]);
break;
case MENU_F1SHRT: case MENU_F1SHRT:
case MENU_F1LONG: case MENU_F1LONG:
case MENU_F2SHRT: case MENU_F2SHRT:
case MENU_F2LONG: case MENU_F2LONG:
case MENU_MLONG:
strcpy(String, gSubMenu_SIDEFUNCTIONS[gSubMenuSelection].name); strcpy(String, gSubMenu_SIDEFUNCTIONS[gSubMenuSelection].name);
break; break;
@@ -891,9 +898,9 @@ void UI_DisplayMenu(void)
} }
} }
if (GetCurrentMenuId() == MENU_SLIST1 || GetCurrentMenuId() == MENU_SLIST2) if (UI_MENU_GetCurrentMenuId() == MENU_SLIST1 || UI_MENU_GetCurrentMenuId() == MENU_SLIST2)
{ {
i = (GetCurrentMenuId() == MENU_SLIST1) ? 0 : 1; i = (UI_MENU_GetCurrentMenuId() == MENU_SLIST1) ? 0 : 1;
// if (gSubMenuSelection == 0xFF) // if (gSubMenuSelection == 0xFF)
if (gSubMenuSelection < 0) if (gSubMenuSelection < 0)
@@ -938,9 +945,9 @@ void UI_DisplayMenu(void)
} }
} }
if (GetCurrentMenuId() == MENU_MEM_CH || if (UI_MENU_GetCurrentMenuId() == MENU_MEM_CH ||
GetCurrentMenuId() == MENU_DEL_CH || UI_MENU_GetCurrentMenuId() == MENU_DEL_CH ||
GetCurrentMenuId() == MENU_1_CALL) UI_MENU_GetCurrentMenuId() == MENU_1_CALL)
{ // display the channel name { // display the channel name
char s[11]; char s[11];
BOARD_fetchChannelName(s, gSubMenuSelection); BOARD_fetchChannelName(s, gSubMenuSelection);
@@ -949,18 +956,19 @@ void UI_DisplayMenu(void)
UI_PrintString(s, menu_item_x1, menu_item_x2, 2, 8); UI_PrintString(s, menu_item_x1, menu_item_x2, 2, 8);
} }
if ((GetCurrentMenuId() == MENU_R_CTCS || GetCurrentMenuId() == MENU_R_DCS) && gCssScanMode != CSS_SCAN_MODE_OFF) if ((UI_MENU_GetCurrentMenuId() == MENU_R_CTCS || UI_MENU_GetCurrentMenuId() == MENU_R_DCS) && gCssBackgroundScan)
UI_PrintString("SCAN", menu_item_x1, menu_item_x2, 4, 8); UI_PrintString("SCAN", menu_item_x1, menu_item_x2, 4, 8);
if (GetCurrentMenuId() == MENU_UPCODE) if (UI_MENU_GetCurrentMenuId() == MENU_UPCODE)
if (strlen(gEeprom.DTMF_UP_CODE) > 8) if (strlen(gEeprom.DTMF_UP_CODE) > 8)
UI_PrintString(gEeprom.DTMF_UP_CODE + 8, menu_item_x1, menu_item_x2, 4, 8); UI_PrintString(gEeprom.DTMF_UP_CODE + 8, menu_item_x1, menu_item_x2, 4, 8);
if (GetCurrentMenuId() == MENU_DWCODE) if (UI_MENU_GetCurrentMenuId() == MENU_DWCODE)
if (strlen(gEeprom.DTMF_DOWN_CODE) > 8) if (strlen(gEeprom.DTMF_DOWN_CODE) > 8)
UI_PrintString(gEeprom.DTMF_DOWN_CODE + 8, menu_item_x1, menu_item_x2, 4, 8); UI_PrintString(gEeprom.DTMF_DOWN_CODE + 8, menu_item_x1, menu_item_x2, 4, 8);
if (GetCurrentMenuId() == MENU_D_LIST && gIsDtmfContactValid) if (UI_MENU_GetCurrentMenuId() == MENU_D_LIST && gIsDtmfContactValid)
{ {
Contact[11] = 0; Contact[11] = 0;
memmove(&gDTMF_ID, Contact + 8, 4); memmove(&gDTMF_ID, Contact + 8, 4);
@@ -968,22 +976,20 @@ void UI_DisplayMenu(void)
UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8); UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8);
} }
if (GetCurrentMenuId() == MENU_R_CTCS || if (UI_MENU_GetCurrentMenuId() == MENU_R_CTCS ||
GetCurrentMenuId() == MENU_T_CTCS || UI_MENU_GetCurrentMenuId() == MENU_T_CTCS ||
GetCurrentMenuId() == MENU_R_DCS || UI_MENU_GetCurrentMenuId() == MENU_R_DCS ||
GetCurrentMenuId() == MENU_T_DCS || UI_MENU_GetCurrentMenuId() == MENU_T_DCS ||
GetCurrentMenuId() == MENU_D_LIST) UI_MENU_GetCurrentMenuId() == MENU_D_LIST)
{ {
unsigned int Offset; sprintf(String, "%2d", gSubMenuSelection);
NUMBER_ToDigits(gSubMenuSelection, String); UI_PrintStringSmall(String, 105, 0, 0);
Offset = (GetCurrentMenuId() == MENU_D_LIST) ? 2 : 3;
UI_DisplaySmallDigits(Offset, String + (8 - Offset), 105, 0, false);
} }
if ((GetCurrentMenuId() == MENU_RESET || if ((UI_MENU_GetCurrentMenuId() == MENU_RESET ||
GetCurrentMenuId() == MENU_MEM_CH || UI_MENU_GetCurrentMenuId() == MENU_MEM_CH ||
GetCurrentMenuId() == MENU_MEM_NAME || UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME ||
GetCurrentMenuId() == MENU_DEL_CH) && gAskForConfirmation) UI_MENU_GetCurrentMenuId() == MENU_DEL_CH) && gAskForConfirmation)
{ // display confirmation { // display confirmation
strcpy(String, (gAskForConfirmation == 1) ? "SURE?" : "WAIT!"); strcpy(String, (gAskForConfirmation == 1) ? "SURE?" : "WAIT!");
UI_PrintString(String, menu_item_x1, menu_item_x2, 5, 8); UI_PrintString(String, menu_item_x1, menu_item_x2, 5, 8);

View File

@@ -21,6 +21,7 @@
#include <stdint.h> #include <stdint.h>
#include "audio.h" // VOICE_ID_t #include "audio.h" // VOICE_ID_t
#include "settings.h"
typedef struct { typedef struct {
const char name[7]; // menu display area only has room for 6 characters const char name[7]; // menu display area only has room for 6 characters
@@ -53,6 +54,8 @@ enum
#endif #endif
MENU_ABR, MENU_ABR,
MENU_ABR_ON_TX_RX, MENU_ABR_ON_TX_RX,
MENU_ABR_MIN,
MENU_ABR_MAX,
MENU_TDR, MENU_TDR,
MENU_BEEP, MENU_BEEP,
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
@@ -108,8 +111,6 @@ enum
MENU_500TX, MENU_500TX,
MENU_350EN, MENU_350EN,
MENU_SCREN, MENU_SCREN,
MENU_TX_EN, // enable TX
#ifdef ENABLE_F_CAL_MENU #ifdef ENABLE_F_CAL_MENU
MENU_F_CALI, // reference xtal calibration MENU_F_CALI, // reference xtal calibration
#endif #endif
@@ -117,7 +118,9 @@ enum
MENU_F1SHRT, MENU_F1SHRT,
MENU_F1LONG, MENU_F1LONG,
MENU_F2SHRT, MENU_F2SHRT,
MENU_F2LONG MENU_F2LONG,
MENU_MLONG,
MENU_BATTYP
}; };
extern const uint8_t FIRST_HIDDEN_MENU_ITEM; extern const uint8_t FIRST_HIDDEN_MENU_ITEM;
@@ -142,16 +145,16 @@ extern const char* gSubMenu_MDF[4];
extern const char gSubMenu_D_RSP[4][11]; extern const char gSubMenu_D_RSP[4][11];
extern const char* gSubMenu_PTT_ID[5]; extern const char* gSubMenu_PTT_ID[5];
extern const char gSubMenu_PONMSG[4][8]; extern const char gSubMenu_PONMSG[4][8];
extern const char* gSubMenu_ROGER[3]; extern const char gSubMenu_ROGER[3][6];
extern const char gSubMenu_RESET[2][4]; 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]; extern const char gSubMenu_BACKLIGHT[8][7];
extern const char gSubMenu_RX_TX[4][6]; extern const char gSubMenu_RX_TX[4][6];
#ifdef ENABLE_AM_FIX_TEST1 #ifdef ENABLE_AM_FIX_TEST1
extern const char gSubMenu_AM_fix_test1[4][8]; extern const char gSubMenu_AM_fix_test1[4][8];
#endif #endif
extern const char gSubMenu_BAT_TXT[3][8]; extern const char gSubMenu_BAT_TXT[3][8];
extern const char gSubMenu_BATTYP[2][9];
extern const char gSubMenu_SCRAMBLER[11][7]; extern const char gSubMenu_SCRAMBLER[11][7];
typedef struct {char* name; uint8_t id;} t_sidefunction; typedef struct {char* name; uint8_t id;} t_sidefunction;
@@ -161,8 +164,7 @@ extern const t_sidefunction* gSubMenu_SIDEFUNCTIONS;
extern bool gIsInSubMenu; extern bool gIsInSubMenu;
extern uint8_t gMenuCursor; extern uint8_t gMenuCursor;
int GetCurrentMenuId();
extern int8_t gMenuScrollDirection;
extern int32_t gSubMenuSelection; extern int32_t gSubMenuSelection;
extern char edit_original[17]; extern char edit_original[17];
@@ -170,5 +172,7 @@ extern char edit[17];
extern int edit_index; extern int edit_index;
void UI_DisplayMenu(void); void UI_DisplayMenu(void);
int UI_MENU_GetCurrentMenuId();
uint8_t UI_MENU_GetMenuIdx(uint8_t id);
#endif #endif

View File

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

View File

@@ -16,10 +16,11 @@
#include <string.h> #include <string.h>
#include "app/scanner.h" #include "app/chFrScanner.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h" #include "app/fm.h"
#endif #endif
#include "app/scanner.h"
#include "bitmaps.h" #include "bitmaps.h"
#include "driver/keyboard.h" #include "driver/keyboard.h"
#include "driver/st7565.h" #include "driver/st7565.h"
@@ -33,7 +34,7 @@
#include "ui/ui.h" #include "ui/ui.h"
#include "ui/status.h" #include "ui/status.h"
void UI_DisplayStatus(const bool test_display) void UI_DisplayStatus()
{ {
uint8_t *line = gStatusLine; uint8_t *line = gStatusLine;
unsigned int x = 0; unsigned int x = 0;
@@ -60,7 +61,7 @@ void UI_DisplayStatus(const bool test_display)
x1 = x + sizeof(BITMAP_RX); x1 = x + sizeof(BITMAP_RX);
} }
else else
if (gCurrentFunction == FUNCTION_POWER_SAVE || test_display) if (gCurrentFunction == FUNCTION_POWER_SAVE)
{ {
memmove(line + x, BITMAP_POWERSAVE, sizeof(BITMAP_POWERSAVE)); memmove(line + x, BITMAP_POWERSAVE, sizeof(BITMAP_POWERSAVE));
x1 = x + sizeof(BITMAP_POWERSAVE); x1 = x + sizeof(BITMAP_POWERSAVE);
@@ -69,7 +70,7 @@ void UI_DisplayStatus(const bool test_display)
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
// NOASS SCAN indicator // NOASS SCAN indicator
if (gIsNoaaMode || test_display) if (gIsNoaaMode)
{ {
memmove(line + x, BITMAP_NOAA, sizeof(BITMAP_NOAA)); memmove(line + x, BITMAP_NOAA, sizeof(BITMAP_NOAA));
x1 = x + sizeof(BITMAP_NOAA); x1 = x + sizeof(BITMAP_NOAA);
@@ -86,30 +87,29 @@ void UI_DisplayStatus(const bool test_display)
} }
else else
// SCAN indicator // SCAN indicator
if (gScanStateDir != SCAN_OFF || gScreenToDisplay == DISPLAY_SCANNER || test_display) if (gScanStateDir != SCAN_OFF || SCANNER_IsScanning())
{ {
if (gNextMrChannel <= MR_CHANNEL_LAST && gScreenToDisplay != DISPLAY_SCANNER) char * s = "";
if (IS_MR_CHANNEL(gNextMrChannel) && !SCANNER_IsScanning())
{ // channel mode { // channel mode
if (gEeprom.SCAN_LIST_DEFAULT == 0) switch(gEeprom.SCAN_LIST_DEFAULT) {
UI_PrintStringSmallBuffer("1", line + x); case 0: s = "1"; break;
else case 1: s = "2"; break;
if (gEeprom.SCAN_LIST_DEFAULT == 1) case 2: s = "*"; break;
UI_PrintStringSmallBuffer("2", line + x); }
else
if (gEeprom.SCAN_LIST_DEFAULT == 2)
UI_PrintStringSmallBuffer("*", line + x);
} }
else else
{ // frequency mode { // frequency mode
UI_PrintStringSmallBuffer("S", line + x); s = "S";
} }
UI_PrintStringSmallBuffer(s, line + x);
x1 = x + 7; x1 = x + 7;
} }
x += 7; // font character width x += 7; // font character width
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
// VOICE indicator // 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)); memmove(line + x, BITMAP_VoicePrompt, sizeof(BITMAP_VoicePrompt));
x1 = x + sizeof(BITMAP_VoicePrompt); x1 = x + sizeof(BITMAP_VoicePrompt);
@@ -120,10 +120,10 @@ void UI_DisplayStatus(const bool test_display)
#endif #endif
x++; x++;
if(gScreenToDisplay != DISPLAY_SCANNER) { if(!SCANNER_IsScanning()) {
uint8_t dw = (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2; uint8_t dw = (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2;
if(dw == 1 || dw == 3 || test_display) { // DWR - dual watch + respond if(dw == 1 || dw == 3) { // DWR - dual watch + respond
if(gDualWatchActive || test_display) if(gDualWatchActive)
memmove(line + x, BITMAP_TDR1, sizeof(BITMAP_TDR1) - (dw==1?0:5)); memmove(line + x, BITMAP_TDR1, sizeof(BITMAP_TDR1) - (dw==1?0:5));
else else
memmove(line + x + 3, BITMAP_TDR2, sizeof(BITMAP_TDR2)); memmove(line + x + 3, BITMAP_TDR2, sizeof(BITMAP_TDR2));
@@ -136,7 +136,7 @@ void UI_DisplayStatus(const bool test_display)
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
// VOX indicator // VOX indicator
if (gEeprom.VOX_SWITCH || test_display) if (gEeprom.VOX_SWITCH)
{ {
memmove(line + x, BITMAP_VOX, sizeof(BITMAP_VOX)); memmove(line + x, BITMAP_VOX, sizeof(BITMAP_VOX));
x1 = x + sizeof(BITMAP_VOX); x1 = x + sizeof(BITMAP_VOX);
@@ -148,7 +148,7 @@ void UI_DisplayStatus(const bool test_display)
x1 = x; x1 = x;
// KEY-LOCK indicator // KEY-LOCK indicator
if (gEeprom.KEY_LOCK || test_display) if (gEeprom.KEY_LOCK)
{ {
memmove(line + x, BITMAP_KeyLock, sizeof(BITMAP_KeyLock)); memmove(line + x, BITMAP_KeyLock, sizeof(BITMAP_KeyLock));
x += sizeof(BITMAP_KeyLock); x += sizeof(BITMAP_KeyLock);
@@ -166,7 +166,7 @@ void UI_DisplayStatus(const bool test_display)
char s[8]; char s[8];
unsigned int space_needed; unsigned int space_needed;
unsigned int x2 = LCD_WIDTH - sizeof(BITMAP_BatteryLevel5) - 3; unsigned int x2 = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - 3;
if (gChargingWithTypeC) if (gChargingWithTypeC)
x2 -= sizeof(BITMAP_USB_C); // the radio is on charge x2 -= sizeof(BITMAP_USB_C); // the radio is on charge
@@ -204,7 +204,7 @@ void UI_DisplayStatus(const bool test_display)
x = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - sizeof(BITMAP_USB_C); x = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - sizeof(BITMAP_USB_C);
// USB-C charge indicator // USB-C charge indicator
if (gChargingWithTypeC || test_display) if (gChargingWithTypeC)
memmove(line + x, BITMAP_USB_C, sizeof(BITMAP_USB_C)); memmove(line + x, BITMAP_USB_C, sizeof(BITMAP_USB_C));
x += sizeof(BITMAP_USB_C); x += sizeof(BITMAP_USB_C);

View File

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

View File

@@ -16,11 +16,11 @@
#include <string.h> #include <string.h>
#include "app/chFrScanner.h"
#include "app/dtmf.h" #include "app/dtmf.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h" #include "app/fm.h"
#endif #endif
#include "app/scanner.h"
#include "driver/keyboard.h" #include "driver/keyboard.h"
#include "misc.h" #include "misc.h"
#ifdef ENABLE_AIRCOPY #ifdef ENABLE_AIRCOPY
@@ -86,7 +86,7 @@ void GUI_SelectNextDisplay(GUI_DisplayType_t Display)
gInputBoxIndex = 0; gInputBoxIndex = 0;
gIsInSubMenu = false; gIsInSubMenu = false;
gCssScanMode = CSS_SCAN_MODE_OFF; gCssBackgroundScan = false;
gScanStateDir = SCAN_OFF; gScanStateDir = SCAN_OFF;
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
gFM_ScanState = FM_SCAN_OFF; gFM_ScanState = FM_SCAN_OFF;

View File

@@ -43,7 +43,6 @@ void UI_DisplayWelcome(void)
{ {
char WelcomeString0[16]; char WelcomeString0[16];
char WelcomeString1[16]; char WelcomeString1[16];
char WelcomeString2[16];
memset(gStatusLine, 0, sizeof(gStatusLine)); memset(gStatusLine, 0, sizeof(gStatusLine));
memset(gFrameBuffer, 0, sizeof(gFrameBuffer)); memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
@@ -61,7 +60,6 @@ void UI_DisplayWelcome(void)
{ {
memset(WelcomeString0, 0, sizeof(WelcomeString0)); memset(WelcomeString0, 0, sizeof(WelcomeString0));
memset(WelcomeString1, 0, sizeof(WelcomeString1)); memset(WelcomeString1, 0, sizeof(WelcomeString1));
memset(WelcomeString2, 0, sizeof(WelcomeString2));
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_VOLTAGE) if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_VOLTAGE)
{ {
@@ -70,10 +68,6 @@ void UI_DisplayWelcome(void)
gBatteryVoltageAverage / 100, gBatteryVoltageAverage / 100,
gBatteryVoltageAverage % 100, gBatteryVoltageAverage % 100,
BATTERY_VoltsToPercent(gBatteryVoltageAverage)); BATTERY_VoltsToPercent(gBatteryVoltageAverage));
#if 0
sprintf(WelcomeString2, "Current %u", gBatteryCurrent); // needs scaling into mA
#endif
} }
else else
{ {
@@ -83,17 +77,9 @@ void UI_DisplayWelcome(void)
UI_PrintString(WelcomeString0, 0, 127, 0, 10); UI_PrintString(WelcomeString0, 0, 127, 0, 10);
UI_PrintString(WelcomeString1, 0, 127, 2, 10); UI_PrintString(WelcomeString1, 0, 127, 2, 10);
#if 0 UI_PrintStringSmall(Version, 0, 0, 6);
UI_PrintStringSmall(WelcomeString2, 0, 127, 4);
#endif
UI_PrintStringSmall(Version, 0, 0, 6);
#if 1 ST7565_BlitStatusLine(); // blank status line
ST7565_BlitStatusLine(); // blank status line
#else
UI_DisplayStatus(true); // show all status line symbols (test)
#endif
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
} }
} }

View File

@@ -18,15 +18,6 @@
:: Delete any left over files from previous compile
::
del /S /Q *.o >nul 2>nul
del /S /Q *.d >nul 2>nul
del /Q firmware >nul 2>nul
del /Q *.bin >nul 2>nul
:: You may need to edit/change these three paths to suit your setup :: You may need to edit/change these three paths to suit your setup
:: ::
:: Temporarily add the compiler and make program directories to the system PATH .. :: Temporarily add the compiler and make program directories to the system PATH ..
@@ -40,14 +31,6 @@ del /Q *.bin >nul 2>nul
make clean make clean
make make
:: Delete the spent files
::
del /S /Q *.o >nul 2>nul
del /S /Q *.d >nul 2>nul
del /Q firmware >nul 2>nul
:: If you have python installed, you can create a 'packed' .bin from the compiled firmware.bin file. :: If you have python installed, you can create a 'packed' .bin from the compiled firmware.bin file.
:: The Quansheng windows upload-to-radio program requires a 'packed' .bin file. :: The Quansheng windows upload-to-radio program requires a 'packed' .bin file.