34 Commits
v0.7 ... v0.9

Author SHA1 Message Date
Krzysiek Egzmont
063dc61e65 Part of the recent changes form 1o11, including DTMF input box error #19 2023-10-09 21:47:06 +02:00
Krzysiek Egzmont
60ccd3372f FIX #8: This should fix compiler errors 2023-10-09 17:17:45 +02:00
Krzysiek Egzmont
149a0f5bdc Revert do not update battery level when TX 2023-10-09 16:57:52 +02:00
Krzysiek Egzmont
c7da7cf725 Battery symbol fix 2023-10-09 16:30:20 +02:00
Krzysiek Egzmont
4b9147327a Fix random upper/lower for TX, bring back TX on last RX 2023-10-09 16:02:57 +02:00
Krzysiek Egzmont
43f4790f5b BUG FIX #15: shifted numbers in spectrum freq input box 2023-10-06 19:57:08 +02:00
Krzysiek Egzmont
43ccce33da README: new build instructions 2023-10-06 12:15:01 +02:00
Krzysiek Egzmont
b2839de2a5 Merge remote-tracking branch 'remotes/OneOfEleven/main' 2023-10-06 11:28:19 +02:00
OneOfEleven
5397b3ee88 Fixed key number offset bug added yesterday 2023-10-06 07:48:45 +01:00
OneOfEleven
9a0a75446a README.md 2023-10-06 00:19:21 +01:00
OneOfEleven
f25e0230f0 Added power-on compile option 2023-10-06 00:18:47 +01:00
OneOfEleven
16c908f0bf Channel/Frequency scanning updates 2023-10-05 23:58:55 +01:00
OneOfEleven
9c7d6a38e5 Remember scan ALL channels option across power cycles 2023-10-05 22:59:26 +01:00
OneOfEleven
ec5e9dde66 Squelch tuning 2023-10-05 22:44:44 +01:00
OneOfEleven
5c346c8466 Fic typing in keys bug 2023-10-05 17:38:25 +01:00
OneOfEleven
40d09591b3 Fixed silly error I made 2023-10-05 16:28:20 +01:00
OneOfEleven
bd9f337a5b Make all warnings vanish over to bricky's house ! 2023-10-05 15:26:08 +01:00
OneOfEleven
cb05a5881f Try again to calm the type warnings 2023-10-05 14:40:34 +01:00
OneOfEleven
6b44659419 Mzybe clear up some signed/unsigned compile warnings 2023-10-05 14:33:05 +01:00
Krzysiek Egzmont
81f18aa281 build errors fix 2023-10-05 15:10:12 +02:00
Krzysiek Egzmont
410c0e47cb Merge remote-tracking branch 'remotes/OneOfEleven/main' 2023-10-05 15:05:54 +02:00
OneOfEleven
2372949eb9 RX bandwidth and squelch update 2023-10-05 13:42:14 +01:00
OneOfEleven
0cf4e1fe36 Merge pull request #123 from bricky149/clang-build
Add support for clang builds
2023-10-05 12:44:47 +01:00
OneOfEleven
9b2ce88a72 RX fixed bandwidth adjustments + squelch sensitivity adjustments 2023-10-05 12:42:40 +01:00
bricky149
a23f359735 Add support for clang builds 2023-10-05 12:22:09 +01:00
OneOfEleven
b343993a72 Don't use fast scan option - for now 2023-10-05 10:19:50 +01:00
OneOfEleven
4d8db8f0b9 Updated 5/7 function key operation (see README.md) 2023-10-05 10:03:07 +01:00
OneOfEleven
609df5f279 Ignore all long-press/function keys whilst in menu 2023-10-05 09:17:38 +01:00
OneOfEleven
e042b21e65 Rename RX_CHANNEL and TX_CHANNEL to RX_VFO and TX_VFO to be much less confusing 2023-10-05 01:07:04 +01:00
OneOfEleven
d632698428 Clean up copy-chan-to-vfo 2023-10-05 00:26:37 +01:00
OneOfEleven
eba4bf9c80 Fix copy-chan-to-vfo 2023-10-05 00:07:35 +01:00
OneOfEleven
56fc929921 Let copy-chan-to-vfo work when dual-watch enabled 2023-10-05 00:01:13 +01:00
Krzysiek Egzmont
2cff29e6db Merge remote-tracking branch 'remotes/OneOfEleven/main' 2023-10-05 00:11:29 +02:00
OneOfEleven
a6324ffcf8 Fix for when channel scan has no scanlisted channels to scan 2023-10-04 23:09:55 +01:00
58 changed files with 2362 additions and 1956 deletions

View File

@@ -3,6 +3,7 @@
# 0 = disable # 0 = disable
# 1 = enable # 1 = enable
# #
ENABLE_CLANG := 0
ENABLE_SWD := 0 ENABLE_SWD := 0
ENABLE_OVERLAY := 0 ENABLE_OVERLAY := 0
ENABLE_LTO := 1 ENABLE_LTO := 1
@@ -13,7 +14,8 @@ ENABLE_NOAA := 0
ENABLE_VOICE := 0 ENABLE_VOICE := 0
ENABLE_VOX := 1 ENABLE_VOX := 1
ENABLE_ALARM := 0 ENABLE_ALARM := 0
ENABLE_TX1750 := 1 ENABLE_TX1750 := 0
ENABLE_PWRON_PASSWORD := 0
ENABLE_BIG_FREQ := 1 ENABLE_BIG_FREQ := 1
ENABLE_SMALL_BOLD := 1 ENABLE_SMALL_BOLD := 1
ENABLE_KEEP_MEM_NAME := 1 ENABLE_KEEP_MEM_NAME := 1
@@ -21,27 +23,31 @@ 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 := 1
ENABLE_MAIN_KEY_HOLD := 1
ENABLE_BOOT_BEEPS := 0 ENABLE_BOOT_BEEPS := 0
ENABLE_SHOW_CHARGE_LEVEL := 1 ENABLE_SHOW_CHARGE_LEVEL := 1
ENABLE_REVERSE_BAT_SYMBOL := 1 ENABLE_REVERSE_BAT_SYMBOL := 1
ENABLE_CODE_SCAN_TIMEOUT := 0 ENABLE_CODE_SCAN_TIMEOUT := 0
ENABLE_AM_FIX := 1 ENABLE_AM_FIX := 1
ENABLE_AM_FIX_SHOW_DATA := 0 ENABLE_AM_FIX_SHOW_DATA := 0
ENABLE_SQUELCH_LOWER := 0 ENABLE_SQUELCH_MORE_SENSITIVE := 1
ENABLE_FASTER_CHANNEL_SCAN := 1 ENABLE_FASTER_CHANNEL_SCAN := 1
ENABLE_RSSI_BAR := 1 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_SINGLE_VFO_CHAN := 1
ENABLE_SPECTRUM := 1 ENABLE_SPECTRUM := 1
#ENABLE_SINGLE_VFO_CHAN := 1
#ENABLE_BAND_SCOPE := 1 #ENABLE_BAND_SCOPE := 1
############################################################# #############################################################
TARGET = firmware TARGET = firmware
ifeq ($(ENABLE_LTO), 1) ifeq ($(ENABLE_CLANG),1)
# GCC's linker, ld, doesn't understand LLVM's generated bytecode
ENABLE_LTO := 0
endif
ifeq ($(ENABLE_LTO),1)
# can't have LTO and OVERLAY enabled at same time # can't have LTO and OVERLAY enabled at same time
ENABLE_OVERLAY := 0 ENABLE_OVERLAY := 0
endif endif
@@ -132,7 +138,9 @@ ifeq ($(ENABLE_FMRADIO),1)
endif endif
OBJS += ui/helper.o OBJS += ui/helper.o
OBJS += ui/inputbox.o OBJS += ui/inputbox.o
OBJS += ui/lock.o ifeq ($(ENABLE_PWRON_PASSWORD),1)
OBJS += ui/lock.o
endif
OBJS += ui/main.o OBJS += ui/main.o
OBJS += ui/menu.o OBJS += ui/menu.o
OBJS += ui/scanner.o OBJS += ui/scanner.o
@@ -149,8 +157,21 @@ else
endif endif
AS = arm-none-eabi-gcc AS = arm-none-eabi-gcc
CC = arm-none-eabi-gcc
CC =
LD = arm-none-eabi-gcc LD = arm-none-eabi-gcc
ifeq ($(ENABLE_CLANG),0)
CC += arm-none-eabi-gcc
# Use GCC's linker to avoid undefined symbol errors
# LD += arm-none-eabi-gcc
else
# May need to adjust this to match your system
CC += clang --sysroot=/usr/arm-none-eabi --target=arm-none-eabi
# Bloats binaries to 512MB
# LD = ld.lld
endif
OBJCOPY = arm-none-eabi-objcopy OBJCOPY = arm-none-eabi-objcopy
SIZE = arm-none-eabi-size SIZE = arm-none-eabi-size
@@ -166,22 +187,30 @@ ifeq ($(ENABLE_OVERLAY),1)
ASFLAGS += -DENABLE_OVERLAY ASFLAGS += -DENABLE_OVERLAY
endif endif
CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD CFLAGS =
#CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c99 -MMD ifeq ($(ENABLE_CLANG),0)
#CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=gnu99 -MMD CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD
#CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=gnu11 -MMD #CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c99 -MMD
#CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=gnu99 -MMD
#CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=gnu11 -MMD
else
# Oz needed to make it fit on flash
CFLAGS += -Oz -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD
endif
ifeq ($(ENABLE_LTO), 1) ifeq ($(ENABLE_LTO),1)
# CFLAGS += -flto
CFLAGS += -flto=2 CFLAGS += -flto=2
else else
# We get most of the space savings if LTO creates problems # We get most of the space savings if LTO creates problems
CFLAGS += -ffunction-sections -fdata-sections CFLAGS += -ffunction-sections -fdata-sections
endif endif
# May cause unhelpful build failures # May cause unhelpful build failures
#CFLAGS += -Wpadded #CFLAGS += -Wpadded
# catch any and all warnings
#CFLAGS += -Wextra
CFLAGS += -DPRINTF_INCLUDE_CONFIG_H CFLAGS += -DPRINTF_INCLUDE_CONFIG_H
CFLAGS += -DGIT_HASH=\"$(GIT_HASH)\" CFLAGS += -DGIT_HASH=\"$(GIT_HASH)\"
@@ -224,6 +253,9 @@ endif
ifeq ($(ENABLE_TX1750),1) ifeq ($(ENABLE_TX1750),1)
CFLAGS += -DENABLE_TX1750 CFLAGS += -DENABLE_TX1750
endif endif
ifeq ($(ENABLE_PWRON_PASSWORD),1)
CFLAGS += -DENABLE_PWRON_PASSWORD
endif
ifeq ($(ENABLE_KEEP_MEM_NAME),1) ifeq ($(ENABLE_KEEP_MEM_NAME),1)
CFLAGS += -DENABLE_KEEP_MEM_NAME CFLAGS += -DENABLE_KEEP_MEM_NAME
endif endif
@@ -239,9 +271,6 @@ endif
ifeq ($(ENABLE_CTCSS_TAIL_PHASE_SHIFT),1) ifeq ($(ENABLE_CTCSS_TAIL_PHASE_SHIFT),1)
CFLAGS += -DENABLE_CTCSS_TAIL_PHASE_SHIFT CFLAGS += -DENABLE_CTCSS_TAIL_PHASE_SHIFT
endif endif
ifeq ($(ENABLE_MAIN_KEY_HOLD),1)
CFLAGS += -DENABLE_MAIN_KEY_HOLD
endif
ifeq ($(ENABLE_BOOT_BEEPS),1) ifeq ($(ENABLE_BOOT_BEEPS),1)
CFLAGS += -DENABLE_BOOT_BEEPS CFLAGS += -DENABLE_BOOT_BEEPS
endif endif
@@ -288,19 +317,25 @@ ifeq ($(ENABLE_BAND_SCOPE),1)
CFLAGS += -DENABLE_BAND_SCOPE CFLAGS += -DENABLE_BAND_SCOPE
endif endif
LDFLAGS = -mcpu=cortex-m0 -nostartfiles -Wl,-T,firmware.ld LDFLAGS =
ifeq ($(ENABLE_CLANG),0)
LDFLAGS += -mcpu=cortex-m0 -nostartfiles -Wl,-T,firmware.ld
else
# Fix warning about implied executable stack
LDFLAGS += -z noexecstack -mcpu=cortex-m0 -nostartfiles -Wl,-T,firmware.ld
endif
# Use newlib-nano instead of newlib # Use newlib-nano instead of newlib
LDFLAGS += --specs=nano.specs LDFLAGS += --specs=nano.specs
ifeq ($(ENABLE_LTO), 0) ifeq ($(ENABLE_LTO),0)
# Throw away unneeded func/data sections like LTO does # Throw away unneeded func/data sections like LTO does
LDFLAGS += -Wl,--gc-sections LDFLAGS += -Wl,--gc-sections
endif endif
ifeq ($(DEBUG),1) ifeq ($(DEBUG),1)
ASFLAGS += -g ASFLAGS += -g
CFLAGS += -g CFLAGS += -g
LDFLAGS += -g LDFLAGS += -g
endif endif

View File

@@ -33,26 +33,31 @@ Anyway, have fun.
# Radio performance # Radio performance
Please note that the Quansheng uv-k radios are not professional quality transceivers, their Please note that the Quansheng UV-Kx radios are not professional quality transceivers, their
performance is strictly limited, somewhat below that of a decent transceiver. The RX front performance is strictly limited. The RX front end has no track-tuned band pass filtering
end has no track-tuned band pass filtering at all, and so are wide band/wide open to any at all, and so are wide band/wide open to any and all signals over a large frequency range.
and all signals over a wide frequency range.
Using the radio in high intensity RF environments will nearly always destroy your reception,
the receiver simply doesn't have a great dynamic range, which means distorted AM audio with
strong received signals, there is nothing more anyone can do in firmware/software to stop that
happening once the RX gain adjustment I do (AM fix) reaches the hardwares limit.
Saying that, they are nice toys for the price, fun to play with. Using the radio in high intensity RF environments will most likely make reception anything but
easy (AM mode will suffer far more than FM ever will), the receiver simply doesn't have a
great dynamic range, which results in distorted AM audio with stronger RX'ed signals.
There is nothing more anyone can do in firmware/software to improve that, once the RX gain
adjustment I do (AM fix) reaches the hardwares limit, your AM RX audio will be all but
non-existant (just like Quansheng's firmware).
On the other hand, FM RX audio will/should be fine.
But, they are nice toys for the price, fun to play with.
# User customization # User customization
You can customize the firmware by enabling/disabling various compile options. You can customize the firmware by enabling/disabling various compile options, this allows
us to remove certain firmware features in order to make room in the flash for others.
You'll find the options at the top of "Makefile" ('0' = disable, '1' = enable) .. You'll find the options at the top of "Makefile" ('0' = disable, '1' = enable) ..
``` ```
ENABLE_CLANG := 0 **experimental, builds with clang instead of gcc (LTO will be disabled if you enable this)
ENABLE_SWD := 0 only needed if using CPU's SWD port (debugging/programming) ENABLE_SWD := 0 only needed if using CPU's SWD port (debugging/programming)
ENABLE_OVERLAY := 0 cpu FLASH stuff, not needed ENABLE_OVERLAY := 0 cpu FLASH stuff, not needed
ENABLE_LTO := 0 **experimental, reduces size of compiled firmware but might break EEPROM reads (overlay will be disabled if you enable this) ENABLE_LTO := 0 **experimental, reduces size of compiled firmware but might break EEPROM reads (OVERLAY will be disabled if you enable this)
ENABLE_UART := 1 without this you can't configure radio via PC ! ENABLE_UART := 1 without this you can't configure radio via PC !
ENABLE_AIRCOPY := 0 easier to just enter frequency with butts ENABLE_AIRCOPY := 0 easier to just enter frequency with butts
ENABLE_FMRADIO := 0 WBFM VHF broadcast band receiver ENABLE_FMRADIO := 0 WBFM VHF broadcast band receiver
@@ -61,6 +66,7 @@ ENABLE_VOICE := 0 want to hear voices ?
ENABLE_VOX := 0 ENABLE_VOX := 0
ENABLE_ALARM := 0 TX alarms ENABLE_ALARM := 0 TX alarms
ENABLE_1750HZ := 0 side key 1750Hz TX tone (older style repeater access) ENABLE_1750HZ := 0 side key 1750Hz TX tone (older style repeater access)
ENABLE_PWRON_PASSWORD := 1 power-on password stuff
ENABLE_BIG_FREQ := 0 big font frequencies (like original QS firmware) ENABLE_BIG_FREQ := 0 big font frequencies (like original QS firmware)
ENABLE_SMALL_BOLD := 1 bold channel name/no. (when name + freq channel display mode) ENABLE_SMALL_BOLD := 1 bold channel name/no. (when name + freq channel display mode)
ENABLE_KEEP_MEM_NAME := 1 maintain channel name when (re)saving memory channel ENABLE_KEEP_MEM_NAME := 1 maintain channel name when (re)saving memory channel
@@ -68,7 +74,6 @@ ENABLE_WIDE_RX := 1 full 18MHz to 1300MHz RX (though front-
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/disable 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_MAIN_KEY_HOLD := 1 initial F-key press not needed, instead just hold down keys 0-9 to access the secondary butt functions
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)
@@ -86,9 +91,13 @@ ENABLE_COPY_CHAN_TO_VFO := 1 copy current channel into the other VFO
# New/modified function keys # New/modified function keys
* Long-press 'M' = Copy selected channel into the same VFO, then switches to frequency mode * Long-press 'M' .. Copy selected channel into same VFO, then switch VFO to frequency mode
* Long-press '5' = Toggle a selected channels scanlist setting .. if NOAA is disable in Makefile *
* Long-press '*' = Toggles the scanlist number 1, 2 or ALL channels .. if in channel scan 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 # Some changes made from the Quansheng firmware
@@ -109,28 +118,38 @@ arm-none-eabi GCC version 10.3.1 is recommended, which is the current version on
Other versions may generate a flash file that is too big. Other versions may generate a flash file that is too big.
You can get an appropriate version from: https://developer.arm.com/downloads/-/gnu-rm You can get an appropriate version from: https://developer.arm.com/downloads/-/gnu-rm
clang may be used but isn't fully supported. Resulting binaries may also be bigger.
You can get it from: https://releases.llvm.org/download.html
# Building # Building
To build the firmware, you need to fetch the submodules and then run make: If you have docker installed you can use `compile-with-docker.bat`, the output files are created in `compiled-firmware` folder. This method gives significantly smaller binaries, I've seen differences up to 1kb, so it can fit more functionalities this way. The challange can be (or not) installing the docker itself.
```
git submodule update --init --recursive --depth=1
make
```
To compile directly in windows without the need of a linux virtual machine:
``` To compile directly in windows:
1. Download and install "gcc-arm-none-eabi-10.3-2021.10-win32.exe" from https://developer.arm.com/downloads/-/gnu-rm
2. Download and install "gnu_make-3.81.exe" from https://gnuwin32.sourceforge.net/packages/make.htm
3. You may (or not) need to manualy add gcc path to you OS environment PATH. 1. Open windows command line and run:
ie add C:\Program Files (x86)\GNU Arm Embedded Toolchain\10 2021.10\bin ```
winget install -e -h git.git Python.Python.3.8 GnuWin32.Make
4. You may (or not) need to reboot your PC after installing the above winget install -e -h Arm.GnuArmEmbeddedToolchain -v "10 2021.10"
``` ```
2. Close command line, open a new one and run:
Then you can run 'win_make.bat' from the directory you saved this source code too. ```
You may need to edit the bat file (path to make.exe) depending on where you installed the above two packages too. pip install --user --upgrade pip
pip install crcmod
mkdir c:\projects & cd /D c:/projects
git clone https://github.com/egzumer/uv-k5-firmware-custom.git
```
3. From now on you can build the firmware by going to `c:\projects\uv-k5-firmware-custom` and running `win_make.bat` or by running a command line:
```
cd /D c:\projects\uv-k5-firmware-custom
win_make.bat
```
4. To reset the repository and pull new changes run (!!! it will delete all your changes !!!):
```
cd /D c:\projects\uv-k5-firmware-custom
git reset --hard & git clean -fd & git pull
```
I've left some notes in the win_make.bat file to maybe help with stuff. I've left some notes in the win_make.bat file to maybe help with stuff.
@@ -138,6 +157,7 @@ I've left some notes in the win_make.bat file to maybe help with stuff.
Many thanks to various people on Telegram for putting up with me during this effort and helping: Many thanks to various people on Telegram for putting up with me during this effort and helping:
* [OneOfEleven](https://github.com/OneOfEleven)
* [DualTachyon](https://github.com/DualTachyon) * [DualTachyon](https://github.com/DualTachyon)
* [Mikhail](https://github.com/fagci) * [Mikhail](https://github.com/fagci)
* [Andrej](https://github.com/Tunas1337) * [Andrej](https://github.com/Tunas1337)
@@ -171,13 +191,13 @@ You may obtain a copy of the License at
# Example changes/updates # Example changes/updates
<p float="left"> <p float="left">
<img src="/image1.png" width=300 /> <img src="/images/image1.png" width=300 />
<img src="/image2.png" width=300 /> <img src="/images/image2.png" width=300 />
<img src="/image3.png" width=300 /> <img src="/images/image3.png" width=300 />
</p> </p>
Video showing the AM fix working .. Video showing the AM fix working ..
<video src="/AM_fix.mp4"></video> <video src="/images/AM_fix.mp4"></video>
<video src="https://github.com/OneOfEleven/uv-k5-firmware-custom/assets/51590168/2a3a9cdc-97da-4966-bf0d-1ce6ad09779c"></video> <video src="https://github.com/OneOfEleven/uv-k5-firmware-custom/assets/51590168/2a3a9cdc-97da-4966-bf0d-1ce6ad09779c"></video>

View File

@@ -475,7 +475,7 @@
void AM_fix_print_data(const int vfo, char *s) void AM_fix_print_data(const int vfo, char *s)
{ {
if (s != NULL && vfo >= 0 && vfo < ARRAY_SIZE(gain_table_index)) if (s != NULL && vfo >= 0 && vfo < (int)ARRAY_SIZE(gain_table_index))
{ {
const unsigned int index = gain_table_index[vfo]; const unsigned int index = gain_table_index[vfo];
// sprintf(s, "%2u.%u %4ddB %3u", index, ARRAY_SIZE(gain_table) - 1, gain_table[index].gain_dB, prev_rssi[vfo]); // sprintf(s, "%2u.%u %4ddB %3u", index, ARRAY_SIZE(gain_table) - 1, gain_table[index].gain_dB, prev_rssi[vfo]);

View File

@@ -84,11 +84,11 @@ void ACTION_Monitor(void)
gMonitor = false; gMonitor = false;
if (gScanState != SCAN_OFF) if (gScanStateDir != SCAN_OFF)
{ {
ScanPauseDelayIn_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
@@ -182,23 +182,36 @@ void ACTION_Scan(bool bRestart)
{ {
GUI_SelectNextDisplay(DISPLAY_MAIN); GUI_SelectNextDisplay(DISPLAY_MAIN);
if (gScanState != SCAN_OFF) if (gScanStateDir != SCAN_OFF)
{ { // already scanning
#if 1
if (gNextMrChannel <= MR_CHANNEL_LAST)
{ // 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
CHANNEL_Next(true, gScanStateDir);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;
gUpdateStatus = true; gUpdateStatus = true;
#else }
else
{ // stop scanning
SCANNER_Stop(); SCANNER_Stop();
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP; gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif #endif
#endif }
} }
else else
{ { // start scanning
CHANNEL_Next(true, 1);
CHANNEL_Next(true, SCAN_FWD);
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN); AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN);
@@ -206,7 +219,7 @@ void ACTION_Scan(bool bRestart)
#endif #endif
// clear the other vfo's rssi level (to hide the antenna symbol) // clear the other vfo's rssi level (to hide the antenna symbol)
gVFO_RSSI_bar_level[(gEeprom.RX_CHANNEL + 1) & 1u] = 0; gVFO_RSSI_bar_level[(gEeprom.RX_VFO + 1) & 1u] = 0;
// let the user see DW is not active // let the user see DW is not active
gDualWatchActive = false; gDualWatchActive = false;
@@ -215,9 +228,16 @@ void ACTION_Scan(bool bRestart)
} }
} }
else else
if (!bRestart) // if (!bRestart)
{ // keep scanning but toggle between scan lists 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; gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3;
// jump to the next channel
CHANNEL_Next(true, gScanStateDir);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;
gUpdateStatus = true; gUpdateStatus = true;
} }
else else
@@ -313,10 +333,11 @@ void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
if (Key == KEY_SIDE1 && !bKeyHeld && bKeyPressed) if (Key == KEY_SIDE1 && !bKeyHeld && bKeyPressed)
{ {
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gDTMF_InputIndex > 0)
if (gDTMF_InputBox_Index > 0)
{ {
gDTMF_InputBox[--gDTMF_InputIndex] = '-'; gDTMF_InputBox[--gDTMF_InputBox_Index] = '-';
if (gDTMF_InputIndex > 0) if (gDTMF_InputBox_Index > 0)
{ {
gPttWasReleased = true; gPttWasReleased = true;
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;

558
app/app.c

File diff suppressed because it is too large Load Diff

View File

@@ -29,7 +29,7 @@ extern const uint8_t orig_mixer;
extern const uint8_t orig_pga; extern const uint8_t orig_pga;
void APP_EndTransmission(void); void APP_EndTransmission(void);
void CHANNEL_Next(bool bFlag, int8_t Direction); void CHANNEL_Next(const bool bFlag, const int8_t scan_direction);
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 Step);
void APP_Update(void); void APP_Update(void);

View File

@@ -36,9 +36,9 @@
char gDTMF_String[15]; char gDTMF_String[15];
char gDTMF_InputBox[15]; char gDTMF_InputBox[15];
uint8_t gDTMF_InputIndex = 0; uint8_t gDTMF_InputBox_Index = 0;
bool gDTMF_InputMode = false; bool gDTMF_InputMode = false;
uint8_t gDTMF_PreviousIndex = 0; uint8_t gDTMF_PreviousIndex = 0;
char gDTMF_RX[17]; char gDTMF_RX[17];
uint8_t gDTMF_RX_index = 0; uint8_t gDTMF_RX_index = 0;
@@ -133,8 +133,26 @@ bool DTMF_FindContact(const char *pContact, char *pResult)
char DTMF_GetCharacter(const unsigned int code) char DTMF_GetCharacter(const unsigned int code)
{ {
const char list[] = "0123456789ABCD*#"; switch (code)
return (code < ARRAY_SIZE(list)) ? list[code] : 0xFF; {
case KEY_0: return '0';
case KEY_1: return '1';
case KEY_2: return '2';
case KEY_3: return '3';
case KEY_4: return '4';
case KEY_5: return '5';
case KEY_6: return '6';
case KEY_7: return '7';
case KEY_8: return '8';
case KEY_9: return '9';
case KEY_MENU: return 'A';
case KEY_UP: return 'B';
case KEY_DOWN: return 'C';
case KEY_EXIT: return 'D';
case KEY_STAR: return '*';
case KEY_F: return '#';
default: return 0xff;
}
} }
bool DTMF_CompareMessage(const char *pMsg, const char *pTemplate, const unsigned int size, const bool bCheckGroup) bool DTMF_CompareMessage(const char *pMsg, const char *pTemplate, const unsigned int size, const bool bCheckGroup)
@@ -163,16 +181,23 @@ DTMF_CallMode_t DTMF_CheckGroupCall(const char *pMsg, const unsigned int size)
return (i < size) ? DTMF_CALL_MODE_GROUP : DTMF_CALL_MODE_NOT_GROUP; return (i < size) ? DTMF_CALL_MODE_GROUP : DTMF_CALL_MODE_NOT_GROUP;
} }
void DTMF_clear_input_box(void)
{
memset(gDTMF_InputBox, 0, sizeof(gDTMF_InputBox));
gDTMF_InputBox_Index = 0;
gDTMF_InputMode = false;
}
void DTMF_Append(const char code) void DTMF_Append(const char code)
{ {
if (gDTMF_InputIndex == 0) if (gDTMF_InputBox_Index == 0)
{ {
memset(gDTMF_InputBox, '-', sizeof(gDTMF_InputBox)); memset(gDTMF_InputBox, '-', sizeof(gDTMF_InputBox) - 1);
gDTMF_InputBox[sizeof(gDTMF_InputBox) - 1] = 0; gDTMF_InputBox[sizeof(gDTMF_InputBox) - 1] = 0;
} }
if (gDTMF_InputIndex < sizeof(gDTMF_InputBox)) if (gDTMF_InputBox_Index < (sizeof(gDTMF_InputBox) - 1))
gDTMF_InputBox[gDTMF_InputIndex++] = code; gDTMF_InputBox[gDTMF_InputBox_Index++] = code;
} }
void DTMF_HandleRequest(void) void DTMF_HandleRequest(void)
@@ -184,7 +209,7 @@ void DTMF_HandleRequest(void)
if (!gDTMF_RX_pending) if (!gDTMF_RX_pending)
return; // nothing new received return; // nothing new received
if (gScanState != SCAN_OFF || gCssScanMode != CSS_SCAN_MODE_OFF) if (gScanStateDir != SCAN_OFF || gCssScanMode != CSS_SCAN_MODE_OFF)
{ // we're busy scanning { // we're busy scanning
DTMF_clear_RX(); DTMF_clear_RX();
return; return;
@@ -331,6 +356,9 @@ void DTMF_HandleRequest(void)
gUpdateDisplay = true; gUpdateDisplay = true;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (gEeprom.DTMF_DECODE_RESPONSE) switch (gEeprom.DTMF_DECODE_RESPONSE)
{ {
case DTMF_DEC_RESPONSE_BOTH: case DTMF_DEC_RESPONSE_BOTH:
@@ -348,6 +376,8 @@ void DTMF_HandleRequest(void)
break; break;
} }
#pragma GCC diagnostic pop
if (gDTMF_IsGroupCall) if (gDTMF_IsGroupCall)
gDTMF_ReplyState = DTMF_REPLY_NONE; gDTMF_ReplyState = DTMF_REPLY_NONE;
} }
@@ -385,8 +415,9 @@ void DTMF_Reply(void)
default: default:
case DTMF_REPLY_NONE: case DTMF_REPLY_NONE:
if (gDTMF_CallState != DTMF_CALL_STATE_NONE || if (gDTMF_CallState != DTMF_CALL_STATE_NONE ||
gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_OFF || gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO ||
gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_OFF ||
gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_TX_DOWN) gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_TX_DOWN)
{ {
gDTMF_ReplyState = DTMF_REPLY_NONE; gDTMF_ReplyState = DTMF_REPLY_NONE;

View File

@@ -33,7 +33,8 @@ typedef enum DTMF_State_t DTMF_State_t;
enum DTMF_CallState_t { enum DTMF_CallState_t {
DTMF_CALL_STATE_NONE = 0, DTMF_CALL_STATE_NONE = 0,
DTMF_CALL_STATE_CALL_OUT, DTMF_CALL_STATE_CALL_OUT,
DTMF_CALL_STATE_RECEIVED DTMF_CALL_STATE_RECEIVED,
DTMF_CALL_STATE_RECEIVED_STAY
}; };
enum DTMF_DecodeResponse_t { enum DTMF_DecodeResponse_t {
@@ -60,12 +61,17 @@ enum DTMF_CallMode_t {
DTMF_CALL_MODE_DTMF DTMF_CALL_MODE_DTMF
}; };
enum { // seconds
DTMF_HOLD_MIN = 5,
DTMF_HOLD_MAX = 60
};
typedef enum DTMF_CallMode_t DTMF_CallMode_t; typedef enum DTMF_CallMode_t DTMF_CallMode_t;
extern char gDTMF_String[15]; extern char gDTMF_String[15];
extern char gDTMF_InputBox[15]; extern char gDTMF_InputBox[15];
extern uint8_t gDTMF_InputIndex; extern uint8_t gDTMF_InputBox_Index;
extern bool gDTMF_InputMode; extern bool gDTMF_InputMode;
extern uint8_t gDTMF_PreviousIndex; extern uint8_t gDTMF_PreviousIndex;
@@ -98,6 +104,7 @@ bool DTMF_FindContact(const char *pContact, char *pResult);
char DTMF_GetCharacter(const unsigned int code); char DTMF_GetCharacter(const unsigned int code);
bool DTMF_CompareMessage(const char *pDTMF, const char *pTemplate, const unsigned int size, const bool bFlag); bool DTMF_CompareMessage(const char *pDTMF, const char *pTemplate, const unsigned int size, const bool bFlag);
DTMF_CallMode_t DTMF_CheckGroupCall(const char *pDTMF, const unsigned int size); DTMF_CallMode_t DTMF_CheckGroupCall(const char *pDTMF, const unsigned int size);
void DTMF_clear_input_box(void);
void DTMF_Append(const char vode); void DTMF_Append(const char vode);
void DTMF_HandleRequest(void); void DTMF_HandleRequest(void);
void DTMF_Reply(void); void DTMF_Reply(void);

View File

@@ -52,12 +52,22 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
if (!bKeyPressed) if (!bKeyPressed)
return; return;
#ifdef ENABLE_VOICE if (gScreenToDisplay != DISPLAY_MENU &&
gAnotherVoiceID = gEeprom.KEY_LOCK ? VOICE_ID_UNLOCK : VOICE_ID_LOCK; gScreenToDisplay != DISPLAY_FM &&
#endif #ifdef ENABLE_FMRADIO
!gFmRadioMode &&
#endif
gCurrentFunction != FUNCTION_TRANSMIT)
{ // toggle the keyboad lock
gEeprom.KEY_LOCK = !gEeprom.KEY_LOCK; #ifdef ENABLE_VOICE
gRequestSaveSettings = true; gAnotherVoiceID = gEeprom.KEY_LOCK ? VOICE_ID_UNLOCK : VOICE_ID_LOCK;
#endif
gEeprom.KEY_LOCK = !gEeprom.KEY_LOCK;
gRequestSaveSettings = true;
}
} }
else else
{ {
@@ -71,6 +81,9 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
gWasFKeyPressed = !gWasFKeyPressed; gWasFKeyPressed = !gWasFKeyPressed;
if (gWasFKeyPressed)
gKeyInputCountdown = key_input_timeout_500ms;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
if (!gWasFKeyPressed) if (!gWasFKeyPressed)
gAnotherVoiceID = VOICE_ID_CANCEL; gAnotherVoiceID = VOICE_ID_CANCEL;
@@ -96,6 +109,7 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
#endif #endif
gBeepToPlay = BEEP_440HZ_500MS; gBeepToPlay = BEEP_440HZ_500MS;
gPttWasReleased = true; gPttWasReleased = true;
} }
} }
@@ -105,161 +119,154 @@ void GENERIC_Key_PTT(bool bKeyPressed)
gInputBoxIndex = 0; gInputBoxIndex = 0;
if (!bKeyPressed || gSerialConfigCountDown_500ms > 0) if (!bKeyPressed || gSerialConfigCountDown_500ms > 0)
{ { // PTT released
//if (gScreenToDisplay == DISPLAY_MAIN)
{ if (gCurrentFunction == FUNCTION_TRANSMIT)
if (gCurrentFunction == FUNCTION_TRANSMIT) { // we are transmitting .. stop
if (gFlagEndTransmission)
{ {
if (gFlagEndTransmission) FUNCTION_Select(FUNCTION_FOREGROUND);
{
FUNCTION_Select(FUNCTION_FOREGROUND);
}
else
{
APP_EndTransmission();
if (gEeprom.REPEATER_TAIL_TONE_ELIMINATION == 0)
{
FUNCTION_Select(FUNCTION_FOREGROUND);
}
else
gRTTECountdown = gEeprom.REPEATER_TAIL_TONE_ELIMINATION * 10;
}
gFlagEndTransmission = false;
#ifdef ENABLE_VOX
gVOX_NoiseDetected = false;
#endif
} }
else
{
APP_EndTransmission();
if (gEeprom.REPEATER_TAIL_TONE_ELIMINATION == 0)
FUNCTION_Select(FUNCTION_FOREGROUND);
else
gRTTECountdown = gEeprom.REPEATER_TAIL_TONE_ELIMINATION * 10;
}
gFlagEndTransmission = false;
#ifdef ENABLE_VOX
gVOX_NoiseDetected = false;
#endif
RADIO_SetVfoState(VFO_STATE_NORMAL); RADIO_SetVfoState(VFO_STATE_NORMAL);
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
return;
} }
gInputBoxIndex = 0;
return; return;
} }
if (gScanState != SCAN_OFF) // PTT pressed
{
SCANNER_Stop();
gPttDebounceCounter = 0; if (gScanStateDir != SCAN_OFF || // frequency/channel scanning
gPttIsPressed = false; gScreenToDisplay == DISPLAY_SCANNER || // CTCSS/CDCSS scanning
gCssScanMode != CSS_SCAN_MODE_OFF) // " "
{ // we're scanning .. stop
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu if (gScreenToDisplay == DISPLAY_SCANNER)
gRequestDisplayScreen = DISPLAY_MAIN; { // CTCSS/CDCSS scanning .. stop
gEeprom.CROSS_BAND_RX_TX = gBackup_CROSS_BAND_RX_TX;
return;
}
#ifdef ENABLE_FMRADIO
if (gFM_ScanState == FM_SCAN_OFF)
#endif
{
if (gCssScanMode == CSS_SCAN_MODE_OFF)
{
#ifdef ENABLE_FMRADIO
if (gScreenToDisplay == DISPLAY_FM)
{
gRequestDisplayScreen = DISPLAY_MAIN;
gInputBoxIndex = 0;
gPttIsPressed = false;
gPttDebounceCounter = 0;
return;
}
#endif
if (gScreenToDisplay != DISPLAY_SCANNER)
{
if (gCurrentFunction == FUNCTION_TRANSMIT && gRTTECountdown == 0)
{
gInputBoxIndex = 0;
return;
}
gFlagPrepareTX = true;
if (gDTMF_InputMode)
{
if (gDTMF_InputIndex > 0 || gDTMF_PreviousIndex > 0)
{
if (gDTMF_InputIndex == 0)
gDTMF_InputIndex = gDTMF_PreviousIndex;
gDTMF_InputBox[gDTMF_InputIndex] = 0;
#if 0
// append our DTMF ID to the inputted DTMF code -
// IF the user inputted code is exactly 3 digits long
if (gDTMF_InputIndex == 3)
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
else
#else
// append our DTMF ID to the inputted DTMF code -
// IF the user inputted code is exactly 3 digits long and D-DCD is enabled
if (gDTMF_InputIndex == 3 && gTxVfo->DTMF_DECODING_ENABLE > 0)
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
else
#endif
gDTMF_CallMode = DTMF_CALL_MODE_DTMF;
strcpy(gDTMF_String, gDTMF_InputBox);
gDTMF_PreviousIndex = gDTMF_InputIndex;
gDTMF_ReplyState = DTMF_REPLY_ANI;
gDTMF_State = DTMF_STATE_0;
}
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
gRequestDisplayScreen = DISPLAY_MAIN;
gDTMF_InputMode = false;
gDTMF_InputIndex = 0;
return;
}
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
gRequestDisplayScreen = DISPLAY_MAIN;
gFlagPrepareTX = true;
gInputBoxIndex = 0;
return;
}
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
gRequestDisplayScreen = DISPLAY_MAIN;
gEeprom.CROSS_BAND_RX_TX = gBackupCROSS_BAND_RX_TX;
gUpdateStatus = true;
gFlagStopScan = true; gFlagStopScan = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD; gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
gFlagResetVfos = true; gFlagResetVfos = true;
} }
else else
{ if (gScanStateDir != SCAN_OFF)
{ // frequency/channel scanning . .stop
SCANNER_Stop();
}
else
if (gCssScanMode != CSS_SCAN_MODE_OFF)
{ // CTCSS/CDCSS scanning .. stop
MENU_StopCssScan(); MENU_StopCssScan();
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu #ifdef ENABLE_VOICE
gRequestDisplayScreen = DISPLAY_MENU; gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
} }
goto cancel_tx;
} }
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
else if (gFM_ScanState != FM_SCAN_OFF)
{ { // FM radio is scanning .. stop
FM_PlayAndUpdate(); FM_PlayAndUpdate();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
gRequestDisplayScreen = DISPLAY_FM; gRequestDisplayScreen = DISPLAY_FM;
goto cancel_tx;
} }
#endif #endif
#ifdef ENABLE_VOICE #ifdef ENABLE_FMRADIO
gAnotherVoiceID = VOICE_ID_SCANNING_STOP; if (gScreenToDisplay == DISPLAY_FM)
goto start_tx; // listening to the FM radio .. start TX'ing
#endif #endif
gPttWasPressed = true; if (gCurrentFunction == FUNCTION_TRANSMIT && gRTTECountdown == 0)
{ // already transmitting
gInputBoxIndex = 0;
return;
}
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
gRequestDisplayScreen = DISPLAY_MAIN;
if (!gDTMF_InputMode && gDTMF_InputBox_Index == 0)
goto start_tx; // wasn't entering a DTMF code .. start TX'ing (maybe)
// was entering a DTMF string
if (gDTMF_InputBox_Index > 0 || gDTMF_PreviousIndex > 0)
{ // going to transmit a DTMF string
if (gDTMF_InputBox_Index == 0 && gDTMF_PreviousIndex > 0)
gDTMF_InputBox_Index = gDTMF_PreviousIndex; // use the previous DTMF string
if (gDTMF_InputBox_Index < sizeof(gDTMF_InputBox))
gDTMF_InputBox[gDTMF_InputBox_Index] = 0; // NULL term the string
#if 0
// append our DTMF ID to the inputted DTMF code -
// IF the user inputted code is exactly 3 digits long
if (gDTMF_InputBox_Index == 3)
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
else
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
gDTMF_PreviousIndex = gDTMF_InputBox_Index;
strcpy(gDTMF_String, gDTMF_InputBox);
gDTMF_ReplyState = DTMF_REPLY_ANI;
gDTMF_State = DTMF_STATE_0;
}
DTMF_clear_input_box();
start_tx:
// request start TX
gFlagPrepareTX = true;
goto done;
cancel_tx:
if (gPttIsPressed)
{
gPttIsPressed = false;
gPttWasPressed = true;
}
done:
gPttDebounceCounter = 0;
if (gScreenToDisplay != DISPLAY_MENU && gRequestDisplayScreen != DISPLAY_FM) // 1of11 .. don't close the menu
gRequestDisplayScreen = DISPLAY_MAIN;
gUpdateStatus = true;
gUpdateDisplay = true;
} }

View File

@@ -37,11 +37,51 @@
#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 "app/spectrum.h"
#endif
void toggle_chan_scanlist(void)
{ // toggle the selected channels scanlist setting
if (gScreenToDisplay == DISPLAY_SCANNER || !IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
return;
if (gTxVfo->SCANLIST1_PARTICIPATION)
{
if (gTxVfo->SCANLIST2_PARTICIPATION)
gTxVfo->SCANLIST1_PARTICIPATION = 0;
else
gTxVfo->SCANLIST2_PARTICIPATION = 1;
}
else
{
if (gTxVfo->SCANLIST2_PARTICIPATION)
gTxVfo->SCANLIST2_PARTICIPATION = 0;
else
gTxVfo->SCANLIST1_PARTICIPATION = 1;
}
SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true);
gVfoConfigureMode = VFO_CONFIGURE;
gFlagResetVfos = true;
}
static void processFKeyFunction(const KEY_Code_t Key, const bool beep) static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
{ {
uint8_t Band; uint8_t Band;
uint8_t Vfo = gEeprom.TX_CHANNEL; uint8_t Vfo = gEeprom.TX_VFO;
if (gScreenToDisplay == DISPLAY_MENU)
{
// if (beep)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
// if (beep)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
switch (Key) switch (Key)
{ {
@@ -102,7 +142,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B) if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B)
gEeprom.DUAL_WATCH = DUAL_WATCH_CHAN_A; gEeprom.DUAL_WATCH = DUAL_WATCH_CHAN_A;
else else
gEeprom.TX_CHANNEL = (Vfo + 1) & 1u; gEeprom.TX_VFO = (Vfo + 1) & 1u;
gRequestSaveSettings = 1; gRequestSaveSettings = 1;
gFlagReconfigureVfos = true; gFlagReconfigureVfos = true;
@@ -125,7 +165,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // swap to frequency mode { // swap to frequency mode
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_CHANNEL]; gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_VFO];
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE; gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif #endif
@@ -134,7 +174,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break; break;
} }
Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_CHANNEL], 1, false, 0); Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 0);
if (Channel != 0xFF) if (Channel != 0xFF)
{ // swap to channel mode { // swap to channel mode
gEeprom.ScreenChannel[Vfo] = Channel; gEeprom.ScreenChannel[Vfo] = Channel;
@@ -158,7 +198,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
gWasFKeyPressed = false; gWasFKeyPressed = false;
gFlagStartScan = true; gFlagStartScan = true;
gScanSingleFrequency = false; gScanSingleFrequency = false;
gBackupCROSS_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;
@@ -173,49 +213,28 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ {
gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_CHANNEL]; gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_VFO];
} }
else else
{ {
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_CHANNEL]; gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_VFO];
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE; gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif #endif
} }
gRequestSaveVFO = true; gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD; gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
#elif defined(ENABLE_SPECTRUM) #elif defined(ENABLE_SPECTRUM)
APP_RunSpectrum(); APP_RunSpectrum();
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
#endif #endif
} }
else { else {
// toggle the selected channels scanlist setting #ifdef ENABLE_VOX
toggle_chan_scanlist();
if (gScreenToDisplay != DISPLAY_SCANNER) #endif
{
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
if (gTxVfo->SCANLIST1_PARTICIPATION)
{
if (gTxVfo->SCANLIST2_PARTICIPATION)
gTxVfo->SCANLIST1_PARTICIPATION = 0;
else
gTxVfo->SCANLIST2_PARTICIPATION = 1;
}
else
{
if (gTxVfo->SCANLIST2_PARTICIPATION)
gTxVfo->SCANLIST2_PARTICIPATION = 0;
else
gTxVfo->SCANLIST1_PARTICIPATION = 1;
}
SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true);
gVfoConfigureMode = VFO_CONFIGURE;
gFlagResetVfos = true;
}
}
} }
break; break;
case KEY_6: case KEY_6:
@@ -226,11 +245,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
ACTION_Vox(); ACTION_Vox();
#else #else
toggle_chan_scanlist();
// TODO: make use of this function key
#endif #endif
break; break;
@@ -273,45 +288,36 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
if (bKeyHeld) if (bKeyHeld)
{ // key held down { // key held down
#ifdef ENABLE_MAIN_KEY_HOLD if (bKeyPressed)
if (bKeyPressed) {
if (gScreenToDisplay == DISPLAY_MAIN)
{ {
if (gScreenToDisplay == DISPLAY_MAIN) if (gInputBoxIndex > 0)
{ { // delete any inputted chars
if (gInputBoxIndex > 0) gInputBoxIndex = 0;
{ // delete any inputted chars gRequestDisplayScreen = DISPLAY_MAIN;
gInputBoxIndex = 0;
gRequestDisplayScreen = DISPLAY_MAIN;
}
gWasFKeyPressed = false;
gUpdateStatus = true;
processFKeyFunction(Key, false);
} }
gWasFKeyPressed = false;
gUpdateStatus = true;
processFKeyFunction(Key, false);
} }
#endif }
return; return;
} }
#ifdef ENABLE_MAIN_KEY_HOLD if (bKeyPressed)
if (bKeyPressed) { // key is pressed
{ // key is pressed gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; // beep when key is pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; // beep when key is pressed return; // don't use the key till it's released
return; // don't use the key till it's released }
}
#else
if (!bKeyPressed)
return;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
#endif
if (!gWasFKeyPressed) if (!gWasFKeyPressed)
{ // F-key wasn't pressed { // F-key wasn't pressed
const uint8_t Vfo = gEeprom.TX_CHANNEL; const uint8_t Vfo = gEeprom.TX_VFO;
gKeyInputCountdown = key_input_timeout_500ms; gKeyInputCountdown = key_input_timeout_500ms;
@@ -359,7 +365,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
// if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) // if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
// #endif // #endif
if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // user is entering frequency { // user is entering a frequency
uint32_t Frequency; uint32_t Frequency;
@@ -492,7 +498,7 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
if (!gFmRadioMode) if (!gFmRadioMode)
#endif #endif
{ {
if (gScanState == SCAN_OFF) if (gScanStateDir == SCAN_OFF)
{ {
if (gInputBoxIndex == 0) if (gInputBoxIndex == 0)
return; return;
@@ -528,10 +534,10 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
if (bKeyHeld && bKeyPressed) if (bKeyHeld && bKeyPressed)
{ // exit key held down { // exit key held down
if (gInputBoxIndex > 0) if (gInputBoxIndex > 0 || gDTMF_InputBox_Index > 0 || gDTMF_InputMode)
{ // cancel key input mode (channel/frequency entry) { // cancel key input mode (channel/frequency entry)
gDTMF_InputMode = false; gDTMF_InputMode = false;
gDTMF_InputIndex = 0; gDTMF_InputBox_Index = 0;
memset(gDTMF_String, 0, sizeof(gDTMF_String)); memset(gDTMF_String, 0, sizeof(gDTMF_String));
gInputBoxIndex = 0; gInputBoxIndex = 0;
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
@@ -542,12 +548,18 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld) static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
{ {
if (bKeyPressed && !bKeyHeld)
// menu key pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (bKeyHeld) if (bKeyHeld)
{ // menu key held down (long press) { // menu key held down (long press)
if (bKeyPressed) if (bKeyPressed)
{ // long press MENU key { // long press MENU key
gWasFKeyPressed = false;
if (gScreenToDisplay == DISPLAY_MAIN) if (gScreenToDisplay == DISPLAY_MAIN)
{ {
if (gInputBoxIndex > 0) if (gInputBoxIndex > 0)
@@ -560,71 +572,50 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
gUpdateStatus = true; gUpdateStatus = true;
#ifdef ENABLE_COPY_CHAN_TO_VFO #ifdef ENABLE_COPY_CHAN_TO_VFO
if (gEeprom.VFO_OPEN &&
gEeprom.DUAL_WATCH == DUAL_WATCH_OFF &&
gScanState == SCAN_OFF &&
gCssScanMode == CSS_SCAN_MODE_OFF)
{ // copy channel to VFO
int channel = -1; if (gEeprom.VFO_OPEN && gCssScanMode == CSS_SCAN_MODE_OFF)
int vfo = -1; {
#if 0 if (gScanStateDir != SCAN_OFF)
// copy channel to opposite VFO
if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[0]) &&
IS_MR_CHANNEL(gEeprom.ScreenChannel[1]))
{ {
channel = gEeprom.ScreenChannel[1]; if (gCurrentFunction != FUNCTION_INCOMING ||
vfo = 0; gRxReceptionMode == RX_MODE_NONE ||
gScanPauseDelayIn_10ms == 0)
{ // scan is running (not paused)
return;
}
} }
else
if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[1]) && const unsigned int vfo = get_rx_VFO();
IS_MR_CHANNEL(gEeprom.ScreenChannel[0]))
{ if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo]))
channel = gEeprom.ScreenChannel[0]; { // copy channel to VFO, then swap to the VFO
vfo = 1;
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
// copy channel to same VFO
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[gEeprom.RX_CHANNEL]))
{
channel = gEeprom.ScreenChannel[gEeprom.RX_CHANNEL];
vfo = gEeprom.RX_CHANNEL;
}
#endif
if (channel >= 0 && vfo >= 0)
{ // copy the channel into the VFO
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gEeprom.MrChannel[vfo] = channel;
gEeprom.ScreenChannel[vfo] = channel;
RADIO_ConfigureChannel(vfo, VFO_CONFIGURE_RELOAD);
channel = FREQ_CHANNEL_FIRST + gEeprom.VfoInfo[vfo].Band;
gEeprom.MrChannel[vfo] = channel;
gEeprom.ScreenChannel[vfo] = channel;
gEeprom.VfoInfo[vfo].CHANNEL_SAVE = channel;
// swap to the VFO
gEeprom.TX_CHANNEL = vfo;
gEeprom.RX_CHANNEL = vfo;
RADIO_SelectVfos();
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
RADIO_SetupRegisters(true);
// SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_CHANNEL, gRxVfo, 1);
gUpdateStatus = true;
gUpdateDisplay = true;
} }
} else
#endif {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
#endif
} }
} }
@@ -636,14 +627,10 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
const bool bFlag = (gInputBoxIndex == 0); const bool bFlag = (gInputBoxIndex == 0);
gInputBoxIndex = 0; gInputBoxIndex = 0;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (bFlag) if (bFlag)
{ {
gFlagRefreshSetting = true; gFlagRefreshSetting = true;
gRequestDisplayScreen = DISPLAY_MENU; gRequestDisplayScreen = DISPLAY_MENU;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_MENU; gAnotherVoiceID = VOICE_ID_MENU;
#endif #endif
@@ -657,6 +644,9 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld) static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
{ {
if (gCurrentFunction == FUNCTION_TRANSMIT)
return;
if (gInputBoxIndex) if (gInputBoxIndex)
{ {
if (!bKeyHeld && bKeyPressed) if (!bKeyHeld && bKeyPressed)
@@ -664,74 +654,72 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
return; return;
} }
if (bKeyHeld || !bKeyPressed) if (bKeyHeld && !gWasFKeyPressed)
{ { // long press .. toggle scanning
if (bKeyHeld || bKeyPressed) if (!bKeyPressed)
{ return; // released
if (!bKeyHeld)
return;
if (!bKeyPressed) ACTION_Scan(false);
return;
ACTION_Scan(false); gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
return; if (bKeyPressed)
} { // just pressed
// gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gBeepToPlay = BEEP_880HZ_40MS_OPTIONAL;
return;
}
// just released
if (!gWasFKeyPressed)
{ // pressed without the F-key
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (gScanState == SCAN_OFF && IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (gScanStateDir == SCAN_OFF && IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
#else #else
if (gScanState == SCAN_OFF) if (gScanStateDir == SCAN_OFF)
#endif #endif
{ { // start entering a DTMF string
gKeyInputCountdown = key_input_timeout_500ms;
memmove(gDTMF_InputBox, gDTMF_String, MIN(sizeof(gDTMF_InputBox), sizeof(gDTMF_String) - 1));
gDTMF_InputBox_Index = 0;
gDTMF_InputMode = true; gDTMF_InputMode = true;
memmove(gDTMF_InputBox, gDTMF_String, sizeof(gDTMF_InputBox));
gDTMF_InputIndex = 0; gKeyInputCountdown = key_input_timeout_500ms;
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
return;
} }
} }
else else
{ { // with the F-key
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (!gWasFKeyPressed)
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
gWasFKeyPressed = false; gWasFKeyPressed = false;
gUpdateStatus = true;
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gFlagStartScan = true;
gScanSingleFrequency = true;
gBackupCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
}
else
{ {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
} }
#else
gFlagStartScan = true;
gScanSingleFrequency = true;
gBackupCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
#endif #endif
gPttWasReleased = true; // scan the CTCSS/DCS code
gFlagStartScan = true;
gScanSingleFrequency = true;
gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
} }
gPttWasReleased = true;
gUpdateStatus = true;
} }
static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction) static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
{ {
uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_CHANNEL]; uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO];
if (bKeyHeld || !bKeyPressed) if (bKeyHeld || !bKeyPressed)
{ {
@@ -765,7 +753,7 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
} }
if (gScanState == SCAN_OFF) if (gScanStateDir == SCAN_OFF)
{ {
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(Channel)) if (IS_NOT_NOAA_CHANNEL(Channel))
@@ -796,8 +784,8 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
if (Channel == Next) if (Channel == Next)
return; return;
gEeprom.MrChannel[gEeprom.TX_CHANNEL] = Next; gEeprom.MrChannel[gEeprom.TX_VFO] = Next;
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Next; gEeprom.ScreenChannel[gEeprom.TX_VFO] = Next;
if (!bKeyHeld) if (!bKeyHeld)
{ {
@@ -810,9 +798,9 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
else else
{ {
Channel = NOAA_CHANNEL_FIRST + NUMBER_AddWithWraparound(gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] - NOAA_CHANNEL_FIRST, Direction, 0, 9); Channel = NOAA_CHANNEL_FIRST + NUMBER_AddWithWraparound(gEeprom.ScreenChannel[gEeprom.TX_VFO] - NOAA_CHANNEL_FIRST, Direction, 0, 9);
gEeprom.NoaaChannel[gEeprom.TX_CHANNEL] = Channel; gEeprom.NoaaChannel[gEeprom.TX_VFO] = Channel;
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Channel; gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel;
} }
#endif #endif
@@ -821,7 +809,10 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
return; return;
} }
// jump to the next channel
CHANNEL_Next(false, Direction); CHANNEL_Next(false, Direction);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;
gPttWasReleased = true; gPttWasReleased = true;
} }
@@ -837,31 +828,25 @@ void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
} }
#endif #endif
if (gDTMF_InputMode && bKeyPressed) if (gDTMF_InputMode && bKeyPressed && !bKeyHeld)
{ {
if (!bKeyHeld) const char Character = DTMF_GetCharacter(Key);
{ if (Character != 0xFF)
const char Character = DTMF_GetCharacter(Key); { // add key to DTMF string
if (Character != 0xFF) DTMF_Append(Character);
{ // add key to DTMF string gKeyInputCountdown = key_input_timeout_500ms;
DTMF_Append(Character); gRequestDisplayScreen = DISPLAY_MAIN;
gPttWasReleased = true;
gKeyInputCountdown = key_input_timeout_500ms; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
gRequestDisplayScreen = DISPLAY_MAIN;
gPttWasReleased = true;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
} }
} }
// TODO: ??? // TODO: ???
if (Key > KEY_PTT) // if (Key > KEY_PTT)
{ // {
Key = KEY_SIDE2; // Key = KEY_SIDE2; // what's this doing ???
} // }
switch (Key) switch (Key)
{ {

View File

@@ -86,8 +86,8 @@ void MENU_StartCssScan(int8_t Direction)
MENU_SelectNextCode(); MENU_SelectNextCode();
ScanPauseDelayIn_10ms = scan_pause_delay_in_2_10ms; gScanPauseDelayIn_10ms = scan_pause_delay_in_2_10ms;
gScheduleScanListen = false; gScheduleScanListen = false;
} }
void MENU_StopCssScan(void) void MENU_StopCssScan(void)
@@ -408,6 +408,9 @@ void MENU_AcceptSetting(void)
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
return; return;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
case MENU_T_CTCS: case MENU_T_CTCS:
pConfig = &gTxVfo->freq_config_TX; pConfig = &gTxVfo->freq_config_TX;
case MENU_R_CTCS: case MENU_R_CTCS:
@@ -436,6 +439,8 @@ void MENU_AcceptSetting(void)
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
return; return;
#pragma GCC diagnostic pop
case MENU_SFT_D: case MENU_SFT_D:
gTxVfo->TX_OFFSET_FREQUENCY_DIRECTION = gSubMenuSelection; gTxVfo->TX_OFFSET_FREQUENCY_DIRECTION = gSubMenuSelection;
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
@@ -472,7 +477,7 @@ void MENU_AcceptSetting(void)
#if 0 #if 0
gEeprom.MrChannel[0] = gSubMenuSelection; gEeprom.MrChannel[0] = gSubMenuSelection;
#else #else
gEeprom.MrChannel[gEeprom.TX_CHANNEL] = gSubMenuSelection; gEeprom.MrChannel[gEeprom.TX_VFO] = gSubMenuSelection;
#endif #endif
gRequestSaveChannel = 2; gRequestSaveChannel = 2;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD; gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
@@ -492,7 +497,7 @@ void MENU_AcceptSetting(void)
// save the channel name // save the channel name
memset(gTxVfo->Name, 0, sizeof(gTxVfo->Name)); memset(gTxVfo->Name, 0, sizeof(gTxVfo->Name));
memmove(gTxVfo->Name, edit, 10); memmove(gTxVfo->Name, edit, 10);
SETTINGS_SaveChannel(gSubMenuSelection, gEeprom.TX_CHANNEL, gTxVfo, 3); SETTINGS_SaveChannel(gSubMenuSelection, gEeprom.TX_VFO, gTxVfo, 3);
gFlagReconfigureVfos = true; gFlagReconfigureVfos = true;
return; return;
@@ -669,7 +674,7 @@ void MENU_AcceptSetting(void)
{ {
GUI_SelectNextDisplay(DISPLAY_MAIN); GUI_SelectNextDisplay(DISPLAY_MAIN);
gDTMF_InputMode = true; gDTMF_InputMode = true;
gDTMF_InputIndex = 3; gDTMF_InputBox_Index = 3;
memmove(gDTMF_InputBox, gDTMF_ID, 4); memmove(gDTMF_InputBox, gDTMF_ID, 4);
gRequestDisplayScreen = DISPLAY_INVALID; gRequestDisplayScreen = DISPLAY_INVALID;
} }
@@ -819,7 +824,7 @@ void MENU_SelectNextCode(void)
RADIO_SetupRegisters(true); RADIO_SetupRegisters(true);
ScanPauseDelayIn_10ms = (gSelectedCodeType == CODE_TYPE_CONTINUOUS_TONE) ? scan_pause_delay_in_3_10ms : scan_pause_delay_in_4_10ms; gScanPauseDelayIn_10ms = (gSelectedCodeType == CODE_TYPE_CONTINUOUS_TONE) ? scan_pause_delay_in_3_10ms : scan_pause_delay_in_4_10ms;
gUpdateDisplay = true; gUpdateDisplay = true;
} }
@@ -921,12 +926,12 @@ void MENU_ShowCurrentSetting(void)
#if 0 #if 0
gSubMenuSelection = gEeprom.MrChannel[0]; gSubMenuSelection = gEeprom.MrChannel[0];
#else #else
gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_CHANNEL]; gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_VFO];
#endif #endif
break; break;
case MENU_MEM_NAME: case MENU_MEM_NAME:
gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_CHANNEL]; gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_VFO];
break; break;
case MENU_SAVE: case MENU_SAVE:
@@ -1106,7 +1111,7 @@ void MENU_ShowCurrentSetting(void)
#if 0 #if 0
gSubMenuSelection = RADIO_FindNextChannel(gEeprom.MrChannel[0], 1, false, 1); gSubMenuSelection = RADIO_FindNextChannel(gEeprom.MrChannel[0], 1, false, 1);
#else #else
gSubMenuSelection = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_CHANNEL], 1, false, 1); gSubMenuSelection = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 1);
#endif #endif
break; break;
@@ -1193,6 +1198,9 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
if (!gIsInSubMenu) if (!gIsInSubMenu)
{ {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (gInputBoxIndex) switch (gInputBoxIndex)
{ {
case 2: case 2:
@@ -1224,6 +1232,8 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
break; break;
} }
#pragma GCC diagnostic pop
gInputBoxIndex = 0; gInputBoxIndex = 0;
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
@@ -1269,7 +1279,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 (IS_MR_CHANNEL(Value)) if (Value <= MR_CHANNEL_LAST)
{ {
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
@@ -1661,6 +1671,9 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
VFO = 0; VFO = 0;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (gMenuCursor) switch (gMenuCursor)
{ {
case MENU_DEL_CH: case MENU_DEL_CH:
@@ -1681,6 +1694,8 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
return; return;
} }
#pragma GCC diagnostic pop
Channel = RADIO_FindNextChannel(gSubMenuSelection + Direction, Direction, bCheckScanList, VFO); Channel = RADIO_FindNextChannel(gSubMenuSelection + Direction, Direction, bCheckScanList, VFO);
if (Channel != 0xFF) if (Channel != 0xFF)
gSubMenuSelection = Channel; gSubMenuSelection = Channel;

View File

@@ -37,11 +37,11 @@ uint32_t gScanFrequency;
bool gScanPauseMode; bool gScanPauseMode;
SCAN_CssState_t gScanCssState; SCAN_CssState_t gScanCssState;
volatile bool gScheduleScanListen = true; volatile bool gScheduleScanListen = true;
volatile uint16_t ScanPauseDelayIn_10ms; volatile uint16_t gScanPauseDelayIn_10ms;
uint8_t gScanProgressIndicator; uint8_t gScanProgressIndicator;
uint8_t gScanHitCount; uint8_t gScanHitCount;
bool gScanUseCssResult; bool gScanUseCssResult;
int8_t gScanState; int8_t gScanStateDir;
bool bScanKeepFrequency; bool bScanKeepFrequency;
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)
@@ -53,7 +53,9 @@ static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
uint16_t Channel; 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)
@@ -65,9 +67,9 @@ static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
} }
gInputBoxIndex = 0; gInputBoxIndex = 0;
Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
if (IS_MR_CHANNEL(Channel)) Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
if (Channel <= MR_CHANNEL_LAST)
{ {
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
@@ -93,7 +95,7 @@ static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
case 0: case 0:
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
gEeprom.CROSS_BAND_RX_TX = gBackupCROSS_BAND_RX_TX; gEeprom.CROSS_BAND_RX_TX = gBackup_CROSS_BAND_RX_TX;
gUpdateStatus = true; gUpdateStatus = true;
gFlagStopScan = true; gFlagStopScan = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD; gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
@@ -193,7 +195,7 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
} }
} }
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (gTxVfo->CHANNEL_SAVE <= MR_CHANNEL_LAST)
{ {
gScannerEditState = 1; gScannerEditState = 1;
gScanChannel = gTxVfo->CHANNEL_SAVE; gScanChannel = gTxVfo->CHANNEL_SAVE;
@@ -247,19 +249,19 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
gTxVfo->freq_config_TX.Code = gScanCssResultCode; gTxVfo->freq_config_TX.Code = gScanCssResultCode;
} }
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (gTxVfo->CHANNEL_SAVE <= MR_CHANNEL_LAST)
{ {
Channel = gScanChannel; Channel = gScanChannel;
gEeprom.MrChannel[gEeprom.TX_CHANNEL] = Channel; gEeprom.MrChannel[gEeprom.TX_VFO] = Channel;
} }
else else
{ {
Channel = gTxVfo->Band + FREQ_CHANNEL_FIRST; Channel = gTxVfo->Band + FREQ_CHANNEL_FIRST;
gEeprom.FreqChannel[gEeprom.TX_CHANNEL] = Channel; gEeprom.FreqChannel[gEeprom.TX_VFO] = Channel;
} }
gTxVfo->CHANNEL_SAVE = Channel; gTxVfo->CHANNEL_SAVE = Channel;
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Channel; gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CONFIRM; gAnotherVoiceID = VOICE_ID_CONFIRM;
#endif #endif
@@ -424,16 +426,16 @@ void SCANNER_Stop(void)
{ {
const uint8_t Previous = gRestoreMrChannel; const uint8_t Previous = gRestoreMrChannel;
gScanState = SCAN_OFF; gScanStateDir = SCAN_OFF;
if (!bScanKeepFrequency) if (!bScanKeepFrequency)
{ {
if (IS_MR_CHANNEL(gNextMrChannel)) if (gNextMrChannel <= MR_CHANNEL_LAST)
{ {
gEeprom.MrChannel[gEeprom.RX_CHANNEL] = gRestoreMrChannel; gEeprom.MrChannel[gEeprom.RX_VFO] = gRestoreMrChannel;
gEeprom.ScreenChannel[gEeprom.RX_CHANNEL] = Previous; gEeprom.ScreenChannel[gEeprom.RX_VFO] = Previous;
RADIO_ConfigureChannel(gEeprom.RX_CHANNEL, VFO_CONFIGURE_RELOAD); RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
} }
else else
{ {
@@ -446,11 +448,11 @@ void SCANNER_Stop(void)
return; return;
} }
if (!IS_MR_CHANNEL(gRxVfo->CHANNEL_SAVE)) if (gRxVfo->CHANNEL_SAVE > MR_CHANNEL_LAST)
{ {
RADIO_ApplyOffset(gRxVfo); RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo); RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_CHANNEL, gRxVfo, 1); SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_VFO, gRxVfo, 1);
return; return;
} }

View File

@@ -32,7 +32,9 @@ typedef enum SCAN_CssState_t SCAN_CssState_t;
enum enum
{ {
SCAN_OFF = 0, SCAN_REV = -1,
SCAN_OFF = 0,
SCAN_FWD = +1
}; };
extern DCS_CodeType_t gScanCssResultType; extern DCS_CodeType_t gScanCssResultType;
@@ -46,11 +48,11 @@ extern uint32_t gScanFrequency;
extern bool gScanPauseMode; extern bool gScanPauseMode;
extern SCAN_CssState_t gScanCssState; extern SCAN_CssState_t gScanCssState;
extern volatile bool gScheduleScanListen; extern volatile bool gScheduleScanListen;
extern volatile uint16_t ScanPauseDelayIn_10ms; extern volatile uint16_t gScanPauseDelayIn_10ms;
extern uint8_t gScanProgressIndicator; extern uint8_t gScanProgressIndicator;
extern uint8_t gScanHitCount; extern uint8_t gScanHitCount;
extern bool gScanUseCssResult; extern bool gScanUseCssResult;
extern int8_t gScanState; extern int8_t gScanStateDir;
extern bool bScanKeepFrequency; 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);

View File

@@ -561,7 +561,7 @@ static void UpdateFreqInput(KEY_Code_t key) {
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
if (i < freqInputIndex) { if (i < freqInputIndex) {
digitKey = freqInputArr[i]; digitKey = freqInputArr[i];
freqInputString[i] = digitKey <= KEY_9 ? '0' + digitKey : '.'; freqInputString[i] = digitKey <= KEY_9 ? '0' + digitKey-KEY_0 : '.';
} else { } else {
freqInputString[i] = '-'; freqInputString[i] = '-';
} }
@@ -569,14 +569,14 @@ static void UpdateFreqInput(KEY_Code_t key) {
uint32_t base = 100000; // 1MHz in BK units uint32_t base = 100000; // 1MHz in BK units
for (int i = dotIndex - 1; i >= 0; --i) { for (int i = dotIndex - 1; i >= 0; --i) {
tempFreq += freqInputArr[i] * base; tempFreq += (freqInputArr[i]-KEY_0) * base;
base *= 10; base *= 10;
} }
base = 10000; // 0.1MHz in BK units base = 10000; // 0.1MHz in BK units
if (dotIndex < freqInputIndex) { if (dotIndex < freqInputIndex) {
for (int i = dotIndex + 1; i < freqInputIndex; ++i) { for (int i = dotIndex + 1; i < freqInputIndex; ++i) {
tempFreq += freqInputArr[i] * base; tempFreq += (freqInputArr[i]-KEY_0) * base;
base /= 10; base /= 10;
} }
} }
@@ -1166,7 +1166,7 @@ static void Tick() {
void APP_RunSpectrum() { void APP_RunSpectrum() {
// TX here coz it always? set to active VFO // TX here coz it always? set to active VFO
currentFreq = initialFreq = currentFreq = initialFreq =
gEeprom.VfoInfo[gEeprom.TX_CHANNEL].pRX->Frequency; gEeprom.VfoInfo[gEeprom.TX_VFO].pRX->Frequency;
BackupRegisters(); BackupRegisters();

View File

@@ -48,7 +48,7 @@ typedef struct {
} Header_t; } Header_t;
typedef struct { typedef struct {
uint8_t Padding[2]; uint8_t Padding[2];
uint16_t ID; uint16_t ID;
} Footer_t; } Footer_t;
@@ -60,10 +60,10 @@ typedef struct {
typedef struct { typedef struct {
Header_t Header; Header_t Header;
struct { struct {
char Version[16]; char Version[16];
bool bHasCustomAesKey; bool bHasCustomAesKey;
bool bIsInLockScreen; bool bIsInLockScreen;
uint8_t Padding[2]; uint8_t Padding[2];
uint32_t Challenge[4]; uint32_t Challenge[4];
} Data; } Data;
} REPLY_0514_t; } REPLY_0514_t;
@@ -71,8 +71,8 @@ typedef struct {
typedef struct { typedef struct {
Header_t Header; Header_t Header;
uint16_t Offset; uint16_t Offset;
uint8_t Size; uint8_t Size;
uint8_t Padding; uint8_t Padding;
uint32_t Timestamp; uint32_t Timestamp;
} CMD_051B_t; } CMD_051B_t;
@@ -80,19 +80,19 @@ typedef struct {
Header_t Header; Header_t Header;
struct { struct {
uint16_t Offset; uint16_t Offset;
uint8_t Size; uint8_t Size;
uint8_t Padding; uint8_t Padding;
uint8_t Data[128]; uint8_t Data[128];
} Data; } Data;
} REPLY_051B_t; } REPLY_051B_t;
typedef struct { typedef struct {
Header_t Header; Header_t Header;
uint16_t Offset; uint16_t Offset;
uint8_t Size; uint8_t Size;
bool bAllowPassword; bool bAllowPassword;
uint32_t Timestamp; uint32_t Timestamp;
uint8_t Data[0]; uint8_t Data[0];
} CMD_051D_t; } CMD_051D_t;
typedef struct { typedef struct {
@@ -106,8 +106,8 @@ typedef struct {
Header_t Header; Header_t Header;
struct { struct {
uint16_t RSSI; uint16_t RSSI;
uint8_t ExNoiseIndicator; uint8_t ExNoiseIndicator;
uint8_t GlitchIndicator; uint8_t GlitchIndicator;
} Data; } Data;
} REPLY_0527_t; } REPLY_0527_t;
@@ -137,7 +137,10 @@ typedef struct {
uint32_t Timestamp; uint32_t Timestamp;
} CMD_052F_t; } CMD_052F_t;
static const uint8_t Obfuscation[16] = { 0x16, 0x6C, 0x14, 0xE6, 0x2E, 0x91, 0x0D, 0x40, 0x21, 0x35, 0xD5, 0x40, 0x13, 0x03, 0xE9, 0x80 }; static const uint8_t Obfuscation[16] =
{
0x16, 0x6C, 0x14, 0xE6, 0x2E, 0x91, 0x0D, 0x40, 0x21, 0x35, 0xD5, 0x40, 0x13, 0x03, 0xE9, 0x80
};
static union static union
{ {
@@ -157,12 +160,11 @@ static void SendReply(void *pReply, uint16_t Size)
{ {
Header_t Header; Header_t Header;
Footer_t Footer; Footer_t Footer;
uint8_t *pBytes;
uint16_t i;
if (bIsEncrypted) if (bIsEncrypted)
{ {
pBytes = (uint8_t *)pReply; uint8_t *pBytes = (uint8_t *)pReply;
unsigned int i;
for (i = 0; i < Size; i++) for (i = 0; i < Size; i++)
pBytes[i] ^= Obfuscation[i % 16]; pBytes[i] ^= Obfuscation[i % 16];
} }
@@ -171,6 +173,7 @@ static void SendReply(void *pReply, uint16_t Size)
Header.Size = Size; Header.Size = Size;
UART_Send(&Header, sizeof(Header)); UART_Send(&Header, sizeof(Header));
UART_Send(pReply, Size); UART_Send(pReply, Size);
if (bIsEncrypted) if (bIsEncrypted)
{ {
Footer.Padding[0] = Obfuscation[(Size + 0) % 16] ^ 0xFF; Footer.Padding[0] = Obfuscation[(Size + 0) % 16] ^ 0xFF;
@@ -205,14 +208,16 @@ static void SendVersion(void)
static bool IsBadChallenge(const uint32_t *pKey, const uint32_t *pIn, const uint32_t *pResponse) static bool IsBadChallenge(const uint32_t *pKey, const uint32_t *pIn, const uint32_t *pResponse)
{ {
uint8_t i; unsigned int i;
uint32_t IV[4]; uint32_t IV[4];
IV[0] = 0; IV[0] = 0;
IV[1] = 0; IV[1] = 0;
IV[2] = 0; IV[2] = 0;
IV[3] = 0; IV[3] = 0;
AES_Encrypt(pKey, IV, pIn, IV, true); AES_Encrypt(pKey, IV, pIn, IV, true);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
if (IV[i] != pResponse[i]) if (IV[i] != pResponse[i])
return true; return true;
@@ -254,10 +259,10 @@ static void CMD_051B(const uint8_t *pBuffer)
#endif #endif
memset(&Reply, 0, sizeof(Reply)); memset(&Reply, 0, sizeof(Reply));
Reply.Header.ID = 0x051C; Reply.Header.ID = 0x051C;
Reply.Header.Size = pCmd->Size + 4; Reply.Header.Size = pCmd->Size + 4;
Reply.Data.Offset = pCmd->Offset; Reply.Data.Offset = pCmd->Offset;
Reply.Data.Size = pCmd->Size; Reply.Data.Size = pCmd->Size;
if (bHasCustomAesKey) if (bHasCustomAesKey)
bLocked = gIsLocked; bLocked = gIsLocked;
@@ -294,7 +299,7 @@ static void CMD_051D(const uint8_t *pBuffer)
if (!bIsLocked) if (!bIsLocked)
{ {
uint16_t i; unsigned int i;
for (i = 0; i < (pCmd->Size / 8); i++) for (i = 0; i < (pCmd->Size / 8); i++)
{ {
const uint16_t Offset = pCmd->Offset + (i * 8U); const uint16_t Offset = pCmd->Offset + (i * 8U);
@@ -331,23 +336,25 @@ static void CMD_0529(void)
{ {
REPLY_0529_t Reply; REPLY_0529_t Reply;
Reply.Header.ID = 0x52A; Reply.Header.ID = 0x52A;
Reply.Header.Size = sizeof(Reply.Data); Reply.Header.Size = sizeof(Reply.Data);
// Original doesn't actually send current! // Original doesn't actually send current!
BOARD_ADC_GetBatteryInfo(&Reply.Data.Voltage, &Reply.Data.Current); BOARD_ADC_GetBatteryInfo(&Reply.Data.Voltage, &Reply.Data.Current);
SendReply(&Reply, sizeof(Reply)); SendReply(&Reply, sizeof(Reply));
} }
static void CMD_052D(const uint8_t *pBuffer) static void CMD_052D(const uint8_t *pBuffer)
{ {
const CMD_052D_t *pCmd = (const CMD_052D_t *)pBuffer; const CMD_052D_t *pCmd = (const CMD_052D_t *)pBuffer;
REPLY_052D_t Reply; REPLY_052D_t Reply;
bool bIsLocked; bool bIsLocked;
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
gFmRadioCountdown_500ms = fm_radio_countdown_500ms; gFmRadioCountdown_500ms = fm_radio_countdown_500ms;
#endif #endif
Reply.Header.ID = 0x052E; Reply.Header.ID = 0x052E;
Reply.Header.Size = sizeof(Reply.Data); Reply.Header.Size = sizeof(Reply.Data);
bIsLocked = bHasCustomAesKey; bIsLocked = bHasCustomAesKey;
@@ -385,7 +392,7 @@ static void CMD_052F(const uint8_t *pBuffer)
gEeprom.DUAL_WATCH = DUAL_WATCH_OFF; gEeprom.DUAL_WATCH = DUAL_WATCH_OFF;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF; gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gEeprom.RX_CHANNEL = 0; gEeprom.RX_VFO = 0;
gEeprom.DTMF_SIDE_TONE = false; gEeprom.DTMF_SIDE_TONE = false;
gEeprom.VfoInfo[0].FrequencyReverse = false; gEeprom.VfoInfo[0].FrequencyReverse = false;
gEeprom.VfoInfo[0].pRX = &gEeprom.VfoInfo[0].freq_config_RX; gEeprom.VfoInfo[0].pRX = &gEeprom.VfoInfo[0].freq_config_RX;
@@ -413,15 +420,13 @@ static void CMD_052F(const uint8_t *pBuffer)
bool UART_IsCommandAvailable(void) bool UART_IsCommandAvailable(void)
{ {
uint16_t DmaLength;
uint16_t CommandLength;
uint16_t Index; uint16_t Index;
uint16_t TailIndex; uint16_t TailIndex;
uint16_t Size; uint16_t Size;
uint16_t CRC; uint16_t CRC;
uint16_t i; uint16_t CommandLength;
uint16_t DmaLength = DMA_CH0->ST & 0xFFFU;
DmaLength = DMA_CH0->ST & 0xFFFU;
while (1) while (1)
{ {
if (gUART_WriteIndex == DmaLength) if (gUART_WriteIndex == DmaLength)
@@ -450,7 +455,7 @@ bool UART_IsCommandAvailable(void)
Index = DMA_INDEX(gUART_WriteIndex, 2); Index = DMA_INDEX(gUART_WriteIndex, 2);
Size = (UART_DMA_Buffer[DMA_INDEX(Index, 1)] << 8) | UART_DMA_Buffer[Index]; Size = (UART_DMA_Buffer[DMA_INDEX(Index, 1)] << 8) | UART_DMA_Buffer[Index];
if ((Size + 8) > sizeof(UART_DMA_Buffer)) if ((Size + 8u) > sizeof(UART_DMA_Buffer))
{ {
gUART_WriteIndex = DmaLength; gUART_WriteIndex = DmaLength;
return false; return false;
@@ -495,8 +500,11 @@ bool UART_IsCommandAvailable(void)
bIsEncrypted = true; bIsEncrypted = true;
if (bIsEncrypted) if (bIsEncrypted)
for (i = 0; i < Size + 2; i++) {
unsigned int i;
for (i = 0; i < (Size + 2u); i++)
UART_Command.Buffer[i] ^= Obfuscation[i % 16]; UART_Command.Buffer[i] ^= Obfuscation[i % 16];
}
CRC = UART_Command.Buffer[Size] | (UART_Command.Buffer[Size + 1] << 8); CRC = UART_Command.Buffer[Size] | (UART_Command.Buffer[Size + 1] << 8);

View File

@@ -142,6 +142,9 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
SYSTEM_DelayMs(60); SYSTEM_DelayMs(60);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (Beep) switch (Beep)
{ {
case BEEP_880HZ_60MS_TRIPLE_BEEP: case BEEP_880HZ_60MS_TRIPLE_BEEP:
@@ -181,6 +184,8 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
break; break;
} }
#pragma GCC diagnostic pop
SYSTEM_DelayMs(Duration); SYSTEM_DelayMs(Duration);
BK4819_EnterTxMute(); BK4819_EnterTxMute();
SYSTEM_DelayMs(20); SYSTEM_DelayMs(20);

View File

@@ -281,54 +281,7 @@ const uint8_t BITMAP_TDR2[12] =
0b00110001 0b00110001
}; };
#endif #endif
/*
const uint8_t BITMAP_SC1[8] =
{ // "I"
0b01000001,
0b01000001,
0b01111111,
0b01111111,
0b01111111,
0b01000001,
0b01000001,
0b00000000
};
const uint8_t BITMAP_SC2[8] =
{ // "II"
0b01000001,
0b01111111,
0b01111111,
0b01000001,
0b01111111,
0b01111111,
0b01000001,
0b00000000
};
*/
/*
const uint8_t BITMAP_SC1[7] =
{ // "1"
0b01000000,
0b01000000,
0b01000110,
0b01111111,
0b01000000,
0b01000000,
0b00000000
};
const uint8_t BITMAP_SC2[7] =
{ // "2"
0b01000010,
0b01100001,
0b01010001,
0b01001001,
0b01001001,
0b01000110,
0b00000000
};
*/
const uint8_t BITMAP_Antenna[5] = const uint8_t BITMAP_Antenna[5] =
{ {
0b00000011, 0b00000011,

View File

@@ -46,11 +46,6 @@ extern const uint8_t BITMAP_TDR2[12];
extern const uint8_t BITMAP_NOAA[12]; extern const uint8_t BITMAP_NOAA[12];
#endif #endif
//extern const uint8_t BITMAP_SC1[8];
//extern const uint8_t BITMAP_SC2[8];
//extern const uint8_t BITMAP_SC1[7];
//extern const uint8_t BITMAP_SC2[7];
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_AntennaLevel1[3];
extern const uint8_t BITMAP_AntennaLevel2[3]; extern const uint8_t BITMAP_AntennaLevel2[3];

View File

@@ -509,7 +509,7 @@ void BOARD_Init(void)
BOARD_PORTCON_Init(); BOARD_PORTCON_Init();
BOARD_GPIO_Init(); BOARD_GPIO_Init();
BOARD_ADC_Init(); BOARD_ADC_Init();
ST7565_Init(); ST7565_Init(true);
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
BK1080_Init(0, false); BK1080_Init(0, false);
#endif #endif
@@ -616,7 +616,7 @@ 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_CHANNEL = (Data[3] < 2) ? Data[3] : 0; gEeprom.TX_VFO = (Data[3] < 2) ? Data[3] : 0;
// 0ED0..0ED7 // 0ED0..0ED7
EEPROM_ReadBuffer(0x0ED0, Data, 8); EEPROM_ReadBuffer(0x0ED0, Data, 8);
@@ -687,7 +687,8 @@ void BOARD_EEPROM_Init(void)
// 0F18..0F1F // 0F18..0F1F
EEPROM_ReadBuffer(0x0F18, Data, 8); EEPROM_ReadBuffer(0x0F18, Data, 8);
gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 2) ? Data[0] : false; // gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 2) ? Data[0] : false;
gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 3) ? Data[0] : false; // we now have 'all' channel scan option
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
const unsigned int j = 1 + (i * 3); const unsigned int j = 1 + (i * 3);

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -102,6 +102,7 @@ void BK4819_DisableVox(void);
void BK4819_DisableDTMF(void); void BK4819_DisableDTMF(void);
void BK4819_EnableDTMF(void); void BK4819_EnableDTMF(void);
void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch); void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch);
void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay, const unsigned int level, const bool play_speaker);
void BK4819_EnterTxMute(void); void BK4819_EnterTxMute(void);
void BK4819_ExitTxMute(void); void BK4819_ExitTxMute(void);
void BK4819_Sleep(void); void BK4819_Sleep(void);

View File

@@ -58,10 +58,10 @@ enum GPIOC_PINS {
GPIOC_PIN_PTT = 5 GPIOC_PIN_PTT = 5
}; };
void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit); void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit);
uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit); uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit);
void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit); void GPIO_FlipBit( volatile uint32_t *pReg, uint8_t Bit);
void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit); void GPIO_SetBit( volatile uint32_t *pReg, uint8_t Bit);
#endif #endif

View File

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

View File

@@ -21,30 +21,29 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
enum KEY_Code_t { enum KEY_Code_e {
KEY_0 = 0, KEY_0 = 0, // 0
KEY_1 = 1, KEY_1, // 1
KEY_2 = 2, KEY_2, // 2
KEY_3 = 3, KEY_3, // 3
KEY_4 = 4, KEY_4, // 4
KEY_5 = 5, KEY_5, // 5
KEY_6 = 6, KEY_6, // 6
KEY_7 = 7, KEY_7, // 7
KEY_8 = 8, KEY_8, // 8
KEY_9 = 9, KEY_9, // 9
KEY_MENU = 10, KEY_MENU, // A
KEY_UP = 11, KEY_UP, // B
KEY_DOWN = 12, KEY_DOWN, // C
KEY_EXIT = 13, KEY_EXIT, // D
KEY_STAR = 14, KEY_STAR, // *
KEY_F = 15, KEY_F, // #
KEY_PTT = 21, KEY_PTT, //
KEY_SIDE2 = 22, KEY_SIDE2, //
KEY_SIDE1 = 23, KEY_SIDE1, //
KEY_INVALID = 255 KEY_INVALID //
}; };
typedef enum KEY_Code_e KEY_Code_t;
typedef enum KEY_Code_t KEY_Code_t;
extern KEY_Code_t gKeyReading0; extern KEY_Code_t gKeyReading0;
extern KEY_Code_t gKeyReading1; extern KEY_Code_t gKeyReading1;

View File

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

View File

@@ -82,10 +82,10 @@ void ST7565_BlitFullScreen(void)
} }
#if 0 #if 0
// whats the delay for I wonder ? .. it slows down scanning :( // whats the delay for I wonder, it holds things up :(
SYSTEM_DelayMs(20); SYSTEM_DelayMs(20);
#else #else
SYSTEM_DelayMs(1); // SYSTEM_DelayMs(1);
#endif #endif
SPI_ToggleMasterMode(&SPI0->CR, true); SPI_ToggleMasterMode(&SPI0->CR, true);
@@ -119,7 +119,11 @@ void ST7565_FillScreen(uint8_t Value)
{ {
unsigned int i; unsigned int i;
// reset some of the displays settings to try and overcome the radios hardware problem - RF corrupting the display
ST7565_Init(false);
SPI_ToggleMasterMode(&SPI0->CR, false); SPI_ToggleMasterMode(&SPI0->CR, false);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
unsigned int j; unsigned int j;
@@ -132,20 +136,26 @@ void ST7565_FillScreen(uint8_t Value)
} }
SPI_WaitForUndocumentedTxFifoStatusBit(); SPI_WaitForUndocumentedTxFifoStatusBit();
} }
SPI_ToggleMasterMode(&SPI0->CR, true); SPI_ToggleMasterMode(&SPI0->CR, true);
} }
void ST7565_Init(void) void ST7565_Init(const bool full)
{ {
SPI0_Init(); if (full)
{
SPI0_Init();
ST7565_Configure_GPIO_B11(); ST7565_HardwareReset();
SPI_ToggleMasterMode(&SPI0->CR, false); SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_WriteByte(0xE2); // internal reset ST7565_WriteByte(0xE2); // internal reset
SYSTEM_DelayMs(120); SYSTEM_DelayMs(120);
}
else
SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_WriteByte(0xA2); // bias 9 ST7565_WriteByte(0xA2); // bias 9
ST7565_WriteByte(0xC0); // com normal ST7565_WriteByte(0xC0); // com normal
@@ -157,21 +167,26 @@ void ST7565_Init(void)
ST7565_WriteByte(0xA4); // all points normal ST7565_WriteByte(0xA4); // all points normal
ST7565_WriteByte(0x24); // ST7565_WriteByte(0x24); //
ST7565_WriteByte(0x81); // volume first ? ST7565_WriteByte(0x81); // volume first ?
ST7565_WriteByte(0x1f); // contrast ? ST7565_WriteByte(0x1f); // contrast ?
ST7565_WriteByte(0x2B); // power control ?
SYSTEM_DelayMs(1); if (full)
{
ST7565_WriteByte(0x2B); // power control ?
ST7565_WriteByte(0x2E); // power control ? SYSTEM_DelayMs(1);
SYSTEM_DelayMs(1); ST7565_WriteByte(0x2E); // power control ?
ST7565_WriteByte(0x2F); // SYSTEM_DelayMs(1);
ST7565_WriteByte(0x2F); //
ST7565_WriteByte(0x2F); //
ST7565_WriteByte(0x2F); //
SYSTEM_DelayMs(40); ST7565_WriteByte(0x2F); //
ST7565_WriteByte(0x2F); //
ST7565_WriteByte(0x2F); //
ST7565_WriteByte(0x2F); //
SYSTEM_DelayMs(40);
}
ST7565_WriteByte(0x40); // start line ? ST7565_WriteByte(0x40); // start line ?
ST7565_WriteByte(0xAF); // display on ? ST7565_WriteByte(0xAF); // display on ?
@@ -180,10 +195,11 @@ void ST7565_Init(void)
SPI_ToggleMasterMode(&SPI0->CR, true); SPI_ToggleMasterMode(&SPI0->CR, true);
ST7565_FillScreen(0x00); if (full)
ST7565_FillScreen(0x00);
} }
void ST7565_Configure_GPIO_B11(void) void ST7565_HardwareReset(void)
{ {
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES); GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES);
SYSTEM_DelayMs(1); SYSTEM_DelayMs(1);

View File

@@ -30,8 +30,8 @@ void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const u
void ST7565_BlitFullScreen(void); 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(void); void ST7565_Init(const bool full);
void ST7565_Configure_GPIO_B11(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);

View File

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

460
font.c
View File

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

View File

@@ -116,8 +116,12 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
gFM_RestoreCountdown_10ms = fm_restore_countdown_10ms; gFM_RestoreCountdown_10ms = fm_restore_countdown_10ms;
#endif #endif
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT || gDTMF_CallState == DTMF_CALL_STATE_RECEIVED) if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT ||
gDTMF_auto_reset_time_500ms = 1 + (gEeprom.DTMF_auto_reset_time * 2); gDTMF_CallState == DTMF_CALL_STATE_RECEIVED ||
gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY)
{
gDTMF_auto_reset_time_500ms = gEeprom.DTMF_auto_reset_time * 2;
}
gUpdateStatus = true; gUpdateStatus = true;
return; return;
@@ -204,6 +208,9 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
DTMF_Reply(); DTMF_Reply();
if (gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO)
BK4819_PlaySingleTone(2525, 250, 0, gEeprom.DTMF_SIDE_TONE);
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
if (gAlarmState != ALARM_STATE_OFF) if (gAlarmState != ALARM_STATE_OFF)
{ {

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

14
init.c
View File

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

16
main.c
View File

@@ -174,12 +174,14 @@ void Main(void)
} }
} }
if (gEeprom.POWER_ON_PASSWORD < 1000000) #ifdef ENABLE_PWRON_PASSWORD
{ if (gEeprom.POWER_ON_PASSWORD < 1000000)
bIsInLockScreen = true; {
UI_DisplayLock(); bIsInLockScreen = true;
bIsInLockScreen = false; UI_DisplayLock();
} bIsInLockScreen = false;
}
#endif
BOOT_ProcessMode(BootMode); BOOT_ProcessMode(BootMode);
@@ -193,7 +195,7 @@ void Main(void)
AUDIO_SetVoiceID(0, VOICE_ID_WELCOME); AUDIO_SetVoiceID(0, VOICE_ID_WELCOME);
Channel = gEeprom.ScreenChannel[gEeprom.TX_CHANNEL]; Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO];
if (IS_MR_CHANNEL(Channel)) if (IS_MR_CHANNEL(Channel))
{ {
AUDIO_SetVoiceID(1, VOICE_ID_CHANNEL_MODE); AUDIO_SetVoiceID(1, VOICE_ID_CHANNEL_MODE);

37
misc.c
View File

@@ -17,6 +17,7 @@
#include <string.h> #include <string.h>
#include "misc.h" #include "misc.h"
#include "settings.h"
const uint8_t fm_resume_countdown_500ms = 2500 / 500; // 2.5 seconds const uint8_t fm_resume_countdown_500ms = 2500 / 500; // 2.5 seconds
const uint8_t fm_radio_countdown_500ms = 2000 / 500; // 2 seconds const uint8_t fm_radio_countdown_500ms = 2000 / 500; // 2 seconds
@@ -219,7 +220,7 @@ bool gKeyBeingHeld;
bool gPttIsPressed; bool gPttIsPressed;
uint8_t gPttDebounceCounter; uint8_t gPttDebounceCounter;
uint8_t gMenuListCount; uint8_t gMenuListCount;
uint8_t gBackupCROSS_BAND_RX_TX; uint8_t gBackup_CROSS_BAND_RX_TX;
uint8_t gScanDelay_10ms; uint8_t gScanDelay_10ms;
#ifdef ENABLE_AIRCOPY #ifdef ENABLE_AIRCOPY
uint8_t gAircopySendCountdown; uint8_t gAircopySendCountdown;
@@ -259,7 +260,39 @@ int16_t gCurrentRSSI[2] = {0, 0}; // now one per VFO
uint8_t gIsLocked = 0xFF; uint8_t gIsLocked = 0xFF;
// -------- unsigned int get_rx_VFO(void)
{
unsigned int rx_vfo = gEeprom.TX_VFO;
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_B)
rx_vfo = 0;
else
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_A)
rx_vfo = 1;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B)
rx_vfo = 1;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A)
rx_vfo = 0;
return rx_vfo;
}
unsigned int get_tx_VFO(void)
{
unsigned int tx_vfo = gEeprom.TX_VFO;
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_B)
tx_vfo = 1;
else
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_A)
tx_vfo = 0;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B)
tx_vfo = 1;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A)
tx_vfo = 0;
return tx_vfo;
}
void NUMBER_Get(char *pDigits, uint32_t *pInteger) void NUMBER_Get(char *pDigits, uint32_t *pInteger)
{ {

31
misc.h
View File

@@ -24,24 +24,28 @@
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#endif #endif
#define IS_MR_CHANNEL(x) ((x) >= MR_CHANNEL_FIRST && (x) <= MR_CHANNEL_LAST) #ifndef MAX
#define IS_FREQ_CHANNEL(x) ((x) >= FREQ_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST) #define MAX(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; })
#define IS_VALID_CHANNEL(x) ((x) < LAST_CHANNEL)
#ifdef ENABLE_NOAA
#define IS_NOAA_CHANNEL(x) ((x) >= NOAA_CHANNEL_FIRST && (x) <= NOAA_CHANNEL_LAST)
#define IS_NOT_NOAA_CHANNEL(x) ((x) >= MR_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST)
#endif #endif
#ifndef MIN
#define MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
#endif
#define IS_MR_CHANNEL(x) ((x) >= MR_CHANNEL_FIRST && (x) <= MR_CHANNEL_LAST)
#define IS_FREQ_CHANNEL(x) ((x) >= FREQ_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST)
#define IS_VALID_CHANNEL(x) ((x) < LAST_CHANNEL)
#define IS_NOAA_CHANNEL(x) ((x) >= NOAA_CHANNEL_FIRST && (x) <= NOAA_CHANNEL_LAST)
#define IS_NOT_NOAA_CHANNEL(x) ((x) >= MR_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST)
enum { enum {
MR_CHANNEL_FIRST = 0, MR_CHANNEL_FIRST = 0,
MR_CHANNEL_LAST = 199u, MR_CHANNEL_LAST = 199u,
FREQ_CHANNEL_FIRST = 200u, FREQ_CHANNEL_FIRST = 200u,
FREQ_CHANNEL_LAST = 206u, FREQ_CHANNEL_LAST = 206u,
#ifdef ENABLE_NOAA NOAA_CHANNEL_FIRST = 207u,
NOAA_CHANNEL_FIRST = 207u, NOAA_CHANNEL_LAST = 216u,
NOAA_CHANNEL_LAST = 216u,
#endif
LAST_CHANNEL LAST_CHANNEL
}; };
@@ -287,7 +291,7 @@ extern bool gKeyBeingHeld;
extern bool gPttIsPressed; extern bool gPttIsPressed;
extern uint8_t gPttDebounceCounter; extern uint8_t gPttDebounceCounter;
extern uint8_t gMenuListCount; extern uint8_t gMenuListCount;
extern uint8_t gBackupCROSS_BAND_RX_TX; extern uint8_t gBackup_CROSS_BAND_RX_TX;
extern uint8_t gScanDelay_10ms; extern uint8_t gScanDelay_10ms;
#ifdef ENABLE_AIRCOPY #ifdef ENABLE_AIRCOPY
extern uint8_t gAircopySendCountdown; extern uint8_t gAircopySendCountdown;
@@ -322,6 +326,9 @@ 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;
unsigned int get_tx_VFO(void);
unsigned int get_rx_VFO(void);
void NUMBER_Get(char *pDigits, uint32_t *pInteger); void NUMBER_Get(char *pDigits, uint32_t *pInteger);
void NUMBER_ToDigits(uint32_t Value, char *pDigits); 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);

171
radio.c
View File

@@ -51,7 +51,7 @@ bool RADIO_CheckValidChannel(uint16_t Channel, bool bCheckScanList, uint8_t VFO)
uint8_t PriorityCh1; uint8_t PriorityCh1;
uint8_t PriorityCh2; uint8_t PriorityCh2;
if (!IS_MR_CHANNEL(Channel)) if (Channel > MR_CHANNEL_LAST)
return false; return false;
Attributes = gMR_ChannelAttributes[Channel]; Attributes = gMR_ChannelAttributes[Channel];
@@ -176,7 +176,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
} }
#endif #endif
if (IS_MR_CHANNEL(Channel)) if (Channel <= MR_CHANNEL_LAST)
{ {
Channel = RADIO_FindNextChannel(Channel, RADIO_CHANNEL_UP, false, VFO); Channel = RADIO_FindNextChannel(Channel, RADIO_CHANNEL_UP, false, VFO);
if (Channel == 0xFF) if (Channel == 0xFF)
@@ -200,7 +200,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
uint8_t Index; uint8_t Index;
if (IS_MR_CHANNEL(Channel)) if (Channel <= MR_CHANNEL_LAST)
{ {
Channel = gEeprom.FreqChannel[VFO]; Channel = gEeprom.FreqChannel[VFO];
gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO]; gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO];
@@ -218,7 +218,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
Band = BAND6_400MHz; Band = BAND6_400MHz;
} }
if (IS_MR_CHANNEL(Channel)) if (Channel <= MR_CHANNEL_LAST)
{ {
gEeprom.VfoInfo[VFO].Band = Band; gEeprom.VfoInfo[VFO].Band = Band;
gEeprom.VfoInfo[VFO].SCANLIST1_PARTICIPATION = !!(Attributes & MR_CH_SCANLIST1); gEeprom.VfoInfo[VFO].SCANLIST1_PARTICIPATION = !!(Attributes & MR_CH_SCANLIST1);
@@ -235,7 +235,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
gEeprom.VfoInfo[VFO].SCANLIST2_PARTICIPATION = bParticipation2; gEeprom.VfoInfo[VFO].SCANLIST2_PARTICIPATION = bParticipation2;
gEeprom.VfoInfo[VFO].CHANNEL_SAVE = Channel; gEeprom.VfoInfo[VFO].CHANNEL_SAVE = Channel;
if (IS_MR_CHANNEL(Channel)) if (Channel <= MR_CHANNEL_LAST)
Base = Channel * 16; Base = Channel * 16;
else else
Base = 0x0C80 + ((Channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16); Base = 0x0C80 + ((Channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16);
@@ -332,12 +332,12 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
if (Data[5] == 0xFF) if (Data[5] == 0xFF)
{ {
gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = false; gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = false;
gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = 0; gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = PTT_ID_OFF;
} }
else else
{ {
gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = !!((Data[5] >> 0) & 1u); gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = ((Data[5] >> 0) & 1u) ? true : false;
gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = ((Data[5] >> 1) & 3u); gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = ((Data[5] >> 1) & 7u);
} }
// *************** // ***************
@@ -380,13 +380,13 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
if (Frequency >= 10800000 && Frequency < 13600000) if (Frequency >= 10800000 && Frequency < 13600000)
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF; gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF;
else else
if (!IS_MR_CHANNEL(Channel)) if (Channel > MR_CHANNEL_LAST)
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY = FREQUENCY_FloorToStep(gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY, gEeprom.VfoInfo[VFO].StepFrequency, 0); gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY = FREQUENCY_FloorToStep(gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY, gEeprom.VfoInfo[VFO].StepFrequency, 0);
RADIO_ApplyOffset(pRadio); RADIO_ApplyOffset(pRadio);
memset(gEeprom.VfoInfo[VFO].Name, 0, sizeof(gEeprom.VfoInfo[VFO].Name)); memset(gEeprom.VfoInfo[VFO].Name, 0, sizeof(gEeprom.VfoInfo[VFO].Name));
if (IS_MR_CHANNEL(Channel)) if (Channel < MR_CHANNEL_LAST)
{ // 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), gEeprom.VfoInfo[VFO].Name + 0, 8);
EEPROM_ReadBuffer(0x0F58 + (Channel * 16), gEeprom.VfoInfo[VFO].Name + 8, 2); EEPROM_ReadBuffer(0x0F58 + (Channel * 16), gEeprom.VfoInfo[VFO].Name + 8, 2);
@@ -426,22 +426,27 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo) void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
{ {
uint8_t Txp[3]; uint8_t Txp[3];
FREQUENCY_Band_t Band = FREQUENCY_GetBand(pInfo->pRX->Frequency); FREQUENCY_Band_t Band;
uint16_t Base = (Band < BAND4_174MHz) ? 0x1E60 : 0x1E00;
// *******************************
// squelch
Band = FREQUENCY_GetBand(pInfo->pRX->Frequency);
uint16_t Base = (Band < BAND4_174MHz) ? 0x1E60 : 0x1E00;
if (gEeprom.SQUELCH_LEVEL == 0) if (gEeprom.SQUELCH_LEVEL == 0)
{ // squelch == 0 (off) { // squelch == 0 (off)
pInfo->SquelchOpenRSSIThresh = 0; pInfo->SquelchOpenRSSIThresh = 0; // 0 ~ 255
pInfo->SquelchOpenNoiseThresh = 127; pInfo->SquelchOpenNoiseThresh = 127; // 127 ~ 0
pInfo->SquelchCloseGlitchThresh = 255; pInfo->SquelchCloseGlitchThresh = 255; // 255 ~ 0
pInfo->SquelchCloseRSSIThresh = 0; pInfo->SquelchCloseRSSIThresh = 0; // 0 ~ 255
pInfo->SquelchCloseNoiseThresh = 127; pInfo->SquelchCloseNoiseThresh = 127; // 127 ~ 0
pInfo->SquelchOpenGlitchThresh = 255; pInfo->SquelchOpenGlitchThresh = 255; // 255 ~ 0
} }
else else
{ // squelch >= 1 { // squelch >= 1
Base += gEeprom.SQUELCH_LEVEL; // my squelch-1 Base += gEeprom.SQUELCH_LEVEL; // my eeprom squelch-1
// VHF UHF // VHF UHF
EEPROM_ReadBuffer(Base + 0x00, &pInfo->SquelchOpenRSSIThresh, 1); // 50 10 EEPROM_ReadBuffer(Base + 0x00, &pInfo->SquelchOpenRSSIThresh, 1); // 50 10
EEPROM_ReadBuffer(Base + 0x10, &pInfo->SquelchCloseRSSIThresh, 1); // 40 5 EEPROM_ReadBuffer(Base + 0x10, &pInfo->SquelchCloseRSSIThresh, 1); // 40 5
@@ -452,6 +457,13 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
EEPROM_ReadBuffer(Base + 0x40, &pInfo->SquelchCloseGlitchThresh, 1); // 90 90 EEPROM_ReadBuffer(Base + 0x40, &pInfo->SquelchCloseGlitchThresh, 1); // 90 90
EEPROM_ReadBuffer(Base + 0x50, &pInfo->SquelchOpenGlitchThresh, 1); // 100 100 EEPROM_ReadBuffer(Base + 0x50, &pInfo->SquelchOpenGlitchThresh, 1); // 100 100
uint16_t rssi_open = pInfo->SquelchOpenRSSIThresh;
uint16_t rssi_close = pInfo->SquelchCloseRSSIThresh;
uint16_t noise_open = pInfo->SquelchOpenNoiseThresh;
uint16_t noise_close = pInfo->SquelchCloseNoiseThresh;
uint16_t glitch_open = pInfo->SquelchOpenGlitchThresh;
uint16_t glitch_close = pInfo->SquelchCloseGlitchThresh;
#if ENABLE_SQUELCH_MORE_SENSITIVE #if ENABLE_SQUELCH_MORE_SENSITIVE
// make squelch a little more sensitive // make squelch a little more sensitive
// //
@@ -459,23 +471,47 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
// //
// note that 'noise' and 'glitch' values are inverted compared to 'rssi' values // note that 'noise' and 'glitch' values are inverted compared to 'rssi' values
pInfo->SquelchOpenRSSIThresh = ((uint16_t)pInfo->SquelchOpenRSSIThresh * 8) / 9; #if 0
pInfo->SquelchCloseRSSIThresh = ((uint16_t)pInfo->SquelchOpenRSSIThresh * 8) / 9; rssi_open = (rssi_open * 8) / 9;
noise_open = (noise_open * 9) / 8;
glitch_open = (glitch_open * 9) / 8;
#else
// even more sensitive .. use when RX bandwidths are fixed (no weak signal auto adjust)
rssi_open = (rssi_open * 1) / 2;
noise_open = (noise_open * 2) / 1;
glitch_open = (glitch_open * 2) / 1;
#endif
pInfo->SquelchOpenNoiseThresh = ((uint16_t)pInfo->SquelchOpenNoiseThresh * 9) / 8; #else
pInfo->SquelchCloseNoiseThresh = ((uint16_t)pInfo->SquelchOpenNoiseThresh * 9) / 8; // more sensitive .. use when RX bandwidths are fixed (no weak signal auto adjust)
rssi_open = (rssi_open * 3) / 4;
pInfo->SquelchOpenGlitchThresh = ((uint16_t)pInfo->SquelchOpenGlitchThresh * 9) / 8; noise_open = (noise_open * 4) / 3;
pInfo->SquelchCloseGlitchThresh = ((uint16_t)pInfo->SquelchOpenGlitchThresh * 9) / 8; glitch_open = (glitch_open * 4) / 3;
#endif #endif
if (pInfo->SquelchOpenNoiseThresh > 127) rssi_close = (rssi_open * 9) / 10;
pInfo->SquelchOpenNoiseThresh = 127; noise_close = (noise_open * 10) / 9;
glitch_close = (glitch_open * 10) / 9;
if (pInfo->SquelchCloseNoiseThresh > 127) // ensure the 'close' threshold is lower than the 'open' threshold
pInfo->SquelchCloseNoiseThresh = 127; if (rssi_close == rssi_open && rssi_close >= 2)
rssi_close -= 2;
if (noise_close == noise_open && noise_close <= 125)
noise_close += 2;
if (glitch_close == glitch_open && glitch_close <= 253)
glitch_close += 2;
pInfo->SquelchOpenRSSIThresh = (rssi_open > 255) ? 255 : rssi_open;
pInfo->SquelchCloseRSSIThresh = (rssi_close > 255) ? 255 : rssi_close;
pInfo->SquelchOpenNoiseThresh = (noise_open > 127) ? 127 : noise_open;
pInfo->SquelchCloseNoiseThresh = (noise_close > 127) ? 127 : noise_close;
pInfo->SquelchOpenGlitchThresh = (glitch_open > 255) ? 255 : glitch_open;
pInfo->SquelchCloseGlitchThresh = (glitch_close > 255) ? 255 : glitch_close;
} }
// *******************************
// output power
Band = FREQUENCY_GetBand(pInfo->pTX->Frequency); Band = FREQUENCY_GetBand(pInfo->pTX->Frequency);
EEPROM_ReadBuffer(0x1ED0 + (Band * 16) + (pInfo->OUTPUT_POWER * 3), Txp, 3); EEPROM_ReadBuffer(0x1ED0 + (Band * 16) + (pInfo->OUTPUT_POWER * 3), Txp, 3);
@@ -488,6 +524,8 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
(frequencyBandTable[Band].lower + frequencyBandTable[Band].upper) / 2, (frequencyBandTable[Band].lower + frequencyBandTable[Band].upper) / 2,
frequencyBandTable[Band].upper, frequencyBandTable[Band].upper,
pInfo->pTX->Frequency); pInfo->pTX->Frequency);
// *******************************
} }
void RADIO_ApplyOffset(VFO_Info_t *pInfo) void RADIO_ApplyOffset(VFO_Info_t *pInfo)
@@ -517,30 +555,16 @@ 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_CHANNEL]; gCurrentVfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gRxVfo : &gEeprom.VfoInfo[gEeprom.TX_VFO];
} }
void RADIO_SelectVfos(void) void RADIO_SelectVfos(void)
{ {
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_B) gEeprom.TX_VFO = get_tx_VFO();
gEeprom.TX_CHANNEL = 1; gEeprom.RX_VFO = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.TX_VFO : (gEeprom.TX_VFO + 1) & 1u;
else
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_A)
gEeprom.TX_CHANNEL = 0;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B)
gEeprom.TX_CHANNEL = 1;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A)
gEeprom.TX_CHANNEL = 0;
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_VFO];
gEeprom.RX_CHANNEL = gEeprom.TX_CHANNEL; gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO];
else
gEeprom.RX_CHANNEL = (gEeprom.TX_CHANNEL == 0) ? 1 : 0;
gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_CHANNEL];
gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_CHANNEL];
RADIO_SelectCurrentVfo(); RADIO_SelectCurrentVfo();
} }
@@ -557,6 +581,9 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, false); BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, false);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (Bandwidth) switch (Bandwidth)
{ {
default: default:
@@ -572,6 +599,8 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
break; break;
} }
#pragma GCC diagnostic pop
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, false); BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, false);
BK4819_SetupPowerAmplifier(0, 0); BK4819_SetupPowerAmplifier(0, 0);
@@ -806,6 +835,9 @@ void RADIO_SetTxParameters(void)
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, false); BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, false);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (Bandwidth) switch (Bandwidth)
{ {
default: default:
@@ -821,6 +853,8 @@ void RADIO_SetTxParameters(void)
break; break;
} }
#pragma GCC diagnostic pop
BK4819_SetFrequency(gCurrentVfo->pTX->Frequency); BK4819_SetFrequency(gCurrentVfo->pTX->Frequency);
// TX compressor // TX compressor
@@ -877,10 +911,9 @@ void RADIO_SetVfoState(VfoState_t State)
VfoState[1] = VFO_STATE_TX_DISABLE; VfoState[1] = VFO_STATE_TX_DISABLE;
} }
else else
{ { // 1of11
unsigned int chan = (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF && gRxVfoIsActive) ? (gEeprom.RX_CHANNEL + 1) & 1 : gEeprom.RX_CHANNEL; // 1of11 const unsigned int vfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
chan = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.TX_CHANNEL : chan; VfoState[vfo] = State;
VfoState[chan] = State;
} }
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
@@ -902,11 +935,12 @@ void RADIO_PrepareTX(void)
gScheduleDualWatch = false; gScheduleDualWatch = false;
if (!gRxVfoIsActive) if (!gRxVfoIsActive)
{ // use the TX vfo { // use the current RX vfo
gEeprom.RX_CHANNEL = gEeprom.TX_CHANNEL; gEeprom.RX_VFO = gEeprom.TX_VFO;
gRxVfo = &gEeprom.VfoInfo[gEeprom.TX_CHANNEL]; gRxVfo = &gEeprom.VfoInfo[gEeprom.TX_VFO];
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;
@@ -939,7 +973,6 @@ void RADIO_PrepareTX(void)
State = VFO_STATE_TX_DISABLE; State = VFO_STATE_TX_DISABLE;
} }
else else
//if (TX_freq_check(gCurrentVfo->pTX->Frequency) == 0 || gCurrentVfo->CHANNEL_SAVE <= FREQ_CHANNEL_LAST)
if (TX_freq_check(gCurrentVfo->pTX->Frequency) == 0) if (TX_freq_check(gCurrentVfo->pTX->Frequency) == 0)
{ // TX frequency is allowed { // TX frequency is allowed
if (gCurrentVfo->BUSY_CHANNEL_LOCK && gCurrentFunction == FUNCTION_RECEIVE) if (gCurrentVfo->BUSY_CHANNEL_LOCK && gCurrentFunction == FUNCTION_RECEIVE)
@@ -958,10 +991,13 @@ void RADIO_PrepareTX(void)
if (State != VFO_STATE_NORMAL) if (State != VFO_STATE_NORMAL)
{ // TX not allowed { // TX not allowed
RADIO_SetVfoState(State); RADIO_SetVfoState(State);
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
gAlarmState = ALARM_STATE_OFF; gAlarmState = ALARM_STATE_OFF;
#endif #endif
gDTMF_ReplyState = DTMF_REPLY_NONE; gDTMF_ReplyState = DTMF_REPLY_NONE;
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL); AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL);
return; return;
} }
@@ -1045,8 +1081,12 @@ void RADIO_SendEndOfTransmission(void)
if (gEeprom.ROGER == ROGER_MODE_MDC) if (gEeprom.ROGER == ROGER_MODE_MDC)
BK4819_PlayRogerMDC(); BK4819_PlayRogerMDC();
if (gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO)
BK4819_PlaySingleTone(2475, 250, 28, gEeprom.DTMF_SIDE_TONE);
if (gDTMF_CallState == DTMF_CALL_STATE_NONE && if (gDTMF_CallState == DTMF_CALL_STATE_NONE &&
(gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_TX_DOWN || gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_BOTH)) (gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_TX_DOWN ||
gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_BOTH))
{ // end-of-tx { // end-of-tx
if (gEeprom.DTMF_SIDE_TONE) if (gEeprom.DTMF_SIDE_TONE)
{ {
@@ -1058,15 +1098,14 @@ void RADIO_SendEndOfTransmission(void)
BK4819_EnterDTMF_TX(gEeprom.DTMF_SIDE_TONE); BK4819_EnterDTMF_TX(gEeprom.DTMF_SIDE_TONE);
BK4819_PlayDTMFString( BK4819_PlayDTMFString(
gEeprom.DTMF_DOWN_CODE, gEeprom.DTMF_DOWN_CODE,
0, 0,
gEeprom.DTMF_FIRST_CODE_PERSIST_TIME, gEeprom.DTMF_FIRST_CODE_PERSIST_TIME,
gEeprom.DTMF_HASH_CODE_PERSIST_TIME, gEeprom.DTMF_HASH_CODE_PERSIST_TIME,
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); GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gEnableSpeaker = false; gEnableSpeaker = false;
} }

View File

@@ -44,7 +44,8 @@ enum PTT_ID_t {
PTT_ID_OFF = 0, // OFF PTT_ID_OFF = 0, // OFF
PTT_ID_TX_UP, // BEGIN OF TX PTT_ID_TX_UP, // BEGIN OF TX
PTT_ID_TX_DOWN, // END OF TX PTT_ID_TX_DOWN, // END OF TX
PTT_ID_BOTH // BOTH PTT_ID_BOTH, // BOTH
PTT_ID_APOLLO // Apolo quindar tones
}; };
typedef enum PTT_ID_t PTT_ID_t; typedef enum PTT_ID_t PTT_ID_t;

View File

@@ -77,20 +77,20 @@ 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 (gScanState == SCAN_OFF && gCssScanMode == CSS_SCAN_MODE_OFF && gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) if (gScanStateDir == SCAN_OFF && gCssScanMode == CSS_SCAN_MODE_OFF && 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 (gScanState == SCAN_OFF && gCssScanMode == CSS_SCAN_MODE_OFF && gEeprom.DUAL_WATCH == DUAL_WATCH_OFF) if (gScanStateDir == SCAN_OFF && gCssScanMode == CSS_SCAN_MODE_OFF && 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 (gScanState != SCAN_OFF || gCssScanMode == CSS_SCAN_MODE_SCANNING) if (gScanStateDir != SCAN_OFF || gCssScanMode == CSS_SCAN_MODE_SCANNING)
if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT) if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT)
DECREMENT_AND_TRIGGER(ScanPauseDelayIn_10ms, gScheduleScanListen); DECREMENT_AND_TRIGGER(gScanPauseDelayIn_10ms, gScheduleScanListen);
DECREMENT_AND_TRIGGER(gTailNoteEliminationCountdown_10ms, gFlagTailNoteEliminationComplete); DECREMENT_AND_TRIGGER(gTailNoteEliminationCountdown_10ms, gFlagTailNoteEliminationComplete);

View File

@@ -117,8 +117,10 @@ void SETTINGS_SaveSettings(void)
EEPROM_WriteBuffer(0x0E90, State); EEPROM_WriteBuffer(0x0E90, State);
memset(Password, 0xFF, sizeof(Password)); memset(Password, 0xFF, sizeof(Password));
Password[0] = gEeprom.POWER_ON_PASSWORD; #ifdef ENABLE_PWRON_PASSWORD
EEPROM_WriteBuffer(0x0E98, State); Password[0] = gEeprom.POWER_ON_PASSWORD;
#endif
EEPROM_WriteBuffer(0x0E98, Password);
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
memset(State, 0xFF, sizeof(State)); memset(State, 0xFF, sizeof(State));
@@ -133,7 +135,7 @@ void SETTINGS_SaveSettings(void)
#endif #endif
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_CHANNEL; State[3] = gEeprom.TX_VFO;
EEPROM_WriteBuffer(0x0EA8, State); EEPROM_WriteBuffer(0x0EA8, State);
State[0] = gEeprom.DTMF_SIDE_TONE; State[0] = gEeprom.DTMF_SIDE_TONE;
@@ -184,10 +186,6 @@ void SETTINGS_SaveSettings(void)
EEPROM_WriteBuffer(0x0F40, State); EEPROM_WriteBuffer(0x0F40, State);
} }
void SETTINGS_LoadChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO)
{
}
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode) void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode)
{ {
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
@@ -197,13 +195,13 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
const uint16_t OffsetMR = Channel * 16; const uint16_t OffsetMR = Channel * 16;
uint16_t OffsetVFO = OffsetMR; uint16_t OffsetVFO = OffsetMR;
if (!IS_MR_CHANNEL(Channel)) if (Channel > MR_CHANNEL_LAST)
{ // 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 || !IS_MR_CHANNEL(Channel)) if (Mode >= 2 || Channel > MR_CHANNEL_LAST)
{ // copy VFO to a channel { // copy VFO to a channel
uint8_t State[8]; uint8_t State[8];
@@ -221,15 +219,16 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
| (pVFO->OUTPUT_POWER << 2) | (pVFO->OUTPUT_POWER << 2)
| (pVFO->CHANNEL_BANDWIDTH << 1) | (pVFO->CHANNEL_BANDWIDTH << 1)
| (pVFO->FrequencyReverse << 0); | (pVFO->FrequencyReverse << 0);
State[5] = (pVFO->DTMF_PTT_ID_TX_MODE << 1) | (pVFO->DTMF_DECODING_ENABLE << 0); State[5] = ((pVFO->DTMF_PTT_ID_TX_MODE & 7u) << 1) | ((pVFO->DTMF_DECODING_ENABLE & 1u) << 0);
State[6] = pVFO->STEP_SETTING; State[6] = pVFO->STEP_SETTING;
State[7] = pVFO->SCRAMBLING_TYPE; State[7] = pVFO->SCRAMBLING_TYPE;
EEPROM_WriteBuffer(OffsetVFO + 8, State); EEPROM_WriteBuffer(OffsetVFO + 8, State);
SETTINGS_UpdateChannel(Channel, pVFO, true); SETTINGS_UpdateChannel(Channel, pVFO, true);
if (IS_MR_CHANNEL(Channel)) if (Channel <= MR_CHANNEL_LAST)
{ { // it's a memory channel
#ifndef ENABLE_KEEP_MEM_NAME #ifndef ENABLE_KEEP_MEM_NAME
// clear/reset the channel name // clear/reset the channel name
//memset(&State, 0xFF, sizeof(State)); //memset(&State, 0xFF, sizeof(State));
@@ -262,7 +261,7 @@ void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep)
uint8_t Attributes = 0xFF; // default attributes uint8_t Attributes = 0xFF; // default attributes
uint16_t Offset = 0x0D60 + (Channel & ~7u); uint16_t Offset = 0x0D60 + (Channel & ~7u);
Attributes &= ~MR_CH_COMPAND; // default to '0' = compander disabled Attributes &= (uint8_t)(~MR_CH_COMPAND); // default to '0' = compander disabled
EEPROM_ReadBuffer(Offset, State, sizeof(State)); EEPROM_ReadBuffer(Offset, State, sizeof(State));
@@ -280,8 +279,9 @@ void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep)
gMR_ChannelAttributes[Channel] = Attributes; gMR_ChannelAttributes[Channel] = Attributes;
// #ifndef ENABLE_KEEP_MEM_NAME // #ifndef ENABLE_KEEP_MEM_NAME
if (IS_MR_CHANNEL(Channel)) if (Channel <= MR_CHANNEL_LAST)
{ { // it's a memory channel
const uint16_t OffsetMR = Channel * 16; const uint16_t OffsetMR = Channel * 16;
if (!keep) if (!keep)
{ // clear/reset the channel name { // clear/reset the channel name

View File

@@ -121,8 +121,8 @@ typedef struct {
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
uint8_t NoaaChannel[2]; uint8_t NoaaChannel[2];
#endif #endif
uint8_t RX_CHANNEL; uint8_t RX_VFO;
uint8_t TX_CHANNEL; uint8_t TX_VFO;
uint8_t field7_0xa; uint8_t field7_0xa;
uint8_t field8_0xb; uint8_t field8_0xb;

View File

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

View File

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

View File

@@ -21,7 +21,7 @@
char gInputBox[8]; char gInputBox[8];
uint8_t gInputBoxIndex; uint8_t gInputBoxIndex;
void INPUTBOX_Append(char Digit) void INPUTBOX_Append(const KEY_Code_t Digit)
{ {
if (gInputBoxIndex >= sizeof(gInputBox)) if (gInputBoxIndex >= sizeof(gInputBox))
return; return;
@@ -29,6 +29,7 @@ void INPUTBOX_Append(char Digit)
if (gInputBoxIndex == 0) if (gInputBoxIndex == 0)
memset(gInputBox, 10, sizeof(gInputBox)); memset(gInputBox, 10, sizeof(gInputBox));
gInputBox[gInputBoxIndex++] = Digit; if (Digit >= KEY_0 && Digit != KEY_INVALID)
gInputBox[gInputBoxIndex++] = (char)(Digit - KEY_0);
} }

View File

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

View File

@@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef ENABLE_PWRON_PASSWORD
#include <string.h> #include <string.h>
#include "ARMCM0.h" #include "ARMCM0.h"
@@ -156,3 +158,5 @@ void UI_DisplayLock(void)
} }
} }
} }
#endif

View File

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

127
ui/main.c
View File

@@ -14,6 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
#pragma GCC diagnostic pop
#include <string.h> #include <string.h>
#include <stdlib.h> // abs() #include <stdlib.h> // abs()
@@ -42,6 +46,9 @@ center_line_t center_line = CENTER_LINE_NONE;
void UI_drawBars(uint8_t *p, const unsigned int level) void UI_drawBars(uint8_t *p, const unsigned int level)
{ {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (level) switch (level)
{ {
default: default:
@@ -54,6 +61,8 @@ void UI_drawBars(uint8_t *p, const unsigned int level)
case 1: memmove(p + 0, BITMAP_Antenna, sizeof(BITMAP_Antenna)); case 1: memmove(p + 0, BITMAP_Antenna, sizeof(BITMAP_Antenna));
case 0: break; case 0: break;
} }
#pragma GCC diagnostic pop
} }
#ifdef ENABLE_AUDIO_BAR #ifdef ENABLE_AUDIO_BAR
@@ -85,56 +94,30 @@ void UI_drawBars(uint8_t *p, const unsigned int level)
const unsigned int bar_width = LCD_WIDTH - 2 - bar_x; const unsigned int bar_width = LCD_WIDTH - 2 - bar_x;
unsigned int i; unsigned int i;
if (gScreenToDisplay != DISPLAY_MAIN)
return;
#if 1
// TX audio level
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; // screen is in use 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 max = 65535; const unsigned int sqrt_level = sqrt16((level < 65535) ? level : 65535);
// const unsigned int level = ((voice_amp * bar_width) + (max / 2)) / max; // with rounding const unsigned int len = (sqrt_level <= bar_width) ? sqrt_level : bar_width;
// const unsigned int len = (level <= bar_width) ? level : bar_width;
// 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;
#else
// TX/RX AF input level (dB)
const uint8_t af_tx_rx = BK4819_GetAfTxRx(); // 6:0
const unsigned int max = 63;
const unsigned int level = (((uint16_t)af_tx_rx * bar_width) + (max / 2)) / max; // with rounding
const unsigned int len = (level <= bar_width) ? level : bar_width;
#endif
uint8_t *p_line = gFrameBuffer[line]; uint8_t *p_line = gFrameBuffer[line];
memset(p_line, 0, LCD_WIDTH); memset(p_line, 0, LCD_WIDTH);
#if 1 for (i = 0; i < bar_width; i++)
// solid bar p_line[bar_x + i] = (i > len) ? ((i & 1) == 0) ? 0x41 : 0x00 : ((i & 1) == 0) ? 0x7f : 0x3e;
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 (gCurrentFunction == FUNCTION_TRANSMIT) if (gCurrentFunction == FUNCTION_TRANSMIT)
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
@@ -172,6 +155,7 @@ void UI_drawBars(uint8_t *p, const unsigned int level)
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)
@@ -212,6 +196,8 @@ void UI_UpdateRSSI(const int16_t rssi, const int vfo)
{ {
#ifdef ENABLE_RSSI_BAR #ifdef ENABLE_RSSI_BAR
(void)vfo; // unused
// optional larger RSSI dBm, S-point and bar level // optional larger RSSI dBm, S-point and bar level
if (center_line != CENTER_LINE_RSSI) if (center_line != CENTER_LINE_RSSI)
@@ -331,13 +317,13 @@ void UI_DisplayMain(void)
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;
uint8_t channel = gEeprom.TX_CHANNEL; unsigned int channel = gEeprom.TX_VFO;
// uint8_t tx_channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_CHANNEL : gEeprom.TX_CHANNEL; // unsigned int tx_channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
const bool same_vfo = (channel == vfo_num) ? true : false; const bool same_vfo = (channel == vfo_num) ? true : false;
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];
uint8_t mode = 0; unsigned int mode = 0;
uint8_t state; unsigned int state;
if (single_vfo) if (single_vfo)
{ // we're in single VFO mode - screen is dedicated to just one VFO { // we're in single VFO mode - screen is dedicated to just one VFO
@@ -349,7 +335,7 @@ void UI_DisplayMain(void)
} }
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF && gRxVfoIsActive) if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF && gRxVfoIsActive)
channel = gEeprom.RX_CHANNEL; // we're currently monitoring the other VFO channel = gEeprom.RX_VFO; // we're currently monitoring the other VFO
if (channel != vfo_num) if (channel != vfo_num)
{ {
@@ -364,7 +350,7 @@ void UI_DisplayMain(void)
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT) if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT)
strcpy(String, (gDTMF_State == DTMF_STATE_CALL_OUT_RSP) ? "CALL OUT(RSP)" : "CALL OUT"); strcpy(String, (gDTMF_State == DTMF_STATE_CALL_OUT_RSP) ? "CALL OUT(RSP)" : "CALL OUT");
else else
if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED) if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED || gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY)
sprintf(String, "CALL FRM:%s", (DTMF_FindContact(gDTMF_Caller, Contact)) ? Contact : gDTMF_Caller); sprintf(String, "CALL FRM:%s", (DTMF_FindContact(gDTMF_Caller, Contact)) ? Contact : gDTMF_Caller);
else else
if (gDTMF_IsTx) if (gDTMF_IsTx)
@@ -373,10 +359,8 @@ void UI_DisplayMain(void)
else else
{ {
sprintf(String, ">%s", gDTMF_InputBox); sprintf(String, ">%s", gDTMF_InputBox);
center_line = CENTER_LINE_IN_USE;
} }
UI_PrintString(String, 2, 0, vfo_num * 3, 8); UI_PrintString(String, 2, 0, 0 + (vfo_num * 3), 8);
memset(String, 0, sizeof(String)); memset(String, 0, sizeof(String));
if (!gDTMF_InputMode) if (!gDTMF_InputMode)
@@ -385,16 +369,12 @@ void UI_DisplayMain(void)
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT) if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT)
sprintf(String, ">%s", (DTMF_FindContact(gDTMF_String, Contact)) ? Contact : gDTMF_String); sprintf(String, ">%s", (DTMF_FindContact(gDTMF_String, Contact)) ? Contact : gDTMF_String);
else else
if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED) if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED || gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY)
sprintf(String, ">%s", (DTMF_FindContact(gDTMF_Callee, Contact)) ? Contact : gDTMF_Callee); sprintf(String, ">%s", (DTMF_FindContact(gDTMF_Callee, Contact)) ? Contact : gDTMF_Callee);
else else
if (gDTMF_IsTx) if (gDTMF_IsTx)
sprintf(String, ">%s", gDTMF_String); sprintf(String, ">%s", gDTMF_String);
} }
else
{
center_line = CENTER_LINE_IN_USE;
}
UI_PrintString(String, 2, 0, 2 + (vfo_num * 3), 8); UI_PrintString(String, 2, 0, 2 + (vfo_num * 3), 8);
center_line = CENTER_LINE_IN_USE; center_line = CENTER_LINE_IN_USE;
@@ -427,7 +407,7 @@ void UI_DisplayMain(void)
else else
#endif #endif
{ {
channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_CHANNEL : gEeprom.TX_CHANNEL; channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
if (channel == vfo_num) if (channel == vfo_num)
{ // show the TX symbol { // show the TX symbol
mode = 1; mode = 1;
@@ -445,7 +425,7 @@ void UI_DisplayMain(void)
if ((gCurrentFunction == FUNCTION_RECEIVE || if ((gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR || gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING) && gCurrentFunction == FUNCTION_INCOMING) &&
gEeprom.RX_CHANNEL == 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);
@@ -455,10 +435,10 @@ void UI_DisplayMain(void)
} }
} }
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num])) if (gEeprom.ScreenChannel[vfo_num] <= MR_CHANNEL_LAST)
{ // channel mode { // channel mode
const unsigned int x = 2; const unsigned int x = 2;
const bool inputting = (gInputBoxIndex == 0 || gEeprom.TX_CHANNEL != 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 NUMBER_ToDigits(gEeprom.ScreenChannel[vfo_num] + 1, String); // show the memory channel number
else else
@@ -478,7 +458,7 @@ void UI_DisplayMain(void)
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
else else
{ {
if (gInputBoxIndex == 0 || gEeprom.TX_CHANNEL != vfo_num) if (gInputBoxIndex == 0 || gEeprom.TX_VFO != vfo_num)
{ // channel number { // channel number
sprintf(String, "N%u", 1 + gEeprom.ScreenChannel[vfo_num] - NOAA_CHANNEL_FIRST); sprintf(String, "N%u", 1 + gEeprom.ScreenChannel[vfo_num] - NOAA_CHANNEL_FIRST);
} }
@@ -497,7 +477,7 @@ void UI_DisplayMain(void)
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
if (gCurrentFunction == FUNCTION_TRANSMIT && gAlarmState == ALARM_STATE_ALARM) if (gCurrentFunction == FUNCTION_TRANSMIT && gAlarmState == ALARM_STATE_ALARM)
{ {
channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_CHANNEL : gEeprom.TX_CHANNEL; channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
if (channel == vfo_num) if (channel == vfo_num)
state = VFO_STATE_ALARM; state = VFO_STATE_ALARM;
} }
@@ -506,11 +486,11 @@ void UI_DisplayMain(void)
if (state != VFO_STATE_NORMAL) if (state != VFO_STATE_NORMAL)
{ {
const char *state_list[] = {"", "BUSY", "BAT LOW", "TX DISABLE", "TIMEOUT", "ALARM", "VOLT HIGH"}; const char *state_list[] = {"", "BUSY", "BAT LOW", "TX DISABLE", "TIMEOUT", "ALARM", "VOLT HIGH"};
if (state >= 0 && 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_CHANNEL == 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); UI_DisplayFrequency(gInputBox, 32, line, true, false);
@@ -521,13 +501,13 @@ void UI_DisplayMain(void)
uint32_t frequency = gEeprom.VfoInfo[vfo_num].pRX->Frequency; uint32_t frequency = gEeprom.VfoInfo[vfo_num].pRX->Frequency;
if (gCurrentFunction == FUNCTION_TRANSMIT) if (gCurrentFunction == FUNCTION_TRANSMIT)
{ // transmitting { // transmitting
channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_CHANNEL : gEeprom.TX_CHANNEL; channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
if (channel == vfo_num) if (channel == vfo_num)
frequency = gEeprom.VfoInfo[vfo_num].pTX->Frequency; frequency = gEeprom.VfoInfo[vfo_num].pTX->Frequency;
} }
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num])) if (gEeprom.ScreenChannel[vfo_num] <= MR_CHANNEL_LAST)
{ // channel mode { // it's a channel
// show the channel symbols // show the channel symbols
const uint8_t attributes = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; const uint8_t attributes = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
@@ -544,6 +524,9 @@ void UI_DisplayMain(void)
#endif #endif
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (gEeprom.CHANNEL_DISPLAY_MODE) switch (gEeprom.CHANNEL_DISPLAY_MODE)
{ {
case MDF_FREQUENCY: // show the channel frequency case MDF_FREQUENCY: // show the channel frequency
@@ -593,6 +576,8 @@ void UI_DisplayMain(void)
break; break;
} }
#pragma GCC diagnostic pop
} }
else else
{ // frequency mode { // frequency mode
@@ -658,7 +643,7 @@ void UI_DisplayMain(void)
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 >= 0 && code_type < ARRAY_SIZE(code_list)) if (code_type < ARRAY_SIZE(code_list))
strcpy(String, code_list[code_type]); strcpy(String, code_list[code_type]);
} }
UI_PrintStringSmall(String, LCD_WIDTH + 24, 0, line + 1); UI_PrintStringSmall(String, LCD_WIDTH + 24, 0, line + 1);
@@ -667,7 +652,7 @@ void UI_DisplayMain(void)
{ // show the TX power { // show the TX power
const char pwr_list[] = "LMH"; const char pwr_list[] = "LMH";
const unsigned int i = gEeprom.VfoInfo[vfo_num].OUTPUT_POWER; const unsigned int i = gEeprom.VfoInfo[vfo_num].OUTPUT_POWER;
String[0] = (i >= 0 && i < ARRAY_SIZE(pwr_list)) ? pwr_list[i] : '\0'; String[0] = (i < ARRAY_SIZE(pwr_list)) ? pwr_list[i] : '\0';
String[1] = '\0'; String[1] = '\0';
UI_PrintStringSmall(String, LCD_WIDTH + 46, 0, line + 1); UI_PrintStringSmall(String, LCD_WIDTH + 46, 0, line + 1);
} }
@@ -721,14 +706,14 @@ void UI_DisplayMain(void)
#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_CHANNEL].AM_mode && gSetting_AM_fix) if (rx && gEeprom.VfoInfo[gEeprom.RX_VFO].AM_mode && 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_CHANNEL, String); AM_fix_print_data(gEeprom.RX_VFO, String);
UI_PrintStringSmall(String, 2, 0, 3); UI_PrintStringSmall(String, 2, 0, 3);
} }
else else
@@ -738,7 +723,7 @@ void UI_DisplayMain(void)
if (rx) if (rx)
{ {
center_line = CENTER_LINE_RSSI; center_line = CENTER_LINE_RSSI;
UI_DisplayRSSIBar(gCurrentRSSI[gEeprom.RX_CHANNEL], false); UI_DisplayRSSIBar(gCurrentRSSI[gEeprom.RX_VFO], false);
} }
else else
#endif #endif

View File

@@ -195,7 +195,7 @@ const char gSubMenu_CHAN[3][10] =
const char gSubMenu_XB[3][10] = const char gSubMenu_XB[3][10] =
{ {
"MAIN\nVFO", "RX\nVFO",
"UPPER\nVFO", "UPPER\nVFO",
"LOWER\nVFO" "LOWER\nVFO"
}; };
@@ -240,12 +240,13 @@ const char gSubMenu_D_RSP[4][11] =
"BOTH" "BOTH"
}; };
const char gSubMenu_PTT_ID[4][7] = const char gSubMenu_PTT_ID[5][15] =
{ {
"OFF", "OFF",
"KEY UP", "KEY\nUP",
"KEY DN", "KEY\nDOWN",
"BOTH" "KEY\nUP+DOWN",
"APOLLO\nQUINDAR"
}; };
const char gSubMenu_PONMSG[4][8] = const char gSubMenu_PONMSG[4][8] =
@@ -436,6 +437,9 @@ void UI_DisplayMenu(void)
bool already_printed = false; bool already_printed = false;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (gMenuCursor) switch (gMenuCursor)
{ {
case MENU_SQL: case MENU_SQL:
@@ -806,6 +810,8 @@ void UI_DisplayMenu(void)
} }
} }
#pragma GCC diagnostic pop
if (!already_printed) if (!already_printed)
{ // we now do multi-line text in a single string { // we now do multi-line text in a single string

View File

@@ -139,7 +139,7 @@ extern const char gSubMenu_MDF[4][15];
extern const char gSubMenu_AL_MOD[2][5]; extern const char gSubMenu_AL_MOD[2][5];
#endif #endif
extern const char gSubMenu_D_RSP[4][11]; extern const char gSubMenu_D_RSP[4][11];
extern const char gSubMenu_PTT_ID[4][7]; extern const char gSubMenu_PTT_ID[5][15];
extern const char gSubMenu_PONMSG[4][8]; extern const char gSubMenu_PONMSG[4][8];
extern const char gSubMenu_ROGER[3][9]; extern const char gSubMenu_ROGER[3][9];
extern const char gSubMenu_RESET[2][4]; extern const char gSubMenu_RESET[2][4];

View File

@@ -28,6 +28,7 @@
#include "helper/battery.h" #include "helper/battery.h"
#include "misc.h" #include "misc.h"
#include "settings.h" #include "settings.h"
#include "ui/battery.h"
#include "ui/helper.h" #include "ui/helper.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "ui/status.h" #include "ui/status.h"
@@ -94,23 +95,25 @@ void UI_DisplayStatus(const bool test_display)
else else
#endif #endif
// SCAN indicator // SCAN indicator
if (gScanState != SCAN_OFF || gScreenToDisplay == DISPLAY_SCANNER || test_display) if (gScanStateDir != SCAN_OFF || gScreenToDisplay == DISPLAY_SCANNER || test_display)
{ {
if (gEeprom.SCAN_LIST_DEFAULT == 0) if (gNextMrChannel <= MR_CHANNEL_LAST)
// memmove(line + x, BITMAP_SC1, sizeof(BITMAP_SC1)); { // channel mode
UI_PrintStringSmallBuffer("1", line + x); if (gEeprom.SCAN_LIST_DEFAULT == 0)
UI_PrintStringSmallBuffer("1", line + x);
else
if (gEeprom.SCAN_LIST_DEFAULT == 1)
UI_PrintStringSmallBuffer("2", line + x);
else
if (gEeprom.SCAN_LIST_DEFAULT == 2)
UI_PrintStringSmallBuffer("*", line + x);
}
else else
if (gEeprom.SCAN_LIST_DEFAULT == 1) { // frequency mode
// memmove(line + x, BITMAP_SC2, sizeof(BITMAP_SC2)); UI_PrintStringSmallBuffer("S", line + x);
UI_PrintStringSmallBuffer("2", line + x); }
else
if (gEeprom.SCAN_LIST_DEFAULT == 2)
// memmove(line + x, BITMAP_SCA, sizeof(BITMAP_SCA));
UI_PrintStringSmallBuffer("*", line + x);
// x1 = x + sizeof(BITMAP_SC1);
x1 = x + 7; x1 = x + 7;
} }
// x += sizeof(BITMAP_SC1);
x += 7; // font character width x += 7; // font character width
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
@@ -215,49 +218,7 @@ void UI_DisplayStatus(const bool test_display)
x += sizeof(BITMAP_USB_C); x += sizeof(BITMAP_USB_C);
// BATTERY LEVEL indicator // BATTERY LEVEL indicator
if (gBatteryDisplayLevel >= 2 && !gLowBattery) UI_DrawBattery(line + x, gBatteryDisplayLevel, gLowBattery);
{
line += x;
memmove(line, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
#ifndef ENABLE_REVERSE_BAT_SYMBOL
line += sizeof(BITMAP_BatteryLevel1);
{
const int8_t pos[] = {-4, -7, -10, 13};
for (unsigned int i = 0; i < ARRAY_SIZE(pos); i++)
if (gBatteryDisplayLevel >= (2 + i))
memmove(line + pos[i], BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
/* switch (gBatteryDisplayLevel)
{
default:
case 5: memmove(line - 13, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
case 4: memmove(line - 10, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
case 3: memmove(line - 7, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
case 2: memmove(line - 4, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
}
*/ }
#else
{
const int8_t pos[] = {3, 6, 9, 12};
for (unsigned int i = 0; i < ARRAY_SIZE(pos); i++)
if (gBatteryDisplayLevel >= (2 + i))
memmove(line + pos[i], BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
/*
switch (gBatteryDisplayLevel)
{
default:
case 5: memmove(line + 12, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
case 4: memmove(line + 9, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
case 3: memmove(line + 6, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
case 2: memmove(line + 3, BITMAP_BatteryLevel, sizeof(BITMAP_BatteryLevel));
}
*/ }
#endif
}
else
if (gLowBatteryBlink == 1)
memmove(line + x, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
// ************** // **************

45
ui/ui.c
View File

@@ -77,33 +77,28 @@ void GUI_DisplayScreen(void)
void GUI_SelectNextDisplay(GUI_DisplayType_t Display) void GUI_SelectNextDisplay(GUI_DisplayType_t Display)
{ {
if (Display != DISPLAY_INVALID) if (Display == DISPLAY_INVALID)
return;
if (gScreenToDisplay != Display)
{ {
if (gScreenToDisplay != Display) DTMF_clear_input_box();
{
gInputBoxIndex = 0;
gIsInSubMenu = false;
gCssScanMode = CSS_SCAN_MODE_OFF;
gScanState = SCAN_OFF;
#ifdef ENABLE_FMRADIO
gFM_ScanState = FM_SCAN_OFF;
#endif
gAskForConfirmation = 0;
gDTMF_InputMode = false;
gDTMF_InputIndex = 0;
gAskToSave = false;
gAskToDelete = false;
if (gWasFKeyPressed) gInputBoxIndex = 0;
{ gIsInSubMenu = false;
gWasFKeyPressed = false; gCssScanMode = CSS_SCAN_MODE_OFF;
gUpdateStatus = true; gScanStateDir = SCAN_OFF;
} #ifdef ENABLE_FMRADIO
gFM_ScanState = FM_SCAN_OFF;
#endif
gAskForConfirmation = 0;
gAskToSave = false;
gAskToDelete = false;
gWasFKeyPressed = false;
gUpdateStatus = true; gUpdateStatus = true;
}
gUpdateDisplay = true;
gScreenToDisplay = Display;
} }
gScreenToDisplay = Display;
gUpdateDisplay = true;
} }

Binary file not shown.

Binary file not shown.