Compare commits
227 Commits
v0.9
...
lowest_pow
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed5fe91d35 | ||
|
|
39eb3e835e | ||
|
|
0d66eb8577 | ||
|
|
13b6bb06b2 | ||
|
|
88f3537af0 | ||
|
|
de8c501d65 | ||
|
|
76bbaf9442 | ||
|
|
c4d9cfc895 | ||
|
|
2a75f8a9be | ||
|
|
e7a21c470f | ||
|
|
fc679c77a4 | ||
|
|
1151cf8667 | ||
|
|
af6b542da1 | ||
|
|
cc49a5007c | ||
|
|
a99d2dd1b1 | ||
|
|
9dc79ce868 | ||
|
|
80fa310646 | ||
|
|
7f5236c44e | ||
|
|
4b583bf2bd | ||
|
|
fa5d3c1594 | ||
|
|
1a53586922 | ||
|
|
687b63abb6 | ||
|
|
06f1c651bc | ||
|
|
33e4e3c4e0 | ||
|
|
93b97eff0a | ||
|
|
8638d37431 | ||
|
|
716e9e23b8 | ||
|
|
d0ae34f9b4 | ||
|
|
bd17aea72b | ||
|
|
34d688b101 | ||
|
|
8c7f736797 | ||
|
|
a19579a888 | ||
|
|
00a2bc75b8 | ||
|
|
268c4dece3 | ||
|
|
0c2fc6184c | ||
|
|
6bdce2d0e2 | ||
|
|
42a2e16e0e | ||
|
|
2e69acbdc4 | ||
|
|
eb6a3d0867 | ||
|
|
e22cc4ccd0 | ||
|
|
a153e63be1 | ||
|
|
4322a7d8a9 | ||
|
|
1203fdf0ca | ||
|
|
cfc4763dd1 | ||
|
|
b6a49db31d | ||
|
|
82ddbcd375 | ||
|
|
335c2ec9cd | ||
|
|
4249d917f8 | ||
|
|
2164461449 | ||
|
|
c3906f42f8 | ||
|
|
d055fb0024 | ||
|
|
c4ad9c6501 | ||
|
|
4fd1ab8899 | ||
|
|
0793b68971 | ||
|
|
f7061c3195 | ||
|
|
5e78916dd3 | ||
|
|
13c17ad073 | ||
|
|
c697596806 | ||
|
|
5c1cb4f2fc | ||
|
|
754d2ce5fb | ||
|
|
c76a96c3ad | ||
|
|
cd032c39d2 | ||
|
|
103bdf212f | ||
|
|
bafe372cbc | ||
|
|
88f7b90237 | ||
|
|
66f1f545c3 | ||
|
|
e5659ad6ab | ||
|
|
c1a009cc2f | ||
|
|
e95f577074 | ||
|
|
52bdd408c4 | ||
|
|
ed395ab638 | ||
|
|
86438ef3ce | ||
|
|
f3297c29cb | ||
|
|
e039e65ee4 | ||
|
|
e2b81bf9c8 | ||
|
|
9ca3ccd744 | ||
|
|
d944ff4a34 | ||
|
|
cfa745fda0 | ||
|
|
b505f81958 | ||
|
|
235a1a2f14 | ||
|
|
a4cefe3401 | ||
|
|
5a2086fcd0 | ||
|
|
c341570838 | ||
|
|
292e2e7e7e | ||
|
|
44ff33613a | ||
|
|
f9e10da9ee | ||
|
|
5ad8229d7c | ||
|
|
90609ca5c5 | ||
|
|
59b3251713 | ||
|
|
fbb4d08b88 | ||
|
|
050e04bcfd | ||
|
|
7857e8ed7a | ||
|
|
4c3eb98e31 | ||
|
|
fe49f250b0 | ||
|
|
3c643208ff | ||
|
|
dc47842892 | ||
|
|
9f22e8a9df | ||
|
|
07588853e4 | ||
|
|
199b1a27f1 | ||
|
|
a0d052b68b | ||
|
|
9a3249a667 | ||
|
|
ffdc0e03b5 | ||
|
|
d8d4384b20 | ||
|
|
0ce7d7bdc3 | ||
|
|
fb30ec8c86 | ||
|
|
67307463e2 | ||
|
|
fdd7fc063e | ||
|
|
592810b7d7 | ||
|
|
6e5e7e7aef | ||
|
|
cd0dc71de6 | ||
|
|
a43a3f949f | ||
|
|
d7b6cdf444 | ||
|
|
7916d79ff1 | ||
|
|
49cec54cd3 | ||
|
|
f154aebd38 | ||
|
|
aaa55c5742 | ||
|
|
345f1444f5 | ||
|
|
7e91d67b53 | ||
|
|
ba29176f33 | ||
|
|
05feff432e | ||
|
|
cf4f85cb22 | ||
|
|
a0c2181197 | ||
|
|
b4abf369e1 | ||
|
|
be0636d69b | ||
|
|
23986a8648 | ||
|
|
b1d3a95ca2 | ||
|
|
1238bf090c | ||
|
|
5987e03141 | ||
|
|
c5e34c4be9 | ||
|
|
b0a01cd8cf | ||
|
|
21535c9ca0 | ||
|
|
8c9bdaacbc | ||
|
|
388c3dadf1 | ||
|
|
72fc4bf52f | ||
|
|
def555678d | ||
|
|
16e79bee7d | ||
|
|
9777b5df8b | ||
|
|
c057f8a097 | ||
|
|
034139d7d5 | ||
|
|
03a51525b6 | ||
|
|
f074114d13 | ||
|
|
8a60535f9d | ||
|
|
c2be853ef1 | ||
|
|
9f1e6ab91f | ||
|
|
25334823e5 | ||
|
|
2796973ad3 | ||
|
|
2344478301 | ||
|
|
61527d1281 | ||
|
|
140b5f4b4a | ||
|
|
3e0ea6f7de | ||
|
|
ed64c7fb49 | ||
|
|
d70fa1b7b4 | ||
|
|
a41628410e | ||
|
|
f7c25b482d | ||
|
|
ac3cd08163 | ||
|
|
c1657a37f2 | ||
|
|
a2580d5d8d | ||
|
|
5d4f7529ed | ||
|
|
20a3e3b605 | ||
|
|
f3cc0f5acf | ||
|
|
2086bd6aaa | ||
|
|
3b3db88e5e | ||
|
|
f6791395cc | ||
|
|
8739996668 | ||
|
|
1740583ccc | ||
|
|
b12244e352 | ||
|
|
e6ac0d1d8d | ||
|
|
eda199d47a | ||
|
|
012c375f2e | ||
|
|
4a96dfa6ce | ||
|
|
ec10aec0c4 | ||
|
|
49c2c6b405 | ||
|
|
38b1e5cbaa | ||
|
|
9a64a18010 | ||
|
|
72eddd009b | ||
|
|
77d58eb8f5 | ||
|
|
856dbe083d | ||
|
|
50cc34ad9b | ||
|
|
c996577a0b | ||
|
|
e877820594 | ||
|
|
8ab123c927 | ||
|
|
a510b89c6a | ||
|
|
8b41a1fa66 | ||
|
|
99fc8a8311 | ||
|
|
5c3eea2fcb | ||
|
|
ffb26a1f86 | ||
|
|
a8ae1b7739 | ||
|
|
b59df11bd6 | ||
|
|
146c8dede4 | ||
|
|
c2090676d8 | ||
|
|
b29bae88f1 | ||
|
|
c55a40481d | ||
|
|
a37a1ca6ef | ||
|
|
8629b1b867 | ||
|
|
f7c0d4149b | ||
|
|
87fd5c19d0 | ||
|
|
d132969c91 | ||
|
|
a5fa0b1e4b | ||
|
|
a21c8a62ac | ||
|
|
9fd3701f46 | ||
|
|
1d95737088 | ||
|
|
2f7042056a | ||
|
|
13b41abce6 | ||
|
|
b9f9566158 | ||
|
|
710a417e12 | ||
|
|
f11d0fbcda | ||
|
|
96144af9e9 | ||
|
|
4dd2445833 | ||
|
|
6172d942be | ||
|
|
0c0cbb232c | ||
|
|
298ff29cf4 | ||
|
|
f70707e17f | ||
|
|
f1fc04591c | ||
|
|
a26c397417 | ||
|
|
d3a2a7bee9 | ||
|
|
d817ff7e6a | ||
|
|
ec4bec5b1f | ||
|
|
d7c458839c | ||
|
|
cff2f25e56 | ||
|
|
63ac84883e | ||
|
|
f8252df281 | ||
|
|
be00bb99ad | ||
|
|
7e6a78ab6c | ||
|
|
06c2ddf543 | ||
|
|
47f1e80252 | ||
|
|
64bc29d362 | ||
|
|
8d17f5922c |
49
.github/workflows/main.yml
vendored
Normal file
49
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
on:
|
||||||
|
push:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
container:
|
||||||
|
image: archlinux:latest
|
||||||
|
steps:
|
||||||
|
- name: base-devel
|
||||||
|
run: pacman -Syyu base-devel --noconfirm
|
||||||
|
- name: arm-none-eabi-gcc
|
||||||
|
run: pacman -Syyu arm-none-eabi-gcc --noconfirm
|
||||||
|
- name: arm-none-eabi-newlib
|
||||||
|
run: pacman -Syyu arm-none-eabi-newlib --noconfirm
|
||||||
|
- name: git
|
||||||
|
run: pacman -Syyu git --noconfirm
|
||||||
|
- name: python-pip
|
||||||
|
run: pacman -Syyu python-pip --noconfirm
|
||||||
|
- name: python-crcmod
|
||||||
|
run: pacman -Syyu python-crcmod --noconfirm
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: safe.directory
|
||||||
|
run: git config --global --add safe.directory /__w/uv-k5-firmware-custom/uv-k5-firmware-custom
|
||||||
|
- name: Make
|
||||||
|
run: make
|
||||||
|
- name: size
|
||||||
|
run: arm-none-eabi-size firmware
|
||||||
|
|
||||||
|
- name: 'Upload Artifact'
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: firmware
|
||||||
|
path: firmware*.bin
|
||||||
|
|
||||||
|
- name: Upload binaries to release
|
||||||
|
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
||||||
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
with:
|
||||||
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
file: firmware.packed.bin
|
||||||
|
asset_name: egzumer_$tag.packed.bin
|
||||||
|
tag: ${{ github.ref }}
|
||||||
|
overwrite: true
|
||||||
|
release_name: release ${{ github.ref_name }}
|
||||||
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -4,3 +4,6 @@ firmware
|
|||||||
/firmware.packed.bin
|
/firmware.packed.bin
|
||||||
/firmware.bin
|
/firmware.bin
|
||||||
/compiled-firmware
|
/compiled-firmware
|
||||||
|
.cache
|
||||||
|
compile_commands.json
|
||||||
|
.vscode
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM archlinux:latest
|
FROM --platform=amd64 archlinux:latest
|
||||||
RUN pacman -Syyu base-devel --noconfirm
|
RUN pacman -Syyu base-devel --noconfirm
|
||||||
RUN pacman -Syyu arm-none-eabi-gcc --noconfirm
|
RUN pacman -Syyu arm-none-eabi-gcc --noconfirm
|
||||||
RUN pacman -Syyu arm-none-eabi-newlib --noconfirm
|
RUN pacman -Syyu arm-none-eabi-newlib --noconfirm
|
||||||
|
|||||||
200
Makefile
200
Makefile
@@ -2,41 +2,53 @@
|
|||||||
# compile options (see README.md for descriptions)
|
# compile options (see README.md for descriptions)
|
||||||
# 0 = disable
|
# 0 = disable
|
||||||
# 1 = enable
|
# 1 = enable
|
||||||
#
|
|
||||||
ENABLE_CLANG := 0
|
# ---- COMPILER/LINKER OPTIONS ----
|
||||||
ENABLE_SWD := 0
|
ENABLE_CLANG ?= 0
|
||||||
ENABLE_OVERLAY := 0
|
ENABLE_SWD ?= 0
|
||||||
ENABLE_LTO := 1
|
ENABLE_OVERLAY ?= 0
|
||||||
ENABLE_UART := 1
|
ENABLE_LTO ?= 1
|
||||||
ENABLE_AIRCOPY := 0
|
|
||||||
ENABLE_FMRADIO := 1
|
# ---- STOCK QUANSHENG FERATURES ----
|
||||||
ENABLE_NOAA := 0
|
ENABLE_UART ?= 1
|
||||||
ENABLE_VOICE := 0
|
ENABLE_AIRCOPY ?= 0
|
||||||
ENABLE_VOX := 1
|
ENABLE_FMRADIO ?= 1
|
||||||
ENABLE_ALARM := 0
|
ENABLE_NOAA ?= 0
|
||||||
ENABLE_TX1750 := 0
|
ENABLE_VOICE ?= 0
|
||||||
ENABLE_PWRON_PASSWORD := 0
|
ENABLE_VOX ?= 1
|
||||||
ENABLE_BIG_FREQ := 1
|
ENABLE_ALARM ?= 0
|
||||||
ENABLE_SMALL_BOLD := 1
|
ENABLE_TX1750 ?= 0
|
||||||
ENABLE_KEEP_MEM_NAME := 1
|
ENABLE_PWRON_PASSWORD ?= 0
|
||||||
ENABLE_WIDE_RX := 1
|
ENABLE_DTMF_CALLING ?= 1
|
||||||
ENABLE_TX_WHEN_AM := 0
|
ENABLE_FLASHLIGHT ?= 1
|
||||||
ENABLE_F_CAL_MENU := 0
|
|
||||||
ENABLE_CTCSS_TAIL_PHASE_SHIFT := 1
|
# ---- CUSTOM MODS ----
|
||||||
ENABLE_BOOT_BEEPS := 0
|
ENABLE_BIG_FREQ ?= 1
|
||||||
ENABLE_SHOW_CHARGE_LEVEL := 1
|
ENABLE_SMALL_BOLD ?= 1
|
||||||
ENABLE_REVERSE_BAT_SYMBOL := 1
|
ENABLE_KEEP_MEM_NAME ?= 1
|
||||||
ENABLE_CODE_SCAN_TIMEOUT := 0
|
ENABLE_WIDE_RX ?= 1
|
||||||
ENABLE_AM_FIX := 1
|
ENABLE_TX_WHEN_AM ?= 0
|
||||||
ENABLE_AM_FIX_SHOW_DATA := 0
|
ENABLE_F_CAL_MENU ?= 0
|
||||||
ENABLE_SQUELCH_MORE_SENSITIVE := 1
|
ENABLE_CTCSS_TAIL_PHASE_SHIFT ?= 0
|
||||||
ENABLE_FASTER_CHANNEL_SCAN := 1
|
ENABLE_BOOT_BEEPS ?= 0
|
||||||
ENABLE_RSSI_BAR := 1
|
ENABLE_SHOW_CHARGE_LEVEL ?= 0
|
||||||
ENABLE_AUDIO_BAR := 1
|
ENABLE_REVERSE_BAT_SYMBOL ?= 0
|
||||||
ENABLE_COPY_CHAN_TO_VFO := 1
|
ENABLE_NO_CODE_SCAN_TIMEOUT ?= 1
|
||||||
ENABLE_SPECTRUM := 1
|
ENABLE_AM_FIX ?= 1
|
||||||
#ENABLE_SINGLE_VFO_CHAN := 1
|
ENABLE_SQUELCH_MORE_SENSITIVE ?= 1
|
||||||
#ENABLE_BAND_SCOPE := 1
|
ENABLE_FASTER_CHANNEL_SCAN ?= 1
|
||||||
|
ENABLE_RSSI_BAR ?= 1
|
||||||
|
ENABLE_AUDIO_BAR ?= 1
|
||||||
|
ENABLE_COPY_CHAN_TO_VFO ?= 1
|
||||||
|
ENABLE_SPECTRUM ?= 1
|
||||||
|
ENABLE_REDUCE_LOW_MID_TX_POWER?= 0
|
||||||
|
ENABLE_BYP_RAW_DEMODULATORS ?= 0
|
||||||
|
ENABLE_BLMIN_TMP_OFF ?= 0
|
||||||
|
ENABLE_SCAN_RANGES ?= 1
|
||||||
|
|
||||||
|
# ---- DEBUGGING ----
|
||||||
|
ENABLE_AM_FIX_SHOW_DATA ?= 0
|
||||||
|
ENABLE_AGC_SHOW_DATA ?= 0
|
||||||
|
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
@@ -99,7 +111,12 @@ ifeq ($(ENABLE_AIRCOPY),1)
|
|||||||
OBJS += app/aircopy.o
|
OBJS += app/aircopy.o
|
||||||
endif
|
endif
|
||||||
OBJS += app/app.o
|
OBJS += app/app.o
|
||||||
|
OBJS += app/chFrScanner.o
|
||||||
|
OBJS += app/common.o
|
||||||
OBJS += app/dtmf.o
|
OBJS += app/dtmf.o
|
||||||
|
ifeq ($(ENABLE_FLASHLIGHT),1)
|
||||||
|
OBJS += app/flashlight.o
|
||||||
|
endif
|
||||||
ifeq ($(ENABLE_FMRADIO),1)
|
ifeq ($(ENABLE_FMRADIO),1)
|
||||||
OBJS += app/fm.o
|
OBJS += app/fm.o
|
||||||
endif
|
endif
|
||||||
@@ -150,24 +167,30 @@ OBJS += ui/welcome.o
|
|||||||
OBJS += version.o
|
OBJS += version.o
|
||||||
OBJS += main.o
|
OBJS += main.o
|
||||||
|
|
||||||
ifeq ($(OS), Windows_NT)
|
ifeq ($(OS), Windows_NT) # windows
|
||||||
TOP := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
|
TOP := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||||
else
|
RM = del /Q
|
||||||
TOP := $(shell pwd)
|
FixPath = $(subst /,\,$1)
|
||||||
|
WHERE = where
|
||||||
|
NULL_OUTPUT = nul
|
||||||
|
else # unix
|
||||||
|
TOP := $(shell pwd)
|
||||||
|
RM = rm -f
|
||||||
|
FixPath = $1
|
||||||
|
WHERE = which
|
||||||
|
NULL_OUTPUT = /dev/null
|
||||||
endif
|
endif
|
||||||
|
|
||||||
AS = arm-none-eabi-gcc
|
AS = arm-none-eabi-gcc
|
||||||
|
|
||||||
CC =
|
|
||||||
LD = arm-none-eabi-gcc
|
LD = arm-none-eabi-gcc
|
||||||
|
|
||||||
ifeq ($(ENABLE_CLANG),0)
|
ifeq ($(ENABLE_CLANG),0)
|
||||||
CC += arm-none-eabi-gcc
|
CC = arm-none-eabi-gcc
|
||||||
# Use GCC's linker to avoid undefined symbol errors
|
# Use GCC's linker to avoid undefined symbol errors
|
||||||
# LD += arm-none-eabi-gcc
|
# LD += arm-none-eabi-gcc
|
||||||
else
|
else
|
||||||
# May need to adjust this to match your system
|
# May need to adjust this to match your system
|
||||||
CC += clang --sysroot=/usr/arm-none-eabi --target=arm-none-eabi
|
CC = clang --sysroot=/usr/arm-none-eabi --target=arm-none-eabi
|
||||||
# Bloats binaries to 512MB
|
# Bloats binaries to 512MB
|
||||||
# LD = ld.lld
|
# LD = ld.lld
|
||||||
endif
|
endif
|
||||||
@@ -175,12 +198,17 @@ endif
|
|||||||
OBJCOPY = arm-none-eabi-objcopy
|
OBJCOPY = arm-none-eabi-objcopy
|
||||||
SIZE = arm-none-eabi-size
|
SIZE = arm-none-eabi-size
|
||||||
|
|
||||||
|
AUTHOR_STRING ?= EGZUMER
|
||||||
# the user might not have/want git installed
|
# the user might not have/want git installed
|
||||||
# can set own version string here (max 7 chars)
|
# can set own version string here (max 7 chars)
|
||||||
GIT_HASH := $(shell git rev-parse --short HEAD)
|
ifneq (, $(shell $(WHERE) git))
|
||||||
#GIT_HASH := 230930b
|
VERSION_STRING ?= $(shell git describe --tags --exact-match 2>$(NULL_OUTPUT))
|
||||||
|
ifeq (, $(VERSION_STRING))
|
||||||
|
VERSION_STRING := $(shell git rev-parse --short HEAD)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
#VERSION_STRING := 230930b
|
||||||
|
|
||||||
$(info GIT_HASH = $(GIT_HASH))
|
|
||||||
|
|
||||||
ASFLAGS = -c -mcpu=cortex-m0
|
ASFLAGS = -c -mcpu=cortex-m0
|
||||||
ifeq ($(ENABLE_OVERLAY),1)
|
ifeq ($(ENABLE_OVERLAY),1)
|
||||||
@@ -189,17 +217,18 @@ endif
|
|||||||
|
|
||||||
CFLAGS =
|
CFLAGS =
|
||||||
ifeq ($(ENABLE_CLANG),0)
|
ifeq ($(ENABLE_CLANG),0)
|
||||||
CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD
|
CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c2x -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=c99 -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=gnu99 -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=gnu11 -MMD
|
||||||
else
|
else
|
||||||
# Oz needed to make it fit on flash
|
# 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
|
CFLAGS += -Oz -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c2x -MMD
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(ENABLE_LTO),1)
|
ifeq ($(ENABLE_LTO),1)
|
||||||
CFLAGS += -flto=2
|
CFLAGS += -flto=auto
|
||||||
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
|
||||||
@@ -209,10 +238,11 @@ endif
|
|||||||
#CFLAGS += -Wpadded
|
#CFLAGS += -Wpadded
|
||||||
|
|
||||||
# catch any and all warnings
|
# catch any and all warnings
|
||||||
#CFLAGS += -Wextra
|
CFLAGS += -Wextra
|
||||||
|
#CFLAGS += -Wpedantic
|
||||||
|
|
||||||
CFLAGS += -DPRINTF_INCLUDE_CONFIG_H
|
CFLAGS += -DPRINTF_INCLUDE_CONFIG_H
|
||||||
CFLAGS += -DGIT_HASH=\"$(GIT_HASH)\"
|
CFLAGS += -DAUTHOR_STRING=\"$(AUTHOR_STRING)\" -DVERSION_STRING=\"$(VERSION_STRING)\"
|
||||||
|
|
||||||
ifeq ($(ENABLE_SPECTRUM),1)
|
ifeq ($(ENABLE_SPECTRUM),1)
|
||||||
CFLAGS += -DENABLE_SPECTRUM
|
CFLAGS += -DENABLE_SPECTRUM
|
||||||
@@ -280,7 +310,7 @@ endif
|
|||||||
ifeq ($(ENABLE_REVERSE_BAT_SYMBOL),1)
|
ifeq ($(ENABLE_REVERSE_BAT_SYMBOL),1)
|
||||||
CFLAGS += -DENABLE_REVERSE_BAT_SYMBOL
|
CFLAGS += -DENABLE_REVERSE_BAT_SYMBOL
|
||||||
endif
|
endif
|
||||||
ifeq ($(ENABLE_CODE_SCAN_TIMEOUT),1)
|
ifeq ($(ENABLE_NO_CODE_SCAN_TIMEOUT),1)
|
||||||
CFLAGS += -DENABLE_CODE_SCAN_TIMEOUT
|
CFLAGS += -DENABLE_CODE_SCAN_TIMEOUT
|
||||||
endif
|
endif
|
||||||
ifeq ($(ENABLE_AM_FIX),1)
|
ifeq ($(ENABLE_AM_FIX),1)
|
||||||
@@ -289,9 +319,6 @@ endif
|
|||||||
ifeq ($(ENABLE_AM_FIX_SHOW_DATA),1)
|
ifeq ($(ENABLE_AM_FIX_SHOW_DATA),1)
|
||||||
CFLAGS += -DENABLE_AM_FIX_SHOW_DATA
|
CFLAGS += -DENABLE_AM_FIX_SHOW_DATA
|
||||||
endif
|
endif
|
||||||
ifeq ($(ENABLE_AM_FIX_TEST1),1)
|
|
||||||
CFLAGS += -DENABLE_AM_FIX_TEST1
|
|
||||||
endif
|
|
||||||
ifeq ($(ENABLE_SQUELCH_MORE_SENSITIVE),1)
|
ifeq ($(ENABLE_SQUELCH_MORE_SENSITIVE),1)
|
||||||
CFLAGS += -DENABLE_SQUELCH_MORE_SENSITIVE
|
CFLAGS += -DENABLE_SQUELCH_MORE_SENSITIVE
|
||||||
endif
|
endif
|
||||||
@@ -316,23 +343,34 @@ endif
|
|||||||
ifeq ($(ENABLE_BAND_SCOPE),1)
|
ifeq ($(ENABLE_BAND_SCOPE),1)
|
||||||
CFLAGS += -DENABLE_BAND_SCOPE
|
CFLAGS += -DENABLE_BAND_SCOPE
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(ENABLE_REDUCE_LOW_MID_TX_POWER),1)
|
||||||
|
CFLAGS += -DENABLE_REDUCE_LOW_MID_TX_POWER
|
||||||
|
endif
|
||||||
|
ifeq ($(ENABLE_BYP_RAW_DEMODULATORS),1)
|
||||||
|
CFLAGS += -DENABLE_BYP_RAW_DEMODULATORS
|
||||||
|
endif
|
||||||
|
ifeq ($(ENABLE_BLMIN_TMP_OFF),1)
|
||||||
|
CFLAGS += -DENABLE_BLMIN_TMP_OFF
|
||||||
|
endif
|
||||||
|
ifeq ($(ENABLE_SCAN_RANGES),1)
|
||||||
|
CFLAGS += -DENABLE_SCAN_RANGES
|
||||||
|
endif
|
||||||
|
ifeq ($(ENABLE_DTMF_CALLING),1)
|
||||||
|
CFLAGS += -DENABLE_DTMF_CALLING
|
||||||
|
endif
|
||||||
|
ifeq ($(ENABLE_AGC_SHOW_DATA),1)
|
||||||
|
CFLAGS += -DENABLE_AGC_SHOW_DATA
|
||||||
|
endif
|
||||||
|
ifeq ($(ENABLE_FLASHLIGHT),1)
|
||||||
|
CFLAGS += -DENABLE_FLASHLIGHT
|
||||||
|
endif
|
||||||
|
|
||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
ifeq ($(ENABLE_CLANG),0)
|
LDFLAGS += -z noexecstack -mcpu=cortex-m0 -nostartfiles -Wl,-T,firmware.ld -Wl,--gc-sections
|
||||||
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)
|
|
||||||
# Throw away unneeded func/data sections like LTO does
|
|
||||||
LDFLAGS += -Wl,--gc-sections
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(DEBUG),1)
|
ifeq ($(DEBUG),1)
|
||||||
ASFLAGS += -g
|
ASFLAGS += -g
|
||||||
CFLAGS += -g
|
CFLAGS += -g
|
||||||
@@ -348,10 +386,34 @@ LIBS =
|
|||||||
|
|
||||||
DEPS = $(OBJS:.o=.d)
|
DEPS = $(OBJS:.o=.d)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ifneq (, $(shell $(WHERE) python))
|
||||||
|
MY_PYTHON := python
|
||||||
|
else ifneq (, $(shell $(WHERE) python3))
|
||||||
|
MY_PYTHON := python3
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef MY_PYTHON
|
||||||
|
HAS_CRCMOD := $(shell $(MY_PYTHON) -c "import crcmod" 2>&1)
|
||||||
|
endif
|
||||||
|
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
$(OBJCOPY) -O binary $< $<.bin
|
$(OBJCOPY) -O binary $< $<.bin
|
||||||
-python fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin
|
|
||||||
-python3 fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin
|
ifndef MY_PYTHON
|
||||||
|
$(info )
|
||||||
|
$(info !!!!!!!! PYTHON NOT FOUND, *.PACKED.BIN WON'T BE BUILT)
|
||||||
|
$(info )
|
||||||
|
else ifneq (,$(HAS_CRCMOD))
|
||||||
|
$(info )
|
||||||
|
$(info !!!!!!!! CRCMOD NOT INSTALLED, *.PACKED.BIN WON'T BE BUILT)
|
||||||
|
$(info !!!!!!!! run: pip install crcmod)
|
||||||
|
$(info )
|
||||||
|
else
|
||||||
|
-$(MY_PYTHON) fw-pack.py $<.bin $(AUTHOR_STRING) $(VERSION_STRING) $<.packed.bin
|
||||||
|
endif
|
||||||
|
|
||||||
$(SIZE) $<
|
$(SIZE) $<
|
||||||
|
|
||||||
debug:
|
debug:
|
||||||
@@ -378,4 +440,4 @@ bsp/dp32g030/%.h: hardware/dp32g030/%.def
|
|||||||
-include $(DEPS)
|
-include $(DEPS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(TARGET).bin $(TARGET).packed.bin $(TARGET) $(OBJS) $(DEPS)
|
$(RM) $(call FixPath, $(TARGET).bin $(TARGET).packed.bin $(TARGET) $(OBJS) $(DEPS))
|
||||||
|
|||||||
197
README.md
197
README.md
@@ -1,37 +1,61 @@
|
|||||||
# Main features:
|
# Open re-implementation of the Quansheng UV-K5/K6/5R v2.1.27 firmware
|
||||||
- OneOfEleven mods, including AM fix
|
|
||||||
- fagci spectrum analyzer (**F+5** to turn on)
|
|
||||||
- better battery percentage calculation (based on real measurement, battery calibration recommended)
|
|
||||||
- battery calibration option available available in the menu (instructions below)
|
|
||||||
|
|
||||||
<img src="images/main.jpg" width=300 /><img src="images/spectrum.jpg" width=300 /><img src="images/audiobar.jpg" width=300 /><img src="images/rssibar.jpg" width=300 />
|
This repository is a merge of [OneOfEleven custom firmware](https://github.com/OneOfEleven/uv-k5-firmware-custom) with [fagci spectrum analizer](https://github.com/fagci/uv-k5-firmware-fagci-mod/tree/refactor) plus my few changes.<br>
|
||||||
|
All is a cloned and customized version of DualTachyon's open firmware found [here](https://github.com/DualTachyon/uv-k5-firmware) ... a cool achievement !
|
||||||
|
|
||||||
❗❗❗You can now calibrate the battery voltage reading in the radio menu.
|
> [!WARNING]
|
||||||
|
> Use this firmware at your own risk (entirely). There is absolutely no guarantee that it will work in any way shape or form on your radio(s), it may even brick your radio(s), in which case, you'd need to buy another radio.
|
||||||
<img src="images/batcal.jpg" width=300 />
|
|
||||||
|
|
||||||
To enter the calibration:
|
|
||||||
|
|
||||||
1. turn the radio on while holding PTT and the first side button
|
|
||||||
2. go to BATCAL option and adjust the voltage with UP/DOWN buttons
|
|
||||||
3. confirm the setting, calibration will be saved to EEPROM
|
|
||||||
|
|
||||||
|
|
||||||
# Open reimplementation of the Quan Sheng UV-K5 v2.1.27 firmware
|
|
||||||
|
|
||||||
This repository is a merge of OneOfEleven custom firmware with fagci spectrum analizer plus my few changes.
|
|
||||||
|
|
||||||
https://github.com/OneOfEleven/uv-k5-firmware-custom<br>
|
|
||||||
https://github.com/fagci/uv-k5-firmware-fagci-mod/tree/refactor
|
|
||||||
|
|
||||||
All is a cloned and customized version of DualTachyon's open firmware found here ..
|
|
||||||
|
|
||||||
https://github.com/DualTachyon/uv-k5-firmware .. a cool achievement !
|
|
||||||
|
|
||||||
Use this firmware at your own risk (entirely). There is absolutely no guarantee that it will work in any way shape or form on your radio(s), it may even brick your radio(s), in which case, you'd need to buy another radio.
|
|
||||||
Anyway, have fun.
|
Anyway, have fun.
|
||||||
|
|
||||||
# Radio performance
|
## Table of Contents
|
||||||
|
|
||||||
|
* [Main Features](#main-features)
|
||||||
|
* [Manual](#manual)
|
||||||
|
* [Radio Performance](#radio-performance)
|
||||||
|
* [User Customization](#user-customization)
|
||||||
|
* [Compiler](#compiler)
|
||||||
|
* [Building](#building)
|
||||||
|
* [Credits](#credits)
|
||||||
|
* [Other sources of information](#other-sources-of-information)
|
||||||
|
* [License](#license)
|
||||||
|
* [Example changes/updates](#example-changesupdates)
|
||||||
|
|
||||||
|
## Main features:
|
||||||
|
* many of OneOfEleven mods:
|
||||||
|
* AM fix, huge improvement in reception quality
|
||||||
|
* long press buttons functions replicating F+ action
|
||||||
|
* fast scanning
|
||||||
|
* channel name editing in the menu
|
||||||
|
* channel name + frequency display option
|
||||||
|
* shortcut for scan-list assignment (long press `5 NOAA`)
|
||||||
|
* scan-list toggle (long press `* Scan` while scanning)
|
||||||
|
* configurable button function selectable from menu
|
||||||
|
* battery percentage/voltage on status bar, selectable from menu
|
||||||
|
* longer backlight times
|
||||||
|
* mic bar
|
||||||
|
* RSSI s-meter
|
||||||
|
* more frequency steps
|
||||||
|
* squelch more sensitive
|
||||||
|
* fagci spectrum analyzer (**F+5** to turn on)
|
||||||
|
* some other mods introduced by me:
|
||||||
|
* SSB demodulation (adopted from fagci)
|
||||||
|
* backlight dimming
|
||||||
|
* battery voltage calibration from menu
|
||||||
|
* better battery percentage calculation, selectable for 1600mAh or 2200mAh
|
||||||
|
* more configurable button functions
|
||||||
|
* long press MENU as another configurable button
|
||||||
|
* better DCS/CTCSS scanning in the menu (`* SCAN` while in RX DCS/CTCSS menu item)
|
||||||
|
* Piotr022 style s-meter
|
||||||
|
* restore initial freq/channel when scanning stopped with EXIT, remember last found transmission with MENU button
|
||||||
|
* reordered and renamed menu entries
|
||||||
|
* LCD interference crash fix
|
||||||
|
* many others...
|
||||||
|
|
||||||
|
## Manual
|
||||||
|
|
||||||
|
Up to date manual is available in the [Wiki section](https://github.com/egzumer/uv-k5-firmware-custom/wiki)
|
||||||
|
|
||||||
|
## Radio performance
|
||||||
|
|
||||||
Please note that the Quansheng UV-Kx 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. The RX front end has no track-tuned band pass filtering
|
performance is strictly limited. The RX front end has no track-tuned band pass filtering
|
||||||
@@ -42,12 +66,12 @@ easy (AM mode will suffer far more than FM ever will), the receiver simply doesn
|
|||||||
great dynamic range, which results in distorted AM audio with stronger RX'ed signals.
|
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
|
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
|
adjustment I do (AM fix) reaches the hardwares limit, your AM RX audio will be all but
|
||||||
non-existant (just like Quansheng's firmware).
|
non-existent (just like Quansheng's firmware).
|
||||||
On the other hand, FM RX audio will/should be fine.
|
On the other hand, FM RX audio will/should be fine.
|
||||||
|
|
||||||
But, they are nice toys for the price, fun to play with.
|
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, this allows
|
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.
|
us to remove certain firmware features in order to make room in the flash for others.
|
||||||
@@ -57,62 +81,47 @@ 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_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 := 1 **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 := 1 WBFM VHF broadcast band receiver
|
||||||
ENABLE_NOAA := 0 everything NOAA (only of any use in the USA)
|
ENABLE_NOAA := 0 everything NOAA (only of any use in the USA)
|
||||||
ENABLE_VOICE := 0 want to hear voices ?
|
ENABLE_VOICE := 0 want to hear voices ?
|
||||||
ENABLE_VOX := 0
|
ENABLE_VOX := 1
|
||||||
ENABLE_ALARM := 0 TX alarms
|
ENABLE_ALARM := 0 TX alarms
|
||||||
ENABLE_1750HZ := 0 side key 1750Hz TX tone (older style repeater access)
|
ENABLE_TX1750 := 0 side key 1750Hz TX tone (older style repeater access)
|
||||||
ENABLE_PWRON_PASSWORD := 1 power-on password stuff
|
ENABLE_PWRON_PASSWORD := 0 power-on password stuff
|
||||||
ENABLE_BIG_FREQ := 0 big font frequencies (like original QS firmware)
|
ENABLE_DTMF_CALLING := 1 DTMF calling fuctionality, sending calls, receiving calls, group calls, contacts list etc.
|
||||||
|
ENABLE_FLASHLIGHT := 1 enable top flashlight LED (on, blink, SOS)
|
||||||
|
|
||||||
|
ENABLE_BIG_FREQ := 1 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
|
||||||
ENABLE_WIDE_RX := 1 full 18MHz to 1300MHz RX (though front-end/PA not designed for full range)
|
ENABLE_WIDE_RX := 1 full 18MHz to 1300MHz RX (though front-end/PA not designed for full range)
|
||||||
ENABLE_TX_WHEN_AM := 0 allow TX (always FM) when RX is set to AM
|
ENABLE_TX_WHEN_AM := 0 allow TX (always FM) when RX is set to AM
|
||||||
ENABLE_F_CAL_MENU := 0 enable/disable the radios hidden frequency calibration menu
|
ENABLE_F_CAL_MENU := 0 enable the radios hidden frequency calibration menu
|
||||||
ENABLE_CTCSS_TAIL_PHASE_SHIFT := 1 standard CTCSS tail phase shift rather than QS's own 55Hz tone method
|
ENABLE_CTCSS_TAIL_PHASE_SHIFT := 0 standard CTCSS tail phase shift rather than QS's own 55Hz tone method
|
||||||
ENABLE_BOOT_BEEPS := 0 gives user audio feedback on volume knob position at boot-up
|
ENABLE_BOOT_BEEPS := 0 gives user audio feedback on volume knob position at boot-up
|
||||||
ENABLE_SHOW_CHARGE_LEVEL := 0 show the charge level when the radio is on charge
|
ENABLE_SHOW_CHARGE_LEVEL := 1 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 := 0 mirror the battery symbol on the status bar (+ pole on the right)
|
||||||
ENABLE_CODE_SCAN_TIMEOUT := 0 enable/disable 32-sec CTCSS/DCS scan timeout (press exit butt instead of time-out to end scan)
|
ENABLE_NO_CODE_SCAN_TIMEOUT := 1 disable 32-sec CTCSS/DCS scan timeout (press exit butt instead of time-out to end scan)
|
||||||
ENABLE_AM_FIX := 1 dynamically adjust the front end gains when in AM mode to helo prevent AM demodulator saturation, ignore the on-screen RSSI level (for now)
|
ENABLE_AM_FIX := 1 dynamically adjust the front end gains when in AM mode to help prevent AM demodulator saturation, ignore the on-screen RSSI level (for now)
|
||||||
ENABLE_AM_FIX_SHOW_DATA := 1 show debug data for the AM fix (still tweaking it)
|
ENABLE_AM_FIX_SHOW_DATA := 0 show debug data for the AM fix
|
||||||
ENABLE_SQUELCH_MORE_SENSITIVE := 0 make squelch levels a little bit more sensitive - I plan to let user adjust the values themselves
|
ENABLE_SQUELCH_MORE_SENSITIVE := 1 make squelch levels a little bit more sensitive - I plan to let user adjust the values themselves
|
||||||
ENABLE_FASTER_CHANNEL_SCAN := 0 increases the channel scan speed, but the squelch is also made more twitchy
|
ENABLE_FASTER_CHANNEL_SCAN := 1 increases the channel scan speed, but the squelch is also made more twitchy
|
||||||
ENABLE_RSSI_BAR := 1 enable a dBm/Sn RSSI bar graph level inplace of the little antenna symbols
|
ENABLE_RSSI_BAR := 1 enable a dBm/Sn RSSI bar graph level in place of the little antenna symbols
|
||||||
ENABLE_AUDIO_BAR := 0 experimental, display an audo bar level when TX'ing
|
ENABLE_AUDIO_BAR := 1 experimental, display an audio bar level when TX'ing
|
||||||
ENABLE_COPY_CHAN_TO_VFO := 1 copy current channel into the other VFO. Long press Menu key ('M')
|
ENABLE_COPY_CHAN_TO_VFO := 1 copy current channel into the other VFO. Long press `1 BAND` when in channel mode
|
||||||
#ENABLE_SINGLE_VFO_CHAN := 1 not yet implemented - single VFO on display when possible
|
ENABLE_SPECTRUM := 1 fagci spectrum analyzer, activated with `F` + `5 NOAA`
|
||||||
#ENABLE_BAND_SCOPE := 1 not yet implemented - spectrum/pan-adapter
|
ENABLE_REDUCE_LOW_MID_TX_POWER:= 0 makes medium and low power settings even lower
|
||||||
|
ENABLE_BYP_RAW_DEMODULATORS := 0 additional BYP (bypass?) and RAW demodulation options, proved not to be very useful, but it is there if you want to experiment
|
||||||
|
ENABLE_BLMIN_TMP_OFF := 0 additional function for configurable buttons that toggles `BLMin` on and off wihout saving it to the EEPROM
|
||||||
|
ENABLE_SCAN_RANGES := 1 scan range mode for frequency scanning, see wiki for instructions (radio operation -> frequency scanning)
|
||||||
```
|
```
|
||||||
|
|
||||||
# New/modified function keys
|
|
||||||
|
|
||||||
* Long-press 'M' .. Copy selected channel into same VFO, then switch VFO to frequency mode
|
## Compiler
|
||||||
*
|
|
||||||
* Long-press '7' .. Toggle selected channel scanlist setting .. if VOX is disabled in Makefile
|
|
||||||
* or
|
|
||||||
* Long-press '5' .. Toggle selected channel scanlist setting .. if NOAA is disabled in Makefile
|
|
||||||
*
|
|
||||||
* Long-press '*' .. Start scanning, then toggles the scanning between scanlists 1, 2 or ALL channels
|
|
||||||
|
|
||||||
# Some changes made from the Quansheng firmware
|
|
||||||
|
|
||||||
* Various Quansheng firmware bugs fixed
|
|
||||||
* Added new bugs
|
|
||||||
* Mic menu includes max gain possible
|
|
||||||
* AM RX everywhere (left the TX as is)
|
|
||||||
* An attempt to improve the AM RX audio (demodulator getting saturated/overloaded in Quansheng firmware)
|
|
||||||
* keypad-5/NOAA button now toggles scanlist-1 on/off for current channel when held down - IF NOAA not used
|
|
||||||
* Better backlight times (inc always on)
|
|
||||||
* Live DTMF decoder option, though the decoder needs some coeff tuning changes to decode other radios it seems
|
|
||||||
* Various menu re-wordings (trying to reduce 'WTH does that mean ?')
|
|
||||||
* ..
|
|
||||||
|
|
||||||
# Compiler
|
|
||||||
|
|
||||||
arm-none-eabi GCC version 10.3.1 is recommended, which is the current version on Ubuntu 22.04.03 LTS.
|
arm-none-eabi GCC version 10.3.1 is recommended, which is the current version on Ubuntu 22.04.03 LTS.
|
||||||
Other versions may generate a flash file that is too big.
|
Other versions may generate a flash file that is too big.
|
||||||
@@ -121,12 +130,33 @@ You can get an appropriate version from: https://developer.arm.com/downloads/-/g
|
|||||||
clang may be used but isn't fully supported. Resulting binaries may also be bigger.
|
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
|
You can get it from: https://releases.llvm.org/download.html
|
||||||
|
|
||||||
# Building
|
## Building
|
||||||
|
|
||||||
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.
|
### Github Codespace build method
|
||||||
|
|
||||||
|
This is the least demanding option as you don't have to install enything on your computer. All you need is Github account.
|
||||||
|
|
||||||
To compile directly in windows:
|
1. Go to https://github.com/egzumer/uv-k5-firmware-custom
|
||||||
|
1. Click green `Code` button
|
||||||
|
1. Change tab from `Local` to `Codespace`
|
||||||
|
1. Click green `Create codespace on main` button
|
||||||
|
|
||||||
|
<img src="images/codespace1.png" width=700 />
|
||||||
|
|
||||||
|
5. Open `Makefile`
|
||||||
|
1. Edit build options, save `Makefile` changes
|
||||||
|
1. Run `./compile-with-docker.sh` in terminal window
|
||||||
|
1. Open folder `compiled-firmware`
|
||||||
|
1. Right click `firmware.packed.bin`
|
||||||
|
1. Click `Download`, now you should have a firmware on your computer that you can proceed to flash on your radio. You can use [online flasher](https://egzumer.github.io/uvtools)
|
||||||
|
|
||||||
|
<img src="images/codespace2.png" width=700 />
|
||||||
|
|
||||||
|
### Docker build method
|
||||||
|
|
||||||
|
If you have docker installed you can use [compile-with-docker.bat](./compile-with-docker.bat) (Windows) or [compile-with-docker.sh](./compile-with-docker.sh) (Linux/Mac), 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 challenge can be (or not) installing docker itself.
|
||||||
|
|
||||||
|
### Windows environment build method
|
||||||
|
|
||||||
1. Open windows command line and run:
|
1. Open windows command line and run:
|
||||||
```
|
```
|
||||||
@@ -153,7 +183,7 @@ To compile directly in windows:
|
|||||||
|
|
||||||
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.
|
||||||
|
|
||||||
# Credits
|
## Credits
|
||||||
|
|
||||||
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:
|
||||||
|
|
||||||
@@ -171,7 +201,12 @@ Many thanks to various people on Telegram for putting up with me during this eff
|
|||||||
* @d1ced95
|
* @d1ced95
|
||||||
* and others I forget
|
* and others I forget
|
||||||
|
|
||||||
# License
|
## Other sources of information
|
||||||
|
|
||||||
|
[ludwich66 - Quansheng UV-K5 Wiki](https://github.com/ludwich66/Quansheng_UV-K5_Wiki/wiki)<br>
|
||||||
|
[amnemonic - tools and sources of information](https://github.com/amnemonic/Quansheng_UV-K5_Firmware)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
Copyright 2023 Dual Tachyon
|
Copyright 2023 Dual Tachyon
|
||||||
https://github.com/DualTachyon
|
https://github.com/DualTachyon
|
||||||
@@ -188,7 +223,7 @@ You may obtain a copy of the License at
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
# Example changes/updates
|
## Example changes/updates
|
||||||
|
|
||||||
<p float="left">
|
<p float="left">
|
||||||
<img src="/images/image1.png" width=300 />
|
<img src="/images/image1.png" width=300 />
|
||||||
|
|||||||
739
am_fix.c
739
am_fix.c
@@ -29,461 +29,374 @@
|
|||||||
#include "frequencies.h"
|
#include "frequencies.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX
|
#ifdef ENABLE_AM_FIX
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint16_t reg_val;
|
uint16_t reg_val;
|
||||||
int8_t gain_dB;
|
int8_t gain_dB;
|
||||||
} __attribute__((packed)) t_gain_table;
|
} __attribute__((packed)) t_gain_table;
|
||||||
|
|
||||||
// REG_10 AGC gain table
|
// REG_10 AGC gain table
|
||||||
//
|
//
|
||||||
// <15:10> ???
|
// <15:10> ???
|
||||||
//
|
//
|
||||||
// <9:8> = LNA Gain Short
|
// <9:8> = LNA Gain Short
|
||||||
// 3 = 0dB < original value
|
// 3 = 0dB < original value
|
||||||
// 2 = -24dB // was -11
|
// 2 = -19dB // was -11
|
||||||
// 1 = -30dB // was -16
|
// 1 = -24dB // was -16
|
||||||
// 0 = -33dB // was -19
|
// 0 = -28dB // was -19
|
||||||
//
|
//
|
||||||
// <7:5> = LNA Gain
|
// <7:5> = LNA Gain
|
||||||
// 7 = 0dB
|
// 7 = 0dB
|
||||||
// 6 = -2dB
|
// 6 = -2dB
|
||||||
// 5 = -4dB
|
// 5 = -4dB < original value
|
||||||
// 4 = -6dB
|
// 4 = -6dB
|
||||||
// 3 = -9dB
|
// 3 = -9dB
|
||||||
// 2 = -14dB < original value
|
// 2 = -14dB
|
||||||
// 1 = -19dB
|
// 1 = -19dB
|
||||||
// 0 = -24dB
|
// 0 = -24dB
|
||||||
//
|
//
|
||||||
// <4:3> = MIXER Gain
|
// <4:3> = MIXER Gain
|
||||||
// 3 = 0dB < original value
|
// 3 = 0dB < original value
|
||||||
// 2 = -3dB
|
// 2 = -3dB
|
||||||
// 1 = -6dB
|
// 1 = -6dB
|
||||||
// 0 = -8dB
|
// 0 = -8dB
|
||||||
//
|
//
|
||||||
// <2:0> = PGA Gain
|
// <2:0> = PGA Gain
|
||||||
// 7 = 0dB
|
// 7 = 0dB
|
||||||
// 6 = -3dB < original value
|
// 6 = -3dB < original value
|
||||||
// 5 = -6dB
|
// 5 = -6dB
|
||||||
// 4 = -9dB
|
// 4 = -9dB
|
||||||
// 3 = -15dB
|
// 3 = -15dB
|
||||||
// 2 = -21dB
|
// 2 = -21dB
|
||||||
// 1 = -27dB
|
// 1 = -27dB
|
||||||
// 0 = -33dB
|
// 0 = -33dB
|
||||||
|
|
||||||
// front end register dB values
|
// front end register dB values
|
||||||
//
|
//
|
||||||
// these values need to be accurate for the code to properly/reliably switch
|
// these values need to be accurate for the code to properly/reliably switch
|
||||||
// between table entries when adjusting the front end registers.
|
// between table entries when adjusting the front end registers.
|
||||||
//
|
//
|
||||||
// these 4 tables need a measuring/calibration update
|
// these 4 tables need a measuring/calibration update
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// QUESTION: why do I have to surround the negative numbers in brackets ???
|
|
||||||
// if I don't add the brackets, reading the table returns unexpected/different values !!!
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//// static const int16_t lna_short_dB[] = { -19, -16, -11, 0}; // was (but wrong)
|
//// static const int16_t lna_short_dB[] = { -19, -16, -11, 0}; // was (but wrong)
|
||||||
// static const int16_t lna_short_dB[] = { (-33), (-30), (-24), 0}; // corrected'ish
|
// static const int16_t lna_short_dB[] = { (-28), (-24), (-19), 0}; // corrected'ish
|
||||||
// static const int16_t lna_dB[] = { (-24), (-19), (-14), ( -9), (-6), (-4), (-2), 0};
|
// static const int16_t lna_dB[] = { (-24), (-19), (-14), ( -9), (-6), (-4), (-2), 0};
|
||||||
// static const int16_t mixer_dB[] = { ( -8), ( -6), ( -3), 0};
|
// static const int16_t mixer_dB[] = { ( -8), ( -6), ( -3), 0};
|
||||||
// static const int16_t pga_dB[] = { (-33), (-27), (-21), (-15), (-9), (-6), (-3), 0};
|
// static const int16_t pga_dB[] = { (-33), (-27), (-21), (-15), (-9), (-6), (-3), 0};
|
||||||
|
|
||||||
// lookup table is hugely easier than writing code to do the same
|
// lookup table is hugely easier than writing code to do the same
|
||||||
//
|
//
|
||||||
static const t_gain_table gain_table[] =
|
|
||||||
{
|
|
||||||
{0x035E, -17}, // 0 .. 3 2 3 6 .. 0dB -14dB 0dB -3dB .. -17dB original
|
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX_TEST1
|
#define LOOKUP_TABLE 1
|
||||||
|
|
||||||
// test table that lets me manually set the lna-short register
|
#if LOOKUP_TABLE
|
||||||
// to measure it's actual dB change using an RF signal generator
|
static const t_gain_table gain_table[] =
|
||||||
|
{
|
||||||
|
{0x03BE, -7}, // 0 .. 3 5 3 6 .. 0dB -4dB 0dB -3dB .. -7dB original
|
||||||
|
|
||||||
{0x005E, -50}, // 1 .. 0 2 3 6 .. -33dB -14dB 0dB -3dB .. -50dB
|
{0x0000,-93}, // 1 .. 0 0 0 0 .. -28dB -24dB -8dB -33dB .. -93dB
|
||||||
{0x015E, -47}, // 2 .. 1 2 3 6 .. -30dB -14dB 0dB -3dB .. -47dB
|
{0x0008,-91}, // 2 .. 0 0 1 0 .. -28dB -24dB -6dB -33dB .. -91dB
|
||||||
{0x025E, -41}, // 3 .. 2 2 3 6 .. -24dB -14dB 0dB -3dB .. -41dB
|
{0x0010,-88}, // 3 .. 0 0 2 0 .. -28dB -24dB -3dB -33dB .. -88dB
|
||||||
{0x035E, -17} // 4 .. 3 2 3 6 .. 0dB -14dB 0dB -3dB .. -17dB original
|
{0x0001,-87}, // 4 .. 0 0 0 1 .. -28dB -24dB -8dB -27dB .. -87dB
|
||||||
};
|
{0x0009,-85}, // 5 .. 0 0 1 1 .. -28dB -24dB -6dB -27dB .. -85dB
|
||||||
|
{0x0011,-82}, // 6 .. 0 0 2 1 .. -28dB -24dB -3dB -27dB .. -82dB
|
||||||
static const unsigned int original_index = 1;
|
{0x0002,-81}, // 7 .. 0 0 0 2 .. -28dB -24dB -8dB -21dB .. -81dB
|
||||||
|
{0x000A,-79}, // 8 .. 0 0 1 2 .. -28dB -24dB -6dB -21dB .. -79dB
|
||||||
|
{0x0012,-76}, // 9 .. 0 0 2 2 .. -28dB -24dB -3dB -21dB .. -76dB
|
||||||
|
{0x0003,-75}, // 10 .. 0 0 0 3 .. -28dB -24dB -8dB -15dB .. -75dB
|
||||||
|
{0x000B,-73}, // 11 .. 0 0 1 3 .. -28dB -24dB -6dB -15dB .. -73dB
|
||||||
|
{0x0013,-70}, // 12 .. 0 0 2 3 .. -28dB -24dB -3dB -15dB .. -70dB
|
||||||
|
{0x0004,-69}, // 13 .. 0 0 0 4 .. -28dB -24dB -8dB -9dB .. -69dB
|
||||||
|
{0x000C,-67}, // 14 .. 0 0 1 4 .. -28dB -24dB -6dB -9dB .. -67dB
|
||||||
|
{0x000D,-64}, // 15 .. 0 0 1 5 .. -28dB -24dB -6dB -6dB .. -64dB
|
||||||
|
{0x001C,-61}, // 16 .. 0 0 3 4 .. -28dB -24dB 0dB - 9dB .. -61dB
|
||||||
|
{0x001D,-58}, // 17 .. 0 0 3 5 .. -28dB -24dB 0dB -6dB .. -58dB
|
||||||
|
{0x001E,-55}, // 18 .. 0 0 3 6 .. -28dB -24dB 0dB -3dB .. -55dB
|
||||||
|
{0x001F,-52}, // 19 .. 0 0 3 7 .. -28dB -24dB 0dB 0dB .. -52dB
|
||||||
|
{0x003E,-50}, // 20 .. 0 1 3 6 .. -28dB -19dB 0dB -3dB .. -50dB
|
||||||
|
{0x003F,-47}, // 21 .. 0 1 3 7 .. -28dB -19dB 0dB 0dB .. -47dB
|
||||||
|
{0x005E,-45}, // 22 .. 0 2 3 6 .. -28dB -14dB 0dB -3dB .. -45dB
|
||||||
|
{0x005F,-42}, // 23 .. 0 2 3 7 .. -28dB -14dB 0dB 0dB .. -42dB
|
||||||
|
{0x007E,-40}, // 24 .. 0 3 3 6 .. -28dB -9dB 0dB -3dB .. -40dB
|
||||||
|
{0x007F,-37}, // 25 .. 0 3 3 7 .. -28dB -9dB 0dB 0dB .. -37dB
|
||||||
|
{0x009F,-34}, // 26 .. 0 4 3 7 .. -28dB -6dB 0dB 0dB .. -34dB
|
||||||
|
{0x00BF,-32}, // 27 .. 0 5 3 7 .. -28dB -4dB 0dB 0dB .. -32dB
|
||||||
|
{0x00DF,-30}, // 28 .. 0 6 3 7 .. -28dB -2dB 0dB 0dB .. -30dB
|
||||||
|
{0x00FF,-28}, // 29 .. 0 7 3 7 .. -28dB 0dB 0dB 0dB .. -28dB
|
||||||
|
{0x01DF,-26}, // 30 .. 1 6 3 7 .. -24dB -2dB 0dB 0dB .. -26dB
|
||||||
|
{0x01FF,-24}, // 31 .. 1 7 3 7 .. -24dB 0dB 0dB 0dB .. -24dB
|
||||||
|
{0x02BF,-23}, // 32 .. 2 5 3 7 .. -19dB -4dB 0dB 0dB .. -23dB
|
||||||
|
{0x02DF,-21}, // 33 .. 2 6 3 7 .. -19dB -2dB 0dB -0dB .. -21dB
|
||||||
|
{0x02FF,-19}, // 34 .. 2 7 3 7 .. -19dB 0dB 0dB 0dB .. -19dB
|
||||||
|
{0x035E,-17}, // 35 .. 3 2 3 6 .. 0dB -14dB 0dB -3dB .. -17dB
|
||||||
|
{0x035F,-14}, // 36 .. 3 2 3 7 .. 0dB -14dB 0dB 0dB .. -14dB
|
||||||
|
{0x037E,-12}, // 37 .. 3 3 3 6 .. 0dB -9dB 0dB -3dB .. -12dB
|
||||||
|
{0x037F,-9}, // 38 .. 3 3 3 7 .. 0dB -9dB 0dB 0dB .. -9dB
|
||||||
|
{0x038F,-6}, // 39 .. 3 4 3 7 .. 0dB - 6dB 0dB 0dB .. -6dB
|
||||||
|
{0x03BF,-4}, // 40 .. 3 5 3 7 .. 0dB -4dB 0dB 0dB .. -4dB
|
||||||
|
{0x03DF,-2}, // 41 .. 3 6 3 7 .. 0dB - 2dB 0dB 0dB .. -2dB
|
||||||
|
{0x03FF,0} // 42 .. 3 7 3 7 .. 0dB 0dB 0dB 0dB .. 0dB
|
||||||
|
|
||||||
|
};
|
||||||
|
const uint8_t gain_table_size = ARRAY_SIZE(gain_table);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
{0x0000, -98}, // 1 .. 0 0 0 0 .. -33dB -24dB -8dB -33dB .. -98dB
|
t_gain_table gain_table[100] = {{0x03BE, -7}}; //original
|
||||||
{0x0008, -96}, // 2 .. 0 0 1 0 .. -33dB -24dB -6dB -33dB .. -96dB
|
uint8_t gain_table_size = 0;
|
||||||
{0x0100, -95}, // 3 .. 1 0 0 0 .. -30dB -24dB -8dB -33dB .. -95dB
|
|
||||||
{0x0020, -93}, // 4 .. 0 1 0 0 .. -33dB -19dB -8dB -33dB .. -93dB
|
|
||||||
{0x0001, -92}, // 5 .. 0 0 0 1 .. -33dB -24dB -8dB -27dB .. -92dB
|
|
||||||
{0x0028, -91}, // 6 .. 0 1 1 0 .. -33dB -19dB -6dB -33dB .. -91dB
|
|
||||||
{0x0009, -90}, // 7 .. 0 0 1 1 .. -33dB -24dB -6dB -27dB .. -90dB
|
|
||||||
{0x0101, -89}, // 8 .. 1 0 0 1 .. -30dB -24dB -8dB -27dB .. -89dB
|
|
||||||
{0x0030, -88}, // 9 .. 0 1 2 0 .. -33dB -19dB -3dB -33dB .. -88dB
|
|
||||||
{0x0118, -87}, // 10 .. 1 0 3 0 .. -30dB -24dB 0dB -33dB .. -87dB
|
|
||||||
{0x0002, -86}, // 11 .. 0 0 0 2 .. -33dB -24dB -8dB -21dB .. -86dB
|
|
||||||
{0x0130, -85}, // 12 .. 1 1 2 0 .. -30dB -19dB -3dB -33dB .. -85dB
|
|
||||||
{0x0019, -84}, // 13 .. 0 0 3 1 .. -33dB -24dB 0dB -27dB .. -84dB
|
|
||||||
{0x0060, -83}, // 14 .. 0 3 0 0 .. -33dB -9dB -8dB -33dB .. -83dB
|
|
||||||
{0x0138, -82}, // 15 .. 1 1 3 0 .. -30dB -19dB 0dB -33dB .. -82dB
|
|
||||||
{0x0119, -81}, // 16 .. 1 0 3 1 .. -30dB -24dB 0dB -27dB .. -81dB
|
|
||||||
{0x0058, -80}, // 17 .. 0 2 3 0 .. -33dB -14dB 0dB -33dB .. -80dB
|
|
||||||
{0x0141, -79}, // 18 .. 1 2 0 1 .. -30dB -14dB -8dB -27dB .. -79dB
|
|
||||||
{0x0070, -78}, // 19 .. 0 3 2 0 .. -33dB -9dB -3dB -33dB .. -78dB
|
|
||||||
{0x0180, -77}, // 20 .. 1 4 0 0 .. -30dB -6dB -8dB -33dB .. -77dB
|
|
||||||
{0x0139, -76}, // 21 .. 1 1 3 1 .. -30dB -19dB 0dB -27dB .. -76dB
|
|
||||||
{0x0013, -75}, // 22 .. 0 0 2 3 .. -33dB -24dB -3dB -15dB .. -75dB
|
|
||||||
{0x0161, -74}, // 23 .. 1 3 0 1 .. -30dB -9dB -8dB -27dB .. -74dB
|
|
||||||
{0x01C0, -73}, // 24 .. 1 6 0 0 .. -30dB -2dB -8dB -33dB .. -73dB
|
|
||||||
{0x00E8, -72}, // 25 .. 0 7 1 0 .. -33dB 0dB -6dB -33dB .. -72dB
|
|
||||||
{0x00D0, -71}, // 26 .. 0 6 2 0 .. -33dB -2dB -3dB -33dB .. -71dB
|
|
||||||
{0x0239, -70}, // 27 .. 2 1 3 1 .. -24dB -19dB 0dB -27dB .. -70dB
|
|
||||||
{0x006A, -69}, // 28 .. 0 3 1 2 .. -33dB -9dB -6dB -21dB .. -69dB
|
|
||||||
{0x0006, -68}, // 29 .. 0 0 0 6 .. -33dB -24dB -8dB -3dB .. -68dB
|
|
||||||
{0x00B1, -67}, // 30 .. 0 5 2 1 .. -33dB -4dB -3dB -27dB .. -67dB
|
|
||||||
{0x000E, -66}, // 31 .. 0 0 1 6 .. -33dB -24dB -6dB -3dB .. -66dB
|
|
||||||
{0x015A, -65}, // 32 .. 1 2 3 2 .. -30dB -14dB 0dB -21dB .. -65dB
|
|
||||||
{0x022B, -64}, // 33 .. 2 1 1 3 .. -24dB -19dB -6dB -15dB .. -64dB
|
|
||||||
{0x01F8, -63}, // 34 .. 1 7 3 0 .. -30dB 0dB 0dB -33dB .. -63dB
|
|
||||||
{0x0163, -62}, // 35 .. 1 3 0 3 .. -30dB -9dB -8dB -15dB .. -62dB
|
|
||||||
{0x0035, -61}, // 36 .. 0 1 2 5 .. -33dB -19dB -3dB -6dB .. -61dB
|
|
||||||
{0x0214, -60}, // 37 .. 2 0 2 4 .. -24dB -24dB -3dB -9dB .. -60dB
|
|
||||||
{0x01D9, -59}, // 38 .. 1 6 3 1 .. -30dB -2dB 0dB -27dB .. -59dB
|
|
||||||
{0x0145, -58}, // 39 .. 1 2 0 5 .. -30dB -14dB -8dB -6dB .. -58dB
|
|
||||||
{0x02A2, -57}, // 40 .. 2 5 0 2 .. -24dB -4dB -8dB -21dB .. -57dB
|
|
||||||
{0x02D1, -56}, // 41 .. 2 6 2 1 .. -24dB -2dB -3dB -27dB .. -56dB
|
|
||||||
{0x00B3, -55}, // 42 .. 0 5 2 3 .. -33dB -4dB -3dB -15dB .. -55dB
|
|
||||||
{0x0216, -54}, // 43 .. 2 0 2 6 .. -24dB -24dB -3dB -3dB .. -54dB
|
|
||||||
{0x0066, -53}, // 44 .. 0 3 0 6 .. -33dB -9dB -8dB -3dB .. -53dB
|
|
||||||
{0x00C4, -52}, // 45 .. 0 6 0 4 .. -33dB -2dB -8dB -9dB .. -52dB
|
|
||||||
{0x006E, -51}, // 46 .. 0 3 1 6 .. -33dB -9dB -6dB -3dB .. -51dB
|
|
||||||
{0x015D, -50}, // 47 .. 1 2 3 5 .. -30dB -14dB 0dB -6dB .. -50dB
|
|
||||||
{0x00AD, -49}, // 48 .. 0 5 1 5 .. -33dB -4dB -6dB -6dB .. -49dB
|
|
||||||
{0x007D, -48}, // 49 .. 0 3 3 5 .. -33dB -9dB 0dB -6dB .. -48dB
|
|
||||||
{0x00D4, -47}, // 50 .. 0 6 2 4 .. -33dB -2dB -3dB -9dB .. -47dB
|
|
||||||
{0x01B4, -46}, // 51 .. 1 5 2 4 .. -30dB -4dB -3dB -9dB .. -46dB
|
|
||||||
{0x030B, -45}, // 52 .. 3 0 1 3 .. 0dB -24dB -6dB -15dB .. -45dB
|
|
||||||
{0x00CE, -44}, // 53 .. 0 6 1 6 .. -33dB -2dB -6dB -3dB .. -44dB
|
|
||||||
{0x01B5, -43}, // 54 .. 1 5 2 5 .. -30dB -4dB -3dB -6dB .. -43dB
|
|
||||||
{0x0097, -42}, // 55 .. 0 4 2 7 .. -33dB -6dB -3dB 0dB .. -42dB
|
|
||||||
{0x0257, -41}, // 56 .. 2 2 2 7 .. -24dB -14dB -3dB 0dB .. -41dB
|
|
||||||
{0x02B4, -40}, // 57 .. 2 5 2 4 .. -24dB -4dB -3dB -9dB .. -40dB
|
|
||||||
{0x027D, -39}, // 58 .. 2 3 3 5 .. -24dB -9dB 0dB -6dB .. -39dB
|
|
||||||
{0x01DD, -38}, // 59 .. 1 6 3 5 .. -30dB -2dB 0dB -6dB .. -38dB
|
|
||||||
{0x02AE, -37}, // 60 .. 2 5 1 6 .. -24dB -4dB -6dB -3dB .. -37dB
|
|
||||||
{0x0379, -36}, // 61 .. 3 3 3 1 .. 0dB -9dB 0dB -27dB .. -36dB
|
|
||||||
{0x035A, -35}, // 62 .. 3 2 3 2 .. 0dB -14dB 0dB -21dB .. -35dB
|
|
||||||
{0x02B6, -34}, // 63 .. 2 5 2 6 .. -24dB -4dB -3dB -3dB .. -34dB
|
|
||||||
{0x030E, -33}, // 64 .. 3 0 1 6 .. 0dB -24dB -6dB -3dB .. -33dB
|
|
||||||
{0x0307, -32}, // 65 .. 3 0 0 7 .. 0dB -24dB -8dB 0dB .. -32dB
|
|
||||||
{0x02BE, -31}, // 66 .. 2 5 3 6 .. -24dB -4dB 0dB -3dB .. -31dB
|
|
||||||
{0x037A, -30}, // 67 .. 3 3 3 2 .. 0dB -9dB 0dB -21dB .. -30dB
|
|
||||||
{0x02DE, -29}, // 68 .. 2 6 3 6 .. -24dB -2dB 0dB -3dB .. -29dB
|
|
||||||
{0x0345, -28}, // 69 .. 3 2 0 5 .. 0dB -14dB -8dB -6dB .. -28dB
|
|
||||||
{0x03A3, -27}, // 70 .. 3 5 0 3 .. 0dB -4dB -8dB -15dB .. -27dB
|
|
||||||
{0x0364, -26}, // 71 .. 3 3 0 4 .. 0dB -9dB -8dB -9dB .. -26dB
|
|
||||||
{0x032F, -25}, // 72 .. 3 1 1 7 .. 0dB -19dB -6dB 0dB .. -25dB
|
|
||||||
{0x0393, -24}, // 73 .. 3 4 2 3 .. 0dB -6dB -3dB -15dB .. -24dB
|
|
||||||
{0x0384, -23}, // 74 .. 3 4 0 4 .. 0dB -6dB -8dB -9dB .. -23dB
|
|
||||||
{0x0347, -22}, // 75 .. 3 2 0 7 .. 0dB -14dB -8dB 0dB .. -22dB
|
|
||||||
{0x03EB, -21}, // 76 .. 3 7 1 3 .. 0dB 0dB -6dB -15dB .. -21dB
|
|
||||||
{0x03D3, -20}, // 77 .. 3 6 2 3 .. 0dB -2dB -3dB -15dB .. -20dB
|
|
||||||
{0x03BB, -19}, // 78 .. 3 5 3 3 .. 0dB -4dB 0dB -15dB .. -19dB
|
|
||||||
{0x037C, -18}, // 79 .. 3 3 3 4 .. 0dB -9dB 0dB -9dB .. -18dB
|
|
||||||
{0x035E, -17}, // 80 .. 3 2 3 6 .. 0dB -14dB 0dB -3dB .. -17dB original
|
|
||||||
{0x03C5, -16}, // 81 .. 3 6 0 5 .. 0dB -2dB -8dB -6dB .. -16dB
|
|
||||||
{0x03EC, -15}, // 82 .. 3 7 1 4 .. 0dB 0dB -6dB -9dB .. -15dB
|
|
||||||
{0x035F, -14}, // 83 .. 3 2 3 7 .. 0dB -14dB 0dB 0dB .. -14dB
|
|
||||||
{0x03C6, -13}, // 84 .. 3 6 0 6 .. 0dB -2dB -8dB -3dB .. -13dB
|
|
||||||
{0x0377, -12}, // 85 .. 3 3 2 7 .. 0dB -9dB -3dB 0dB .. -12dB
|
|
||||||
{0x03E6, -11}, // 86 .. 3 7 0 6 .. 0dB 0dB -8dB -3dB .. -11dB
|
|
||||||
{0x03BD, -10}, // 87 .. 3 5 3 5 .. 0dB -4dB 0dB -6dB .. -10dB
|
|
||||||
{0x03F5, -9}, // 88 .. 3 7 2 5 .. 0dB 0dB -3dB -6dB .. -9dB
|
|
||||||
{0x03DD, -8}, // 89 .. 3 6 3 5 .. 0dB -2dB 0dB -6dB .. -8dB
|
|
||||||
{0x03B7, -7}, // 90 .. 3 5 2 7 .. 0dB -4dB -3dB 0dB .. -7dB
|
|
||||||
{0x03F6, -6}, // 91 .. 3 7 2 6 .. 0dB 0dB -3dB -3dB .. -6dB
|
|
||||||
{0x03D7, -5}, // 92 .. 3 6 2 7 .. 0dB -2dB -3dB 0dB .. -5dB
|
|
||||||
{0x03BF, -4}, // 93 .. 3 5 3 7 .. 0dB -4dB 0dB 0dB .. -4dB
|
|
||||||
{0x03F7, -3}, // 94 .. 3 7 2 7 .. 0dB 0dB -3dB 0dB .. -3dB
|
|
||||||
{0x03DF, -2}, // 95 .. 3 6 3 7 .. 0dB -2dB 0dB 0dB .. -2dB
|
|
||||||
{0x03FF, 0} // 96 .. 3 7 3 7 .. 0dB 0dB 0dB 0dB .. 0dB
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned int original_index = 80;
|
void CreateTable()
|
||||||
|
{
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
uint8_t pgaIdx:3;
|
||||||
|
uint8_t mixerIdx:2;
|
||||||
|
uint8_t lnaIdx:3;
|
||||||
|
uint8_t lnaSIdx:2;
|
||||||
|
};
|
||||||
|
uint16_t __raw;
|
||||||
|
} GainData;
|
||||||
|
|
||||||
|
static const int8_t lna_short_dB[] = {-28, -24, -19, 0}; // corrected'ish
|
||||||
|
static const int8_t lna_dB[] = {-24, -19, -14, -9, -6, -4, -2, 0};
|
||||||
|
static const int8_t mixer_dB[] = { -8, -6, -3, 0};
|
||||||
|
static const int8_t pga_dB[] = {-33, -27, -21, -15, -9, -6, -3, 0};
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
for (uint8_t lnaSIdx = 0; lnaSIdx < ARRAY_SIZE(lna_short_dB); lnaSIdx++) {
|
||||||
|
for (uint8_t lnaIdx = 0; lnaIdx < ARRAY_SIZE(lna_dB); lnaIdx++) {
|
||||||
|
for (uint8_t mixerIdx = 0; mixerIdx < ARRAY_SIZE(mixer_dB); mixerIdx++) {
|
||||||
|
for (uint8_t pgaIdx = 0; pgaIdx < ARRAY_SIZE(pga_dB); pgaIdx++) {
|
||||||
|
int16_t db = lna_short_dB[lnaSIdx] + lna_dB[lnaIdx] + mixer_dB[mixerIdx] + pga_dB[pgaIdx];
|
||||||
|
GainData gainData = {{
|
||||||
|
pgaIdx,
|
||||||
|
mixerIdx,
|
||||||
|
lnaIdx,
|
||||||
|
lnaSIdx,
|
||||||
|
}};
|
||||||
|
|
||||||
|
for (i = 1; i < ARRAY_SIZE(gain_table); i++) {
|
||||||
|
t_gain_table * gain = &gain_table[i];
|
||||||
|
if (db == gain->gain_dB)
|
||||||
|
break;
|
||||||
|
if (db > gain->gain_dB)
|
||||||
|
continue;
|
||||||
|
if (db < gain->gain_dB) {
|
||||||
|
if(gain->gain_dB)
|
||||||
|
memmove(gain + 1, gain, 100 - i);
|
||||||
|
gain->gain_dB = db;
|
||||||
|
gain->reg_val = gainData.__raw;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gain->gain_dB = db;
|
||||||
|
gain->reg_val = gainData.__raw;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gain_table_size = i+1;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
||||||
|
// display update rate
|
||||||
|
static const unsigned int display_update_rate = 250 / 10; // max 250ms display update rate
|
||||||
|
unsigned int counter = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned int gain_table_index[2] = {0, 0};
|
||||||
|
// used simply to detect a changed gain setting
|
||||||
|
unsigned int gain_table_index_prev[2] = {0, 0};
|
||||||
|
// holds the previous RSSI level .. we do an average of old + new RSSI reading
|
||||||
|
int16_t prev_rssi[2] = {0, 0};
|
||||||
|
// to help reduce gain hunting, peak hold count down tick
|
||||||
|
unsigned int hold_counter[2] = {0, 0};
|
||||||
|
// -89dBm, any higher and the AM demodulator starts to saturate/clip/distort
|
||||||
|
const int16_t desired_rssi = (-89 + 160) * 2;
|
||||||
|
|
||||||
|
int8_t currentGainDiff;
|
||||||
|
bool enabled = true;
|
||||||
|
|
||||||
|
void AM_fix_init(void)
|
||||||
|
{ // called at boot-up
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
gain_table_index[i] = 0; // re-start with original QS setting
|
||||||
|
}
|
||||||
|
#if !LOOKUP_TABLE
|
||||||
|
CreateTable();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void AM_fix_reset(const unsigned vfo)
|
||||||
|
{ // reset the AM fixer upper
|
||||||
|
if (vfo > 1)
|
||||||
|
return;
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
||||||
// display update rate
|
counter = 0;
|
||||||
static const unsigned int display_update_rate = 250 / 10; // max 250ms display update rate
|
|
||||||
unsigned int counter = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX_TEST1
|
prev_rssi[vfo] = 0;
|
||||||
// user manually sets the table index .. used to calibrate the desired dB gain table
|
hold_counter[vfo] = 0;
|
||||||
unsigned int gain_table_index[2] = {1 + gSetting_AM_fix_test1, 1 + gSetting_AM_fix_test1};
|
gain_table_index_prev[vfo] = 0;
|
||||||
#else
|
}
|
||||||
unsigned int gain_table_index[2] = {original_index, original_index};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// used simply to detect a changed gain setting
|
// adjust the RX gain to try and prevent the AM demodulator from
|
||||||
unsigned int gain_table_index_prev[2] = {0, 0};
|
// saturating/overloading/clipping (distorted AM audio)
|
||||||
|
//
|
||||||
|
// we're actually doing the BK4819's job for it here, but as the chip
|
||||||
|
// won't/don't do it for itself, we're left to bodging it ourself by
|
||||||
|
// playing with the RF front end gain setting
|
||||||
|
//
|
||||||
|
void AM_fix_10ms(const unsigned vfo)
|
||||||
|
{
|
||||||
|
if(!gSetting_AM_fix || !enabled || vfo > 1 )
|
||||||
|
return;
|
||||||
|
|
||||||
// holds the previous RSSI level .. we do an average of old + new RSSI reading
|
switch (gCurrentFunction)
|
||||||
int16_t prev_rssi[2] = {0, 0};
|
{
|
||||||
|
case FUNCTION_TRANSMIT:
|
||||||
|
case FUNCTION_BAND_SCOPE:
|
||||||
|
case FUNCTION_POWER_SAVE:
|
||||||
|
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
||||||
|
counter = display_update_rate; // queue up a display update as soon as we switch to RX mode
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
|
||||||
// to help reduce gain hunting, peak hold count down tick
|
// only adjust stuff if we're in one of these modes
|
||||||
unsigned int hold_counter[2] = {0, 0};
|
case FUNCTION_FOREGROUND:
|
||||||
|
case FUNCTION_RECEIVE:
|
||||||
|
case FUNCTION_MONITOR:
|
||||||
|
case FUNCTION_INCOMING:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// used to correct the RSSI readings after our RF gain adjustments
|
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
||||||
int16_t rssi_gain_diff[2] = {0, 0};
|
if (counter > 0) {
|
||||||
|
if (++counter >= display_update_rate) { // trigger a display update
|
||||||
// used to limit the max RF gain
|
counter = 0;
|
||||||
unsigned int max_index = ARRAY_SIZE(gain_table) - 1;
|
gUpdateDisplay = true;
|
||||||
|
|
||||||
#ifndef ENABLE_AM_FIX_TEST1
|
|
||||||
// -89dBm, any higher and the AM demodulator starts to saturate/clip/distort
|
|
||||||
const int16_t desired_rssi = (-89 + 160) * 2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void AM_fix_init(void)
|
|
||||||
{ // called at boot-up
|
|
||||||
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
#ifdef ENABLE_AM_FIX_TEST1
|
|
||||||
gain_table_index[i] = 1 + gSetting_AM_fix_test1;
|
|
||||||
#else
|
|
||||||
gain_table_index[i] = original_index; // re-start with original QS setting
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
static uint32_t lastFreq[2];
|
||||||
{ // set a maximum gain to use
|
if(gEeprom.VfoInfo[vfo].pRX->Frequency != lastFreq[vfo]) {
|
||||||
// const int16_t max_gain_dB = gain_dB[original_index];
|
lastFreq[vfo] = gEeprom.VfoInfo[vfo].pRX->Frequency;
|
||||||
const int16_t max_gain_dB = -10;
|
AM_fix_reset(vfo);
|
||||||
|
}
|
||||||
|
|
||||||
max_index = ARRAY_SIZE(gain_table);
|
int16_t rssi;
|
||||||
while (--max_index > 1)
|
{ // sample the current RSSI level
|
||||||
// if (gain_dB[max_index] <= max_gain_dB)
|
// average it with the previous rssi (a bit of noise/spike immunity)
|
||||||
if (gain_table[max_index].gain_dB <= max_gain_dB)
|
const int16_t new_rssi = BK4819_GetRSSI();
|
||||||
|
rssi = (prev_rssi[vfo] > 0) ? (prev_rssi[vfo] + new_rssi) / 2 : new_rssi;
|
||||||
|
prev_rssi[vfo] = new_rssi;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
||||||
|
{
|
||||||
|
static int16_t lastRssi;
|
||||||
|
|
||||||
|
if (lastRssi != rssi) { // rssi changed
|
||||||
|
lastRssi = rssi;
|
||||||
|
|
||||||
|
if (counter == 0) {
|
||||||
|
counter = 1;
|
||||||
|
gUpdateDisplay = true; // trigger a display update
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// automatically adjust the RF RX gain
|
||||||
|
|
||||||
|
// update the gain hold counter
|
||||||
|
if (hold_counter[vfo] > 0)
|
||||||
|
hold_counter[vfo]--;
|
||||||
|
|
||||||
|
// dB difference between actual and desired RSSI level
|
||||||
|
int16_t diff_dB = (rssi - desired_rssi) / 2;
|
||||||
|
|
||||||
|
if (diff_dB > 0) { // decrease gain
|
||||||
|
unsigned int index = gain_table_index[vfo]; // current position we're at
|
||||||
|
|
||||||
|
if (diff_dB >= 10) { // jump immediately to a new gain setting
|
||||||
|
// this greatly speeds up initial gain reduction (but reduces noise/spike immunity)
|
||||||
|
|
||||||
|
const int16_t desired_gain_dB = (int16_t)gain_table[index].gain_dB - diff_dB + 8; // get no closer than 8dB (bit of noise/spike immunity)
|
||||||
|
|
||||||
|
// scan the table to see what index to jump straight too
|
||||||
|
while (index > 1)
|
||||||
|
if (gain_table[--index].gain_dB <= desired_gain_dB)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#else
|
else
|
||||||
// use the full range of available gains
|
{ // incrementally reduce the gain .. taking it slow improves noise/spike immunity
|
||||||
max_index = ARRAY_SIZE(gain_table) - 1;
|
if (index > 1)
|
||||||
#endif
|
index--; // slow step-by-step gain reduction
|
||||||
|
}
|
||||||
|
|
||||||
|
index = MAX(1u, index);
|
||||||
|
|
||||||
|
if (gain_table_index[vfo] != index)
|
||||||
|
{
|
||||||
|
gain_table_index[vfo] = index;
|
||||||
|
hold_counter[vfo] = 30; // 300ms hold
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AM_fix_reset(const int vfo)
|
if (diff_dB >= -6) // 6dB hysterisis (help reduce gain hunting)
|
||||||
{ // reset the AM fixer upper
|
hold_counter[vfo] = 30; // 300ms hold
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
if (hold_counter[vfo] == 0)
|
||||||
counter = 0;
|
{ // hold has been released, we're free to increase gain
|
||||||
#endif
|
const unsigned int index = gain_table_index[vfo] + 1; // move up to next gain index
|
||||||
|
gain_table_index[vfo] = MIN(index, gain_table_size - 1u);
|
||||||
prev_rssi[vfo] = 0;
|
|
||||||
|
|
||||||
hold_counter[vfo] = 0;
|
|
||||||
|
|
||||||
rssi_gain_diff[vfo] = 0;
|
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX_TEST1
|
|
||||||
// gain_table_index[vfo] = 1 + gSetting_AM_fix_test1;
|
|
||||||
#else
|
|
||||||
// gain_table_index[vfo] = original_index; // re-start with original QS setting
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gain_table_index_prev[vfo] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust the RX gain to try and prevent the AM demodulator from
|
|
||||||
// saturating/overloading/clipping (distorted AM audio)
|
|
||||||
//
|
|
||||||
// we're actually doing the BK4819's job for it here, but as the chip
|
|
||||||
// won't/don't do it for itself, we're left to bodging it ourself by
|
|
||||||
// playing with the RF front end gain setting
|
|
||||||
//
|
|
||||||
void AM_fix_10ms(const int vfo)
|
|
||||||
{
|
|
||||||
int16_t diff_dB;
|
|
||||||
int16_t rssi;
|
|
||||||
|
|
||||||
switch (gCurrentFunction)
|
{ // apply the new settings to the front end registers
|
||||||
{
|
const unsigned int index = gain_table_index[vfo];
|
||||||
case FUNCTION_TRANSMIT:
|
|
||||||
case FUNCTION_BAND_SCOPE:
|
|
||||||
case FUNCTION_POWER_SAVE:
|
|
||||||
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
|
||||||
counter = display_update_rate; // queue up a display update as soon as we switch to RX mode
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
|
|
||||||
// only adjust stuff if we're in one of these modes
|
// remember the new table index
|
||||||
case FUNCTION_FOREGROUND:
|
gain_table_index_prev[vfo] = index;
|
||||||
case FUNCTION_RECEIVE:
|
currentGainDiff = gain_table[0].gain_dB - gain_table[index].gain_dB;
|
||||||
case FUNCTION_MONITOR:
|
BK4819_WriteRegister(BK4819_REG_13, gain_table[index].reg_val);
|
||||||
case FUNCTION_INCOMING:
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
||||||
if (counter > 0)
|
if (counter == 0) {
|
||||||
{
|
counter = 1;
|
||||||
if (++counter >= display_update_rate)
|
gUpdateDisplay = true;
|
||||||
{ // trigger a display update
|
}
|
||||||
counter = 0;
|
#endif
|
||||||
gUpdateDisplay = true;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{ // sample the current RSSI level
|
|
||||||
// average it with the previous rssi (a bit of noise/spike immunity)
|
|
||||||
const int16_t new_rssi = BK4819_GetRSSI();
|
|
||||||
rssi = (prev_rssi[vfo] > 0) ? (prev_rssi[vfo] + new_rssi) / 2 : new_rssi;
|
|
||||||
prev_rssi[vfo] = new_rssi;
|
|
||||||
}
|
|
||||||
|
|
||||||
// save the corrected RSSI level
|
|
||||||
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
|
||||||
{
|
|
||||||
const int16_t new_rssi = rssi - rssi_gain_diff[vfo];
|
|
||||||
if (gCurrentRSSI[vfo] != new_rssi)
|
|
||||||
{
|
|
||||||
gCurrentRSSI[vfo] = new_rssi;
|
|
||||||
|
|
||||||
if (counter == 0)
|
|
||||||
{ // trigger a display update
|
|
||||||
counter = 1;
|
|
||||||
gUpdateDisplay = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
gCurrentRSSI[vfo] = rssi - rssi_gain_diff[vfo];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX_TEST1
|
|
||||||
// user is manually adjusting a gain register - don't do anything automatically
|
|
||||||
|
|
||||||
{
|
|
||||||
int i = 1 + (int)gSetting_AM_fix_test1;
|
|
||||||
i = (i < 1) ? 1 : (i > ((int)ARRAY_SIZE(gain_table) - 1) ? ARRAY_SIZE(gain_table) - 1 : i;
|
|
||||||
|
|
||||||
if (gain_table_index[vfo] == i)
|
|
||||||
return; // no change
|
|
||||||
|
|
||||||
gain_table_index[vfo] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
// automatically adjust the RF RX gain
|
|
||||||
|
|
||||||
// update the gain hold counter
|
|
||||||
if (hold_counter[vfo] > 0)
|
|
||||||
hold_counter[vfo]--;
|
|
||||||
|
|
||||||
// dB difference between actual and desired RSSI level
|
|
||||||
diff_dB = (rssi - desired_rssi) / 2;
|
|
||||||
|
|
||||||
if (diff_dB > 0)
|
|
||||||
{ // decrease gain
|
|
||||||
|
|
||||||
unsigned int index = gain_table_index[vfo]; // current position we're at
|
|
||||||
|
|
||||||
if (diff_dB >= 10)
|
|
||||||
{ // jump immediately to a new gain setting
|
|
||||||
// this greatly speeds up initial gain reduction (but reduces noise/spike immunity)
|
|
||||||
|
|
||||||
const int16_t desired_gain_dB = (int16_t)gain_table[index].gain_dB - diff_dB + 8; // get no closer than 8dB (bit of noise/spike immunity)
|
|
||||||
|
|
||||||
// scan the table to see what index to jump straight too
|
|
||||||
while (index > 1)
|
|
||||||
if (gain_table[--index].gain_dB <= desired_gain_dB)
|
|
||||||
break;
|
|
||||||
|
|
||||||
//index = (gain_table_index[vfo] + index) / 2; // easy does it
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // incrementally reduce the gain .. taking it slow improves noise/spike immunity
|
|
||||||
|
|
||||||
// if (index >= (1 + 3) && diff_dB >= 3)
|
|
||||||
// index -= 3; // faster gain reduction
|
|
||||||
// else
|
|
||||||
if (index > 1)
|
|
||||||
index--; // slow step-by-step gain reduction
|
|
||||||
}
|
|
||||||
|
|
||||||
index = (index < 1) ? 1 : (index > max_index) ? max_index : index;
|
|
||||||
|
|
||||||
if (gain_table_index[vfo] != index)
|
|
||||||
{
|
|
||||||
gain_table_index[vfo] = index;
|
|
||||||
hold_counter[vfo] = 30; // 300ms hold
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (diff_dB >= -6) // 6dB hysterisis (help reduce gain hunting)
|
|
||||||
hold_counter[vfo] = 30; // 300ms hold
|
|
||||||
|
|
||||||
if (hold_counter[vfo] == 0)
|
|
||||||
{ // hold has been released, we're free to increase gain
|
|
||||||
const unsigned int index = gain_table_index[vfo] + 1; // move up to next gain index
|
|
||||||
gain_table_index[vfo] = (index <= max_index) ? index : max_index; // limit the gain index
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (gain_table_index[vfo] == gain_table_index_prev[vfo])
|
|
||||||
return; // no gain change - this is to reduce writing to the BK chip on ever call
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
||||||
|
void AM_fix_print_data(const unsigned vfo, char *s) {
|
||||||
|
if (s != NULL && vfo < ARRAY_SIZE(gain_table_index)) {
|
||||||
|
const unsigned int index = gain_table_index[vfo];
|
||||||
|
sprintf(s, "%2u %4ddB %3u", index, gain_table[index].gain_dB, prev_rssi[vfo]);
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{ // apply the new settings to the front end registers
|
int8_t AM_fix_get_gain_diff()
|
||||||
|
{
|
||||||
const unsigned int index = gain_table_index[vfo];
|
return currentGainDiff;
|
||||||
|
}
|
||||||
// remember the new table index
|
|
||||||
gain_table_index_prev[vfo] = index;
|
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_13, gain_table[index].reg_val);
|
|
||||||
|
|
||||||
// offset the RSSI reading to the rest of the firmware to cancel out the gain adjustments we make
|
|
||||||
|
|
||||||
// RF gain difference from original QS setting
|
|
||||||
rssi_gain_diff[vfo] = ((int16_t)gain_table[index].gain_dB - gain_table[original_index].gain_dB) * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// save the corrected RSSI level
|
|
||||||
gCurrentRSSI[vfo] = rssi - rssi_gain_diff[vfo];
|
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
|
||||||
if (counter == 0)
|
|
||||||
{
|
|
||||||
counter = 1;
|
|
||||||
gUpdateDisplay = true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
|
||||||
|
|
||||||
void AM_fix_print_data(const int vfo, char *s)
|
|
||||||
{
|
|
||||||
if (s != NULL && vfo >= 0 && vfo < (int)ARRAY_SIZE(gain_table_index))
|
|
||||||
{
|
|
||||||
const unsigned int index = gain_table_index[vfo];
|
|
||||||
// sprintf(s, "%2u.%u %4ddB %3u", index, ARRAY_SIZE(gain_table) - 1, gain_table[index].gain_dB, prev_rssi[vfo]);
|
|
||||||
sprintf(s, "%2u %4ddB %3u", index, gain_table[index].gain_dB, prev_rssi[vfo]);
|
|
||||||
counter = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
void AM_fix_enable(bool on)
|
||||||
|
{
|
||||||
|
enabled = on;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
10
am_fix.h
10
am_fix.h
@@ -21,14 +21,14 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX
|
#ifdef ENABLE_AM_FIX
|
||||||
extern int16_t rssi_gain_diff[2];
|
|
||||||
|
|
||||||
void AM_fix_init(void);
|
void AM_fix_init(void);
|
||||||
void AM_fix_reset(const int vfo);
|
void AM_fix_reset(const unsigned vfo);
|
||||||
void AM_fix_10ms(const int vfo);
|
void AM_fix_10ms(const unsigned vfo);
|
||||||
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
#ifdef ENABLE_AM_FIX_SHOW_DATA
|
||||||
void AM_fix_print_data(const int vfo, char *s);
|
void AM_fix_print_data(const unsigned vfo, char *s);
|
||||||
#endif
|
#endif
|
||||||
|
int8_t AM_fix_get_gain_diff();
|
||||||
|
void AM_fix_enable(bool on);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
643
app/action.c
643
app/action.c
@@ -14,11 +14,17 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "app/action.h"
|
#include "app/action.h"
|
||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
|
#include "app/chFrScanner.h"
|
||||||
|
#include "app/common.h"
|
||||||
#include "app/dtmf.h"
|
#include "app/dtmf.h"
|
||||||
|
#ifdef ENABLE_FLASHLIGHT
|
||||||
|
#include "app/flashlight.h"
|
||||||
|
#endif
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
#include "app/fm.h"
|
#include "app/fm.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -30,28 +36,73 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "driver/bk4819.h"
|
#include "driver/bk4819.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
|
#include "driver/backlight.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "ui/inputbox.h"
|
#include "ui/inputbox.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
|
||||||
static void ACTION_FlashLight(void)
|
#if defined(ENABLE_FMRADIO)
|
||||||
{
|
static void ACTION_Scan_FM(bool bRestart);
|
||||||
switch (gFlashLightState)
|
#endif
|
||||||
{
|
|
||||||
case 0:
|
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
|
||||||
gFlashLightState++;
|
static void ACTION_AlarmOr1750(bool b1750);
|
||||||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
|
inline static void ACTION_Alarm() { ACTION_AlarmOr1750(false); }
|
||||||
break;
|
inline static void ACTION_1750() { ACTION_AlarmOr1750(true); };
|
||||||
case 1:
|
#endif
|
||||||
gFlashLightState++;
|
|
||||||
break;
|
inline static void ACTION_ScanRestart() { ACTION_Scan(true); };
|
||||||
default:
|
|
||||||
gFlashLightState = 0;
|
void (*action_opt_table[])(void) = {
|
||||||
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
|
[ACTION_OPT_NONE] = &FUNCTION_NOP,
|
||||||
}
|
[ACTION_OPT_POWER] = &ACTION_Power,
|
||||||
}
|
[ACTION_OPT_MONITOR] = &ACTION_Monitor,
|
||||||
|
[ACTION_OPT_SCAN] = &ACTION_ScanRestart,
|
||||||
|
[ACTION_OPT_KEYLOCK] = &COMMON_KeypadLockToggle,
|
||||||
|
[ACTION_OPT_A_B] = &COMMON_SwitchVFOs,
|
||||||
|
[ACTION_OPT_VFO_MR] = &COMMON_SwitchVFOMode,
|
||||||
|
[ACTION_OPT_SWITCH_DEMODUL] = &ACTION_SwitchDemodul,
|
||||||
|
|
||||||
|
#ifdef ENABLE_FLASHLIGHT
|
||||||
|
[ACTION_OPT_FLASHLIGHT] = &ACTION_FlashLight,
|
||||||
|
#else
|
||||||
|
[ACTION_OPT_FLASHLIGHT] = &FUNCTION_NOP,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOX
|
||||||
|
[ACTION_OPT_VOX] = &ACTION_Vox,
|
||||||
|
#else
|
||||||
|
[ACTION_OPT_VOX] = &FUNCTION_NOP,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_FMRADIO
|
||||||
|
[ACTION_OPT_FM] = &ACTION_FM,
|
||||||
|
#else
|
||||||
|
[ACTION_OPT_FM] = &FUNCTION_NOP,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_ALARM
|
||||||
|
[ACTION_OPT_ALARM] = &ACTION_Alarm,
|
||||||
|
#else
|
||||||
|
[ACTION_OPT_ALARM] = &FUNCTION_NOP,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_TX1750
|
||||||
|
[ACTION_OPT_1750] = &ACTION_1750,
|
||||||
|
#else
|
||||||
|
[ACTION_OPT_1750] = &FUNCTION_NOP,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_BLMIN_TMP_OFF
|
||||||
|
[ACTION_OPT_BLMIN_TMP_OFF] = &ACTION_BlminTmpOff,
|
||||||
|
#else
|
||||||
|
[ACTION_OPT_BLMIN_TMP_OFF] = &FUNCTION_NOP,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(ARRAY_SIZE(action_opt_table) == ACTION_OPT_LEN);
|
||||||
|
|
||||||
void ACTION_Power(void)
|
void ACTION_Power(void)
|
||||||
{
|
{
|
||||||
@@ -59,369 +110,335 @@ void ACTION_Power(void)
|
|||||||
gTxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW;
|
gTxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW;
|
||||||
|
|
||||||
gRequestSaveChannel = 1;
|
gRequestSaveChannel = 1;
|
||||||
//gRequestSaveChannel = 2; // auto save the channel
|
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
gAnotherVoiceID = VOICE_ID_POWER;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gRequestDisplayScreen = gScreenToDisplay;
|
gRequestDisplayScreen = gScreenToDisplay;
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
gAnotherVoiceID = VOICE_ID_POWER;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ACTION_Monitor(void)
|
void ACTION_Monitor(void)
|
||||||
{
|
{
|
||||||
if (gCurrentFunction != FUNCTION_MONITOR)
|
if (gCurrentFunction != FUNCTION_MONITOR) { // enable the monitor
|
||||||
{ // enable the monitor
|
|
||||||
RADIO_SelectVfos();
|
RADIO_SelectVfos();
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST && gIsNoaaMode)
|
if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST && gIsNoaaMode)
|
||||||
gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
|
gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
|
||||||
#endif
|
#endif
|
||||||
RADIO_SetupRegisters(true);
|
RADIO_SetupRegisters(true);
|
||||||
APP_StartListening(FUNCTION_MONITOR, false);
|
APP_StartListening(FUNCTION_MONITOR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gMonitor = false;
|
gMonitor = false;
|
||||||
|
|
||||||
if (gScanStateDir != SCAN_OFF)
|
if (gScanStateDir != SCAN_OFF) {
|
||||||
{
|
|
||||||
gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms;
|
gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms;
|
||||||
gScheduleScanListen = false;
|
gScheduleScanListen = false;
|
||||||
gScanPauseMode = true;
|
gScanPauseMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode)
|
if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode) {
|
||||||
{
|
gNOAA_Countdown_10ms = NOAA_countdown_10ms;
|
||||||
gNOAA_Countdown_10ms = NOAA_countdown_10ms;
|
gScheduleNOAA = false;
|
||||||
gScheduleNOAA = false;
|
}
|
||||||
}
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
RADIO_SetupRegisters(true);
|
RADIO_SetupRegisters(true);
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
if (gFmRadioMode)
|
if (gFmRadioMode) {
|
||||||
{
|
FM_Start();
|
||||||
FM_Start();
|
gRequestDisplayScreen = DISPLAY_FM;
|
||||||
gRequestDisplayScreen = DISPLAY_FM;
|
}
|
||||||
}
|
else
|
||||||
else
|
#endif
|
||||||
#endif
|
gRequestDisplayScreen = gScreenToDisplay;
|
||||||
gRequestDisplayScreen = gScreenToDisplay;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ACTION_Scan(bool bRestart)
|
void ACTION_Scan(bool bRestart)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_FMRADIO
|
(void)bRestart;
|
||||||
if (gFmRadioMode)
|
|
||||||
{
|
|
||||||
if (gCurrentFunction != FUNCTION_RECEIVE &&
|
|
||||||
gCurrentFunction != FUNCTION_MONITOR &&
|
|
||||||
gCurrentFunction != FUNCTION_TRANSMIT)
|
|
||||||
{
|
|
||||||
GUI_SelectNextDisplay(DISPLAY_FM);
|
|
||||||
|
|
||||||
gMonitor = false;
|
#ifdef ENABLE_FMRADIO
|
||||||
|
if (gFmRadioMode) {
|
||||||
|
ACTION_Scan_FM(bRestart);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (gFM_ScanState != FM_SCAN_OFF)
|
if (SCANNER_IsScanning()) {
|
||||||
{
|
return;
|
||||||
FM_PlayAndUpdate();
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
// not scanning
|
||||||
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
|
gMonitor = false;
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint16_t Frequency;
|
|
||||||
|
|
||||||
if (bRestart)
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
{
|
DTMF_clear_RX();
|
||||||
gFM_AutoScan = true;
|
#endif
|
||||||
gFM_ChannelPosition = 0;
|
gDTMF_RX_live_timeout = 0;
|
||||||
FM_EraseChannels();
|
memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live));
|
||||||
Frequency = gEeprom.FM_LowerLimit;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gFM_AutoScan = false;
|
|
||||||
gFM_ChannelPosition = 0;
|
|
||||||
Frequency = gEeprom.FM_FrequencyPlaying;
|
|
||||||
}
|
|
||||||
|
|
||||||
BK1080_GetFrequencyDeviation(Frequency);
|
RADIO_SelectVfos();
|
||||||
FM_Tune(Frequency, 1, bRestart);
|
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_NOAA
|
||||||
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;
|
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) {
|
||||||
#endif
|
return;
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
|
GUI_SelectNextDisplay(DISPLAY_MAIN);
|
||||||
|
|
||||||
|
if (gScanStateDir != SCAN_OFF) {
|
||||||
|
// already scanning
|
||||||
|
|
||||||
|
if (!IS_MR_CHANNEL(gNextMrChannel)) {
|
||||||
|
CHFRSCANNER_Stop();
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (gScreenToDisplay != DISPLAY_SCANNER)
|
// channel mode. Keep scanning but toggle between scan lists
|
||||||
{ // not scanning
|
|
||||||
|
|
||||||
gMonitor = false;
|
|
||||||
|
|
||||||
DTMF_clear_RX();
|
|
||||||
|
|
||||||
gDTMF_RX_live_timeout = 0;
|
|
||||||
memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live));
|
|
||||||
|
|
||||||
RADIO_SelectVfos();
|
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
|
||||||
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
GUI_SelectNextDisplay(DISPLAY_MAIN);
|
|
||||||
|
|
||||||
if (gScanStateDir != SCAN_OFF)
|
|
||||||
{ // already scanning
|
|
||||||
|
|
||||||
if (gNextMrChannel <= MR_CHANNEL_LAST)
|
|
||||||
{ // channel mode
|
|
||||||
|
|
||||||
// keep scanning but toggle between scan lists
|
|
||||||
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3;
|
|
||||||
|
|
||||||
// jump to the next channel
|
|
||||||
CHANNEL_Next(true, gScanStateDir);
|
|
||||||
gScanPauseDelayIn_10ms = 1;
|
|
||||||
gScheduleScanListen = false;
|
|
||||||
|
|
||||||
gUpdateStatus = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // stop scanning
|
|
||||||
|
|
||||||
SCANNER_Stop();
|
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // start scanning
|
|
||||||
|
|
||||||
CHANNEL_Next(true, SCAN_FWD);
|
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN);
|
|
||||||
AUDIO_PlaySingleVoice(true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// clear the other vfo's rssi level (to hide the antenna symbol)
|
|
||||||
gVFO_RSSI_bar_level[(gEeprom.RX_VFO + 1) & 1u] = 0;
|
|
||||||
|
|
||||||
// let the user see DW is not active
|
|
||||||
gDualWatchActive = false;
|
|
||||||
gUpdateStatus = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// if (!bRestart)
|
|
||||||
if (!bRestart && gNextMrChannel <= MR_CHANNEL_LAST)
|
|
||||||
{ // channel mode, keep scanning but toggle between scan lists
|
|
||||||
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3;
|
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3;
|
||||||
|
|
||||||
// jump to the next channel
|
// jump to the next channel
|
||||||
CHANNEL_Next(true, gScanStateDir);
|
CHFRSCANNER_Start(false, gScanStateDir);
|
||||||
gScanPauseDelayIn_10ms = 1;
|
gScanPauseDelayIn_10ms = 1;
|
||||||
gScheduleScanListen = false;
|
gScheduleScanListen = false;
|
||||||
|
} else {
|
||||||
|
// start scanning
|
||||||
|
CHFRSCANNER_Start(true, SCAN_FWD);
|
||||||
|
|
||||||
gUpdateStatus = true;
|
#ifdef ENABLE_VOICE
|
||||||
|
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN);
|
||||||
|
AUDIO_PlaySingleVoice(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// clear the other vfo's rssi level (to hide the antenna symbol)
|
||||||
|
gVFO_RSSI_bar_level[(gEeprom.RX_VFO + 1) & 1U] = 0;
|
||||||
|
|
||||||
|
// let the user see DW is not active
|
||||||
|
gDualWatchActive = false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{ // stop scanning
|
|
||||||
gMonitor = false;
|
|
||||||
|
|
||||||
SCANNER_Stop();
|
gUpdateStatus = true;
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_VOX
|
|
||||||
void ACTION_Vox(void)
|
|
||||||
{
|
|
||||||
gEeprom.VOX_SWITCH = !gEeprom.VOX_SWITCH;
|
|
||||||
gRequestSaveSettings = true;
|
|
||||||
gFlagReconfigureVfos = true;
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
gAnotherVoiceID = VOICE_ID_VOX;
|
|
||||||
#endif
|
|
||||||
gUpdateStatus = true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
|
void ACTION_SwitchDemodul(void)
|
||||||
static void ACTION_AlarmOr1750(const bool b1750)
|
{
|
||||||
{
|
gRequestSaveChannel = 1;
|
||||||
gInputBoxIndex = 0;
|
|
||||||
|
|
||||||
#if defined(ENABLE_ALARM) && defined(ENABLE_TX1750)
|
gTxVfo->Modulation++;
|
||||||
gAlarmState = b1750 ? ALARM_STATE_TX1750 : ALARM_STATE_TXALARM;
|
|
||||||
gAlarmRunningCounter = 0;
|
|
||||||
#elif defined(ENABLE_ALARM)
|
|
||||||
gAlarmState = ALARM_STATE_TXALARM;
|
|
||||||
gAlarmRunningCounter = 0;
|
|
||||||
#else
|
|
||||||
gAlarmState = ALARM_STATE_TX1750;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gFlagPrepareTX = true;
|
if(gTxVfo->Modulation == MODULATION_UKNOWN)
|
||||||
|
gTxVfo->Modulation = MODULATION_FM;
|
||||||
|
}
|
||||||
|
|
||||||
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
|
|
||||||
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
|
||||||
void ACTION_FM(void)
|
|
||||||
{
|
|
||||||
if (gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_MONITOR)
|
|
||||||
{
|
|
||||||
if (gFmRadioMode)
|
|
||||||
{
|
|
||||||
FM_TurnOff();
|
|
||||||
|
|
||||||
gInputBoxIndex = 0;
|
|
||||||
#ifdef ENABLE_VOX
|
|
||||||
gVoxResumeCountdown = 80;
|
|
||||||
#endif
|
|
||||||
gFlagReconfigureVfos = true;
|
|
||||||
|
|
||||||
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gMonitor = false;
|
|
||||||
|
|
||||||
RADIO_SelectVfos();
|
|
||||||
RADIO_SetupRegisters(true);
|
|
||||||
|
|
||||||
FM_Start();
|
|
||||||
|
|
||||||
gInputBoxIndex = 0;
|
|
||||||
|
|
||||||
gRequestDisplayScreen = DISPLAY_FM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
||||||
{
|
{
|
||||||
uint8_t Short = ACTION_OPT_NONE;
|
if (gScreenToDisplay == DISPLAY_MAIN && gDTMF_InputMode){
|
||||||
uint8_t Long = ACTION_OPT_NONE;
|
// entering DTMF code
|
||||||
|
|
||||||
if (gScreenToDisplay == DISPLAY_MAIN && gDTMF_InputMode)
|
|
||||||
{
|
|
||||||
if (Key == KEY_SIDE1 && !bKeyHeld && bKeyPressed)
|
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
|
||||||
|
|
||||||
if (gDTMF_InputBox_Index > 0)
|
|
||||||
{
|
|
||||||
gDTMF_InputBox[--gDTMF_InputBox_Index] = '-';
|
|
||||||
if (gDTMF_InputBox_Index > 0)
|
|
||||||
{
|
|
||||||
gPttWasReleased = true;
|
|
||||||
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
gAnotherVoiceID = VOICE_ID_CANCEL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
||||||
gDTMF_InputMode = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
gPttWasReleased = true;
|
gPttWasReleased = true;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Key == KEY_SIDE1)
|
if (Key != KEY_SIDE1 || bKeyHeld || !bKeyPressed){
|
||||||
{
|
return;
|
||||||
Short = gEeprom.KEY_1_SHORT_PRESS_ACTION;
|
}
|
||||||
Long = gEeprom.KEY_1_LONG_PRESS_ACTION;
|
|
||||||
}
|
// side1 btn pressed
|
||||||
else
|
|
||||||
if (Key == KEY_SIDE2)
|
|
||||||
{
|
|
||||||
Short = gEeprom.KEY_2_SHORT_PRESS_ACTION;
|
|
||||||
Long = gEeprom.KEY_2_LONG_PRESS_ACTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bKeyHeld && bKeyPressed)
|
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
||||||
|
|
||||||
|
if (gDTMF_InputBox_Index <= 0) {
|
||||||
|
// turn off DTMF input box if no codes left
|
||||||
|
gDTMF_InputMode = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DTMF codes are in the input box
|
||||||
|
gDTMF_InputBox[--gDTMF_InputBox_Index] = '-'; // delete one code
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
gAnotherVoiceID = VOICE_ID_CANCEL;
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bKeyHeld || bKeyPressed)
|
enum ACTION_OPT_t funcShort = ACTION_OPT_NONE;
|
||||||
|
enum ACTION_OPT_t funcLong = ACTION_OPT_NONE;
|
||||||
|
switch(Key) {
|
||||||
|
case KEY_SIDE1:
|
||||||
|
funcShort = gEeprom.KEY_1_SHORT_PRESS_ACTION;
|
||||||
|
funcLong = gEeprom.KEY_1_LONG_PRESS_ACTION;
|
||||||
|
break;
|
||||||
|
case KEY_SIDE2:
|
||||||
|
funcShort = gEeprom.KEY_2_SHORT_PRESS_ACTION;
|
||||||
|
funcLong = gEeprom.KEY_2_LONG_PRESS_ACTION;
|
||||||
|
break;
|
||||||
|
case KEY_MENU:
|
||||||
|
funcLong = gEeprom.KEY_M_LONG_PRESS_ACTION;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bKeyHeld && bKeyPressed) // button pushed
|
||||||
{
|
{
|
||||||
if (!bKeyHeld)
|
return;
|
||||||
return;
|
}
|
||||||
|
|
||||||
Short = Long;
|
// held or released beyond this point
|
||||||
|
|
||||||
if (!bKeyPressed)
|
if(!(bKeyHeld && !bKeyPressed)) // don't beep on released after hold
|
||||||
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
|
|
||||||
|
if (bKeyHeld || bKeyPressed) // held
|
||||||
|
{
|
||||||
|
funcShort = funcLong;
|
||||||
|
|
||||||
|
if (!bKeyPressed) //ignore release if held
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Short)
|
// held or released after short press beyond this point
|
||||||
|
|
||||||
|
action_opt_table[funcShort]();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ENABLE_FMRADIO
|
||||||
|
void ACTION_FM(void)
|
||||||
|
{
|
||||||
|
if (gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_MONITOR)
|
||||||
{
|
{
|
||||||
default:
|
gInputBoxIndex = 0;
|
||||||
case ACTION_OPT_NONE:
|
|
||||||
break;
|
if (gFmRadioMode) {
|
||||||
case ACTION_OPT_FLASHLIGHT:
|
FM_TurnOff();
|
||||||
ACTION_FlashLight();
|
gFlagReconfigureVfos = true;
|
||||||
break;
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
||||||
case ACTION_OPT_POWER:
|
|
||||||
ACTION_Power();
|
#ifdef ENABLE_VOX
|
||||||
break;
|
gVoxResumeCountdown = 80;
|
||||||
case ACTION_OPT_MONITOR:
|
#endif
|
||||||
ACTION_Monitor();
|
return;
|
||||||
break;
|
}
|
||||||
case ACTION_OPT_SCAN:
|
|
||||||
ACTION_Scan(true);
|
gMonitor = false;
|
||||||
break;
|
|
||||||
case ACTION_OPT_VOX:
|
RADIO_SelectVfos();
|
||||||
#ifdef ENABLE_VOX
|
RADIO_SetupRegisters(true);
|
||||||
ACTION_Vox();
|
|
||||||
#endif
|
FM_Start();
|
||||||
break;
|
|
||||||
case ACTION_OPT_ALARM:
|
gRequestDisplayScreen = DISPLAY_FM;
|
||||||
#ifdef ENABLE_ALARM
|
|
||||||
ACTION_AlarmOr1750(false);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
#ifdef ENABLE_FMRADIO
|
|
||||||
case ACTION_OPT_FM:
|
|
||||||
ACTION_FM();
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case ACTION_OPT_1750:
|
|
||||||
#ifdef ENABLE_TX1750
|
|
||||||
ACTION_AlarmOr1750(true);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ACTION_Scan_FM(bool bRestart)
|
||||||
|
{
|
||||||
|
if (FUNCTION_IsRx()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GUI_SelectNextDisplay(DISPLAY_FM);
|
||||||
|
|
||||||
|
gMonitor = false;
|
||||||
|
|
||||||
|
if (gFM_ScanState != FM_SCAN_OFF) {
|
||||||
|
FM_PlayAndUpdate();
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Frequency;
|
||||||
|
|
||||||
|
if (bRestart) {
|
||||||
|
gFM_AutoScan = true;
|
||||||
|
gFM_ChannelPosition = 0;
|
||||||
|
FM_EraseChannels();
|
||||||
|
Frequency = gEeprom.FM_LowerLimit;
|
||||||
|
} else {
|
||||||
|
gFM_AutoScan = false;
|
||||||
|
gFM_ChannelPosition = 0;
|
||||||
|
Frequency = gEeprom.FM_FrequencyPlaying;
|
||||||
|
}
|
||||||
|
|
||||||
|
BK1080_GetFrequencyDeviation(Frequency);
|
||||||
|
FM_Tune(Frequency, 1, bRestart);
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
|
||||||
|
static void ACTION_AlarmOr1750(const bool b1750)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined(ENABLE_ALARM)
|
||||||
|
const AlarmState_t alarm_mode = (gEeprom.ALARM_MODE == ALARM_MODE_TONE) ? ALARM_STATE_TXALARM : ALARM_STATE_SITE_ALARM;
|
||||||
|
gAlarmRunningCounter = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ENABLE_ALARM) && defined(ENABLE_TX1750)
|
||||||
|
gAlarmState = b1750 ? ALARM_STATE_TX1750 : alarm_mode;
|
||||||
|
#elif defined(ENABLE_ALARM)
|
||||||
|
gAlarmState = alarm_mode;
|
||||||
|
#else
|
||||||
|
gAlarmState = ALARM_STATE_TX1750;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
(void)b1750;
|
||||||
|
gInputBoxIndex = 0;
|
||||||
|
|
||||||
|
gFlagPrepareTX = gAlarmState != ALARM_STATE_OFF;
|
||||||
|
|
||||||
|
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
|
||||||
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOX
|
||||||
|
void ACTION_Vox(void)
|
||||||
|
{
|
||||||
|
gEeprom.VOX_SWITCH = !gEeprom.VOX_SWITCH;
|
||||||
|
gRequestSaveSettings = true;
|
||||||
|
gFlagReconfigureVfos = true;
|
||||||
|
gUpdateStatus = true;
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
gAnotherVoiceID = VOICE_ID_VOX;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_BLMIN_TMP_OFF
|
||||||
|
void ACTION_BlminTmpOff(void)
|
||||||
|
{
|
||||||
|
if(++gEeprom.BACKLIGHT_MIN_STAT == BLMIN_STAT_UNKNOWN) {
|
||||||
|
gEeprom.BACKLIGHT_MIN_STAT = BLMIN_STAT_ON;
|
||||||
|
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MIN);
|
||||||
|
} else {
|
||||||
|
BACKLIGHT_SetBrightness(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
13
app/action.h
13
app/action.h
@@ -19,21 +19,22 @@
|
|||||||
|
|
||||||
#include "driver/keyboard.h"
|
#include "driver/keyboard.h"
|
||||||
|
|
||||||
//static void ACTION_FlashLight(void)
|
|
||||||
void ACTION_Power(void);
|
void ACTION_Power(void);
|
||||||
void ACTION_Monitor(void);
|
void ACTION_Monitor(void);
|
||||||
void ACTION_Scan(bool bFlag);
|
void ACTION_Scan(bool bRestart);
|
||||||
#ifdef ENABLE_VOX
|
#ifdef ENABLE_VOX
|
||||||
void ACTION_Vox(void);
|
void ACTION_Vox(void);
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_ALARM
|
|
||||||
//static void ACTION_AlarmOr1750(bool b1750)
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
void ACTION_FM(void);
|
void ACTION_FM(void);
|
||||||
#endif
|
#endif
|
||||||
|
void ACTION_SwitchDemodul(void);
|
||||||
|
|
||||||
|
#ifdef ENABLE_BLMIN_TMP_OFF
|
||||||
|
void ACTION_BlminTmpOff(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
|
void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
298
app/aircopy.c
298
app/aircopy.c
@@ -28,18 +28,26 @@
|
|||||||
#include "ui/inputbox.h"
|
#include "ui/inputbox.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
|
||||||
static const uint16_t Obfuscation[8] = {0x6C16, 0xE614, 0x912E, 0x400D, 0x3521, 0x40D5, 0x0313, 0x80E9};
|
static const uint16_t Obfuscation[8] = { 0x6C16, 0xE614, 0x912E, 0x400D, 0x3521, 0x40D5, 0x0313, 0x80E9 };
|
||||||
|
|
||||||
AIRCOPY_State_t gAircopyState;
|
AIRCOPY_State_t gAircopyState;
|
||||||
uint16_t gAirCopyBlockNumber;
|
uint16_t gAirCopyBlockNumber;
|
||||||
uint16_t gErrorsDuringAirCopy;
|
uint16_t gErrorsDuringAirCopy;
|
||||||
uint8_t gAirCopyIsSendMode;
|
uint8_t gAirCopyIsSendMode;
|
||||||
|
|
||||||
uint16_t g_FSK_Buffer[36];
|
uint16_t g_FSK_Buffer[36];
|
||||||
|
|
||||||
void AIRCOPY_SendMessage(void)
|
bool AIRCOPY_SendMessage(void)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
static uint8_t gAircopySendCountdown = 1;
|
||||||
|
|
||||||
|
if (gAircopyState != AIRCOPY_TRANSFER) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (--gAircopySendCountdown) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
g_FSK_Buffer[1] = (gAirCopyBlockNumber & 0x3FF) << 6;
|
g_FSK_Buffer[1] = (gAirCopyBlockNumber & 0x3FF) << 6;
|
||||||
|
|
||||||
@@ -47,185 +55,187 @@ void AIRCOPY_SendMessage(void)
|
|||||||
|
|
||||||
g_FSK_Buffer[34] = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64);
|
g_FSK_Buffer[34] = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64);
|
||||||
|
|
||||||
for (i = 0; i < 34; i++)
|
for (unsigned int i = 0; i < 34; i++) {
|
||||||
g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8];
|
g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8];
|
||||||
|
}
|
||||||
|
|
||||||
if (++gAirCopyBlockNumber >= 0x78)
|
if (++gAirCopyBlockNumber >= 0x78) {
|
||||||
gAircopyState = AIRCOPY_COMPLETE;
|
gAircopyState = AIRCOPY_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
RADIO_SetTxParameters();
|
RADIO_SetTxParameters();
|
||||||
|
|
||||||
BK4819_SendFSKData(g_FSK_Buffer);
|
BK4819_SendFSKData(g_FSK_Buffer);
|
||||||
BK4819_SetupPowerAmplifier(0, 0);
|
BK4819_SetupPowerAmplifier(0, 0);
|
||||||
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, false);
|
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
|
||||||
|
|
||||||
gAircopySendCountdown = 30;
|
gAircopySendCountdown = 30;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIRCOPY_StorePacket(void)
|
void AIRCOPY_StorePacket(void)
|
||||||
{
|
{
|
||||||
uint16_t Status;
|
if (gFSKWriteIndex < 36) {
|
||||||
|
|
||||||
if (gFSKWriteIndex < 36)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gFSKWriteIndex = 0;
|
gFSKWriteIndex = 0;
|
||||||
gUpdateDisplay = true;
|
gUpdateDisplay = true;
|
||||||
Status = BK4819_ReadRegister(BK4819_REG_0B);
|
uint16_t Status = BK4819_ReadRegister(BK4819_REG_0B);
|
||||||
BK4819_PrepareFSKReceive();
|
BK4819_PrepareFSKReceive();
|
||||||
|
|
||||||
// Doc says bit 4 should be 1 = CRC OK, 0 = CRC FAIL, but original firmware checks for FAIL.
|
// Doc says bit 4 should be 1 = CRC OK, 0 = CRC FAIL, but original firmware checks for FAIL.
|
||||||
|
|
||||||
if ((Status & 0x0010U) == 0 && g_FSK_Buffer[0] == 0xABCD && g_FSK_Buffer[35] == 0xDCBA)
|
if ((Status & 0x0010U) != 0 || g_FSK_Buffer[0] != 0xABCD || g_FSK_Buffer[35] != 0xDCBA) {
|
||||||
{
|
gErrorsDuringAirCopy++;
|
||||||
uint16_t CRC;
|
return;
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 34; i++)
|
|
||||||
g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8];
|
|
||||||
|
|
||||||
CRC = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64);
|
|
||||||
if (g_FSK_Buffer[34] == CRC)
|
|
||||||
{
|
|
||||||
const uint16_t *pData;
|
|
||||||
uint16_t Offset;
|
|
||||||
|
|
||||||
Offset = g_FSK_Buffer[1];
|
|
||||||
if (Offset < 0x1E00)
|
|
||||||
{
|
|
||||||
pData = &g_FSK_Buffer[2];
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
EEPROM_WriteBuffer(Offset, pData);
|
|
||||||
pData += 4;
|
|
||||||
Offset += 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Offset == 0x1E00)
|
|
||||||
gAircopyState = AIRCOPY_COMPLETE;
|
|
||||||
|
|
||||||
gAirCopyBlockNumber++;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
gErrorsDuringAirCopy++;
|
|
||||||
|
for (unsigned int i = 0; i < 34; i++) {
|
||||||
|
g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t CRC = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64);
|
||||||
|
if (g_FSK_Buffer[34] != CRC) {
|
||||||
|
gErrorsDuringAirCopy++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Offset = g_FSK_Buffer[1];
|
||||||
|
|
||||||
|
if (Offset >= 0x1E00) {
|
||||||
|
gErrorsDuringAirCopy++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint16_t *pData = &g_FSK_Buffer[2];
|
||||||
|
for (unsigned int i = 0; i < 8; i++) {
|
||||||
|
EEPROM_WriteBuffer(Offset, pData);
|
||||||
|
pData += 4;
|
||||||
|
Offset += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Offset == 0x1E00) {
|
||||||
|
gAircopyState = AIRCOPY_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gAirCopyBlockNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
||||||
{
|
{
|
||||||
if (!bKeyHeld && bKeyPressed)
|
if (bKeyHeld || !bKeyPressed) {
|
||||||
{
|
return;
|
||||||
uint32_t Frequency;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
INPUTBOX_Append(Key);
|
|
||||||
gRequestDisplayScreen = DISPLAY_AIRCOPY;
|
|
||||||
if (gInputBoxIndex < 6)
|
|
||||||
{
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
gAnotherVoiceID = (VOICE_ID_t)Key;
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gInputBoxIndex = 0;
|
|
||||||
|
|
||||||
NUMBER_Get(gInputBox, &Frequency);
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(frequencyBandTable); i++)
|
|
||||||
{
|
|
||||||
if (Frequency >= frequencyBandTable[i].lower && Frequency < frequencyBandTable[i].upper)
|
|
||||||
{
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
gAnotherVoiceID = (VOICE_ID_t)Key;
|
|
||||||
#endif
|
|
||||||
gRxVfo->Band = i;
|
|
||||||
Frequency += 75;
|
|
||||||
Frequency = FREQUENCY_FloorToStep(Frequency, gRxVfo->StepFrequency, 0);
|
|
||||||
gRxVfo->freq_config_RX.Frequency = Frequency;
|
|
||||||
gRxVfo->freq_config_TX.Frequency = Frequency;
|
|
||||||
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
|
|
||||||
gCurrentVfo = gRxVfo;
|
|
||||||
RADIO_SetupRegisters(true);
|
|
||||||
BK4819_SetupAircopy();
|
|
||||||
BK4819_ResetFSK();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gRequestDisplayScreen = DISPLAY_AIRCOPY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INPUTBOX_Append(Key);
|
||||||
|
|
||||||
|
gRequestDisplayScreen = DISPLAY_AIRCOPY;
|
||||||
|
|
||||||
|
if (gInputBoxIndex < 6) {
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gInputBoxIndex = 0;
|
||||||
|
uint32_t Frequency = StrToUL(INPUTBOX_GetAscii()) * 100;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < BAND_N_ELEM; i++) {
|
||||||
|
if (Frequency < frequencyBandTable[i].lower || Frequency >= frequencyBandTable[i].upper) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TX_freq_check(Frequency)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Frequency = FREQUENCY_RoundToStep(Frequency, gRxVfo->StepFrequency);
|
||||||
|
gRxVfo->Band = i;
|
||||||
|
gRxVfo->freq_config_RX.Frequency = Frequency;
|
||||||
|
gRxVfo->freq_config_TX.Frequency = Frequency;
|
||||||
|
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
|
||||||
|
gCurrentVfo = gRxVfo;
|
||||||
|
RADIO_SetupRegisters(true);
|
||||||
|
BK4819_SetupAircopy();
|
||||||
|
BK4819_ResetFSK();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gRequestDisplayScreen = DISPLAY_AIRCOPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AIRCOPY_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
|
static void AIRCOPY_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
|
||||||
{
|
{
|
||||||
if (!bKeyHeld && bKeyPressed)
|
if (bKeyHeld || !bKeyPressed) {
|
||||||
{
|
return;
|
||||||
if (gInputBoxIndex == 0)
|
|
||||||
{
|
|
||||||
gFSKWriteIndex = 0;
|
|
||||||
gAirCopyBlockNumber = 0;
|
|
||||||
gErrorsDuringAirCopy = 0;
|
|
||||||
gInputBoxIndex = 0;
|
|
||||||
gAirCopyIsSendMode = 0;
|
|
||||||
|
|
||||||
BK4819_PrepareFSKReceive();
|
|
||||||
|
|
||||||
gAircopyState = AIRCOPY_TRANSFER;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
gInputBox[--gInputBoxIndex] = 10;
|
|
||||||
|
|
||||||
gRequestDisplayScreen = DISPLAY_AIRCOPY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gInputBoxIndex == 0) {
|
||||||
|
gFSKWriteIndex = 0;
|
||||||
|
gAirCopyBlockNumber = 0;
|
||||||
|
gInputBoxIndex = 0;
|
||||||
|
gErrorsDuringAirCopy = 0;
|
||||||
|
gAirCopyIsSendMode = 0;
|
||||||
|
|
||||||
|
BK4819_PrepareFSKReceive();
|
||||||
|
|
||||||
|
gAircopyState = AIRCOPY_TRANSFER;
|
||||||
|
} else {
|
||||||
|
gInputBox[--gInputBoxIndex] = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
gRequestDisplayScreen = DISPLAY_AIRCOPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AIRCOPY_Key_MENU(bool bKeyPressed, bool bKeyHeld)
|
static void AIRCOPY_Key_MENU(bool bKeyPressed, bool bKeyHeld)
|
||||||
{
|
{
|
||||||
if (!bKeyHeld && bKeyPressed)
|
if (bKeyHeld || !bKeyPressed) {
|
||||||
{
|
return;
|
||||||
gFSKWriteIndex = 0;
|
|
||||||
gAirCopyBlockNumber = 0;
|
|
||||||
gInputBoxIndex = 0;
|
|
||||||
gAirCopyIsSendMode = 1;
|
|
||||||
g_FSK_Buffer[0] = 0xABCD;
|
|
||||||
g_FSK_Buffer[1] = 0;
|
|
||||||
g_FSK_Buffer[35] = 0xDCBA;
|
|
||||||
|
|
||||||
AIRCOPY_SendMessage();
|
|
||||||
|
|
||||||
GUI_DisplayScreen();
|
|
||||||
|
|
||||||
gAircopyState = AIRCOPY_TRANSFER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gFSKWriteIndex = 0;
|
||||||
|
gAirCopyBlockNumber = 0;
|
||||||
|
gInputBoxIndex = 0;
|
||||||
|
gAirCopyIsSendMode = 1;
|
||||||
|
g_FSK_Buffer[0] = 0xABCD;
|
||||||
|
g_FSK_Buffer[1] = 0;
|
||||||
|
g_FSK_Buffer[35] = 0xDCBA;
|
||||||
|
|
||||||
|
GUI_DisplayScreen();
|
||||||
|
|
||||||
|
gAircopyState = AIRCOPY_TRANSFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
||||||
{
|
{
|
||||||
switch (Key)
|
switch (Key) {
|
||||||
{
|
case KEY_0:
|
||||||
case KEY_0:
|
case KEY_1:
|
||||||
case KEY_1:
|
case KEY_2:
|
||||||
case KEY_2:
|
case KEY_3:
|
||||||
case KEY_3:
|
case KEY_4:
|
||||||
case KEY_4:
|
case KEY_5:
|
||||||
case KEY_5:
|
case KEY_6:
|
||||||
case KEY_6:
|
case KEY_7:
|
||||||
case KEY_7:
|
case KEY_8:
|
||||||
case KEY_8:
|
case KEY_9:
|
||||||
case KEY_9:
|
AIRCOPY_Key_DIGITS(Key, bKeyPressed, bKeyHeld);
|
||||||
AIRCOPY_Key_DIGITS(Key, bKeyPressed, bKeyHeld);
|
break;
|
||||||
break;
|
case KEY_MENU:
|
||||||
case KEY_MENU:
|
AIRCOPY_Key_MENU(bKeyPressed, bKeyHeld);
|
||||||
AIRCOPY_Key_MENU(bKeyPressed, bKeyHeld);
|
break;
|
||||||
break;
|
case KEY_EXIT:
|
||||||
case KEY_EXIT:
|
AIRCOPY_Key_EXIT(bKeyPressed, bKeyHeld);
|
||||||
AIRCOPY_Key_EXIT(bKeyPressed, bKeyHeld);
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,11 +37,10 @@ extern uint8_t gAirCopyIsSendMode;
|
|||||||
|
|
||||||
extern uint16_t g_FSK_Buffer[36];
|
extern uint16_t g_FSK_Buffer[36];
|
||||||
|
|
||||||
void AIRCOPY_SendMessage(void);
|
bool AIRCOPY_SendMessage(void);
|
||||||
void AIRCOPY_StorePacket(void);
|
void AIRCOPY_StorePacket(void);
|
||||||
void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
|
void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
11
app/app.h
11
app/app.h
@@ -23,15 +23,10 @@
|
|||||||
#include "frequencies.h"
|
#include "frequencies.h"
|
||||||
#include "radio.h"
|
#include "radio.h"
|
||||||
|
|
||||||
extern const uint8_t orig_lna_short;
|
|
||||||
extern const uint8_t orig_lna;
|
|
||||||
extern const uint8_t orig_mixer;
|
|
||||||
extern const uint8_t orig_pga;
|
|
||||||
|
|
||||||
void APP_EndTransmission(void);
|
void APP_EndTransmission(void);
|
||||||
void CHANNEL_Next(const bool bFlag, const int8_t scan_direction);
|
void APP_StartListening(FUNCTION_Type_t function);
|
||||||
void APP_StartListening(FUNCTION_Type_t Function, const bool reset_am_fix);
|
uint32_t APP_SetFreqByStepAndLimits(VFO_Info_t *pInfo, int8_t direction, uint32_t lower, uint32_t upper);
|
||||||
uint32_t APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t Step);
|
uint32_t APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t direction);
|
||||||
void APP_Update(void);
|
void APP_Update(void);
|
||||||
void APP_TimeSlice10ms(void);
|
void APP_TimeSlice10ms(void);
|
||||||
void APP_TimeSlice500ms(void);
|
void APP_TimeSlice500ms(void);
|
||||||
|
|||||||
273
app/chFrScanner.c
Normal file
273
app/chFrScanner.c
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
|
||||||
|
#include "app/app.h"
|
||||||
|
#include "app/chFrScanner.h"
|
||||||
|
#include "functions.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
int8_t gScanStateDir;
|
||||||
|
bool gScanKeepResult;
|
||||||
|
bool gScanPauseMode;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
uint32_t gScanRangeStart;
|
||||||
|
uint32_t gScanRangeStop;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SCAN_NEXT_CHAN_SCANLIST1 = 0,
|
||||||
|
SCAN_NEXT_CHAN_SCANLIST2,
|
||||||
|
SCAN_NEXT_CHAN_DUAL_WATCH,
|
||||||
|
SCAN_NEXT_CHAN_MR,
|
||||||
|
SCAN_NEXT_NUM
|
||||||
|
} scan_next_chan_t;
|
||||||
|
|
||||||
|
scan_next_chan_t currentScanList;
|
||||||
|
uint32_t initialFrqOrChan;
|
||||||
|
uint8_t initialCROSS_BAND_RX_TX;
|
||||||
|
uint32_t lastFoundFrqOrChan;
|
||||||
|
|
||||||
|
static void NextFreqChannel(void);
|
||||||
|
static void NextMemChannel(void);
|
||||||
|
|
||||||
|
void CHFRSCANNER_Start(const bool storeBackupSettings, const int8_t scan_direction)
|
||||||
|
{
|
||||||
|
if (storeBackupSettings) {
|
||||||
|
initialCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
|
||||||
|
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
|
||||||
|
gScanKeepResult = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RADIO_SelectVfos();
|
||||||
|
|
||||||
|
gNextMrChannel = gRxVfo->CHANNEL_SAVE;
|
||||||
|
currentScanList = SCAN_NEXT_CHAN_SCANLIST1;
|
||||||
|
gScanStateDir = scan_direction;
|
||||||
|
|
||||||
|
if (IS_MR_CHANNEL(gNextMrChannel))
|
||||||
|
{ // channel mode
|
||||||
|
if (storeBackupSettings) {
|
||||||
|
initialFrqOrChan = gRxVfo->CHANNEL_SAVE;
|
||||||
|
lastFoundFrqOrChan = initialFrqOrChan;
|
||||||
|
}
|
||||||
|
NextMemChannel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // frequency mode
|
||||||
|
if (storeBackupSettings) {
|
||||||
|
initialFrqOrChan = gRxVfo->freq_config_RX.Frequency;
|
||||||
|
lastFoundFrqOrChan = initialFrqOrChan;
|
||||||
|
}
|
||||||
|
NextFreqChannel();
|
||||||
|
}
|
||||||
|
|
||||||
|
gScanPauseDelayIn_10ms = scan_pause_delay_in_2_10ms;
|
||||||
|
gScheduleScanListen = false;
|
||||||
|
gRxReceptionMode = RX_MODE_NONE;
|
||||||
|
gScanPauseMode = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHFRSCANNER_ContinueScanning(void)
|
||||||
|
{
|
||||||
|
if (IS_FREQ_CHANNEL(gNextMrChannel))
|
||||||
|
{
|
||||||
|
if (gCurrentFunction == FUNCTION_INCOMING)
|
||||||
|
APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE);
|
||||||
|
else
|
||||||
|
NextFreqChannel(); // switch to next frequency
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (gCurrentCodeType == CODE_TYPE_OFF && gCurrentFunction == FUNCTION_INCOMING)
|
||||||
|
APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE);
|
||||||
|
else
|
||||||
|
NextMemChannel(); // switch to next channel
|
||||||
|
}
|
||||||
|
|
||||||
|
gScanPauseMode = false;
|
||||||
|
gRxReceptionMode = RX_MODE_NONE;
|
||||||
|
gScheduleScanListen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHFRSCANNER_Found(void)
|
||||||
|
{
|
||||||
|
switch (gEeprom.SCAN_RESUME_MODE)
|
||||||
|
{
|
||||||
|
case SCAN_RESUME_TO:
|
||||||
|
if (!gScanPauseMode)
|
||||||
|
{
|
||||||
|
gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms;
|
||||||
|
gScheduleScanListen = false;
|
||||||
|
gScanPauseMode = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCAN_RESUME_CO:
|
||||||
|
case SCAN_RESUME_SE:
|
||||||
|
gScanPauseDelayIn_10ms = 0;
|
||||||
|
gScheduleScanListen = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_MR_CHANNEL(gRxVfo->CHANNEL_SAVE)) { //memory scan
|
||||||
|
lastFoundFrqOrChan = gRxVfo->CHANNEL_SAVE;
|
||||||
|
}
|
||||||
|
else { // frequency scan
|
||||||
|
lastFoundFrqOrChan = gRxVfo->freq_config_RX.Frequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gScanKeepResult = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHFRSCANNER_Stop(void)
|
||||||
|
{
|
||||||
|
if(initialCROSS_BAND_RX_TX != CROSS_BAND_OFF) {
|
||||||
|
gEeprom.CROSS_BAND_RX_TX = initialCROSS_BAND_RX_TX;
|
||||||
|
initialCROSS_BAND_RX_TX = CROSS_BAND_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
gScanStateDir = SCAN_OFF;
|
||||||
|
|
||||||
|
const uint32_t chFr = gScanKeepResult ? lastFoundFrqOrChan : initialFrqOrChan;
|
||||||
|
const bool channelChanged = chFr != initialFrqOrChan;
|
||||||
|
if (IS_MR_CHANNEL(gNextMrChannel)) {
|
||||||
|
gEeprom.MrChannel[gEeprom.RX_VFO] = chFr;
|
||||||
|
gEeprom.ScreenChannel[gEeprom.RX_VFO] = chFr;
|
||||||
|
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
|
||||||
|
|
||||||
|
if(channelChanged) {
|
||||||
|
SETTINGS_SaveVfoIndices();
|
||||||
|
gUpdateStatus = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gRxVfo->freq_config_RX.Frequency = chFr;
|
||||||
|
RADIO_ApplyOffset(gRxVfo);
|
||||||
|
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
|
||||||
|
if(channelChanged) {
|
||||||
|
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_VFO, gRxVfo, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RADIO_SetupRegisters(true);
|
||||||
|
gUpdateDisplay = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NextFreqChannel(void)
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
if(gScanRangeStart) {
|
||||||
|
gRxVfo->freq_config_RX.Frequency = APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, gScanRangeStart, gScanRangeStop);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
gRxVfo->freq_config_RX.Frequency = APP_SetFrequencyByStep(gRxVfo, gScanStateDir);
|
||||||
|
|
||||||
|
RADIO_ApplyOffset(gRxVfo);
|
||||||
|
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
|
||||||
|
RADIO_SetupRegisters(true);
|
||||||
|
|
||||||
|
#ifdef ENABLE_FASTER_CHANNEL_SCAN
|
||||||
|
gScanPauseDelayIn_10ms = 9; // 90ms
|
||||||
|
#else
|
||||||
|
gScanPauseDelayIn_10ms = scan_pause_delay_in_6_10ms;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gUpdateDisplay = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NextMemChannel(void)
|
||||||
|
{
|
||||||
|
static unsigned int prev_mr_chan = 0;
|
||||||
|
const bool enabled = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCAN_LIST_ENABLED[gEeprom.SCAN_LIST_DEFAULT] : true;
|
||||||
|
const int chan1 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH1[gEeprom.SCAN_LIST_DEFAULT] : -1;
|
||||||
|
const int chan2 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH2[gEeprom.SCAN_LIST_DEFAULT] : -1;
|
||||||
|
const unsigned int prev_chan = gNextMrChannel;
|
||||||
|
unsigned int chan = 0;
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
{
|
||||||
|
switch (currentScanList)
|
||||||
|
{
|
||||||
|
case SCAN_NEXT_CHAN_SCANLIST1:
|
||||||
|
prev_mr_chan = gNextMrChannel;
|
||||||
|
|
||||||
|
if (chan1 >= 0)
|
||||||
|
{
|
||||||
|
if (RADIO_CheckValidChannel(chan1, false, 0))
|
||||||
|
{
|
||||||
|
currentScanList = SCAN_NEXT_CHAN_SCANLIST1;
|
||||||
|
gNextMrChannel = chan1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[[fallthrough]];
|
||||||
|
case SCAN_NEXT_CHAN_SCANLIST2:
|
||||||
|
if (chan2 >= 0)
|
||||||
|
{
|
||||||
|
if (RADIO_CheckValidChannel(chan2, false, 0))
|
||||||
|
{
|
||||||
|
currentScanList = SCAN_NEXT_CHAN_SCANLIST2;
|
||||||
|
gNextMrChannel = chan2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[[fallthrough]];
|
||||||
|
|
||||||
|
// this bit doesn't yet work if the other VFO is a frequency
|
||||||
|
case SCAN_NEXT_CHAN_DUAL_WATCH:
|
||||||
|
// dual watch is enabled - include the other VFO in the scan
|
||||||
|
// if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
|
||||||
|
// {
|
||||||
|
// chan = (gEeprom.RX_VFO + 1) & 1u;
|
||||||
|
// chan = gEeprom.ScreenChannel[chan];
|
||||||
|
// if (IS_MR_CHANNEL(chan))
|
||||||
|
// {
|
||||||
|
// currentScanList = SCAN_NEXT_CHAN_DUAL_WATCH;
|
||||||
|
// gNextMrChannel = chan;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
default:
|
||||||
|
case SCAN_NEXT_CHAN_MR:
|
||||||
|
currentScanList = SCAN_NEXT_CHAN_MR;
|
||||||
|
gNextMrChannel = prev_mr_chan;
|
||||||
|
chan = 0xff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enabled || chan == 0xff)
|
||||||
|
{
|
||||||
|
chan = RADIO_FindNextChannel(gNextMrChannel + gScanStateDir, gScanStateDir, (gEeprom.SCAN_LIST_DEFAULT < 2) ? true : false, gEeprom.SCAN_LIST_DEFAULT);
|
||||||
|
if (chan == 0xFF)
|
||||||
|
{ // no valid channel found
|
||||||
|
chan = MR_CHANNEL_FIRST;
|
||||||
|
}
|
||||||
|
|
||||||
|
gNextMrChannel = chan;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gNextMrChannel != prev_chan)
|
||||||
|
{
|
||||||
|
gEeprom.MrChannel[ gEeprom.RX_VFO] = gNextMrChannel;
|
||||||
|
gEeprom.ScreenChannel[gEeprom.RX_VFO] = gNextMrChannel;
|
||||||
|
|
||||||
|
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
|
||||||
|
RADIO_SetupRegisters(true);
|
||||||
|
|
||||||
|
gUpdateDisplay = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_FASTER_CHANNEL_SCAN
|
||||||
|
gScanPauseDelayIn_10ms = 9; // 90ms .. <= ~60ms it misses signals (squelch response and/or PLL lock time) ?
|
||||||
|
#else
|
||||||
|
gScanPauseDelayIn_10ms = scan_pause_delay_in_3_10ms;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
if (++currentScanList >= SCAN_NEXT_NUM)
|
||||||
|
currentScanList = SCAN_NEXT_CHAN_SCANLIST1; // back round we go
|
||||||
|
}
|
||||||
23
app/chFrScanner.h
Normal file
23
app/chFrScanner.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef APP_CHFRSCANNER_H
|
||||||
|
#define APP_CHFRSCANNER_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// scan direction, if not equal SCAN_OFF indicates
|
||||||
|
// that we are in a process of scanning channels/frequencies
|
||||||
|
extern int8_t gScanStateDir;
|
||||||
|
extern bool gScanKeepResult;
|
||||||
|
extern bool gScanPauseMode;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
extern uint32_t gScanRangeStart;
|
||||||
|
extern uint32_t gScanRangeStop;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void CHFRSCANNER_Found(void);
|
||||||
|
void CHFRSCANNER_Stop(void);
|
||||||
|
void CHFRSCANNER_Start(const bool storeBackupSettings, const int8_t scan_direction);
|
||||||
|
void CHFRSCANNER_ContinueScanning(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
77
app/common.c
Normal file
77
app/common.c
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#include "app/chFrScanner.h"
|
||||||
|
#include "audio.h"
|
||||||
|
#include "functions.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "ui/ui.h"
|
||||||
|
|
||||||
|
void COMMON_KeypadLockToggle()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (gScreenToDisplay != DISPLAY_MENU &&
|
||||||
|
gCurrentFunction != FUNCTION_TRANSMIT)
|
||||||
|
{ // toggle the keyboad lock
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
gAnotherVoiceID = gEeprom.KEY_LOCK ? VOICE_ID_UNLOCK : VOICE_ID_LOCK;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gEeprom.KEY_LOCK = !gEeprom.KEY_LOCK;
|
||||||
|
|
||||||
|
gRequestSaveSettings = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void COMMON_SwitchVFOs()
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
gScanRangeStart = 0;
|
||||||
|
#endif
|
||||||
|
gEeprom.TX_VFO ^= 1;
|
||||||
|
|
||||||
|
if (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF)
|
||||||
|
gEeprom.CROSS_BAND_RX_TX = gEeprom.TX_VFO + 1;
|
||||||
|
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
|
||||||
|
gEeprom.DUAL_WATCH = gEeprom.TX_VFO + 1;
|
||||||
|
|
||||||
|
gRequestSaveSettings = 1;
|
||||||
|
gFlagReconfigureVfos = true;
|
||||||
|
gScheduleDualWatch = true;
|
||||||
|
|
||||||
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void COMMON_SwitchVFOMode()
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_NOAA
|
||||||
|
if (gEeprom.VFO_OPEN && !IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
||||||
|
#else
|
||||||
|
if (gEeprom.VFO_OPEN)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
||||||
|
{ // swap to frequency mode
|
||||||
|
gEeprom.ScreenChannel[gEeprom.TX_VFO] = gEeprom.FreqChannel[gEeprom.TX_VFO];
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
|
||||||
|
#endif
|
||||||
|
gRequestSaveVFO = true;
|
||||||
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 0);
|
||||||
|
if (Channel != 0xFF)
|
||||||
|
{ // swap to channel mode
|
||||||
|
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel;
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
|
||||||
|
AUDIO_SetDigitVoice(1, Channel + 1);
|
||||||
|
gAnotherVoiceID = (VOICE_ID_t)0xFE;
|
||||||
|
#endif
|
||||||
|
gRequestSaveVFO = true;
|
||||||
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
app/common.h
Normal file
13
app/common.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
#ifndef APP_COMMON_H
|
||||||
|
#define APP_COMMON_H
|
||||||
|
|
||||||
|
#include "functions.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "ui/ui.h"
|
||||||
|
|
||||||
|
void COMMON_KeypadLockToggle();
|
||||||
|
void COMMON_SwitchVFOs();
|
||||||
|
void COMMON_SwitchVFOMode();
|
||||||
|
|
||||||
|
#endif
|
||||||
83
app/dtmf.c
83
app/dtmf.c
@@ -17,6 +17,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h> // NULL
|
#include <stdio.h> // NULL
|
||||||
|
|
||||||
|
#include "app/chFrScanner.h"
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
#include "app/fm.h"
|
#include "app/fm.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -40,14 +41,15 @@ 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_live[20];
|
||||||
|
uint8_t gDTMF_RX_live_timeout = 0;
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
char gDTMF_RX[17];
|
char gDTMF_RX[17];
|
||||||
uint8_t gDTMF_RX_index = 0;
|
uint8_t gDTMF_RX_index = 0;
|
||||||
uint8_t gDTMF_RX_timeout = 0;
|
uint8_t gDTMF_RX_timeout = 0;
|
||||||
bool gDTMF_RX_pending = false;
|
bool gDTMF_RX_pending = false;
|
||||||
|
|
||||||
char gDTMF_RX_live[20];
|
|
||||||
uint8_t gDTMF_RX_live_timeout = 0;
|
|
||||||
|
|
||||||
bool gIsDtmfContactValid;
|
bool gIsDtmfContactValid;
|
||||||
char gDTMF_ID[4];
|
char gDTMF_ID[4];
|
||||||
char gDTMF_Caller[4];
|
char gDTMF_Caller[4];
|
||||||
@@ -57,12 +59,16 @@ uint8_t gDTMF_DecodeRingCountdown_500ms;
|
|||||||
uint8_t gDTMF_chosen_contact;
|
uint8_t gDTMF_chosen_contact;
|
||||||
uint8_t gDTMF_auto_reset_time_500ms;
|
uint8_t gDTMF_auto_reset_time_500ms;
|
||||||
DTMF_CallState_t gDTMF_CallState;
|
DTMF_CallState_t gDTMF_CallState;
|
||||||
DTMF_ReplyState_t gDTMF_ReplyState;
|
|
||||||
DTMF_CallMode_t gDTMF_CallMode;
|
DTMF_CallMode_t gDTMF_CallMode;
|
||||||
|
|
||||||
bool gDTMF_IsTx;
|
bool gDTMF_IsTx;
|
||||||
|
|
||||||
uint8_t gDTMF_TxStopCountdown_500ms;
|
uint8_t gDTMF_TxStopCountdown_500ms;
|
||||||
bool gDTMF_IsGroupCall;
|
bool gDTMF_IsGroupCall;
|
||||||
|
#endif
|
||||||
|
DTMF_ReplyState_t gDTMF_ReplyState;
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
void DTMF_clear_RX(void)
|
void DTMF_clear_RX(void)
|
||||||
{
|
{
|
||||||
gDTMF_RX_timeout = 0;
|
gDTMF_RX_timeout = 0;
|
||||||
@@ -70,6 +76,7 @@ void DTMF_clear_RX(void)
|
|||||||
gDTMF_RX_pending = false;
|
gDTMF_RX_pending = false;
|
||||||
memset(gDTMF_RX, 0, sizeof(gDTMF_RX));
|
memset(gDTMF_RX, 0, sizeof(gDTMF_RX));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool DTMF_ValidateCodes(char *pCode, const unsigned int size)
|
bool DTMF_ValidateCodes(char *pCode, const unsigned int size)
|
||||||
{
|
{
|
||||||
@@ -93,6 +100,7 @@ bool DTMF_ValidateCodes(char *pCode, const unsigned int size)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
bool DTMF_GetContact(const int Index, char *pContact)
|
bool DTMF_GetContact(const int Index, char *pContact)
|
||||||
{
|
{
|
||||||
int i = -1;
|
int i = -1;
|
||||||
@@ -101,7 +109,7 @@ bool DTMF_GetContact(const int Index, char *pContact)
|
|||||||
EEPROM_ReadBuffer(0x1C00 + (Index * 16), pContact, 16);
|
EEPROM_ReadBuffer(0x1C00 + (Index * 16), pContact, 16);
|
||||||
i = (int)pContact[0] - ' ';
|
i = (int)pContact[0] - ' ';
|
||||||
}
|
}
|
||||||
return (i < 0 || i >= 95) ? false : true;
|
return (i >= 0 && i < 95);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DTMF_FindContact(const char *pContact, char *pResult)
|
bool DTMF_FindContact(const char *pContact, char *pResult)
|
||||||
@@ -122,7 +130,7 @@ bool DTMF_FindContact(const char *pContact, char *pResult)
|
|||||||
|
|
||||||
if (j == 3)
|
if (j == 3)
|
||||||
{
|
{
|
||||||
memmove(pResult, Contact, 8);
|
memcpy(pResult, Contact, 8);
|
||||||
pResult[8] = 0;
|
pResult[8] = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -131,6 +139,8 @@ bool DTMF_FindContact(const char *pContact, char *pResult)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
char DTMF_GetCharacter(const unsigned int code)
|
char DTMF_GetCharacter(const unsigned int code)
|
||||||
{
|
{
|
||||||
switch (code)
|
switch (code)
|
||||||
@@ -154,8 +164,8 @@ char DTMF_GetCharacter(const unsigned int code)
|
|||||||
default: return 0xff;
|
default: return 0xff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
bool DTMF_CompareMessage(const char *pMsg, const char *pTemplate, const unsigned int size, const bool bCheckGroup)
|
static bool CompareMessage(const char *pMsg, const char *pTemplate, const unsigned int size, const bool bCheckGroup)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
@@ -180,6 +190,7 @@ 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;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void DTMF_clear_input_box(void)
|
void DTMF_clear_input_box(void)
|
||||||
{
|
{
|
||||||
@@ -200,16 +211,17 @@ void DTMF_Append(const char code)
|
|||||||
gDTMF_InputBox[gDTMF_InputBox_Index++] = code;
|
gDTMF_InputBox[gDTMF_InputBox_Index++] = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
void DTMF_HandleRequest(void)
|
void DTMF_HandleRequest(void)
|
||||||
{ // proccess the RX'ed DTMF characters
|
{ // proccess the RX'ed DTMF characters
|
||||||
|
|
||||||
char String[20];
|
char String[21];
|
||||||
unsigned int Offset;
|
unsigned int Offset;
|
||||||
|
|
||||||
if (!gDTMF_RX_pending)
|
if (!gDTMF_RX_pending)
|
||||||
return; // nothing new received
|
return; // nothing new received
|
||||||
|
|
||||||
if (gScanStateDir != SCAN_OFF || gCssScanMode != CSS_SCAN_MODE_OFF)
|
if (gScanStateDir != SCAN_OFF || gCssBackgroundScan)
|
||||||
{ // we're busy scanning
|
{ // we're busy scanning
|
||||||
DTMF_clear_RX();
|
DTMF_clear_RX();
|
||||||
return;
|
return;
|
||||||
@@ -230,7 +242,7 @@ void DTMF_HandleRequest(void)
|
|||||||
|
|
||||||
Offset = gDTMF_RX_index - strlen(String);
|
Offset = gDTMF_RX_index - strlen(String);
|
||||||
|
|
||||||
if (DTMF_CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
|
if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
|
||||||
{ // bugger
|
{ // bugger
|
||||||
|
|
||||||
if (gEeprom.PERMIT_REMOTE_KILL)
|
if (gEeprom.PERMIT_REMOTE_KILL)
|
||||||
@@ -271,7 +283,7 @@ void DTMF_HandleRequest(void)
|
|||||||
|
|
||||||
Offset = gDTMF_RX_index - strlen(String);
|
Offset = gDTMF_RX_index - strlen(String);
|
||||||
|
|
||||||
if (DTMF_CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
|
if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
|
||||||
{ // shit, we're back !
|
{ // shit, we're back !
|
||||||
|
|
||||||
gSetting_KILLED = false;
|
gSetting_KILLED = false;
|
||||||
@@ -296,7 +308,7 @@ void DTMF_HandleRequest(void)
|
|||||||
|
|
||||||
Offset = gDTMF_RX_index - strlen(String);
|
Offset = gDTMF_RX_index - strlen(String);
|
||||||
|
|
||||||
if (DTMF_CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
|
if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
|
||||||
{ // ends with "AB"
|
{ // ends with "AB"
|
||||||
|
|
||||||
if (gDTMF_ReplyState != DTMF_REPLY_NONE) // 1of11
|
if (gDTMF_ReplyState != DTMF_REPLY_NONE) // 1of11
|
||||||
@@ -320,7 +332,7 @@ void DTMF_HandleRequest(void)
|
|||||||
|
|
||||||
Offset = gDTMF_RX_index - strlen(String);
|
Offset = gDTMF_RX_index - strlen(String);
|
||||||
|
|
||||||
if (DTMF_CompareMessage(gDTMF_RX + Offset, String, strlen(String), false))
|
if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), false))
|
||||||
{ // we got a response
|
{ // we got a response
|
||||||
gDTMF_State = DTMF_STATE_CALL_OUT_RSP;
|
gDTMF_State = DTMF_STATE_CALL_OUT_RSP;
|
||||||
DTMF_clear_RX();
|
DTMF_clear_RX();
|
||||||
@@ -342,27 +354,25 @@ void DTMF_HandleRequest(void)
|
|||||||
|
|
||||||
Offset = gDTMF_RX_index - strlen(String) - 3;
|
Offset = gDTMF_RX_index - strlen(String) - 3;
|
||||||
|
|
||||||
if (DTMF_CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
|
if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
|
||||||
{ // it's for us !
|
{ // it's for us !
|
||||||
|
|
||||||
gDTMF_CallState = DTMF_CALL_STATE_RECEIVED;
|
gDTMF_CallState = DTMF_CALL_STATE_RECEIVED;
|
||||||
|
|
||||||
memset(gDTMF_Callee, 0, sizeof(gDTMF_Callee));
|
memset(gDTMF_Callee, 0, sizeof(gDTMF_Callee));
|
||||||
memset(gDTMF_Caller, 0, sizeof(gDTMF_Caller));
|
memset(gDTMF_Caller, 0, sizeof(gDTMF_Caller));
|
||||||
memmove(gDTMF_Callee, gDTMF_RX + Offset + 0, 3);
|
memcpy(gDTMF_Callee, gDTMF_RX + Offset + 0, 3);
|
||||||
memmove(gDTMF_Caller, gDTMF_RX + Offset + 4, 3);
|
memcpy(gDTMF_Caller, gDTMF_RX + Offset + 4, 3);
|
||||||
|
|
||||||
DTMF_clear_RX();
|
DTMF_clear_RX();
|
||||||
|
|
||||||
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:
|
||||||
gDTMF_DecodeRingCountdown_500ms = DTMF_decode_ring_countdown_500ms;
|
gDTMF_DecodeRingCountdown_500ms = DTMF_decode_ring_countdown_500ms;
|
||||||
|
[[fallthrough]];
|
||||||
case DTMF_DEC_RESPONSE_REPLY:
|
case DTMF_DEC_RESPONSE_REPLY:
|
||||||
gDTMF_ReplyState = DTMF_REPLY_AAAAA;
|
gDTMF_ReplyState = DTMF_REPLY_AAAAA;
|
||||||
break;
|
break;
|
||||||
@@ -376,34 +386,38 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void DTMF_Reply(void)
|
void DTMF_Reply(void)
|
||||||
{
|
{
|
||||||
uint16_t Delay;
|
uint16_t Delay;
|
||||||
char String[20];
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
char String[23];
|
||||||
|
#endif
|
||||||
const char *pString = NULL;
|
const char *pString = NULL;
|
||||||
|
|
||||||
switch (gDTMF_ReplyState)
|
switch (gDTMF_ReplyState)
|
||||||
{
|
{
|
||||||
case DTMF_REPLY_ANI:
|
case DTMF_REPLY_ANI:
|
||||||
if (gDTMF_CallMode == DTMF_CALL_MODE_DTMF)
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
{
|
if (gDTMF_CallMode != DTMF_CALL_MODE_DTMF)
|
||||||
pString = gDTMF_String;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // append our ID code onto the end of the DTMF code to send
|
{ // append our ID code onto the end of the DTMF code to send
|
||||||
sprintf(String, "%s%c%s", gDTMF_String, gEeprom.DTMF_SEPARATE_CODE, gEeprom.ANI_DTMF_ID);
|
sprintf(String, "%s%c%s", gDTMF_String, gEeprom.DTMF_SEPARATE_CODE, gEeprom.ANI_DTMF_ID);
|
||||||
pString = String;
|
pString = String;
|
||||||
}
|
}
|
||||||
break;
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
pString = gDTMF_String;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
case DTMF_REPLY_AB:
|
case DTMF_REPLY_AB:
|
||||||
pString = "AB";
|
pString = "AB";
|
||||||
break;
|
break;
|
||||||
@@ -412,10 +426,13 @@ void DTMF_Reply(void)
|
|||||||
sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, "AAAAA");
|
sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, "AAAAA");
|
||||||
pString = String;
|
pString = String;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
case DTMF_REPLY_NONE:
|
case DTMF_REPLY_NONE:
|
||||||
if (gDTMF_CallState != DTMF_CALL_STATE_NONE ||
|
if (
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
gDTMF_CallState != DTMF_CALL_STATE_NONE ||
|
||||||
|
#endif
|
||||||
gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO ||
|
gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO ||
|
||||||
gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_OFF ||
|
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)
|
||||||
@@ -438,7 +455,7 @@ void DTMF_Reply(void)
|
|||||||
|
|
||||||
if (gEeprom.DTMF_SIDE_TONE)
|
if (gEeprom.DTMF_SIDE_TONE)
|
||||||
{ // the user will also hear the transmitted tones
|
{ // the user will also hear the transmitted tones
|
||||||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOn();
|
||||||
gEnableSpeaker = true;
|
gEnableSpeaker = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +471,7 @@ void DTMF_Reply(void)
|
|||||||
gEeprom.DTMF_CODE_PERSIST_TIME,
|
gEeprom.DTMF_CODE_PERSIST_TIME,
|
||||||
gEeprom.DTMF_CODE_INTERVAL_TIME);
|
gEeprom.DTMF_CODE_INTERVAL_TIME);
|
||||||
|
|
||||||
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOff();
|
||||||
|
|
||||||
gEnableSpeaker = false;
|
gEnableSpeaker = false;
|
||||||
|
|
||||||
|
|||||||
25
app/dtmf.h
25
app/dtmf.h
@@ -75,14 +75,15 @@ extern uint8_t gDTMF_InputBox_Index;
|
|||||||
extern bool gDTMF_InputMode;
|
extern bool gDTMF_InputMode;
|
||||||
extern uint8_t gDTMF_PreviousIndex;
|
extern uint8_t gDTMF_PreviousIndex;
|
||||||
|
|
||||||
|
extern char gDTMF_RX_live[20];
|
||||||
|
extern uint8_t gDTMF_RX_live_timeout;
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
extern char gDTMF_RX[17];
|
extern char gDTMF_RX[17];
|
||||||
extern uint8_t gDTMF_RX_index;
|
extern uint8_t gDTMF_RX_index;
|
||||||
extern uint8_t gDTMF_RX_timeout;
|
extern uint8_t gDTMF_RX_timeout;
|
||||||
extern bool gDTMF_RX_pending;
|
extern bool gDTMF_RX_pending;
|
||||||
|
|
||||||
extern char gDTMF_RX_live[20];
|
|
||||||
extern uint8_t gDTMF_RX_live_timeout;
|
|
||||||
|
|
||||||
extern bool gIsDtmfContactValid;
|
extern bool gIsDtmfContactValid;
|
||||||
extern char gDTMF_ID[4];
|
extern char gDTMF_ID[4];
|
||||||
extern char gDTMF_Caller[4];
|
extern char gDTMF_Caller[4];
|
||||||
@@ -92,21 +93,25 @@ extern uint8_t gDTMF_DecodeRingCountdown_500ms;
|
|||||||
extern uint8_t gDTMF_chosen_contact;
|
extern uint8_t gDTMF_chosen_contact;
|
||||||
extern uint8_t gDTMF_auto_reset_time_500ms;
|
extern uint8_t gDTMF_auto_reset_time_500ms;
|
||||||
extern DTMF_CallState_t gDTMF_CallState;
|
extern DTMF_CallState_t gDTMF_CallState;
|
||||||
extern DTMF_ReplyState_t gDTMF_ReplyState;
|
|
||||||
extern DTMF_CallMode_t gDTMF_CallMode;
|
extern DTMF_CallMode_t gDTMF_CallMode;
|
||||||
extern bool gDTMF_IsTx;
|
extern bool gDTMF_IsTx;
|
||||||
extern uint8_t gDTMF_TxStopCountdown_500ms;
|
extern uint8_t gDTMF_TxStopCountdown_500ms;
|
||||||
|
#endif
|
||||||
|
extern DTMF_ReplyState_t gDTMF_ReplyState;
|
||||||
|
|
||||||
void DTMF_clear_RX(void);
|
|
||||||
bool DTMF_ValidateCodes(char *pCode, const unsigned int size);
|
bool DTMF_ValidateCodes(char *pCode, const unsigned int size);
|
||||||
bool DTMF_GetContact(const int Index, char *pContact);
|
|
||||||
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);
|
|
||||||
DTMF_CallMode_t DTMF_CheckGroupCall(const char *pDTMF, const unsigned int size);
|
|
||||||
void DTMF_clear_input_box(void);
|
void DTMF_clear_input_box(void);
|
||||||
void DTMF_Append(const char vode);
|
void DTMF_Append(const char vode);
|
||||||
void DTMF_HandleRequest(void);
|
|
||||||
void DTMF_Reply(void);
|
void DTMF_Reply(void);
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
void DTMF_clear_RX(void);
|
||||||
|
DTMF_CallMode_t DTMF_CheckGroupCall(const char *pDTMF, const unsigned int size);
|
||||||
|
bool DTMF_GetContact(const int Index, char *pContact);
|
||||||
|
bool DTMF_FindContact(const char *pContact, char *pResult);
|
||||||
|
void DTMF_HandleRequest(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
66
app/flashlight.c
Normal file
66
app/flashlight.c
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#ifdef ENABLE_FLASHLIGHT
|
||||||
|
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "bsp/dp32g030/gpio.h"
|
||||||
|
|
||||||
|
#include "flashlight.h"
|
||||||
|
|
||||||
|
enum FlashlightMode_t gFlashLightState;
|
||||||
|
|
||||||
|
void FlashlightTimeSlice()
|
||||||
|
{
|
||||||
|
if (gFlashLightState == FLASHLIGHT_BLINK && (gFlashLightBlinkCounter & 15u) == 0) {
|
||||||
|
GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gFlashLightState == FLASHLIGHT_SOS) {
|
||||||
|
const uint16_t u = 15;
|
||||||
|
static uint8_t c;
|
||||||
|
static uint16_t next;
|
||||||
|
|
||||||
|
if (gFlashLightBlinkCounter - next > 7 * u) {
|
||||||
|
c = 0;
|
||||||
|
next = gFlashLightBlinkCounter + 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gFlashLightBlinkCounter == next) {
|
||||||
|
if (c==0) {
|
||||||
|
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
|
||||||
|
} else {
|
||||||
|
GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c >= 18) {
|
||||||
|
next = gFlashLightBlinkCounter + 7 * u;
|
||||||
|
c = 0;
|
||||||
|
} else if(c==7 || c==9 || c==11) {
|
||||||
|
next = gFlashLightBlinkCounter + 3 * u;
|
||||||
|
} else {
|
||||||
|
next = gFlashLightBlinkCounter + u;
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACTION_FlashLight(void)
|
||||||
|
{
|
||||||
|
switch (gFlashLightState) {
|
||||||
|
case FLASHLIGHT_OFF:
|
||||||
|
gFlashLightState++;
|
||||||
|
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
|
||||||
|
break;
|
||||||
|
case FLASHLIGHT_ON:
|
||||||
|
case FLASHLIGHT_BLINK:
|
||||||
|
gFlashLightState++;
|
||||||
|
break;
|
||||||
|
case FLASHLIGHT_SOS:
|
||||||
|
default:
|
||||||
|
gFlashLightState = 0;
|
||||||
|
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
23
app/flashlight.h
Normal file
23
app/flashlight.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef APP_FLASHLIGHT_H
|
||||||
|
#define APP_FLASHLIGHT_H
|
||||||
|
|
||||||
|
#ifdef ENABLE_FLASHLIGHT
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
enum FlashlightMode_t {
|
||||||
|
FLASHLIGHT_OFF = 0,
|
||||||
|
FLASHLIGHT_ON,
|
||||||
|
FLASHLIGHT_BLINK,
|
||||||
|
FLASHLIGHT_SOS
|
||||||
|
};
|
||||||
|
|
||||||
|
extern enum FlashlightMode_t gFlashLightState;
|
||||||
|
extern volatile uint16_t gFlashLightBlinkCounter;
|
||||||
|
|
||||||
|
void FlashlightTimeSlice(void);
|
||||||
|
void ACTION_FlashLight(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
275
app/fm.c
275
app/fm.c
@@ -45,12 +45,24 @@ bool gFM_AutoScan;
|
|||||||
uint8_t gFM_ChannelPosition;
|
uint8_t gFM_ChannelPosition;
|
||||||
bool gFM_FoundFrequency;
|
bool gFM_FoundFrequency;
|
||||||
bool gFM_AutoScan;
|
bool gFM_AutoScan;
|
||||||
uint8_t gFM_ResumeCountdown_500ms;
|
|
||||||
uint16_t gFM_RestoreCountdown_10ms;
|
uint16_t gFM_RestoreCountdown_10ms;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const uint8_t BUTTON_STATE_PRESSED = 1 << 0;
|
||||||
|
const uint8_t BUTTON_STATE_HELD = 1 << 1;
|
||||||
|
|
||||||
|
const uint8_t BUTTON_EVENT_PRESSED = BUTTON_STATE_PRESSED;
|
||||||
|
const uint8_t BUTTON_EVENT_HELD = BUTTON_STATE_PRESSED | BUTTON_STATE_HELD;
|
||||||
|
const uint8_t BUTTON_EVENT_SHORT = 0;
|
||||||
|
const uint8_t BUTTON_EVENT_LONG = BUTTON_STATE_HELD;
|
||||||
|
|
||||||
|
|
||||||
|
static void Key_FUNC(KEY_Code_t Key, uint8_t state);
|
||||||
|
|
||||||
bool FM_CheckValidChannel(uint8_t Channel)
|
bool FM_CheckValidChannel(uint8_t Channel)
|
||||||
{
|
{
|
||||||
return (Channel < ARRAY_SIZE(gFM_Channels) && (gFM_Channels[Channel] >= 760 && gFM_Channels[Channel] < 1080)) ? true : false;
|
return (Channel < ARRAY_SIZE(gFM_Channels) && (gFM_Channels[Channel] >= 760 && gFM_Channels[Channel] < 1080));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t FM_FindNextChannel(uint8_t Channel, uint8_t Direction)
|
uint8_t FM_FindNextChannel(uint8_t Channel, uint8_t Direction)
|
||||||
@@ -97,7 +109,7 @@ void FM_TurnOff(void)
|
|||||||
gFM_ScanState = FM_SCAN_OFF;
|
gFM_ScanState = FM_SCAN_OFF;
|
||||||
gFM_RestoreCountdown_10ms = 0;
|
gFM_RestoreCountdown_10ms = 0;
|
||||||
|
|
||||||
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOff();
|
||||||
|
|
||||||
gEnableSpeaker = false;
|
gEnableSpeaker = false;
|
||||||
|
|
||||||
@@ -120,7 +132,7 @@ void FM_EraseChannels(void)
|
|||||||
|
|
||||||
void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag)
|
void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag)
|
||||||
{
|
{
|
||||||
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOff();
|
||||||
|
|
||||||
gEnableSpeaker = false;
|
gEnableSpeaker = false;
|
||||||
|
|
||||||
@@ -167,7 +179,7 @@ void FM_PlayAndUpdate(void)
|
|||||||
gScheduleFM = false;
|
gScheduleFM = false;
|
||||||
gAskToSave = false;
|
gAskToSave = false;
|
||||||
|
|
||||||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOn();
|
||||||
|
|
||||||
gEnableSpeaker = true;
|
gEnableSpeaker = true;
|
||||||
}
|
}
|
||||||
@@ -181,42 +193,37 @@ int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit)
|
|||||||
// This is supposed to be a signed value, but above function is unsigned
|
// This is supposed to be a signed value, but above function is unsigned
|
||||||
const uint16_t Deviation = BK1080_REG_07_GET_FREQD(Test2);
|
const uint16_t Deviation = BK1080_REG_07_GET_FREQD(Test2);
|
||||||
|
|
||||||
if (BK1080_REG_07_GET_SNR(Test2) >= 2)
|
if (BK1080_REG_07_GET_SNR(Test2) <= 2){
|
||||||
{
|
goto Bail;
|
||||||
const uint16_t Status = BK1080_ReadRegister(BK1080_REG_10);
|
|
||||||
if ((Status & BK1080_REG_10_MASK_AFCRL) == BK1080_REG_10_AFCRL_NOT_RAILED && BK1080_REG_10_GET_RSSI(Status) >= 10)
|
|
||||||
{
|
|
||||||
//if (Deviation > -281 && Deviation < 280)
|
|
||||||
if (Deviation < 280 || Deviation > 3815)
|
|
||||||
{
|
|
||||||
// not BLE(less than or equal)
|
|
||||||
|
|
||||||
if (Frequency > LowerLimit && (Frequency - BK1080_BaseFrequency) == 1)
|
|
||||||
{
|
|
||||||
if (BK1080_FrequencyDeviation & 0x800)
|
|
||||||
goto Bail;
|
|
||||||
|
|
||||||
if (BK1080_FrequencyDeviation < 20)
|
|
||||||
goto Bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not BLT(less than)
|
|
||||||
|
|
||||||
if (Frequency >= LowerLimit && (BK1080_BaseFrequency - Frequency) == 1)
|
|
||||||
{
|
|
||||||
if ((BK1080_FrequencyDeviation & 0x800) == 0)
|
|
||||||
goto Bail;
|
|
||||||
|
|
||||||
// if (BK1080_FrequencyDeviation > -21)
|
|
||||||
if (BK1080_FrequencyDeviation > 4075)
|
|
||||||
goto Bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint16_t Status = BK1080_ReadRegister(BK1080_REG_10);
|
||||||
|
|
||||||
|
if ((Status & BK1080_REG_10_MASK_AFCRL) != BK1080_REG_10_AFCRL_NOT_RAILED || BK1080_REG_10_GET_RSSI(Status) < 10) {
|
||||||
|
goto Bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (Deviation > -281 && Deviation < 280)
|
||||||
|
if (Deviation >= 280 && Deviation <= 3815) {
|
||||||
|
goto Bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not BLE(less than or equal)
|
||||||
|
if (Frequency > LowerLimit && (Frequency - BK1080_BaseFrequency) == 1) {
|
||||||
|
if (BK1080_FrequencyDeviation & 0x800 || (BK1080_FrequencyDeviation < 20))
|
||||||
|
goto Bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not BLT(less than)
|
||||||
|
|
||||||
|
if (Frequency >= LowerLimit && (BK1080_BaseFrequency - Frequency) == 1) {
|
||||||
|
if ((BK1080_FrequencyDeviation & 0x800) == 0 || (BK1080_FrequencyDeviation > 4075))
|
||||||
|
goto Bail;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
Bail:
|
Bail:
|
||||||
BK1080_FrequencyDeviation = Deviation;
|
BK1080_FrequencyDeviation = Deviation;
|
||||||
BK1080_BaseFrequency = Frequency;
|
BK1080_BaseFrequency = Frequency;
|
||||||
@@ -224,32 +231,23 @@ Bail:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
static void Key_DIGITS(KEY_Code_t Key, uint8_t state)
|
||||||
{
|
{
|
||||||
#define STATE_FREQ_MODE 0
|
enum { STATE_FREQ_MODE, STATE_MR_MODE, STATE_SAVE };
|
||||||
#define STATE_MR_MODE 1
|
|
||||||
#define STATE_SAVE 2
|
|
||||||
|
|
||||||
if (!bKeyHeld && bKeyPressed)
|
if (state == BUTTON_EVENT_SHORT && !gWasFKeyPressed) {
|
||||||
{
|
|
||||||
if (!gWasFKeyPressed)
|
|
||||||
{
|
|
||||||
uint8_t State;
|
uint8_t State;
|
||||||
|
|
||||||
if (gAskToDelete)
|
if (gAskToDelete) {
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gAskToSave)
|
if (gAskToSave) {
|
||||||
{
|
|
||||||
State = STATE_SAVE;
|
State = STATE_SAVE;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
if (gFM_ScanState != FM_SCAN_OFF) {
|
||||||
if (gFM_ScanState != FM_SCAN_OFF)
|
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -261,60 +259,47 @@ static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
|
|
||||||
gRequestDisplayScreen = DISPLAY_FM;
|
gRequestDisplayScreen = DISPLAY_FM;
|
||||||
|
|
||||||
if (State == STATE_FREQ_MODE)
|
if (State == STATE_FREQ_MODE) {
|
||||||
{
|
if (gInputBoxIndex == 1) {
|
||||||
if (gInputBoxIndex == 1)
|
if (gInputBox[0] > 1) {
|
||||||
{
|
|
||||||
if (gInputBox[0] > 1)
|
|
||||||
{
|
|
||||||
gInputBox[1] = gInputBox[0];
|
gInputBox[1] = gInputBox[0];
|
||||||
gInputBox[0] = 0;
|
gInputBox[0] = 0;
|
||||||
gInputBoxIndex = 2;
|
gInputBoxIndex = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (gInputBoxIndex > 3) {
|
||||||
if (gInputBoxIndex > 3)
|
|
||||||
{
|
|
||||||
uint32_t Frequency;
|
uint32_t Frequency;
|
||||||
|
|
||||||
gInputBoxIndex = 0;
|
gInputBoxIndex = 0;
|
||||||
NUMBER_Get(gInputBox, &Frequency);
|
Frequency = StrToUL(INPUTBOX_GetAscii());
|
||||||
Frequency /= 10000;
|
|
||||||
|
|
||||||
if (Frequency < gEeprom.FM_LowerLimit || gEeprom.FM_UpperLimit < Frequency)
|
if (Frequency < gEeprom.FM_LowerLimit || gEeprom.FM_UpperLimit < Frequency) {
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
gRequestDisplayScreen = DISPLAY_FM;
|
gRequestDisplayScreen = DISPLAY_FM;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gEeprom.FM_SelectedFrequency = (uint16_t)Frequency;
|
gEeprom.FM_SelectedFrequency = (uint16_t)Frequency;
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
#ifdef ENABLE_VOICE
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
||||||
gAnotherVoiceID = (VOICE_ID_t)Key;
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency;
|
gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency;
|
||||||
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
|
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
|
||||||
gRequestSaveFM = true;
|
gRequestSaveFM = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (gInputBoxIndex == 2) {
|
||||||
if (gInputBoxIndex == 2)
|
|
||||||
{
|
|
||||||
uint8_t Channel;
|
uint8_t Channel;
|
||||||
|
|
||||||
gInputBoxIndex = 0;
|
gInputBoxIndex = 0;
|
||||||
Channel = ((gInputBox[0] * 10) + gInputBox[1]) - 1;
|
Channel = ((gInputBox[0] * 10) + gInputBox[1]) - 1;
|
||||||
|
|
||||||
if (State == STATE_MR_MODE)
|
if (State == STATE_MR_MODE) {
|
||||||
{
|
if (FM_CheckValidChannel(Channel)) {
|
||||||
if (FM_CheckValidChannel(Channel))
|
#ifdef ENABLE_VOICE
|
||||||
{
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
||||||
#ifdef ENABLE_VOICE
|
#endif
|
||||||
gAnotherVoiceID = (VOICE_ID_t)Key;
|
|
||||||
#endif
|
|
||||||
gEeprom.FM_SelectedChannel = Channel;
|
gEeprom.FM_SelectedChannel = Channel;
|
||||||
gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel];
|
gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel];
|
||||||
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
|
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
|
||||||
@@ -322,12 +307,10 @@ static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (Channel < 20) {
|
||||||
if (Channel < 20)
|
#ifdef ENABLE_VOICE
|
||||||
{
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
||||||
#ifdef ENABLE_VOICE
|
#endif
|
||||||
gAnotherVoiceID = (VOICE_ID_t)Key;
|
|
||||||
#endif
|
|
||||||
gRequestDisplayScreen = DISPLAY_FM;
|
gRequestDisplayScreen = DISPLAY_FM;
|
||||||
gInputBoxIndex = 0;
|
gInputBoxIndex = 0;
|
||||||
gFM_ChannelPosition = Channel;
|
gFM_ChannelPosition = Channel;
|
||||||
@@ -338,25 +321,31 @@ static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
gAnotherVoiceID = (VOICE_ID_t)Key;
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Key_FUNC(Key, state);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
static void Key_FUNC(KEY_Code_t Key, uint8_t state)
|
||||||
}
|
{
|
||||||
|
if (state == BUTTON_EVENT_SHORT || state == BUTTON_EVENT_HELD)
|
||||||
|
{
|
||||||
|
bool autoScan = gWasFKeyPressed || (state == BUTTON_EVENT_HELD);
|
||||||
|
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
gWasFKeyPressed = false;
|
gWasFKeyPressed = false;
|
||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
gRequestDisplayScreen = DISPLAY_FM;
|
gRequestDisplayScreen = DISPLAY_FM;
|
||||||
|
|
||||||
switch (Key)
|
switch (Key) {
|
||||||
{
|
|
||||||
case KEY_0:
|
case KEY_0:
|
||||||
ACTION_FM();
|
ACTION_FM();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_1:
|
case KEY_3:
|
||||||
gEeprom.FM_IsMrMode = !gEeprom.FM_IsMrMode;
|
gEeprom.FM_IsMrMode = !gEeprom.FM_IsMrMode;
|
||||||
|
|
||||||
if (!FM_ConfigureChannelState())
|
if (!FM_ConfigureChannelState())
|
||||||
@@ -368,12 +357,8 @@ static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_2:
|
case KEY_STAR:
|
||||||
ACTION_Scan(true);
|
ACTION_Scan(autoScan);
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_3:
|
|
||||||
ACTION_Scan(false);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -383,12 +368,9 @@ static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FM_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
|
static void Key_EXIT(uint8_t state)
|
||||||
{
|
{
|
||||||
if (bKeyHeld)
|
if (state != BUTTON_EVENT_SHORT)
|
||||||
return;
|
|
||||||
|
|
||||||
if (!bKeyPressed)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
@@ -443,13 +425,11 @@ static void FM_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
|
|||||||
gRequestDisplayScreen = DISPLAY_FM;
|
gRequestDisplayScreen = DISPLAY_FM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FM_Key_MENU(bool bKeyPressed, bool bKeyHeld)
|
static void Key_MENU(uint8_t state)
|
||||||
{
|
{
|
||||||
if (bKeyHeld)
|
if (state != BUTTON_EVENT_SHORT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!bKeyPressed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
gRequestDisplayScreen = DISPLAY_FM;
|
gRequestDisplayScreen = DISPLAY_FM;
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
@@ -461,11 +441,9 @@ static void FM_Key_MENU(bool bKeyPressed, bool bKeyHeld)
|
|||||||
if (gAskToSave)
|
if (gAskToSave)
|
||||||
{
|
{
|
||||||
gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying;
|
gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying;
|
||||||
gAskToSave = false;
|
gRequestSaveFM = true;
|
||||||
gRequestSaveFM = true;
|
|
||||||
}
|
}
|
||||||
else
|
gAskToSave = !gAskToSave;
|
||||||
gAskToSave = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -477,10 +455,9 @@ static void FM_Key_MENU(bool bKeyPressed, bool bKeyHeld)
|
|||||||
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
|
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
|
||||||
|
|
||||||
gRequestSaveFM = true;
|
gRequestSaveFM = true;
|
||||||
gAskToDelete = false;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
gAskToDelete = true;
|
gAskToDelete = !gAskToDelete;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -495,46 +472,33 @@ static void FM_Key_MENU(bool bKeyPressed, bool bKeyHeld)
|
|||||||
if (gAskToSave)
|
if (gAskToSave)
|
||||||
{
|
{
|
||||||
gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying;
|
gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying;
|
||||||
gAskToSave = false;
|
|
||||||
gRequestSaveFM = true;
|
gRequestSaveFM = true;
|
||||||
}
|
}
|
||||||
else
|
gAskToSave = !gAskToSave;
|
||||||
gAskToSave = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FM_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Step)
|
static void Key_UP_DOWN(uint8_t state, int8_t Step)
|
||||||
{
|
{
|
||||||
if (bKeyHeld || !bKeyPressed)
|
if (state == BUTTON_EVENT_PRESSED) {
|
||||||
{
|
if (gInputBoxIndex) {
|
||||||
if (gInputBoxIndex)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!bKeyPressed)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (gInputBoxIndex)
|
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
|
} else if (gInputBoxIndex || state!=BUTTON_EVENT_HELD) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gAskToSave)
|
if (gAskToSave) {
|
||||||
{
|
|
||||||
gRequestDisplayScreen = DISPLAY_FM;
|
gRequestDisplayScreen = DISPLAY_FM;
|
||||||
gFM_ChannelPosition = NUMBER_AddWithWraparound(gFM_ChannelPosition, Step, 0, 19);
|
gFM_ChannelPosition = NUMBER_AddWithWraparound(gFM_ChannelPosition, Step, 0, 19);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gFM_ScanState != FM_SCAN_OFF)
|
if (gFM_ScanState != FM_SCAN_OFF) {
|
||||||
{
|
if (gFM_AutoScan) {
|
||||||
if (gFM_AutoScan)
|
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -544,8 +508,7 @@ static void FM_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Step)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gEeprom.FM_IsMrMode)
|
if (gEeprom.FM_IsMrMode) {
|
||||||
{
|
|
||||||
const uint8_t Channel = FM_FindNextChannel(gEeprom.FM_SelectedChannel + Step, Step);
|
const uint8_t Channel = FM_FindNextChannel(gEeprom.FM_SelectedChannel + Step, Step);
|
||||||
if (Channel == 0xFF || gEeprom.FM_SelectedChannel == Channel)
|
if (Channel == 0xFF || gEeprom.FM_SelectedChannel == Channel)
|
||||||
goto Bail;
|
goto Bail;
|
||||||
@@ -553,9 +516,9 @@ static void FM_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Step)
|
|||||||
gEeprom.FM_SelectedChannel = Channel;
|
gEeprom.FM_SelectedChannel = Channel;
|
||||||
gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel];
|
gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel];
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
uint16_t Frequency = gEeprom.FM_SelectedFrequency + Step;
|
uint16_t Frequency = gEeprom.FM_SelectedFrequency + Step;
|
||||||
|
|
||||||
if (Frequency < gEeprom.FM_LowerLimit)
|
if (Frequency < gEeprom.FM_LowerLimit)
|
||||||
Frequency = gEeprom.FM_UpperLimit;
|
Frequency = gEeprom.FM_UpperLimit;
|
||||||
else
|
else
|
||||||
@@ -576,6 +539,8 @@ Bail:
|
|||||||
|
|
||||||
void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
||||||
{
|
{
|
||||||
|
uint8_t state = bKeyPressed + 2 * bKeyHeld;
|
||||||
|
|
||||||
switch (Key)
|
switch (Key)
|
||||||
{
|
{
|
||||||
case KEY_0:
|
case KEY_0:
|
||||||
@@ -588,19 +553,22 @@ void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
case KEY_7:
|
case KEY_7:
|
||||||
case KEY_8:
|
case KEY_8:
|
||||||
case KEY_9:
|
case KEY_9:
|
||||||
FM_Key_DIGITS(Key, bKeyPressed, bKeyHeld);
|
Key_DIGITS(Key, state);
|
||||||
|
break;
|
||||||
|
case KEY_STAR:
|
||||||
|
Key_FUNC(Key, state);
|
||||||
break;
|
break;
|
||||||
case KEY_MENU:
|
case KEY_MENU:
|
||||||
FM_Key_MENU(bKeyPressed, bKeyHeld);
|
Key_MENU(state);
|
||||||
return;
|
break;
|
||||||
case KEY_UP:
|
case KEY_UP:
|
||||||
FM_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1);
|
Key_UP_DOWN(state, 1);
|
||||||
break;
|
break;
|
||||||
case KEY_DOWN:
|
case KEY_DOWN:
|
||||||
FM_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1);
|
Key_UP_DOWN(state, -1);
|
||||||
break;;
|
break;;
|
||||||
case KEY_EXIT:
|
case KEY_EXIT:
|
||||||
FM_Key_EXIT(bKeyPressed, bKeyHeld);
|
Key_EXIT(state);
|
||||||
break;
|
break;
|
||||||
case KEY_F:
|
case KEY_F:
|
||||||
GENERIC_Key_F(bKeyPressed, bKeyHeld);
|
GENERIC_Key_F(bKeyPressed, bKeyHeld);
|
||||||
@@ -627,7 +595,7 @@ void FM_Play(void)
|
|||||||
if (!gEeprom.FM_IsMrMode)
|
if (!gEeprom.FM_IsMrMode)
|
||||||
gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying;
|
gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying;
|
||||||
|
|
||||||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOn();
|
||||||
gEnableSpeaker = true;
|
gEnableSpeaker = true;
|
||||||
|
|
||||||
GUI_SelectNextDisplay(DISPLAY_FM);
|
GUI_SelectNextDisplay(DISPLAY_FM);
|
||||||
@@ -655,13 +623,14 @@ void FM_Play(void)
|
|||||||
|
|
||||||
void FM_Start(void)
|
void FM_Start(void)
|
||||||
{
|
{
|
||||||
|
gDualWatchActive = false;
|
||||||
gFmRadioMode = true;
|
gFmRadioMode = true;
|
||||||
gFM_ScanState = FM_SCAN_OFF;
|
gFM_ScanState = FM_SCAN_OFF;
|
||||||
gFM_RestoreCountdown_10ms = 0;
|
gFM_RestoreCountdown_10ms = 0;
|
||||||
|
|
||||||
BK1080_Init(gEeprom.FM_FrequencyPlaying, true);
|
BK1080_Init(gEeprom.FM_FrequencyPlaying, true);
|
||||||
|
|
||||||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOn();
|
||||||
|
|
||||||
gEnableSpeaker = true;
|
gEnableSpeaker = true;
|
||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
|
|||||||
3
app/fm.h
3
app/fm.h
@@ -38,8 +38,6 @@ extern uint8_t gFM_ChannelPosition;
|
|||||||
// Doubts about whether this should be signed or not
|
// Doubts about whether this should be signed or not
|
||||||
extern uint16_t gFM_FrequencyDeviation;
|
extern uint16_t gFM_FrequencyDeviation;
|
||||||
extern bool gFM_FoundFrequency;
|
extern bool gFM_FoundFrequency;
|
||||||
extern bool gFM_AutoScan;
|
|
||||||
extern uint8_t gFM_ResumeCountdown_500ms;
|
|
||||||
extern uint16_t gFM_RestoreCountdown_10ms;
|
extern uint16_t gFM_RestoreCountdown_10ms;
|
||||||
|
|
||||||
bool FM_CheckValidChannel(uint8_t Channel);
|
bool FM_CheckValidChannel(uint8_t Channel);
|
||||||
@@ -60,4 +58,3 @@ void FM_Start(void);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
148
app/generic.c
148
app/generic.c
@@ -17,9 +17,13 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
|
#include "app/chFrScanner.h"
|
||||||
|
#include "app/common.h"
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
#include "app/fm.h"
|
#include "app/fm.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "app/generic.h"
|
#include "app/generic.h"
|
||||||
#include "app/menu.h"
|
#include "app/menu.h"
|
||||||
#include "app/scanner.h"
|
#include "app/scanner.h"
|
||||||
@@ -37,39 +41,24 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
|
|||||||
{
|
{
|
||||||
if (gInputBoxIndex > 0)
|
if (gInputBoxIndex > 0)
|
||||||
{
|
{
|
||||||
if (!bKeyHeld && bKeyPressed)
|
if (!bKeyHeld && bKeyPressed) // short pressed
|
||||||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bKeyHeld || !bKeyPressed)
|
if (bKeyHeld || !bKeyPressed) // held or released
|
||||||
{
|
{
|
||||||
if (bKeyHeld || bKeyPressed)
|
if (bKeyHeld || bKeyPressed) // held or pressed (cannot be held and not pressed I guess, so it checks only if HELD?)
|
||||||
{
|
{
|
||||||
if (!bKeyHeld)
|
if (!bKeyHeld) // won't ever pass
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!bKeyPressed)
|
if (!bKeyPressed) // won't ever pass
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (gScreenToDisplay != DISPLAY_MENU &&
|
COMMON_KeypadLockToggle();
|
||||||
gScreenToDisplay != DISPLAY_FM &&
|
|
||||||
#ifdef ENABLE_FMRADIO
|
|
||||||
!gFmRadioMode &&
|
|
||||||
#endif
|
|
||||||
gCurrentFunction != FUNCTION_TRANSMIT)
|
|
||||||
{ // toggle the keyboad lock
|
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
gAnotherVoiceID = gEeprom.KEY_LOCK ? VOICE_ID_UNLOCK : VOICE_ID_LOCK;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gEeprom.KEY_LOCK = !gEeprom.KEY_LOCK;
|
|
||||||
|
|
||||||
gRequestSaveSettings = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else // released
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
if ((gFmRadioMode || gScreenToDisplay != DISPLAY_MAIN) && gScreenToDisplay != DISPLAY_FM)
|
if ((gFmRadioMode || gScreenToDisplay != DISPLAY_MAIN) && gScreenToDisplay != DISPLAY_FM)
|
||||||
@@ -79,7 +68,7 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
|
|||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gWasFKeyPressed = !gWasFKeyPressed;
|
gWasFKeyPressed = !gWasFKeyPressed; // toggle F function
|
||||||
|
|
||||||
if (gWasFKeyPressed)
|
if (gWasFKeyPressed)
|
||||||
gKeyInputCountdown = key_input_timeout_500ms;
|
gKeyInputCountdown = key_input_timeout_500ms;
|
||||||
@@ -92,16 +81,18 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
|
|||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else // short pressed
|
||||||
{
|
{
|
||||||
|
#ifdef ENABLE_FMRADIO
|
||||||
if (gScreenToDisplay != DISPLAY_FM)
|
if (gScreenToDisplay != DISPLAY_FM)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
if (gFM_ScanState == FM_SCAN_OFF)
|
if (gFM_ScanState == FM_SCAN_OFF) // not scanning
|
||||||
{
|
{
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
return;
|
return;
|
||||||
@@ -118,9 +109,8 @@ void GENERIC_Key_PTT(bool bKeyPressed)
|
|||||||
{
|
{
|
||||||
gInputBoxIndex = 0;
|
gInputBoxIndex = 0;
|
||||||
|
|
||||||
if (!bKeyPressed || gSerialConfigCountDown_500ms > 0)
|
if (!bKeyPressed || SerialConfigInProgress())
|
||||||
{ // PTT released
|
{ // PTT released
|
||||||
|
|
||||||
if (gCurrentFunction == FUNCTION_TRANSMIT)
|
if (gCurrentFunction == FUNCTION_TRANSMIT)
|
||||||
{ // we are transmitting .. stop
|
{ // we are transmitting .. stop
|
||||||
|
|
||||||
@@ -155,52 +145,37 @@ void GENERIC_Key_PTT(bool bKeyPressed)
|
|||||||
|
|
||||||
// PTT pressed
|
// PTT pressed
|
||||||
|
|
||||||
if (gScanStateDir != SCAN_OFF || // frequency/channel scanning
|
|
||||||
gScreenToDisplay == DISPLAY_SCANNER || // CTCSS/CDCSS scanning
|
|
||||||
gCssScanMode != CSS_SCAN_MODE_OFF) // " "
|
|
||||||
{ // we're scanning .. stop
|
|
||||||
|
|
||||||
if (gScreenToDisplay == DISPLAY_SCANNER)
|
|
||||||
{ // CTCSS/CDCSS scanning .. stop
|
|
||||||
gEeprom.CROSS_BAND_RX_TX = gBackup_CROSS_BAND_RX_TX;
|
|
||||||
gFlagStopScan = true;
|
|
||||||
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
|
||||||
gFlagResetVfos = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (gScanStateDir != SCAN_OFF)
|
|
||||||
{ // frequency/channel scanning . .stop
|
|
||||||
SCANNER_Stop();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (gCssScanMode != CSS_SCAN_MODE_OFF)
|
|
||||||
{ // CTCSS/CDCSS scanning .. stop
|
|
||||||
MENU_StopCssScan();
|
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (SCANNER_IsScanning())
|
||||||
|
{ // CTCSS/CDCSS scanning .. stop
|
||||||
|
SCANNER_Stop();
|
||||||
goto cancel_tx;
|
goto cancel_tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
if (gScanStateDir != SCAN_OFF)
|
||||||
if (gFM_ScanState != FM_SCAN_OFF)
|
{ // frequency/channel scanning . .stop
|
||||||
{ // FM radio is scanning .. stop
|
CHFRSCANNER_Stop();
|
||||||
FM_PlayAndUpdate();
|
goto cancel_tx;
|
||||||
#ifdef ENABLE_VOICE
|
}
|
||||||
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
|
|
||||||
#endif
|
|
||||||
gRequestDisplayScreen = DISPLAY_FM;
|
|
||||||
goto cancel_tx;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
|
||||||
if (gScreenToDisplay == DISPLAY_FM)
|
|
||||||
goto start_tx; // listening to the FM radio .. start TX'ing
|
#ifdef ENABLE_FMRADIO
|
||||||
#endif
|
if (gFM_ScanState != FM_SCAN_OFF)
|
||||||
|
{ // FM radio is scanning .. stop
|
||||||
|
FM_PlayAndUpdate();
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
|
||||||
|
#endif
|
||||||
|
gRequestDisplayScreen = DISPLAY_FM;
|
||||||
|
goto cancel_tx;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_FMRADIO
|
||||||
|
if (gScreenToDisplay == DISPLAY_FM)
|
||||||
|
goto start_tx; // listening to the FM radio .. start TX'ing
|
||||||
|
#endif
|
||||||
|
|
||||||
if (gCurrentFunction == FUNCTION_TRANSMIT && gRTTECountdown == 0)
|
if (gCurrentFunction == FUNCTION_TRANSMIT && gRTTECountdown == 0)
|
||||||
{ // already transmitting
|
{ // already transmitting
|
||||||
@@ -211,6 +186,7 @@ void GENERIC_Key_PTT(bool bKeyPressed)
|
|||||||
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;
|
||||||
|
|
||||||
|
|
||||||
if (!gDTMF_InputMode && gDTMF_InputBox_Index == 0)
|
if (!gDTMF_InputMode && gDTMF_InputBox_Index == 0)
|
||||||
goto start_tx; // wasn't entering a DTMF code .. start TX'ing (maybe)
|
goto start_tx; // wasn't entering a DTMF code .. start TX'ing (maybe)
|
||||||
|
|
||||||
@@ -225,28 +201,20 @@ void GENERIC_Key_PTT(bool bKeyPressed)
|
|||||||
if (gDTMF_InputBox_Index < sizeof(gDTMF_InputBox))
|
if (gDTMF_InputBox_Index < sizeof(gDTMF_InputBox))
|
||||||
gDTMF_InputBox[gDTMF_InputBox_Index] = 0; // NULL term the string
|
gDTMF_InputBox[gDTMF_InputBox_Index] = 0; // NULL term the string
|
||||||
|
|
||||||
#if 0
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
// append our DTMF ID to the inputted DTMF code -
|
// append our DTMF ID to the inputted DTMF code -
|
||||||
// IF the user inputted code is exactly 3 digits long
|
// IF the user inputted code is exactly 3 digits long and D-DCD is enabled
|
||||||
if (gDTMF_InputBox_Index == 3)
|
if (gDTMF_InputBox_Index == 3 && gTxVfo->DTMF_DECODING_ENABLE > 0)
|
||||||
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
|
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
|
||||||
else
|
else
|
||||||
gDTMF_CallMode = DTMF_CALL_MODE_DTMF;
|
gDTMF_CallMode = DTMF_CALL_MODE_DTMF;
|
||||||
#else
|
|
||||||
// append our DTMF ID to the inputted DTMF code -
|
|
||||||
// IF the user inputted code is exactly 3 digits long and D-DCD is enabled
|
|
||||||
if (gDTMF_InputBox_Index == 3 && gTxVfo->DTMF_DECODING_ENABLE > 0)
|
|
||||||
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
|
|
||||||
else
|
|
||||||
gDTMF_CallMode = DTMF_CALL_MODE_DTMF;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
gDTMF_State = DTMF_STATE_0;
|
||||||
|
#endif
|
||||||
// remember the DTMF string
|
// remember the DTMF string
|
||||||
gDTMF_PreviousIndex = gDTMF_InputBox_Index;
|
gDTMF_PreviousIndex = gDTMF_InputBox_Index;
|
||||||
strcpy(gDTMF_String, gDTMF_InputBox);
|
strcpy(gDTMF_String, gDTMF_InputBox);
|
||||||
|
|
||||||
gDTMF_ReplyState = DTMF_REPLY_ANI;
|
gDTMF_ReplyState = DTMF_REPLY_ANI;
|
||||||
gDTMF_State = DTMF_STATE_0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DTMF_clear_input_box();
|
DTMF_clear_input_box();
|
||||||
@@ -259,14 +227,20 @@ start_tx:
|
|||||||
cancel_tx:
|
cancel_tx:
|
||||||
if (gPttIsPressed)
|
if (gPttIsPressed)
|
||||||
{
|
{
|
||||||
gPttIsPressed = false;
|
|
||||||
gPttWasPressed = true;
|
gPttWasPressed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
gPttDebounceCounter = 0;
|
gPttDebounceCounter = 0;
|
||||||
if (gScreenToDisplay != DISPLAY_MENU && gRequestDisplayScreen != DISPLAY_FM) // 1of11 .. don't close the menu
|
if (gScreenToDisplay != DISPLAY_MENU
|
||||||
|
#ifdef ENABLE_FMRADIO
|
||||||
|
&& gRequestDisplayScreen != DISPLAY_FM
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
// 1of11 .. don't close the menu
|
||||||
gRequestDisplayScreen = DISPLAY_MAIN;
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
||||||
|
}
|
||||||
|
|
||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
gUpdateDisplay = true;
|
gUpdateDisplay = true;
|
||||||
}
|
}
|
||||||
|
|||||||
395
app/main.c
395
app/main.c
@@ -18,15 +18,19 @@
|
|||||||
|
|
||||||
#include "app/action.h"
|
#include "app/action.h"
|
||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
|
#include "app/chFrScanner.h"
|
||||||
|
#include "app/common.h"
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
#include "app/fm.h"
|
#include "app/fm.h"
|
||||||
#endif
|
#endif
|
||||||
#include "app/generic.h"
|
#include "app/generic.h"
|
||||||
#include "app/main.h"
|
#include "app/main.h"
|
||||||
#include "app/scanner.h"
|
#include "app/scanner.h"
|
||||||
|
|
||||||
#ifdef ENABLE_SPECTRUM
|
#ifdef ENABLE_SPECTRUM
|
||||||
#include "app/spectrum.h"
|
#include "app/spectrum.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "driver/bk4819.h"
|
#include "driver/bk4819.h"
|
||||||
@@ -37,29 +41,28 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "ui/inputbox.h"
|
#include "ui/inputbox.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
#ifdef ENABLE_SPECTRUM
|
#include <stdlib.h>
|
||||||
// #include "app/spectrum.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void toggle_chan_scanlist(void)
|
void toggle_chan_scanlist(void)
|
||||||
{ // toggle the selected channels scanlist setting
|
{ // toggle the selected channels scanlist setting
|
||||||
|
|
||||||
if (gScreenToDisplay == DISPLAY_SCANNER || !IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
if (SCANNER_IsScanning())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (gTxVfo->SCANLIST1_PARTICIPATION)
|
if(!IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
|
||||||
{
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
if (gTxVfo->SCANLIST2_PARTICIPATION)
|
gScanRangeStart = gScanRangeStart ? 0 : gTxVfo->pRX->Frequency;
|
||||||
gTxVfo->SCANLIST1_PARTICIPATION = 0;
|
gScanRangeStop = gEeprom.VfoInfo[!gEeprom.TX_VFO].freq_config_RX.Frequency;
|
||||||
else
|
if(gScanRangeStart > gScanRangeStop)
|
||||||
gTxVfo->SCANLIST2_PARTICIPATION = 1;
|
SWAP(gScanRangeStart, gScanRangeStop);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
if (gTxVfo->SCANLIST1_PARTICIPATION ^ gTxVfo->SCANLIST2_PARTICIPATION){
|
||||||
if (gTxVfo->SCANLIST2_PARTICIPATION)
|
gTxVfo->SCANLIST2_PARTICIPATION = gTxVfo->SCANLIST1_PARTICIPATION;
|
||||||
gTxVfo->SCANLIST2_PARTICIPATION = 0;
|
} else {
|
||||||
else
|
gTxVfo->SCANLIST1_PARTICIPATION = !gTxVfo->SCANLIST1_PARTICIPATION;
|
||||||
gTxVfo->SCANLIST1_PARTICIPATION = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true);
|
SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true);
|
||||||
@@ -70,7 +73,6 @@ void toggle_chan_scanlist(void)
|
|||||||
|
|
||||||
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 Vfo = gEeprom.TX_VFO;
|
uint8_t Vfo = gEeprom.TX_VFO;
|
||||||
|
|
||||||
if (gScreenToDisplay == DISPLAY_MENU)
|
if (gScreenToDisplay == DISPLAY_MENU)
|
||||||
@@ -98,26 +100,68 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_1:
|
case KEY_1:
|
||||||
if (!IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
if (!IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
|
||||||
{
|
|
||||||
gWasFKeyPressed = false;
|
gWasFKeyPressed = false;
|
||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
|
|
||||||
|
#ifdef ENABLE_COPY_CHAN_TO_VFO
|
||||||
|
if (!gEeprom.VFO_OPEN || gCssBackgroundScan)
|
||||||
|
{
|
||||||
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gScanStateDir != SCAN_OFF)
|
||||||
|
{
|
||||||
|
if (gCurrentFunction != FUNCTION_INCOMING ||
|
||||||
|
gRxReceptionMode == RX_MODE_NONE ||
|
||||||
|
gScanPauseDelayIn_10ms == 0)
|
||||||
|
{ // scan is running (not paused)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t vfo = gEeprom.TX_VFO;
|
||||||
|
|
||||||
|
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo]))
|
||||||
|
{ // copy channel to VFO, then swap to the VFO
|
||||||
|
|
||||||
|
gEeprom.ScreenChannel[vfo] = FREQ_CHANNEL_FIRST + gEeprom.VfoInfo[vfo].Band;
|
||||||
|
gEeprom.VfoInfo[vfo].CHANNEL_SAVE = gEeprom.ScreenChannel[vfo];
|
||||||
|
|
||||||
|
RADIO_SelectVfos();
|
||||||
|
RADIO_ApplyOffset(gRxVfo);
|
||||||
|
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
|
||||||
|
RADIO_SetupRegisters(true);
|
||||||
|
|
||||||
|
//SETTINGS_SaveChannel(channel, gEeprom.RX_VFO, gRxVfo, 1);
|
||||||
|
|
||||||
|
gUpdateDisplay = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Band = gTxVfo->Band + 1;
|
#ifdef ENABLE_WIDE_RX
|
||||||
if (gSetting_350EN || Band != BAND5_350MHz)
|
if(gTxVfo->Band == BAND7_470MHz && gTxVfo->pRX->Frequency < _1GHz_in_KHz) {
|
||||||
{
|
gTxVfo->pRX->Frequency = _1GHz_in_KHz;
|
||||||
if (Band > BAND7_470MHz)
|
return;
|
||||||
Band = BAND1_50MHz;
|
|
||||||
}
|
}
|
||||||
else
|
#endif
|
||||||
Band = BAND6_400MHz;
|
|
||||||
gTxVfo->Band = Band;
|
|
||||||
|
|
||||||
gEeprom.ScreenChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
|
gTxVfo->Band += 1;
|
||||||
gEeprom.FreqChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
|
|
||||||
|
if (gTxVfo->Band == BAND5_350MHz && !gSetting_350EN) {
|
||||||
|
// skip if not enabled
|
||||||
|
gTxVfo->Band += 1;
|
||||||
|
} else if (gTxVfo->Band >= BAND_N_ELEM){
|
||||||
|
// go arround if overflowed
|
||||||
|
gTxVfo->Band = BAND1_50MHz;
|
||||||
|
}
|
||||||
|
|
||||||
|
gEeprom.ScreenChannel[Vfo] = FREQ_CHANNEL_FIRST + gTxVfo->Band;
|
||||||
|
gEeprom.FreqChannel[Vfo] = FREQ_CHANNEL_FIRST + gTxVfo->Band;
|
||||||
|
|
||||||
gRequestSaveVFO = true;
|
gRequestSaveVFO = true;
|
||||||
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
||||||
@@ -130,64 +174,14 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_2:
|
case KEY_2:
|
||||||
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_A)
|
COMMON_SwitchVFOs();
|
||||||
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_CHAN_B;
|
|
||||||
else
|
|
||||||
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_B)
|
|
||||||
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_CHAN_A;
|
|
||||||
else
|
|
||||||
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A)
|
|
||||||
gEeprom.DUAL_WATCH = DUAL_WATCH_CHAN_B;
|
|
||||||
else
|
|
||||||
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B)
|
|
||||||
gEeprom.DUAL_WATCH = DUAL_WATCH_CHAN_A;
|
|
||||||
else
|
|
||||||
gEeprom.TX_VFO = (Vfo + 1) & 1u;
|
|
||||||
|
|
||||||
gRequestSaveSettings = 1;
|
|
||||||
gFlagReconfigureVfos = true;
|
|
||||||
|
|
||||||
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
||||||
|
|
||||||
if (beep)
|
if (beep)
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_3:
|
case KEY_3:
|
||||||
#ifdef ENABLE_NOAA
|
COMMON_SwitchVFOMode();
|
||||||
if (gEeprom.VFO_OPEN && IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
|
||||||
#else
|
|
||||||
if (gEeprom.VFO_OPEN)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
uint8_t Channel;
|
|
||||||
|
|
||||||
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
|
||||||
{ // swap to frequency mode
|
|
||||||
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_VFO];
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
|
|
||||||
#endif
|
|
||||||
gRequestSaveVFO = true;
|
|
||||||
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 0);
|
|
||||||
if (Channel != 0xFF)
|
|
||||||
{ // swap to channel mode
|
|
||||||
gEeprom.ScreenChannel[Vfo] = Channel;
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
|
|
||||||
AUDIO_SetDigitVoice(1, Channel + 1);
|
|
||||||
gAnotherVoiceID = (VOICE_ID_t)0xFE;
|
|
||||||
#endif
|
|
||||||
gRequestSaveVFO = true;
|
|
||||||
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (beep)
|
if (beep)
|
||||||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
@@ -196,31 +190,31 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
|
|||||||
|
|
||||||
case KEY_4:
|
case KEY_4:
|
||||||
gWasFKeyPressed = false;
|
gWasFKeyPressed = false;
|
||||||
gFlagStartScan = true;
|
|
||||||
gScanSingleFrequency = false;
|
|
||||||
gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
|
gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
|
||||||
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
|
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
|
||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
|
|
||||||
if (beep)
|
if (beep)
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
|
|
||||||
|
SCANNER_Start(false);
|
||||||
|
gRequestDisplayScreen = DISPLAY_SCANNER;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_5:
|
case KEY_5:
|
||||||
if(beep) {
|
if(beep) {
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
|
|
||||||
if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
||||||
{
|
{
|
||||||
gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_VFO];
|
gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_VFO];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_VFO];
|
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;
|
||||||
@@ -230,9 +224,9 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#ifdef ENABLE_VOX
|
#ifdef ENABLE_VOX
|
||||||
toggle_chan_scanlist();
|
toggle_chan_scanlist();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -242,11 +236,11 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_7:
|
case KEY_7:
|
||||||
#ifdef ENABLE_VOX
|
#ifdef ENABLE_VOX
|
||||||
ACTION_Vox();
|
ACTION_Vox();
|
||||||
#else
|
#else
|
||||||
toggle_chan_scanlist();
|
toggle_chan_scanlist();
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_8:
|
case KEY_8:
|
||||||
@@ -259,11 +253,11 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
|
|||||||
{
|
{
|
||||||
gEeprom.MrChannel[Vfo] = gEeprom.CHAN_1_CALL;
|
gEeprom.MrChannel[Vfo] = gEeprom.CHAN_1_CALL;
|
||||||
gEeprom.ScreenChannel[Vfo] = gEeprom.CHAN_1_CALL;
|
gEeprom.ScreenChannel[Vfo] = gEeprom.CHAN_1_CALL;
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
|
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
|
||||||
AUDIO_SetDigitVoice(1, gEeprom.CHAN_1_CALL + 1);
|
AUDIO_SetDigitVoice(1, gEeprom.CHAN_1_CALL + 1);
|
||||||
gAnotherVoiceID = (VOICE_ID_t)0xFE;
|
gAnotherVoiceID = (VOICE_ID_t)0xFE;
|
||||||
#endif
|
#endif
|
||||||
gRequestSaveVFO = true;
|
gRequestSaveVFO = true;
|
||||||
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
||||||
break;
|
break;
|
||||||
@@ -328,8 +322,6 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
||||||
{ // user is entering channel number
|
{ // user is entering channel number
|
||||||
|
|
||||||
uint16_t Channel;
|
|
||||||
|
|
||||||
if (gInputBoxIndex != 3)
|
if (gInputBoxIndex != 3)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
@@ -341,7 +333,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
|
|
||||||
gInputBoxIndex = 0;
|
gInputBoxIndex = 0;
|
||||||
|
|
||||||
Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
|
const uint16_t Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
|
||||||
|
|
||||||
if (!RADIO_CheckValidChannel(Channel, false, 0))
|
if (!RADIO_CheckValidChannel(Channel, false, 0))
|
||||||
{
|
{
|
||||||
@@ -362,25 +354,22 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// #ifdef ENABLE_NOAA
|
// #ifdef ENABLE_NOAA
|
||||||
// if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
// if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
||||||
// #endif
|
// #endif
|
||||||
if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
||||||
{ // user is entering a frequency
|
{ // user is entering a frequency
|
||||||
|
|
||||||
uint32_t Frequency;
|
#ifdef ENABLE_VOICE
|
||||||
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
||||||
if (gInputBoxIndex < 6)
|
#endif
|
||||||
|
bool isGigaF = gTxVfo->pRX->Frequency >= _1GHz_in_KHz;
|
||||||
|
if (gInputBoxIndex < 6 + isGigaF)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
gAnotherVoiceID = (VOICE_ID_t)Key;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gInputBoxIndex = 0;
|
gInputBoxIndex = 0;
|
||||||
|
uint32_t Frequency = StrToUL(INPUTBOX_GetAscii()) * 100;
|
||||||
NUMBER_Get(gInputBox, &Frequency);
|
|
||||||
|
|
||||||
// clamp the frequency entered to some valid value
|
// clamp the frequency entered to some valid value
|
||||||
if (Frequency < frequencyBandTable[0].lower)
|
if (Frequency < frequencyBandTable[0].lower)
|
||||||
@@ -394,54 +383,42 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
Frequency = (Frequency < center) ? BX4819_band1.upper : BX4819_band2.lower;
|
Frequency = (Frequency < center) ? BX4819_band1.upper : BX4819_band2.lower;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (Frequency > frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper)
|
if (Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper)
|
||||||
{
|
{
|
||||||
Frequency = frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper;
|
Frequency = frequencyBandTable[BAND_N_ELEM - 1].upper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FREQUENCY_Band_t band = FREQUENCY_GetBand(Frequency);
|
||||||
|
|
||||||
|
if (gTxVfo->Band != band)
|
||||||
{
|
{
|
||||||
const FREQUENCY_Band_t band = FREQUENCY_GetBand(Frequency);
|
gTxVfo->Band = band;
|
||||||
|
gEeprom.ScreenChannel[Vfo] = band + FREQ_CHANNEL_FIRST;
|
||||||
|
gEeprom.FreqChannel[Vfo] = band + FREQ_CHANNEL_FIRST;
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
SETTINGS_SaveVfoIndices();
|
||||||
gAnotherVoiceID = (VOICE_ID_t)Key;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (gTxVfo->Band != band)
|
RADIO_ConfigureChannel(Vfo, VFO_CONFIGURE_RELOAD);
|
||||||
{
|
|
||||||
gTxVfo->Band = band;
|
|
||||||
gEeprom.ScreenChannel[Vfo] = band + FREQ_CHANNEL_FIRST;
|
|
||||||
gEeprom.FreqChannel[Vfo] = band + FREQ_CHANNEL_FIRST;
|
|
||||||
|
|
||||||
SETTINGS_SaveVfoIndices();
|
|
||||||
|
|
||||||
RADIO_ConfigureChannel(Vfo, VFO_CONFIGURE_RELOAD);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Frequency += 75; // is this meant to be rounding ?
|
|
||||||
Frequency += gTxVfo->StepFrequency / 2; // no idea, but this is
|
|
||||||
|
|
||||||
Frequency = FREQUENCY_FloorToStep(Frequency, gTxVfo->StepFrequency, frequencyBandTable[gTxVfo->Band].lower);
|
|
||||||
|
|
||||||
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
|
|
||||||
{ // clamp the frequency to the limit
|
|
||||||
const uint32_t center = (BX4819_band1.upper + BX4819_band2.lower) / 2;
|
|
||||||
Frequency = (Frequency < center) ? BX4819_band1.upper - gTxVfo->StepFrequency : BX4819_band2.lower;
|
|
||||||
}
|
|
||||||
|
|
||||||
gTxVfo->freq_config_RX.Frequency = Frequency;
|
|
||||||
|
|
||||||
gRequestSaveChannel = 1;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Frequency = FREQUENCY_RoundToStep(Frequency, gTxVfo->StepFrequency);
|
||||||
|
|
||||||
|
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
|
||||||
|
{ // clamp the frequency to the limit
|
||||||
|
const uint32_t center = (BX4819_band1.upper + BX4819_band2.lower) / 2;
|
||||||
|
Frequency = (Frequency < center) ? BX4819_band1.upper - gTxVfo->StepFrequency : BX4819_band2.lower;
|
||||||
|
}
|
||||||
|
|
||||||
|
gTxVfo->freq_config_RX.Frequency = Frequency;
|
||||||
|
|
||||||
|
gRequestSaveChannel = 1;
|
||||||
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
else
|
else
|
||||||
if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
||||||
{ // user is entering NOAA channel
|
{ // user is entering NOAA channel
|
||||||
|
|
||||||
uint8_t Channel;
|
|
||||||
|
|
||||||
if (gInputBoxIndex != 2)
|
if (gInputBoxIndex != 2)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
@@ -453,7 +430,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
|
|
||||||
gInputBoxIndex = 0;
|
gInputBoxIndex = 0;
|
||||||
|
|
||||||
Channel = (gInputBox[0] * 10) + gInputBox[1];
|
uint8_t Channel = (gInputBox[0] * 10) + gInputBox[1];
|
||||||
if (Channel >= 1 && Channel <= ARRAY_SIZE(NoaaFrequencyTable))
|
if (Channel >= 1 && Channel <= ARRAY_SIZE(NoaaFrequencyTable))
|
||||||
{
|
{
|
||||||
Channel += NOAA_CHANNEL_FIRST;
|
Channel += NOAA_CHANNEL_FIRST;
|
||||||
@@ -487,12 +464,14 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
|
|||||||
|
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
if (gDTMF_CallState != DTMF_CALL_STATE_NONE && gCurrentFunction != FUNCTION_TRANSMIT)
|
if (gDTMF_CallState != DTMF_CALL_STATE_NONE && gCurrentFunction != FUNCTION_TRANSMIT)
|
||||||
{ // clear CALL mode being displayed
|
{ // clear CALL mode being displayed
|
||||||
gDTMF_CallState = DTMF_CALL_STATE_NONE;
|
gDTMF_CallState = DTMF_CALL_STATE_NONE;
|
||||||
gUpdateDisplay = true;
|
gUpdateDisplay = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
if (!gFmRadioMode)
|
if (!gFmRadioMode)
|
||||||
@@ -513,7 +492,8 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SCANNER_Stop();
|
gScanKeepResult = false;
|
||||||
|
CHFRSCANNER_Stop();
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
|
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
|
||||||
@@ -571,51 +551,7 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
|
|||||||
gWasFKeyPressed = false;
|
gWasFKeyPressed = false;
|
||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
|
|
||||||
#ifdef ENABLE_COPY_CHAN_TO_VFO
|
ACTION_Handle(KEY_MENU, bKeyPressed, bKeyHeld);
|
||||||
|
|
||||||
if (gEeprom.VFO_OPEN && gCssScanMode == CSS_SCAN_MODE_OFF)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (gScanStateDir != SCAN_OFF)
|
|
||||||
{
|
|
||||||
if (gCurrentFunction != FUNCTION_INCOMING ||
|
|
||||||
gRxReceptionMode == RX_MODE_NONE ||
|
|
||||||
gScanPauseDelayIn_10ms == 0)
|
|
||||||
{ // scan is running (not paused)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned int vfo = get_rx_VFO();
|
|
||||||
|
|
||||||
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo]))
|
|
||||||
{ // copy channel to VFO, then swap to the VFO
|
|
||||||
|
|
||||||
const unsigned int channel = FREQ_CHANNEL_FIRST + gEeprom.VfoInfo[vfo].Band;
|
|
||||||
|
|
||||||
gEeprom.ScreenChannel[vfo] = channel;
|
|
||||||
gEeprom.VfoInfo[vfo].CHANNEL_SAVE = channel;
|
|
||||||
gEeprom.TX_VFO = vfo;
|
|
||||||
|
|
||||||
RADIO_SelectVfos();
|
|
||||||
RADIO_ApplyOffset(gRxVfo);
|
|
||||||
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
|
|
||||||
RADIO_SetupRegisters(true);
|
|
||||||
|
|
||||||
//SETTINGS_SaveChannel(channel, gEeprom.RX_VFO, gRxVfo, 1);
|
|
||||||
|
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
|
||||||
|
|
||||||
gUpdateStatus = true;
|
|
||||||
gUpdateDisplay = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,11 +560,16 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
|
|||||||
|
|
||||||
if (!bKeyPressed && !gDTMF_InputMode)
|
if (!bKeyPressed && !gDTMF_InputMode)
|
||||||
{ // menu key released
|
{ // menu key released
|
||||||
const bool bFlag = (gInputBoxIndex == 0);
|
const bool bFlag = !gInputBoxIndex;
|
||||||
gInputBoxIndex = 0;
|
gInputBoxIndex = 0;
|
||||||
|
|
||||||
if (bFlag)
|
if (bFlag)
|
||||||
{
|
{
|
||||||
|
if (gScanStateDir != SCAN_OFF) {
|
||||||
|
CHFRSCANNER_Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gFlagRefreshSetting = true;
|
gFlagRefreshSetting = true;
|
||||||
gRequestDisplayScreen = DISPLAY_MENU;
|
gRequestDisplayScreen = DISPLAY_MENU;
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
@@ -654,37 +595,37 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bKeyHeld && !gWasFKeyPressed)
|
if (bKeyHeld && !gWasFKeyPressed) // long press
|
||||||
{ // long press .. toggle scanning
|
{
|
||||||
if (!bKeyPressed)
|
if (!bKeyPressed) // released
|
||||||
return; // released
|
return;
|
||||||
|
|
||||||
ACTION_Scan(false);
|
ACTION_Scan(false);// toggle scanning
|
||||||
|
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bKeyPressed)
|
if (bKeyPressed) // just pressed
|
||||||
{ // just pressed
|
{
|
||||||
// gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
|
||||||
gBeepToPlay = BEEP_880HZ_40MS_OPTIONAL;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// just released
|
// just released
|
||||||
|
|
||||||
if (!gWasFKeyPressed)
|
if (!gWasFKeyPressed) // pressed without the F-key
|
||||||
{ // pressed without the F-key
|
{
|
||||||
|
if (gScanStateDir == SCAN_OFF
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
if (gScanStateDir == SCAN_OFF && IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
&& !IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)
|
||||||
#else
|
#endif
|
||||||
if (gScanStateDir == SCAN_OFF)
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
#endif
|
&& gScanRangeStart == 0
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{ // start entering a DTMF string
|
{ // start entering a DTMF string
|
||||||
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
memmove(gDTMF_InputBox, gDTMF_String, MIN(sizeof(gDTMF_InputBox), sizeof(gDTMF_String) - 1));
|
memcpy(gDTMF_InputBox, gDTMF_String, MIN(sizeof(gDTMF_InputBox), sizeof(gDTMF_String) - 1));
|
||||||
gDTMF_InputBox_Index = 0;
|
gDTMF_InputBox_Index = 0;
|
||||||
gDTMF_InputMode = true;
|
gDTMF_InputMode = true;
|
||||||
|
|
||||||
@@ -692,28 +633,28 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
|
|||||||
|
|
||||||
gRequestDisplayScreen = DISPLAY_MAIN;
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // with the F-key
|
{ // with the F-key
|
||||||
gWasFKeyPressed = false;
|
gWasFKeyPressed = false;
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
|
||||||
{
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
return;
|
||||||
return;
|
}
|
||||||
}
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
// scan the CTCSS/DCS code
|
// scan the CTCSS/DCS code
|
||||||
gFlagStartScan = true;
|
|
||||||
gScanSingleFrequency = true;
|
|
||||||
gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
|
gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
|
||||||
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
|
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
|
||||||
|
SCANNER_Start(true);
|
||||||
|
gRequestDisplayScreen = DISPLAY_SCANNER;
|
||||||
}
|
}
|
||||||
|
|
||||||
gPttWasReleased = true;
|
gPttWasReleased = true;
|
||||||
|
|
||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,7 +697,7 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
|
|||||||
if (gScanStateDir == SCAN_OFF)
|
if (gScanStateDir == SCAN_OFF)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
if (IS_NOT_NOAA_CHANNEL(Channel))
|
if (!IS_NOAA_CHANNEL(Channel))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
uint8_t Next;
|
uint8_t Next;
|
||||||
@@ -810,7 +751,7 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// jump to the next channel
|
// jump to the next channel
|
||||||
CHANNEL_Next(false, Direction);
|
CHFRSCANNER_Start(false, Direction);
|
||||||
gScanPauseDelayIn_10ms = 1;
|
gScanPauseDelayIn_10ms = 1;
|
||||||
gScheduleScanListen = false;
|
gScheduleScanListen = false;
|
||||||
|
|
||||||
|
|||||||
626
app/menu.c
626
app/menu.c
File diff suppressed because it is too large
Load Diff
@@ -23,11 +23,13 @@
|
|||||||
void writeXtalFreqCal(const int32_t value, const bool update_eeprom);
|
void writeXtalFreqCal(const int32_t value, const bool update_eeprom);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax);
|
extern uint8_t gUnlockAllTxConfCnt;
|
||||||
|
|
||||||
|
int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax);
|
||||||
void MENU_AcceptSetting(void);
|
void MENU_AcceptSetting(void);
|
||||||
void MENU_SelectNextCode(void);
|
|
||||||
void MENU_ShowCurrentSetting(void);
|
void MENU_ShowCurrentSetting(void);
|
||||||
void MENU_StartCssScan(int8_t Direction);
|
void MENU_StartCssScan(void);
|
||||||
|
void MENU_CssScanFound(void);
|
||||||
void MENU_StopCssScan(void);
|
void MENU_StopCssScan(void);
|
||||||
|
|
||||||
void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
|
void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
|
||||||
|
|||||||
472
app/scanner.c
472
app/scanner.c
@@ -14,8 +14,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "app/app.h"
|
||||||
#include "app/dtmf.h"
|
#include "app/dtmf.h"
|
||||||
#include "app/generic.h"
|
#include "app/generic.h"
|
||||||
|
#include "app/menu.h"
|
||||||
#include "app/scanner.h"
|
#include "app/scanner.h"
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "driver/bk4819.h"
|
#include "driver/bk4819.h"
|
||||||
@@ -28,54 +30,45 @@
|
|||||||
|
|
||||||
DCS_CodeType_t gScanCssResultType;
|
DCS_CodeType_t gScanCssResultType;
|
||||||
uint8_t gScanCssResultCode;
|
uint8_t gScanCssResultCode;
|
||||||
bool gFlagStartScan;
|
bool gScanSingleFrequency; // scan CTCSS/DCS codes for current frequency
|
||||||
bool gFlagStopScan;
|
SCAN_SaveState_t gScannerSaveState;
|
||||||
bool gScanSingleFrequency;
|
|
||||||
uint8_t gScannerEditState;
|
|
||||||
uint8_t gScanChannel;
|
uint8_t gScanChannel;
|
||||||
uint32_t gScanFrequency;
|
uint32_t gScanFrequency;
|
||||||
bool gScanPauseMode;
|
|
||||||
SCAN_CssState_t gScanCssState;
|
SCAN_CssState_t gScanCssState;
|
||||||
volatile bool gScheduleScanListen = true;
|
|
||||||
volatile uint16_t gScanPauseDelayIn_10ms;
|
|
||||||
uint8_t gScanProgressIndicator;
|
uint8_t gScanProgressIndicator;
|
||||||
uint8_t gScanHitCount;
|
|
||||||
bool gScanUseCssResult;
|
bool gScanUseCssResult;
|
||||||
int8_t gScanStateDir;
|
|
||||||
bool bScanKeepFrequency;
|
STEP_Setting_t stepSetting;
|
||||||
|
uint8_t scanHitCount;
|
||||||
|
|
||||||
|
|
||||||
static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
||||||
{
|
{
|
||||||
if (!bKeyHeld && bKeyPressed)
|
if (!bKeyHeld && bKeyPressed)
|
||||||
{
|
{
|
||||||
if (gScannerEditState == 1)
|
if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
|
||||||
{
|
|
||||||
uint16_t Channel;
|
|
||||||
|
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
|
|
||||||
INPUTBOX_Append(Key);
|
INPUTBOX_Append(Key);
|
||||||
|
|
||||||
gRequestDisplayScreen = DISPLAY_SCANNER;
|
gRequestDisplayScreen = DISPLAY_SCANNER;
|
||||||
|
|
||||||
if (gInputBoxIndex < 3)
|
if (gInputBoxIndex < 3) {
|
||||||
{
|
#ifdef ENABLE_VOICE
|
||||||
#ifdef ENABLE_VOICE
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
||||||
gAnotherVoiceID = (VOICE_ID_t)Key;
|
#endif
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gInputBoxIndex = 0;
|
gInputBoxIndex = 0;
|
||||||
|
|
||||||
Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
|
uint16_t chan = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
|
||||||
if (Channel <= MR_CHANNEL_LAST)
|
if (IS_MR_CHANNEL(chan)) {
|
||||||
{
|
#ifdef ENABLE_VOICE
|
||||||
#ifdef ENABLE_VOICE
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
||||||
gAnotherVoiceID = (VOICE_ID_t)Key;
|
#endif
|
||||||
#endif
|
gShowChPrefix = RADIO_CheckValidChannel(chan, false, 0);
|
||||||
gShowChPrefix = RADIO_CheckValidChannel(Channel, false, 0);
|
gScanChannel = (uint8_t)chan;
|
||||||
gScanChannel = (uint8_t)Channel;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,28 +79,17 @@ static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
|
|
||||||
static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
|
static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
|
||||||
{
|
{
|
||||||
if (!bKeyHeld && bKeyPressed)
|
if (!bKeyHeld && bKeyPressed) { // short pressed
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
|
|
||||||
switch (gScannerEditState)
|
switch (gScannerSaveState) {
|
||||||
{
|
case SCAN_SAVE_NO_PROMPT:
|
||||||
case 0:
|
SCANNER_Stop();
|
||||||
gRequestDisplayScreen = DISPLAY_MAIN;
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
||||||
|
|
||||||
gEeprom.CROSS_BAND_RX_TX = gBackup_CROSS_BAND_RX_TX;
|
|
||||||
gUpdateStatus = true;
|
|
||||||
gFlagStopScan = true;
|
|
||||||
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
|
||||||
gFlagResetVfos = true;
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
gAnotherVoiceID = VOICE_ID_CANCEL;
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case SCAN_SAVE_CHAN_SEL:
|
||||||
if (gInputBoxIndex > 0)
|
if (gInputBoxIndex > 0) {
|
||||||
{
|
|
||||||
gInputBox[--gInputBoxIndex] = 10;
|
gInputBox[--gInputBoxIndex] = 10;
|
||||||
gRequestDisplayScreen = DISPLAY_SCANNER;
|
gRequestDisplayScreen = DISPLAY_SCANNER;
|
||||||
break;
|
break;
|
||||||
@@ -115,11 +97,11 @@ static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
|
|||||||
|
|
||||||
// Fallthrough
|
// Fallthrough
|
||||||
|
|
||||||
case 2:
|
case SCAN_SAVE_CHANNEL:
|
||||||
gScannerEditState = 0;
|
gScannerSaveState = SCAN_SAVE_NO_PROMPT;
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
gAnotherVoiceID = VOICE_ID_CANCEL;
|
gAnotherVoiceID = VOICE_ID_CANCEL;
|
||||||
#endif
|
#endif
|
||||||
gRequestDisplayScreen = DISPLAY_SCANNER;
|
gRequestDisplayScreen = DISPLAY_SCANNER;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -128,118 +110,85 @@ static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
|
|||||||
|
|
||||||
static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
|
static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
|
||||||
{
|
{
|
||||||
uint8_t Channel;
|
if (bKeyHeld || !bKeyPressed) // ignore long press or release button events
|
||||||
|
|
||||||
if (bKeyHeld)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!bKeyPressed)
|
if (gScanCssState == SCAN_CSS_STATE_OFF && !gScanSingleFrequency) {
|
||||||
return;
|
|
||||||
|
|
||||||
if (gScanCssState == SCAN_CSS_STATE_OFF && !gScanSingleFrequency)
|
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gScanCssState == SCAN_CSS_STATE_SCANNING)
|
if (gScanCssState == SCAN_CSS_STATE_SCANNING && gScanSingleFrequency) {
|
||||||
{
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
if (gScanSingleFrequency)
|
return;
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gScanCssState == SCAN_CSS_STATE_FAILED)
|
if (gScanCssState == SCAN_CSS_STATE_FAILED) {
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
|
|
||||||
switch (gScannerEditState)
|
switch (gScannerSaveState) {
|
||||||
{
|
case SCAN_SAVE_NO_PROMPT:
|
||||||
case 0:
|
|
||||||
if (!gScanSingleFrequency)
|
if (!gScanSingleFrequency)
|
||||||
{
|
{
|
||||||
int16_t Delta625;
|
uint32_t freq250 = FREQUENCY_RoundToStep(gScanFrequency, 250);
|
||||||
uint32_t Freq250 = FREQUENCY_FloorToStep(gScanFrequency, 250, 0);
|
uint32_t freq625 = FREQUENCY_RoundToStep(gScanFrequency, 625);
|
||||||
uint32_t Freq625 = FREQUENCY_FloorToStep(gScanFrequency, 625, 0);
|
|
||||||
int16_t Delta250 = (int16_t)gScanFrequency - (int16_t)Freq250;
|
|
||||||
|
|
||||||
if (125 < Delta250)
|
uint32_t diff250 = gScanFrequency > freq250 ? gScanFrequency - freq250 : freq250 - gScanFrequency;
|
||||||
{
|
uint32_t diff625 = gScanFrequency > freq625 ? gScanFrequency - freq625 : freq625 - gScanFrequency;
|
||||||
Delta250 = 250 - Delta250;
|
|
||||||
Freq250 += 250;
|
if(diff250 > diff625) {
|
||||||
|
stepSetting = STEP_6_25kHz;
|
||||||
|
gScanFrequency = freq625;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
Delta625 = (int16_t)gScanFrequency - (int16_t)Freq625;
|
stepSetting = STEP_2_5kHz;
|
||||||
|
gScanFrequency = freq250;
|
||||||
if (312 < Delta625)
|
|
||||||
{
|
|
||||||
Delta625 = 625 - Delta625;
|
|
||||||
Freq625 += 625;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Delta625 < Delta250)
|
|
||||||
{
|
|
||||||
gStepSetting = STEP_6_25kHz;
|
|
||||||
gScanFrequency = Freq625;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gStepSetting = STEP_2_5kHz;
|
|
||||||
gScanFrequency = Freq250;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gTxVfo->CHANNEL_SAVE <= MR_CHANNEL_LAST)
|
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
|
||||||
{
|
gScannerSaveState = SCAN_SAVE_CHAN_SEL;
|
||||||
gScannerEditState = 1;
|
|
||||||
gScanChannel = gTxVfo->CHANNEL_SAVE;
|
gScanChannel = gTxVfo->CHANNEL_SAVE;
|
||||||
gShowChPrefix = RADIO_CheckValidChannel(gTxVfo->CHANNEL_SAVE, false, 0);
|
gShowChPrefix = RADIO_CheckValidChannel(gTxVfo->CHANNEL_SAVE, false, 0);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
gScannerSaveState = SCAN_SAVE_CHANNEL;
|
||||||
gScannerEditState = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gScanCssState = SCAN_CSS_STATE_FOUND;
|
gScanCssState = SCAN_CSS_STATE_FOUND;
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
gAnotherVoiceID = VOICE_ID_MEMORY_CHANNEL;
|
gAnotherVoiceID = VOICE_ID_MEMORY_CHANNEL;
|
||||||
#endif
|
#endif
|
||||||
gRequestDisplayScreen = DISPLAY_SCANNER;
|
gRequestDisplayScreen = DISPLAY_SCANNER;
|
||||||
|
|
||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case SCAN_SAVE_CHAN_SEL:
|
||||||
if (gInputBoxIndex == 0)
|
if (gInputBoxIndex == 0) {
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
gRequestDisplayScreen = DISPLAY_SCANNER;
|
gRequestDisplayScreen = DISPLAY_SCANNER;
|
||||||
gScannerEditState = 2;
|
gScannerSaveState = SCAN_SAVE_CHANNEL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case SCAN_SAVE_CHANNEL:
|
||||||
if (!gScanSingleFrequency)
|
if (!gScanSingleFrequency) {
|
||||||
{
|
|
||||||
RADIO_InitInfo(gTxVfo, gTxVfo->CHANNEL_SAVE, gScanFrequency);
|
RADIO_InitInfo(gTxVfo, gTxVfo->CHANNEL_SAVE, gScanFrequency);
|
||||||
|
|
||||||
if (gScanUseCssResult)
|
if (gScanUseCssResult) {
|
||||||
{
|
|
||||||
gTxVfo->freq_config_RX.CodeType = gScanCssResultType;
|
gTxVfo->freq_config_RX.CodeType = gScanCssResultType;
|
||||||
gTxVfo->freq_config_RX.Code = gScanCssResultCode;
|
gTxVfo->freq_config_RX.Code = gScanCssResultCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
gTxVfo->freq_config_TX = gTxVfo->freq_config_RX;
|
gTxVfo->freq_config_TX = gTxVfo->freq_config_RX;
|
||||||
gTxVfo->STEP_SETTING = gStepSetting;
|
gTxVfo->STEP_SETTING = stepSetting;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD);
|
RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD);
|
||||||
RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD);
|
RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD);
|
||||||
|
|
||||||
@@ -249,25 +198,24 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
|
|||||||
gTxVfo->freq_config_TX.Code = gScanCssResultCode;
|
gTxVfo->freq_config_TX.Code = gScanCssResultCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gTxVfo->CHANNEL_SAVE <= MR_CHANNEL_LAST)
|
uint8_t chan;
|
||||||
{
|
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
|
||||||
Channel = gScanChannel;
|
chan = gScanChannel;
|
||||||
gEeprom.MrChannel[gEeprom.TX_VFO] = Channel;
|
gEeprom.MrChannel[gEeprom.TX_VFO] = chan;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
chan = gTxVfo->Band + FREQ_CHANNEL_FIRST;
|
||||||
Channel = gTxVfo->Band + FREQ_CHANNEL_FIRST;
|
gEeprom.FreqChannel[gEeprom.TX_VFO] = chan;
|
||||||
gEeprom.FreqChannel[gEeprom.TX_VFO] = Channel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gTxVfo->CHANNEL_SAVE = Channel;
|
gTxVfo->CHANNEL_SAVE = chan;
|
||||||
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel;
|
gEeprom.ScreenChannel[gEeprom.TX_VFO] = chan;
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
gAnotherVoiceID = VOICE_ID_CONFIRM;
|
gAnotherVoiceID = VOICE_ID_CONFIRM;
|
||||||
#endif
|
#endif
|
||||||
gRequestDisplayScreen = DISPLAY_SCANNER;
|
gRequestDisplayScreen = DISPLAY_SCANNER;
|
||||||
gRequestSaveChannel = 2;
|
gRequestSaveChannel = 2;
|
||||||
gScannerEditState = 0;
|
gScannerSaveState = SCAN_SAVE_NO_PROMPT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -278,23 +226,20 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
|
|||||||
|
|
||||||
static void SCANNER_Key_STAR(bool bKeyPressed, bool bKeyHeld)
|
static void SCANNER_Key_STAR(bool bKeyPressed, bool bKeyHeld)
|
||||||
{
|
{
|
||||||
if (!bKeyHeld && bKeyPressed)
|
if (!bKeyHeld && bKeyPressed) {
|
||||||
{
|
|
||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
gFlagStartScan = true;
|
SCANNER_Start(gScanSingleFrequency);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Direction)
|
static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Direction)
|
||||||
{
|
{
|
||||||
if (pKeyHeld)
|
if (pKeyHeld) {
|
||||||
{
|
|
||||||
if (!bKeyPressed)
|
if (!bKeyPressed)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if (!bKeyPressed)
|
if (!bKeyPressed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -302,8 +247,7 @@ static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Directio
|
|||||||
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gScannerEditState == 1)
|
if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
|
||||||
{
|
|
||||||
gScanChannel = NUMBER_AddWithWraparound(gScanChannel, Direction, 0, MR_CHANNEL_LAST);
|
gScanChannel = NUMBER_AddWithWraparound(gScanChannel, Direction, 0, MR_CHANNEL_LAST);
|
||||||
gShowChPrefix = RADIO_CheckValidChannel(gScanChannel, false, 0);
|
gShowChPrefix = RADIO_CheckValidChannel(gScanChannel, false, 0);
|
||||||
gRequestDisplayScreen = DISPLAY_SCANNER;
|
gRequestDisplayScreen = DISPLAY_SCANNER;
|
||||||
@@ -314,8 +258,7 @@ static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Directio
|
|||||||
|
|
||||||
void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
||||||
{
|
{
|
||||||
switch (Key)
|
switch (Key) {
|
||||||
{
|
|
||||||
case KEY_0:
|
case KEY_0:
|
||||||
case KEY_1:
|
case KEY_1:
|
||||||
case KEY_2:
|
case KEY_2:
|
||||||
@@ -353,110 +296,233 @@ void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCANNER_Start(void)
|
void SCANNER_Start(bool singleFreq)
|
||||||
{
|
{
|
||||||
uint8_t BackupStep;
|
gScanSingleFrequency = singleFreq;
|
||||||
uint16_t BackupFrequency;
|
gMonitor = false;
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;
|
||||||
|
#endif
|
||||||
|
|
||||||
BK4819_StopScan();
|
BK4819_StopScan();
|
||||||
|
|
||||||
RADIO_SelectVfos();
|
RADIO_SelectVfos();
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
|
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
|
||||||
gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + BAND6_400MHz;
|
gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + BAND6_400MHz;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BackupStep = gRxVfo->STEP_SETTING;
|
uint8_t backupStep = gRxVfo->STEP_SETTING;
|
||||||
BackupFrequency = gRxVfo->StepFrequency;
|
uint16_t backupFrequency = gRxVfo->StepFrequency;
|
||||||
|
|
||||||
RADIO_InitInfo(gRxVfo, gRxVfo->CHANNEL_SAVE, gRxVfo->pRX->Frequency);
|
RADIO_InitInfo(gRxVfo, gRxVfo->CHANNEL_SAVE, gRxVfo->pRX->Frequency);
|
||||||
|
|
||||||
gRxVfo->STEP_SETTING = BackupStep;
|
gRxVfo->STEP_SETTING = backupStep;
|
||||||
gRxVfo->StepFrequency = BackupFrequency;
|
gRxVfo->StepFrequency = backupFrequency;
|
||||||
|
|
||||||
RADIO_SetupRegisters(true);
|
RADIO_SetupRegisters(true);
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
gIsNoaaMode = false;
|
gIsNoaaMode = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gScanSingleFrequency)
|
if (gScanSingleFrequency) {
|
||||||
{
|
|
||||||
gScanCssState = SCAN_CSS_STATE_SCANNING;
|
gScanCssState = SCAN_CSS_STATE_SCANNING;
|
||||||
gScanFrequency = gRxVfo->pRX->Frequency;
|
gScanFrequency = gRxVfo->pRX->Frequency;
|
||||||
gStepSetting = gRxVfo->STEP_SETTING;
|
stepSetting = gRxVfo->STEP_SETTING;
|
||||||
|
|
||||||
BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency);
|
BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency);
|
||||||
BK4819_SetScanFrequency(gScanFrequency);
|
BK4819_SetScanFrequency(gScanFrequency);
|
||||||
|
|
||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
gScanCssState = SCAN_CSS_STATE_OFF;
|
gScanCssState = SCAN_CSS_STATE_OFF;
|
||||||
gScanFrequency = 0xFFFFFFFF;
|
gScanFrequency = 0xFFFFFFFF;
|
||||||
|
|
||||||
BK4819_PickRXFilterPathBasedOnFrequency(0xFFFFFFFF);
|
BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency);
|
||||||
BK4819_EnableFrequencyScan();
|
BK4819_EnableFrequencyScan();
|
||||||
|
|
||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
DTMF_clear_RX();
|
DTMF_clear_RX();
|
||||||
|
#endif
|
||||||
|
|
||||||
gScanDelay_10ms = scan_delay_10ms;
|
gScanDelay_10ms = scan_delay_10ms;
|
||||||
gScanCssResultCode = 0xFF;
|
gScanCssResultCode = 0xFF;
|
||||||
gScanCssResultType = 0xFF;
|
gScanCssResultType = 0xFF;
|
||||||
gScanHitCount = 0;
|
scanHitCount = 0;
|
||||||
gScanUseCssResult = false;
|
gScanUseCssResult = false;
|
||||||
g_CxCSS_TAIL_Found = false;
|
g_CxCSS_TAIL_Found = false;
|
||||||
g_CDCSS_Lost = false;
|
g_CDCSS_Lost = false;
|
||||||
gCDCSSCodeType = 0;
|
gCDCSSCodeType = 0;
|
||||||
g_CTCSS_Lost = false;
|
g_CTCSS_Lost = false;
|
||||||
#ifdef ENABLE_VOX
|
#ifdef ENABLE_VOX
|
||||||
g_VOX_Lost = false;
|
g_VOX_Lost = false;
|
||||||
#endif
|
#endif
|
||||||
g_SquelchLost = false;
|
g_SquelchLost = false;
|
||||||
gScannerEditState = 0;
|
gScannerSaveState = SCAN_SAVE_NO_PROMPT;
|
||||||
gScanProgressIndicator = 0;
|
gScanProgressIndicator = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCANNER_Stop(void)
|
void SCANNER_Stop(void)
|
||||||
{
|
{
|
||||||
const uint8_t Previous = gRestoreMrChannel;
|
if(SCANNER_IsScanning()) {
|
||||||
|
gEeprom.CROSS_BAND_RX_TX = gBackup_CROSS_BAND_RX_TX;
|
||||||
gScanStateDir = SCAN_OFF;
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
||||||
|
gFlagResetVfos = true;
|
||||||
if (!bScanKeepFrequency)
|
gUpdateStatus = true;
|
||||||
{
|
gCssBackgroundScan = false;
|
||||||
if (gNextMrChannel <= MR_CHANNEL_LAST)
|
gScanUseCssResult = false;
|
||||||
{
|
#ifdef ENABLE_VOICE
|
||||||
gEeprom.MrChannel[gEeprom.RX_VFO] = gRestoreMrChannel;
|
gAnotherVoiceID = VOICE_ID_CANCEL;
|
||||||
gEeprom.ScreenChannel[gEeprom.RX_VFO] = Previous;
|
#endif
|
||||||
|
BK4819_StopScan();
|
||||||
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gRxVfo->freq_config_RX.Frequency = gRestoreFrequency;
|
|
||||||
RADIO_ApplyOffset(gRxVfo);
|
|
||||||
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
|
|
||||||
}
|
|
||||||
RADIO_SetupRegisters(true);
|
|
||||||
gUpdateDisplay = true;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (gRxVfo->CHANNEL_SAVE > MR_CHANNEL_LAST)
|
|
||||||
{
|
void SCANNER_TimeSlice10ms(void)
|
||||||
RADIO_ApplyOffset(gRxVfo);
|
{
|
||||||
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
|
if (!SCANNER_IsScanning())
|
||||||
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_VFO, gRxVfo, 1);
|
return;
|
||||||
return;
|
|
||||||
}
|
if (gScanDelay_10ms > 0) {
|
||||||
|
gScanDelay_10ms--;
|
||||||
SETTINGS_SaveVfoIndices();
|
return;
|
||||||
|
}
|
||||||
gUpdateStatus = true;
|
|
||||||
|
if (gScannerSaveState != SCAN_SAVE_NO_PROMPT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (gScanCssState) {
|
||||||
|
case SCAN_CSS_STATE_OFF: {
|
||||||
|
// must be RF frequency scanning if we're here ?
|
||||||
|
uint32_t result;
|
||||||
|
if (!BK4819_GetFrequencyScanResult(&result))
|
||||||
|
break;
|
||||||
|
|
||||||
|
int32_t delta = result - gScanFrequency;
|
||||||
|
gScanFrequency = result;
|
||||||
|
|
||||||
|
if (delta < 0)
|
||||||
|
delta = -delta;
|
||||||
|
if (delta < 100)
|
||||||
|
scanHitCount++;
|
||||||
|
else
|
||||||
|
scanHitCount = 0;
|
||||||
|
|
||||||
|
BK4819_DisableFrequencyScan();
|
||||||
|
|
||||||
|
if (scanHitCount < 3) {
|
||||||
|
BK4819_EnableFrequencyScan();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BK4819_SetScanFrequency(gScanFrequency);
|
||||||
|
gScanCssResultCode = 0xFF;
|
||||||
|
gScanCssResultType = 0xFF;
|
||||||
|
scanHitCount = 0;
|
||||||
|
gScanUseCssResult = false;
|
||||||
|
gScanProgressIndicator = 0;
|
||||||
|
gScanCssState = SCAN_CSS_STATE_SCANNING;
|
||||||
|
|
||||||
|
if(!gCssBackgroundScan)
|
||||||
|
GUI_SelectNextDisplay(DISPLAY_SCANNER);
|
||||||
|
|
||||||
|
gUpdateStatus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
gScanDelay_10ms = scan_delay_10ms;
|
||||||
|
//gScanDelay_10ms = 1; // 10ms
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SCAN_CSS_STATE_SCANNING: {
|
||||||
|
uint32_t cdcssFreq;
|
||||||
|
uint16_t ctcssFreq;
|
||||||
|
BK4819_CssScanResult_t scanResult = BK4819_GetCxCSSScanResult(&cdcssFreq, &ctcssFreq);
|
||||||
|
if (scanResult == BK4819_CSS_RESULT_NOT_FOUND)
|
||||||
|
break;
|
||||||
|
|
||||||
|
BK4819_Disable();
|
||||||
|
|
||||||
|
if (scanResult == BK4819_CSS_RESULT_CDCSS) {
|
||||||
|
const uint8_t Code = DCS_GetCdcssCode(cdcssFreq);
|
||||||
|
if (Code != 0xFF)
|
||||||
|
{
|
||||||
|
gScanCssResultCode = Code;
|
||||||
|
gScanCssResultType = CODE_TYPE_DIGITAL;
|
||||||
|
gScanCssState = SCAN_CSS_STATE_FOUND;
|
||||||
|
gScanUseCssResult = true;
|
||||||
|
gUpdateStatus = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (scanResult == BK4819_CSS_RESULT_CTCSS) {
|
||||||
|
const uint8_t Code = DCS_GetCtcssCode(ctcssFreq);
|
||||||
|
if (Code != 0xFF) {
|
||||||
|
if (Code == gScanCssResultCode && gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) {
|
||||||
|
if (++scanHitCount >= 2) {
|
||||||
|
gScanCssState = SCAN_CSS_STATE_FOUND;
|
||||||
|
gScanUseCssResult = true;
|
||||||
|
gUpdateStatus = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
scanHitCount = 0;
|
||||||
|
|
||||||
|
gScanCssResultType = CODE_TYPE_CONTINUOUS_TONE;
|
||||||
|
gScanCssResultCode = Code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gScanCssState < SCAN_CSS_STATE_FOUND) { // scanning or off
|
||||||
|
BK4819_SetScanFrequency(gScanFrequency);
|
||||||
|
gScanDelay_10ms = scan_delay_10ms;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gCssBackgroundScan) {
|
||||||
|
gCssBackgroundScan = false;
|
||||||
|
if(gScanUseCssResult)
|
||||||
|
MENU_CssScanFound();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
GUI_SelectNextDisplay(DISPLAY_SCANNER);
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
gCssBackgroundScan = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SCANNER_TimeSlice500ms(void)
|
||||||
|
{
|
||||||
|
if (SCANNER_IsScanning() && gScannerSaveState == SCAN_SAVE_NO_PROMPT && gScanCssState < SCAN_CSS_STATE_FOUND) {
|
||||||
|
gScanProgressIndicator++;
|
||||||
|
#ifdef ENABLE_NO_CODE_SCAN_TIMEOUT
|
||||||
|
if (gScanProgressIndicator > 32) {
|
||||||
|
if (gScanCssState == SCAN_CSS_STATE_SCANNING && !gScanSingleFrequency)
|
||||||
|
gScanCssState = SCAN_CSS_STATE_FOUND;
|
||||||
|
else
|
||||||
|
gScanCssState = SCAN_CSS_STATE_FAILED;
|
||||||
|
|
||||||
|
gUpdateStatus = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
gUpdateDisplay = true;
|
||||||
|
}
|
||||||
|
else if(gCssBackgroundScan) {
|
||||||
|
gUpdateDisplay = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SCANNER_IsScanning(void)
|
||||||
|
{
|
||||||
|
return gCssBackgroundScan || (gScreenToDisplay == DISPLAY_SCANNER);
|
||||||
}
|
}
|
||||||
@@ -20,44 +20,38 @@
|
|||||||
#include "dcs.h"
|
#include "dcs.h"
|
||||||
#include "driver/keyboard.h"
|
#include "driver/keyboard.h"
|
||||||
|
|
||||||
enum SCAN_CssState_t
|
typedef enum
|
||||||
{
|
{
|
||||||
SCAN_CSS_STATE_OFF = 0,
|
SCAN_CSS_STATE_OFF,
|
||||||
SCAN_CSS_STATE_SCANNING,
|
SCAN_CSS_STATE_SCANNING,
|
||||||
SCAN_CSS_STATE_FOUND,
|
SCAN_CSS_STATE_FOUND,
|
||||||
SCAN_CSS_STATE_FAILED
|
SCAN_CSS_STATE_FAILED
|
||||||
};
|
} SCAN_CssState_t;
|
||||||
|
|
||||||
typedef enum SCAN_CssState_t SCAN_CssState_t;
|
typedef enum
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
{
|
||||||
SCAN_REV = -1,
|
SCAN_SAVE_NO_PROMPT, // saving process not initiated
|
||||||
SCAN_OFF = 0,
|
SCAN_SAVE_CHAN_SEL, // "SAVE: ", channel select prompt, actives only in channel mode
|
||||||
SCAN_FWD = +1
|
SCAN_SAVE_CHANNEL, // "SAVE?" prompt, waits for confirmation to save settings to channel, or current VFO
|
||||||
};
|
} SCAN_SaveState_t;
|
||||||
|
|
||||||
|
|
||||||
extern DCS_CodeType_t gScanCssResultType;
|
extern DCS_CodeType_t gScanCssResultType;
|
||||||
extern uint8_t gScanCssResultCode;
|
extern uint8_t gScanCssResultCode;
|
||||||
extern bool gFlagStartScan;
|
|
||||||
extern bool gFlagStopScan;
|
|
||||||
extern bool gScanSingleFrequency;
|
extern bool gScanSingleFrequency;
|
||||||
extern uint8_t gScannerEditState;
|
extern SCAN_SaveState_t gScannerSaveState;
|
||||||
extern uint8_t gScanChannel;
|
extern uint8_t gScanChannel;
|
||||||
extern uint32_t gScanFrequency;
|
extern uint32_t gScanFrequency;
|
||||||
extern bool gScanPauseMode;
|
|
||||||
extern SCAN_CssState_t gScanCssState;
|
extern SCAN_CssState_t gScanCssState;
|
||||||
extern volatile bool gScheduleScanListen;
|
|
||||||
extern volatile uint16_t gScanPauseDelayIn_10ms;
|
|
||||||
extern uint8_t gScanProgressIndicator;
|
extern uint8_t gScanProgressIndicator;
|
||||||
extern uint8_t gScanHitCount;
|
|
||||||
extern bool gScanUseCssResult;
|
extern bool gScanUseCssResult;
|
||||||
extern int8_t gScanStateDir;
|
|
||||||
extern bool bScanKeepFrequency;
|
|
||||||
|
|
||||||
void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
|
void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
|
||||||
void SCANNER_Start(void);
|
void SCANNER_Start(bool singleFreq);
|
||||||
void SCANNER_Stop(void);
|
void SCANNER_Stop(void);
|
||||||
|
void SCANNER_TimeSlice10ms(void);
|
||||||
|
void SCANNER_TimeSlice500ms(void);
|
||||||
|
bool SCANNER_IsScanning(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
463
app/spectrum.c
463
app/spectrum.c
@@ -13,28 +13,27 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
#include "app/spectrum.h"
|
||||||
|
#include "am_fix.h"
|
||||||
|
#include "audio.h"
|
||||||
|
|
||||||
#include "../app/spectrum.h"
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
#include "chFrScanner.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "driver/backlight.h"
|
||||||
|
#include "frequencies.h"
|
||||||
|
#include "ui/helper.h"
|
||||||
|
#include "ui/main.h"
|
||||||
|
|
||||||
struct FrequencyBandInfo {
|
struct FrequencyBandInfo {
|
||||||
uint32_t lower;
|
uint32_t lower;
|
||||||
uint32_t upper;
|
uint32_t upper;
|
||||||
uint32_t middle;
|
uint32_t middle;
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct FrequencyBandInfo FrequencyBandTable[7] = {
|
#define F_MIN frequencyBandTable[0].lower
|
||||||
[BAND1_50MHz ] = {.lower = 1600000, .middle = 6500000, .upper = 7600000},
|
#define F_MAX frequencyBandTable[BAND_N_ELEM - 1].upper
|
||||||
[BAND2_108MHz] = {.lower = 10800000, .middle = 12200000, .upper = 13599990},
|
|
||||||
[BAND3_136MHz] = {.lower = 13600000, .middle = 15000000, .upper = 17399990},
|
|
||||||
[BAND4_174MHz] = {.lower = 17400000, .middle = 26000000, .upper = 34999990},
|
|
||||||
[BAND5_350MHz] = {.lower = 35000000, .middle = 37000000, .upper = 39999990},
|
|
||||||
[BAND6_400MHz] = {.lower = 40000000, .middle = 43500000, .upper = 46999990},
|
|
||||||
[BAND7_470MHz] = {.lower = 47000000, .middle = 55000000, .upper = 130000000},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define F_MIN FrequencyBandTable[0].lower
|
|
||||||
#define F_MAX FrequencyBandTable[ARRAY_SIZE(FrequencyBandTable) - 1].upper
|
|
||||||
|
|
||||||
const uint16_t RSSI_MAX_VALUE = 65535;
|
const uint16_t RSSI_MAX_VALUE = 65535;
|
||||||
|
|
||||||
@@ -50,6 +49,7 @@ bool redrawScreen = false;
|
|||||||
bool newScanStart = true;
|
bool newScanStart = true;
|
||||||
bool preventKeypress = true;
|
bool preventKeypress = true;
|
||||||
bool audioState = true;
|
bool audioState = true;
|
||||||
|
bool lockAGC = false;
|
||||||
|
|
||||||
State currentState = SPECTRUM, previousState = SPECTRUM;
|
State currentState = SPECTRUM, previousState = SPECTRUM;
|
||||||
|
|
||||||
@@ -57,41 +57,45 @@ PeakInfo peak;
|
|||||||
ScanInfo scanInfo;
|
ScanInfo scanInfo;
|
||||||
KeyboardState kbd = {KEY_INVALID, KEY_INVALID, 0};
|
KeyboardState kbd = {KEY_INVALID, KEY_INVALID, 0};
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
static uint16_t blacklistFreqs[15];
|
||||||
|
static uint8_t blacklistFreqsIdx;
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *bwOptions[] = {" 25k", "12.5k", "6.25k"};
|
const char *bwOptions[] = {" 25k", "12.5k", "6.25k"};
|
||||||
const char *modulationTypeOptions[] = {" FM", " AM", "USB"};
|
|
||||||
const uint8_t modulationTypeTuneSteps[] = {100, 50, 10};
|
const uint8_t modulationTypeTuneSteps[] = {100, 50, 10};
|
||||||
const uint8_t modTypeReg47Values[] = {1, 7, 5};
|
const uint8_t modTypeReg47Values[] = {1, 7, 5};
|
||||||
|
|
||||||
SpectrumSettings settings = {stepsCount: STEPS_64,
|
SpectrumSettings settings = {.stepsCount = STEPS_64,
|
||||||
scanStepIndex: S_STEP_25_0kHz,
|
.scanStepIndex = S_STEP_25_0kHz,
|
||||||
frequencyChangeStep: 80000,
|
.frequencyChangeStep = 80000,
|
||||||
scanDelay: 3200,
|
.scanDelay = 3200,
|
||||||
rssiTriggerLevel: 150,
|
.rssiTriggerLevel = 150,
|
||||||
backlightState: true,
|
.backlightState = true,
|
||||||
bw: BK4819_FILTER_BW_WIDE,
|
.bw = BK4819_FILTER_BW_WIDE,
|
||||||
listenBw: BK4819_FILTER_BW_WIDE,
|
.listenBw = BK4819_FILTER_BW_WIDE,
|
||||||
modulationType: false,
|
.modulationType = false,
|
||||||
dbMin: -130,
|
.dbMin = -130,
|
||||||
dbMax: -50};
|
.dbMax = -50};
|
||||||
|
|
||||||
uint32_t fMeasure = 0;
|
uint32_t fMeasure = 0;
|
||||||
uint32_t currentFreq, tempFreq;
|
uint32_t currentFreq, tempFreq;
|
||||||
uint16_t rssiHistory[128] = {};
|
uint16_t rssiHistory[128];
|
||||||
|
int vfo;
|
||||||
uint8_t freqInputIndex = 0;
|
uint8_t freqInputIndex = 0;
|
||||||
uint8_t freqInputDotIndex = 0;
|
uint8_t freqInputDotIndex = 0;
|
||||||
KEY_Code_t freqInputArr[10];
|
KEY_Code_t freqInputArr[10];
|
||||||
char freqInputString[11] = "----------\0"; // XXXX.XXXXX\0
|
char freqInputString[11];
|
||||||
|
|
||||||
uint8_t menuState = 0;
|
uint8_t menuState = 0;
|
||||||
uint16_t listenT = 0;
|
uint16_t listenT = 0;
|
||||||
|
|
||||||
RegisterSpec registerSpecs[] = {
|
RegisterSpec registerSpecs[] = {
|
||||||
{},
|
{},
|
||||||
{"LNAs", 0x13, 8, 0b11, 1},
|
{"LNAs", BK4819_REG_13, 8, 0b11, 1},
|
||||||
{"LNA", 0x13, 5, 0b111, 1},
|
{"LNA", BK4819_REG_13, 5, 0b111, 1},
|
||||||
{"PGA", 0x13, 0, 0b111, 1},
|
{"PGA", BK4819_REG_13, 0, 0b111, 1},
|
||||||
{"IF", 0x3D, 0, 0xFFFF, 0x2aaa},
|
{"IF", BK4819_REG_3D, 0, 0xFFFF, 0x2aaa},
|
||||||
// {"MIX", 0x13, 3, 0b11, 1}, // TODO: hidden
|
// {"MIX", 0x13, 3, 0b11, 1}, // TODO: hidden
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -108,26 +112,37 @@ static uint8_t DBm2S(int dbm) {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Rssi2DBm(uint16_t rssi) { return (rssi >> 1) - 160; }
|
static int Rssi2DBm(uint16_t rssi) {
|
||||||
|
return (rssi / 2) - 160 + dBmCorrTable[gRxVfo->Band];
|
||||||
|
}
|
||||||
|
|
||||||
static uint16_t GetRegMenuValue(uint8_t st) {
|
static uint16_t GetRegMenuValue(uint8_t st) {
|
||||||
RegisterSpec s = registerSpecs[st];
|
RegisterSpec s = registerSpecs[st];
|
||||||
return (BK4819_ReadRegister(s.num) >> s.offset) & s.maxValue;
|
return (BK4819_ReadRegister(s.num) >> s.offset) & s.mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LockAGC()
|
||||||
|
{
|
||||||
|
RADIO_SetupAGC(settings.modulationType==MODULATION_AM, lockAGC);
|
||||||
|
lockAGC = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetRegMenuValue(uint8_t st, bool add) {
|
static void SetRegMenuValue(uint8_t st, bool add) {
|
||||||
uint16_t v = GetRegMenuValue(st);
|
uint16_t v = GetRegMenuValue(st);
|
||||||
RegisterSpec s = registerSpecs[st];
|
RegisterSpec s = registerSpecs[st];
|
||||||
|
|
||||||
|
if(s.num == BK4819_REG_13)
|
||||||
|
LockAGC();
|
||||||
|
|
||||||
uint16_t reg = BK4819_ReadRegister(s.num);
|
uint16_t reg = BK4819_ReadRegister(s.num);
|
||||||
if (add && v <= s.maxValue - s.inc) {
|
if (add && v <= s.mask - s.inc) {
|
||||||
v += s.inc;
|
v += s.inc;
|
||||||
} else if (!add && v >= 0 + s.inc) {
|
} else if (!add && v >= 0 + s.inc) {
|
||||||
v -= s.inc;
|
v -= s.inc;
|
||||||
}
|
}
|
||||||
// TODO: use max value for bits count in max value, or reset by additional
|
// TODO: use max value for bits count in max value, or reset by additional
|
||||||
// mask in spec
|
// mask in spec
|
||||||
reg &= ~(s.maxValue << s.offset);
|
reg &= ~(s.mask << s.offset);
|
||||||
BK4819_WriteRegister(s.num, reg | (v << s.offset));
|
BK4819_WriteRegister(s.num, reg | (v << s.offset));
|
||||||
redrawScreen = true;
|
redrawScreen = true;
|
||||||
}
|
}
|
||||||
@@ -135,21 +150,13 @@ static void SetRegMenuValue(uint8_t st, bool add) {
|
|||||||
// GUI functions
|
// GUI functions
|
||||||
|
|
||||||
static void PutPixel(uint8_t x, uint8_t y, bool fill) {
|
static void PutPixel(uint8_t x, uint8_t y, bool fill) {
|
||||||
if (fill) {
|
UI_DrawPixelBuffer(gFrameBuffer, x, y, fill);
|
||||||
gFrameBuffer[y >> 3][x] |= 1 << (y & 7);
|
|
||||||
} else {
|
|
||||||
gFrameBuffer[y >> 3][x] &= ~(1 << (y & 7));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
static void PutPixelStatus(uint8_t x, uint8_t y, bool fill) {
|
static void PutPixelStatus(uint8_t x, uint8_t y, bool fill) {
|
||||||
if (fill) {
|
UI_DrawPixelBuffer(&gStatusLine, x, y, fill);
|
||||||
gStatusLine[x] |= 1 << y;
|
|
||||||
} else {
|
|
||||||
gStatusLine[x] &= ~(1 << y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawHLine(int sy, int ey, int nx, bool fill) {
|
static void DrawVLine(int sy, int ey, int nx, bool fill) {
|
||||||
for (int i = sy; i <= ey; i++) {
|
for (int i = sy; i <= ey; i++) {
|
||||||
if (i < 56 && nx < 128) {
|
if (i < 56 && nx < 128) {
|
||||||
PutPixel(nx, i, fill);
|
PutPixel(nx, i, fill);
|
||||||
@@ -215,35 +222,23 @@ static void ToggleAFBit(bool on) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void BackupRegisters() {
|
static void BackupRegisters() {
|
||||||
R30 = BK4819_ReadRegister(0x30);
|
R30 = BK4819_ReadRegister(BK4819_REG_30);
|
||||||
R37 = BK4819_ReadRegister(0x37);
|
R37 = BK4819_ReadRegister(BK4819_REG_37);
|
||||||
R3D = BK4819_ReadRegister(0x3D);
|
R3D = BK4819_ReadRegister(BK4819_REG_3D);
|
||||||
R43 = BK4819_ReadRegister(0x43);
|
R43 = BK4819_ReadRegister(BK4819_REG_43);
|
||||||
R47 = BK4819_ReadRegister(0x47);
|
R47 = BK4819_ReadRegister(BK4819_REG_47);
|
||||||
R48 = BK4819_ReadRegister(0x48);
|
R48 = BK4819_ReadRegister(BK4819_REG_48);
|
||||||
R7E = BK4819_ReadRegister(0x7E);
|
R7E = BK4819_ReadRegister(BK4819_REG_7E);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RestoreRegisters() {
|
static void RestoreRegisters() {
|
||||||
BK4819_WriteRegister(0x30, R30);
|
BK4819_WriteRegister(BK4819_REG_30, R30);
|
||||||
BK4819_WriteRegister(0x37, R37);
|
BK4819_WriteRegister(BK4819_REG_37, R37);
|
||||||
BK4819_WriteRegister(0x3D, R3D);
|
BK4819_WriteRegister(BK4819_REG_3D, R3D);
|
||||||
BK4819_WriteRegister(0x43, R43);
|
BK4819_WriteRegister(BK4819_REG_43, R43);
|
||||||
BK4819_WriteRegister(0x47, R47);
|
BK4819_WriteRegister(BK4819_REG_47, R47);
|
||||||
BK4819_WriteRegister(0x48, R48);
|
BK4819_WriteRegister(BK4819_REG_48, R48);
|
||||||
BK4819_WriteRegister(0x7E, R7E);
|
BK4819_WriteRegister(BK4819_REG_7E, R7E);
|
||||||
}
|
|
||||||
|
|
||||||
static void SetModulation(ModulationType type) {
|
|
||||||
RestoreRegisters();
|
|
||||||
uint16_t reg = BK4819_ReadRegister(BK4819_REG_47);
|
|
||||||
reg &= ~(0b111 << 8);
|
|
||||||
BK4819_WriteRegister(BK4819_REG_47, reg | (modTypeReg47Values[type] << 8));
|
|
||||||
if (type == MOD_USB) {
|
|
||||||
BK4819_WriteRegister(0x3D, 0b0010101101000101);
|
|
||||||
BK4819_WriteRegister(BK4819_REG_37, 0x160F);
|
|
||||||
BK4819_WriteRegister(0x48, 0b0000001110101000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ToggleAFDAC(bool on) {
|
static void ToggleAFDAC(bool on) {
|
||||||
@@ -274,12 +269,24 @@ static void ResetPeak() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IsCenterMode() { return settings.scanStepIndex < S_STEP_2_5kHz; }
|
bool IsCenterMode() { return settings.scanStepIndex < S_STEP_2_5kHz; }
|
||||||
uint8_t GetStepsCount() { return 128 >> settings.stepsCount; }
|
// scan step in 0.01khz
|
||||||
uint16_t GetScanStep() { return scanStepValues[settings.scanStepIndex]; }
|
uint16_t GetScanStep() { return scanStepValues[settings.scanStepIndex]; }
|
||||||
|
|
||||||
|
uint16_t GetStepsCount()
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
if(gScanRangeStart) {
|
||||||
|
return (gScanRangeStop - gScanRangeStart) / GetScanStep();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 128 >> settings.stepsCount;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t GetBW() { return GetStepsCount() * GetScanStep(); }
|
uint32_t GetBW() { return GetStepsCount() * GetScanStep(); }
|
||||||
uint32_t GetFStart() {
|
uint32_t GetFStart() {
|
||||||
return IsCenterMode() ? currentFreq - (GetBW() >> 1) : currentFreq;
|
return IsCenterMode() ? currentFreq - (GetBW() >> 1) : currentFreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GetFEnd() { return currentFreq + GetBW(); }
|
uint32_t GetFEnd() { return currentFreq + GetBW(); }
|
||||||
|
|
||||||
static void TuneToPeak() {
|
static void TuneToPeak() {
|
||||||
@@ -305,7 +312,12 @@ uint16_t GetRssi() {
|
|||||||
while ((BK4819_ReadRegister(0x63) & 0b11111111) >= 255) {
|
while ((BK4819_ReadRegister(0x63) & 0b11111111) >= 255) {
|
||||||
SYSTICK_DelayUs(100);
|
SYSTICK_DelayUs(100);
|
||||||
}
|
}
|
||||||
return BK4819_GetRSSI();
|
uint16_t rssi = BK4819_GetRSSI();
|
||||||
|
#ifdef ENABLE_AM_FIX
|
||||||
|
if(settings.modulationType==MODULATION_AM && gSetting_AM_fix)
|
||||||
|
rssi += AM_fix_get_gain_diff()*2;
|
||||||
|
#endif
|
||||||
|
return rssi;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ToggleAudio(bool on) {
|
static void ToggleAudio(bool on) {
|
||||||
@@ -314,16 +326,17 @@ static void ToggleAudio(bool on) {
|
|||||||
}
|
}
|
||||||
audioState = on;
|
audioState = on;
|
||||||
if (on) {
|
if (on) {
|
||||||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOn();
|
||||||
} else {
|
} else {
|
||||||
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOff();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ToggleRX(bool on) {
|
static void ToggleRX(bool on) {
|
||||||
isListening = on;
|
isListening = on;
|
||||||
|
|
||||||
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, on);
|
RADIO_SetupAGC(on, lockAGC);
|
||||||
|
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, on);
|
||||||
|
|
||||||
ToggleAudio(on);
|
ToggleAudio(on);
|
||||||
ToggleAFDAC(on);
|
ToggleAFDAC(on);
|
||||||
@@ -360,6 +373,10 @@ static void ResetBlacklist() {
|
|||||||
if (rssiHistory[i] == RSSI_MAX_VALUE)
|
if (rssiHistory[i] == RSSI_MAX_VALUE)
|
||||||
rssiHistory[i] = 0;
|
rssiHistory[i] = 0;
|
||||||
}
|
}
|
||||||
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
memset(blacklistFreqs, 0, sizeof(blacklistFreqs));
|
||||||
|
blacklistFreqsIdx = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RelaunchScan() {
|
static void RelaunchScan() {
|
||||||
@@ -406,15 +423,41 @@ static void UpdatePeakInfo() {
|
|||||||
UpdatePeakInfoForce();
|
UpdatePeakInfoForce();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Measure() { rssiHistory[scanInfo.i] = scanInfo.rssi = GetRssi(); }
|
static void Measure()
|
||||||
|
{
|
||||||
|
uint16_t rssi = scanInfo.rssi = GetRssi();
|
||||||
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
if(scanInfo.measurementsCount > 128) {
|
||||||
|
uint8_t idx = (uint32_t)ARRAY_SIZE(rssiHistory) * 1000 / scanInfo.measurementsCount * scanInfo.i / 1000;
|
||||||
|
if(rssiHistory[idx] < rssi || isListening)
|
||||||
|
rssiHistory[idx] = rssi;
|
||||||
|
rssiHistory[(idx+1)%128] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
rssiHistory[scanInfo.i] = rssi;
|
||||||
|
}
|
||||||
|
|
||||||
// Update things by keypress
|
// Update things by keypress
|
||||||
|
|
||||||
|
static uint16_t dbm2rssi(int dBm) {
|
||||||
|
return (dBm + 160 - dBmCorrTable[gRxVfo->Band]) * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ClampRssiTriggerLevel() {
|
||||||
|
settings.rssiTriggerLevel =
|
||||||
|
clamp(settings.rssiTriggerLevel, dbm2rssi(settings.dbMin),
|
||||||
|
dbm2rssi(settings.dbMax));
|
||||||
|
}
|
||||||
|
|
||||||
static void UpdateRssiTriggerLevel(bool inc) {
|
static void UpdateRssiTriggerLevel(bool inc) {
|
||||||
if (inc)
|
if (inc)
|
||||||
settings.rssiTriggerLevel += 2;
|
settings.rssiTriggerLevel += 2;
|
||||||
else
|
else
|
||||||
settings.rssiTriggerLevel -= 2;
|
settings.rssiTriggerLevel -= 2;
|
||||||
|
|
||||||
|
ClampRssiTriggerLevel();
|
||||||
|
|
||||||
redrawScreen = true;
|
redrawScreen = true;
|
||||||
redrawStatus = true;
|
redrawStatus = true;
|
||||||
}
|
}
|
||||||
@@ -427,6 +470,8 @@ static void UpdateDBMax(bool inc) {
|
|||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClampRssiTriggerLevel();
|
||||||
redrawStatus = true;
|
redrawStatus = true;
|
||||||
redrawScreen = true;
|
redrawScreen = true;
|
||||||
SYSTEM_DelayMs(20);
|
SYSTEM_DelayMs(20);
|
||||||
@@ -483,12 +528,14 @@ static void UpdateFreqChangeStep(bool inc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ToggleModulation() {
|
static void ToggleModulation() {
|
||||||
if (settings.modulationType < MOD_USB) {
|
if (settings.modulationType < MODULATION_UKNOWN - 1) {
|
||||||
settings.modulationType++;
|
settings.modulationType++;
|
||||||
} else {
|
} else {
|
||||||
settings.modulationType = MOD_FM;
|
settings.modulationType = MODULATION_FM;
|
||||||
}
|
}
|
||||||
SetModulation(settings.modulationType);
|
RADIO_SetModulation(settings.modulationType);
|
||||||
|
|
||||||
|
RelaunchScan();
|
||||||
redrawScreen = true;
|
redrawScreen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,9 +551,9 @@ static void ToggleListeningBW() {
|
|||||||
static void ToggleBacklight() {
|
static void ToggleBacklight() {
|
||||||
settings.backlightState = !settings.backlightState;
|
settings.backlightState = !settings.backlightState;
|
||||||
if (settings.backlightState) {
|
if (settings.backlightState) {
|
||||||
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
|
BACKLIGHT_TurnOn();
|
||||||
} else {
|
} else {
|
||||||
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
|
BACKLIGHT_TurnOff();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,6 +595,8 @@ static void UpdateFreqInput(KEY_Code_t key) {
|
|||||||
}
|
}
|
||||||
if (key == KEY_EXIT) {
|
if (key == KEY_EXIT) {
|
||||||
freqInputIndex--;
|
freqInputIndex--;
|
||||||
|
if (freqInputDotIndex == freqInputIndex)
|
||||||
|
freqInputDotIndex = 0;
|
||||||
} else {
|
} else {
|
||||||
freqInputArr[freqInputIndex++] = key;
|
freqInputArr[freqInputIndex++] = key;
|
||||||
}
|
}
|
||||||
@@ -561,7 +610,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-KEY_0 : '.';
|
freqInputString[i] = digitKey <= KEY_9 ? '0' + digitKey - KEY_0 : '.';
|
||||||
} else {
|
} else {
|
||||||
freqInputString[i] = '-';
|
freqInputString[i] = '-';
|
||||||
}
|
}
|
||||||
@@ -569,14 +618,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]-KEY_0) * 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]-KEY_0) * base;
|
tempFreq += (freqInputArr[i] - KEY_0) * base;
|
||||||
base /= 10;
|
base /= 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -584,12 +633,25 @@ static void UpdateFreqInput(KEY_Code_t key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void Blacklist() {
|
static void Blacklist() {
|
||||||
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
blacklistFreqs[blacklistFreqsIdx++ % ARRAY_SIZE(blacklistFreqs)] = peak.i;
|
||||||
|
#endif
|
||||||
rssiHistory[peak.i] = RSSI_MAX_VALUE;
|
rssiHistory[peak.i] = RSSI_MAX_VALUE;
|
||||||
ResetPeak();
|
ResetPeak();
|
||||||
ToggleRX(false);
|
ToggleRX(false);
|
||||||
newScanStart = true;
|
ResetScanStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
static bool IsBlacklisted(uint16_t idx)
|
||||||
|
{
|
||||||
|
for(uint8_t i = 0; i < ARRAY_SIZE(blacklistFreqs); i++)
|
||||||
|
if(blacklistFreqs[i] == idx)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Draw things
|
// Draw things
|
||||||
|
|
||||||
// applied x2 to prevent initial rounding
|
// applied x2 to prevent initial rounding
|
||||||
@@ -600,7 +662,7 @@ uint8_t Rssi2PX(uint16_t rssi, uint8_t pxMin, uint8_t pxMax) {
|
|||||||
|
|
||||||
const uint8_t PX_RANGE = pxMax - pxMin;
|
const uint8_t PX_RANGE = pxMax - pxMin;
|
||||||
|
|
||||||
int dbm = clamp(rssi - (160 << 1), DB_MIN, DB_MAX);
|
int dbm = clamp(Rssi2DBm(rssi) << 1, DB_MIN, DB_MAX);
|
||||||
|
|
||||||
return ((dbm - DB_MIN) * PX_RANGE + DB_RANGE / 2) / DB_RANGE + pxMin;
|
return ((dbm - DB_MIN) * PX_RANGE + DB_RANGE / 2) / DB_RANGE + pxMin;
|
||||||
}
|
}
|
||||||
@@ -613,7 +675,7 @@ static void DrawSpectrum() {
|
|||||||
for (uint8_t x = 0; x < 128; ++x) {
|
for (uint8_t x = 0; x < 128; ++x) {
|
||||||
uint16_t rssi = rssiHistory[x >> settings.stepsCount];
|
uint16_t rssi = rssiHistory[x >> settings.stepsCount];
|
||||||
if (rssi != RSSI_MAX_VALUE) {
|
if (rssi != RSSI_MAX_VALUE) {
|
||||||
DrawHLine(Rssi2Y(rssi), DrawingEndY, x, true);
|
DrawVLine(Rssi2Y(rssi), DrawingEndY, x, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -627,50 +689,36 @@ static void DrawStatus() {
|
|||||||
#endif
|
#endif
|
||||||
GUI_DisplaySmallest(String, 0, 1, true, true);
|
GUI_DisplaySmallest(String, 0, 1, true, true);
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryCheckCounter++ % 4],
|
||||||
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[i], &gBatteryCurrent);
|
&gBatteryCurrent);
|
||||||
|
|
||||||
|
uint16_t voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] +
|
||||||
|
gBatteryVoltages[2] + gBatteryVoltages[3]) /
|
||||||
|
4 * 760 / gBatteryCalibration[3];
|
||||||
|
|
||||||
|
unsigned perc = BATTERY_VoltsToPercent(voltage);
|
||||||
|
|
||||||
|
// sprintf(String, "%d %d", voltage, perc);
|
||||||
|
// GUI_DisplaySmallest(String, 48, 1, true, true);
|
||||||
|
|
||||||
|
gStatusLine[116] = 0b00011100;
|
||||||
|
gStatusLine[117] = 0b00111110;
|
||||||
|
for (int i = 118; i <= 126; i++) {
|
||||||
|
gStatusLine[i] = 0b00100010;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Voltage;
|
for (unsigned i = 127; i >= 118; i--) {
|
||||||
uint8_t v = 0;
|
if (127 - i <= (perc + 5) * 9 / 100) {
|
||||||
|
gStatusLine[i] = 0b00111110;
|
||||||
Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] +
|
|
||||||
gBatteryVoltages[3]) /
|
|
||||||
4;
|
|
||||||
|
|
||||||
if (gBatteryCalibration[5] < Voltage) {
|
|
||||||
v = 5;
|
|
||||||
} else if (gBatteryCalibration[4] < Voltage) {
|
|
||||||
v = 5;
|
|
||||||
} else if (gBatteryCalibration[3] < Voltage) {
|
|
||||||
v = 4;
|
|
||||||
} else if (gBatteryCalibration[2] < Voltage) {
|
|
||||||
v = 3;
|
|
||||||
} else if (gBatteryCalibration[1] < Voltage) {
|
|
||||||
v = 2;
|
|
||||||
} else if (gBatteryCalibration[0] < Voltage) {
|
|
||||||
v = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
gStatusLine[127] = 0b01111110;
|
|
||||||
for (int i = 126; i >= 116; i--) {
|
|
||||||
gStatusLine[i] = 0b01000010;
|
|
||||||
}
|
|
||||||
v <<= 1;
|
|
||||||
for (int i = 125; i >= 116; i--) {
|
|
||||||
if (126 - i <= v) {
|
|
||||||
gStatusLine[i + 2] = 0b01111110;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gStatusLine[117] = 0b01111110;
|
|
||||||
gStatusLine[116] = 0b00011000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawF(uint32_t f) {
|
static void DrawF(uint32_t f) {
|
||||||
sprintf(String, "%u.%05u", f / 100000, f % 100000);
|
sprintf(String, "%u.%05u", f / 100000, f % 100000);
|
||||||
UI_PrintStringSmall(String, 8, 127, 0);
|
UI_PrintStringSmall(String, 8, 127, 0);
|
||||||
|
|
||||||
sprintf(String, "%s", modulationTypeOptions[settings.modulationType]);
|
sprintf(String, "%3s", gModulationStr[settings.modulationType]);
|
||||||
GUI_DisplaySmallest(String, 116, 1, false, true);
|
GUI_DisplaySmallest(String, 116, 1, false, true);
|
||||||
sprintf(String, "%s", bwOptions[settings.listenBw]);
|
sprintf(String, "%s", bwOptions[settings.listenBw]);
|
||||||
GUI_DisplaySmallest(String, 108, 7, false, true);
|
GUI_DisplaySmallest(String, 108, 7, false, true);
|
||||||
@@ -686,7 +734,7 @@ static void DrawNums() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (IsCenterMode()) {
|
if (IsCenterMode()) {
|
||||||
sprintf(String, "%u.%05u \xB1%u.%02uk", currentFreq / 100000,
|
sprintf(String, "%u.%05u \x7F%u.%02uk", currentFreq / 100000,
|
||||||
currentFreq % 100000, settings.frequencyChangeStep / 100,
|
currentFreq % 100000, settings.frequencyChangeStep / 100,
|
||||||
settings.frequencyChangeStep % 100);
|
settings.frequencyChangeStep % 100);
|
||||||
GUI_DisplaySmallest(String, 36, 49, false, true);
|
GUI_DisplaySmallest(String, 36, 49, false, true);
|
||||||
@@ -694,7 +742,7 @@ static void DrawNums() {
|
|||||||
sprintf(String, "%u.%05u", GetFStart() / 100000, GetFStart() % 100000);
|
sprintf(String, "%u.%05u", GetFStart() / 100000, GetFStart() % 100000);
|
||||||
GUI_DisplaySmallest(String, 0, 49, false, true);
|
GUI_DisplaySmallest(String, 0, 49, false, true);
|
||||||
|
|
||||||
sprintf(String, "\xB1%u.%02uk", settings.frequencyChangeStep / 100,
|
sprintf(String, "\x7F%u.%02uk", settings.frequencyChangeStep / 100,
|
||||||
settings.frequencyChangeStep % 100);
|
settings.frequencyChangeStep % 100);
|
||||||
GUI_DisplaySmallest(String, 48, 49, false, true);
|
GUI_DisplaySmallest(String, 48, 49, false, true);
|
||||||
|
|
||||||
@@ -713,9 +761,11 @@ static void DrawRssiTriggerLevel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void DrawTicks() {
|
static void DrawTicks() {
|
||||||
uint32_t f = GetFStart() % 100000;
|
uint32_t f = GetFStart();
|
||||||
uint32_t step = GetScanStep();
|
uint32_t span = GetFEnd() - GetFStart();
|
||||||
for (uint8_t i = 0; i < 128; i += (1 << settings.stepsCount), f += step) {
|
uint32_t step = span / 128;
|
||||||
|
for (uint8_t i = 0; i < 128; i += (1 << settings.stepsCount)) {
|
||||||
|
f = GetFStart() + span * i / 128;
|
||||||
uint8_t barValue = 0b00000001;
|
uint8_t barValue = 0b00000001;
|
||||||
(f % 10000) < step && (barValue |= 0b00000010);
|
(f % 10000) < step && (barValue |= 0b00000010);
|
||||||
(f % 50000) < step && (barValue |= 0b00000100);
|
(f % 50000) < step && (barValue |= 0b00000100);
|
||||||
@@ -726,19 +776,13 @@ static void DrawTicks() {
|
|||||||
|
|
||||||
// center
|
// center
|
||||||
if (IsCenterMode()) {
|
if (IsCenterMode()) {
|
||||||
gFrameBuffer[5][62] = 0x80;
|
memset(gFrameBuffer[5] + 62, 0x80, 5);
|
||||||
gFrameBuffer[5][63] = 0x80;
|
|
||||||
gFrameBuffer[5][64] = 0xff;
|
gFrameBuffer[5][64] = 0xff;
|
||||||
gFrameBuffer[5][65] = 0x80;
|
|
||||||
gFrameBuffer[5][66] = 0x80;
|
|
||||||
} else {
|
} else {
|
||||||
|
memset(gFrameBuffer[5] + 1, 0x80, 3);
|
||||||
|
memset(gFrameBuffer[5] + 124, 0x80, 3);
|
||||||
|
|
||||||
gFrameBuffer[5][0] = 0xff;
|
gFrameBuffer[5][0] = 0xff;
|
||||||
gFrameBuffer[5][1] = 0x80;
|
|
||||||
gFrameBuffer[5][2] = 0x80;
|
|
||||||
gFrameBuffer[5][3] = 0x80;
|
|
||||||
gFrameBuffer[5][124] = 0x80;
|
|
||||||
gFrameBuffer[5][125] = 0x80;
|
|
||||||
gFrameBuffer[5][126] = 0x80;
|
|
||||||
gFrameBuffer[5][127] = 0xff;
|
gFrameBuffer[5][127] = 0xff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -773,10 +817,16 @@ static void OnKeyDown(uint8_t key) {
|
|||||||
UpdateFreqChangeStep(false);
|
UpdateFreqChangeStep(false);
|
||||||
break;
|
break;
|
||||||
case KEY_UP:
|
case KEY_UP:
|
||||||
UpdateCurrentFreq(true);
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
if(!gScanRangeStart)
|
||||||
|
#endif
|
||||||
|
UpdateCurrentFreq(true);
|
||||||
break;
|
break;
|
||||||
case KEY_DOWN:
|
case KEY_DOWN:
|
||||||
UpdateCurrentFreq(false);
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
if(!gScanRangeStart)
|
||||||
|
#endif
|
||||||
|
UpdateCurrentFreq(false);
|
||||||
break;
|
break;
|
||||||
case KEY_SIDE1:
|
case KEY_SIDE1:
|
||||||
Blacklist();
|
Blacklist();
|
||||||
@@ -788,7 +838,10 @@ static void OnKeyDown(uint8_t key) {
|
|||||||
UpdateRssiTriggerLevel(false);
|
UpdateRssiTriggerLevel(false);
|
||||||
break;
|
break;
|
||||||
case KEY_5:
|
case KEY_5:
|
||||||
FreqInput();
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
if(!gScanRangeStart)
|
||||||
|
#endif
|
||||||
|
FreqInput();
|
||||||
break;
|
break;
|
||||||
case KEY_0:
|
case KEY_0:
|
||||||
ToggleModulation();
|
ToggleModulation();
|
||||||
@@ -797,7 +850,10 @@ static void OnKeyDown(uint8_t key) {
|
|||||||
ToggleListeningBW();
|
ToggleListeningBW();
|
||||||
break;
|
break;
|
||||||
case KEY_4:
|
case KEY_4:
|
||||||
ToggleStepsCount();
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
if(!gScanRangeStart)
|
||||||
|
#endif
|
||||||
|
ToggleStepsCount();
|
||||||
break;
|
break;
|
||||||
case KEY_SIDE2:
|
case KEY_SIDE2:
|
||||||
ToggleBacklight();
|
ToggleBacklight();
|
||||||
@@ -905,8 +961,8 @@ void OnKeyDownStill(KEY_Code_t key) {
|
|||||||
break;
|
break;
|
||||||
case KEY_PTT:
|
case KEY_PTT:
|
||||||
// TODO: start transmit
|
// TODO: start transmit
|
||||||
/* BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, false);
|
/* BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
|
||||||
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, true); */
|
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); */
|
||||||
break;
|
break;
|
||||||
case KEY_MENU:
|
case KEY_MENU:
|
||||||
if (menuState == ARRAY_SIZE(registerSpecs) - 1) {
|
if (menuState == ARRAY_SIZE(registerSpecs) - 1) {
|
||||||
@@ -919,6 +975,7 @@ void OnKeyDownStill(KEY_Code_t key) {
|
|||||||
case KEY_EXIT:
|
case KEY_EXIT:
|
||||||
if (!menuState) {
|
if (!menuState) {
|
||||||
SetState(SPECTRUM);
|
SetState(SPECTRUM);
|
||||||
|
lockAGC = false;
|
||||||
monitorMode = false;
|
monitorMode = false;
|
||||||
RelaunchScan();
|
RelaunchScan();
|
||||||
break;
|
break;
|
||||||
@@ -930,9 +987,7 @@ void OnKeyDownStill(KEY_Code_t key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RenderFreqInput() {
|
static void RenderFreqInput() { UI_PrintString(freqInputString, 2, 127, 0, 8); }
|
||||||
UI_PrintString(freqInputString, 2, 127, 0, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void RenderStatus() {
|
static void RenderStatus() {
|
||||||
memset(gStatusLine, 0, sizeof(gStatusLine));
|
memset(gStatusLine, 0, sizeof(gStatusLine));
|
||||||
@@ -942,7 +997,7 @@ static void RenderStatus() {
|
|||||||
|
|
||||||
static void RenderSpectrum() {
|
static void RenderSpectrum() {
|
||||||
DrawTicks();
|
DrawTicks();
|
||||||
DrawArrow(peak.i << settings.stepsCount);
|
DrawArrow(128u * peak.i / GetStepsCount());
|
||||||
DrawSpectrum();
|
DrawSpectrum();
|
||||||
DrawRssiTriggerLevel();
|
DrawRssiTriggerLevel();
|
||||||
DrawF(peak.f);
|
DrawF(peak.f);
|
||||||
@@ -954,14 +1009,14 @@ static void RenderStill() {
|
|||||||
|
|
||||||
const uint8_t METER_PAD_LEFT = 3;
|
const uint8_t METER_PAD_LEFT = 3;
|
||||||
|
|
||||||
for (int i = 0; i < 121; i++) {
|
memset(&gFrameBuffer[2][METER_PAD_LEFT], 0b00010000, 121);
|
||||||
if (i % 10 == 0) {
|
|
||||||
gFrameBuffer[2][i + METER_PAD_LEFT] = 0b01110000;
|
for (int i = 0; i < 121; i+=5) {
|
||||||
} else if (i % 5 == 0) {
|
gFrameBuffer[2][i + METER_PAD_LEFT] = 0b00110000;
|
||||||
gFrameBuffer[2][i + METER_PAD_LEFT] = 0b00110000;
|
}
|
||||||
} else {
|
|
||||||
gFrameBuffer[2][i + METER_PAD_LEFT] = 0b00010000;
|
for (int i = 0; i < 121; i+=10) {
|
||||||
}
|
gFrameBuffer[2][i + METER_PAD_LEFT] = 0b01110000;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t x = Rssi2PX(scanInfo.rssi, 0, 121);
|
uint8_t x = Rssi2PX(scanInfo.rssi, 0, 121);
|
||||||
@@ -1031,17 +1086,17 @@ bool HandleUserInput() {
|
|||||||
kbd.prev = kbd.current;
|
kbd.prev = kbd.current;
|
||||||
kbd.current = GetKey();
|
kbd.current = GetKey();
|
||||||
|
|
||||||
if (kbd.current == KEY_INVALID) {
|
if (kbd.current != KEY_INVALID && kbd.current == kbd.prev) {
|
||||||
kbd.counter = 0;
|
if (kbd.counter < 16)
|
||||||
return true;
|
kbd.counter++;
|
||||||
}
|
else
|
||||||
|
kbd.counter -= 3;
|
||||||
if (kbd.current == kbd.prev && kbd.counter <= 16) {
|
|
||||||
kbd.counter++;
|
|
||||||
SYSTEM_DelayMs(20);
|
SYSTEM_DelayMs(20);
|
||||||
|
} else {
|
||||||
|
kbd.counter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kbd.counter == 3 || kbd.counter > 16) {
|
if (kbd.counter == 3 || kbd.counter == 16) {
|
||||||
switch (currentState) {
|
switch (currentState) {
|
||||||
case SPECTRUM:
|
case SPECTRUM:
|
||||||
OnKeyDown(kbd.current);
|
OnKeyDown(kbd.current);
|
||||||
@@ -1059,7 +1114,11 @@ bool HandleUserInput() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void Scan() {
|
static void Scan() {
|
||||||
if (rssiHistory[scanInfo.i] != RSSI_MAX_VALUE) {
|
if (rssiHistory[scanInfo.i] != RSSI_MAX_VALUE
|
||||||
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
&& !IsBlacklisted(scanInfo.i)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
SetF(scanInfo.f);
|
SetF(scanInfo.f);
|
||||||
Measure();
|
Measure();
|
||||||
UpdateScanInfo();
|
UpdateScanInfo();
|
||||||
@@ -1080,6 +1139,10 @@ static void UpdateScan() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(scanInfo.measurementsCount < 128)
|
||||||
|
memset(&rssiHistory[scanInfo.measurementsCount], 0,
|
||||||
|
sizeof(rssiHistory) - scanInfo.measurementsCount*sizeof(rssiHistory[0]));
|
||||||
|
|
||||||
redrawScreen = true;
|
redrawScreen = true;
|
||||||
preventKeypress = false;
|
preventKeypress = false;
|
||||||
|
|
||||||
@@ -1132,10 +1195,39 @@ static void UpdateListening() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ToggleRX(false);
|
ToggleRX(false);
|
||||||
newScanStart = true;
|
ResetScanStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Tick() {
|
static void Tick() {
|
||||||
|
#ifdef ENABLE_AM_FIX
|
||||||
|
if (gNextTimeslice) {
|
||||||
|
gNextTimeslice = false;
|
||||||
|
if(settings.modulationType == MODULATION_AM && !lockAGC) {
|
||||||
|
AM_fix_10ms(vfo); //allow AM_Fix to apply its AGC action
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
if (gNextTimeslice_500ms) {
|
||||||
|
gNextTimeslice_500ms = false;
|
||||||
|
|
||||||
|
// if a lot of steps then it takes long time
|
||||||
|
// we don't want to wait for whole scan
|
||||||
|
// listening has it's own timer
|
||||||
|
if(GetStepsCount()>128 && !isListening) {
|
||||||
|
UpdatePeakInfo();
|
||||||
|
if (IsPeakOverLevel()) {
|
||||||
|
ToggleRX(true);
|
||||||
|
TuneToPeak();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
redrawScreen = true;
|
||||||
|
preventKeypress = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!preventKeypress) {
|
if (!preventKeypress) {
|
||||||
HandleUserInput();
|
HandleUserInput();
|
||||||
}
|
}
|
||||||
@@ -1165,25 +1257,40 @@ 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 =
|
vfo = gEeprom.TX_VFO;
|
||||||
gEeprom.VfoInfo[gEeprom.TX_VFO].pRX->Frequency;
|
// set the current frequency in the middle of the display
|
||||||
|
#ifdef ENABLE_SCAN_RANGES
|
||||||
|
if(gScanRangeStart) {
|
||||||
|
currentFreq = initialFreq = gScanRangeStart;
|
||||||
|
for(uint8_t i = 0; i < ARRAY_SIZE(scanStepValues); i++) {
|
||||||
|
if(scanStepValues[i] >= gTxVfo->StepFrequency) {
|
||||||
|
settings.scanStepIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settings.stepsCount = STEPS_128;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
currentFreq = initialFreq = gTxVfo->pRX->Frequency -
|
||||||
|
((GetStepsCount() / 2) * GetScanStep());
|
||||||
|
|
||||||
BackupRegisters();
|
BackupRegisters();
|
||||||
|
|
||||||
isListening = true; // to turn off RX later
|
isListening = true; // to turn off RX later
|
||||||
redrawStatus = true;
|
redrawStatus = true;
|
||||||
redrawScreen = false; // we will wait until scan done
|
redrawScreen = true;
|
||||||
newScanStart = true;
|
newScanStart = true;
|
||||||
|
|
||||||
|
|
||||||
ToggleRX(true), ToggleRX(false); // hack to prevent noise when squelch off
|
ToggleRX(true), ToggleRX(false); // hack to prevent noise when squelch off
|
||||||
SetModulation(settings.modulationType = MOD_FM);
|
RADIO_SetModulation(settings.modulationType = gTxVfo->Modulation);
|
||||||
|
|
||||||
BK4819_SetFilterBandwidth(settings.listenBw = BK4819_FILTER_BW_WIDE, false);
|
BK4819_SetFilterBandwidth(settings.listenBw = BK4819_FILTER_BW_WIDE, false);
|
||||||
|
|
||||||
RelaunchScan();
|
RelaunchScan();
|
||||||
|
|
||||||
for (int i = 0; i < 128; ++i) {
|
memset(rssiHistory, 0, sizeof(rssiHistory));
|
||||||
rssiHistory[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
#include "../driver/systick.h"
|
#include "../driver/systick.h"
|
||||||
#include "../external/printf/printf.h"
|
#include "../external/printf/printf.h"
|
||||||
#include "../font.h"
|
#include "../font.h"
|
||||||
#include "../frequencies.h"
|
|
||||||
#include "../helper/battery.h"
|
#include "../helper/battery.h"
|
||||||
#include "../misc.h"
|
#include "../misc.h"
|
||||||
#include "../radio.h"
|
#include "../radio.h"
|
||||||
@@ -46,9 +45,8 @@ static const uint8_t U8RssiMap[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t scanStepValues[] = {
|
static const uint16_t scanStepValues[] = {
|
||||||
1, 10, 50, 100,
|
1, 10, 50, 100, 250, 500, 625, 833,
|
||||||
|
1000, 1250, 1500, 2000, 2500, 5000, 10000,
|
||||||
250, 500, 625, 833, 1000, 1250, 2500, 10000,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t scanStepBWRegValues[] = {
|
static const uint16_t scanStepBWRegValues[] = {
|
||||||
@@ -99,12 +97,6 @@ typedef enum StepsCount {
|
|||||||
STEPS_16,
|
STEPS_16,
|
||||||
} StepsCount;
|
} StepsCount;
|
||||||
|
|
||||||
typedef enum ModulationType {
|
|
||||||
MOD_FM,
|
|
||||||
MOD_AM,
|
|
||||||
MOD_USB,
|
|
||||||
} ModulationType;
|
|
||||||
|
|
||||||
typedef enum ScanStep {
|
typedef enum ScanStep {
|
||||||
S_STEP_0_01kHz,
|
S_STEP_0_01kHz,
|
||||||
S_STEP_0_1kHz,
|
S_STEP_0_1kHz,
|
||||||
@@ -117,7 +109,10 @@ typedef enum ScanStep {
|
|||||||
S_STEP_8_33kHz,
|
S_STEP_8_33kHz,
|
||||||
S_STEP_10_0kHz,
|
S_STEP_10_0kHz,
|
||||||
S_STEP_12_5kHz,
|
S_STEP_12_5kHz,
|
||||||
|
S_STEP_15_0kHz,
|
||||||
|
S_STEP_20_0kHz,
|
||||||
S_STEP_25_0kHz,
|
S_STEP_25_0kHz,
|
||||||
|
S_STEP_50_0kHz,
|
||||||
S_STEP_100_0kHz,
|
S_STEP_100_0kHz,
|
||||||
} ScanStep;
|
} ScanStep;
|
||||||
|
|
||||||
@@ -131,7 +126,7 @@ typedef struct SpectrumSettings {
|
|||||||
BK4819_FilterBandwidth_t listenBw;
|
BK4819_FilterBandwidth_t listenBw;
|
||||||
int dbMin;
|
int dbMin;
|
||||||
int dbMax;
|
int dbMax;
|
||||||
ModulationType modulationType;
|
ModulationMode_t modulationType;
|
||||||
bool backlightState;
|
bool backlightState;
|
||||||
} SpectrumSettings;
|
} SpectrumSettings;
|
||||||
|
|
||||||
@@ -143,25 +138,17 @@ typedef struct KeyboardState {
|
|||||||
|
|
||||||
typedef struct ScanInfo {
|
typedef struct ScanInfo {
|
||||||
uint16_t rssi, rssiMin, rssiMax;
|
uint16_t rssi, rssiMin, rssiMax;
|
||||||
uint8_t i, iPeak;
|
uint16_t i, iPeak;
|
||||||
uint32_t f, fPeak;
|
uint32_t f, fPeak;
|
||||||
uint16_t scanStep;
|
uint16_t scanStep;
|
||||||
uint8_t measurementsCount;
|
uint16_t measurementsCount;
|
||||||
} ScanInfo;
|
} ScanInfo;
|
||||||
|
|
||||||
typedef struct RegisterSpec {
|
|
||||||
char *name;
|
|
||||||
uint8_t num;
|
|
||||||
uint8_t offset;
|
|
||||||
uint16_t maxValue;
|
|
||||||
uint16_t inc;
|
|
||||||
} RegisterSpec;
|
|
||||||
|
|
||||||
typedef struct PeakInfo {
|
typedef struct PeakInfo {
|
||||||
uint16_t t;
|
uint16_t t;
|
||||||
uint16_t rssi;
|
uint16_t rssi;
|
||||||
uint32_t f;
|
uint32_t f;
|
||||||
uint8_t i;
|
uint16_t i;
|
||||||
} PeakInfo;
|
} PeakInfo;
|
||||||
|
|
||||||
void APP_RunSpectrum(void);
|
void APP_RunSpectrum(void);
|
||||||
|
|||||||
27
app/uart.c
27
app/uart.c
@@ -27,6 +27,7 @@
|
|||||||
#include "bsp/dp32g030/dma.h"
|
#include "bsp/dp32g030/dma.h"
|
||||||
#include "bsp/dp32g030/gpio.h"
|
#include "bsp/dp32g030/gpio.h"
|
||||||
#include "driver/aes.h"
|
#include "driver/aes.h"
|
||||||
|
#include "driver/backlight.h"
|
||||||
#include "driver/bk4819.h"
|
#include "driver/bk4819.h"
|
||||||
#include "driver/crc.h"
|
#include "driver/crc.h"
|
||||||
#include "driver/eeprom.h"
|
#include "driver/eeprom.h"
|
||||||
@@ -35,10 +36,12 @@
|
|||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#if defined(ENABLE_OVERLAY)
|
#if defined(ENABLE_OVERLAY)
|
||||||
#include "sram-overlay.h"
|
#include "sram-overlay.h"
|
||||||
#endif
|
#endif
|
||||||
#include "version.h"
|
|
||||||
|
|
||||||
#define DMA_INDEX(x, y) (((x) + (y)) % sizeof(UART_DMA_Buffer))
|
#define DMA_INDEX(x, y) (((x) + (y)) % sizeof(UART_DMA_Buffer))
|
||||||
|
|
||||||
@@ -225,6 +228,8 @@ static bool IsBadChallenge(const uint32_t *pKey, const uint32_t *pIn, const uint
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// session init, sends back version info and state
|
||||||
|
// timestamp is a session id really
|
||||||
static void CMD_0514(const uint8_t *pBuffer)
|
static void CMD_0514(const uint8_t *pBuffer)
|
||||||
{
|
{
|
||||||
const CMD_0514_t *pCmd = (const CMD_0514_t *)pBuffer;
|
const CMD_0514_t *pCmd = (const CMD_0514_t *)pBuffer;
|
||||||
@@ -238,11 +243,12 @@ static void CMD_0514(const uint8_t *pBuffer)
|
|||||||
gSerialConfigCountDown_500ms = 12; // 6 sec
|
gSerialConfigCountDown_500ms = 12; // 6 sec
|
||||||
|
|
||||||
// turn the LCD backlight off
|
// turn the LCD backlight off
|
||||||
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
|
BACKLIGHT_TurnOff();
|
||||||
|
|
||||||
SendVersion();
|
SendVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// read eeprom
|
||||||
static void CMD_051B(const uint8_t *pBuffer)
|
static void CMD_051B(const uint8_t *pBuffer)
|
||||||
{
|
{
|
||||||
const CMD_051B_t *pCmd = (const CMD_051B_t *)pBuffer;
|
const CMD_051B_t *pCmd = (const CMD_051B_t *)pBuffer;
|
||||||
@@ -273,6 +279,7 @@ static void CMD_051B(const uint8_t *pBuffer)
|
|||||||
SendReply(&Reply, pCmd->Size + 8);
|
SendReply(&Reply, pCmd->Size + 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write eeprom
|
||||||
static void CMD_051D(const uint8_t *pBuffer)
|
static void CMD_051D(const uint8_t *pBuffer)
|
||||||
{
|
{
|
||||||
const CMD_051D_t *pCmd = (const CMD_051D_t *)pBuffer;
|
const CMD_051D_t *pCmd = (const CMD_051D_t *)pBuffer;
|
||||||
@@ -313,12 +320,13 @@ static void CMD_051D(const uint8_t *pBuffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bReloadEeprom)
|
if (bReloadEeprom)
|
||||||
BOARD_EEPROM_Init();
|
SETTINGS_InitEEPROM();
|
||||||
}
|
}
|
||||||
|
|
||||||
SendReply(&Reply, sizeof(Reply));
|
SendReply(&Reply, sizeof(Reply));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// read RSSI
|
||||||
static void CMD_0527(void)
|
static void CMD_0527(void)
|
||||||
{
|
{
|
||||||
REPLY_0527_t Reply;
|
REPLY_0527_t Reply;
|
||||||
@@ -332,6 +340,7 @@ static void CMD_0527(void)
|
|||||||
SendReply(&Reply, sizeof(Reply));
|
SendReply(&Reply, sizeof(Reply));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// read ADC
|
||||||
static void CMD_0529(void)
|
static void CMD_0529(void)
|
||||||
{
|
{
|
||||||
REPLY_0529_t Reply;
|
REPLY_0529_t Reply;
|
||||||
@@ -399,7 +408,9 @@ static void CMD_052F(const uint8_t *pBuffer)
|
|||||||
gEeprom.VfoInfo[0].pTX = &gEeprom.VfoInfo[0].freq_config_TX;
|
gEeprom.VfoInfo[0].pTX = &gEeprom.VfoInfo[0].freq_config_TX;
|
||||||
gEeprom.VfoInfo[0].TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF;
|
gEeprom.VfoInfo[0].TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF;
|
||||||
gEeprom.VfoInfo[0].DTMF_PTT_ID_TX_MODE = PTT_ID_OFF;
|
gEeprom.VfoInfo[0].DTMF_PTT_ID_TX_MODE = PTT_ID_OFF;
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
gEeprom.VfoInfo[0].DTMF_DECODING_ENABLE = false;
|
gEeprom.VfoInfo[0].DTMF_DECODING_ENABLE = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
gIsNoaaMode = false;
|
gIsNoaaMode = false;
|
||||||
@@ -413,7 +424,7 @@ static void CMD_052F(const uint8_t *pBuffer)
|
|||||||
Timestamp = pCmd->Timestamp;
|
Timestamp = pCmd->Timestamp;
|
||||||
|
|
||||||
// turn the LCD backlight off
|
// turn the LCD backlight off
|
||||||
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
|
BACKLIGHT_TurnOff();
|
||||||
|
|
||||||
SendVersion();
|
SendVersion();
|
||||||
}
|
}
|
||||||
@@ -476,11 +487,11 @@ bool UART_IsCommandAvailable(void)
|
|||||||
if (TailIndex < Index)
|
if (TailIndex < Index)
|
||||||
{
|
{
|
||||||
const uint16_t ChunkSize = sizeof(UART_DMA_Buffer) - Index;
|
const uint16_t ChunkSize = sizeof(UART_DMA_Buffer) - Index;
|
||||||
memmove(UART_Command.Buffer, UART_DMA_Buffer + Index, ChunkSize);
|
memcpy(UART_Command.Buffer, UART_DMA_Buffer + Index, ChunkSize);
|
||||||
memmove(UART_Command.Buffer + ChunkSize, UART_DMA_Buffer, TailIndex);
|
memcpy(UART_Command.Buffer + ChunkSize, UART_DMA_Buffer, TailIndex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
memmove(UART_Command.Buffer, UART_DMA_Buffer + Index, TailIndex - Index);
|
memcpy(UART_Command.Buffer, UART_DMA_Buffer + Index, TailIndex - Index);
|
||||||
|
|
||||||
TailIndex = DMA_INDEX(TailIndex, 2);
|
TailIndex = DMA_INDEX(TailIndex, 2);
|
||||||
if (TailIndex < gUART_WriteIndex)
|
if (TailIndex < gUART_WriteIndex)
|
||||||
@@ -549,7 +560,7 @@ void UART_HandleCommand(void)
|
|||||||
CMD_052F(UART_Command.Buffer);
|
CMD_052F(UART_Command.Buffer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x05DD:
|
case 0x05DD: // reset
|
||||||
#if defined(ENABLE_OVERLAY)
|
#if defined(ENABLE_OVERLAY)
|
||||||
overlay_FLASH_RebootToBootloader();
|
overlay_FLASH_RebootToBootloader();
|
||||||
#else
|
#else
|
||||||
|
|||||||
604
audio.c
604
audio.c
@@ -31,50 +31,11 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
|
|
||||||
static const uint8_t VoiceClipLengthChinese[58] =
|
|
||||||
{
|
|
||||||
0x32, 0x32, 0x32, 0x37, 0x37, 0x32, 0x32, 0x32,
|
|
||||||
0x32, 0x37, 0x37, 0x32, 0x64, 0x64, 0x64, 0x64,
|
|
||||||
0x64, 0x69, 0x64, 0x69, 0x5A, 0x5F, 0x5F, 0x64,
|
|
||||||
0x64, 0x69, 0x64, 0x64, 0x69, 0x69, 0x69, 0x64,
|
|
||||||
0x64, 0x6E, 0x69, 0x5F, 0x64, 0x64, 0x64, 0x69,
|
|
||||||
0x69, 0x69, 0x64, 0x69, 0x64, 0x64, 0x55, 0x5F,
|
|
||||||
0x5A, 0x4B, 0x4B, 0x46, 0x46, 0x69, 0x64, 0x6E,
|
|
||||||
0x5A, 0x64,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t VoiceClipLengthEnglish[76] =
|
|
||||||
{
|
|
||||||
0x50, 0x32, 0x2D, 0x2D, 0x2D, 0x37, 0x37, 0x37,
|
|
||||||
0x32, 0x32, 0x3C, 0x37, 0x46, 0x46, 0x4B, 0x82,
|
|
||||||
0x82, 0x6E, 0x82, 0x46, 0x96, 0x64, 0x46, 0x6E,
|
|
||||||
0x78, 0x6E, 0x87, 0x64, 0x96, 0x96, 0x46, 0x9B,
|
|
||||||
0x91, 0x82, 0x82, 0x73, 0x78, 0x64, 0x82, 0x6E,
|
|
||||||
0x78, 0x82, 0x87, 0x6E, 0x55, 0x78, 0x64, 0x69,
|
|
||||||
0x9B, 0x5A, 0x50, 0x3C, 0x32, 0x55, 0x64, 0x64,
|
|
||||||
0x50, 0x46, 0x46, 0x46, 0x4B, 0x4B, 0x50, 0x50,
|
|
||||||
0x55, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x37,
|
|
||||||
0x41, 0x32, 0x3C, 0x37,
|
|
||||||
};
|
|
||||||
|
|
||||||
VOICE_ID_t gVoiceID[8];
|
|
||||||
uint8_t gVoiceReadIndex;
|
|
||||||
uint8_t gVoiceWriteIndex;
|
|
||||||
volatile uint16_t gCountdownToPlayNextVoice_10ms;
|
|
||||||
volatile bool gFlagPlayQueuedVoice;
|
|
||||||
VOICE_ID_t gAnotherVoiceID = VOICE_ID_INVALID;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BEEP_Type_t gBeepToPlay = BEEP_NONE;
|
BEEP_Type_t gBeepToPlay = BEEP_NONE;
|
||||||
|
|
||||||
void AUDIO_PlayBeep(BEEP_Type_t Beep)
|
void AUDIO_PlayBeep(BEEP_Type_t Beep)
|
||||||
{
|
{
|
||||||
uint16_t ToneConfig;
|
|
||||||
uint16_t ToneFrequency;
|
|
||||||
uint16_t Duration;
|
|
||||||
|
|
||||||
if (Beep != BEEP_880HZ_60MS_TRIPLE_BEEP &&
|
if (Beep != BEEP_880HZ_60MS_TRIPLE_BEEP &&
|
||||||
Beep != BEEP_500HZ_60MS_DOUBLE_BEEP &&
|
Beep != BEEP_500HZ_60MS_DOUBLE_BEEP &&
|
||||||
@@ -84,10 +45,10 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
|
|||||||
!gEeprom.BEEP_CONTROL)
|
!gEeprom.BEEP_CONTROL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef ENABLE_AIRCOPY
|
#ifdef ENABLE_AIRCOPY
|
||||||
if (gScreenToDisplay == DISPLAY_AIRCOPY)
|
if (gScreenToDisplay == DISPLAY_AIRCOPY)
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gCurrentFunction == FUNCTION_RECEIVE)
|
if (gCurrentFunction == FUNCTION_RECEIVE)
|
||||||
return;
|
return;
|
||||||
@@ -95,20 +56,21 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
|
|||||||
if (gCurrentFunction == FUNCTION_MONITOR)
|
if (gCurrentFunction == FUNCTION_MONITOR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ToneConfig = BK4819_ReadRegister(BK4819_REG_71);
|
#ifdef ENABLE_FMRADIO
|
||||||
|
if (gFmRadioMode)
|
||||||
|
BK1080_Mute(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOff();
|
||||||
|
|
||||||
if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode)
|
if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode)
|
||||||
BK4819_RX_TurnOn();
|
BK4819_RX_TurnOn();
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
|
||||||
if (gFmRadioMode)
|
|
||||||
BK1080_Mute(true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(20);
|
SYSTEM_DelayMs(20);
|
||||||
|
|
||||||
|
uint16_t ToneConfig = BK4819_ReadRegister(BK4819_REG_71);
|
||||||
|
|
||||||
|
uint16_t ToneFrequency;
|
||||||
switch (Beep)
|
switch (Beep)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
@@ -138,13 +100,11 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
|
|||||||
|
|
||||||
SYSTEM_DelayMs(2);
|
SYSTEM_DelayMs(2);
|
||||||
|
|
||||||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOn();
|
||||||
|
|
||||||
SYSTEM_DelayMs(60);
|
SYSTEM_DelayMs(60);
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
uint16_t Duration;
|
||||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
|
|
||||||
|
|
||||||
switch (Beep)
|
switch (Beep)
|
||||||
{
|
{
|
||||||
case BEEP_880HZ_60MS_TRIPLE_BEEP:
|
case BEEP_880HZ_60MS_TRIPLE_BEEP:
|
||||||
@@ -152,30 +112,27 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
|
|||||||
SYSTEM_DelayMs(60);
|
SYSTEM_DelayMs(60);
|
||||||
BK4819_EnterTxMute();
|
BK4819_EnterTxMute();
|
||||||
SYSTEM_DelayMs(20);
|
SYSTEM_DelayMs(20);
|
||||||
|
[[fallthrough]];
|
||||||
case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL:
|
case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL:
|
||||||
case BEEP_500HZ_60MS_DOUBLE_BEEP:
|
case BEEP_500HZ_60MS_DOUBLE_BEEP:
|
||||||
BK4819_ExitTxMute();
|
BK4819_ExitTxMute();
|
||||||
SYSTEM_DelayMs(60);
|
SYSTEM_DelayMs(60);
|
||||||
BK4819_EnterTxMute();
|
BK4819_EnterTxMute();
|
||||||
SYSTEM_DelayMs(20);
|
SYSTEM_DelayMs(20);
|
||||||
|
[[fallthrough]];
|
||||||
case BEEP_1KHZ_60MS_OPTIONAL:
|
case BEEP_1KHZ_60MS_OPTIONAL:
|
||||||
BK4819_ExitTxMute();
|
BK4819_ExitTxMute();
|
||||||
Duration = 60;
|
Duration = 60;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BEEP_880HZ_40MS_OPTIONAL:
|
case BEEP_880HZ_40MS_OPTIONAL:
|
||||||
case BEEP_440HZ_40MS_OPTIONAL:
|
case BEEP_440HZ_40MS_OPTIONAL:
|
||||||
BK4819_ExitTxMute();
|
BK4819_ExitTxMute();
|
||||||
Duration = 40;
|
Duration = 40;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BEEP_880HZ_200MS:
|
case BEEP_880HZ_200MS:
|
||||||
BK4819_ExitTxMute();
|
BK4819_ExitTxMute();
|
||||||
Duration = 200;
|
Duration = 200;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BEEP_440HZ_500MS:
|
case BEEP_440HZ_500MS:
|
||||||
case BEEP_880HZ_500MS:
|
case BEEP_880HZ_500MS:
|
||||||
default:
|
default:
|
||||||
@@ -184,17 +141,11 @@ 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);
|
||||||
|
|
||||||
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOff();
|
||||||
|
|
||||||
#ifdef ENABLE_VOX
|
|
||||||
gVoxResumeCountdown = 80;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(5);
|
SYSTEM_DelayMs(5);
|
||||||
BK4819_TurnsOffTones_TurnsOnRX();
|
BK4819_TurnsOffTones_TurnsOnRX();
|
||||||
@@ -202,255 +153,290 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
|
|||||||
BK4819_WriteRegister(BK4819_REG_71, ToneConfig);
|
BK4819_WriteRegister(BK4819_REG_71, ToneConfig);
|
||||||
|
|
||||||
if (gEnableSpeaker)
|
if (gEnableSpeaker)
|
||||||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOn();
|
||||||
|
|
||||||
|
#ifdef ENABLE_FMRADIO
|
||||||
|
if (gFmRadioMode)
|
||||||
|
BK1080_Mute(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode)
|
||||||
|
BK4819_Sleep();
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOX
|
||||||
|
gVoxResumeCountdown = 80;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
|
||||||
|
static const uint8_t VoiceClipLengthChinese[58] =
|
||||||
|
{
|
||||||
|
0x32, 0x32, 0x32, 0x37, 0x37, 0x32, 0x32, 0x32,
|
||||||
|
0x32, 0x37, 0x37, 0x32, 0x64, 0x64, 0x64, 0x64,
|
||||||
|
0x64, 0x69, 0x64, 0x69, 0x5A, 0x5F, 0x5F, 0x64,
|
||||||
|
0x64, 0x69, 0x64, 0x64, 0x69, 0x69, 0x69, 0x64,
|
||||||
|
0x64, 0x6E, 0x69, 0x5F, 0x64, 0x64, 0x64, 0x69,
|
||||||
|
0x69, 0x69, 0x64, 0x69, 0x64, 0x64, 0x55, 0x5F,
|
||||||
|
0x5A, 0x4B, 0x4B, 0x46, 0x46, 0x69, 0x64, 0x6E,
|
||||||
|
0x5A, 0x64,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t VoiceClipLengthEnglish[76] =
|
||||||
|
{
|
||||||
|
0x50, 0x32, 0x2D, 0x2D, 0x2D, 0x37, 0x37, 0x37,
|
||||||
|
0x32, 0x32, 0x3C, 0x37, 0x46, 0x46, 0x4B, 0x82,
|
||||||
|
0x82, 0x6E, 0x82, 0x46, 0x96, 0x64, 0x46, 0x6E,
|
||||||
|
0x78, 0x6E, 0x87, 0x64, 0x96, 0x96, 0x46, 0x9B,
|
||||||
|
0x91, 0x82, 0x82, 0x73, 0x78, 0x64, 0x82, 0x6E,
|
||||||
|
0x78, 0x82, 0x87, 0x6E, 0x55, 0x78, 0x64, 0x69,
|
||||||
|
0x9B, 0x5A, 0x50, 0x3C, 0x32, 0x55, 0x64, 0x64,
|
||||||
|
0x50, 0x46, 0x46, 0x46, 0x4B, 0x4B, 0x50, 0x50,
|
||||||
|
0x55, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x37,
|
||||||
|
0x41, 0x32, 0x3C, 0x37,
|
||||||
|
};
|
||||||
|
|
||||||
|
VOICE_ID_t gVoiceID[8];
|
||||||
|
uint8_t gVoiceReadIndex;
|
||||||
|
uint8_t gVoiceWriteIndex;
|
||||||
|
volatile uint16_t gCountdownToPlayNextVoice_10ms;
|
||||||
|
volatile bool gFlagPlayQueuedVoice;
|
||||||
|
VOICE_ID_t gAnotherVoiceID = VOICE_ID_INVALID;
|
||||||
|
|
||||||
|
|
||||||
|
static void AUDIO_PlayVoice(uint8_t VoiceID)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
|
||||||
|
SYSTEM_DelayMs(20);
|
||||||
|
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if ((VoiceID & 0x80U) == 0)
|
||||||
|
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
|
||||||
|
else
|
||||||
|
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
|
||||||
|
|
||||||
|
SYSTICK_DelayUs(1000);
|
||||||
|
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
|
||||||
|
SYSTICK_DelayUs(1200);
|
||||||
|
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
|
||||||
|
VoiceID <<= 1;
|
||||||
|
SYSTICK_DelayUs(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUDIO_PlaySingleVoice(bool bFlag)
|
||||||
|
{
|
||||||
|
uint8_t VoiceID;
|
||||||
|
uint8_t Delay;
|
||||||
|
|
||||||
|
VoiceID = gVoiceID[0];
|
||||||
|
|
||||||
|
if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF && gVoiceWriteIndex > 0)
|
||||||
|
{
|
||||||
|
if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE)
|
||||||
|
{ // Chinese
|
||||||
|
if (VoiceID >= ARRAY_SIZE(VoiceClipLengthChinese))
|
||||||
|
goto Bailout;
|
||||||
|
|
||||||
|
Delay = VoiceClipLengthChinese[VoiceID];
|
||||||
|
VoiceID += VOICE_ID_CHI_BASE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // English
|
||||||
|
if (VoiceID >= ARRAY_SIZE(VoiceClipLengthEnglish))
|
||||||
|
goto Bailout;
|
||||||
|
|
||||||
|
Delay = VoiceClipLengthEnglish[VoiceID];
|
||||||
|
VoiceID += VOICE_ID_ENG_BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FUNCTION_IsRx()) // 1of11
|
||||||
|
BK4819_SetAF(BK4819_AF_MUTE);
|
||||||
|
|
||||||
|
#ifdef ENABLE_FMRADIO
|
||||||
|
if (gFmRadioMode)
|
||||||
|
BK1080_Mute(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AUDIO_AudioPathOn();
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOX
|
||||||
|
gVoxResumeCountdown = 2000;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SYSTEM_DelayMs(5);
|
||||||
|
AUDIO_PlayVoice(VoiceID);
|
||||||
|
|
||||||
|
if (gVoiceWriteIndex == 1)
|
||||||
|
Delay += 3;
|
||||||
|
|
||||||
|
if (bFlag)
|
||||||
|
{
|
||||||
|
SYSTEM_DelayMs(Delay * 10);
|
||||||
|
|
||||||
|
if (FUNCTION_IsRx()) // 1of11
|
||||||
|
RADIO_SetModulation(gRxVfo->Modulation);
|
||||||
|
|
||||||
|
#ifdef ENABLE_FMRADIO
|
||||||
|
if (gFmRadioMode)
|
||||||
|
BK1080_Mute(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!gEnableSpeaker)
|
||||||
|
AUDIO_AudioPathOff();
|
||||||
|
|
||||||
|
gVoiceWriteIndex = 0;
|
||||||
|
gVoiceReadIndex = 0;
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOX
|
||||||
|
gVoxResumeCountdown = 80;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gVoiceReadIndex = 1;
|
||||||
|
gCountdownToPlayNextVoice_10ms = Delay;
|
||||||
|
gFlagPlayQueuedVoice = false;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bailout:
|
||||||
|
gVoiceReadIndex = 0;
|
||||||
|
gVoiceWriteIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID)
|
||||||
|
{
|
||||||
|
if (Index >= ARRAY_SIZE(gVoiceID))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Index == 0)
|
||||||
|
{
|
||||||
|
gVoiceWriteIndex = 0;
|
||||||
|
gVoiceReadIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gVoiceID[Index] = VoiceID;
|
||||||
|
|
||||||
|
gVoiceWriteIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value)
|
||||||
|
{
|
||||||
|
uint16_t Remainder;
|
||||||
|
uint8_t Result;
|
||||||
|
uint8_t Count;
|
||||||
|
|
||||||
|
if (Index == 0)
|
||||||
|
{
|
||||||
|
gVoiceWriteIndex = 0;
|
||||||
|
gVoiceReadIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Count = 0;
|
||||||
|
Result = Value / 1000U;
|
||||||
|
Remainder = Value % 1000U;
|
||||||
|
if (Remainder < 100U)
|
||||||
|
{
|
||||||
|
if (Remainder < 10U)
|
||||||
|
goto Skip;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result = Remainder / 100U;
|
||||||
|
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result;
|
||||||
|
Count++;
|
||||||
|
Remainder -= Result * 100U;
|
||||||
|
}
|
||||||
|
Result = Remainder / 10U;
|
||||||
|
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result;
|
||||||
|
Count++;
|
||||||
|
Remainder -= Result * 10U;
|
||||||
|
|
||||||
|
Skip:
|
||||||
|
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Remainder;
|
||||||
|
|
||||||
|
return Count + 1U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUDIO_PlayQueuedVoice(void)
|
||||||
|
{
|
||||||
|
uint8_t VoiceID;
|
||||||
|
uint8_t Delay;
|
||||||
|
bool Skip;
|
||||||
|
|
||||||
|
Skip = false;
|
||||||
|
|
||||||
|
if (gVoiceReadIndex != gVoiceWriteIndex && gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF)
|
||||||
|
{
|
||||||
|
VoiceID = gVoiceID[gVoiceReadIndex];
|
||||||
|
if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE)
|
||||||
|
{
|
||||||
|
if (VoiceID < ARRAY_SIZE(VoiceClipLengthChinese))
|
||||||
|
{
|
||||||
|
Delay = VoiceClipLengthChinese[VoiceID];
|
||||||
|
VoiceID += VOICE_ID_CHI_BASE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Skip = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (VoiceID < ARRAY_SIZE(VoiceClipLengthEnglish))
|
||||||
|
{
|
||||||
|
Delay = VoiceClipLengthEnglish[VoiceID];
|
||||||
|
VoiceID += VOICE_ID_ENG_BASE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Skip = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
gVoiceReadIndex++;
|
||||||
|
|
||||||
|
if (!Skip)
|
||||||
|
{
|
||||||
|
if (gVoiceReadIndex == gVoiceWriteIndex)
|
||||||
|
Delay += 3;
|
||||||
|
|
||||||
|
AUDIO_PlayVoice(VoiceID);
|
||||||
|
|
||||||
|
gCountdownToPlayNextVoice_10ms = Delay;
|
||||||
|
gFlagPlayQueuedVoice = false;
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOX
|
||||||
|
gVoxResumeCountdown = 2000;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FUNCTION_IsRx())
|
||||||
|
{
|
||||||
|
RADIO_SetModulation(gRxVfo->Modulation); // 1of11
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
if (gFmRadioMode)
|
if (gFmRadioMode)
|
||||||
BK1080_Mute(false);
|
BK1080_Mute(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode)
|
if (!gEnableSpeaker)
|
||||||
BK4819_Sleep();
|
AUDIO_AudioPathOff();
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOX
|
||||||
|
gVoxResumeCountdown = 80;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gVoiceWriteIndex = 0;
|
||||||
|
gVoiceReadIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
|
|
||||||
void AUDIO_PlayVoice(uint8_t VoiceID)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
|
|
||||||
SYSTEM_DelayMs(20);
|
|
||||||
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
|
|
||||||
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
if ((VoiceID & 0x80U) == 0)
|
|
||||||
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
|
|
||||||
else
|
|
||||||
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
|
|
||||||
|
|
||||||
SYSTICK_DelayUs(1000);
|
|
||||||
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
|
|
||||||
SYSTICK_DelayUs(1200);
|
|
||||||
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
|
|
||||||
VoiceID <<= 1;
|
|
||||||
SYSTICK_DelayUs(200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUDIO_PlaySingleVoice(bool bFlag)
|
|
||||||
{
|
|
||||||
uint8_t VoiceID;
|
|
||||||
uint8_t Delay;
|
|
||||||
|
|
||||||
VoiceID = gVoiceID[0];
|
|
||||||
|
|
||||||
if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF && gVoiceWriteIndex > 0)
|
|
||||||
{
|
|
||||||
if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE)
|
|
||||||
{ // Chinese
|
|
||||||
if (VoiceID >= ARRAY_SIZE(VoiceClipLengthChinese))
|
|
||||||
goto Bailout;
|
|
||||||
|
|
||||||
Delay = VoiceClipLengthChinese[VoiceID];
|
|
||||||
VoiceID += VOICE_ID_CHI_BASE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // English
|
|
||||||
if (VoiceID >= ARRAY_SIZE(VoiceClipLengthEnglish))
|
|
||||||
goto Bailout;
|
|
||||||
|
|
||||||
Delay = VoiceClipLengthEnglish[VoiceID];
|
|
||||||
VoiceID += VOICE_ID_ENG_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gCurrentFunction == FUNCTION_RECEIVE ||
|
|
||||||
gCurrentFunction == FUNCTION_MONITOR ||
|
|
||||||
gCurrentFunction == FUNCTION_INCOMING) // 1of11
|
|
||||||
BK4819_SetAF(BK4819_AF_MUTE);
|
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
|
||||||
if (gFmRadioMode)
|
|
||||||
BK1080_Mute(true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
|
||||||
|
|
||||||
#ifdef ENABLE_VOX
|
|
||||||
gVoxResumeCountdown = 2000;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(5);
|
|
||||||
AUDIO_PlayVoice(VoiceID);
|
|
||||||
|
|
||||||
if (gVoiceWriteIndex == 1)
|
|
||||||
Delay += 3;
|
|
||||||
|
|
||||||
if (bFlag)
|
|
||||||
{
|
|
||||||
SYSTEM_DelayMs(Delay * 10);
|
|
||||||
|
|
||||||
if (gCurrentFunction == FUNCTION_RECEIVE ||
|
|
||||||
gCurrentFunction == FUNCTION_MONITOR ||
|
|
||||||
gCurrentFunction == FUNCTION_INCOMING) // 1of11
|
|
||||||
BK4819_SetAF(gRxVfo->AM_mode ? BK4819_AF_AM : BK4819_AF_FM);
|
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
|
||||||
if (gFmRadioMode)
|
|
||||||
BK1080_Mute(false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!gEnableSpeaker)
|
|
||||||
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
|
||||||
|
|
||||||
gVoiceWriteIndex = 0;
|
|
||||||
gVoiceReadIndex = 0;
|
|
||||||
|
|
||||||
#ifdef ENABLE_VOX
|
|
||||||
gVoxResumeCountdown = 80;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gVoiceReadIndex = 1;
|
|
||||||
gCountdownToPlayNextVoice_10ms = Delay;
|
|
||||||
gFlagPlayQueuedVoice = false;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bailout:
|
|
||||||
gVoiceReadIndex = 0;
|
|
||||||
gVoiceWriteIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID)
|
|
||||||
{
|
|
||||||
if (Index >= ARRAY_SIZE(gVoiceID))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (Index == 0)
|
|
||||||
{
|
|
||||||
gVoiceWriteIndex = 0;
|
|
||||||
gVoiceReadIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
gVoiceID[Index] = VoiceID;
|
|
||||||
|
|
||||||
gVoiceWriteIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value)
|
|
||||||
{
|
|
||||||
uint16_t Remainder;
|
|
||||||
uint8_t Result;
|
|
||||||
uint8_t Count;
|
|
||||||
|
|
||||||
if (Index == 0)
|
|
||||||
{
|
|
||||||
gVoiceWriteIndex = 0;
|
|
||||||
gVoiceReadIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Count = 0;
|
|
||||||
Result = Value / 1000U;
|
|
||||||
Remainder = Value % 1000U;
|
|
||||||
if (Remainder < 100U)
|
|
||||||
{
|
|
||||||
if (Remainder < 10U)
|
|
||||||
goto Skip;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Result = Remainder / 100U;
|
|
||||||
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result;
|
|
||||||
Count++;
|
|
||||||
Remainder -= Result * 100U;
|
|
||||||
}
|
|
||||||
Result = Remainder / 10U;
|
|
||||||
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result;
|
|
||||||
Count++;
|
|
||||||
Remainder -= Result * 10U;
|
|
||||||
|
|
||||||
Skip:
|
|
||||||
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Remainder;
|
|
||||||
|
|
||||||
return Count + 1U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUDIO_PlayQueuedVoice(void)
|
|
||||||
{
|
|
||||||
uint8_t VoiceID;
|
|
||||||
uint8_t Delay;
|
|
||||||
bool Skip;
|
|
||||||
|
|
||||||
Skip = false;
|
|
||||||
|
|
||||||
if (gVoiceReadIndex != gVoiceWriteIndex && gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF)
|
|
||||||
{
|
|
||||||
VoiceID = gVoiceID[gVoiceReadIndex];
|
|
||||||
if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE)
|
|
||||||
{
|
|
||||||
if (VoiceID < ARRAY_SIZE(VoiceClipLengthChinese))
|
|
||||||
{
|
|
||||||
Delay = VoiceClipLengthChinese[VoiceID];
|
|
||||||
VoiceID += VOICE_ID_CHI_BASE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Skip = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (VoiceID < ARRAY_SIZE(VoiceClipLengthEnglish))
|
|
||||||
{
|
|
||||||
Delay = VoiceClipLengthEnglish[VoiceID];
|
|
||||||
VoiceID += VOICE_ID_ENG_BASE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Skip = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
gVoiceReadIndex++;
|
|
||||||
|
|
||||||
if (!Skip)
|
|
||||||
{
|
|
||||||
if (gVoiceReadIndex == gVoiceWriteIndex)
|
|
||||||
Delay += 3;
|
|
||||||
|
|
||||||
AUDIO_PlayVoice(VoiceID);
|
|
||||||
|
|
||||||
gCountdownToPlayNextVoice_10ms = Delay;
|
|
||||||
gFlagPlayQueuedVoice = false;
|
|
||||||
|
|
||||||
#ifdef ENABLE_VOX
|
|
||||||
gVoxResumeCountdown = 2000;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gCurrentFunction == FUNCTION_RECEIVE ||
|
|
||||||
gCurrentFunction == FUNCTION_MONITOR ||
|
|
||||||
gCurrentFunction == FUNCTION_INCOMING) // 1of11
|
|
||||||
BK4819_SetAF(gRxVfo->AM_mode ? BK4819_AF_AM : BK4819_AF_FM);
|
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
|
||||||
if (gFmRadioMode)
|
|
||||||
BK1080_Mute(false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!gEnableSpeaker)
|
|
||||||
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
|
||||||
|
|
||||||
#ifdef ENABLE_VOX
|
|
||||||
gVoxResumeCountdown = 80;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gVoiceWriteIndex = 0;
|
|
||||||
gVoiceReadIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
13
audio.h
13
audio.h
@@ -20,6 +20,9 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "bsp/dp32g030/gpio.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
enum BEEP_Type_t
|
enum BEEP_Type_t
|
||||||
{
|
{
|
||||||
BEEP_NONE = 0,
|
BEEP_NONE = 0,
|
||||||
@@ -130,6 +133,14 @@ enum VOICE_ID_t
|
|||||||
|
|
||||||
typedef enum VOICE_ID_t VOICE_ID_t;
|
typedef enum VOICE_ID_t VOICE_ID_t;
|
||||||
|
|
||||||
|
static inline void AUDIO_AudioPathOn(void) {
|
||||||
|
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void AUDIO_AudioPathOff(void) {
|
||||||
|
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
extern VOICE_ID_t gVoiceID[8];
|
extern VOICE_ID_t gVoiceID[8];
|
||||||
extern uint8_t gVoiceReadIndex;
|
extern uint8_t gVoiceReadIndex;
|
||||||
@@ -138,7 +149,6 @@ typedef enum VOICE_ID_t VOICE_ID_t;
|
|||||||
extern volatile bool gFlagPlayQueuedVoice;
|
extern volatile bool gFlagPlayQueuedVoice;
|
||||||
extern VOICE_ID_t gAnotherVoiceID;
|
extern VOICE_ID_t gAnotherVoiceID;
|
||||||
|
|
||||||
void AUDIO_PlayVoice(uint8_t VoiceID);
|
|
||||||
void AUDIO_PlaySingleVoice(bool bFlag);
|
void AUDIO_PlaySingleVoice(bool bFlag);
|
||||||
void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID);
|
void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID);
|
||||||
uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value);
|
uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value);
|
||||||
@@ -146,4 +156,3 @@ typedef enum VOICE_ID_t VOICE_ID_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
190
bitmaps.c
190
bitmaps.c
@@ -6,27 +6,16 @@
|
|||||||
|
|
||||||
const uint8_t BITMAP_POWERSAVE[8] =
|
const uint8_t BITMAP_POWERSAVE[8] =
|
||||||
{
|
{
|
||||||
#if 0
|
// "PS"
|
||||||
// "S"
|
0b00000000,
|
||||||
0b00000000,
|
0b01111111,
|
||||||
0b00100110,
|
0b00010001,
|
||||||
0b01001001,
|
0b00001110,
|
||||||
0b01001001,
|
0b00000000,
|
||||||
0b01001001,
|
0b01000110,
|
||||||
0b01001001,
|
0b01001001,
|
||||||
0b01001001,
|
0b00110001
|
||||||
0b00110010
|
|
||||||
#else
|
|
||||||
// "PS"
|
|
||||||
0b00000000,
|
|
||||||
0b01111111,
|
|
||||||
0b00010001,
|
|
||||||
0b00001110,
|
|
||||||
0b00000000,
|
|
||||||
0b01000110,
|
|
||||||
0b01001001,
|
|
||||||
0b00110001
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t BITMAP_TX[8] =
|
const uint8_t BITMAP_TX[8] =
|
||||||
@@ -53,6 +42,20 @@ const uint8_t BITMAP_RX[8] =
|
|||||||
0b00000000
|
0b00000000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const uint8_t BITMAP_FM[10] =
|
||||||
|
{ // "FM"
|
||||||
|
0b00000000,
|
||||||
|
0b01111111,
|
||||||
|
0b00001001,
|
||||||
|
0b00000001,
|
||||||
|
0b00000000,
|
||||||
|
0b01111111,
|
||||||
|
0b00000010,
|
||||||
|
0b00001100,
|
||||||
|
0b00000010,
|
||||||
|
0b01111111
|
||||||
|
};
|
||||||
|
|
||||||
const uint8_t BITMAP_BatteryLevel[2] =
|
const uint8_t BITMAP_BatteryLevel[2] =
|
||||||
{
|
{
|
||||||
0b01011101,
|
0b01011101,
|
||||||
@@ -162,46 +165,29 @@ const uint8_t BITMAP_F_Key[6] =
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
|
||||||
const uint8_t BITMAP_WX[12] =
|
|
||||||
{ // "WX"
|
|
||||||
0b00000000,
|
|
||||||
0b01111111,
|
|
||||||
0b00100000,
|
|
||||||
0b00011000,
|
|
||||||
0b00100000,
|
|
||||||
0b01111111,
|
|
||||||
0b00000000,
|
|
||||||
0b01100011,
|
|
||||||
0b00010100,
|
|
||||||
0b00001000,
|
|
||||||
0b00010100,
|
|
||||||
0b01100011
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
// 'XB' (cross-band/cross-VFO)
|
|
||||||
const uint8_t BITMAP_XB[12] =
|
|
||||||
{ // "XB"
|
|
||||||
0b00000000,
|
|
||||||
0b01100011,
|
|
||||||
0b00010100,
|
|
||||||
0b00001000,
|
|
||||||
0b00010100,
|
|
||||||
0b01100011,
|
|
||||||
0b00000000,
|
|
||||||
0b01111111,
|
|
||||||
0b01001001,
|
|
||||||
0b01001001,
|
|
||||||
0b01001001,
|
|
||||||
0b00110110
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const uint8_t BITMAP_TDR1[12] =
|
// 'XB' (cross-band/cross-VFO)
|
||||||
{ // "DW"
|
const uint8_t BITMAP_XB[12] =
|
||||||
|
{ // "XB"
|
||||||
|
0b00000000,
|
||||||
|
0b01100011,
|
||||||
|
0b00010100,
|
||||||
|
0b00001000,
|
||||||
|
0b00010100,
|
||||||
|
0b01100011,
|
||||||
|
0b00000000,
|
||||||
|
0b01111111,
|
||||||
|
0b01001001,
|
||||||
|
0b01001001,
|
||||||
|
0b01001001,
|
||||||
|
0b00110110
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const uint8_t BITMAP_TDR1[16] =
|
||||||
|
{ // "DWR"
|
||||||
0b00000000,
|
0b00000000,
|
||||||
0b01111111,
|
0b01111111,
|
||||||
0b01000001,
|
|
||||||
0b01000001,
|
0b01000001,
|
||||||
0b01000001,
|
0b01000001,
|
||||||
0b00111110,
|
0b00111110,
|
||||||
@@ -210,12 +196,16 @@ const uint8_t BITMAP_TDR1[12] =
|
|||||||
0b00100000,
|
0b00100000,
|
||||||
0b00011000,
|
0b00011000,
|
||||||
0b00100000,
|
0b00100000,
|
||||||
0b01111111
|
0b01111111,
|
||||||
|
0b00000000,
|
||||||
|
0b01111111,
|
||||||
|
0b00011001,
|
||||||
|
0b00101001,
|
||||||
|
0b01000110
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t BITMAP_TDR2[12] =
|
const uint8_t BITMAP_TDR2[10] =
|
||||||
{ // "><" .. DW on hold
|
{ // "><" .. DW on hold
|
||||||
0b00000000,
|
|
||||||
0b00000000,
|
0b00000000,
|
||||||
0b00100010,
|
0b00100010,
|
||||||
0b00110110,
|
0b00110110,
|
||||||
@@ -226,7 +216,6 @@ const uint8_t BITMAP_TDR2[12] =
|
|||||||
0b00011100,
|
0b00011100,
|
||||||
0b00110110,
|
0b00110110,
|
||||||
0b00100010,
|
0b00100010,
|
||||||
0b00000000
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
@@ -244,27 +233,8 @@ const uint8_t BITMAP_TDR2[12] =
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
|
||||||
const uint8_t BITMAP_FM[12] =
|
|
||||||
{ // "FM"
|
|
||||||
0b00000000,
|
|
||||||
0b01111111,
|
|
||||||
0b00001001,
|
|
||||||
0b00001001,
|
|
||||||
0b00001001,
|
|
||||||
0b00000001,
|
|
||||||
|
|
||||||
0b00000000,
|
|
||||||
0b01111111,
|
|
||||||
0b00000010,
|
|
||||||
0b00001100,
|
|
||||||
0b00000010,
|
|
||||||
0b01111111
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
const uint8_t BITMAP_NOAA[12] =
|
const uint8_t BITMAP_NOAA[11] =
|
||||||
{ // "NS"
|
{ // "NS"
|
||||||
0b00000000,
|
0b00000000,
|
||||||
0b01111111,
|
0b01111111,
|
||||||
@@ -272,12 +242,10 @@ const uint8_t BITMAP_TDR2[12] =
|
|||||||
0b00001000,
|
0b00001000,
|
||||||
0b00010000,
|
0b00010000,
|
||||||
0b01111111,
|
0b01111111,
|
||||||
|
|
||||||
0b00000000,
|
0b00000000,
|
||||||
0b01000110,
|
0b01000110,
|
||||||
0b01001001,
|
0b01001001,
|
||||||
0b01001001,
|
0b01001001,
|
||||||
0b01001001,
|
|
||||||
0b00110001
|
0b00110001
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@@ -291,60 +259,6 @@ const uint8_t BITMAP_Antenna[5] =
|
|||||||
0b00000011
|
0b00000011
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t BITMAP_AntennaLevel1[3] =
|
|
||||||
{
|
|
||||||
0b01100000,
|
|
||||||
0b01100000,
|
|
||||||
0b00000000
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t BITMAP_AntennaLevel2[3] =
|
|
||||||
{
|
|
||||||
0b01110000,
|
|
||||||
0b01110000,
|
|
||||||
0b00000000
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t BITMAP_AntennaLevel3[3] =
|
|
||||||
{
|
|
||||||
0b01111000,
|
|
||||||
0b01111000,
|
|
||||||
0b00000000
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t BITMAP_AntennaLevel4[3] =
|
|
||||||
{
|
|
||||||
0b01111100,
|
|
||||||
0b01111100,
|
|
||||||
0b00000000
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t BITMAP_AntennaLevel5[3] =
|
|
||||||
{
|
|
||||||
0b01111110,
|
|
||||||
0b01111110,
|
|
||||||
0b00000000
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t BITMAP_AntennaLevel6[3] =
|
|
||||||
{
|
|
||||||
0b01111111,
|
|
||||||
0b01111111,
|
|
||||||
0b00000000
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t BITMAP_MARKER[8] =
|
|
||||||
{
|
|
||||||
0b11111111,
|
|
||||||
0b11111111,
|
|
||||||
0b01111110,
|
|
||||||
0b01111110,
|
|
||||||
0b00111100,
|
|
||||||
0b00111100,
|
|
||||||
0b00011000,
|
|
||||||
0b00011000
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t BITMAP_VFO_Default[8] =
|
const uint8_t BITMAP_VFO_Default[8] =
|
||||||
{
|
{
|
||||||
0b00000000,
|
0b00000000,
|
||||||
|
|||||||
30
bitmaps.h
30
bitmaps.h
@@ -7,13 +7,9 @@
|
|||||||
extern const uint8_t BITMAP_POWERSAVE[8];
|
extern const uint8_t BITMAP_POWERSAVE[8];
|
||||||
extern const uint8_t BITMAP_TX[8];
|
extern const uint8_t BITMAP_TX[8];
|
||||||
extern const uint8_t BITMAP_RX[8];
|
extern const uint8_t BITMAP_RX[8];
|
||||||
|
extern const uint8_t BITMAP_FM[10];
|
||||||
extern const uint8_t BITMAP_BatteryLevel[2];
|
extern const uint8_t BITMAP_BatteryLevel[2];
|
||||||
extern const uint8_t BITMAP_BatteryLevel1[17];
|
extern const uint8_t BITMAP_BatteryLevel1[17];
|
||||||
extern const uint8_t BITMAP_BatteryLevel2[17];
|
|
||||||
extern const uint8_t BITMAP_BatteryLevel3[17];
|
|
||||||
extern const uint8_t BITMAP_BatteryLevel4[17];
|
|
||||||
extern const uint8_t BITMAP_BatteryLevel5[17];
|
|
||||||
|
|
||||||
extern const uint8_t BITMAP_USB_C[9];
|
extern const uint8_t BITMAP_USB_C[9];
|
||||||
|
|
||||||
@@ -25,36 +21,20 @@ extern const uint8_t BITMAP_F_Key[6];
|
|||||||
extern const uint8_t BITMAP_VOX[18];
|
extern const uint8_t BITMAP_VOX[18];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
extern const uint8_t BITMAP_XB[12];
|
||||||
extern const uint8_t BITMAP_WX[12];
|
|
||||||
#else
|
|
||||||
extern const uint8_t BITMAP_XB[12];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern const uint8_t BITMAP_TDR1[12];
|
extern const uint8_t BITMAP_TDR1[16];
|
||||||
extern const uint8_t BITMAP_TDR2[12];
|
extern const uint8_t BITMAP_TDR2[10];
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
extern const uint8_t BITMAP_VoicePrompt[9];
|
extern const uint8_t BITMAP_VoicePrompt[9];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
|
||||||
extern const uint8_t BITMAP_FM[12];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
extern const uint8_t BITMAP_NOAA[12];
|
extern const uint8_t BITMAP_NOAA[11];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const uint8_t BITMAP_Antenna[5];
|
extern const uint8_t BITMAP_Antenna[5];
|
||||||
extern const uint8_t BITMAP_AntennaLevel1[3];
|
|
||||||
extern const uint8_t BITMAP_AntennaLevel2[3];
|
|
||||||
extern const uint8_t BITMAP_AntennaLevel3[3];
|
|
||||||
extern const uint8_t BITMAP_AntennaLevel4[3];
|
|
||||||
extern const uint8_t BITMAP_AntennaLevel5[3];
|
|
||||||
extern const uint8_t BITMAP_AntennaLevel6[3];
|
|
||||||
|
|
||||||
extern const uint8_t BITMAP_MARKER[8];
|
|
||||||
|
|
||||||
extern const uint8_t BITMAP_VFO_Default[8];
|
extern const uint8_t BITMAP_VFO_Default[8];
|
||||||
extern const uint8_t BITMAP_VFO_NotDefault[8];
|
extern const uint8_t BITMAP_VFO_NotDefault[8];
|
||||||
|
|||||||
393
board.c
393
board.c
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "app/dtmf.h"
|
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
#include "app/fm.h"
|
#include "app/fm.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -26,11 +25,11 @@
|
|||||||
#include "bsp/dp32g030/saradc.h"
|
#include "bsp/dp32g030/saradc.h"
|
||||||
#include "bsp/dp32g030/syscon.h"
|
#include "bsp/dp32g030/syscon.h"
|
||||||
#include "driver/adc.h"
|
#include "driver/adc.h"
|
||||||
//#include "driver/backlight.h"
|
#include "driver/backlight.h"
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
#include "driver/bk1080.h"
|
#include "driver/bk1080.h"
|
||||||
#endif
|
#endif
|
||||||
#include "driver/bk4819.h"
|
|
||||||
#include "driver/crc.h"
|
#include "driver/crc.h"
|
||||||
#include "driver/eeprom.h"
|
#include "driver/eeprom.h"
|
||||||
#include "driver/flash.h"
|
#include "driver/flash.h"
|
||||||
@@ -44,16 +43,6 @@
|
|||||||
#if defined(ENABLE_OVERLAY)
|
#if defined(ENABLE_OVERLAY)
|
||||||
#include "sram-overlay.h"
|
#include "sram-overlay.h"
|
||||||
#endif
|
#endif
|
||||||
#include "ui/menu.h"
|
|
||||||
|
|
||||||
static const uint32_t gDefaultFrequencyTable[] =
|
|
||||||
{
|
|
||||||
14500000, //
|
|
||||||
14550000, //
|
|
||||||
43300000, //
|
|
||||||
43320000, //
|
|
||||||
43350000 //
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(ENABLE_OVERLAY)
|
#if defined(ENABLE_OVERLAY)
|
||||||
void BOARD_FLASH_Init(void)
|
void BOARD_FLASH_Init(void)
|
||||||
@@ -94,8 +83,6 @@ void BOARD_GPIO_Init(void)
|
|||||||
| GPIO_DIR_6_MASK // INPUT
|
| GPIO_DIR_6_MASK // INPUT
|
||||||
);
|
);
|
||||||
GPIOB->DIR |= 0
|
GPIOB->DIR |= 0
|
||||||
// Back light
|
|
||||||
| GPIO_DIR_6_BITS_OUTPUT
|
|
||||||
// ST7565
|
// ST7565
|
||||||
| GPIO_DIR_9_BITS_OUTPUT
|
| GPIO_DIR_9_BITS_OUTPUT
|
||||||
// ST7565 + SWD IO
|
// ST7565 + SWD IO
|
||||||
@@ -183,14 +170,10 @@ void BOARD_PORTCON_Init(void)
|
|||||||
// PORT B pin selection
|
// PORT B pin selection
|
||||||
|
|
||||||
PORTCON_PORTB_SEL0 &= ~(0
|
PORTCON_PORTB_SEL0 &= ~(0
|
||||||
// Back light
|
|
||||||
| PORTCON_PORTB_SEL0_B6_MASK
|
|
||||||
// SPI0 SSN
|
// SPI0 SSN
|
||||||
| PORTCON_PORTB_SEL0_B7_MASK
|
| PORTCON_PORTB_SEL0_B7_MASK
|
||||||
);
|
);
|
||||||
PORTCON_PORTB_SEL0 |= 0
|
PORTCON_PORTB_SEL0 |= 0
|
||||||
// Back light
|
|
||||||
| PORTCON_PORTB_SEL0_B6_BITS_GPIOB6
|
|
||||||
// SPI0 SSN
|
// SPI0 SSN
|
||||||
| PORTCON_PORTB_SEL0_B7_BITS_SPI0_SSN
|
| PORTCON_PORTB_SEL0_B7_BITS_SPI0_SSN
|
||||||
;
|
;
|
||||||
@@ -508,375 +491,15 @@ void BOARD_Init(void)
|
|||||||
{
|
{
|
||||||
BOARD_PORTCON_Init();
|
BOARD_PORTCON_Init();
|
||||||
BOARD_GPIO_Init();
|
BOARD_GPIO_Init();
|
||||||
|
BACKLIGHT_InitHardware();
|
||||||
BOARD_ADC_Init();
|
BOARD_ADC_Init();
|
||||||
ST7565_Init(true);
|
ST7565_Init();
|
||||||
#ifdef ENABLE_FMRADIO
|
|
||||||
BK1080_Init(0, false);
|
|
||||||
#endif
|
|
||||||
CRC_Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BOARD_EEPROM_Init(void)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
uint8_t Data[16];
|
|
||||||
|
|
||||||
memset(Data, 0, sizeof(Data));
|
|
||||||
|
|
||||||
// 0E70..0E77
|
|
||||||
EEPROM_ReadBuffer(0x0E70, Data, 8);
|
|
||||||
gEeprom.CHAN_1_CALL = IS_MR_CHANNEL(Data[0]) ? Data[0] : MR_CHANNEL_FIRST;
|
|
||||||
gEeprom.SQUELCH_LEVEL = (Data[1] < 10) ? Data[1] : 1;
|
|
||||||
gEeprom.TX_TIMEOUT_TIMER = (Data[2] < 11) ? Data[2] : 1;
|
|
||||||
#ifdef ENABLE_NOAA
|
|
||||||
gEeprom.NOAA_AUTO_SCAN = (Data[3] < 2) ? Data[3] : false;
|
|
||||||
#endif
|
|
||||||
gEeprom.KEY_LOCK = (Data[4] < 2) ? Data[4] : false;
|
|
||||||
#ifdef ENABLE_VOX
|
|
||||||
gEeprom.VOX_SWITCH = (Data[5] < 2) ? Data[5] : false;
|
|
||||||
gEeprom.VOX_LEVEL = (Data[6] < 10) ? Data[6] : 1;
|
|
||||||
#endif
|
|
||||||
gEeprom.MIC_SENSITIVITY = (Data[7] < 5) ? Data[7] : 4;
|
|
||||||
|
|
||||||
// 0E78..0E7F
|
|
||||||
EEPROM_ReadBuffer(0x0E78, Data, 8);
|
|
||||||
gEeprom.CHANNEL_DISPLAY_MODE = (Data[1] < 4) ? Data[1] : MDF_FREQUENCY; // 4 instead of 3 - extra display mode
|
|
||||||
gEeprom.CROSS_BAND_RX_TX = (Data[2] < 3) ? Data[2] : CROSS_BAND_OFF;
|
|
||||||
gEeprom.BATTERY_SAVE = (Data[3] < 5) ? Data[3] : 4;
|
|
||||||
gEeprom.DUAL_WATCH = (Data[4] < 3) ? Data[4] : DUAL_WATCH_CHAN_A;
|
|
||||||
gEeprom.BACKLIGHT = (Data[5] < ARRAY_SIZE(gSubMenu_BACKLIGHT)) ? Data[5] : 3;
|
|
||||||
gEeprom.TAIL_NOTE_ELIMINATION = (Data[6] < 2) ? Data[6] : false;
|
|
||||||
gEeprom.VFO_OPEN = (Data[7] < 2) ? Data[7] : true;
|
|
||||||
|
|
||||||
// 0E80..0E87
|
|
||||||
EEPROM_ReadBuffer(0x0E80, Data, 8);
|
|
||||||
gEeprom.ScreenChannel[0] = IS_VALID_CHANNEL(Data[0]) ? Data[0] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
|
||||||
gEeprom.ScreenChannel[1] = IS_VALID_CHANNEL(Data[3]) ? Data[3] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
|
||||||
gEeprom.MrChannel[0] = IS_MR_CHANNEL(Data[1]) ? Data[1] : MR_CHANNEL_FIRST;
|
|
||||||
gEeprom.MrChannel[1] = IS_MR_CHANNEL(Data[4]) ? Data[4] : MR_CHANNEL_FIRST;
|
|
||||||
gEeprom.FreqChannel[0] = IS_FREQ_CHANNEL(Data[2]) ? Data[2] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
|
||||||
gEeprom.FreqChannel[1] = IS_FREQ_CHANNEL(Data[5]) ? Data[5] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
|
||||||
#ifdef ENABLE_NOAA
|
|
||||||
gEeprom.NoaaChannel[0] = IS_NOAA_CHANNEL(Data[6]) ? Data[6] : NOAA_CHANNEL_FIRST;
|
|
||||||
gEeprom.NoaaChannel[1] = IS_NOAA_CHANNEL(Data[7]) ? Data[7] : NOAA_CHANNEL_FIRST;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
{ // 0E88..0E8F
|
BK1080_Init(0, false);
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint16_t SelectedFrequency;
|
|
||||||
uint8_t SelectedChannel;
|
|
||||||
uint8_t IsMrMode;
|
|
||||||
uint8_t Padding[8];
|
|
||||||
} __attribute__((packed)) FM;
|
|
||||||
|
|
||||||
EEPROM_ReadBuffer(0x0E88, &FM, 8);
|
|
||||||
gEeprom.FM_LowerLimit = 760;
|
|
||||||
gEeprom.FM_UpperLimit = 1080;
|
|
||||||
if (FM.SelectedFrequency < gEeprom.FM_LowerLimit || FM.SelectedFrequency > gEeprom.FM_UpperLimit)
|
|
||||||
gEeprom.FM_SelectedFrequency = 960;
|
|
||||||
else
|
|
||||||
gEeprom.FM_SelectedFrequency = FM.SelectedFrequency;
|
|
||||||
|
|
||||||
gEeprom.FM_SelectedChannel = FM.SelectedChannel;
|
|
||||||
gEeprom.FM_IsMrMode = (FM.IsMrMode < 2) ? FM.IsMrMode : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0E40..0E67
|
|
||||||
EEPROM_ReadBuffer(0x0E40, gFM_Channels, sizeof(gFM_Channels));
|
|
||||||
FM_ConfigureChannelState();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 0E90..0E97
|
#if defined(ENABLE_UART) || defined(ENABLED_AIRCOPY)
|
||||||
EEPROM_ReadBuffer(0x0E90, Data, 8);
|
CRC_Init();
|
||||||
gEeprom.BEEP_CONTROL = (Data[0] < 2) ? Data[0] : true;
|
#endif
|
||||||
gEeprom.KEY_1_SHORT_PRESS_ACTION = (Data[1] < ACTION_OPT_LEN) ? Data[1] : ACTION_OPT_MONITOR;
|
|
||||||
gEeprom.KEY_1_LONG_PRESS_ACTION = (Data[2] < ACTION_OPT_LEN) ? Data[2] : ACTION_OPT_FLASHLIGHT;
|
|
||||||
gEeprom.KEY_2_SHORT_PRESS_ACTION = (Data[3] < ACTION_OPT_LEN) ? Data[3] : ACTION_OPT_SCAN;
|
|
||||||
gEeprom.KEY_2_LONG_PRESS_ACTION = (Data[4] < ACTION_OPT_LEN) ? Data[4] : ACTION_OPT_NONE;
|
|
||||||
gEeprom.SCAN_RESUME_MODE = (Data[5] < 3) ? Data[5] : SCAN_RESUME_CO;
|
|
||||||
gEeprom.AUTO_KEYPAD_LOCK = (Data[6] < 2) ? Data[6] : false;
|
|
||||||
gEeprom.POWER_ON_DISPLAY_MODE = (Data[7] < 4) ? Data[7] : POWER_ON_DISPLAY_MODE_VOLTAGE;
|
|
||||||
|
|
||||||
// 0E98..0E9F
|
|
||||||
EEPROM_ReadBuffer(0x0E98, Data, 8);
|
|
||||||
memmove(&gEeprom.POWER_ON_PASSWORD, Data, 4);
|
|
||||||
|
|
||||||
// 0EA0..0EA7
|
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
EEPROM_ReadBuffer(0x0EA0, Data, 8);
|
|
||||||
gEeprom.VOICE_PROMPT = (Data[0] < 3) ? Data[0] : VOICE_PROMPT_ENGLISH;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 0EA8..0EAF
|
|
||||||
EEPROM_ReadBuffer(0x0EA8, Data, 8);
|
|
||||||
#ifdef ENABLE_ALARM
|
|
||||||
gEeprom.ALARM_MODE = (Data[0] < 2) ? Data[0] : true;
|
|
||||||
#endif
|
|
||||||
gEeprom.ROGER = (Data[1] < 3) ? Data[1] : ROGER_MODE_OFF;
|
|
||||||
gEeprom.REPEATER_TAIL_TONE_ELIMINATION = (Data[2] < 11) ? Data[2] : 0;
|
|
||||||
gEeprom.TX_VFO = (Data[3] < 2) ? Data[3] : 0;
|
|
||||||
|
|
||||||
// 0ED0..0ED7
|
|
||||||
EEPROM_ReadBuffer(0x0ED0, Data, 8);
|
|
||||||
gEeprom.DTMF_SIDE_TONE = (Data[0] < 2) ? Data[0] : true;
|
|
||||||
gEeprom.DTMF_SEPARATE_CODE = DTMF_ValidateCodes((char *)(Data + 1), 1) ? Data[1] : '*';
|
|
||||||
gEeprom.DTMF_GROUP_CALL_CODE = DTMF_ValidateCodes((char *)(Data + 2), 1) ? Data[2] : '#';
|
|
||||||
gEeprom.DTMF_DECODE_RESPONSE = (Data[3] < 4) ? Data[3] : 0;
|
|
||||||
gEeprom.DTMF_auto_reset_time = (Data[4] < 61) ? Data[4] : (Data[4] >= 5) ? Data[4] : 10;
|
|
||||||
gEeprom.DTMF_PRELOAD_TIME = (Data[5] < 101) ? Data[5] * 10 : 300;
|
|
||||||
gEeprom.DTMF_FIRST_CODE_PERSIST_TIME = (Data[6] < 101) ? Data[6] * 10 : 100;
|
|
||||||
gEeprom.DTMF_HASH_CODE_PERSIST_TIME = (Data[7] < 101) ? Data[7] * 10 : 100;
|
|
||||||
|
|
||||||
// 0ED8..0EDF
|
|
||||||
EEPROM_ReadBuffer(0x0ED8, Data, 8);
|
|
||||||
gEeprom.DTMF_CODE_PERSIST_TIME = (Data[0] < 101) ? Data[0] * 10 : 100;
|
|
||||||
gEeprom.DTMF_CODE_INTERVAL_TIME = (Data[1] < 101) ? Data[1] * 10 : 100;
|
|
||||||
gEeprom.PERMIT_REMOTE_KILL = (Data[2] < 2) ? Data[2] : true;
|
|
||||||
|
|
||||||
// 0EE0..0EE7
|
|
||||||
EEPROM_ReadBuffer(0x0EE0, Data, 8);
|
|
||||||
if (DTMF_ValidateCodes((char *)Data, 8))
|
|
||||||
memmove(gEeprom.ANI_DTMF_ID, Data, 8);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memset(gEeprom.ANI_DTMF_ID, 0, sizeof(gEeprom.ANI_DTMF_ID));
|
|
||||||
strcpy(gEeprom.ANI_DTMF_ID, "123");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0EE8..0EEF
|
|
||||||
EEPROM_ReadBuffer(0x0EE8, Data, 8);
|
|
||||||
if (DTMF_ValidateCodes((char *)Data, 8))
|
|
||||||
memmove(gEeprom.KILL_CODE, Data, 8);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memset(gEeprom.KILL_CODE, 0, sizeof(gEeprom.KILL_CODE));
|
|
||||||
strcpy(gEeprom.KILL_CODE, "ABCD9");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0EF0..0EF7
|
|
||||||
EEPROM_ReadBuffer(0x0EF0, Data, 8);
|
|
||||||
if (DTMF_ValidateCodes((char *)Data, 8))
|
|
||||||
memmove(gEeprom.REVIVE_CODE, Data, 8);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memset(gEeprom.REVIVE_CODE, 0, sizeof(gEeprom.REVIVE_CODE));
|
|
||||||
strcpy(gEeprom.REVIVE_CODE, "9DCBA");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0EF8..0F07
|
|
||||||
EEPROM_ReadBuffer(0x0EF8, Data, 16);
|
|
||||||
if (DTMF_ValidateCodes((char *)Data, 16))
|
|
||||||
memmove(gEeprom.DTMF_UP_CODE, Data, 16);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memset(gEeprom.DTMF_UP_CODE, 0, sizeof(gEeprom.DTMF_UP_CODE));
|
|
||||||
strcpy(gEeprom.DTMF_UP_CODE, "12345");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0F08..0F17
|
|
||||||
EEPROM_ReadBuffer(0x0F08, Data, 16);
|
|
||||||
if (DTMF_ValidateCodes((char *)Data, 16))
|
|
||||||
memmove(gEeprom.DTMF_DOWN_CODE, Data, 16);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memset(gEeprom.DTMF_DOWN_CODE, 0, sizeof(gEeprom.DTMF_DOWN_CODE));
|
|
||||||
strcpy(gEeprom.DTMF_DOWN_CODE, "54321");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0F18..0F1F
|
|
||||||
EEPROM_ReadBuffer(0x0F18, Data, 8);
|
|
||||||
// gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 2) ? Data[0] : false;
|
|
||||||
gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 3) ? Data[0] : false; // we now have 'all' channel scan option
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
const unsigned int j = 1 + (i * 3);
|
|
||||||
gEeprom.SCAN_LIST_ENABLED[i] = (Data[j + 0] < 2) ? Data[j] : false;
|
|
||||||
gEeprom.SCANLIST_PRIORITY_CH1[i] = Data[j + 1];
|
|
||||||
gEeprom.SCANLIST_PRIORITY_CH2[i] = Data[j + 2];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0F40..0F47
|
|
||||||
EEPROM_ReadBuffer(0x0F40, Data, 8);
|
|
||||||
gSetting_F_LOCK = (Data[0] < 6) ? Data[0] : F_LOCK_OFF;
|
|
||||||
gSetting_350TX = (Data[1] < 2) ? Data[1] : false; // was true
|
|
||||||
gSetting_KILLED = (Data[2] < 2) ? Data[2] : false;
|
|
||||||
gSetting_200TX = (Data[3] < 2) ? Data[3] : false;
|
|
||||||
gSetting_500TX = (Data[4] < 2) ? Data[4] : false;
|
|
||||||
gSetting_350EN = (Data[5] < 2) ? Data[5] : true;
|
|
||||||
gSetting_ScrambleEnable = (Data[6] < 2) ? Data[6] : true;
|
|
||||||
gSetting_TX_EN = (Data[7] & (1u << 0)) ? true : false;
|
|
||||||
gSetting_live_DTMF_decoder = (Data[7] & (1u << 1)) ? true : false;
|
|
||||||
gSetting_battery_text = (((Data[7] >> 2) & 3u) <= 2) ? (Data[7] >> 2) & 3 : 2;
|
|
||||||
#ifdef ENABLE_AUDIO_BAR
|
|
||||||
gSetting_mic_bar = (Data[7] & (1u << 4)) ? true : false;
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_AM_FIX
|
|
||||||
gSetting_AM_fix = (Data[7] & (1u << 5)) ? true : false;
|
|
||||||
#endif
|
|
||||||
gSetting_backlight_on_tx_rx = (Data[7] >> 6) & 3u;
|
|
||||||
|
|
||||||
if (!gEeprom.VFO_OPEN)
|
|
||||||
{
|
|
||||||
gEeprom.ScreenChannel[0] = gEeprom.MrChannel[0];
|
|
||||||
gEeprom.ScreenChannel[1] = gEeprom.MrChannel[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0D60..0E27
|
|
||||||
EEPROM_ReadBuffer(0x0D60, gMR_ChannelAttributes, sizeof(gMR_ChannelAttributes));
|
|
||||||
|
|
||||||
// 0F30..0F3F
|
|
||||||
EEPROM_ReadBuffer(0x0F30, gCustomAesKey, sizeof(gCustomAesKey));
|
|
||||||
bHasCustomAesKey = false;
|
|
||||||
for (i = 0; i < ARRAY_SIZE(gCustomAesKey); i++)
|
|
||||||
{
|
|
||||||
if (gCustomAesKey[i] != 0xFFFFFFFFu)
|
|
||||||
{
|
|
||||||
bHasCustomAesKey = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BOARD_EEPROM_LoadMoreSettings(void)
|
|
||||||
{
|
|
||||||
// uint8_t Mic;
|
|
||||||
|
|
||||||
EEPROM_ReadBuffer(0x1EC0, gEEPROM_1EC0_0, 8);
|
|
||||||
memmove(gEEPROM_1EC0_1, gEEPROM_1EC0_0, 8);
|
|
||||||
memmove(gEEPROM_1EC0_2, gEEPROM_1EC0_0, 8);
|
|
||||||
memmove(gEEPROM_1EC0_3, gEEPROM_1EC0_0, 8);
|
|
||||||
|
|
||||||
// 8 * 16-bit values
|
|
||||||
EEPROM_ReadBuffer(0x1EC0, gEEPROM_RSSI_CALIB[0], 8);
|
|
||||||
EEPROM_ReadBuffer(0x1EC8, gEEPROM_RSSI_CALIB[1], 8);
|
|
||||||
|
|
||||||
EEPROM_ReadBuffer(0x1F40, gBatteryCalibration, 12);
|
|
||||||
if (gBatteryCalibration[0] >= 5000)
|
|
||||||
{
|
|
||||||
gBatteryCalibration[0] = 1900;
|
|
||||||
gBatteryCalibration[1] = 2000;
|
|
||||||
}
|
|
||||||
gBatteryCalibration[5] = 2300;
|
|
||||||
|
|
||||||
#ifdef ENABLE_VOX
|
|
||||||
EEPROM_ReadBuffer(0x1F50 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX1_THRESHOLD, 2);
|
|
||||||
EEPROM_ReadBuffer(0x1F68 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX0_THRESHOLD, 2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//EEPROM_ReadBuffer(0x1F80 + gEeprom.MIC_SENSITIVITY, &Mic, 1);
|
|
||||||
//gEeprom.MIC_SENSITIVITY_TUNING = (Mic < 32) ? Mic : 15;
|
|
||||||
gEeprom.MIC_SENSITIVITY_TUNING = gMicGain_dB2[gEeprom.MIC_SENSITIVITY];
|
|
||||||
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
int16_t BK4819_XtalFreqLow;
|
|
||||||
uint16_t EEPROM_1F8A;
|
|
||||||
uint16_t EEPROM_1F8C;
|
|
||||||
uint8_t VOLUME_GAIN;
|
|
||||||
uint8_t DAC_GAIN;
|
|
||||||
} __attribute__((packed)) Misc;
|
|
||||||
|
|
||||||
// radio 1 .. 04 00 46 00 50 00 2C 0E
|
|
||||||
// radio 2 .. 05 00 46 00 50 00 2C 0E
|
|
||||||
EEPROM_ReadBuffer(0x1F88, &Misc, 8);
|
|
||||||
|
|
||||||
gEeprom.BK4819_XTAL_FREQ_LOW = (Misc.BK4819_XtalFreqLow >= -1000 && Misc.BK4819_XtalFreqLow <= 1000) ? Misc.BK4819_XtalFreqLow : 0;
|
|
||||||
gEEPROM_1F8A = Misc.EEPROM_1F8A & 0x01FF;
|
|
||||||
gEEPROM_1F8C = Misc.EEPROM_1F8C & 0x01FF;
|
|
||||||
gEeprom.VOLUME_GAIN = (Misc.VOLUME_GAIN < 64) ? Misc.VOLUME_GAIN : 58;
|
|
||||||
gEeprom.DAC_GAIN = (Misc.DAC_GAIN < 16) ? Misc.DAC_GAIN : 8;
|
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_3B, 22656 + gEeprom.BK4819_XTAL_FREQ_LOW);
|
|
||||||
// BK4819_WriteRegister(BK4819_REG_3C, gEeprom.BK4819_XTAL_FREQ_HIGH);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t BOARD_fetchChannelFrequency(const int channel)
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32_t frequency;
|
|
||||||
uint32_t offset;
|
|
||||||
} __attribute__((packed)) info;
|
|
||||||
|
|
||||||
EEPROM_ReadBuffer(channel * 16, &info, sizeof(info));
|
|
||||||
|
|
||||||
return info.frequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BOARD_fetchChannelName(char *s, const int channel)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (s == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
memset(s, 0, 11); // 's' had better be large enough !
|
|
||||||
|
|
||||||
if (channel < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!RADIO_CheckValidChannel(channel, false, 0))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
EEPROM_ReadBuffer(0x0F50 + (channel * 16), s + 0, 8);
|
|
||||||
EEPROM_ReadBuffer(0x0F58 + (channel * 16), s + 8, 2);
|
|
||||||
|
|
||||||
for (i = 0; i < 10; i++)
|
|
||||||
if (s[i] < 32 || s[i] > 127)
|
|
||||||
break; // invalid char
|
|
||||||
|
|
||||||
s[i--] = 0; // null term
|
|
||||||
|
|
||||||
while (i >= 0 && s[i] == 32) // trim trailing spaces
|
|
||||||
s[i--] = 0; // null term
|
|
||||||
}
|
|
||||||
|
|
||||||
void BOARD_FactoryReset(bool bIsAll)
|
|
||||||
{
|
|
||||||
uint16_t i;
|
|
||||||
uint8_t Template[8];
|
|
||||||
|
|
||||||
memset(Template, 0xFF, sizeof(Template));
|
|
||||||
|
|
||||||
for (i = 0x0C80; i < 0x1E00; i += 8)
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
!(i >= 0x0EE0 && i < 0x0F18) && // ANI ID + DTMF codes
|
|
||||||
!(i >= 0x0F30 && i < 0x0F50) && // AES KEY + F LOCK + Scramble Enable
|
|
||||||
!(i >= 0x1C00 && i < 0x1E00) && // DTMF contacts
|
|
||||||
!(i >= 0x0EB0 && i < 0x0ED0) && // Welcome strings
|
|
||||||
!(i >= 0x0EA0 && i < 0x0EA8) && // Voice Prompt
|
|
||||||
(bIsAll ||
|
|
||||||
(
|
|
||||||
!(i >= 0x0D60 && i < 0x0E28) && // MR Channel Attributes
|
|
||||||
!(i >= 0x0F18 && i < 0x0F30) && // Scan List
|
|
||||||
!(i >= 0x0F50 && i < 0x1C00) && // MR Channel Names
|
|
||||||
!(i >= 0x0E40 && i < 0x0E70) && // FM Channels
|
|
||||||
!(i >= 0x0E88 && i < 0x0E90) // FM settings
|
|
||||||
))
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EEPROM_WriteBuffer(i, Template);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bIsAll)
|
|
||||||
{
|
|
||||||
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_FIRST + BAND6_400MHz, 43350000);
|
|
||||||
|
|
||||||
// set the first few memory channels
|
|
||||||
for (i = 0; i < ARRAY_SIZE(gDefaultFrequencyTable); i++)
|
|
||||||
{
|
|
||||||
const uint32_t Frequency = gDefaultFrequencyTable[i];
|
|
||||||
gRxVfo->freq_config_RX.Frequency = Frequency;
|
|
||||||
gRxVfo->freq_config_TX.Frequency = Frequency;
|
|
||||||
gRxVfo->Band = FREQUENCY_GetBand(Frequency);
|
|
||||||
SETTINGS_SaveChannel(MR_CHANNEL_FIRST + i, 0, gRxVfo, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
5
board.h
5
board.h
@@ -26,11 +26,6 @@ void BOARD_PORTCON_Init(void);
|
|||||||
void BOARD_ADC_Init(void);
|
void BOARD_ADC_Init(void);
|
||||||
void BOARD_ADC_GetBatteryInfo(uint16_t *pVoltage, uint16_t *pCurrent);
|
void BOARD_ADC_GetBatteryInfo(uint16_t *pVoltage, uint16_t *pCurrent);
|
||||||
void BOARD_Init(void);
|
void BOARD_Init(void);
|
||||||
void BOARD_EEPROM_Init(void);
|
|
||||||
void BOARD_EEPROM_LoadMoreSettings(void);
|
|
||||||
uint32_t BOARD_fetchChannelFrequency(const int channel);
|
|
||||||
void BOARD_fetchChannelName(char *s, const int channel);
|
|
||||||
void BOARD_FactoryReset(bool bIsAll);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
146
bsp/dp32g030/pwmplus.h
Normal file
146
bsp/dp32g030/pwmplus.h
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
#ifndef HARDWARE_DP32G030_PWMPLUS_H
|
||||||
|
#define HARDWARE_DP32G030_PWMPLUS_H
|
||||||
|
|
||||||
|
#define PWM_PLUS0_BASE_ADDR 0x400B4000U
|
||||||
|
|
||||||
|
//---------------
|
||||||
|
|
||||||
|
#define PWMPLUS_CFG 0x00U
|
||||||
|
|
||||||
|
#define PWMPLUS_CFG_COUNTER_EN_SHIFT 0U
|
||||||
|
#define PWMPLUS_CFG_COUNTER_EN_WIDTH 1U
|
||||||
|
#define PWMPLUS_CFG_COUNTER_EN_MASK (((1U << PWMPLUS_CFG_COUNTER_EN_WIDTH) - 1U) << PWMPLUS_CFG_COUNTER_EN_SHIFT)
|
||||||
|
#define PWMPLUS_CFG_COUNTER_EN_VALUE_ENABLE 1U
|
||||||
|
#define PWMPLUS_CFG_COUNTER_EN_BITS_ENABLE (PWMPLUS_CFG_COUNTER_EN_VALUE_ENABLE << PWMPLUS_CFG_COUNTER_EN_SHIFT)
|
||||||
|
|
||||||
|
#define PWMPLUS_CFG_CNT_TYPE_SHIFT 1U
|
||||||
|
|
||||||
|
#define PWMPLUS_CFG_CNT_REP_SHIFT 2U
|
||||||
|
#define PWMPLUS_CFG_CNT_REP_WIDTH 1U
|
||||||
|
#define PWMPLUS_CFG_CNT_REP_VALUE_ENABLE 1U
|
||||||
|
#define PWMPLUS_CFG_CNT_REP_BITS_ENABLE (PWMPLUS_CFG_CNT_REP_VALUE_ENABLE << PWMPLUS_CFG_CNT_REP_SHIFT)
|
||||||
|
|
||||||
|
#define PWMPLUS_CFG_OUT_MODE_SHIFT 3U
|
||||||
|
#define PWMPLUS_CFG_OUT_MODE_VALUE_ENABLE 1U
|
||||||
|
#define PWMPLUS_CFG_OUT_MODE_BITS_ENABLE (PWMPLUS_CFG_OUT_MODE_VALUE_ENABLE << PWMPLUS_CFG_OUT_MODE_SHIFT)
|
||||||
|
|
||||||
|
#define PWMPLUS_CFG_AUTO_RELOAD_SHIFT 8U
|
||||||
|
|
||||||
|
//---------------
|
||||||
|
|
||||||
|
#define PWMPLUS_GEN 0x04U
|
||||||
|
|
||||||
|
#define PWMPLUS_GEN_CH0_OE_SHIFT 24U
|
||||||
|
#define PWMPLUS_GEN_CH0_OE_WIDTH 1U
|
||||||
|
#define PWMPLUS_GEN_CH0_OE_VALUE_ENABLE 1U
|
||||||
|
#define PWMPLUS_GEN_CH0_OE_BITS_ENABLE (PWMPLUS_GEN_CH0_OE_VALUE_ENABLE << PWMPLUS_GEN_CH0_OE_SHIFT)
|
||||||
|
|
||||||
|
#define PWMPLUS_GEN_CH0_OUTINV_SHIFT 16U
|
||||||
|
#define PWMPLUS_GEN_CH0_OUTINV_WIDTH 1U
|
||||||
|
#define PWMPLUS_GEN_CH0_OUTINV_VALUE_ENABLE 1U
|
||||||
|
#define PWMPLUS_GEN_CH0_OUTINV_BITS_ENABLE (PWMPLUS_GEN_CH0_OUTINV_VALUE_ENABLE << PWMPLUS_GEN_CH0_OUTINV_SHIFT)
|
||||||
|
|
||||||
|
#define PWMPLUS_GEN_CH0_START_SHIFT 8U
|
||||||
|
#define PWMPLUS_GEN_CH0_START_WIDTH 1U
|
||||||
|
#define PWMPLUS_GEN_CH0_START_VALUE_ENABLE 1U
|
||||||
|
#define PWMPLUS_GEN_CH0_START_BITS_ENABLE (PWMPLUS_GEN_CH0_START_VALUE_ENABLE << PWMPLUS_GEN_CH0_START_SHIFT)
|
||||||
|
|
||||||
|
#define PWMPLUS_GEN_CH0_IDLE_SHIFT 0U
|
||||||
|
#define PWMPLUS_GEN_CH0_IDLE_WIDTH 1U
|
||||||
|
#define PWMPLUS_GEN_CH0_IDLE_VALUE_ENABLE 1U
|
||||||
|
#define PWMPLUS_GEN_CH0_IDLE_BITS_ENABLE (PWMPLUS_GEN_CH0_IDLE_VALUE_ENABLE << PWMPLUS_GEN_CH0_IDLE_SHIFT)
|
||||||
|
|
||||||
|
//---------------
|
||||||
|
|
||||||
|
#define PWMPLUS_CLKSRC 0x08U
|
||||||
|
#define PWMPLUS_BRAKE_CFG 0x0CU
|
||||||
|
#define PWMPLUS_MASK_LEV 0x10U
|
||||||
|
#define PWMPLUS_PERIOD 0x1CU
|
||||||
|
#define PWMPLUS_CH0_COMP 0x20U
|
||||||
|
#define PWMPLUS_CH1_COMP 0x24U
|
||||||
|
#define PWMPLUS_CH2_COMP 0x28U
|
||||||
|
#define PWMPLUS_CH0_DT 0x30U
|
||||||
|
#define PWMPLUS_CH1_DT 0x34U
|
||||||
|
#define PWMPLUS_CH2_DT 0x38U
|
||||||
|
#define PWMPLUS_TRIG_COMP 0x40U
|
||||||
|
#define PWMPLUS_TRIG_CFG 0x44U
|
||||||
|
#define PWMPLUS_IE 0x60U
|
||||||
|
#define PWMPLUS_IF 0x64U
|
||||||
|
#define PWMPLUS_SWLOAD 0x84U
|
||||||
|
#define PWMPLUS_MASK_EN 0x88
|
||||||
|
#define PWMPLUS_CNT_ST 0xE0
|
||||||
|
#define PWMPLUS_BRAKE_ST 0xE4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define PWM_PLUS0_CFG_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CFG)
|
||||||
|
#define PWM_PLUS0_CFG (*(volatile uint32_t *)PWM_PLUS0_CFG_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_GEN_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_GEN)
|
||||||
|
#define PWM_PLUS0_GEN (*(volatile uint32_t *)PWM_PLUS0_GEN_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_CLKSRC_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CLKSRC)
|
||||||
|
#define PWM_PLUS0_CLKSRC (*(volatile uint32_t *)PWM_PLUS0_CLKSRC_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_BRAKE_CFG_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_BRAKE_CFG)
|
||||||
|
#define PWM_PLUS0_BRAKE_CFG (*(volatile uint32_t *)PWM_PLUS0_BRAKE_CFG_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_MASK_LEV_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_MASK_LEV)
|
||||||
|
#define PWM_PLUS0_MASK_LEV (*(volatile uint32_t *)PWM_PLUS0_MASK_LEV_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_PERIOD_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_PERIOD)
|
||||||
|
#define PWM_PLUS0_PERIOD (*(volatile uint32_t *)PWM_PLUS0_PERIOD_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_CH0_COMP_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH0_COMP)
|
||||||
|
#define PWM_PLUS0_CH0_COMP (*(volatile uint32_t *)PWM_PLUS0_CH0_COMP_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_CH1_COMP_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH1_COMP)
|
||||||
|
#define PWM_PLUS0_CH1_COMP (*(volatile uint32_t *)PWM_PLUS0_CH1_COMP_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_CH2_COMP_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH2_COMP)
|
||||||
|
#define PWM_PLUS0_CH2_COMP (*(volatile uint32_t *)PWM_PLUS0_CH2_COMP_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_CH0_DT_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH0_DT)
|
||||||
|
#define PWM_PLUS0_CH0_DT (*(volatile uint32_t *)PWM_PLUS0_CH0_DT_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_CH1_DT_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH1_DT)
|
||||||
|
#define PWM_PLUS0_CH1_DT (*(volatile uint32_t *)PWM_PLUS0_CH1_DT_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_CH2_DT_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH2_DT)
|
||||||
|
#define PWM_PLUS0_CH2_DT (*(volatile uint32_t *)PWM_PLUS0_CH2_DT_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_TRIG_COMP_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_TRIG_COMP)
|
||||||
|
#define PWM_PLUS0_TRIG_COMP (*(volatile uint32_t *)PWM_PLUS0_TRIG_COMP_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_TRIG_CFG_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_TRIG_CFG)
|
||||||
|
#define PWM_PLUS0_TRIG_CFG (*(volatile uint32_t *)PWM_PLUS0_TRIG_CFG_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_IE_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_IE)
|
||||||
|
#define PWM_PLUS0_IE (*(volatile uint32_t *)PWM_PLUS0_IE_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_IF_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_IF)
|
||||||
|
#define PWM_PLUS0_IF (*(volatile uint32_t *)PWM_PLUS0_IF_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_SWLOAD_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_SWLOAD)
|
||||||
|
#define PWM_PLUS0_SWLOAD (*(volatile uint32_t *)PWM_PLUS0_SWLOAD_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_MASK_EN_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_MASK_EN)
|
||||||
|
#define PWM_PLUS0_MASK_EN (*(volatile uint32_t *)PWM_PLUS0_MASK_EN_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_CNT_ST_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CNT_ST)
|
||||||
|
#define PWM_PLUS0_CNT_ST (*(volatile uint32_t *)PWM_PLUS0_CNT_ST_ADDR)
|
||||||
|
|
||||||
|
#define PWM_PLUS0_BRAKE_ST_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_BRAKE_ST)
|
||||||
|
#define PWM_PLUS0_BRAKE_ST (*(volatile uint32_t *)PWM_PLUS0_BRAKE_ST_ADDR)
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
@echo off
|
@echo off
|
||||||
docker build -t uvk5 .
|
docker build -t uvk5 .
|
||||||
docker run -v %CD%\compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make clean && make && cp firmware* compiled-firmware/"
|
docker run --rm -v %CD%\compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make clean && make && cp firmware* compiled-firmware/"
|
||||||
pause
|
pause
|
||||||
2
compile-with-docker.sh
Normal file → Executable file
2
compile-with-docker.sh
Normal file → Executable file
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
docker build -t uvk5 .
|
docker build -t uvk5 .
|
||||||
docker run -v $(PWD)/compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make && cp firmware* compiled-firmware/"
|
docker run --rm -v ${PWD}/compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make && cp firmware* compiled-firmware/"
|
||||||
|
|||||||
38
debugging.h
Normal file
38
debugging.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef DEBUGGING_H
|
||||||
|
#define DEBUGGING_H
|
||||||
|
|
||||||
|
#ifdef ENABLE_UART
|
||||||
|
|
||||||
|
#include "driver/uart.h"
|
||||||
|
#include "driver/bk4819.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "external/printf/printf.h"
|
||||||
|
#include "am_fix.h"
|
||||||
|
|
||||||
|
static inline void LogUart(const char *const str)
|
||||||
|
{
|
||||||
|
UART_Send(str, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void LogRegUart(uint16_t reg)
|
||||||
|
{
|
||||||
|
uint16_t regVal = BK4819_ReadRegister(reg);
|
||||||
|
char buf[32];
|
||||||
|
sprintf(buf, "reg%02X: %04X\n", reg, regVal);
|
||||||
|
LogUart(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void LogPrint()
|
||||||
|
{
|
||||||
|
uint16_t rssi = BK4819_GetRSSI();
|
||||||
|
uint16_t reg7e = BK4819_ReadRegister(0x7E);
|
||||||
|
char buf[32];
|
||||||
|
sprintf(buf, "reg7E: %d %2d %6d %2d %d rssi: %d\n", (reg7e >> 15),
|
||||||
|
(reg7e >> 12) & 0b111, (reg7e >> 5) & 0b1111111,
|
||||||
|
(reg7e >> 2) & 0b111, (reg7e >> 0) & 0b11, rssi);
|
||||||
|
LogUart(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -16,45 +16,103 @@
|
|||||||
|
|
||||||
#include "backlight.h"
|
#include "backlight.h"
|
||||||
#include "bsp/dp32g030/gpio.h"
|
#include "bsp/dp32g030/gpio.h"
|
||||||
|
#include "bsp/dp32g030/pwmplus.h"
|
||||||
|
#include "bsp/dp32g030/portcon.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
// this is decremented once every 500ms
|
// this is decremented once every 500ms
|
||||||
uint16_t gBacklightCountdown = 0;
|
uint16_t gBacklightCountdown_500ms = 0;
|
||||||
|
bool backlightOn;
|
||||||
|
|
||||||
|
void BACKLIGHT_InitHardware()
|
||||||
|
{
|
||||||
|
// 48MHz / 94 / 1024 ~ 500Hz
|
||||||
|
const uint32_t PWM_FREQUENCY_HZ = 1000;
|
||||||
|
PWM_PLUS0_CLKSRC |= ((48000000 / 1024 / PWM_FREQUENCY_HZ) << 16);
|
||||||
|
PWM_PLUS0_PERIOD = 1023;
|
||||||
|
|
||||||
|
PORTCON_PORTB_SEL0 &= ~(0
|
||||||
|
// Back light
|
||||||
|
| PORTCON_PORTB_SEL0_B6_MASK
|
||||||
|
);
|
||||||
|
PORTCON_PORTB_SEL0 |= 0
|
||||||
|
// Back light PWM
|
||||||
|
| PORTCON_PORTB_SEL0_B6_BITS_PWMP0_CH0
|
||||||
|
;
|
||||||
|
|
||||||
|
PWM_PLUS0_GEN =
|
||||||
|
PWMPLUS_GEN_CH0_OE_BITS_ENABLE |
|
||||||
|
PWMPLUS_GEN_CH0_OUTINV_BITS_ENABLE |
|
||||||
|
0;
|
||||||
|
|
||||||
|
PWM_PLUS0_CFG =
|
||||||
|
PWMPLUS_CFG_CNT_REP_BITS_ENABLE |
|
||||||
|
PWMPLUS_CFG_COUNTER_EN_BITS_ENABLE |
|
||||||
|
0;
|
||||||
|
}
|
||||||
|
|
||||||
void BACKLIGHT_TurnOn(void)
|
void BACKLIGHT_TurnOn(void)
|
||||||
{
|
{
|
||||||
if (gEeprom.BACKLIGHT == 0)
|
if (gEeprom.BACKLIGHT_TIME == 0) {
|
||||||
|
BACKLIGHT_TurnOff();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// turn the backlight ON
|
|
||||||
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
|
|
||||||
|
|
||||||
switch (gEeprom.BACKLIGHT)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case 1: // 5 sec
|
|
||||||
gBacklightCountdown = 5;
|
|
||||||
break;
|
|
||||||
case 2: // 10 sec
|
|
||||||
gBacklightCountdown = 10;
|
|
||||||
break;
|
|
||||||
case 3: // 20 sec
|
|
||||||
gBacklightCountdown = 20;
|
|
||||||
break;
|
|
||||||
case 4: // 1 min
|
|
||||||
gBacklightCountdown = 60;
|
|
||||||
break;
|
|
||||||
case 5: // 2 min
|
|
||||||
gBacklightCountdown = 60 * 2;
|
|
||||||
break;
|
|
||||||
case 6: // 4 min
|
|
||||||
gBacklightCountdown = 60 * 4;
|
|
||||||
break;
|
|
||||||
case 7: // always on
|
|
||||||
gBacklightCountdown = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gBacklightCountdown *= 2;
|
backlightOn = true;
|
||||||
|
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX);
|
||||||
|
|
||||||
|
switch (gEeprom.BACKLIGHT_TIME) {
|
||||||
|
default:
|
||||||
|
case 1: // 5 sec
|
||||||
|
case 2: // 10 sec
|
||||||
|
case 3: // 20 sec
|
||||||
|
gBacklightCountdown_500ms = 1 + (2 << (gEeprom.BACKLIGHT_TIME - 1)) * 5;
|
||||||
|
break;
|
||||||
|
case 4: // 1 min
|
||||||
|
case 5: // 2 min
|
||||||
|
case 6: // 4 min
|
||||||
|
gBacklightCountdown_500ms = 1 + (2 << (gEeprom.BACKLIGHT_TIME - 4)) * 60;
|
||||||
|
break;
|
||||||
|
case 7: // always on
|
||||||
|
gBacklightCountdown_500ms = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BACKLIGHT_TurnOff()
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_BLMIN_TMP_OFF
|
||||||
|
register uint8_t tmp;
|
||||||
|
|
||||||
|
if (gEeprom.BACKLIGHT_MIN_STAT == BLMIN_STAT_ON)
|
||||||
|
tmp = gEeprom.BACKLIGHT_MIN;
|
||||||
|
else
|
||||||
|
tmp = 0;
|
||||||
|
|
||||||
|
BACKLIGHT_SetBrightness(tmp);
|
||||||
|
#else
|
||||||
|
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MIN);
|
||||||
|
#endif
|
||||||
|
gBacklightCountdown_500ms = 0;
|
||||||
|
backlightOn = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BACKLIGHT_IsOn()
|
||||||
|
{
|
||||||
|
return backlightOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t currentBrightness;
|
||||||
|
|
||||||
|
void BACKLIGHT_SetBrightness(uint8_t brigtness)
|
||||||
|
{
|
||||||
|
currentBrightness = brigtness;
|
||||||
|
PWM_PLUS0_CH0_COMP = (1 << brigtness) - 1;
|
||||||
|
//PWM_PLUS0_SWLOAD = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BACKLIGHT_GetBrightness(void)
|
||||||
|
{
|
||||||
|
return currentBrightness;
|
||||||
}
|
}
|
||||||
@@ -18,10 +18,24 @@
|
|||||||
#define DRIVER_BACKLIGHT_H
|
#define DRIVER_BACKLIGHT_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
extern uint16_t gBacklightCountdown;
|
extern uint16_t gBacklightCountdown_500ms;
|
||||||
|
extern uint8_t gBacklightBrightness;
|
||||||
void BACKLIGHT_TurnOn(void);
|
|
||||||
|
|
||||||
|
#ifdef ENABLE_BLMIN_TMP_OFF
|
||||||
|
typedef enum {
|
||||||
|
BLMIN_STAT_ON,
|
||||||
|
BLMIN_STAT_OFF,
|
||||||
|
BLMIN_STAT_UNKNOWN
|
||||||
|
} BLMIN_STAT_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void BACKLIGHT_InitHardware();
|
||||||
|
void BACKLIGHT_TurnOn();
|
||||||
|
void BACKLIGHT_TurnOff();
|
||||||
|
bool BACKLIGHT_IsOn();
|
||||||
|
void BACKLIGHT_SetBrightness(uint8_t brigtness);
|
||||||
|
uint8_t BACKLIGHT_GetBrightness(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -17,6 +17,19 @@
|
|||||||
#ifndef BK4819_REGS_H
|
#ifndef BK4819_REGS_H
|
||||||
#define BK4819_REGS_H
|
#define BK4819_REGS_H
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
uint8_t num;
|
||||||
|
uint8_t offset;
|
||||||
|
uint16_t mask;
|
||||||
|
uint16_t inc;
|
||||||
|
} RegisterSpec;
|
||||||
|
|
||||||
|
static const RegisterSpec afcDisableRegSpec = {"AFC Disable", 0x73, 4, 1, 1};
|
||||||
|
static const RegisterSpec afOutRegSpec = {"AF Output Select", 0x47, 8, 0xF, 1};
|
||||||
|
static const RegisterSpec afDacGainRegSpec = {"AF DAC Gain", 0x48, 0, 0xF, 1};
|
||||||
|
|
||||||
enum BK4819_REGISTER_t {
|
enum BK4819_REGISTER_t {
|
||||||
BK4819_REG_00 = 0x00U,
|
BK4819_REG_00 = 0x00U,
|
||||||
BK4819_REG_02 = 0x02U,
|
BK4819_REG_02 = 0x02U,
|
||||||
@@ -28,10 +41,15 @@ enum BK4819_REGISTER_t {
|
|||||||
BK4819_REG_0C = 0x0CU,
|
BK4819_REG_0C = 0x0CU,
|
||||||
BK4819_REG_0D = 0x0DU,
|
BK4819_REG_0D = 0x0DU,
|
||||||
BK4819_REG_0E = 0x0EU,
|
BK4819_REG_0E = 0x0EU,
|
||||||
|
// RX AGC Gain Table[0]
|
||||||
BK4819_REG_10 = 0x10U,
|
BK4819_REG_10 = 0x10U,
|
||||||
|
// RX AGC Gain Table[1]
|
||||||
BK4819_REG_11 = 0x11U,
|
BK4819_REG_11 = 0x11U,
|
||||||
|
// RX AGC Gain Table[2]
|
||||||
BK4819_REG_12 = 0x12U,
|
BK4819_REG_12 = 0x12U,
|
||||||
|
// RX AGC Gain Table[3]
|
||||||
BK4819_REG_13 = 0x13U,
|
BK4819_REG_13 = 0x13U,
|
||||||
|
// RX AGC Gain Table[-1]
|
||||||
BK4819_REG_14 = 0x14U,
|
BK4819_REG_14 = 0x14U,
|
||||||
BK4819_REG_19 = 0x19U,
|
BK4819_REG_19 = 0x19U,
|
||||||
BK4819_REG_1F = 0x1FU,
|
BK4819_REG_1F = 0x1FU,
|
||||||
@@ -52,12 +70,19 @@ enum BK4819_REGISTER_t {
|
|||||||
BK4819_REG_3A = 0x3AU,
|
BK4819_REG_3A = 0x3AU,
|
||||||
BK4819_REG_3B = 0x3BU,
|
BK4819_REG_3B = 0x3BU,
|
||||||
BK4819_REG_3C = 0x3CU,
|
BK4819_REG_3C = 0x3CU,
|
||||||
|
BK4819_REG_3D = 0x3DU,
|
||||||
BK4819_REG_3E = 0x3EU,
|
BK4819_REG_3E = 0x3EU,
|
||||||
BK4819_REG_3F = 0x3FU,
|
BK4819_REG_3F = 0x3FU,
|
||||||
BK4819_REG_43 = 0x43U,
|
BK4819_REG_43 = 0x43U,
|
||||||
BK4819_REG_46 = 0x46U,
|
BK4819_REG_46 = 0x46U,
|
||||||
BK4819_REG_47 = 0x47U,
|
BK4819_REG_47 = 0x47U,
|
||||||
BK4819_REG_48 = 0x48U,
|
BK4819_REG_48 = 0x48U,
|
||||||
|
// REG_49<15:14> 0b00; High/Low Lo selection:
|
||||||
|
// 0X: Auto High/Low Lo
|
||||||
|
// 10: Low Lo
|
||||||
|
// 11: High Lo
|
||||||
|
// REG_49<13:7> 0x50; RF AGC high threshold, 1 dB/LSB
|
||||||
|
// REG_49<6:0> 0x30; RF AGC low threshold, 1 dB/LSB
|
||||||
BK4819_REG_49 = 0x49U,
|
BK4819_REG_49 = 0x49U,
|
||||||
BK4819_REG_4D = 0x4DU,
|
BK4819_REG_4D = 0x4DU,
|
||||||
BK4819_REG_4E = 0x4EU,
|
BK4819_REG_4E = 0x4EU,
|
||||||
@@ -86,22 +111,34 @@ enum BK4819_REGISTER_t {
|
|||||||
BK4819_REG_78 = 0x78U,
|
BK4819_REG_78 = 0x78U,
|
||||||
BK4819_REG_79 = 0x79U,
|
BK4819_REG_79 = 0x79U,
|
||||||
BK4819_REG_7A = 0x7AU,
|
BK4819_REG_7A = 0x7AU,
|
||||||
|
// REG_7B<15:0> 0xae34 RSSI table
|
||||||
BK4819_REG_7B = 0x7BU,
|
BK4819_REG_7B = 0x7BU,
|
||||||
|
// REG_7C<15:0> 0x8000 RSSI table
|
||||||
BK4819_REG_7C = 0x7CU,
|
BK4819_REG_7C = 0x7CU,
|
||||||
BK4819_REG_7D = 0x7DU,
|
BK4819_REG_7D = 0x7DU,
|
||||||
|
// REG_7E<15> 0; AGC fix mode:
|
||||||
|
// 1: Fix
|
||||||
|
// 0: Auto
|
||||||
|
// REG_7E<14:12> 0b011; AGC fix index:
|
||||||
|
// 011: Max.
|
||||||
|
// …
|
||||||
|
// 100: Min.
|
||||||
|
// REG_7E<5:3> 0b101; DC filter bandwidth for TX (MIC in):
|
||||||
|
// 000: Bypass DC filter
|
||||||
|
// REG_7E<2:0> 0b110; DC filter bandwidth for RX (IF in):
|
||||||
|
// 000: Bypass DC filter
|
||||||
BK4819_REG_7E = 0x7EU,
|
BK4819_REG_7E = 0x7EU,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum BK4819_REGISTER_t BK4819_REGISTER_t;
|
typedef enum BK4819_REGISTER_t BK4819_REGISTER_t;
|
||||||
|
|
||||||
enum BK4819_GPIO_PIN_t {
|
enum BK4819_GPIO_PIN_t {
|
||||||
BK4819_GPIO6_PIN2 = 0,
|
BK4819_GPIO0_PIN28_RX_ENABLE = 0,
|
||||||
BK4819_GPIO5_PIN1 = 1,
|
BK4819_GPIO1_PIN29_PA_ENABLE = 1,
|
||||||
BK4819_GPIO4_PIN32 = 2,
|
BK4819_GPIO3_PIN31_UHF_LNA = 3,
|
||||||
BK4819_GPIO3_PIN31 = 3,
|
BK4819_GPIO4_PIN32_VHF_LNA = 4,
|
||||||
BK4819_GPIO2_PIN30 = 4,
|
BK4819_GPIO5_PIN1_RED = 5,
|
||||||
BK4819_GPIO1_PIN29_RED = 5,
|
BK4819_GPIO6_PIN2_GREEN = 6,
|
||||||
BK4819_GPIO0_PIN28_GREEN = 6,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum BK4819_GPIO_PIN_t BK4819_GPIO_PIN_t;
|
typedef enum BK4819_GPIO_PIN_t BK4819_GPIO_PIN_t;
|
||||||
|
|||||||
452
driver/bk4819.c
452
driver/bk4819.c
@@ -16,12 +16,15 @@
|
|||||||
|
|
||||||
#include <stdio.h> // NULL
|
#include <stdio.h> // NULL
|
||||||
|
|
||||||
|
#include "../audio.h"
|
||||||
|
#include "../bsp/dp32g030/gpio.h"
|
||||||
|
#include "../bsp/dp32g030/portcon.h"
|
||||||
|
|
||||||
#include "bk4819.h"
|
#include "bk4819.h"
|
||||||
#include "bsp/dp32g030/gpio.h"
|
#include "gpio.h"
|
||||||
#include "bsp/dp32g030/portcon.h"
|
#include "system.h"
|
||||||
#include "driver/gpio.h"
|
#include "systick.h"
|
||||||
#include "driver/system.h"
|
|
||||||
#include "driver/systick.h"
|
|
||||||
|
|
||||||
#ifndef ARRAY_SIZE
|
#ifndef ARRAY_SIZE
|
||||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||||
@@ -29,6 +32,9 @@
|
|||||||
|
|
||||||
static const uint16_t FSK_RogerTable[7] = {0xF1A2, 0x7446, 0x61A4, 0x6544, 0x4E8A, 0xE044, 0xEA84};
|
static const uint16_t FSK_RogerTable[7] = {0xF1A2, 0x7446, 0x61A4, 0x6544, 0x4E8A, 0xE044, 0xEA84};
|
||||||
|
|
||||||
|
static const uint8_t DTMF_TONE1_GAIN = 65;
|
||||||
|
static const uint8_t DTMF_TONE2_GAIN = 93;
|
||||||
|
|
||||||
static uint16_t gBK4819_GpioOutState;
|
static uint16_t gBK4819_GpioOutState;
|
||||||
|
|
||||||
bool gRxIdleMode;
|
bool gRxIdleMode;
|
||||||
@@ -51,8 +57,8 @@ void BK4819_Init(void)
|
|||||||
BK4819_WriteRegister(BK4819_REG_37, 0x1D0F);
|
BK4819_WriteRegister(BK4819_REG_37, 0x1D0F);
|
||||||
BK4819_WriteRegister(BK4819_REG_36, 0x0022);
|
BK4819_WriteRegister(BK4819_REG_36, 0x0022);
|
||||||
|
|
||||||
BK4819_SetAGC(0);
|
BK4819_InitAGC(false);
|
||||||
// BK4819_SetAGC(1);
|
BK4819_SetAGC(true);
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_19, 0b0001000001000001); // <15> MIC AGC 1 = disable 0 = enable
|
BK4819_WriteRegister(BK4819_REG_19, 0b0001000001000001); // <15> MIC AGC 1 = disable 0 = enable
|
||||||
|
|
||||||
@@ -123,7 +129,6 @@ static uint16_t BK4819_ReadU16(void)
|
|||||||
PORTCON_PORTC_IE = (PORTCON_PORTC_IE & ~PORTCON_PORTC_IE_C2_MASK) | PORTCON_PORTC_IE_C2_BITS_ENABLE;
|
PORTCON_PORTC_IE = (PORTCON_PORTC_IE & ~PORTCON_PORTC_IE_C2_MASK) | PORTCON_PORTC_IE_C2_BITS_ENABLE;
|
||||||
GPIOC->DIR = (GPIOC->DIR & ~GPIO_DIR_2_MASK) | GPIO_DIR_2_BITS_INPUT;
|
GPIOC->DIR = (GPIOC->DIR & ~GPIO_DIR_2_MASK) | GPIO_DIR_2_BITS_INPUT;
|
||||||
SYSTICK_DelayUs(1);
|
SYSTICK_DelayUs(1);
|
||||||
|
|
||||||
Value = 0;
|
Value = 0;
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
@@ -232,119 +237,127 @@ void BK4819_WriteU16(uint16_t Data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_SetAGC(uint8_t Value)
|
void BK4819_SetAGC(bool enable)
|
||||||
{
|
{
|
||||||
if (Value == 0)
|
uint16_t regVal = BK4819_ReadRegister(BK4819_REG_7E);
|
||||||
{
|
if(!(regVal & (1 << 15)) == enable)
|
||||||
// REG_10
|
return;
|
||||||
//
|
|
||||||
// 0x0038 Rx AGC Gain Table[0]. (Index Max->Min is 3,2,1,0,-1)
|
|
||||||
//
|
|
||||||
// <15:10> ???
|
|
||||||
//
|
|
||||||
// <9:8> LNA Gain Short
|
|
||||||
// 3 = 0dB <<<
|
|
||||||
// 2 = -24dB // was -11
|
|
||||||
// 1 = -30dB // was -16
|
|
||||||
// 0 = -33dB // was -19
|
|
||||||
//
|
|
||||||
// <7:5> LNA Gain
|
|
||||||
// 7 = 0dB
|
|
||||||
// 6 = -2dB
|
|
||||||
// 5 = -4dB
|
|
||||||
// 4 = -6dB
|
|
||||||
// 3 = -9dB
|
|
||||||
// 2 = -14dB <<<
|
|
||||||
// 1 = -19dB
|
|
||||||
// 0 = -24dB
|
|
||||||
//
|
|
||||||
// <4:3> MIXER Gain
|
|
||||||
// 3 = 0dB <<<
|
|
||||||
// 2 = -3dB
|
|
||||||
// 1 = -6dB
|
|
||||||
// 0 = -8dB
|
|
||||||
//
|
|
||||||
// <2:0> PGA Gain
|
|
||||||
// 7 = 0dB
|
|
||||||
// 6 = -3dB <<<
|
|
||||||
// 5 = -6dB
|
|
||||||
// 4 = -9dB
|
|
||||||
// 3 = -15dB
|
|
||||||
// 2 = -21dB
|
|
||||||
// 1 = -27dB
|
|
||||||
// 0 = -33dB
|
|
||||||
//
|
|
||||||
BK4819_WriteRegister(BK4819_REG_13, (3u << 8) | (2u << 5) | (3u << 3) | (6u << 0)); // 000000 11 101 11 110
|
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_12, 0x037B); // 000000 11 011 11 011
|
BK4819_WriteRegister(BK4819_REG_7E, (regVal & ~(1 << 15) & ~(0b111 << 12))
|
||||||
BK4819_WriteRegister(BK4819_REG_11, 0x027B); // 000000 10 011 11 011
|
| (!enable << 15) // 0 AGC fix mode
|
||||||
BK4819_WriteRegister(BK4819_REG_10, 0x007A); // 000000 00 011 11 010
|
| (3u << 12) // 3 AGC fix index
|
||||||
BK4819_WriteRegister(BK4819_REG_14, 0x0019); // 000000 00 000 11 001
|
);
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_49, 0x2A38);
|
// if(enable) {
|
||||||
BK4819_WriteRegister(BK4819_REG_7B, 0x8420);
|
// BK4819_WriteRegister(BK4819_REG_7B, 0x8420);
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// BK4819_WriteRegister(BK4819_REG_7B, 0x318C);
|
||||||
|
|
||||||
|
// BK4819_WriteRegister(BK4819_REG_7C, 0x595E);
|
||||||
|
// BK4819_WriteRegister(BK4819_REG_20, 0x8DEF);
|
||||||
|
|
||||||
|
// for (uint8_t i = 0; i < 8; i++) {
|
||||||
|
// //BK4819_WriteRegister(BK4819_REG_06, ((i << 13) | 0x2500u) + 0x036u);
|
||||||
|
// BK4819_WriteRegister(BK4819_REG_06, (i & 7) << 13 | 0x4A << 7 | 0x36);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
void BK4819_InitAGC(bool amModulation)
|
||||||
|
{
|
||||||
|
// REG_10, REG_11, REG_12 REG_13, REG_14
|
||||||
|
//
|
||||||
|
// Rx AGC Gain Table[]. (Index Max->Min is 3,2,1,0,-1)
|
||||||
|
//
|
||||||
|
// <15:10> ???
|
||||||
|
//
|
||||||
|
// <9:8> LNA Gain Short
|
||||||
|
// 3 = 0dB <<< 1o11 read from spectrum reference manual
|
||||||
|
// 2 = -24dB -19 -11
|
||||||
|
// 1 = -30dB -24 -16
|
||||||
|
// 0 = -33dB -28 -19
|
||||||
|
//
|
||||||
|
// <7:5> LNA Gain
|
||||||
|
// 7 = 0dB
|
||||||
|
// 6 = -2dB
|
||||||
|
// 5 = -4dB
|
||||||
|
// 4 = -6dB
|
||||||
|
// 3 = -9dB
|
||||||
|
// 2 = -14dB <<<
|
||||||
|
// 1 = -19dB
|
||||||
|
// 0 = -24dB
|
||||||
|
//
|
||||||
|
// <4:3> MIXER Gain
|
||||||
|
// 3 = 0dB <<<
|
||||||
|
// 2 = -3dB
|
||||||
|
// 1 = -6dB
|
||||||
|
// 0 = -8dB
|
||||||
|
//
|
||||||
|
// <2:0> PGA Gain
|
||||||
|
// 7 = 0dB
|
||||||
|
// 6 = -3dB <<<
|
||||||
|
// 5 = -6dB
|
||||||
|
// 4 = -9dB
|
||||||
|
// 3 = -15dB
|
||||||
|
// 2 = -21dB
|
||||||
|
// 1 = -27dB
|
||||||
|
// 0 = -33dB
|
||||||
|
//
|
||||||
|
|
||||||
|
BK4819_WriteRegister(BK4819_REG_13, 0x03BE); // 0x03BE / 000000 11 101 11 110 / -7dB
|
||||||
|
BK4819_WriteRegister(BK4819_REG_12, 0x037B); // 0x037B / 000000 11 011 11 011 / -24dB
|
||||||
|
BK4819_WriteRegister(BK4819_REG_11, 0x027B); // 0x027B / 000000 10 011 11 011 / -43dB
|
||||||
|
BK4819_WriteRegister(BK4819_REG_10, 0x007A); // 0x007A / 000000 00 011 11 010 / -58dB
|
||||||
|
if(amModulation) {
|
||||||
|
BK4819_WriteRegister(BK4819_REG_14, 0x0000);
|
||||||
|
BK4819_WriteRegister(BK4819_REG_49, (0 << 14) | (50 << 7) | (32 << 0));
|
||||||
}
|
}
|
||||||
else
|
else{
|
||||||
if (Value == 1)
|
BK4819_WriteRegister(BK4819_REG_14, 0x0019); // 0x0019 / 000000 00 000 11 001 / -79dB
|
||||||
{ // what does this do ???
|
BK4819_WriteRegister(BK4819_REG_49, (0 << 14) | (84 << 7) | (56 << 0)); //0x2A38 / 00 1010100 0111000 / 84, 56
|
||||||
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
// REG_10
|
|
||||||
//
|
|
||||||
// 0x0038 Rx AGC Gain Table[0]. (Index Max->Min is 3,2,1,0,-1)
|
|
||||||
//
|
|
||||||
// (15:10> ???
|
|
||||||
//
|
|
||||||
// <9:8> LNA Gain Short
|
|
||||||
// 3 = 0dB << original
|
|
||||||
// 2 = -24dB // was -11
|
|
||||||
// 1 = -30dB // was -16
|
|
||||||
// 0 = -33dB // was -19
|
|
||||||
//
|
|
||||||
// <7:5> LNA Gain
|
|
||||||
// 7 = 0dB
|
|
||||||
// 6 = -2dB
|
|
||||||
// 5 = -4dB
|
|
||||||
// 4 = -6dB
|
|
||||||
// 3 = -9dB
|
|
||||||
// 2 = -14dB << original
|
|
||||||
// 1 = -19dB
|
|
||||||
// 0 = -24dB
|
|
||||||
//
|
|
||||||
// <4:3> MIXER Gain
|
|
||||||
// 3 = 0dB << original
|
|
||||||
// 2 = -3dB
|
|
||||||
// 1 = -6dB
|
|
||||||
// 0 = -8dB
|
|
||||||
//
|
|
||||||
// <2:0> PGA Gain
|
|
||||||
// 7 = 0dB
|
|
||||||
// 6 = -3dB << original
|
|
||||||
// 5 = -6dB
|
|
||||||
// 4 = -9dB
|
|
||||||
// 3 = -15dB
|
|
||||||
// 2 = -21dB
|
|
||||||
// 1 = -27dB
|
|
||||||
// 0 = -33dB
|
|
||||||
//
|
|
||||||
BK4819_WriteRegister(BK4819_REG_13, (3u << 8) | (2u << 5) | (3u << 3) | (6u << 0));
|
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_12, 0x037C); // 000000 11 011 11 100
|
|
||||||
BK4819_WriteRegister(BK4819_REG_11, 0x027B); // 000000 10 011 11 011
|
|
||||||
BK4819_WriteRegister(BK4819_REG_10, 0x007A); // 000000 00 011 11 010
|
|
||||||
BK4819_WriteRegister(BK4819_REG_14, 0x0018); // 000000 00 000 11 000
|
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_49, 0x2A38);
|
|
||||||
BK4819_WriteRegister(BK4819_REG_7B, 0x318C);
|
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_7C, 0x595E);
|
|
||||||
BK4819_WriteRegister(BK4819_REG_20, 0x8DEF);
|
|
||||||
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
// Bug? The bit 0x2000 below overwrites the (i << 13)
|
|
||||||
BK4819_WriteRegister(BK4819_REG_06, ((i << 13) | 0x2500u) + 0x036u);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BK4819_WriteRegister(BK4819_REG_7B, 0x8420);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t BK4819_GetRxGain_dB(void)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint16_t pga:3;
|
||||||
|
uint16_t mixer:2;
|
||||||
|
uint16_t lna:3;
|
||||||
|
uint16_t lnaS:2;
|
||||||
|
};
|
||||||
|
uint16_t __raw;
|
||||||
|
} agcGainReg;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint16_t _ : 5;
|
||||||
|
uint16_t agcSigStrength : 7;
|
||||||
|
int16_t gainIdx : 3;
|
||||||
|
uint16_t agcEnab : 1;
|
||||||
|
};
|
||||||
|
uint16_t __raw;
|
||||||
|
} reg7e;
|
||||||
|
|
||||||
|
reg7e.__raw = BK4819_ReadRegister(BK4819_REG_7E);
|
||||||
|
uint8_t gainAddr = reg7e.gainIdx < 0 ? BK4819_REG_14 : BK4819_REG_10 + reg7e.gainIdx;
|
||||||
|
agcGainReg.__raw = BK4819_ReadRegister(gainAddr);
|
||||||
|
int8_t lnaShortTab[] = {-28, -24, -19, 0};
|
||||||
|
int8_t lnaTab[] = {-24, -19, -14, -9, -6, -4, -2, 0};
|
||||||
|
int8_t mixerTab[] = {-8, -6, -3, 0};
|
||||||
|
int8_t pgaTab[] = {-33, -27, -21, -15, -9, -6, -3, 0};
|
||||||
|
return lnaShortTab[agcGainReg.lnaS] + lnaTab[agcGainReg.lna] + mixerTab[agcGainReg.mixer] + pgaTab[agcGainReg.pga];
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t BK4819_GetRSSI_dBm(void)
|
||||||
|
{
|
||||||
|
uint16_t rssi = BK4819_GetRSSI();
|
||||||
|
return (rssi / 2) - 160;// - BK4819_GetRxGain_dB();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet)
|
void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet)
|
||||||
@@ -700,10 +713,13 @@ void BK4819_SetupPowerAmplifier(const uint8_t bias, const uint32_t frequency)
|
|||||||
// 7 = max
|
// 7 = max
|
||||||
// 0 = min
|
// 0 = min
|
||||||
//
|
//
|
||||||
// 280MHz gain 1 = 1 gain 2 = 0 gain 1 = 4 gain 2 = 2
|
// 280MHz g1=1 g2=0 (-14.9dBm), g1=4 g2=2 (0.13dBm)
|
||||||
const uint8_t gain = (frequency < 28000000) ? (1u << 3) | (0u << 0) : (4u << 3) | (2u << 0);
|
uint8_t gain = (frequency < 28000000) ? (1u << 3) | (0u << 0) : (4u << 3) | (2u << 0);
|
||||||
|
gain = 0b000010;
|
||||||
|
(void)bias;
|
||||||
|
(void)frequency;
|
||||||
const uint8_t enable = 1;
|
const uint8_t enable = 1;
|
||||||
BK4819_WriteRegister(BK4819_REG_36, (bias << 8) | (enable << 7) | (gain << 0));
|
BK4819_WriteRegister(BK4819_REG_36, (16 << 8) | (enable << 7) | (gain << 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_SetFrequency(uint32_t Frequency)
|
void BK4819_SetFrequency(uint32_t Frequency)
|
||||||
@@ -760,19 +776,13 @@ void BK4819_SetupSquelch(
|
|||||||
// 0 ~ 255
|
// 0 ~ 255
|
||||||
//
|
//
|
||||||
BK4819_WriteRegister(BK4819_REG_4E, // 01 101 11 1 00000000
|
BK4819_WriteRegister(BK4819_REG_4E, // 01 101 11 1 00000000
|
||||||
#ifndef ENABLE_FASTER_CHANNEL_SCAN
|
|
||||||
// original (*)
|
// original (*)
|
||||||
(1u << 14) | // 1 ???
|
(1u << 14) | // 1 ???
|
||||||
(3u << 11) | // *5 squelch = open delay .. 0 ~ 7
|
(5u << 11) | // *5 squelch = open delay .. 0 ~ 7
|
||||||
(2u << 9) | // *3 squelch = close delay .. 0 ~ 3
|
(6u << 9) | // *3 squelch = close delay .. 0 ~ 3
|
||||||
SquelchOpenGlitchThresh); // 0 ~ 255
|
SquelchOpenGlitchThresh); // 0 ~ 255
|
||||||
#else
|
|
||||||
// faster (but twitchier)
|
|
||||||
(1u << 14) | // 1 ???
|
|
||||||
(2u << 11) | // *5 squelch = open delay .. 0 ~ 7
|
|
||||||
(1u << 9) | // *3 squelch = close delay .. 0 ~ 3
|
|
||||||
SquelchOpenGlitchThresh); // 0 ~ 255
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// REG_4F
|
// REG_4F
|
||||||
//
|
//
|
||||||
@@ -804,7 +814,14 @@ void BK4819_SetAF(BK4819_AF_Type_t AF)
|
|||||||
// AF Output Inverse Mode = Inverse
|
// AF Output Inverse Mode = Inverse
|
||||||
// Undocumented bits 0x2040
|
// Undocumented bits 0x2040
|
||||||
//
|
//
|
||||||
BK4819_WriteRegister(BK4819_REG_47, 0x6040 | (AF << 8));
|
// BK4819_WriteRegister(BK4819_REG_47, 0x6040 | (AF << 8));
|
||||||
|
BK4819_WriteRegister(BK4819_REG_47, (6u << 12) | (AF << 8) | (1u << 6));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BK4819_SetRegValue(RegisterSpec s, uint16_t v) {
|
||||||
|
uint16_t reg = BK4819_ReadRegister(s.num);
|
||||||
|
reg &= ~(s.mask << s.offset);
|
||||||
|
BK4819_WriteRegister(s.num, reg | (v << s.offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_RX_TurnOn(void)
|
void BK4819_RX_TurnOn(void)
|
||||||
@@ -828,35 +845,37 @@ void BK4819_RX_TurnOn(void)
|
|||||||
// Turn off everything
|
// Turn off everything
|
||||||
BK4819_WriteRegister(BK4819_REG_30, 0);
|
BK4819_WriteRegister(BK4819_REG_30, 0);
|
||||||
|
|
||||||
// Enable VCO Calibration
|
|
||||||
// Enable RX Link
|
BK4819_WriteRegister(BK4819_REG_30,
|
||||||
// Enable AF DAC
|
BK4819_REG_30_ENABLE_VCO_CALIB |
|
||||||
// Enable PLL/VCO
|
BK4819_REG_30_DISABLE_UNKNOWN |
|
||||||
// Disable PA Gain
|
BK4819_REG_30_ENABLE_RX_LINK |
|
||||||
// Disable MIC ADC
|
BK4819_REG_30_ENABLE_AF_DAC |
|
||||||
// Disable TX DSP
|
BK4819_REG_30_ENABLE_DISC_MODE |
|
||||||
// Enable RX DSP
|
BK4819_REG_30_ENABLE_PLL_VCO |
|
||||||
//
|
BK4819_REG_30_DISABLE_PA_GAIN |
|
||||||
BK4819_WriteRegister(BK4819_REG_30, 0b1011111111110001); // 1 0 1111 1 1 1111 0 0 0 1
|
BK4819_REG_30_DISABLE_MIC_ADC |
|
||||||
|
BK4819_REG_30_DISABLE_TX_DSP |
|
||||||
|
BK4819_REG_30_ENABLE_RX_DSP );
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_PickRXFilterPathBasedOnFrequency(uint32_t Frequency)
|
void BK4819_PickRXFilterPathBasedOnFrequency(uint32_t Frequency)
|
||||||
{
|
{
|
||||||
if (Frequency < 28000000)
|
if (Frequency < 28000000)
|
||||||
{
|
{ // VHF
|
||||||
BK4819_ToggleGpioOut(BK4819_GPIO2_PIN30, true);
|
BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, true);
|
||||||
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31, false);
|
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (Frequency == 0xFFFFFFFF)
|
if (Frequency == 0xFFFFFFFF)
|
||||||
{
|
{ // OFF
|
||||||
BK4819_ToggleGpioOut(BK4819_GPIO2_PIN30, false);
|
BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, false);
|
||||||
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31, false);
|
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{ // UHF
|
||||||
BK4819_ToggleGpioOut(BK4819_GPIO2_PIN30, false);
|
BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, false);
|
||||||
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31, true);
|
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -975,27 +994,27 @@ void BK4819_EnableDTMF(void)
|
|||||||
// <3:0> 14 Max symbol number for SelCall detection
|
// <3:0> 14 Max symbol number for SelCall detection
|
||||||
//
|
//
|
||||||
// const uint16_t threshold = 24; // default, but doesn't decode non-QS radios
|
// const uint16_t threshold = 24; // default, but doesn't decode non-QS radios
|
||||||
const uint16_t threshold = 160; // but 128 ~ 247 does
|
const uint16_t threshold = 130; // but 128 ~ 247 does
|
||||||
BK4819_WriteRegister(BK4819_REG_24, // 1 00011000 1 1 1 1110
|
BK4819_WriteRegister(BK4819_REG_24, // 1 00011000 1 1 1 1110
|
||||||
(1u << BK4819_REG_24_SHIFT_UNKNOWN_15) |
|
(1u << BK4819_REG_24_SHIFT_UNKNOWN_15) |
|
||||||
(threshold << BK4819_REG_24_SHIFT_THRESHOLD) | // 0 ~ 255
|
(threshold << BK4819_REG_24_SHIFT_THRESHOLD) | // 0 ~ 255
|
||||||
(1u << BK4819_REG_24_SHIFT_UNKNOWN_6) |
|
(1u << BK4819_REG_24_SHIFT_UNKNOWN_6) |
|
||||||
BK4819_REG_24_ENABLE |
|
BK4819_REG_24_ENABLE |
|
||||||
BK4819_REG_24_SELECT_DTMF |
|
BK4819_REG_24_SELECT_DTMF |
|
||||||
(14u << BK4819_REG_24_SHIFT_MAX_SYMBOLS)); // 0 ~ 15
|
(15u << BK4819_REG_24_SHIFT_MAX_SYMBOLS)); // 0 ~ 15
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch)
|
void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch)
|
||||||
{
|
{
|
||||||
uint16_t ToneConfig;
|
uint16_t ToneConfig = BK4819_REG_70_ENABLE_TONE1;
|
||||||
|
|
||||||
BK4819_EnterTxMute();
|
BK4819_EnterTxMute();
|
||||||
BK4819_SetAF(BK4819_AF_BEEP);
|
BK4819_SetAF(BK4819_AF_BEEP);
|
||||||
|
|
||||||
if (bTuningGainSwitch == 0)
|
if (bTuningGainSwitch == 0)
|
||||||
ToneConfig = BK4819_REG_70_ENABLE_TONE1 | (96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN);
|
ToneConfig |= 96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN;
|
||||||
else
|
else
|
||||||
ToneConfig = BK4819_REG_70_ENABLE_TONE1 | (28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN);
|
ToneConfig |= 28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN;
|
||||||
BK4819_WriteRegister(BK4819_REG_70, ToneConfig);
|
BK4819_WriteRegister(BK4819_REG_70, ToneConfig);
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_30, 0);
|
BK4819_WriteRegister(BK4819_REG_30, 0);
|
||||||
@@ -1004,21 +1023,20 @@ void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch)
|
|||||||
BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency));
|
BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// level 0 ~ 127
|
||||||
void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay, const unsigned int level, const bool play_speaker)
|
void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay, const unsigned int level, const bool play_speaker)
|
||||||
{
|
{
|
||||||
BK4819_EnterTxMute();
|
BK4819_EnterTxMute();
|
||||||
|
|
||||||
if (play_speaker)
|
if (play_speaker)
|
||||||
{
|
{
|
||||||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOn();
|
||||||
BK4819_SetAF(BK4819_AF_BEEP);
|
BK4819_SetAF(BK4819_AF_BEEP);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
BK4819_SetAF(BK4819_AF_MUTE);
|
BK4819_SetAF(BK4819_AF_MUTE);
|
||||||
|
|
||||||
// level 0 ~ 127
|
|
||||||
// BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
|
||||||
// BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
|
||||||
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | ((level & 0x7f) << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | ((level & 0x7f) << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
||||||
|
|
||||||
BK4819_EnableTXLink();
|
BK4819_EnableTXLink();
|
||||||
@@ -1032,12 +1050,13 @@ void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay,
|
|||||||
|
|
||||||
if (play_speaker)
|
if (play_speaker)
|
||||||
{
|
{
|
||||||
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
AUDIO_AudioPathOff();
|
||||||
BK4819_SetAF(BK4819_AF_MUTE);
|
BK4819_SetAF(BK4819_AF_MUTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_70, 0x0000);
|
BK4819_WriteRegister(BK4819_REG_70, 0x0000);
|
||||||
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE);
|
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE);
|
||||||
|
BK4819_ExitTxMute();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_EnterTxMute(void)
|
void BK4819_EnterTxMute(void)
|
||||||
@@ -1130,11 +1149,15 @@ void BK4819_ExitBypass(void)
|
|||||||
// 0 ~ 7
|
// 0 ~ 7
|
||||||
// 0 = bypass DC filter
|
// 0 = bypass DC filter
|
||||||
//
|
//
|
||||||
BK4819_WriteRegister(BK4819_REG_7E, // 0x302E); // 0 011 000000 101 110
|
|
||||||
(0u << 15) | // 0 AGC fix mode
|
uint16_t regVal = BK4819_ReadRegister(BK4819_REG_7E);
|
||||||
(3u << 12) | // 3 AGC fix index
|
|
||||||
(5u << 3) | // 5 DC Filter band width for Tx (MIC In)
|
// 0x302E / 0 011 000000 101 110
|
||||||
(6u << 0)); // 6 DC Filter band width for Rx (I.F In)
|
BK4819_WriteRegister(BK4819_REG_7E, (regVal & ~(0b111 << 3))
|
||||||
|
|
||||||
|
| (5u << 3) // 5 DC Filter band width for Tx (MIC In)
|
||||||
|
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_PrepareTransmit(void)
|
void BK4819_PrepareTransmit(void)
|
||||||
@@ -1198,7 +1221,7 @@ void BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable(void)
|
|||||||
{
|
{
|
||||||
if (gRxIdleMode)
|
if (gRxIdleMode)
|
||||||
{
|
{
|
||||||
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, true);
|
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, true);
|
||||||
BK4819_RX_TurnOn();
|
BK4819_RX_TurnOn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1211,9 +1234,9 @@ void BK4819_EnterDTMF_TX(bool bLocalLoopback)
|
|||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_70,
|
BK4819_WriteRegister(BK4819_REG_70,
|
||||||
BK4819_REG_70_MASK_ENABLE_TONE1 |
|
BK4819_REG_70_MASK_ENABLE_TONE1 |
|
||||||
(83u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) |
|
(DTMF_TONE1_GAIN << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) |
|
||||||
BK4819_REG_70_MASK_ENABLE_TONE2 |
|
BK4819_REG_70_MASK_ENABLE_TONE2 |
|
||||||
(83u << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN));
|
(DTMF_TONE2_GAIN << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN));
|
||||||
|
|
||||||
BK4819_EnableTXLink();
|
BK4819_EnableTXLink();
|
||||||
}
|
}
|
||||||
@@ -1249,30 +1272,30 @@ void BK4819_PlayDTMF(char Code)
|
|||||||
uint16_t tone1 = 0;
|
uint16_t tone1 = 0;
|
||||||
uint16_t tone2 = 0;
|
uint16_t tone2 = 0;
|
||||||
|
|
||||||
switch (Code) // Hz Hz
|
switch (Code)
|
||||||
{ //
|
{
|
||||||
case '0': tone1 = 9715; tone2 = 13793; break; // 941 1336
|
case '0': tone1 = 941; tone2 = 1336; break;
|
||||||
case '1': tone1 = 7196; tone2 = 12482; break; // 679 1209
|
case '1': tone1 = 697; tone2 = 1209; break;
|
||||||
case '2': tone1 = 7196; tone2 = 13793; break; // 697 1336
|
case '2': tone1 = 697; tone2 = 1336; break;
|
||||||
case '3': tone1 = 7196; tone2 = 15249; break; // 679 1477
|
case '3': tone1 = 697; tone2 = 1477; break;
|
||||||
case '4': tone1 = 7950; tone2 = 12482; break; // 770 1209
|
case '4': tone1 = 770; tone2 = 1209; break;
|
||||||
case '5': tone1 = 7950; tone2 = 13793; break; // 770 1336
|
case '5': tone1 = 770; tone2 = 1336; break;
|
||||||
case '6': tone1 = 7950; tone2 = 15249; break; // 770 1477
|
case '6': tone1 = 770; tone2 = 1477; break;
|
||||||
case '7': tone1 = 8796; tone2 = 12482; break; // 852 1209
|
case '7': tone1 = 852; tone2 = 1209; break;
|
||||||
case '8': tone1 = 8796; tone2 = 13793; break; // 852 1336
|
case '8': tone1 = 852; tone2 = 1336; break;
|
||||||
case '9': tone1 = 8796; tone2 = 15249; break; // 852 1477
|
case '9': tone1 = 852; tone2 = 1477; break;
|
||||||
case 'A': tone1 = 7196; tone2 = 16860; break; // 679 1633
|
case 'A': tone1 = 697; tone2 = 1633; break;
|
||||||
case 'B': tone1 = 7950; tone2 = 16860; break; // 770 1633
|
case 'B': tone1 = 770; tone2 = 1633; break;
|
||||||
case 'C': tone1 = 8796; tone2 = 16860; break; // 852 1633
|
case 'C': tone1 = 852; tone2 = 1633; break;
|
||||||
case 'D': tone1 = 9715; tone2 = 16860; break; // 941 1633
|
case 'D': tone1 = 941; tone2 = 1633; break;
|
||||||
case '*': tone1 = 9715; tone2 = 12482; break; // 941 1209
|
case '*': tone1 = 941; tone2 = 1209; break;
|
||||||
case '#': tone1 = 9715; tone2 = 15249; break; // 941 1477
|
case '#': tone1 = 941; tone2 = 1477; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tone1 > 0)
|
if (tone1 > 0)
|
||||||
BK4819_WriteRegister(BK4819_REG_71, tone1);
|
BK4819_WriteRegister(BK4819_REG_71, (((uint32_t)tone1 * 103244) + 5000) / 10000); // with rounding
|
||||||
if (tone2 > 0)
|
if (tone2 > 0)
|
||||||
BK4819_WriteRegister(BK4819_REG_72, tone2);
|
BK4819_WriteRegister(BK4819_REG_72, (((uint32_t)tone2 * 103244) + 5000) / 10000); // with rounding
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_PlayDTMFString(const char *pString, bool bDelayFirst, uint16_t FirstCodePersistTime, uint16_t HashCodePersistTime, uint16_t CodePersistTime, uint16_t CodeInternalTime)
|
void BK4819_PlayDTMFString(const char *pString, bool bDelayFirst, uint16_t FirstCodePersistTime, uint16_t HashCodePersistTime, uint16_t CodePersistTime, uint16_t CodeInternalTime)
|
||||||
@@ -1322,8 +1345,7 @@ void BK4819_TransmitTone(bool bLocalLoopback, uint32_t Frequency)
|
|||||||
//
|
//
|
||||||
// set the tone amplitude
|
// set the tone amplitude
|
||||||
//
|
//
|
||||||
// BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_MASK_ENABLE_TONE1 | (96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_MASK_ENABLE_TONE1 | (66u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
||||||
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_MASK_ENABLE_TONE1 | (28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
|
||||||
|
|
||||||
BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency));
|
BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency));
|
||||||
|
|
||||||
@@ -1513,12 +1535,46 @@ BK4819_CssScanResult_t BK4819_GetCxCSSScanResult(uint32_t *pCdcssFreq, uint16_t
|
|||||||
|
|
||||||
void BK4819_DisableFrequencyScan(void)
|
void BK4819_DisableFrequencyScan(void)
|
||||||
{
|
{
|
||||||
BK4819_WriteRegister(BK4819_REG_32, 0x0244);
|
// REG_32
|
||||||
|
//
|
||||||
|
// <15:14> 0 frequency scan time
|
||||||
|
// 0 = 0.2 sec
|
||||||
|
// 1 = 0.4 sec
|
||||||
|
// 2 = 0.8 sec
|
||||||
|
// 3 = 1.6 sec
|
||||||
|
//
|
||||||
|
// <13:1> ???
|
||||||
|
//
|
||||||
|
// <0> 0 frequency scan enable
|
||||||
|
// 1 = enable
|
||||||
|
// 0 = disable
|
||||||
|
//
|
||||||
|
BK4819_WriteRegister(BK4819_REG_32, // 0x0244); // 00 0000100100010 0
|
||||||
|
( 0u << 14) | // 0 frequency scan Time
|
||||||
|
(290u << 1) | // ???
|
||||||
|
( 0u << 0)); // 0 frequency scan enable
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_EnableFrequencyScan(void)
|
void BK4819_EnableFrequencyScan(void)
|
||||||
{
|
{
|
||||||
BK4819_WriteRegister(BK4819_REG_32, 0x0245); // 00 0000100100010 1
|
// REG_32
|
||||||
|
//
|
||||||
|
// <15:14> 0 frequency scan time
|
||||||
|
// 0 = 0.2 sec
|
||||||
|
// 1 = 0.4 sec
|
||||||
|
// 2 = 0.8 sec
|
||||||
|
// 3 = 1.6 sec
|
||||||
|
//
|
||||||
|
// <13:1> ???
|
||||||
|
//
|
||||||
|
// <0> 0 frequency scan enable
|
||||||
|
// 1 = enable
|
||||||
|
// 0 = disable
|
||||||
|
//
|
||||||
|
BK4819_WriteRegister(BK4819_REG_32, // 0x0245); // 00 0000100100010 1
|
||||||
|
( 0u << 14) | // 0 frequency scan time
|
||||||
|
(290u << 1) | // ???
|
||||||
|
( 1u << 0)); // 1 frequency scan enable
|
||||||
}
|
}
|
||||||
|
|
||||||
void BK4819_SetScanFrequency(uint32_t Frequency)
|
void BK4819_SetScanFrequency(uint32_t Frequency)
|
||||||
@@ -1668,8 +1724,7 @@ void BK4819_PlayRoger(void)
|
|||||||
BK4819_EnterTxMute();
|
BK4819_EnterTxMute();
|
||||||
BK4819_SetAF(BK4819_AF_MUTE);
|
BK4819_SetAF(BK4819_AF_MUTE);
|
||||||
|
|
||||||
// BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (66u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
||||||
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
|
||||||
|
|
||||||
BK4819_EnableTXLink();
|
BK4819_EnableTXLink();
|
||||||
SYSTEM_DelayMs(50);
|
SYSTEM_DelayMs(50);
|
||||||
@@ -1750,7 +1805,12 @@ void BK4819_PlayDTMFEx(bool bLocalLoopback, char Code)
|
|||||||
BK4819_EnterTxMute();
|
BK4819_EnterTxMute();
|
||||||
|
|
||||||
BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE);
|
BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE);
|
||||||
BK4819_WriteRegister(BK4819_REG_70, 0xD3D3);
|
|
||||||
|
BK4819_WriteRegister(BK4819_REG_70,
|
||||||
|
BK4819_REG_70_MASK_ENABLE_TONE1 |
|
||||||
|
(DTMF_TONE1_GAIN << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) |
|
||||||
|
BK4819_REG_70_MASK_ENABLE_TONE2 |
|
||||||
|
(DTMF_TONE2_GAIN << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN));
|
||||||
|
|
||||||
BK4819_EnableTXLink();
|
BK4819_EnableTXLink();
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ enum BK4819_AF_Type_t
|
|||||||
BK4819_AF_FM = 1u, // FM
|
BK4819_AF_FM = 1u, // FM
|
||||||
BK4819_AF_ALAM = 2u, //
|
BK4819_AF_ALAM = 2u, //
|
||||||
BK4819_AF_BEEP = 3u, //
|
BK4819_AF_BEEP = 3u, //
|
||||||
BK4819_AF_BASEBAND1 = 4u, // SSB
|
BK4819_AF_BASEBAND1 = 4u, // RAW
|
||||||
BK4819_AF_BASEBAND2 = 5u, // SSB
|
BK4819_AF_BASEBAND2 = 5u, // USB
|
||||||
BK4819_AF_CTCO = 6u, // strange LF audio .. maybe the CTCSS LF line ?
|
BK4819_AF_CTCO = 6u, // strange LF audio .. maybe the CTCSS LF line ?
|
||||||
BK4819_AF_AM = 7u, // AM
|
BK4819_AF_AM = 7u, // AM
|
||||||
BK4819_AF_FSKO = 8u, // nothing
|
BK4819_AF_FSKO = 8u, // nothing
|
||||||
BK4819_AF_UNKNOWN3 = 9u, // distorted
|
BK4819_AF_UNKNOWN3 = 9u, // BYP
|
||||||
BK4819_AF_UNKNOWN4 = 10u, // nothing at all
|
BK4819_AF_UNKNOWN4 = 10u, // nothing at all
|
||||||
BK4819_AF_UNKNOWN5 = 11u, // distorted
|
BK4819_AF_UNKNOWN5 = 11u, // distorted
|
||||||
BK4819_AF_UNKNOWN6 = 12u, // distorted
|
BK4819_AF_UNKNOWN6 = 12u, // distorted
|
||||||
@@ -62,15 +62,18 @@ enum BK4819_CssScanResult_t
|
|||||||
|
|
||||||
typedef enum BK4819_CssScanResult_t BK4819_CssScanResult_t;
|
typedef enum BK4819_CssScanResult_t BK4819_CssScanResult_t;
|
||||||
|
|
||||||
|
// radio is asleep, not listening
|
||||||
extern bool gRxIdleMode;
|
extern bool gRxIdleMode;
|
||||||
|
|
||||||
void BK4819_Init(void);
|
void BK4819_Init(void);
|
||||||
uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register);
|
uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register);
|
||||||
void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data);
|
void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data);
|
||||||
|
void BK4819_SetRegValue(RegisterSpec s, uint16_t v);
|
||||||
void BK4819_WriteU8(uint8_t Data);
|
void BK4819_WriteU8(uint8_t Data);
|
||||||
void BK4819_WriteU16(uint16_t Data);
|
void BK4819_WriteU16(uint16_t Data);
|
||||||
|
|
||||||
void BK4819_SetAGC(uint8_t Value);
|
void BK4819_SetAGC(bool enable);
|
||||||
|
void BK4819_InitAGC(bool amModulation);
|
||||||
|
|
||||||
void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet);
|
void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet);
|
||||||
|
|
||||||
@@ -133,6 +136,8 @@ void BK4819_EnableCDCSS(void);
|
|||||||
void BK4819_EnableCTCSS(void);
|
void BK4819_EnableCTCSS(void);
|
||||||
|
|
||||||
uint16_t BK4819_GetRSSI(void);
|
uint16_t BK4819_GetRSSI(void);
|
||||||
|
int8_t BK4819_GetRxGain_dB(void);
|
||||||
|
int16_t BK4819_GetRSSI_dBm(void);
|
||||||
uint8_t BK4819_GetGlitchIndicator(void);
|
uint8_t BK4819_GetGlitchIndicator(void);
|
||||||
uint8_t BK4819_GetExNoiceIndicator(void);
|
uint8_t BK4819_GetExNoiceIndicator(void);
|
||||||
uint16_t BK4819_GetVoiceAmplitudeOut(void);
|
uint16_t BK4819_GetVoiceAmplitudeOut(void);
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "bsp/dp32g030/crc.h"
|
#include "../bsp/dp32g030/crc.h"
|
||||||
#include "driver/crc.h"
|
#include "crc.h"
|
||||||
|
|
||||||
void CRC_Init(void)
|
void CRC_Init(void)
|
||||||
{
|
{
|
||||||
@@ -47,4 +47,3 @@ uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size)
|
|||||||
|
|
||||||
return Crc;
|
return Crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "driver/eeprom.h"
|
#include "driver/eeprom.h"
|
||||||
#include "driver/i2c.h"
|
#include "driver/i2c.h"
|
||||||
#include "driver/system.h"
|
#include "driver/system.h"
|
||||||
@@ -38,16 +41,22 @@ void EEPROM_ReadBuffer(uint16_t Address, void *pBuffer, uint8_t Size)
|
|||||||
|
|
||||||
void EEPROM_WriteBuffer(uint16_t Address, const void *pBuffer)
|
void EEPROM_WriteBuffer(uint16_t Address, const void *pBuffer)
|
||||||
{
|
{
|
||||||
I2C_Start();
|
if (pBuffer == NULL || Address >= 0x2000)
|
||||||
|
return;
|
||||||
|
|
||||||
I2C_Write(0xA0);
|
|
||||||
|
|
||||||
I2C_Write((Address >> 8) & 0xFF);
|
uint8_t buffer[8];
|
||||||
I2C_Write((Address >> 0) & 0xFF);
|
EEPROM_ReadBuffer(Address, buffer, 8);
|
||||||
|
if (memcmp(pBuffer, buffer, 8) != 0)
|
||||||
|
{
|
||||||
|
I2C_Start();
|
||||||
|
I2C_Write(0xA0);
|
||||||
|
I2C_Write((Address >> 8) & 0xFF);
|
||||||
|
I2C_Write((Address >> 0) & 0xFF);
|
||||||
|
I2C_WriteBuffer(pBuffer, 8);
|
||||||
|
I2C_Stop();
|
||||||
|
}
|
||||||
|
|
||||||
I2C_WriteBuffer(pBuffer, 8);
|
// give the EEPROM time to burn the data in (apparently takes 5ms)
|
||||||
|
SYSTEM_DelayMs(8);
|
||||||
I2C_Stop();
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(10);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,25 +14,5 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "driver/gpio.h"
|
|
||||||
|
|
||||||
void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit)
|
|
||||||
{
|
|
||||||
*pReg &= ~(1U << Bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit)
|
|
||||||
{
|
|
||||||
return (*pReg >> Bit) & 1U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit)
|
|
||||||
{
|
|
||||||
*pReg ^= 1U << Bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit)
|
|
||||||
{
|
|
||||||
*pReg |= 1U << Bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -58,10 +58,21 @@ enum GPIOC_PINS {
|
|||||||
GPIOC_PIN_PTT = 5
|
GPIOC_PIN_PTT = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit);
|
static inline void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit) {
|
||||||
uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit);
|
*pReg &= ~(1U << Bit);
|
||||||
void GPIO_FlipBit( volatile uint32_t *pReg, uint8_t Bit);
|
}
|
||||||
void GPIO_SetBit( volatile uint32_t *pReg, uint8_t Bit);
|
|
||||||
|
static inline uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit) {
|
||||||
|
return (*pReg >> Bit) & 1U;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit) {
|
||||||
|
*pReg ^= 1U << Bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit) {
|
||||||
|
*pReg |= 1U << Bit;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -117,19 +117,13 @@ KEY_Code_t KEYBOARD_Poll(void)
|
|||||||
GPIOA->DATA &= keyboard[j].set_to_zero_mask;
|
GPIOA->DATA &= keyboard[j].set_to_zero_mask;
|
||||||
|
|
||||||
// Read all 4 GPIO pins at once .. with de-noise, max of 8 sample loops
|
// Read all 4 GPIO pins at once .. with de-noise, max of 8 sample loops
|
||||||
for (i = 0, k = 0, reg = 0; i < 3 && k < 8; i++, k++)
|
for (i = 0, k = 0, reg = 0; i < 3 && k < 8; i++, k++) {
|
||||||
{
|
|
||||||
uint16_t reg2;
|
|
||||||
|
|
||||||
SYSTICK_DelayUs(1);
|
SYSTICK_DelayUs(1);
|
||||||
|
uint16_t reg2 = GPIOA->DATA;
|
||||||
reg2 = GPIOA->DATA;
|
i *= reg == reg2;
|
||||||
if (reg != reg2)
|
reg = reg2;
|
||||||
{ // noise
|
|
||||||
reg = reg2;
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < 3)
|
if (i < 3)
|
||||||
break; // noise is too bad
|
break; // noise is too bad
|
||||||
|
|
||||||
|
|||||||
249
driver/st7565.c
249
driver/st7565.c
@@ -25,178 +25,163 @@
|
|||||||
#include "driver/system.h"
|
#include "driver/system.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
uint8_t gStatusLine[128];
|
uint8_t gStatusLine[LCD_WIDTH];
|
||||||
uint8_t gFrameBuffer[7][128];
|
uint8_t gFrameBuffer[FRAME_LINES][LCD_WIDTH];
|
||||||
|
|
||||||
void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const unsigned int Size, const uint8_t *pBitmap)
|
static void DrawLine(uint8_t column, uint8_t line, const uint8_t * lineBuffer, unsigned size_defVal)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
ST7565_SelectColumnAndLine(column + 4, line);
|
||||||
|
|
||||||
SPI_ToggleMasterMode(&SPI0->CR, false);
|
|
||||||
|
|
||||||
ST7565_SelectColumnAndLine(Column + 4U, Line);
|
|
||||||
|
|
||||||
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
|
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
|
||||||
|
for (unsigned i = 0; i < size_defVal; i++) {
|
||||||
if (pBitmap != NULL)
|
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
|
||||||
{
|
SPI0->WDR = lineBuffer ? lineBuffer[i] : size_defVal;
|
||||||
for (i = 0; i < Size; i++)
|
|
||||||
{
|
|
||||||
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
|
|
||||||
SPI0->WDR = pBitmap[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i < Size; i++)
|
|
||||||
{
|
|
||||||
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
|
|
||||||
SPI0->WDR = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SPI_WaitForUndocumentedTxFifoStatusBit();
|
SPI_WaitForUndocumentedTxFifoStatusBit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const uint8_t *pBitmap, const unsigned int Size)
|
||||||
|
{
|
||||||
|
SPI_ToggleMasterMode(&SPI0->CR, false);
|
||||||
|
DrawLine(Column, Line, pBitmap, Size);
|
||||||
SPI_ToggleMasterMode(&SPI0->CR, true);
|
SPI_ToggleMasterMode(&SPI0->CR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ST7565_BlitFullScreen(void)
|
void ST7565_BlitFullScreen(void)
|
||||||
{
|
{
|
||||||
unsigned int Line;
|
|
||||||
|
|
||||||
SPI_ToggleMasterMode(&SPI0->CR, false);
|
SPI_ToggleMasterMode(&SPI0->CR, false);
|
||||||
|
|
||||||
ST7565_WriteByte(0x40);
|
ST7565_WriteByte(0x40);
|
||||||
|
for (unsigned line = 0; line < FRAME_LINES; line++) {
|
||||||
for (Line = 0; Line < ARRAY_SIZE(gFrameBuffer); Line++)
|
DrawLine(0, line+1, gFrameBuffer[line], LCD_WIDTH);
|
||||||
{
|
|
||||||
unsigned int Column;
|
|
||||||
ST7565_SelectColumnAndLine(4, Line + 1);
|
|
||||||
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
|
|
||||||
for (Column = 0; Column < ARRAY_SIZE(gFrameBuffer[0]); Column++)
|
|
||||||
{
|
|
||||||
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
|
|
||||||
SPI0->WDR = gFrameBuffer[Line][Column];
|
|
||||||
}
|
|
||||||
SPI_WaitForUndocumentedTxFifoStatusBit();
|
|
||||||
}
|
}
|
||||||
|
SPI_ToggleMasterMode(&SPI0->CR, true);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
void ST7565_BlitLine(unsigned line)
|
||||||
// whats the delay for I wonder, it holds things up :(
|
{
|
||||||
SYSTEM_DelayMs(20);
|
SPI_ToggleMasterMode(&SPI0->CR, false);
|
||||||
#else
|
ST7565_WriteByte(0x40); // start line ?
|
||||||
// SYSTEM_DelayMs(1);
|
DrawLine(0, line+1, gFrameBuffer[line], LCD_WIDTH);
|
||||||
#endif
|
|
||||||
|
|
||||||
SPI_ToggleMasterMode(&SPI0->CR, true);
|
SPI_ToggleMasterMode(&SPI0->CR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ST7565_BlitStatusLine(void)
|
void ST7565_BlitStatusLine(void)
|
||||||
{ // the top small text line on the display
|
{ // the top small text line on the display
|
||||||
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
SPI_ToggleMasterMode(&SPI0->CR, false);
|
SPI_ToggleMasterMode(&SPI0->CR, false);
|
||||||
|
|
||||||
ST7565_WriteByte(0x40); // start line ?
|
ST7565_WriteByte(0x40); // start line ?
|
||||||
|
DrawLine(0, 0, gStatusLine, LCD_WIDTH);
|
||||||
ST7565_SelectColumnAndLine(4, 0);
|
|
||||||
|
|
||||||
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(gStatusLine); i++)
|
|
||||||
{
|
|
||||||
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
|
|
||||||
SPI0->WDR = gStatusLine[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
SPI_WaitForUndocumentedTxFifoStatusBit();
|
|
||||||
|
|
||||||
SPI_ToggleMasterMode(&SPI0->CR, true);
|
SPI_ToggleMasterMode(&SPI0->CR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ST7565_FillScreen(uint8_t Value)
|
void ST7565_FillScreen(uint8_t value)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
// reset some of the displays settings to try and overcome the radios hardware problem - RF corrupting the display
|
|
||||||
ST7565_Init(false);
|
|
||||||
|
|
||||||
SPI_ToggleMasterMode(&SPI0->CR, false);
|
SPI_ToggleMasterMode(&SPI0->CR, false);
|
||||||
|
for (unsigned i = 0; i < 8; i++) {
|
||||||
for (i = 0; i < 8; i++)
|
DrawLine(0, i, NULL, value);
|
||||||
{
|
|
||||||
unsigned int j;
|
|
||||||
ST7565_SelectColumnAndLine(0, i);
|
|
||||||
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
|
|
||||||
for (j = 0; j < 132; j++)
|
|
||||||
{
|
|
||||||
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {}
|
|
||||||
SPI0->WDR = Value;
|
|
||||||
}
|
|
||||||
SPI_WaitForUndocumentedTxFifoStatusBit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SPI_ToggleMasterMode(&SPI0->CR, true);
|
SPI_ToggleMasterMode(&SPI0->CR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ST7565_Init(const bool full)
|
// Software reset
|
||||||
|
const uint8_t ST7565_CMD_SOFTWARE_RESET = 0xE2;
|
||||||
|
// Bias Select
|
||||||
|
// 1 0 1 0 0 0 1 BS
|
||||||
|
// Select bias setting 0=1/9; 1=1/7 (at 1/65 duty)
|
||||||
|
const uint8_t ST7565_CMD_BIAS_SELECT = 0xA2;
|
||||||
|
// COM Direction
|
||||||
|
// 1 1 0 0 MY - - -
|
||||||
|
// Set output direction of COM
|
||||||
|
// MY=1, reverse direction
|
||||||
|
// MY=0, normal direction
|
||||||
|
const uint8_t ST7565_CMD_COM_DIRECTION = 0xC0;
|
||||||
|
// SEG Direction
|
||||||
|
// 1 0 1 0 0 0 0 MX
|
||||||
|
// Set scan direction of SEG
|
||||||
|
// MX=1, reverse direction
|
||||||
|
// MX=0, normal direction
|
||||||
|
const uint8_t ST7565_CMD_SEG_DIRECTION = 0xA0;
|
||||||
|
// Inverse Display
|
||||||
|
// 1 0 1 0 0 1 1 INV
|
||||||
|
// INV =1, inverse display
|
||||||
|
// INV =0, normal display
|
||||||
|
const uint8_t ST7565_CMD_INVERSE_DISPLAY = 0xA6;
|
||||||
|
// All Pixel ON
|
||||||
|
// 1 0 1 0 0 1 0 AP
|
||||||
|
// AP=1, set all pixel ON
|
||||||
|
// AP=0, normal display
|
||||||
|
const uint8_t ST7565_CMD_ALL_PIXEL_ON = 0xA4;
|
||||||
|
// Regulation Ratio
|
||||||
|
// 0 0 1 0 0 RR2 RR1 RR0
|
||||||
|
// This instruction controls the regulation ratio of the built-in regulator
|
||||||
|
const uint8_t ST7565_CMD_REGULATION_RATIO = 0x20;
|
||||||
|
// Double command!! Set electronic volume (EV) level
|
||||||
|
// Send next: 0 0 EV5 EV4 EV3 EV2 EV1 EV0 contrast 0-63
|
||||||
|
const uint8_t ST7565_CMD_SET_EV = 0x81;
|
||||||
|
// Control built-in power circuit ON/OFF - 0 0 1 0 1 VB VR VF
|
||||||
|
// VB: Built-in Booster
|
||||||
|
// VR: Built-in Regulator
|
||||||
|
// VF: Built-in Follower
|
||||||
|
const uint8_t ST7565_CMD_POWER_CIRCUIT = 0x28;
|
||||||
|
// Set display start line 0-63
|
||||||
|
// 0 0 0 1 S5 S4 S3 S2 S1 S0
|
||||||
|
const uint8_t ST7565_CMD_SET_START_LINE = 0x40;
|
||||||
|
// Display ON/OFF
|
||||||
|
// 0 0 1 0 1 0 1 1 1 D
|
||||||
|
// D=1, display ON
|
||||||
|
// D=0, display OFF
|
||||||
|
const uint8_t ST7565_CMD_DISPLAY_ON_OFF = 0xAE;
|
||||||
|
|
||||||
|
uint8_t cmds[] = {
|
||||||
|
ST7565_CMD_BIAS_SELECT | 0, // Select bias setting: 1/9
|
||||||
|
ST7565_CMD_COM_DIRECTION | (0 << 3), // Set output direction of COM: normal
|
||||||
|
ST7565_CMD_SEG_DIRECTION | 1, // Set scan direction of SEG: reverse
|
||||||
|
ST7565_CMD_INVERSE_DISPLAY | 0, // Inverse Display: false
|
||||||
|
ST7565_CMD_ALL_PIXEL_ON | 0, // All Pixel ON: false - normal display
|
||||||
|
ST7565_CMD_REGULATION_RATIO | (4 << 0), // Regulation Ratio 5.0
|
||||||
|
|
||||||
|
ST7565_CMD_SET_EV, // Set contrast
|
||||||
|
31,
|
||||||
|
|
||||||
|
ST7565_CMD_POWER_CIRCUIT | 0b111, // Built-in power circuit ON/OFF: VB=1 VR=1 VF=1
|
||||||
|
ST7565_CMD_SET_START_LINE | 0, // Set Start Line: 0
|
||||||
|
ST7565_CMD_DISPLAY_ON_OFF | 1, // Display ON/OFF: ON
|
||||||
|
};
|
||||||
|
|
||||||
|
void ST7565_Init(void)
|
||||||
{
|
{
|
||||||
if (full)
|
SPI0_Init();
|
||||||
{
|
ST7565_HardwareReset();
|
||||||
SPI0_Init();
|
SPI_ToggleMasterMode(&SPI0->CR, false);
|
||||||
|
ST7565_WriteByte(ST7565_CMD_SOFTWARE_RESET); // software reset
|
||||||
|
SYSTEM_DelayMs(120);
|
||||||
|
|
||||||
ST7565_HardwareReset();
|
for(uint8_t i = 0; i < 8; i++)
|
||||||
|
ST7565_WriteByte(cmds[i]);
|
||||||
|
|
||||||
SPI_ToggleMasterMode(&SPI0->CR, false);
|
ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b011); // VB=0 VR=1 VF=1
|
||||||
|
SYSTEM_DelayMs(1);
|
||||||
|
ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b110); // VB=1 VR=1 VF=0
|
||||||
|
SYSTEM_DelayMs(1);
|
||||||
|
|
||||||
ST7565_WriteByte(0xE2); // internal reset
|
for(uint8_t i = 0; i < 4; i++) // why 4 times?
|
||||||
|
ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b111); // VB=1 VR=1 VF=1
|
||||||
|
|
||||||
SYSTEM_DelayMs(120);
|
SYSTEM_DelayMs(40);
|
||||||
}
|
|
||||||
else
|
|
||||||
SPI_ToggleMasterMode(&SPI0->CR, false);
|
|
||||||
|
|
||||||
ST7565_WriteByte(0xA2); // bias 9
|
|
||||||
ST7565_WriteByte(0xC0); // com normal
|
|
||||||
ST7565_WriteByte(0xA1); // reverse ?
|
|
||||||
|
|
||||||
ST7565_WriteByte(0xA6); // normal screen ?
|
|
||||||
// ST7565_WriteByte(0xA7); // inverse screen ?
|
|
||||||
|
|
||||||
ST7565_WriteByte(0xA4); // all points normal
|
|
||||||
ST7565_WriteByte(0x24); //
|
|
||||||
ST7565_WriteByte(0x81); // volume first ?
|
|
||||||
|
|
||||||
ST7565_WriteByte(0x1f); // contrast ?
|
|
||||||
|
|
||||||
if (full)
|
|
||||||
{
|
|
||||||
ST7565_WriteByte(0x2B); // power control ?
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(1);
|
|
||||||
|
|
||||||
ST7565_WriteByte(0x2E); // power control ?
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(1);
|
|
||||||
|
|
||||||
ST7565_WriteByte(0x2F); //
|
|
||||||
ST7565_WriteByte(0x2F); //
|
|
||||||
ST7565_WriteByte(0x2F); //
|
|
||||||
ST7565_WriteByte(0x2F); //
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(40);
|
|
||||||
}
|
|
||||||
|
|
||||||
ST7565_WriteByte(0x40); // start line ?
|
|
||||||
ST7565_WriteByte(0xAF); // display on ?
|
|
||||||
|
|
||||||
|
ST7565_WriteByte(ST7565_CMD_SET_START_LINE | 0); // line 0
|
||||||
|
ST7565_WriteByte(ST7565_CMD_DISPLAY_ON_OFF | 1); // D=1
|
||||||
SPI_WaitForUndocumentedTxFifoStatusBit();
|
SPI_WaitForUndocumentedTxFifoStatusBit();
|
||||||
|
|
||||||
SPI_ToggleMasterMode(&SPI0->CR, true);
|
SPI_ToggleMasterMode(&SPI0->CR, true);
|
||||||
|
|
||||||
if (full)
|
ST7565_FillScreen(0x00);
|
||||||
ST7565_FillScreen(0x00);
|
}
|
||||||
|
|
||||||
|
void ST7565_FixInterfGlitch(void)
|
||||||
|
{
|
||||||
|
SPI_ToggleMasterMode(&SPI0->CR, false);
|
||||||
|
for(uint8_t i = 0; i < ARRAY_SIZE(cmds); i++)
|
||||||
|
ST7565_WriteByte(cmds[i]);
|
||||||
|
SPI_WaitForUndocumentedTxFifoStatusBit();
|
||||||
|
SPI_ToggleMasterMode(&SPI0->CR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ST7565_HardwareReset(void)
|
void ST7565_HardwareReset(void)
|
||||||
|
|||||||
@@ -22,15 +22,18 @@
|
|||||||
|
|
||||||
#define LCD_WIDTH 128
|
#define LCD_WIDTH 128
|
||||||
#define LCD_HEIGHT 64
|
#define LCD_HEIGHT 64
|
||||||
|
#define FRAME_LINES 7
|
||||||
|
|
||||||
extern uint8_t gStatusLine[128];
|
extern uint8_t gStatusLine[LCD_WIDTH];
|
||||||
extern uint8_t gFrameBuffer[7][128];
|
extern uint8_t gFrameBuffer[FRAME_LINES][LCD_WIDTH];
|
||||||
|
|
||||||
void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const unsigned int Size, const uint8_t *pBitmap);
|
void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const uint8_t *pBitmap, const unsigned int Size);
|
||||||
void ST7565_BlitFullScreen(void);
|
void ST7565_BlitFullScreen(void);
|
||||||
|
void ST7565_BlitLine(unsigned line);
|
||||||
void ST7565_BlitStatusLine(void);
|
void ST7565_BlitStatusLine(void);
|
||||||
void ST7565_FillScreen(uint8_t Value);
|
void ST7565_FillScreen(uint8_t Value);
|
||||||
void ST7565_Init(const bool full);
|
void ST7565_Init(void);
|
||||||
|
void ST7565_FixInterfGlitch(void);
|
||||||
void ST7565_HardwareReset(void);
|
void ST7565_HardwareReset(void);
|
||||||
void ST7565_SelectColumnAndLine(uint8_t Column, uint8_t Line);
|
void ST7565_SelectColumnAndLine(uint8_t Column, uint8_t Line);
|
||||||
void ST7565_WriteByte(uint8_t Value);
|
void ST7565_WriteByte(uint8_t Value);
|
||||||
|
|||||||
@@ -14,10 +14,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "bsp/dp32g030/pmu.h"
|
#include "../bsp/dp32g030/pmu.h"
|
||||||
#include "bsp/dp32g030/syscon.h"
|
#include "../bsp/dp32g030/syscon.h"
|
||||||
#include "driver/system.h"
|
#include "system.h"
|
||||||
#include "driver/systick.h"
|
#include "systick.h"
|
||||||
|
|
||||||
void SYSTEM_DelayMs(uint32_t Delay)
|
void SYSTEM_DelayMs(uint32_t Delay)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,8 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ARMCM0.h"
|
#include "ARMCM0.h"
|
||||||
#include "driver/systick.h"
|
#include "systick.h"
|
||||||
#include "misc.h"
|
#include "../misc.h"
|
||||||
|
|
||||||
// 0x20000324
|
// 0x20000324
|
||||||
static uint32_t gTickMultiplier;
|
static uint32_t gTickMultiplier;
|
||||||
@@ -29,17 +29,21 @@ void SYSTICK_Init(void)
|
|||||||
|
|
||||||
void SYSTICK_DelayUs(uint32_t Delay)
|
void SYSTICK_DelayUs(uint32_t Delay)
|
||||||
{
|
{
|
||||||
const uint32_t ticks = Delay * gTickMultiplier;
|
const uint32_t ticks = Delay * gTickMultiplier;
|
||||||
uint32_t i = 0;
|
uint32_t elapsed_ticks = 0;
|
||||||
uint32_t Start = SysTick->LOAD;
|
uint32_t Start = SysTick->LOAD;
|
||||||
uint32_t Previous = SysTick->VAL;
|
uint32_t Previous = SysTick->VAL;
|
||||||
do {
|
do {
|
||||||
uint32_t Current;
|
uint32_t Current;
|
||||||
uint32_t Delta;
|
|
||||||
while ((Current = SysTick->VAL) == Previous) {}
|
|
||||||
Delta = (Current < Previous) ? -Current : Start - Current;
|
|
||||||
i += Delta + Previous;
|
|
||||||
Previous = Current;
|
|
||||||
} while (i < ticks);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
do {
|
||||||
|
Current = SysTick->VAL;
|
||||||
|
} while (Current == Previous);
|
||||||
|
|
||||||
|
uint32_t Delta = ((Current < Previous) ? - Current : Start - Current);
|
||||||
|
|
||||||
|
elapsed_ticks += Delta + Previous;
|
||||||
|
|
||||||
|
Previous = Current;
|
||||||
|
} while (elapsed_ticks < ticks);
|
||||||
|
}
|
||||||
|
|||||||
580
font.c
580
font.c
@@ -16,201 +16,202 @@
|
|||||||
|
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
|
||||||
//const uint8_t gFontBig[95][16] =
|
// removed last and middle column which was all 0x00
|
||||||
const uint8_t gFontBig[95][15] =
|
// also the space char is not needed
|
||||||
|
const uint8_t gFontBig[95 - 1][16 - 2] =
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // ' '
|
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // ' '
|
||||||
{0x00, 0x00, 0x70, 0xF8, 0xF8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '!'
|
{0x00, 0x00, 0x70, 0xF8, 0xF8, 0x70, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '!'
|
||||||
{0x00, 0x1E, 0x3E, 0x00, 0x00, 0x3E, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '"'
|
{0x00, 0x1E, 0x3E, 0x00, 0x00, 0x3E, 0x1E, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '"'
|
||||||
{0x40, 0xF0, 0xF0, 0x40, 0xF0, 0xF0, 0x40, 0x00, 0x04, 0x1F, 0x1F, 0x04, 0x1F, 0x1F, 0x04}, // , 0x00}, // '#'
|
{0x40, 0xF0, 0xF0, 0x40, 0xF0, 0xF0, 0x40, /*0x00,*/ 0x04, 0x1F, 0x1F, 0x04, 0x1F, 0x1F, 0x04}, // , 0x00}, // '#'
|
||||||
{0x70, 0xF8, 0x88, 0x8F, 0x8F, 0x98, 0x30, 0x00, 0x06, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // , 0x00}, // '$'
|
{0x70, 0xF8, 0x88, 0x8F, 0x8F, 0x98, 0x30, /*0x00,*/ 0x06, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // , 0x00}, // '$'
|
||||||
{0x60, 0x60, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x00, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x18, 0x18}, // , 0x00}, // '%'
|
{0x60, 0x60, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x18, 0x18}, // , 0x00}, // '%'
|
||||||
{0x00, 0xB0, 0xF8, 0xC8, 0x78, 0xB0, 0x80, 0x00, 0x0F, 0x1F, 0x10, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // '&'
|
{0x00, 0xB0, 0xF8, 0xC8, 0x78, 0xB0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // '&'
|
||||||
{0x00, 0x20, 0x3E, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '''
|
{0x00, 0x20, 0x3E, 0x1E, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '''
|
||||||
{0x00, 0x00, 0xE0, 0xF0, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x00}, // , 0x00}, // '('
|
{0x00, 0x00, 0xE0, 0xF0, 0x18, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x00}, // , 0x00}, // '('
|
||||||
{0x00, 0x00, 0x08, 0x18, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x0F, 0x07, 0x00}, // , 0x00}, // ')'
|
{0x00, 0x00, 0x08, 0x18, 0xF0, 0xE0, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x18, 0x0F, 0x07, 0x00}, // , 0x00}, // ')'
|
||||||
{0x00, 0x40, 0xC0, 0x80, 0x80, 0xC0, 0x40, 0x00, 0x01, 0x05, 0x07, 0x03, 0x03, 0x07, 0x05}, // , 0x01}, // '*'
|
{0x00, 0x40, 0xC0, 0x80, 0x80, 0xC0, 0x40, /*0x00,*/ 0x01, 0x05, 0x07, 0x03, 0x03, 0x07, 0x05}, // , 0x01}, // '*'
|
||||||
{0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x07, 0x07, 0x01, 0x01}, // , 0x00}, // '+'
|
{0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, /*0x00,*/ 0x00, 0x01, 0x01, 0x07, 0x07, 0x01, 0x01}, // , 0x00}, // '+'
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x1C, 0x00, 0x00}, // , 0x00}, // ','
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x20, 0x3C, 0x1C, 0x00, 0x00}, // , 0x00}, // ','
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, // , 0x00}, // '-'
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, // , 0x00}, // '-'
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, // , 0x00}, // '.'
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, // , 0x00}, // '.'
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x00, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00}, // , 0x00}, // '/'
|
{0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00}, // , 0x00}, // '/'
|
||||||
{0xF0, 0xF8, 0x08, 0x88, 0x48, 0xF8, 0xF0, 0x00, 0x0F, 0x1F, 0x12, 0x11, 0x10, 0x1F, 0x0F}, // , 0x00}, // '0'
|
{0xF0, 0xF8, 0x08, 0x88, 0x48, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x12, 0x11, 0x10, 0x1F, 0x0F}, // , 0x00}, // '0'
|
||||||
{0x00, 0x20, 0x30, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10}, // , 0x00}, // '1'
|
{0x00, 0x20, 0x30, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10}, // , 0x00}, // '1'
|
||||||
{0x10, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x30, 0x00, 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x18}, // , 0x00}, // '2'
|
{0x10, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x18}, // , 0x00}, // '2'
|
||||||
{0x10, 0x18, 0x88, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x08, 0x18, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '3'
|
{0x10, 0x18, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '3'
|
||||||
{0x80, 0xC0, 0x60, 0x30, 0xF8, 0xF8, 0x00, 0x00, 0x01, 0x01, 0x01, 0x11, 0x1F, 0x1F, 0x11}, // , 0x00}, // '4'
|
{0x80, 0xC0, 0x60, 0x30, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x11, 0x1F, 0x1F, 0x11}, // , 0x00}, // '4'
|
||||||
{0xF8, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x08, 0x00, 0x08, 0x18, 0x10, 0x10, 0x11, 0x1F, 0x0F}, // , 0x00}, // '5'
|
{0xF8, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x08, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x11, 0x1F, 0x0F}, // , 0x00}, // '5'
|
||||||
{0xE0, 0xF0, 0x98, 0x88, 0x88, 0x80, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '6'
|
{0xE0, 0xF0, 0x98, 0x88, 0x88, 0x80, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '6'
|
||||||
{0x18, 0x18, 0x08, 0x08, 0x88, 0xF8, 0x78, 0x00, 0x00, 0x00, 0x1E, 0x1F, 0x01, 0x00, 0x00}, // , 0x00}, // '7'
|
{0x18, 0x18, 0x08, 0x08, 0x88, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x1E, 0x1F, 0x01, 0x00, 0x00}, // , 0x00}, // '7'
|
||||||
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '8'
|
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '8'
|
||||||
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0xF0, 0x00, 0x00, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // '9'
|
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0xF0, /*0x00,*/ 0x00, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // '9'
|
||||||
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // , 0x00}, // ':'
|
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // , 0x00}, // ':'
|
||||||
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1C, 0x0C, 0x00, 0x00}, // , 0x00}, // ';'
|
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1C, 0x0C, 0x00, 0x00}, // , 0x00}, // ';'
|
||||||
{0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x10, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18, 0x10}, // , 0x00}, // '<'
|
{0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x10, /*0x00,*/ 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18, 0x10}, // , 0x00}, // '<'
|
||||||
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, // , 0x00}, // '='
|
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, // , 0x00}, // '='
|
||||||
{0x00, 0x10, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x10, 0x18, 0x0C, 0x06, 0x03, 0x01}, // , 0x00}, // '>'
|
{0x00, 0x10, 0x30, 0x60, 0xC0, 0x80, 0x00, /*0x00,*/ 0x00, 0x10, 0x18, 0x0C, 0x06, 0x03, 0x01}, // , 0x00}, // '>'
|
||||||
{0x30, 0x38, 0x08, 0x88, 0xC8, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '?'
|
{0x30, 0x38, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '?'
|
||||||
{0xE0, 0xF0, 0x10, 0x90, 0x90, 0xF0, 0xE0, 0x00, 0x0F, 0x1F, 0x10, 0x17, 0x17, 0x17, 0x03}, // , 0x00}, // '@'
|
{0xE0, 0xF0, 0x10, 0x90, 0x90, 0xF0, 0xE0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x17, 0x17, 0x17, 0x03}, // , 0x00}, // '@'
|
||||||
{0xC0, 0xE0, 0x30, 0x18, 0x30, 0xE0, 0xC0, 0x00, 0x1F, 0x1F, 0x01, 0x01, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'A'
|
{0xC0, 0xE0, 0x30, 0x18, 0x30, 0xE0, 0xC0, /*0x00,*/ 0x1F, 0x1F, 0x01, 0x01, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'A'
|
||||||
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'B'
|
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'B'
|
||||||
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x10, 0x18, 0x0C}, // , 0x00}, // 'C'
|
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x10, 0x18, 0x0C}, // , 0x00}, // 'C'
|
||||||
{0x08, 0xF8, 0xF8, 0x08, 0x18, 0xF0, 0xE0, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'D'
|
{0x08, 0xF8, 0xF8, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'D'
|
||||||
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x11, 0x18, 0x1C}, // , 0x00}, // 'E'
|
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x11, 0x18, 0x1C}, // , 0x00}, // 'E'
|
||||||
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x01, 0x00, 0x00}, // , 0x00}, // 'F'
|
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x01, 0x00, 0x00}, // , 0x00}, // 'F'
|
||||||
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, 0x00, 0x07, 0x0F, 0x18, 0x11, 0x11, 0x0F, 0x1F}, // , 0x00}, // 'G'
|
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x11, 0x11, 0x0F, 0x1F}, // , 0x00}, // 'G'
|
||||||
{0xF8, 0xF8, 0x80, 0x80, 0x80, 0xF8, 0xF8, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'H'
|
{0xF8, 0xF8, 0x80, 0x80, 0x80, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'H'
|
||||||
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'I'
|
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'I'
|
||||||
{0x00, 0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, 0x00, 0x0E, 0x1E, 0x10, 0x10, 0x1F, 0x0F, 0x00}, // , 0x00}, // 'J'
|
{0x00, 0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, /*0x00,*/ 0x0E, 0x1E, 0x10, 0x10, 0x1F, 0x0F, 0x00}, // , 0x00}, // 'J'
|
||||||
{0x08, 0xF8, 0xF8, 0x80, 0xE0, 0x78, 0x18, 0x00, 0x10, 0x1F, 0x1F, 0x01, 0x03, 0x1E, 0x1C}, // , 0x00}, // 'K'
|
{0x08, 0xF8, 0xF8, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x01, 0x03, 0x1E, 0x1C}, // , 0x00}, // 'K'
|
||||||
{0x08, 0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x18, 0x1C}, // , 0x00}, // 'L'
|
{0x08, 0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x18, 0x1C}, // , 0x00}, // 'L'
|
||||||
{0xF8, 0xF8, 0x70, 0xE0, 0x70, 0xF8, 0xF8, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'M'
|
{0xF8, 0xF8, 0x70, 0xE0, 0x70, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'M'
|
||||||
{0xF8, 0xF8, 0x70, 0xE0, 0xC0, 0xF8, 0xF8, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'N'
|
{0xF8, 0xF8, 0x70, 0xE0, 0xC0, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'N'
|
||||||
{0xE0, 0xF0, 0x18, 0x08, 0x18, 0xF0, 0xE0, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'O'
|
{0xE0, 0xF0, 0x18, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'O'
|
||||||
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'P'
|
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'P'
|
||||||
{0xF0, 0xF8, 0x08, 0x08, 0x08, 0xF8, 0xF0, 0x00, 0x0F, 0x1F, 0x10, 0x1C, 0x78, 0x7F, 0x4F}, // , 0x00}, // 'Q'
|
{0xF0, 0xF8, 0x08, 0x08, 0x08, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x1C, 0x78, 0x7F, 0x4F}, // , 0x00}, // 'Q'
|
||||||
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x10, 0x1F, 0x1F, 0x00, 0x01, 0x1F, 0x1E}, // , 0x00}, // 'R'
|
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x01, 0x1F, 0x1E}, // , 0x00}, // 'R'
|
||||||
{0x30, 0x78, 0xC8, 0x88, 0x88, 0x38, 0x30, 0x00, 0x0C, 0x1C, 0x10, 0x10, 0x11, 0x1F, 0x0E}, // , 0x00}, // 'S'
|
{0x30, 0x78, 0xC8, 0x88, 0x88, 0x38, 0x30, /*0x00,*/ 0x0C, 0x1C, 0x10, 0x10, 0x11, 0x1F, 0x0E}, // , 0x00}, // 'S'
|
||||||
{0x00, 0x38, 0x18, 0xF8, 0xF8, 0x18, 0x38, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'T'
|
{0x00, 0x38, 0x18, 0xF8, 0xF8, 0x18, 0x38, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'T'
|
||||||
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'U'
|
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'U'
|
||||||
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x03, 0x07, 0x0C, 0x18, 0x0C, 0x07, 0x03}, // , 0x00}, // 'V'
|
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x03, 0x07, 0x0C, 0x18, 0x0C, 0x07, 0x03}, // , 0x00}, // 'V'
|
||||||
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x07, 0x1F, 0x1C, 0x07, 0x1C, 0x1F, 0x07}, // , 0x00}, // 'W'
|
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x07, 0x1F, 0x1C, 0x07, 0x1C, 0x1F, 0x07}, // , 0x00}, // 'W'
|
||||||
{0x18, 0x78, 0xE0, 0x80, 0xE0, 0x78, 0x18, 0x00, 0x18, 0x1E, 0x07, 0x01, 0x07, 0x1E, 0x18}, // , 0x00}, // 'X'
|
{0x18, 0x78, 0xE0, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x18, 0x1E, 0x07, 0x01, 0x07, 0x1E, 0x18}, // , 0x00}, // 'X'
|
||||||
{0x00, 0x78, 0xF8, 0x80, 0x80, 0xF8, 0x78, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'Y'
|
{0x00, 0x78, 0xF8, 0x80, 0x80, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'Y'
|
||||||
{0x38, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x38, 0x00, 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x1C}, // , 0x00}, // 'Z'
|
{0x38, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x38, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x1C}, // , 0x00}, // 'Z'
|
||||||
{0x00, 0x00, 0xF8, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x00}, // , 0x00}, // '['
|
{0x00, 0x00, 0xF8, 0xF8, 0x08, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x00}, // , 0x00}, // '['
|
||||||
{0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x1C}, // , 0x00}, // '"\'
|
{0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x1C}, // , 0x00}, // '"\'
|
||||||
{0x00, 0x00, 0x08, 0x08, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x00}, // , 0x00}, // ']'
|
{0x00, 0x00, 0x08, 0x08, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x00}, // , 0x00}, // ']'
|
||||||
{0x10, 0x18, 0x0E, 0x07, 0x0E, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '^'
|
{0x10, 0x18, 0x0E, 0x07, 0x0E, 0x18, 0x10, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '^'
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, // , 0x40}, // '_'
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, // , 0x40}, // '_'
|
||||||
{0x00, 0x00, 0x07, 0x0F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '`'
|
{0x00, 0x00, 0x07, 0x0F, 0x08, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '`'
|
||||||
{0x00, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x00, 0x0E, 0x1F, 0x11, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'a'
|
{0x00, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x0E, 0x1F, 0x11, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'a'
|
||||||
{0x08, 0xF8, 0xF8, 0x40, 0xC0, 0x80, 0x00, 0x00, 0x10, 0x1F, 0x0F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'b'
|
{0x08, 0xF8, 0xF8, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x10, 0x1F, 0x0F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'b'
|
||||||
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x18, 0x08}, // , 0x00}, // 'c'
|
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x18, 0x08}, // , 0x00}, // 'c'
|
||||||
{0x00, 0x80, 0xC0, 0x48, 0xF8, 0xF8, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'd'
|
{0x00, 0x80, 0xC0, 0x48, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'd'
|
||||||
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x0F, 0x1F, 0x11, 0x11, 0x11, 0x19, 0x09}, // , 0x00}, // 'e'
|
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x11, 0x11, 0x11, 0x19, 0x09}, // , 0x00}, // 'e'
|
||||||
{0x80, 0xF0, 0xF8, 0x88, 0x18, 0x30, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'f'
|
{0x80, 0xF0, 0xF8, 0x88, 0x18, 0x30, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'f'
|
||||||
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, 0x00, 0x4F, 0xDF, 0x90, 0x90, 0xFF, 0x7F, 0x00}, // , 0x00}, // 'g'
|
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x4F, 0xDF, 0x90, 0x90, 0xFF, 0x7F, 0x00}, // , 0x00}, // 'g'
|
||||||
{0x08, 0xF8, 0xF8, 0x80, 0x40, 0xC0, 0x80, 0x00, 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'h'
|
{0x08, 0xF8, 0xF8, 0x80, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'h'
|
||||||
{0x00, 0x00, 0x40, 0xD8, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'i'
|
{0x00, 0x00, 0x40, 0xD8, 0xD8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'i'
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x40, 0xD8, 0xD8, 0x00, 0x00, 0x60, 0xE0, 0x80, 0x80, 0xFF, 0x7F}, // , 0x00}, // 'j'
|
{0x00, 0x00, 0x00, 0x00, 0x40, 0xD8, 0xD8, /*0x00,*/ 0x00, 0x60, 0xE0, 0x80, 0x80, 0xFF, 0x7F}, // , 0x00}, // 'j'
|
||||||
{0x08, 0xF8, 0xF8, 0x00, 0x80, 0xC0, 0x40, 0x00, 0x10, 0x1F, 0x1F, 0x03, 0x07, 0x1C, 0x18}, // , 0x00}, // 'k'
|
{0x08, 0xF8, 0xF8, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x03, 0x07, 0x1C, 0x18}, // , 0x00}, // 'k'
|
||||||
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'l'
|
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'l'
|
||||||
{0xC0, 0xC0, 0xC0, 0x80, 0xC0, 0xC0, 0x80, 0x00, 0x1F, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'm'
|
{0xC0, 0xC0, 0xC0, 0x80, 0xC0, 0xC0, 0x80, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'm'
|
||||||
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'n'
|
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'n'
|
||||||
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'o'
|
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'o'
|
||||||
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x80, 0xFF, 0xFF, 0x90, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'p'
|
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x80, 0xFF, 0xFF, 0x90, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'p'
|
||||||
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, 0x00, 0x0F, 0x1F, 0x10, 0x90, 0xFF, 0xFF, 0x80}, // , 0x00}, // 'q'
|
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x90, 0xFF, 0xFF, 0x80}, // , 0x00}, // 'q'
|
||||||
{0x40, 0xC0, 0x80, 0xC0, 0x40, 0xC0, 0x80, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x01}, // , 0x00}, // 'r'
|
{0x40, 0xC0, 0x80, 0xC0, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x01}, // , 0x00}, // 'r'
|
||||||
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x08, 0x19, 0x13, 0x12, 0x16, 0x1C, 0x08}, // , 0x00}, // 's'
|
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x08, 0x19, 0x13, 0x12, 0x16, 0x1C, 0x08}, // , 0x00}, // 's'
|
||||||
{0x40, 0x40, 0xF0, 0xF8, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x18, 0x08}, // , 0x00}, // 't'
|
{0x40, 0x40, 0xF0, 0xF8, 0x40, 0x40, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x18, 0x08}, // , 0x00}, // 't'
|
||||||
{0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'u'
|
{0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'u'
|
||||||
{0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x07, 0x0F, 0x18, 0x18, 0x0F, 0x07}, // , 0x00}, // 'v'
|
{0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x00, 0x07, 0x0F, 0x18, 0x18, 0x0F, 0x07}, // , 0x00}, // 'v'
|
||||||
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x0F, 0x1F, 0x18, 0x0E, 0x18, 0x1F, 0x0F}, // , 0x00}, // 'w'
|
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x0F, 0x1F, 0x18, 0x0E, 0x18, 0x1F, 0x0F}, // , 0x00}, // 'w'
|
||||||
{0x40, 0xC0, 0x80, 0x00, 0x80, 0xC0, 0x40, 0x00, 0x10, 0x18, 0x0F, 0x07, 0x0F, 0x18, 0x10}, // , 0x00}, // 'x'
|
{0x40, 0xC0, 0x80, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x18, 0x0F, 0x07, 0x0F, 0x18, 0x10}, // , 0x00}, // 'x'
|
||||||
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x8F, 0x9F, 0x90, 0x90, 0xD0, 0x7F, 0x3F}, // , 0x00}, // 'y'
|
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x8F, 0x9F, 0x90, 0x90, 0xD0, 0x7F, 0x3F}, // , 0x00}, // 'y'
|
||||||
{0xC0, 0xC0, 0x40, 0x40, 0xC0, 0xC0, 0x40, 0x00, 0x18, 0x1C, 0x16, 0x13, 0x11, 0x18, 0x18}, // , 0x00}, // 'z'
|
{0xC0, 0xC0, 0x40, 0x40, 0xC0, 0xC0, 0x40, /*0x00,*/ 0x18, 0x1C, 0x16, 0x13, 0x11, 0x18, 0x18}, // , 0x00}, // 'z'
|
||||||
{0x00, 0x80, 0x80, 0xF0, 0x78, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10}, // , 0x00}, // '{'
|
{0x00, 0x80, 0x80, 0xF0, 0x78, 0x08, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10}, // , 0x00}, // '{'
|
||||||
{0x00, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00}, // , 0x00}, // '|'
|
{0x00, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00}, // , 0x00}, // '|'
|
||||||
{0x00, 0x08, 0x08, 0x78, 0xF0, 0x80, 0x80, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x0F, 0x00, 0x00}, // , 0x00}, // '}'
|
{0x00, 0x08, 0x08, 0x78, 0xF0, 0x80, 0x80, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x0F, 0x00, 0x00}, // , 0x00}, // '}'
|
||||||
{0x10, 0x18, 0x08, 0x18, 0x10, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // , 0x00} // '->'
|
{0x10, 0x18, 0x08, 0x18, 0x10, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // , 0x00} // '->'
|
||||||
#else
|
#else
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' '
|
||||||
{0x00, 0x00, 0x00, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '!'
|
||||||
{0x00, 0x0F, 0x1F, 0x00, 0x00, 0x1F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x0F, 0x1F, 0x00, 0x00, 0x1F, 0x0F, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '"'
|
||||||
{0x20, 0xF8, 0xF8, 0x20, 0xF8, 0xF8, 0x20, 0x00, 0x02, 0x0F, 0x0F, 0x02, 0x0F, 0x0F, 0x02},
|
{0x20, 0xF8, 0xF8, 0x20, 0xF8, 0xF8, 0x20, /*0x00,*/ 0x02, 0x0F, 0x0F, 0x02, 0x0F, 0x0F, 0x02}, // '#'
|
||||||
{0x70, 0xF8, 0x88, 0x8E, 0x8E, 0x98, 0x10, 0x00, 0x04, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07},
|
{0x70, 0xF8, 0x88, 0x8E, 0x8E, 0x98, 0x10, /*0x00,*/ 0x04, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // '$'
|
||||||
{0x30, 0x30, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x00, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x0C, 0x0C},
|
{0x30, 0x30, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x0C, 0x0C}, // '%'
|
||||||
{0x80, 0xD8, 0x7C, 0xE4, 0xBC, 0xD8, 0x40, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x07, 0x0F, 0x08},
|
{0x80, 0xD8, 0x7C, 0xE4, 0xBC, 0xD8, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x07, 0x0F, 0x08}, // '&'
|
||||||
{0x00, 0x10, 0x1F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x10, 0x1F, 0x0F, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '''
|
||||||
{0x00, 0x00, 0xF0, 0xF8, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0C, 0x08, 0x00},
|
{0x00, 0x00, 0xF0, 0xF8, 0x0C, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x03, 0x07, 0x0C, 0x08, 0x00}, // '('
|
||||||
{0x00, 0x00, 0x04, 0x0C, 0xF8, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0C, 0x07, 0x03, 0x00},
|
{0x00, 0x00, 0x04, 0x0C, 0xF8, 0xF0, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0C, 0x07, 0x03, 0x00}, // ')'
|
||||||
{0x00, 0x80, 0xA0, 0xE0, 0xC0, 0xE0, 0xA0, 0x80, 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x02},
|
{0x00, 0x80, 0xA0, 0xE0, 0xC0, 0xE0, 0xA0, /*0x80,*/ 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x02}, // '*'
|
||||||
{0x00, 0x80, 0x80, 0xE0, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00},
|
{0x00, 0x80, 0x80, 0xE0, 0xE0, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00}, // '+'
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1E, 0x0E, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1E, 0x0E, 0x00, 0x00}, // ','
|
||||||
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '-'
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // '.'
|
||||||
{0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x00, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00}, // '/'
|
||||||
{0xF8, 0xFC, 0x84, 0xC4, 0x64, 0xFC, 0xF8, 0x00, 0x07, 0x0F, 0x09, 0x08, 0x08, 0x0F, 0x07},
|
{0xF8, 0xFC, 0x84, 0xC4, 0x64, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x09, 0x08, 0x08, 0x0F, 0x07}, // '0'
|
||||||
{0x00, 0x10, 0x18, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08},
|
{0x00, 0x10, 0x18, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08}, // '1'
|
||||||
{0x18, 0x1C, 0x04, 0x84, 0xC4, 0x7C, 0x38, 0x00, 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08},
|
{0x18, 0x1C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // '2'
|
||||||
{0x18, 0x1C, 0x44, 0x44, 0x44, 0xFC, 0xB8, 0x00, 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07},
|
{0x18, 0x1C, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '3'
|
||||||
{0x80, 0xC0, 0x60, 0x30, 0x18, 0xFC, 0xFC, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x0F},
|
{0x80, 0xC0, 0x60, 0x30, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x0F}, // '4'
|
||||||
{0x7C, 0x7C, 0x44, 0x44, 0x44, 0xC4, 0x84, 0x00, 0x04, 0x0C, 0x08, 0x08, 0x08, 0x0F, 0x07},
|
{0x7C, 0x7C, 0x44, 0x44, 0x44, 0xC4, 0x84, /*0x00,*/ 0x04, 0x0C, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '5'
|
||||||
{0xF0, 0xF8, 0x4C, 0x44, 0x44, 0xC4, 0x80, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
|
{0xF0, 0xF8, 0x4C, 0x44, 0x44, 0xC4, 0x80, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '6'
|
||||||
{0x04, 0x04, 0x04, 0x84, 0xE4, 0x7C, 0x1C, 0x00, 0x00, 0x00, 0x0E, 0x0F, 0x01, 0x00, 0x00},
|
{0x04, 0x04, 0x04, 0x84, 0xE4, 0x7C, 0x1C, /*0x00,*/ 0x00, 0x00, 0x0E, 0x0F, 0x01, 0x00, 0x00}, // '7'
|
||||||
{0xB8, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
|
{0xB8, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '8'
|
||||||
{0x78, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, 0x00, 0x00, 0x08, 0x08, 0x08, 0x0C, 0x07, 0x03},
|
{0x78, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x00, 0x08, 0x08, 0x08, 0x0C, 0x07, 0x03}, // '9'
|
||||||
{0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00}, // ':'
|
||||||
{0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 0x06, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0E, 0x06, 0x00, 0x00}, // ';'
|
||||||
{0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x08},
|
{0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x08}, // '<'
|
||||||
{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02},
|
{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /*0x00,*/ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}, // '='
|
||||||
{0x00, 0x08, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x08, 0x0C, 0x06, 0x03, 0x01, 0x00},
|
{0x00, 0x08, 0x18, 0x30, 0x60, 0xC0, 0x80, /*0x00,*/ 0x00, 0x08, 0x0C, 0x06, 0x03, 0x01, 0x00}, // '>'
|
||||||
{0x38, 0x3C, 0x04, 0x84, 0xC4, 0x7C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00},
|
{0x38, 0x3C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '?'
|
||||||
{0xF0, 0xF8, 0x08, 0xC8, 0xC8, 0xF8, 0xF0, 0x00, 0x07, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x01},
|
{0xF0, 0xF8, 0x08, 0xC8, 0xC8, 0xF8, 0xF0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x01}, // '@'
|
||||||
{0xF8, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F},
|
{0xF8, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'A'
|
||||||
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
|
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'B'
|
||||||
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0x1C, 0x18, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0E, 0x06},
|
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0x1C, 0x18, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0E, 0x06}, // 'C'
|
||||||
{0xFC, 0xFC, 0x04, 0x04, 0x0C, 0xF8, 0xF0, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x0C, 0x07, 0x03},
|
{0xFC, 0xFC, 0x04, 0x04, 0x0C, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x0C, 0x07, 0x03}, // 'D'
|
||||||
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08},
|
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'E'
|
||||||
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'F'
|
||||||
{0xF8, 0xFC, 0x04, 0x84, 0x84, 0x9C, 0x98, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
|
{0xF8, 0xFC, 0x04, 0x84, 0x84, 0x9C, 0x98, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'G'
|
||||||
{0xFC, 0xFC, 0x40, 0x40, 0x40, 0xFC, 0xFC, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F},
|
{0xFC, 0xFC, 0x40, 0x40, 0x40, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'H'
|
||||||
{0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00},
|
{0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'I'
|
||||||
{0x00, 0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, 0x00, 0x06, 0x0E, 0x08, 0x08, 0x0F, 0x07, 0x00},
|
{0x00, 0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x0F, 0x07, 0x00}, // 'J'
|
||||||
{0xFC, 0xFC, 0xE0, 0x30, 0x18, 0x0C, 0x04, 0x00, 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08},
|
{0xFC, 0xFC, 0xE0, 0x30, 0x18, 0x0C, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'K'
|
||||||
{0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08},
|
{0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'L'
|
||||||
{0xFC, 0xFC, 0x18, 0x70, 0x18, 0xFC, 0xFC, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F},
|
{0xFC, 0xFC, 0x18, 0x70, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'M'
|
||||||
{0xFC, 0xFC, 0x60, 0xC0, 0x80, 0xFC, 0xFC, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0F},
|
{0xFC, 0xFC, 0x60, 0xC0, 0x80, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0F}, // 'N'
|
||||||
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
|
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'O'
|
||||||
{0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'P'
|
||||||
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, 0x00, 0x07, 0x0F, 0x08, 0x0C, 0x0C, 0x1F, 0x17},
|
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0C, 0x0C, 0x1F, 0x17}, // 'Q'
|
||||||
{0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, 0x00, 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08},
|
{0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'R'
|
||||||
{0x38, 0x7C, 0x44, 0x44, 0x44, 0xCC, 0x88, 0x00, 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07},
|
{0x38, 0x7C, 0x44, 0x44, 0x44, 0xCC, 0x88, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'S'
|
||||||
{0x00, 0x04, 0x04, 0xFC, 0xFC, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00},
|
{0x00, 0x04, 0x04, 0xFC, 0xFC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'T'
|
||||||
{0xFC, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
|
{0xFC, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'U'
|
||||||
{0x7C, 0xFC, 0x80, 0x00, 0x80, 0xFC, 0x7C, 0x00, 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00},
|
{0x7C, 0xFC, 0x80, 0x00, 0x80, 0xFC, 0x7C, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'V'
|
||||||
{0xFC, 0xFC, 0x00, 0x80, 0x00, 0xFC, 0xFC, 0x00, 0x0F, 0x0F, 0x06, 0x03, 0x06, 0x0F, 0x0F},
|
{0xFC, 0xFC, 0x00, 0x80, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x06, 0x03, 0x06, 0x0F, 0x0F}, // 'W'
|
||||||
{0x0C, 0x3C, 0xF0, 0xC0, 0xF0, 0x3C, 0x0C, 0x00, 0x0C, 0x0F, 0x03, 0x00, 0x03, 0x0F, 0x0C},
|
{0x0C, 0x3C, 0xF0, 0xC0, 0xF0, 0x3C, 0x0C, /*0x00,*/ 0x0C, 0x0F, 0x03, 0x00, 0x03, 0x0F, 0x0C}, // 'X'
|
||||||
{0x00, 0x3C, 0x7C, 0xC0, 0xC0, 0x7C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00},
|
{0x00, 0x3C, 0x7C, 0xC0, 0xC0, 0x7C, 0x3C, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'Y'
|
||||||
{0x04, 0x04, 0x84, 0xC4, 0x64, 0x3C, 0x1C, 0x00, 0x0E, 0x0F, 0x09, 0x08, 0x08, 0x08, 0x08},
|
{0x04, 0x04, 0x84, 0xC4, 0x64, 0x3C, 0x1C, /*0x00,*/ 0x0E, 0x0F, 0x09, 0x08, 0x08, 0x08, 0x08}, // 'Z'
|
||||||
{0x00, 0x00, 0xFC, 0xFC, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x00},
|
{0x00, 0x00, 0xFC, 0xFC, 0x04, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x00}, // '['
|
||||||
{0x38, 0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E},
|
{0x38, 0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E}, // '"\'
|
||||||
{0x00, 0x00, 0x04, 0x04, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x00},
|
{0x00, 0x00, 0x04, 0x04, 0xFC, 0xFC, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x00}, // ']'
|
||||||
{0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '^'
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20},
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, // '_'
|
||||||
{0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '`'
|
||||||
{0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, 0xC0, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F},
|
{0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'a'
|
||||||
{0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
|
{0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'b'
|
||||||
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0x60, 0x40, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0C, 0x04},
|
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0x60, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0C, 0x04}, // 'c'
|
||||||
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xFC, 0xFC, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F},
|
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'd'
|
||||||
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x07, 0x0F, 0x09, 0x09, 0x09, 0x09, 0x01},
|
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x09, 0x09, 0x09, 0x09, 0x01}, // 'e'
|
||||||
{0x20, 0x20, 0xF8, 0xFC, 0x24, 0x24, 0x04, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00},
|
{0x20, 0x20, 0xF8, 0xFC, 0x24, 0x24, 0x04, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00}, // 'f'
|
||||||
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, 0x00, 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F},
|
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'g'
|
||||||
{0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F},
|
{0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'h'
|
||||||
{0x00, 0x00, 0x20, 0xEC, 0xEC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00},
|
{0x00, 0x00, 0x20, 0xEC, 0xEC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'i'
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x20, 0xEC, 0xEC, 0x00, 0x00, 0x30, 0x70, 0x40, 0x40, 0x7F, 0x3F},
|
{0x00, 0x00, 0x00, 0x00, 0x20, 0xEC, 0xEC, /*0x00,*/ 0x00, 0x30, 0x70, 0x40, 0x40, 0x7F, 0x3F}, // 'j'
|
||||||
{0xFC, 0xFC, 0x00, 0x80, 0xC0, 0x60, 0x20, 0x00, 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08},
|
{0xFC, 0xFC, 0x00, 0x80, 0xC0, 0x60, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'k'
|
||||||
{0x00, 0x00, 0x04, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00},
|
{0x00, 0x00, 0x04, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'l'
|
||||||
{0xE0, 0xE0, 0x20, 0xE0, 0x20, 0xE0, 0xC0, 0x00, 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x0F},
|
{0xE0, 0xE0, 0x20, 0xE0, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x0F}, // 'm'
|
||||||
{0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F},
|
{0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'n'
|
||||||
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
|
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'o'
|
||||||
{0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x7F, 0x7F, 0x08, 0x08, 0x08, 0x0F, 0x07},
|
{0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x7F, 0x7F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'p'
|
||||||
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x7F, 0x7F},
|
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x7F, 0x7F}, // 'q'
|
||||||
{0xE0, 0xE0, 0x60, 0x20, 0x20, 0x20, 0x20, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{0xE0, 0xE0, 0x60, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'r'
|
||||||
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x08, 0x09, 0x09, 0x09, 0x09, 0x0F, 0x06},
|
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x08, 0x09, 0x09, 0x09, 0x09, 0x0F, 0x06}, // 's'
|
||||||
{0x20, 0x20, 0xFC, 0xFC, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08},
|
{0x20, 0x20, 0xFC, 0xFC, 0x20, 0x20, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08}, // 't'
|
||||||
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F},
|
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'u'
|
||||||
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x00, 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00},
|
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'v'
|
||||||
{0xE0, 0xE0, 0x00, 0x80, 0x00, 0xE0, 0xE0, 0x00, 0x07, 0x0F, 0x08, 0x0F, 0x08, 0x0F, 0x07},
|
{0xE0, 0xE0, 0x00, 0x80, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0F, 0x08, 0x0F, 0x07}, // 'w'
|
||||||
{0x60, 0xE0, 0x80, 0x00, 0x80, 0xE0, 0x60, 0x00, 0x0C, 0x0E, 0x03, 0x01, 0x03, 0x0E, 0x0C},
|
{0x60, 0xE0, 0x80, 0x00, 0x80, 0xE0, 0x60, /*0x00,*/ 0x0C, 0x0E, 0x03, 0x01, 0x03, 0x0E, 0x0C}, // 'x'
|
||||||
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x00, 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F},
|
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'y'
|
||||||
{0x20, 0x20, 0x20, 0xA0, 0xE0, 0x60, 0x20, 0x00, 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08},
|
{0x20, 0x20, 0x20, 0xA0, 0xE0, 0x60, 0x20, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // 'z'
|
||||||
{0x00, 0x00, 0x40, 0xF8, 0xBC, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08},
|
{0x00, 0x00, 0x40, 0xF8, 0xBC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08}, // '{'
|
||||||
{0x00, 0x00, 0x00, 0xBC, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0xBC, 0xBC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // '|'
|
||||||
{0x00, 0x04, 0x04, 0xBC, 0xF8, 0x40, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0F, 0x07, 0x00, 0x00},
|
{0x00, 0x04, 0x04, 0xBC, 0xF8, 0x40, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x07, 0x00, 0x00}, // '}'
|
||||||
{0x08, 0x0C, 0x04, 0x0C, 0x08, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
{0x08, 0x0C, 0x04, 0x0C, 0x08, 0x0C, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // '->'
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -230,37 +231,40 @@ const uint8_t gFontBig[95][15] =
|
|||||||
{0x00, 0xF0, 0xF8, 0xB8, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1C, 0xB8, 0xF0, 0xE0, 0x00, 0x11, 0x33, 0x77, 0x67, 0x66, 0x66, 0x66, 0x76, 0x33, 0x3F, 0x1F, 0x07},
|
{0x00, 0xF0, 0xF8, 0xB8, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1C, 0xB8, 0xF0, 0xE0, 0x00, 0x11, 0x33, 0x77, 0x67, 0x66, 0x66, 0x66, 0x76, 0x33, 0x3F, 0x1F, 0x07},
|
||||||
{0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00}
|
{0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 6 Empty columns removed
|
||||||
#elif 0
|
#elif 0
|
||||||
// VCR font
|
// VCR font
|
||||||
const uint8_t gFontBigDigits[11][26] =
|
const uint8_t gFontBigDigits[11][26 - 6] =
|
||||||
{
|
{
|
||||||
{0x00, 0x00, 0xF8, 0xFC, 0x06, 0x86, 0xC6, 0xE6, 0xF6, 0x76, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x77, 0x67, 0x63, 0x61, 0x60, 0x70, 0x3F, 0x1F, 0x00},
|
{/*0x00, 0x00,*/ 0xF8, 0xFC, 0x06, 0x86, 0xC6, 0xE6, 0xF6, 0x76, 0xFC, 0xF8, /*0x00,*/ /*0x00, 0x00,*/ 0x1F, 0x3F, 0x77, 0x67, 0x63, 0x61, 0x60, 0x70, 0x3F, 0x1F, /*0x00*/},
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x60, 0x60, 0x00, 0x00, 0x00},
|
{/*0x00, 0x00,*/ 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x60, 0x60, 0x00, 0x00, /*0x00*/},
|
||||||
{0x00, 0x00, 0x18, 0x1C, 0x86, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, 0x00, 0x00, 0x00, 0x7E, 0x7F, 0x63, 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x60, 0x00},
|
{/*0x00, 0x00,*/ 0x18, 0x1C, 0x86, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x7E, 0x7F, 0x63, 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x60, /*0x00*/},
|
||||||
{0x00, 0x00, 0x18, 0x1C, 0x06, 0x06, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, 0x00, 0x00, 0x00, 0x18, 0x38, 0x70, 0x60, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, 0x00},
|
{/*0x00, 0x00,*/ 0x18, 0x1C, 0x06, 0x06, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x70, 0x60, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/},
|
||||||
{0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x7F, 0x7F, 0x06, 0x06, 0x00},
|
{/*0x00, 0x00,*/ 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0xFE, 0xFE, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x7F, 0x7F, 0x06, 0x06, /*0x00*/},
|
||||||
{0x00, 0x00, 0x7E, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x66, 0xE6, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x18, 0x38, 0x70, 0x60, 0x60, 0x60, 0x60, 0x70, 0x3F, 0x1F, 0x00},
|
{/*0x00, 0x00,*/ 0x7E, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x66, 0xE6, 0xC6, 0x86, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x70, 0x60, 0x60, 0x60, 0x60, 0x70, 0x3F, 0x1F, /*0x00*/},
|
||||||
{0x00, 0x00, 0xF8, 0xFC, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x1C, 0x18, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x71, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, 0x00},
|
{/*0x00, 0x00,*/ 0xF8, 0xFC, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x1C, 0x18, /*0x00,*/ /*0x00, 0x00,*/ 0x1F, 0x3F, 0x71, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/},
|
||||||
{0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x86, 0xC6, 0xE6, 0x7E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00},
|
{/*0x00, 0x00,*/ 0x06, 0x06, 0x06, 0x06, 0x06, 0x86, 0xC6, 0xE6, 0x7E, 0x3E, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, /*0x00*/},
|
||||||
{0x00, 0x00, 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, 0x00, 0x00, 0x00, 0x1E, 0x3F, 0x73, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, 0x00},
|
{/*0x00, 0x00,*/ 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x1E, 0x3F, 0x73, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/},
|
||||||
{0x00, 0x00, 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0x86, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x18, 0x38, 0x71, 0x61, 0x61, 0x61, 0x61, 0x71, 0x3F, 0x1F, 0x00},
|
{/*0x00, 0x00,*/ 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0x86, 0xFC, 0xF8, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x71, 0x61, 0x61, 0x61, 0x61, 0x71, 0x3F, 0x1F, /*0x00*/},
|
||||||
{0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}
|
{/*0x00, 0x00,*/ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, /*0x00*/}
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
// Terminus font
|
// Terminus font
|
||||||
const uint8_t gFontBigDigits[11][26] =
|
|
||||||
|
const uint8_t gFontBigDigits[11][26 - 6] =
|
||||||
{
|
{
|
||||||
{0x00, 0x00, 0xFC, 0xFE, 0xFE, 0x06, 0x86, 0xC6, 0xE6, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x7F, 0x67, 0x63, 0x61, 0x60, 0x7F, 0x7F, 0x3F, 0x00},
|
{/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x86, 0xC6, 0xE6, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x67, 0x63, 0x61, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/},
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x7F, 0x60, 0x60, 0x00, 0x00},
|
{/*0x00, 0x00,*/ 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x7F, 0x60, 0x60, 0x00, /*0x00*/},
|
||||||
{0x00, 0x00, 0x1C, 0x1E, 0x1E, 0x06, 0x06, 0x06, 0x86, 0xFE, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x60, 0x70, 0x78, 0x7C, 0x6E, 0x67, 0x63, 0x61, 0x60, 0x60, 0x00},
|
{/*0x00, 0x00,*/ 0x1C, 0x1E, 0x1E, 0x06, 0x06, 0x06, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x60, 0x70, 0x78, 0x7C, 0x6E, 0x67, 0x63, 0x61, 0x60, 0x60, /*0x00*/},
|
||||||
{0x00, 0x00, 0x0C, 0x0E, 0x0E, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x30, 0x70, 0x70, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3E, 0x00},
|
{/*0x00, 0x00,*/ 0x0C, 0x0E, 0x0E, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3E, /*0x00*/},
|
||||||
{0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x7F, 0x7F, 0x7F, 0x00},
|
{/*0x00, 0x00,*/ 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0xFE, 0xFE, 0xFE, /*0x00,*/ /*0x00, 0x00,*/ 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x7F, 0x7F, 0x7F, /*0x00*/},
|
||||||
{0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x30, 0x70, 0x70, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, 0x00},
|
{/*0x00, 0x00,*/ 0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x86, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/},
|
||||||
{0x00, 0x00, 0xF8, 0xFC, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x80, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, 0x00},
|
{/*0x00, 0x00,*/ 0xF8, 0xFC, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x80, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/},
|
||||||
{0x00, 0x00, 0x0E, 0x0E, 0x0E, 0x06, 0x06, 0x86, 0xE6, 0xFE, 0x7E, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7F, 0x7F, 0x03, 0x00, 0x00, 0x00},
|
{/*0x00, 0x00,*/ 0x0E, 0x0E, 0x0E, 0x06, 0x06, 0x86, 0xE6, 0xFE, 0x7E, 0x1E, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7F, 0x7F, 0x03, 0x00, 0x00, /*0x00*/},
|
||||||
{0x00, 0x00, 0x7C, 0xFE, 0xFE, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x7F, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3F, 0x00},
|
{/*0x00, 0x00,*/ 0x7C, 0xFE, 0xFE, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3F, /*0x00*/},
|
||||||
{0x00, 0x00, 0xFC, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x01, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7F, 0x3F, 0x1F, 0x00},
|
{/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x01, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7F, 0x3F, 0x1F, /*0x00*/},
|
||||||
{0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}
|
{/*0x00, 0x00,*/ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, /*0x00*/}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
@@ -279,9 +283,9 @@ const uint8_t gFontSmallDigits[11][7] =
|
|||||||
{0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00} // '-'
|
{0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00} // '-'
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
const uint8_t gFontSmall[95][6] =
|
const uint8_t gFontSmall[95-1][6] =
|
||||||
{
|
{
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' '
|
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' '
|
||||||
{0x00, 0x00, 0x5E, 0x00, 0x00, 0x00}, // '!'
|
{0x00, 0x00, 0x5E, 0x00, 0x00, 0x00}, // '!'
|
||||||
{0x00, 0x06, 0x00, 0x06, 0x00, 0x00}, // '"'
|
{0x00, 0x06, 0x00, 0x06, 0x00, 0x00}, // '"'
|
||||||
{0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00}, // '#'
|
{0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00}, // '#'
|
||||||
@@ -379,9 +383,9 @@ const uint8_t gFontSmall[95][6] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ENABLE_SMALL_BOLD
|
#ifdef ENABLE_SMALL_BOLD
|
||||||
const uint8_t gFontSmallBold[95][6] =
|
const uint8_t gFontSmallBold[95 - 1][6] =
|
||||||
{
|
{
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x5E, 0x5E, 0x00, 0x00},
|
{0x00, 0x00, 0x5E, 0x5E, 0x00, 0x00},
|
||||||
{0x06, 0x06, 0x00, 0x06, 0x06, 0x00},
|
{0x06, 0x06, 0x00, 0x06, 0x06, 0x00},
|
||||||
{0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00},
|
{0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00},
|
||||||
@@ -480,7 +484,7 @@ const uint8_t gFontSmall[95][6] =
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_SPECTRUM
|
#ifdef ENABLE_SPECTRUM
|
||||||
const uint8_t gFont3x5[160][3] =
|
const uint8_t gFont3x5[][3] =
|
||||||
{
|
{
|
||||||
{0x00, 0x00, 0x00}, // 32 - space
|
{0x00, 0x00, 0x00}, // 32 - space
|
||||||
{0x00, 0x17, 0x00}, // 33 - exclam
|
{0x00, 0x17, 0x00}, // 33 - exclam
|
||||||
@@ -577,70 +581,74 @@ const uint8_t gFontSmall[95][6] =
|
|||||||
{0x00, 0x1b, 0x00}, // 124 - bar
|
{0x00, 0x1b, 0x00}, // 124 - bar
|
||||||
{0x11, 0x1b, 0x04}, // 125 - braceright
|
{0x11, 0x1b, 0x04}, // 125 - braceright
|
||||||
{0x02, 0x03, 0x01}, // 126 - asciitilde
|
{0x02, 0x03, 0x01}, // 126 - asciitilde
|
||||||
{0x00, 0x00, 0x00}, // 127 - empty
|
|
||||||
{0x00, 0x00, 0x00}, // 128 - empty
|
{0x12, 0x17, 0x12}, // 127 - plusminus
|
||||||
{0x00, 0x00, 0x00}, // 129 - empty
|
|
||||||
{0x00, 0x00, 0x00}, // 130 - empty
|
|
||||||
{0x00, 0x00, 0x00}, // 131 - empty
|
// {0x00, 0x00, 0x00}, // 127 - empty
|
||||||
{0x00, 0x00, 0x00}, // 132 - empty
|
// {0x00, 0x00, 0x00}, // 128 - empty
|
||||||
{0x00, 0x00, 0x00}, // 133 - empty
|
// {0x00, 0x00, 0x00}, // 129 - empty
|
||||||
{0x00, 0x00, 0x00}, // 134 - empty
|
// {0x00, 0x00, 0x00}, // 130 - empty
|
||||||
{0x00, 0x00, 0x00}, // 135 - empty
|
// {0x00, 0x00, 0x00}, // 131 - empty
|
||||||
{0x00, 0x00, 0x00}, // 136 - empty
|
// {0x00, 0x00, 0x00}, // 132 - empty
|
||||||
{0x00, 0x00, 0x00}, // 137 - empty
|
// {0x00, 0x00, 0x00}, // 133 - empty
|
||||||
{0x00, 0x00, 0x00}, // 138 - empty
|
// {0x00, 0x00, 0x00}, // 134 - empty
|
||||||
{0x00, 0x00, 0x00}, // 139 - empty
|
// {0x00, 0x00, 0x00}, // 135 - empty
|
||||||
{0x00, 0x00, 0x00}, // 140 - empty
|
// {0x00, 0x00, 0x00}, // 136 - empty
|
||||||
{0x00, 0x00, 0x00}, // 141 - empty
|
// {0x00, 0x00, 0x00}, // 137 - empty
|
||||||
{0x00, 0x00, 0x00}, // 142 - empty
|
// {0x00, 0x00, 0x00}, // 138 - empty
|
||||||
{0x00, 0x00, 0x00}, // 143 - empty
|
// {0x00, 0x00, 0x00}, // 139 - empty
|
||||||
{0x00, 0x00, 0x00}, // 144 - empty
|
// {0x00, 0x00, 0x00}, // 140 - empty
|
||||||
{0x00, 0x00, 0x00}, // 145 - empty
|
// {0x00, 0x00, 0x00}, // 141 - empty
|
||||||
{0x00, 0x00, 0x00}, // 146 - empty
|
// {0x00, 0x00, 0x00}, // 142 - empty
|
||||||
{0x00, 0x00, 0x00}, // 147 - empty
|
// {0x00, 0x00, 0x00}, // 143 - empty
|
||||||
{0x00, 0x00, 0x00}, // 148 - empty
|
// {0x00, 0x00, 0x00}, // 144 - empty
|
||||||
{0x00, 0x00, 0x00}, // 149 - empty
|
// {0x00, 0x00, 0x00}, // 145 - empty
|
||||||
{0x00, 0x00, 0x00}, // 150 - empty
|
// {0x00, 0x00, 0x00}, // 146 - empty
|
||||||
{0x00, 0x00, 0x00}, // 151 - empty
|
// {0x00, 0x00, 0x00}, // 147 - empty
|
||||||
{0x00, 0x00, 0x00}, // 152 - empty
|
// {0x00, 0x00, 0x00}, // 148 - empty
|
||||||
{0x00, 0x00, 0x00}, // 153 - empty
|
// {0x00, 0x00, 0x00}, // 149 - empty
|
||||||
{0x00, 0x00, 0x00}, // 154 - empty
|
// {0x00, 0x00, 0x00}, // 150 - empty
|
||||||
{0x00, 0x00, 0x00}, // 155 - empty
|
// {0x00, 0x00, 0x00}, // 151 - empty
|
||||||
{0x00, 0x00, 0x00}, // 156 - empty
|
// {0x00, 0x00, 0x00}, // 152 - empty
|
||||||
{0x00, 0x00, 0x00}, // 157 - empty
|
// {0x00, 0x00, 0x00}, // 153 - empty
|
||||||
{0x00, 0x00, 0x00}, // 158 - empty
|
// {0x00, 0x00, 0x00}, // 154 - empty
|
||||||
{0x00, 0x00, 0x00}, // 159 - empty
|
// {0x00, 0x00, 0x00}, // 155 - empty
|
||||||
{0x00, 0x00, 0x00}, // 160 - empty
|
// {0x00, 0x00, 0x00}, // 156 - empty
|
||||||
{0x00, 0x1d, 0x00}, // 161 - exclamdown
|
// {0x00, 0x00, 0x00}, // 157 - empty
|
||||||
{0x0e, 0x1b, 0x0a}, // 162 - cent
|
// {0x00, 0x00, 0x00}, // 158 - empty
|
||||||
{0x14, 0x1f, 0x15}, // 163 - sterling
|
// {0x00, 0x00, 0x00}, // 159 - empty
|
||||||
{0x15, 0x0e, 0x15}, // 164 - currency
|
// {0x00, 0x00, 0x00}, // 160 - empty
|
||||||
{0x0b, 0x1c, 0x0b}, // 165 - yen
|
// {0x00, 0x1d, 0x00}, // 161 - exclamdown
|
||||||
{0x00, 0x1b, 0x00}, // 166 - brokenbar
|
// {0x0e, 0x1b, 0x0a}, // 162 - cent
|
||||||
{0x14, 0x1b, 0x05}, // 167 - section
|
// {0x14, 0x1f, 0x15}, // 163 - sterling
|
||||||
{0x01, 0x00, 0x01}, // 168 - dieresis
|
// {0x15, 0x0e, 0x15}, // 164 - currency
|
||||||
{0x02, 0x05, 0x05}, // 169 - copyright
|
// {0x0b, 0x1c, 0x0b}, // 165 - yen
|
||||||
{0x16, 0x15, 0x17}, // 170 - ordfeminine
|
// {0x00, 0x1b, 0x00}, // 166 - brokenbar
|
||||||
{0x02, 0x05, 0x00}, // 171 - guillemotleft
|
// {0x14, 0x1b, 0x05}, // 167 - section
|
||||||
{0x02, 0x02, 0x06}, // 172 - logicalnot
|
// {0x01, 0x00, 0x01}, // 168 - dieresis
|
||||||
{0x04, 0x04, 0x00}, // 173 - softhyphen
|
// {0x02, 0x05, 0x05}, // 169 - copyright
|
||||||
{0x07, 0x03, 0x04}, // 174 - registered
|
// {0x16, 0x15, 0x17}, // 170 - ordfeminine
|
||||||
{0x01, 0x01, 0x01}, // 175 - macron
|
// {0x02, 0x05, 0x00}, // 171 - guillemotleft
|
||||||
{0x02, 0x05, 0x02}, // 176 - degree
|
// {0x02, 0x02, 0x06}, // 172 - logicalnot
|
||||||
{0x12, 0x17, 0x12}, // 177 - plusminus
|
// {0x04, 0x04, 0x00}, // 173 - softhyphen
|
||||||
{0x01, 0x07, 0x04}, // 178 - twosuperior
|
// {0x07, 0x03, 0x04}, // 174 - registered
|
||||||
{0x05, 0x07, 0x07}, // 179 - threesuperior
|
// {0x01, 0x01, 0x01}, // 175 - macron
|
||||||
{0x00, 0x02, 0x01}, // 180 - acute
|
// {0x02, 0x05, 0x02}, // 176 - degree
|
||||||
{0x1f, 0x08, 0x07}, // 181 - mu
|
// {0x12, 0x17, 0x12}, // 177 - plusminus
|
||||||
{0x02, 0x1d, 0x1f}, // 182 - paragraph
|
// {0x01, 0x07, 0x04}, // 178 - twosuperior
|
||||||
{0x0e, 0x0e, 0x0e}, // 183 - periodcentered
|
// {0x05, 0x07, 0x07}, // 179 - threesuperior
|
||||||
{0x10, 0x14, 0x08}, // 184 - cedilla
|
// {0x00, 0x02, 0x01}, // 180 - acute
|
||||||
{0x00, 0x07, 0x00}, // 185 - onesuperior
|
// {0x1f, 0x08, 0x07}, // 181 - mu
|
||||||
{0x12, 0x15, 0x12}, // 186 - ordmasculine
|
// {0x02, 0x1d, 0x1f}, // 182 - paragraph
|
||||||
{0x00, 0x05, 0x02}, // 187 - guillemotright
|
// {0x0e, 0x0e, 0x0e}, // 183 - periodcentered
|
||||||
{0x03, 0x08, 0x18}, // 188 - onequarter
|
// {0x10, 0x14, 0x08}, // 184 - cedilla
|
||||||
{0x0b, 0x18, 0x10}, // 189 - onehalf
|
// {0x00, 0x07, 0x00}, // 185 - onesuperior
|
||||||
{0x03, 0x0b, 0x18}, // 190 - threequarters
|
// {0x12, 0x15, 0x12}, // 186 - ordmasculine
|
||||||
{0x18, 0x15, 0x10}, // 191 - questiondown
|
// {0x00, 0x05, 0x02}, // 187 - guillemotright
|
||||||
|
// {0x03, 0x08, 0x18}, // 188 - onequarter
|
||||||
|
// {0x0b, 0x18, 0x10}, // 189 - onehalf
|
||||||
|
// {0x03, 0x0b, 0x18}, // 190 - threequarters
|
||||||
|
// {0x18, 0x15, 0x10}, // 191 - questiondown
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
13
font.h
13
font.h
@@ -19,14 +19,13 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
//extern const uint8_t gFontBig[95][16];
|
|
||||||
extern const uint8_t gFontBig[95][15];
|
extern const uint8_t gFontBig[95 - 1][16 - 2];
|
||||||
extern const uint8_t gFontBigDigits[11][26];
|
extern const uint8_t gFontBigDigits[11][26 - 6];
|
||||||
//extern const uint8_t gFontSmallDigits[11][7];
|
extern const uint8_t gFont3x5[96][3];
|
||||||
extern const uint8_t gFont3x5[160][3];
|
extern const uint8_t gFontSmall[95 - 1][6];
|
||||||
extern const uint8_t gFontSmall[95][6];
|
|
||||||
#ifdef ENABLE_SMALL_BOLD
|
#ifdef ENABLE_SMALL_BOLD
|
||||||
extern const uint8_t gFontSmallBold[95][6];
|
extern const uint8_t gFontSmallBold[95 - 1][6];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
161
frequencies.c
161
frequencies.c
@@ -17,32 +17,32 @@
|
|||||||
#include "frequencies.h"
|
#include "frequencies.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
// the BK4819 has 2 bands it covers, 18MHz ~ 630MHz and 760MHz ~ 1300MHz
|
// the BK4819 has 2 bands it covers, 18MHz ~ 630MHz and 760MHz ~ 1300MHz
|
||||||
const freq_band_table_t BX4819_band1 = { 1800000, 63000000};
|
|
||||||
const freq_band_table_t BX4819_band2 = {84000000, 130000000};
|
|
||||||
|
|
||||||
const freq_band_table_t frequencyBandTable[7] =
|
#define BX4819_band1_lower 1800000
|
||||||
|
#define BX4819_band2_upper 130000000
|
||||||
|
|
||||||
|
const freq_band_table_t BX4819_band1 = {BX4819_band1_lower, 63000000};
|
||||||
|
const freq_band_table_t BX4819_band2 = {84000000, BX4819_band2_upper};
|
||||||
|
|
||||||
|
const freq_band_table_t frequencyBandTable[] =
|
||||||
{
|
{
|
||||||
#ifndef ENABLE_WIDE_RX
|
#ifndef ENABLE_WIDE_RX
|
||||||
// QS original
|
// QS original
|
||||||
{ 5000000, 7600000},
|
[BAND1_50MHz ]={.lower = 5000000, .upper = 7600000},
|
||||||
{10800000, 13600000},
|
[BAND7_470MHz]={.lower = 47000000, .upper = 60000000},
|
||||||
{13600000, 17400000},
|
|
||||||
{17400000, 35000000},
|
|
||||||
{35000000, 40000000},
|
|
||||||
{40000000, 47000000},
|
|
||||||
{47000000, 60000000}
|
|
||||||
#else
|
#else
|
||||||
// extended range
|
// extended range
|
||||||
{ 1800000, 10800000},
|
[BAND1_50MHz ]={.lower = BX4819_band1_lower, .upper = 10800000},
|
||||||
{10800000, 13600000},
|
[BAND7_470MHz]={.lower = 47000000, .upper = BX4819_band2_upper},
|
||||||
{13600000, 17400000},
|
|
||||||
{17400000, 35000000},
|
|
||||||
{35000000, 40000000},
|
|
||||||
{40000000, 47000000},
|
|
||||||
{47000000, 130000000}
|
|
||||||
#endif
|
#endif
|
||||||
|
[BAND2_108MHz]={.lower = 10800000, .upper = 13700000},
|
||||||
|
[BAND3_137MHz]={.lower = 13700000, .upper = 17400000},
|
||||||
|
[BAND4_174MHz]={.lower = 17400000, .upper = 35000000},
|
||||||
|
[BAND5_350MHz]={.lower = 35000000, .upper = 40000000},
|
||||||
|
[BAND6_400MHz]={.lower = 40000000, .upper = 47000000}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
@@ -61,24 +61,67 @@ const freq_band_table_t frequencyBandTable[7] =
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ENABLE_12_5KHZ_STEP
|
|
||||||
// QS steps (*10 Hz)
|
// this order of steps has to be preserved for backwards compatibility with other/stock firmwares
|
||||||
const uint16_t StepFrequencyTable[7] = {250, 500, 625, 1000, 1250, 2500, 833};
|
const uint16_t gStepFrequencyTable[] = {
|
||||||
#else
|
// standard steps
|
||||||
// includes 1.25kHz step
|
[STEP_2_5kHz] = 250,
|
||||||
const uint16_t StepFrequencyTable[7] = {125, 250, 625, 1000, 1250, 2500, 833};
|
[STEP_5kHz] = 500,
|
||||||
#endif
|
[STEP_6_25kHz] = 625,
|
||||||
|
[STEP_10kHz] = 1000,
|
||||||
|
[STEP_12_5kHz] = 1250,
|
||||||
|
[STEP_25kHz] = 2500,
|
||||||
|
[STEP_8_33kHz] = 833,
|
||||||
|
// custom steps
|
||||||
|
[STEP_0_01kHz] = 1,
|
||||||
|
[STEP_0_05kHz] = 5,
|
||||||
|
[STEP_0_1kHz] = 10,
|
||||||
|
[STEP_0_25kHz] = 25,
|
||||||
|
[STEP_0_5kHz] = 50,
|
||||||
|
[STEP_1kHz] = 100,
|
||||||
|
[STEP_1_25kHz] = 125,
|
||||||
|
[STEP_9kHz] = 900,
|
||||||
|
[STEP_15kHz] = 1500,
|
||||||
|
[STEP_20kHz] = 2000,
|
||||||
|
[STEP_30kHz] = 3000,
|
||||||
|
[STEP_50kHz] = 5000,
|
||||||
|
[STEP_100kHz] = 10000,
|
||||||
|
[STEP_125kHz] = 12500,
|
||||||
|
[STEP_200kHz] = 20000,
|
||||||
|
[STEP_250kHz] = 25000,
|
||||||
|
[STEP_500kHz] = 50000
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const STEP_Setting_t StepSortedIndexes[] = {
|
||||||
|
STEP_0_01kHz, STEP_0_05kHz, STEP_0_1kHz, STEP_0_25kHz, STEP_0_5kHz, STEP_1kHz, STEP_1_25kHz, STEP_2_5kHz, STEP_5kHz, STEP_6_25kHz,
|
||||||
|
STEP_8_33kHz, STEP_9kHz, STEP_10kHz, STEP_12_5kHz, STEP_15kHz, STEP_20kHz, STEP_25kHz, STEP_30kHz, STEP_50kHz, STEP_100kHz,
|
||||||
|
STEP_125kHz, STEP_200kHz, STEP_250kHz, STEP_500kHz
|
||||||
|
};
|
||||||
|
|
||||||
|
STEP_Setting_t FREQUENCY_GetStepIdxFromSortedIdx(uint8_t sortedIdx)
|
||||||
|
{
|
||||||
|
return StepSortedIndexes[sortedIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FREQUENCY_GetSortedIdxFromStepIdx(uint8_t stepIdx)
|
||||||
|
{
|
||||||
|
for(uint8_t i = 0; i < ARRAY_SIZE(gStepFrequencyTable); i++)
|
||||||
|
if(StepSortedIndexes[i] == stepIdx)
|
||||||
|
return i;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(ARRAY_SIZE(gStepFrequencyTable) == STEP_N_ELEM);
|
||||||
|
|
||||||
|
|
||||||
FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency)
|
FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency)
|
||||||
{
|
{
|
||||||
int band;
|
for (int32_t band = BAND_N_ELEM - 1; band >= 0; band--)
|
||||||
for (band = ARRAY_SIZE(frequencyBandTable) - 1; band >= 0; band--)
|
|
||||||
if (Frequency >= frequencyBandTable[band].lower)
|
if (Frequency >= frequencyBandTable[band].lower)
|
||||||
// if (Frequency < frequencyBandTable[band].upper)
|
|
||||||
return (FREQUENCY_Band_t)band;
|
return (FREQUENCY_Band_t)band;
|
||||||
|
|
||||||
return BAND1_50MHz;
|
return BAND1_50MHz;
|
||||||
// return BAND_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, int32_t LowerLimit, int32_t Middle, int32_t UpperLimit, int32_t Frequency)
|
uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, int32_t LowerLimit, int32_t Middle, int32_t UpperLimit, int32_t Frequency)
|
||||||
@@ -100,51 +143,46 @@ uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t T
|
|||||||
return TxpMid;
|
return TxpMid;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FREQUENCY_FloorToStep(uint32_t Upper, uint32_t Step, uint32_t Lower)
|
|
||||||
|
uint32_t FREQUENCY_RoundToStep(uint32_t freq, uint16_t step)
|
||||||
{
|
{
|
||||||
uint32_t Index;
|
if(step == 833) {
|
||||||
|
uint32_t base = freq/2500*2500;
|
||||||
if (Step == 833)
|
int chno = (freq - base) / 700; // convert entered aviation 8.33Khz channel number scheme to actual frequency.
|
||||||
{
|
return base + (chno * 833) + (chno == 3);
|
||||||
const uint32_t Delta = Upper - Lower;
|
|
||||||
uint32_t Base = (Delta / 2500) * 2500;
|
|
||||||
const uint32_t Index = ((Delta - Base) % 2500) / 833;
|
|
||||||
|
|
||||||
if (Index == 2)
|
|
||||||
Base++;
|
|
||||||
|
|
||||||
return Lower + Base + (Index * 833);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Index = (Upper - Lower) / Step;
|
if(step == 1)
|
||||||
|
return freq;
|
||||||
return Lower + (Step * Index);
|
if(step >= 1000)
|
||||||
|
step = step/2;
|
||||||
|
return (freq + (step + 1) / 2) / step * step;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TX_freq_check(const uint32_t Frequency)
|
int32_t TX_freq_check(const uint32_t Frequency)
|
||||||
{ // return '0' if TX frequency is allowed
|
{ // return '0' if TX frequency is allowed
|
||||||
// otherwise return '-1'
|
// otherwise return '-1'
|
||||||
|
|
||||||
if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper)
|
if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper)
|
||||||
return -1; // not allowed outside this range
|
return 1; // not allowed outside this range
|
||||||
|
|
||||||
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
|
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
|
||||||
return -1; // BX chip does not work in this range
|
return -1; // BX chip does not work in this range
|
||||||
|
|
||||||
switch (gSetting_F_LOCK)
|
switch (gSetting_F_LOCK)
|
||||||
{
|
{
|
||||||
case F_LOCK_OFF:
|
case F_LOCK_DEF:
|
||||||
if (Frequency >= 13600000 && Frequency < 17400000)
|
if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < frequencyBandTable[BAND3_137MHz].upper)
|
||||||
return 0;
|
return 0;
|
||||||
if (Frequency >= 17400000 && Frequency < 35000000)
|
if (Frequency >= frequencyBandTable[BAND4_174MHz].lower && Frequency < frequencyBandTable[BAND4_174MHz].upper)
|
||||||
if (gSetting_200TX)
|
if (gSetting_200TX)
|
||||||
return 0;
|
return 0;
|
||||||
if (Frequency >= 35000000 && Frequency < 40000000)
|
if (Frequency >= frequencyBandTable[BAND5_350MHz].lower && Frequency < frequencyBandTable[BAND5_350MHz].upper)
|
||||||
if (gSetting_350TX && gSetting_350EN)
|
if (gSetting_350TX && gSetting_350EN)
|
||||||
return 0;
|
return 0;
|
||||||
if (Frequency >= 40000000 && Frequency < 47000000)
|
if (Frequency >= frequencyBandTable[BAND6_400MHz].lower && Frequency < frequencyBandTable[BAND6_400MHz].upper)
|
||||||
return 0;
|
return 0;
|
||||||
if (Frequency >= 47000000 && Frequency <= 60000000)
|
if (Frequency >= frequencyBandTable[BAND7_470MHz].lower && Frequency <= 60000000)
|
||||||
if (gSetting_500TX)
|
if (gSetting_500TX)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
@@ -171,29 +209,38 @@ int TX_freq_check(const uint32_t Frequency)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case F_LOCK_430:
|
case F_LOCK_430:
|
||||||
if (Frequency >= 13600000 && Frequency < 17400000)
|
if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000)
|
||||||
return 0;
|
return 0;
|
||||||
if (Frequency >= 40000000 && Frequency < 43000000)
|
if (Frequency >= 40000000 && Frequency < 43000000)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case F_LOCK_438:
|
case F_LOCK_438:
|
||||||
if (Frequency >= 13600000 && Frequency < 17400000)
|
if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000)
|
||||||
return 0;
|
return 0;
|
||||||
if (Frequency >= 40000000 && Frequency < 43800000)
|
if (Frequency >= 40000000 && Frequency < 43800000)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case F_LOCK_ALL:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case F_LOCK_NONE:
|
||||||
|
for (uint32_t i = 0; i < ARRAY_SIZE(frequencyBandTable); i++)
|
||||||
|
if (Frequency >= frequencyBandTable[i].lower && Frequency < frequencyBandTable[i].upper)
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dis-allowed TX frequency
|
// dis-allowed TX frequency
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RX_freq_check(const uint32_t Frequency)
|
int32_t RX_freq_check(const uint32_t Frequency)
|
||||||
{ // return '0' if RX frequency is allowed
|
{ // return '0' if RX frequency is allowed
|
||||||
// otherwise return '-1'
|
// otherwise return '-1'
|
||||||
|
|
||||||
if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper)
|
if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
|
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define ENABLE_12_5KHZ_STEP
|
#define _1GHz_in_KHz 100000000
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const uint32_t lower;
|
const uint32_t lower;
|
||||||
@@ -29,46 +29,52 @@ typedef struct {
|
|||||||
extern const freq_band_table_t BX4819_band1;
|
extern const freq_band_table_t BX4819_band1;
|
||||||
extern const freq_band_table_t BX4819_band2;
|
extern const freq_band_table_t BX4819_band2;
|
||||||
|
|
||||||
extern const freq_band_table_t frequencyBandTable[7];
|
typedef enum {
|
||||||
|
BAND_NONE = -1,
|
||||||
enum FREQUENCY_Band_t {
|
BAND1_50MHz = 0,
|
||||||
BAND_NONE = -1,
|
|
||||||
BAND1_50MHz = 0,
|
|
||||||
BAND2_108MHz,
|
BAND2_108MHz,
|
||||||
BAND3_136MHz,
|
BAND3_137MHz,
|
||||||
BAND4_174MHz,
|
BAND4_174MHz,
|
||||||
BAND5_350MHz,
|
BAND5_350MHz,
|
||||||
BAND6_400MHz,
|
BAND6_400MHz,
|
||||||
BAND7_470MHz
|
BAND7_470MHz,
|
||||||
};
|
BAND_N_ELEM
|
||||||
typedef enum FREQUENCY_Band_t FREQUENCY_Band_t;
|
} FREQUENCY_Band_t;
|
||||||
|
|
||||||
#ifndef ENABLE_12_5KHZ_STEP
|
extern const freq_band_table_t frequencyBandTable[];
|
||||||
// QS steps
|
|
||||||
enum STEP_Setting_t {
|
|
||||||
STEP_2_5kHz = 0,
|
|
||||||
STEP_5_0kHz,
|
|
||||||
STEP_6_25kHz,
|
|
||||||
STEP_10_0kHz,
|
|
||||||
STEP_12_5kHz,
|
|
||||||
STEP_25_0kHz,
|
|
||||||
STEP_8_33kHz
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
// includes 1.25kHz step
|
|
||||||
enum STEP_Setting_t {
|
|
||||||
STEP_1_25kHz = 0,
|
|
||||||
STEP_2_5kHz,
|
|
||||||
STEP_6_25kHz,
|
|
||||||
STEP_10_0kHz,
|
|
||||||
STEP_12_5kHz,
|
|
||||||
STEP_25_0kHz,
|
|
||||||
STEP_8_33kHz
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
typedef enum STEP_Setting_t STEP_Setting_t;
|
|
||||||
|
|
||||||
extern const uint16_t StepFrequencyTable[7];
|
typedef enum {
|
||||||
|
// standard steps
|
||||||
|
STEP_2_5kHz,
|
||||||
|
STEP_5kHz,
|
||||||
|
STEP_6_25kHz,
|
||||||
|
STEP_10kHz,
|
||||||
|
STEP_12_5kHz,
|
||||||
|
STEP_25kHz,
|
||||||
|
STEP_8_33kHz,
|
||||||
|
// custom steps
|
||||||
|
STEP_0_01kHz,
|
||||||
|
STEP_0_05kHz,
|
||||||
|
STEP_0_1kHz,
|
||||||
|
STEP_0_25kHz,
|
||||||
|
STEP_0_5kHz,
|
||||||
|
STEP_1kHz,
|
||||||
|
STEP_1_25kHz,
|
||||||
|
STEP_9kHz,
|
||||||
|
STEP_15kHz,
|
||||||
|
STEP_20kHz,
|
||||||
|
STEP_30kHz,
|
||||||
|
STEP_50kHz,
|
||||||
|
STEP_100kHz,
|
||||||
|
STEP_125kHz,
|
||||||
|
STEP_200kHz,
|
||||||
|
STEP_250kHz,
|
||||||
|
STEP_500kHz,
|
||||||
|
STEP_N_ELEM
|
||||||
|
} STEP_Setting_t;
|
||||||
|
|
||||||
|
|
||||||
|
extern const uint16_t gStepFrequencyTable[];
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
extern const uint32_t NoaaFrequencyTable[10];
|
extern const uint32_t NoaaFrequencyTable[10];
|
||||||
@@ -76,9 +82,12 @@ extern const uint16_t StepFrequencyTable[7];
|
|||||||
|
|
||||||
FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency);
|
FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency);
|
||||||
uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, int32_t LowerLimit, int32_t Middle, int32_t UpperLimit, int32_t Frequency);
|
uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, int32_t LowerLimit, int32_t Middle, int32_t UpperLimit, int32_t Frequency);
|
||||||
uint32_t FREQUENCY_FloorToStep(uint32_t Upper, uint32_t Step, uint32_t Lower);
|
uint32_t FREQUENCY_RoundToStep(uint32_t freq, uint16_t step);
|
||||||
|
|
||||||
int TX_freq_check(const uint32_t Frequency);
|
STEP_Setting_t FREQUENCY_GetStepIdxFromSortedIdx(uint8_t sortedIdx);
|
||||||
int RX_freq_check(const uint32_t Frequency);
|
uint32_t FREQUENCY_GetSortedIdxFromStepIdx(uint8_t step);
|
||||||
|
|
||||||
|
int32_t TX_freq_check(uint32_t Frequency);
|
||||||
|
int32_t RX_freq_check(uint32_t Frequency);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
324
functions.c
324
functions.c
@@ -20,6 +20,7 @@
|
|||||||
#if defined(ENABLE_FMRADIO)
|
#if defined(ENABLE_FMRADIO)
|
||||||
#include "app/fm.h"
|
#include "app/fm.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "audio.h"
|
||||||
#include "bsp/dp32g030/gpio.h"
|
#include "bsp/dp32g030/gpio.h"
|
||||||
#include "dcs.h"
|
#include "dcs.h"
|
||||||
#include "driver/backlight.h"
|
#include "driver/backlight.h"
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
#include "driver/bk4819.h"
|
#include "driver/bk4819.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "driver/system.h"
|
#include "driver/system.h"
|
||||||
|
#include "driver/st7565.h"
|
||||||
#include "frequencies.h"
|
#include "frequencies.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "helper/battery.h"
|
#include "helper/battery.h"
|
||||||
@@ -40,22 +42,30 @@
|
|||||||
|
|
||||||
FUNCTION_Type_t gCurrentFunction;
|
FUNCTION_Type_t gCurrentFunction;
|
||||||
|
|
||||||
|
inline bool FUNCTION_IsRx()
|
||||||
|
{
|
||||||
|
return gCurrentFunction == FUNCTION_MONITOR ||
|
||||||
|
gCurrentFunction == FUNCTION_INCOMING ||
|
||||||
|
gCurrentFunction == FUNCTION_RECEIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FUNCTION_Init(void)
|
void FUNCTION_Init(void)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
|
if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
gCurrentCodeType = gSelectedCodeType;
|
gCurrentCodeType = (gRxVfo->Modulation != MODULATION_FM) ? CODE_TYPE_OFF : gRxVfo->pRX->CodeType;
|
||||||
if (gCssScanMode == CSS_SCAN_MODE_OFF)
|
|
||||||
gCurrentCodeType = gRxVfo->AM_mode ? CODE_TYPE_OFF : gRxVfo->pRX->CodeType;
|
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
else
|
else
|
||||||
gCurrentCodeType = CODE_TYPE_CONTINUOUS_TONE;
|
gCurrentCodeType = CODE_TYPE_CONTINUOUS_TONE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
DTMF_clear_RX();
|
DTMF_clear_RX();
|
||||||
|
#endif
|
||||||
|
|
||||||
g_CxCSS_TAIL_Found = false;
|
g_CxCSS_TAIL_Found = false;
|
||||||
g_CDCSS_Lost = false;
|
g_CDCSS_Lost = false;
|
||||||
@@ -82,10 +92,150 @@ void FUNCTION_Init(void)
|
|||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FUNCTION_Foreground(const FUNCTION_Type_t PreviousFunction)
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
if (gDTMF_ReplyState != DTMF_REPLY_NONE)
|
||||||
|
RADIO_PrepareCssTX();
|
||||||
|
#endif
|
||||||
|
if (PreviousFunction == FUNCTION_TRANSMIT) {
|
||||||
|
ST7565_FixInterfGlitch();
|
||||||
|
gVFO_RSSI_bar_level[0] = 0;
|
||||||
|
gVFO_RSSI_bar_level[1] = 0;
|
||||||
|
} else if (PreviousFunction != FUNCTION_RECEIVE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(ENABLE_FMRADIO)
|
||||||
|
if (gFmRadioMode)
|
||||||
|
gFM_RestoreCountdown_10ms = fm_restore_countdown_10ms;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT ||
|
||||||
|
gDTMF_CallState == DTMF_CALL_STATE_RECEIVED ||
|
||||||
|
gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY)
|
||||||
|
{
|
||||||
|
gDTMF_auto_reset_time_500ms = gEeprom.DTMF_auto_reset_time * 2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
gUpdateStatus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FUNCTION_PowerSave() {
|
||||||
|
gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10;
|
||||||
|
gPowerSaveCountdownExpired = false;
|
||||||
|
|
||||||
|
gRxIdleMode = true;
|
||||||
|
|
||||||
|
gMonitor = false;
|
||||||
|
|
||||||
|
BK4819_DisableVox();
|
||||||
|
BK4819_Sleep();
|
||||||
|
|
||||||
|
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false);
|
||||||
|
|
||||||
|
gUpdateStatus = true;
|
||||||
|
|
||||||
|
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
|
||||||
|
GUI_SelectNextDisplay(DISPLAY_MAIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FUNCTION_Transmit()
|
||||||
|
{
|
||||||
|
// if DTMF is enabled when TX'ing, it changes the TX audio filtering !! .. 1of11
|
||||||
|
BK4819_DisableDTMF();
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
// clear the DTMF RX buffer
|
||||||
|
DTMF_clear_RX();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// clear the DTMF RX live decoder buffer
|
||||||
|
gDTMF_RX_live_timeout = 0;
|
||||||
|
gDTMF_RX_live_timeout = 0;
|
||||||
|
memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live));
|
||||||
|
|
||||||
|
#if defined(ENABLE_FMRADIO)
|
||||||
|
if (gFmRadioMode)
|
||||||
|
BK1080_Init(0, false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_ALARM
|
||||||
|
if (gAlarmState == ALARM_STATE_SITE_ALARM)
|
||||||
|
{
|
||||||
|
GUI_DisplayScreen();
|
||||||
|
|
||||||
|
AUDIO_AudioPathOff();
|
||||||
|
|
||||||
|
SYSTEM_DelayMs(20);
|
||||||
|
BK4819_PlayTone(500, 0);
|
||||||
|
SYSTEM_DelayMs(2);
|
||||||
|
|
||||||
|
AUDIO_AudioPathOn();
|
||||||
|
|
||||||
|
gEnableSpeaker = true;
|
||||||
|
|
||||||
|
SYSTEM_DelayMs(60);
|
||||||
|
BK4819_ExitTxMute();
|
||||||
|
|
||||||
|
gAlarmToneCounter = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gUpdateStatus = true;
|
||||||
|
|
||||||
|
GUI_DisplayScreen();
|
||||||
|
|
||||||
|
RADIO_SetTxParameters();
|
||||||
|
|
||||||
|
// turn the RED LED on
|
||||||
|
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true);
|
||||||
|
|
||||||
|
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 (gAlarmState != ALARM_STATE_OFF) {
|
||||||
|
#ifdef ENABLE_TX1750
|
||||||
|
if (gAlarmState == ALARM_STATE_TX1750)
|
||||||
|
BK4819_TransmitTone(true, 1750);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_ALARM
|
||||||
|
if (gAlarmState == ALARM_STATE_TXALARM)
|
||||||
|
BK4819_TransmitTone(true, 500);
|
||||||
|
|
||||||
|
gAlarmToneCounter = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SYSTEM_DelayMs(2);
|
||||||
|
AUDIO_AudioPathOn();
|
||||||
|
gEnableSpeaker = true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (gCurrentVfo->SCRAMBLING_TYPE > 0 && gSetting_ScrambleEnable)
|
||||||
|
BK4819_EnableScramble(gCurrentVfo->SCRAMBLING_TYPE - 1);
|
||||||
|
else
|
||||||
|
BK4819_DisableScramble();
|
||||||
|
|
||||||
|
if (gSetting_backlight_on_tx_rx & BACKLIGHT_ON_TR_TX) {
|
||||||
|
BACKLIGHT_TurnOn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void FUNCTION_Select(FUNCTION_Type_t Function)
|
void FUNCTION_Select(FUNCTION_Type_t Function)
|
||||||
{
|
{
|
||||||
const FUNCTION_Type_t PreviousFunction = gCurrentFunction;
|
const FUNCTION_Type_t PreviousFunction = gCurrentFunction;
|
||||||
const bool bWasPowerSave = (PreviousFunction == FUNCTION_POWER_SAVE);
|
const bool bWasPowerSave = PreviousFunction == FUNCTION_POWER_SAVE;
|
||||||
|
|
||||||
gCurrentFunction = Function;
|
gCurrentFunction = Function;
|
||||||
|
|
||||||
@@ -93,155 +243,29 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
|
|||||||
{
|
{
|
||||||
BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable();
|
BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable();
|
||||||
gRxIdleMode = false;
|
gRxIdleMode = false;
|
||||||
UI_DisplayStatus(false);
|
UI_DisplayStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Function)
|
switch (Function)
|
||||||
{
|
{
|
||||||
case FUNCTION_FOREGROUND:
|
case FUNCTION_FOREGROUND:
|
||||||
if (gDTMF_ReplyState != DTMF_REPLY_NONE)
|
FUNCTION_Foreground(PreviousFunction);
|
||||||
RADIO_PrepareCssTX();
|
|
||||||
|
|
||||||
if (PreviousFunction == FUNCTION_TRANSMIT)
|
|
||||||
{
|
|
||||||
gVFO_RSSI_bar_level[0] = 0;
|
|
||||||
gVFO_RSSI_bar_level[1] = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (PreviousFunction != FUNCTION_RECEIVE)
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if defined(ENABLE_FMRADIO)
|
|
||||||
if (gFmRadioMode)
|
|
||||||
gFM_RestoreCountdown_10ms = fm_restore_countdown_10ms;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT ||
|
|
||||||
gDTMF_CallState == DTMF_CALL_STATE_RECEIVED ||
|
|
||||||
gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY)
|
|
||||||
{
|
|
||||||
gDTMF_auto_reset_time_500ms = gEeprom.DTMF_auto_reset_time * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
gUpdateStatus = true;
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case FUNCTION_POWER_SAVE:
|
||||||
|
FUNCTION_PowerSave();
|
||||||
|
return;
|
||||||
|
|
||||||
|
case FUNCTION_TRANSMIT:
|
||||||
|
FUNCTION_Transmit();
|
||||||
|
break;
|
||||||
|
|
||||||
case FUNCTION_MONITOR:
|
case FUNCTION_MONITOR:
|
||||||
gMonitor = true;
|
gMonitor = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FUNCTION_INCOMING:
|
case FUNCTION_INCOMING:
|
||||||
case FUNCTION_RECEIVE:
|
case FUNCTION_RECEIVE:
|
||||||
break;
|
|
||||||
|
|
||||||
case FUNCTION_POWER_SAVE:
|
|
||||||
gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10;
|
|
||||||
gPowerSaveCountdownExpired = false;
|
|
||||||
|
|
||||||
gRxIdleMode = true;
|
|
||||||
|
|
||||||
gMonitor = false;
|
|
||||||
|
|
||||||
BK4819_DisableVox();
|
|
||||||
BK4819_Sleep();
|
|
||||||
|
|
||||||
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, false);
|
|
||||||
|
|
||||||
gUpdateStatus = true;
|
|
||||||
|
|
||||||
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
|
|
||||||
GUI_SelectNextDisplay(DISPLAY_MAIN);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
case FUNCTION_TRANSMIT:
|
|
||||||
|
|
||||||
// if DTMF is enabled when TX'ing, it changes the TX audio filtering !! .. 1of11
|
|
||||||
BK4819_DisableDTMF();
|
|
||||||
|
|
||||||
// clear the DTMF RX buffer
|
|
||||||
DTMF_clear_RX();
|
|
||||||
|
|
||||||
// clear the DTMF RX live decoder buffer
|
|
||||||
gDTMF_RX_live_timeout = 0;
|
|
||||||
gDTMF_RX_live_timeout = 0;
|
|
||||||
memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live));
|
|
||||||
|
|
||||||
#if defined(ENABLE_FMRADIO)
|
|
||||||
if (gFmRadioMode)
|
|
||||||
BK1080_Init(0, false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_ALARM
|
|
||||||
if (gAlarmState == ALARM_STATE_TXALARM && gEeprom.ALARM_MODE != ALARM_MODE_TONE)
|
|
||||||
{
|
|
||||||
gAlarmState = ALARM_STATE_ALARM;
|
|
||||||
|
|
||||||
GUI_DisplayScreen();
|
|
||||||
|
|
||||||
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(20);
|
|
||||||
BK4819_PlayTone(500, 0);
|
|
||||||
SYSTEM_DelayMs(2);
|
|
||||||
|
|
||||||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
|
||||||
|
|
||||||
gEnableSpeaker = true;
|
|
||||||
|
|
||||||
SYSTEM_DelayMs(60);
|
|
||||||
BK4819_ExitTxMute();
|
|
||||||
|
|
||||||
gAlarmToneCounter = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gUpdateStatus = true;
|
|
||||||
|
|
||||||
GUI_DisplayScreen();
|
|
||||||
|
|
||||||
RADIO_SetTxParameters();
|
|
||||||
|
|
||||||
// turn the RED LED on
|
|
||||||
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, true);
|
|
||||||
|
|
||||||
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 (gAlarmState != ALARM_STATE_OFF)
|
|
||||||
{
|
|
||||||
#ifdef ENABLE_TX1750
|
|
||||||
if (gAlarmState == ALARM_STATE_TX1750)
|
|
||||||
BK4819_TransmitTone(true, 1750);
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_ALARM
|
|
||||||
if (gAlarmState == ALARM_STATE_TXALARM)
|
|
||||||
BK4819_TransmitTone(true, 500);
|
|
||||||
#endif
|
|
||||||
SYSTEM_DelayMs(2);
|
|
||||||
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
|
|
||||||
#ifdef ENABLE_ALARM
|
|
||||||
gAlarmToneCounter = 0;
|
|
||||||
#endif
|
|
||||||
gEnableSpeaker = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (gCurrentVfo->SCRAMBLING_TYPE > 0 && gSetting_ScrambleEnable)
|
|
||||||
BK4819_EnableScramble(gCurrentVfo->SCRAMBLING_TYPE - 1);
|
|
||||||
else
|
|
||||||
BK4819_DisableScramble();
|
|
||||||
|
|
||||||
if (gSetting_backlight_on_tx_rx == 1 || gSetting_backlight_on_tx_rx == 3)
|
|
||||||
BACKLIGHT_TurnOn();
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FUNCTION_BAND_SCOPE:
|
case FUNCTION_BAND_SCOPE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -249,7 +273,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
|
|||||||
gBatterySaveCountdown_10ms = battery_save_count_10ms;
|
gBatterySaveCountdown_10ms = battery_save_count_10ms;
|
||||||
gSchedulePowerSave = false;
|
gSchedulePowerSave = false;
|
||||||
|
|
||||||
#if defined(ENABLE_FMRADIO)
|
#if defined(ENABLE_FMRADIO)
|
||||||
gFM_RestoreCountdown_10ms = 0;
|
gFM_RestoreCountdown_10ms = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,6 @@ extern FUNCTION_Type_t gCurrentFunction;
|
|||||||
|
|
||||||
void FUNCTION_Init(void);
|
void FUNCTION_Init(void);
|
||||||
void FUNCTION_Select(FUNCTION_Type_t Function);
|
void FUNCTION_Select(FUNCTION_Type_t Function);
|
||||||
|
bool FUNCTION_IsRx();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -21,11 +21,10 @@ def obfuscate(fw):
|
|||||||
return bytes([a^b for a, b in zip(fw, cycle(OBFUSCATION))])
|
return bytes([a^b for a, b in zip(fw, cycle(OBFUSCATION))])
|
||||||
|
|
||||||
plain = open(sys.argv[1], 'rb').read()
|
plain = open(sys.argv[1], 'rb').read()
|
||||||
if len(sys.argv[2]) > 10:
|
|
||||||
print('Version suffix is too big!')
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
version = b'*OEFW-' + bytes(sys.argv[2], 'ascii')
|
version = b'*' + bytes(sys.argv[2], 'ascii') + b' ' + bytes(sys.argv[3], 'ascii')
|
||||||
|
version = version[0:16]
|
||||||
|
|
||||||
if len(version) < 16:
|
if len(version) < 16:
|
||||||
version += b'\x00' * (16 - len(version))
|
version += b'\x00' * (16 - len(version))
|
||||||
|
|
||||||
@@ -36,5 +35,5 @@ crc.update(packed)
|
|||||||
digest = crc.digest()
|
digest = crc.digest()
|
||||||
digest = bytes([digest[1], digest[0]])
|
digest = bytes([digest[1], digest[0]])
|
||||||
|
|
||||||
open(sys.argv[3], 'wb').write(packed + digest)
|
open(sys.argv[4], 'wb').write(packed + digest)
|
||||||
|
|
||||||
|
|||||||
201
helper/battery.c
201
helper/battery.c
@@ -14,9 +14,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "battery.h"
|
#include "battery.h"
|
||||||
#include "driver/backlight.h"
|
#include "driver/backlight.h"
|
||||||
|
#include "driver/st7565.h"
|
||||||
|
#include "functions.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "settings.h"
|
||||||
#include "ui/battery.h"
|
#include "ui/battery.h"
|
||||||
#include "ui/menu.h"
|
#include "ui/menu.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
@@ -28,54 +33,63 @@ uint16_t gBatteryVoltages[4];
|
|||||||
uint16_t gBatteryVoltageAverage;
|
uint16_t gBatteryVoltageAverage;
|
||||||
uint8_t gBatteryDisplayLevel;
|
uint8_t gBatteryDisplayLevel;
|
||||||
bool gChargingWithTypeC;
|
bool gChargingWithTypeC;
|
||||||
bool gLowBattery;
|
|
||||||
bool gLowBatteryBlink;
|
bool gLowBatteryBlink;
|
||||||
|
bool gLowBattery;
|
||||||
|
bool gLowBatteryConfirmed;
|
||||||
uint16_t gBatteryCheckCounter;
|
uint16_t gBatteryCheckCounter;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BATTERY_LOW_INACTIVE,
|
||||||
|
BATTERY_LOW_ACTIVE,
|
||||||
|
BATTERY_LOW_CONFIRMED
|
||||||
|
} BatteryLow_t;
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t lowBatteryCountdown;
|
||||||
|
const uint16_t lowBatteryPeriod = 30;
|
||||||
|
|
||||||
volatile uint16_t gPowerSave_10ms;
|
volatile uint16_t gPowerSave_10ms;
|
||||||
|
|
||||||
/*
|
|
||||||
Based on real measurement
|
|
||||||
|
|
||||||
Volts Percent Volts Percent Volts Percent Volts Percent
|
const uint16_t Voltage2PercentageTable[][7][2] = {
|
||||||
8.28 100 7.95099 73 7.7184 46 7.48116 19
|
[BATTERY_TYPE_1600_MAH] = {
|
||||||
8.22 99 7.94188 72 7.71091 45 7.46364 18
|
{828, 100},
|
||||||
8.17 98 7.9338 71 7.70911 44 7.44789 17
|
{814, 97 },
|
||||||
8.13632 97 7.92684 70 7.70098 43 7.43318 16
|
{760, 25 },
|
||||||
8.12308 96 7.9178 69 7.69619 42 7.41864 15
|
{729, 6 },
|
||||||
8.09688 95 7.90823 68 7.69018 41 7.40579 14
|
{630, 0 },
|
||||||
8.08124 94 7.89858 67 7.68473 40 7.39289 13
|
{0, 0 },
|
||||||
8.06912 93 7.88667 66 7.67911 39 7.37839 12
|
{0, 0 },
|
||||||
8.05826 92 7.87673 65 7.67087 38 7.36017 11
|
},
|
||||||
8.05008 91 7.86864 64 7.66601 37 7.33704 10
|
|
||||||
8.04192 90 7.85802 63 7.6599 36 7.3079 9
|
[BATTERY_TYPE_2200_MAH] = {
|
||||||
8.03866 89 7.84816 62 7.65418 35 7.26793 8
|
{832, 100},
|
||||||
8.03089 88 7.83744 61 7.64775 34 7.21291 7
|
{813, 95 },
|
||||||
8.0284 87 7.82748 60 7.64065 33 7.13416 6
|
{740, 60 },
|
||||||
8.02044 86 7.81983 59 7.63136 32 7.02785 5
|
{707, 21 },
|
||||||
8.01832 85 7.80929 58 7.6244 31 6.89448 4
|
{682, 5 },
|
||||||
8.01072 84 7.79955 57 7.61636 30 6.72912 3
|
{630, 0 },
|
||||||
8.00965 83 7.79017 56 7.60738 29 6.5164 2
|
{0, 0 },
|
||||||
8.00333 82 7.78107 55 7.597 28 6.19272 1
|
},
|
||||||
7.99973 81 7.77167 54 7.5876 27 5.63138 0
|
};
|
||||||
7.99218 80 7.76509 53 7.57732 26
|
|
||||||
7.98999 79 7.75649 52 7.56563 25
|
static_assert(ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_1600_MAH]) ==
|
||||||
7.98234 78 7.74939 51 7.55356 24
|
ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_2200_MAH]));
|
||||||
7.97892 77 7.7411 50 7.54088 23
|
|
||||||
7.97043 76 7.73648 49 7.52683 22
|
|
||||||
7.96478 75 7.72911 48 7.51285 21
|
|
||||||
7.95983 74 7.72097 47 7.49832 20
|
|
||||||
*/
|
|
||||||
unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV)
|
unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV)
|
||||||
{
|
{
|
||||||
if (voltage_10mV > 814)
|
const uint16_t (*crv)[2] = Voltage2PercentageTable[gEeprom.BATTERY_TYPE];
|
||||||
return 100;
|
const int mulipl = 1000;
|
||||||
if (voltage_10mV > 756)
|
for (unsigned int i = 1; i < ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_2200_MAH]); i++) {
|
||||||
return ((132ul * voltage_10mV) / 100) - 974u;
|
if (voltage_10mV > crv[i][0]) {
|
||||||
if (voltage_10mV > 729)
|
const int a = (crv[i - 1][1] - crv[i][1]) * mulipl / (crv[i - 1][0] - crv[i][0]);
|
||||||
return ((63ul * voltage_10mV) / 100) - 452u;
|
const int b = crv[i][1] - a * crv[i][0] / mulipl;
|
||||||
if (voltage_10mV > 600)
|
const int p = a * voltage_10mV / mulipl + b;
|
||||||
return ((52ul * voltage_10mV) / 1000) - 31u;
|
return MIN(p, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,29 +98,26 @@ void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
|
|||||||
const uint8_t PreviousBatteryLevel = gBatteryDisplayLevel;
|
const uint8_t PreviousBatteryLevel = gBatteryDisplayLevel;
|
||||||
const uint16_t Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] + gBatteryVoltages[3]) / 4;
|
const uint16_t Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] + gBatteryVoltages[3]) / 4;
|
||||||
|
|
||||||
gBatteryDisplayLevel = 0;
|
|
||||||
|
|
||||||
if (gBatteryCalibration[5] < Voltage)
|
|
||||||
gBatteryDisplayLevel = 6;
|
|
||||||
else
|
|
||||||
if (gBatteryCalibration[4] < Voltage)
|
|
||||||
gBatteryDisplayLevel = 5;
|
|
||||||
else
|
|
||||||
if (gBatteryCalibration[3] < Voltage)
|
|
||||||
gBatteryDisplayLevel = 4;
|
|
||||||
else
|
|
||||||
if (gBatteryCalibration[2] < Voltage)
|
|
||||||
gBatteryDisplayLevel = 3;
|
|
||||||
else
|
|
||||||
if (gBatteryCalibration[1] < Voltage)
|
|
||||||
gBatteryDisplayLevel = 2;
|
|
||||||
else
|
|
||||||
if (gBatteryCalibration[0] < Voltage)
|
|
||||||
gBatteryDisplayLevel = 1;
|
|
||||||
|
|
||||||
gBatteryVoltageAverage = (Voltage * 760) / gBatteryCalibration[3];
|
gBatteryVoltageAverage = (Voltage * 760) / gBatteryCalibration[3];
|
||||||
|
|
||||||
if ((gScreenToDisplay == DISPLAY_MENU) && gMenuCursor == MENU_VOL)
|
if(gBatteryVoltageAverage > 890)
|
||||||
|
gBatteryDisplayLevel = 7; // battery overvoltage
|
||||||
|
else if(gBatteryVoltageAverage < 630)
|
||||||
|
gBatteryDisplayLevel = 0; // battery critical
|
||||||
|
else {
|
||||||
|
gBatteryDisplayLevel = 1;
|
||||||
|
const uint8_t levels[] = {5,17,41,65,88};
|
||||||
|
uint8_t perc = BATTERY_VoltsToPercent(gBatteryVoltageAverage);
|
||||||
|
for(uint8_t i = 6; i >= 1; i--){
|
||||||
|
if (perc > levels[i-2]) {
|
||||||
|
gBatteryDisplayLevel = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((gScreenToDisplay == DISPLAY_MENU) && UI_MENU_GetCurrentMenuId() == MENU_VOL)
|
||||||
gUpdateDisplay = true;
|
gUpdateDisplay = true;
|
||||||
|
|
||||||
if (gBatteryCurrent < 501)
|
if (gBatteryCurrent < 501)
|
||||||
@@ -133,7 +144,9 @@ void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
|
|||||||
|
|
||||||
if (PreviousBatteryLevel != gBatteryDisplayLevel)
|
if (PreviousBatteryLevel != gBatteryDisplayLevel)
|
||||||
{
|
{
|
||||||
if (gBatteryDisplayLevel < 2)
|
if(gBatteryDisplayLevel > 2)
|
||||||
|
gLowBatteryConfirmed = false;
|
||||||
|
else if (gBatteryDisplayLevel < 2)
|
||||||
{
|
{
|
||||||
gLowBattery = true;
|
gLowBattery = true;
|
||||||
}
|
}
|
||||||
@@ -145,6 +158,68 @@ void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
|
|||||||
UI_DisplayBattery(gBatteryDisplayLevel, gLowBatteryBlink);
|
UI_DisplayBattery(gBatteryDisplayLevel, gLowBatteryBlink);
|
||||||
}
|
}
|
||||||
|
|
||||||
gLowBatteryCountdown = 0;
|
if(!gLowBatteryConfirmed)
|
||||||
|
gUpdateDisplay = true;
|
||||||
|
|
||||||
|
lowBatteryCountdown = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BATTERY_TimeSlice500ms(void)
|
||||||
|
{
|
||||||
|
if (!gLowBattery) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gLowBatteryBlink = ++lowBatteryCountdown & 1;
|
||||||
|
|
||||||
|
UI_DisplayBattery(0, gLowBatteryBlink);
|
||||||
|
|
||||||
|
if (gCurrentFunction == FUNCTION_TRANSMIT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not transmitting
|
||||||
|
|
||||||
|
if (lowBatteryCountdown < lowBatteryPeriod) {
|
||||||
|
if (lowBatteryCountdown == lowBatteryPeriod-1 && !gChargingWithTypeC && !gLowBatteryConfirmed) {
|
||||||
|
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lowBatteryCountdown = 0;
|
||||||
|
|
||||||
|
if (gChargingWithTypeC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not on charge
|
||||||
|
if (!gLowBatteryConfirmed) {
|
||||||
|
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP);
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
AUDIO_SetVoiceID(0, VOICE_ID_LOW_VOLTAGE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gBatteryDisplayLevel != 0) {
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
AUDIO_PlaySingleVoice(false);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
AUDIO_PlaySingleVoice(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gReducedService = true;
|
||||||
|
|
||||||
|
FUNCTION_Select(FUNCTION_POWER_SAVE);
|
||||||
|
|
||||||
|
ST7565_HardwareReset();
|
||||||
|
|
||||||
|
if (gEeprom.BACKLIGHT_TIME < (ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1)) {
|
||||||
|
BACKLIGHT_TurnOff();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,14 +27,22 @@ extern uint16_t gBatteryVoltages[4];
|
|||||||
extern uint16_t gBatteryVoltageAverage;
|
extern uint16_t gBatteryVoltageAverage;
|
||||||
extern uint8_t gBatteryDisplayLevel;
|
extern uint8_t gBatteryDisplayLevel;
|
||||||
extern bool gChargingWithTypeC;
|
extern bool gChargingWithTypeC;
|
||||||
extern bool gLowBattery;
|
|
||||||
extern bool gLowBatteryBlink;
|
extern bool gLowBatteryBlink;
|
||||||
|
extern bool gLowBattery;
|
||||||
|
extern bool gLowBatteryConfirmed;
|
||||||
extern uint16_t gBatteryCheckCounter;
|
extern uint16_t gBatteryCheckCounter;
|
||||||
|
|
||||||
extern volatile uint16_t gPowerSave_10ms;
|
extern volatile uint16_t gPowerSave_10ms;
|
||||||
|
|
||||||
unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV);
|
typedef enum {
|
||||||
void BATTERY_GetReadings(const bool bDisplayBatteryLevel);
|
BATTERY_TYPE_1600_MAH,
|
||||||
|
BATTERY_TYPE_2200_MAH,
|
||||||
|
BATTERY_TYPE_UNKNOWN
|
||||||
|
} BATTERY_Type_t;
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int BATTERY_VoltsToPercent(unsigned int voltage_10mV);
|
||||||
|
void BATTERY_GetReadings(bool bDisplayBatteryLevel);
|
||||||
|
void BATTERY_TimeSlice500ms(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ void BOOT_ProcessMode(BOOT_Mode_t Mode)
|
|||||||
gEeprom.KEY_1_LONG_PRESS_ACTION = ACTION_OPT_NONE;
|
gEeprom.KEY_1_LONG_PRESS_ACTION = ACTION_OPT_NONE;
|
||||||
gEeprom.KEY_2_SHORT_PRESS_ACTION = ACTION_OPT_NONE;
|
gEeprom.KEY_2_SHORT_PRESS_ACTION = ACTION_OPT_NONE;
|
||||||
gEeprom.KEY_2_LONG_PRESS_ACTION = ACTION_OPT_NONE;
|
gEeprom.KEY_2_LONG_PRESS_ACTION = ACTION_OPT_NONE;
|
||||||
|
gEeprom.KEY_M_LONG_PRESS_ACTION = ACTION_OPT_NONE;
|
||||||
|
|
||||||
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_LAST - 1, 41002500);
|
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_LAST - 1, 41002500);
|
||||||
|
|
||||||
|
|||||||
BIN
images/codespace1.png
Normal file
BIN
images/codespace1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 81 KiB |
BIN
images/codespace2.png
Normal file
BIN
images/codespace2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 122 KiB |
143
main.c
143
main.c
@@ -14,44 +14,52 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h> // NULL
|
#include <stdio.h> // NULL
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX
|
#ifdef ENABLE_AM_FIX
|
||||||
#include "am_fix.h"
|
#include "am_fix.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "audio.h"
|
||||||
|
#include "board.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "radio.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
#include "app/dtmf.h"
|
#include "app/dtmf.h"
|
||||||
#include "audio.h"
|
|
||||||
#include "bsp/dp32g030/gpio.h"
|
#include "bsp/dp32g030/gpio.h"
|
||||||
#include "bsp/dp32g030/syscon.h"
|
#include "bsp/dp32g030/syscon.h"
|
||||||
#include "board.h"
|
|
||||||
#include "driver/backlight.h"
|
#include "driver/backlight.h"
|
||||||
#include "driver/bk4819.h"
|
#include "driver/bk4819.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "driver/system.h"
|
#include "driver/system.h"
|
||||||
#include "driver/systick.h"
|
#include "driver/systick.h"
|
||||||
#include "driver/uart.h"
|
#ifdef ENABLE_UART
|
||||||
|
#include "driver/uart.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "helper/battery.h"
|
#include "helper/battery.h"
|
||||||
#include "helper/boot.h"
|
#include "helper/boot.h"
|
||||||
#include "misc.h"
|
|
||||||
#include "radio.h"
|
|
||||||
#include "settings.h"
|
|
||||||
#include "ui/lock.h"
|
#include "ui/lock.h"
|
||||||
#include "ui/welcome.h"
|
#include "ui/welcome.h"
|
||||||
#include "ui/menu.h"
|
#include "ui/menu.h"
|
||||||
#include "version.h"
|
void _putchar(__attribute__((unused)) char c)
|
||||||
|
|
||||||
void _putchar(char c)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef ENABLE_UART
|
||||||
UART_Send((uint8_t *)&c, 1);
|
UART_Send((uint8_t *)&c, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Main(void)
|
void Main(void)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
|
||||||
BOOT_Mode_t BootMode;
|
|
||||||
|
|
||||||
// Enable clock gating of blocks we need
|
// Enable clock gating of blocks we need
|
||||||
SYSCON_DEV_CLK_GATE = 0
|
SYSCON_DEV_CLK_GATE = 0
|
||||||
| SYSCON_DEV_CLK_GATE_GPIOA_BITS_ENABLE
|
| SYSCON_DEV_CLK_GATE_GPIOA_BITS_ENABLE
|
||||||
@@ -61,20 +69,22 @@ void Main(void)
|
|||||||
| SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE
|
| SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE
|
||||||
| SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE
|
| SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE
|
||||||
| SYSCON_DEV_CLK_GATE_CRC_BITS_ENABLE
|
| SYSCON_DEV_CLK_GATE_CRC_BITS_ENABLE
|
||||||
| SYSCON_DEV_CLK_GATE_AES_BITS_ENABLE;
|
| SYSCON_DEV_CLK_GATE_AES_BITS_ENABLE
|
||||||
|
| SYSCON_DEV_CLK_GATE_PWM_PLUS0_BITS_ENABLE;
|
||||||
|
|
||||||
|
|
||||||
SYSTICK_Init();
|
SYSTICK_Init();
|
||||||
BOARD_Init();
|
BOARD_Init();
|
||||||
UART_Init();
|
|
||||||
|
|
||||||
boot_counter_10ms = 250; // 2.5 sec
|
boot_counter_10ms = 250; // 2.5 sec
|
||||||
|
|
||||||
|
#ifdef ENABLE_UART
|
||||||
|
UART_Init();
|
||||||
UART_Send(UART_Version, strlen(UART_Version));
|
UART_Send(UART_Version, strlen(UART_Version));
|
||||||
|
#endif
|
||||||
|
|
||||||
// Not implementing authentic device checks
|
// Not implementing authentic device checks
|
||||||
|
|
||||||
memset(&gEeprom, 0, sizeof(gEeprom));
|
|
||||||
|
|
||||||
memset(gDTMF_String, '-', sizeof(gDTMF_String));
|
memset(gDTMF_String, '-', sizeof(gDTMF_String));
|
||||||
gDTMF_String[sizeof(gDTMF_String) - 1] = 0;
|
gDTMF_String[sizeof(gDTMF_String) - 1] = 0;
|
||||||
|
|
||||||
@@ -82,9 +92,9 @@ void Main(void)
|
|||||||
|
|
||||||
BOARD_ADC_GetBatteryInfo(&gBatteryCurrentVoltage, &gBatteryCurrent);
|
BOARD_ADC_GetBatteryInfo(&gBatteryCurrentVoltage, &gBatteryCurrent);
|
||||||
|
|
||||||
BOARD_EEPROM_Init();
|
SETTINGS_InitEEPROM();
|
||||||
|
SETTINGS_WriteBuildOptions();
|
||||||
BOARD_EEPROM_LoadMoreSettings();
|
SETTINGS_LoadCalibration();
|
||||||
|
|
||||||
RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD);
|
RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD);
|
||||||
RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD);
|
RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD);
|
||||||
@@ -93,34 +103,29 @@ void Main(void)
|
|||||||
|
|
||||||
RADIO_SetupRegisters(true);
|
RADIO_SetupRegisters(true);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(gBatteryVoltages); i++)
|
for (unsigned int i = 0; i < ARRAY_SIZE(gBatteryVoltages); i++)
|
||||||
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[i], &gBatteryCurrent);
|
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[i], &gBatteryCurrent);
|
||||||
|
|
||||||
BATTERY_GetReadings(false);
|
BATTERY_GetReadings(false);
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX
|
#ifdef ENABLE_AM_FIX
|
||||||
AM_fix_init();
|
AM_fix_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BootMode = BOOT_GetMode();
|
const BOOT_Mode_t BootMode = BOOT_GetMode();
|
||||||
|
|
||||||
// count the number of menu items
|
|
||||||
gMenuListCount = 0;
|
|
||||||
while (MenuList[gMenuListCount].name[0] != '\0')
|
|
||||||
gMenuListCount++;
|
|
||||||
|
|
||||||
if (BootMode == BOOT_MODE_F_LOCK)
|
if (BootMode == BOOT_MODE_F_LOCK)
|
||||||
{
|
{
|
||||||
gF_LOCK = true; // flag to say include the hidden menu items
|
gF_LOCK = true; // flag to say include the hidden menu items
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{ // hide the hidden menu items
|
|
||||||
|
|
||||||
gMenuListCount -= 9;
|
// count the number of menu items
|
||||||
|
gMenuListCount = 0;
|
||||||
|
while (MenuList[gMenuListCount].name[0] != '\0') {
|
||||||
|
if(!gF_LOCK && MenuList[gMenuListCount].menu_id == FIRST_HIDDEN_MENU_ITEM)
|
||||||
|
break;
|
||||||
|
|
||||||
#ifndef ENABLE_F_CAL_MENU
|
gMenuListCount++;
|
||||||
gMenuListCount++;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for user to release all butts before moving on
|
// wait for user to release all butts before moving on
|
||||||
@@ -130,8 +135,9 @@ void Main(void)
|
|||||||
{ // keys are pressed
|
{ // keys are pressed
|
||||||
UI_DisplayReleaseKeys();
|
UI_DisplayReleaseKeys();
|
||||||
BACKLIGHT_TurnOn();
|
BACKLIGHT_TurnOn();
|
||||||
i = 0;
|
|
||||||
while (i < 50) // 500ms
|
// 500ms
|
||||||
|
for (int i = 0; i < 50;)
|
||||||
{
|
{
|
||||||
i = (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && KEYBOARD_Poll() == KEY_INVALID) ? i + 1 : 0;
|
i = (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && KEYBOARD_Poll() == KEY_INVALID) ? i + 1 : 0;
|
||||||
SYSTEM_DelayMs(10);
|
SYSTEM_DelayMs(10);
|
||||||
@@ -145,10 +151,10 @@ void Main(void)
|
|||||||
{
|
{
|
||||||
FUNCTION_Select(FUNCTION_POWER_SAVE);
|
FUNCTION_Select(FUNCTION_POWER_SAVE);
|
||||||
|
|
||||||
if (gEeprom.BACKLIGHT < (ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1))
|
if (gEeprom.BACKLIGHT_TIME < (ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1)) // backlight is not set to be always on
|
||||||
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight OFF
|
BACKLIGHT_TurnOff(); // turn the backlight OFF
|
||||||
else
|
else
|
||||||
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight ON
|
BACKLIGHT_TurnOn(); // turn the backlight ON
|
||||||
|
|
||||||
gReducedService = true;
|
gReducedService = true;
|
||||||
}
|
}
|
||||||
@@ -167,21 +173,21 @@ void Main(void)
|
|||||||
boot_counter_10ms = 0;
|
boot_counter_10ms = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_BOOT_BEEPS
|
#ifdef ENABLE_BOOT_BEEPS
|
||||||
if ((boot_counter_10ms % 25) == 0)
|
if ((boot_counter_10ms % 25) == 0)
|
||||||
AUDIO_PlayBeep(BEEP_880HZ_40MS_OPTIONAL);
|
AUDIO_PlayBeep(BEEP_880HZ_40MS_OPTIONAL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_PWRON_PASSWORD
|
#ifdef ENABLE_PWRON_PASSWORD
|
||||||
if (gEeprom.POWER_ON_PASSWORD < 1000000)
|
if (gEeprom.POWER_ON_PASSWORD < 1000000)
|
||||||
{
|
{
|
||||||
bIsInLockScreen = true;
|
bIsInLockScreen = true;
|
||||||
UI_DisplayLock();
|
UI_DisplayLock();
|
||||||
bIsInLockScreen = false;
|
bIsInLockScreen = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BOOT_ProcessMode(BootMode);
|
BOOT_ProcessMode(BootMode);
|
||||||
|
|
||||||
@@ -189,7 +195,7 @@ void Main(void)
|
|||||||
|
|
||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
{
|
{
|
||||||
uint8_t Channel;
|
uint8_t Channel;
|
||||||
|
|
||||||
@@ -201,35 +207,28 @@ void Main(void)
|
|||||||
AUDIO_SetVoiceID(1, VOICE_ID_CHANNEL_MODE);
|
AUDIO_SetVoiceID(1, VOICE_ID_CHANNEL_MODE);
|
||||||
AUDIO_SetDigitVoice(2, Channel + 1);
|
AUDIO_SetDigitVoice(2, Channel + 1);
|
||||||
}
|
}
|
||||||
else
|
else if (IS_FREQ_CHANNEL(Channel))
|
||||||
if (IS_FREQ_CHANNEL(Channel))
|
|
||||||
AUDIO_SetVoiceID(1, VOICE_ID_FREQUENCY_MODE);
|
AUDIO_SetVoiceID(1, VOICE_ID_FREQUENCY_MODE);
|
||||||
|
|
||||||
AUDIO_PlaySingleVoice(0);
|
AUDIO_PlaySingleVoice(0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
RADIO_ConfigureNOAA();
|
RADIO_ConfigureNOAA();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ******************
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (true) {
|
||||||
{
|
|
||||||
APP_Update();
|
APP_Update();
|
||||||
|
|
||||||
if (gNextTimeslice)
|
if (gNextTimeslice) {
|
||||||
{
|
|
||||||
APP_TimeSlice10ms();
|
|
||||||
gNextTimeslice = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gNextTimeslice_500ms)
|
APP_TimeSlice10ms();
|
||||||
{
|
|
||||||
APP_TimeSlice500ms();
|
if (gNextTimeslice_500ms) {
|
||||||
gNextTimeslice_500ms = false;
|
APP_TimeSlice500ms();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
120
misc.c
120
misc.c
@@ -19,19 +19,22 @@
|
|||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
const uint8_t fm_resume_countdown_500ms = 2500 / 500; // 2.5 seconds
|
|
||||||
const uint8_t fm_radio_countdown_500ms = 2000 / 500; // 2 seconds
|
const uint8_t fm_radio_countdown_500ms = 2000 / 500; // 2 seconds
|
||||||
const uint16_t fm_play_countdown_scan_10ms = 100 / 10; // 100ms
|
const uint16_t fm_play_countdown_scan_10ms = 100 / 10; // 100ms
|
||||||
const uint16_t fm_play_countdown_noscan_10ms = 1200 / 10; // 1.2 seconds
|
const uint16_t fm_play_countdown_noscan_10ms = 1200 / 10; // 1.2 seconds
|
||||||
const uint16_t fm_restore_countdown_10ms = 5000 / 10; // 5 seconds
|
const uint16_t fm_restore_countdown_10ms = 5000 / 10; // 5 seconds
|
||||||
|
|
||||||
|
const uint8_t vfo_state_resume_countdown_500ms = 2500 / 500; // 2.5 seconds
|
||||||
|
|
||||||
const uint8_t menu_timeout_500ms = 20000 / 500; // 20 seconds
|
const uint8_t menu_timeout_500ms = 20000 / 500; // 20 seconds
|
||||||
const uint16_t menu_timeout_long_500ms = 120000 / 500; // 2 minutes
|
const uint16_t menu_timeout_long_500ms = 120000 / 500; // 2 minutes
|
||||||
|
|
||||||
const uint8_t DTMF_RX_live_timeout_500ms = 6000 / 500; // 6 seconds live decoder on screen
|
const uint8_t DTMF_RX_live_timeout_500ms = 6000 / 500; // 6 seconds live decoder on screen
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
const uint8_t DTMF_RX_timeout_500ms = 10000 / 500; // 10 seconds till we wipe the DTMF receiver
|
const uint8_t DTMF_RX_timeout_500ms = 10000 / 500; // 10 seconds till we wipe the DTMF receiver
|
||||||
const uint8_t DTMF_decode_ring_countdown_500ms = 15000 / 500; // 15 seconds .. time we sound the ringing for
|
const uint8_t DTMF_decode_ring_countdown_500ms = 15000 / 500; // 15 seconds .. time we sound the ringing for
|
||||||
const uint8_t DTMF_txstop_countdown_500ms = 3000 / 500; // 6 seconds
|
const uint8_t DTMF_txstop_countdown_500ms = 3000 / 500; // 6 seconds
|
||||||
|
#endif
|
||||||
|
|
||||||
const uint8_t key_input_timeout_500ms = 8000 / 500; // 8 seconds
|
const uint8_t key_input_timeout_500ms = 8000 / 500; // 8 seconds
|
||||||
|
|
||||||
@@ -72,30 +75,26 @@ const uint16_t NOAA_countdown_10ms = 5000 / 10; // 5 seconds
|
|||||||
const uint16_t NOAA_countdown_2_10ms = 500 / 10; // 500ms
|
const uint16_t NOAA_countdown_2_10ms = 500 / 10; // 500ms
|
||||||
const uint16_t NOAA_countdown_3_10ms = 200 / 10; // 200ms
|
const uint16_t NOAA_countdown_3_10ms = 200 / 10; // 200ms
|
||||||
|
|
||||||
//const uint16_t gMax_bat_v = 840; // 8.4V
|
|
||||||
//const uint16_t gMin_bat_v = 660; // 6.6V
|
|
||||||
|
|
||||||
const uint32_t gDefaultAesKey[4] = {0x4AA5CC60, 0x0312CC5F, 0xFFD2DABB, 0x6BBA7F92};
|
const uint32_t gDefaultAesKey[4] = {0x4AA5CC60, 0x0312CC5F, 0xFFD2DABB, 0x6BBA7F92};
|
||||||
|
|
||||||
const uint8_t gMicGain_dB2[5] = {3, 8, 16, 24, 31};
|
const uint8_t gMicGain_dB2[5] = {3, 8, 16, 24, 31};
|
||||||
|
|
||||||
bool gSetting_350TX;
|
bool gSetting_350TX;
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
bool gSetting_KILLED;
|
bool gSetting_KILLED;
|
||||||
|
#endif
|
||||||
bool gSetting_200TX;
|
bool gSetting_200TX;
|
||||||
bool gSetting_500TX;
|
bool gSetting_500TX;
|
||||||
bool gSetting_350EN;
|
bool gSetting_350EN;
|
||||||
bool gSetting_TX_EN;
|
|
||||||
uint8_t gSetting_F_LOCK;
|
uint8_t gSetting_F_LOCK;
|
||||||
bool gSetting_ScrambleEnable;
|
bool gSetting_ScrambleEnable;
|
||||||
|
|
||||||
uint8_t gSetting_backlight_on_tx_rx;
|
enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX
|
#ifdef ENABLE_AM_FIX
|
||||||
bool gSetting_AM_fix;
|
bool gSetting_AM_fix;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_AM_FIX_TEST1
|
|
||||||
uint8_t gSetting_AM_fix_test1 = 0;
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_AUDIO_BAR
|
#ifdef ENABLE_AUDIO_BAR
|
||||||
bool gSetting_mic_bar;
|
bool gSetting_mic_bar;
|
||||||
#endif
|
#endif
|
||||||
@@ -109,17 +108,12 @@ bool bHasCustomAesKey;
|
|||||||
uint32_t gChallenge[4];
|
uint32_t gChallenge[4];
|
||||||
uint8_t gTryCount;
|
uint8_t gTryCount;
|
||||||
|
|
||||||
uint8_t gEEPROM_1EC0_0[8];
|
uint16_t gEEPROM_RSSI_CALIB[7][4];
|
||||||
uint8_t gEEPROM_1EC0_1[8];
|
|
||||||
uint8_t gEEPROM_1EC0_2[8];
|
|
||||||
uint8_t gEEPROM_1EC0_3[8];
|
|
||||||
|
|
||||||
uint16_t gEEPROM_RSSI_CALIB[2][4];
|
|
||||||
|
|
||||||
uint16_t gEEPROM_1F8A;
|
uint16_t gEEPROM_1F8A;
|
||||||
uint16_t gEEPROM_1F8C;
|
uint16_t gEEPROM_1F8C;
|
||||||
|
|
||||||
uint8_t gMR_ChannelAttributes[FREQ_CHANNEL_LAST + 1];
|
ChannelAttributes_t gMR_ChannelAttributes[FREQ_CHANNEL_LAST + 1];
|
||||||
|
|
||||||
volatile uint16_t gBatterySaveCountdown_10ms = battery_save_count_10ms;
|
volatile uint16_t gBatterySaveCountdown_10ms = battery_save_count_10ms;
|
||||||
|
|
||||||
@@ -129,7 +123,6 @@ volatile bool gSchedulePowerSave;
|
|||||||
volatile bool gScheduleDualWatch = true;
|
volatile bool gScheduleDualWatch = true;
|
||||||
|
|
||||||
volatile uint16_t gDualWatchCountdown_10ms;
|
volatile uint16_t gDualWatchCountdown_10ms;
|
||||||
volatile bool gDualWatchCountdownExpired = true;
|
|
||||||
bool gDualWatchActive = false;
|
bool gDualWatchActive = false;
|
||||||
|
|
||||||
volatile uint8_t gSerialConfigCountDown_500ms;
|
volatile uint8_t gSerialConfigCountDown_500ms;
|
||||||
@@ -141,6 +134,8 @@ volatile bool gTxTimeoutReached;
|
|||||||
|
|
||||||
volatile uint16_t gTailNoteEliminationCountdown_10ms;
|
volatile uint16_t gTailNoteEliminationCountdown_10ms;
|
||||||
|
|
||||||
|
volatile uint8_t gVFOStateResumeCountdown_500ms;
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
volatile uint16_t gNOAA_Countdown_10ms;
|
volatile uint16_t gNOAA_Countdown_10ms;
|
||||||
#endif
|
#endif
|
||||||
@@ -160,8 +155,11 @@ uint8_t gVFO_RSSI_bar_level[2];
|
|||||||
|
|
||||||
uint8_t gReducedService;
|
uint8_t gReducedService;
|
||||||
uint8_t gBatteryVoltageIndex;
|
uint8_t gBatteryVoltageIndex;
|
||||||
CssScanMode_t gCssScanMode;
|
bool gCssBackgroundScan;
|
||||||
bool gUpdateRSSI;
|
|
||||||
|
volatile bool gScheduleScanListen = true;
|
||||||
|
volatile uint16_t gScanPauseDelayIn_10ms;
|
||||||
|
|
||||||
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
|
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
|
||||||
AlarmState_t gAlarmState;
|
AlarmState_t gAlarmState;
|
||||||
#endif
|
#endif
|
||||||
@@ -200,17 +198,13 @@ bool g_CxCSS_TAIL_Found;
|
|||||||
uint16_t gVoxPauseCountdown;
|
uint16_t gVoxPauseCountdown;
|
||||||
#endif
|
#endif
|
||||||
bool g_SquelchLost;
|
bool g_SquelchLost;
|
||||||
uint8_t gFlashLightState;
|
|
||||||
volatile uint16_t gFlashLightBlinkCounter;
|
volatile uint16_t gFlashLightBlinkCounter;
|
||||||
|
|
||||||
bool gFlagEndTransmission;
|
bool gFlagEndTransmission;
|
||||||
uint16_t gLowBatteryCountdown;
|
|
||||||
uint8_t gNextMrChannel;
|
uint8_t gNextMrChannel;
|
||||||
ReceptionMode_t gRxReceptionMode;
|
ReceptionMode_t gRxReceptionMode;
|
||||||
|
|
||||||
uint8_t gRestoreMrChannel;
|
|
||||||
enum scan_next_chan_t gCurrentScanList;
|
|
||||||
uint32_t gRestoreFrequency;
|
|
||||||
|
|
||||||
bool gRxVfoIsActive;
|
bool gRxVfoIsActive;
|
||||||
#ifdef ENABLE_ALARM
|
#ifdef ENABLE_ALARM
|
||||||
uint8_t gAlarmToneCounter;
|
uint8_t gAlarmToneCounter;
|
||||||
@@ -222,9 +216,6 @@ uint8_t gPttDebounceCounter;
|
|||||||
uint8_t gMenuListCount;
|
uint8_t gMenuListCount;
|
||||||
uint8_t gBackup_CROSS_BAND_RX_TX;
|
uint8_t gBackup_CROSS_BAND_RX_TX;
|
||||||
uint8_t gScanDelay_10ms;
|
uint8_t gScanDelay_10ms;
|
||||||
#ifdef ENABLE_AIRCOPY
|
|
||||||
uint8_t gAircopySendCountdown;
|
|
||||||
#endif
|
|
||||||
uint8_t gFSKWriteIndex;
|
uint8_t gFSKWriteIndex;
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
@@ -256,70 +247,11 @@ volatile bool gFlagTailNoteEliminationComplete;
|
|||||||
|
|
||||||
volatile uint8_t boot_counter_10ms;
|
volatile uint8_t boot_counter_10ms;
|
||||||
|
|
||||||
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)
|
inline void FUNCTION_NOP() { ; }
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
uint32_t Multiplier = 10000000;
|
|
||||||
uint32_t Value = 0;
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
if (pDigits[i] > 9)
|
|
||||||
break;
|
|
||||||
Value += pDigits[i] * Multiplier;
|
|
||||||
Multiplier /= 10U;
|
|
||||||
}
|
|
||||||
*pInteger = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NUMBER_ToDigits(uint32_t Value, char *pDigits)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
const uint32_t Result = Value / 10U;
|
|
||||||
pDigits[7 - i] = Value - (Result * 10U);
|
|
||||||
Value = Result;
|
|
||||||
}
|
|
||||||
pDigits[8] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit)
|
int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit)
|
||||||
{
|
{
|
||||||
@@ -333,3 +265,15 @@ int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit,
|
|||||||
|
|
||||||
return Base;
|
return Base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long StrToUL(const char * str)
|
||||||
|
{
|
||||||
|
unsigned long ul = 0;
|
||||||
|
for(uint8_t i = 0; i < strlen(str); i++){
|
||||||
|
char c = str[i];
|
||||||
|
if(c < '0' || c > '9')
|
||||||
|
break;
|
||||||
|
ul = ul * 10 + (uint8_t)(c-'0');
|
||||||
|
}
|
||||||
|
return ul;
|
||||||
|
}
|
||||||
|
|||||||
116
misc.h
116
misc.h
@@ -32,12 +32,14 @@
|
|||||||
#define MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
|
#define MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define IS_MR_CHANNEL(x) ((x) >= MR_CHANNEL_FIRST && (x) <= MR_CHANNEL_LAST)
|
#ifndef SWAP
|
||||||
|
#define SWAP(a, b) ({ __typeof__ (a) _c = (a); a = b; b = _c; })
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IS_MR_CHANNEL(x) ((x) <= MR_CHANNEL_LAST)
|
||||||
#define IS_FREQ_CHANNEL(x) ((x) >= FREQ_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST)
|
#define IS_FREQ_CHANNEL(x) ((x) >= FREQ_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST)
|
||||||
#define IS_VALID_CHANNEL(x) ((x) < LAST_CHANNEL)
|
#define IS_VALID_CHANNEL(x) ((x) < LAST_CHANNEL)
|
||||||
|
|
||||||
#define IS_NOAA_CHANNEL(x) ((x) >= NOAA_CHANNEL_FIRST && (x) <= NOAA_CHANNEL_LAST)
|
#define IS_NOAA_CHANNEL(x) ((x) >= NOAA_CHANNEL_FIRST && (x) <= NOAA_CHANNEL_LAST)
|
||||||
#define IS_NOT_NOAA_CHANNEL(x) ((x) >= MR_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST)
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MR_CHANNEL_FIRST = 0,
|
MR_CHANNEL_FIRST = 0,
|
||||||
@@ -49,12 +51,6 @@ enum {
|
|||||||
LAST_CHANNEL
|
LAST_CHANNEL
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
FLASHLIGHT_OFF = 0,
|
|
||||||
FLASHLIGHT_ON,
|
|
||||||
FLASHLIGHT_BLINK
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
VFO_CONFIGURE_NONE = 0,
|
VFO_CONFIGURE_NONE = 0,
|
||||||
VFO_CONFIGURE,
|
VFO_CONFIGURE,
|
||||||
@@ -64,7 +60,7 @@ enum {
|
|||||||
enum AlarmState_t {
|
enum AlarmState_t {
|
||||||
ALARM_STATE_OFF = 0,
|
ALARM_STATE_OFF = 0,
|
||||||
ALARM_STATE_TXALARM,
|
ALARM_STATE_TXALARM,
|
||||||
ALARM_STATE_ALARM,
|
ALARM_STATE_SITE_ALARM,
|
||||||
ALARM_STATE_TX1750
|
ALARM_STATE_TX1750
|
||||||
};
|
};
|
||||||
typedef enum AlarmState_t AlarmState_t;
|
typedef enum AlarmState_t AlarmState_t;
|
||||||
@@ -76,36 +72,29 @@ enum ReceptionMode_t {
|
|||||||
};
|
};
|
||||||
typedef enum ReceptionMode_t ReceptionMode_t;
|
typedef enum ReceptionMode_t ReceptionMode_t;
|
||||||
|
|
||||||
enum CssScanMode_t
|
enum BacklightOnRxTx_t {
|
||||||
{
|
BACKLIGHT_ON_TR_OFF,
|
||||||
CSS_SCAN_MODE_OFF = 0,
|
BACKLIGHT_ON_TR_TX,
|
||||||
CSS_SCAN_MODE_SCANNING,
|
BACKLIGHT_ON_TR_RX,
|
||||||
CSS_SCAN_MODE_FOUND,
|
BACKLIGHT_ON_TR_TXRX
|
||||||
};
|
};
|
||||||
typedef enum CssScanMode_t CssScanMode_t;
|
|
||||||
|
|
||||||
enum scan_next_chan_t {
|
|
||||||
SCAN_NEXT_CHAN_SCANLIST1 = 0,
|
|
||||||
SCAN_NEXT_CHAN_SCANLIST2,
|
|
||||||
SCAN_NEXT_CHAN_DUAL_WATCH,
|
|
||||||
SCAN_NEXT_CHAN_MR,
|
|
||||||
SCAN_NEXT_NUM
|
|
||||||
};
|
|
||||||
typedef enum scan_next_chan_t scan_next_chan_t;
|
|
||||||
|
|
||||||
extern const uint8_t fm_resume_countdown_500ms;
|
|
||||||
extern const uint8_t fm_radio_countdown_500ms;
|
extern const uint8_t fm_radio_countdown_500ms;
|
||||||
extern const uint16_t fm_play_countdown_scan_10ms;
|
extern const uint16_t fm_play_countdown_scan_10ms;
|
||||||
extern const uint16_t fm_play_countdown_noscan_10ms;
|
extern const uint16_t fm_play_countdown_noscan_10ms;
|
||||||
extern const uint16_t fm_restore_countdown_10ms;
|
extern const uint16_t fm_restore_countdown_10ms;
|
||||||
|
|
||||||
|
extern const uint8_t vfo_state_resume_countdown_500ms;
|
||||||
|
|
||||||
extern const uint8_t menu_timeout_500ms;
|
extern const uint8_t menu_timeout_500ms;
|
||||||
extern const uint16_t menu_timeout_long_500ms;
|
extern const uint16_t menu_timeout_long_500ms;
|
||||||
|
|
||||||
extern const uint8_t DTMF_RX_live_timeout_500ms;
|
extern const uint8_t DTMF_RX_live_timeout_500ms;
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
extern const uint8_t DTMF_RX_timeout_500ms;
|
extern const uint8_t DTMF_RX_timeout_500ms;
|
||||||
extern const uint8_t DTMF_decode_ring_countdown_500ms;
|
extern const uint8_t DTMF_decode_ring_countdown_500ms;
|
||||||
extern const uint8_t DTMF_txstop_countdown_500ms;
|
extern const uint8_t DTMF_txstop_countdown_500ms;
|
||||||
|
#endif
|
||||||
|
|
||||||
extern const uint8_t key_input_timeout_500ms;
|
extern const uint8_t key_input_timeout_500ms;
|
||||||
|
|
||||||
@@ -152,22 +141,21 @@ extern const uint16_t scan_pause_delay_in_7_10ms;
|
|||||||
extern const uint8_t gMicGain_dB2[5];
|
extern const uint8_t gMicGain_dB2[5];
|
||||||
|
|
||||||
extern bool gSetting_350TX;
|
extern bool gSetting_350TX;
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
extern bool gSetting_KILLED;
|
extern bool gSetting_KILLED;
|
||||||
|
#endif
|
||||||
extern bool gSetting_200TX;
|
extern bool gSetting_200TX;
|
||||||
extern bool gSetting_500TX;
|
extern bool gSetting_500TX;
|
||||||
extern bool gSetting_350EN;
|
extern bool gSetting_350EN;
|
||||||
extern bool gSetting_TX_EN;
|
|
||||||
extern uint8_t gSetting_F_LOCK;
|
extern uint8_t gSetting_F_LOCK;
|
||||||
extern bool gSetting_ScrambleEnable;
|
extern bool gSetting_ScrambleEnable;
|
||||||
|
|
||||||
extern uint8_t gSetting_backlight_on_tx_rx;
|
extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX
|
#ifdef ENABLE_AM_FIX
|
||||||
extern bool gSetting_AM_fix;
|
extern bool gSetting_AM_fix;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_AM_FIX_TEST1
|
|
||||||
extern uint8_t gSetting_AM_fix_test1;
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_AUDIO_BAR
|
#ifdef ENABLE_AUDIO_BAR
|
||||||
extern bool gSetting_mic_bar;
|
extern bool gSetting_mic_bar;
|
||||||
#endif
|
#endif
|
||||||
@@ -182,17 +170,23 @@ extern bool bHasCustomAesKey;
|
|||||||
extern uint32_t gChallenge[4];
|
extern uint32_t gChallenge[4];
|
||||||
extern uint8_t gTryCount;
|
extern uint8_t gTryCount;
|
||||||
|
|
||||||
extern uint8_t gEEPROM_1EC0_0[8];
|
extern uint16_t gEEPROM_RSSI_CALIB[7][4];
|
||||||
extern uint8_t gEEPROM_1EC0_1[8];
|
|
||||||
extern uint8_t gEEPROM_1EC0_2[8];
|
|
||||||
extern uint8_t gEEPROM_1EC0_3[8];
|
|
||||||
|
|
||||||
extern uint16_t gEEPROM_RSSI_CALIB[2][4];
|
|
||||||
|
|
||||||
extern uint16_t gEEPROM_1F8A;
|
extern uint16_t gEEPROM_1F8A;
|
||||||
extern uint16_t gEEPROM_1F8C;
|
extern uint16_t gEEPROM_1F8C;
|
||||||
|
|
||||||
extern uint8_t gMR_ChannelAttributes[207];
|
typedef union {
|
||||||
|
struct {
|
||||||
|
uint8_t
|
||||||
|
band : 4,
|
||||||
|
compander : 2,
|
||||||
|
scanlist2 : 1,
|
||||||
|
scanlist1 : 1;
|
||||||
|
};
|
||||||
|
uint8_t __val;
|
||||||
|
} ChannelAttributes_t;
|
||||||
|
|
||||||
|
extern ChannelAttributes_t gMR_ChannelAttributes[207];
|
||||||
|
|
||||||
extern volatile uint16_t gBatterySaveCountdown_10ms;
|
extern volatile uint16_t gBatterySaveCountdown_10ms;
|
||||||
|
|
||||||
@@ -202,7 +196,6 @@ extern volatile bool gSchedulePowerSave;
|
|||||||
extern volatile bool gScheduleDualWatch;
|
extern volatile bool gScheduleDualWatch;
|
||||||
|
|
||||||
extern volatile uint16_t gDualWatchCountdown_10ms;
|
extern volatile uint16_t gDualWatchCountdown_10ms;
|
||||||
extern volatile bool gDualWatchCountdownExpired;
|
|
||||||
extern bool gDualWatchActive;
|
extern bool gDualWatchActive;
|
||||||
|
|
||||||
extern volatile uint8_t gSerialConfigCountDown_500ms;
|
extern volatile uint8_t gSerialConfigCountDown_500ms;
|
||||||
@@ -233,10 +226,24 @@ extern bool gEndOfRxDetectedMaybe;
|
|||||||
extern int16_t gVFO_RSSI[2];
|
extern int16_t gVFO_RSSI[2];
|
||||||
extern uint8_t gVFO_RSSI_bar_level[2];
|
extern uint8_t gVFO_RSSI_bar_level[2];
|
||||||
|
|
||||||
|
// battery critical, limit functionality to minimum
|
||||||
extern uint8_t gReducedService;
|
extern uint8_t gReducedService;
|
||||||
extern uint8_t gBatteryVoltageIndex;
|
extern uint8_t gBatteryVoltageIndex;
|
||||||
extern CssScanMode_t gCssScanMode;
|
|
||||||
extern bool gUpdateRSSI;
|
// we are searching CTCSS/DCS inside RX ctcss/dcs menu
|
||||||
|
extern bool gCssBackgroundScan;
|
||||||
|
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SCAN_REV = -1,
|
||||||
|
SCAN_OFF = 0,
|
||||||
|
SCAN_FWD = +1
|
||||||
|
};
|
||||||
|
|
||||||
|
extern volatile bool gScheduleScanListen;
|
||||||
|
extern volatile uint16_t gScanPauseDelayIn_10ms;
|
||||||
|
|
||||||
extern AlarmState_t gAlarmState;
|
extern AlarmState_t gAlarmState;
|
||||||
extern uint16_t gMenuCountdown;
|
extern uint16_t gMenuCountdown;
|
||||||
extern bool gPttWasReleased;
|
extern bool gPttWasReleased;
|
||||||
@@ -272,18 +279,17 @@ extern bool g_CxCSS_TAIL_Found;
|
|||||||
extern uint16_t gVoxResumeCountdown;
|
extern uint16_t gVoxResumeCountdown;
|
||||||
extern uint16_t gVoxPauseCountdown;
|
extern uint16_t gVoxPauseCountdown;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// true means we are receiving signal
|
||||||
extern bool g_SquelchLost;
|
extern bool g_SquelchLost;
|
||||||
extern uint8_t gFlashLightState;
|
|
||||||
extern volatile uint16_t gFlashLightBlinkCounter;
|
extern volatile uint16_t gFlashLightBlinkCounter;
|
||||||
|
|
||||||
extern bool gFlagEndTransmission;
|
extern bool gFlagEndTransmission;
|
||||||
extern uint16_t gLowBatteryCountdown;
|
|
||||||
extern uint8_t gNextMrChannel;
|
extern uint8_t gNextMrChannel;
|
||||||
extern ReceptionMode_t gRxReceptionMode;
|
extern ReceptionMode_t gRxReceptionMode;
|
||||||
|
|
||||||
extern uint8_t gRestoreMrChannel;
|
//TRUE when dual watch is momentarly suspended and RX_VFO is locked to either last TX or RX
|
||||||
extern scan_next_chan_t gCurrentScanList;
|
|
||||||
extern uint32_t gRestoreFrequency;
|
|
||||||
|
|
||||||
extern bool gRxVfoIsActive;
|
extern bool gRxVfoIsActive;
|
||||||
extern uint8_t gAlarmToneCounter;
|
extern uint8_t gAlarmToneCounter;
|
||||||
extern uint16_t gAlarmRunningCounter;
|
extern uint16_t gAlarmRunningCounter;
|
||||||
@@ -293,9 +299,6 @@ extern uint8_t gPttDebounceCounter;
|
|||||||
extern uint8_t gMenuListCount;
|
extern uint8_t gMenuListCount;
|
||||||
extern uint8_t gBackup_CROSS_BAND_RX_TX;
|
extern uint8_t gBackup_CROSS_BAND_RX_TX;
|
||||||
extern uint8_t gScanDelay_10ms;
|
extern uint8_t gScanDelay_10ms;
|
||||||
#ifdef ENABLE_AIRCOPY
|
|
||||||
extern uint8_t gAircopySendCountdown;
|
|
||||||
#endif
|
|
||||||
extern uint8_t gFSKWriteIndex;
|
extern uint8_t gFSKWriteIndex;
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
extern bool gIsNoaaMode;
|
extern bool gIsNoaaMode;
|
||||||
@@ -319,19 +322,18 @@ extern volatile bool gNextTimeslice40ms;
|
|||||||
extern volatile bool gScheduleNOAA;
|
extern volatile bool gScheduleNOAA;
|
||||||
#endif
|
#endif
|
||||||
extern volatile bool gFlagTailNoteEliminationComplete;
|
extern volatile bool gFlagTailNoteEliminationComplete;
|
||||||
|
extern volatile uint8_t gVFOStateResumeCountdown_500ms;
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
extern volatile bool gScheduleFM;
|
extern volatile bool gScheduleFM;
|
||||||
#endif
|
#endif
|
||||||
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_ToDigits(uint32_t Value, char *pDigits);
|
|
||||||
int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit);
|
int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit);
|
||||||
|
unsigned long StrToUL(const char * str);
|
||||||
|
|
||||||
|
void FUNCTION_NOP();
|
||||||
|
|
||||||
|
inline bool SerialConfigInProgress() { return gSerialConfigCountDown_500ms != 0; }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
55
radio.h
55
radio.h
@@ -23,13 +23,6 @@
|
|||||||
#include "dcs.h"
|
#include "dcs.h"
|
||||||
#include "frequencies.h"
|
#include "frequencies.h"
|
||||||
|
|
||||||
enum {
|
|
||||||
MR_CH_BAND_MASK = 0x0F << 0,
|
|
||||||
MR_CH_COMPAND = 3u << 4, // new
|
|
||||||
MR_CH_SCANLIST2 = 1u << 6,
|
|
||||||
MR_CH_SCANLIST1 = 1u << 7
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RADIO_CHANNEL_UP = 0x01u,
|
RADIO_CHANNEL_UP = 0x01u,
|
||||||
RADIO_CHANNEL_DOWN = 0xFFu,
|
RADIO_CHANNEL_DOWN = 0xFFu,
|
||||||
@@ -57,10 +50,26 @@ enum VfoState_t
|
|||||||
VFO_STATE_TX_DISABLE,
|
VFO_STATE_TX_DISABLE,
|
||||||
VFO_STATE_TIMEOUT,
|
VFO_STATE_TIMEOUT,
|
||||||
VFO_STATE_ALARM,
|
VFO_STATE_ALARM,
|
||||||
VFO_STATE_VOLTAGE_HIGH
|
VFO_STATE_VOLTAGE_HIGH,
|
||||||
|
_VFO_STATE_LAST_ELEMENT
|
||||||
};
|
};
|
||||||
typedef enum VfoState_t VfoState_t;
|
typedef enum VfoState_t VfoState_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MODULATION_FM,
|
||||||
|
MODULATION_AM,
|
||||||
|
MODULATION_USB,
|
||||||
|
|
||||||
|
#ifdef ENABLE_BYP_RAW_DEMODULATORS
|
||||||
|
MODULATION_BYP,
|
||||||
|
MODULATION_RAW,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MODULATION_UKNOWN
|
||||||
|
} ModulationMode_t;
|
||||||
|
|
||||||
|
extern const char gModulationStr[MODULATION_UKNOWN][4];
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t Frequency;
|
uint32_t Frequency;
|
||||||
@@ -73,7 +82,14 @@ typedef struct VFO_Info_t
|
|||||||
{
|
{
|
||||||
FREQ_Config_t freq_config_RX;
|
FREQ_Config_t freq_config_RX;
|
||||||
FREQ_Config_t freq_config_TX;
|
FREQ_Config_t freq_config_TX;
|
||||||
|
|
||||||
|
// this is for a purpose of the FrequencyReverse function
|
||||||
|
// it points to freq_config_RX normally and to freq_config_TX if reverse function is active
|
||||||
|
//
|
||||||
FREQ_Config_t *pRX;
|
FREQ_Config_t *pRX;
|
||||||
|
|
||||||
|
// this is for a purpose of the FrequencyReverse function
|
||||||
|
// it points to freq_config_TX normally and to freq_config_RX if reverse function is active
|
||||||
FREQ_Config_t *pTX;
|
FREQ_Config_t *pTX;
|
||||||
|
|
||||||
uint32_t TX_OFFSET_FREQUENCY;
|
uint32_t TX_OFFSET_FREQUENCY;
|
||||||
@@ -102,28 +118,33 @@ typedef struct VFO_Info_t
|
|||||||
uint8_t SCANLIST2_PARTICIPATION;
|
uint8_t SCANLIST2_PARTICIPATION;
|
||||||
|
|
||||||
uint8_t Band;
|
uint8_t Band;
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
uint8_t DTMF_DECODING_ENABLE;
|
uint8_t DTMF_DECODING_ENABLE;
|
||||||
|
#endif
|
||||||
PTT_ID_t DTMF_PTT_ID_TX_MODE;
|
PTT_ID_t DTMF_PTT_ID_TX_MODE;
|
||||||
|
|
||||||
uint8_t BUSY_CHANNEL_LOCK;
|
uint8_t BUSY_CHANNEL_LOCK;
|
||||||
|
|
||||||
uint8_t AM_mode;
|
ModulationMode_t Modulation;
|
||||||
|
|
||||||
uint8_t Compander;
|
uint8_t Compander;
|
||||||
|
|
||||||
char Name[16];
|
char Name[16];
|
||||||
} VFO_Info_t;
|
} VFO_Info_t;
|
||||||
|
|
||||||
|
// Settings of the main VFO that is selected by the user
|
||||||
|
// The pointer follows gEeprom.TX_VFO index
|
||||||
extern VFO_Info_t *gTxVfo;
|
extern VFO_Info_t *gTxVfo;
|
||||||
|
|
||||||
|
// Settings of the actual VFO that is now used for RX,
|
||||||
|
// It is being alternated by dual watch, and flipped by crossband
|
||||||
|
// The pointer follows gEeprom.RX_VFO
|
||||||
extern VFO_Info_t *gRxVfo;
|
extern VFO_Info_t *gRxVfo;
|
||||||
|
|
||||||
|
// Equal to gTxVfo unless dual watch changes it on incomming transmition (this can only happen when XB off and DW on)
|
||||||
extern VFO_Info_t *gCurrentVfo;
|
extern VFO_Info_t *gCurrentVfo;
|
||||||
|
|
||||||
extern DCS_CodeType_t gSelectedCodeType;
|
|
||||||
extern DCS_CodeType_t gCurrentCodeType;
|
extern DCS_CodeType_t gCurrentCodeType;
|
||||||
extern uint8_t gSelectedCode;
|
|
||||||
|
|
||||||
extern STEP_Setting_t gStepSetting;
|
|
||||||
|
|
||||||
extern VfoState_t VfoState[2];
|
extern VfoState_t VfoState[2];
|
||||||
|
|
||||||
@@ -134,16 +155,18 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int confi
|
|||||||
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo);
|
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo);
|
||||||
void RADIO_ApplyOffset(VFO_Info_t *pInfo);
|
void RADIO_ApplyOffset(VFO_Info_t *pInfo);
|
||||||
void RADIO_SelectVfos(void);
|
void RADIO_SelectVfos(void);
|
||||||
void RADIO_SetupRegisters(bool bSwitchToFunction0);
|
void RADIO_SetupRegisters(bool switchToForeground);
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
void RADIO_ConfigureNOAA(void);
|
void RADIO_ConfigureNOAA(void);
|
||||||
#endif
|
#endif
|
||||||
void RADIO_SetTxParameters(void);
|
void RADIO_SetTxParameters(void);
|
||||||
|
void RADIO_SetupAGC(bool listeningAM, bool disable);
|
||||||
|
void RADIO_SetModulation(ModulationMode_t modulation);
|
||||||
void RADIO_SetVfoState(VfoState_t State);
|
void RADIO_SetVfoState(VfoState_t State);
|
||||||
void RADIO_PrepareTX(void);
|
void RADIO_PrepareTX(void);
|
||||||
void RADIO_EnableCxCSS(void);
|
void RADIO_EnableCxCSS(void);
|
||||||
void RADIO_PrepareCssTX(void);
|
void RADIO_PrepareCssTX(void);
|
||||||
void RADIO_SendEndOfTransmission(void);
|
void RADIO_SendEndOfTransmission(void);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "app/chFrScanner.h"
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
#include "app/fm.h"
|
#include "app/fm.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -77,18 +78,18 @@ void SystickHandler(void)
|
|||||||
if (gCurrentFunction == FUNCTION_POWER_SAVE)
|
if (gCurrentFunction == FUNCTION_POWER_SAVE)
|
||||||
DECREMENT_AND_TRIGGER(gPowerSave_10ms, gPowerSaveCountdownExpired);
|
DECREMENT_AND_TRIGGER(gPowerSave_10ms, gPowerSaveCountdownExpired);
|
||||||
|
|
||||||
if (gScanStateDir == SCAN_OFF && gCssScanMode == CSS_SCAN_MODE_OFF && gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
|
if (gScanStateDir == SCAN_OFF && !gCssBackgroundScan && gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
|
||||||
if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_RECEIVE)
|
if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_RECEIVE)
|
||||||
DECREMENT_AND_TRIGGER(gDualWatchCountdown_10ms, gScheduleDualWatch);
|
DECREMENT_AND_TRIGGER(gDualWatchCountdown_10ms, gScheduleDualWatch);
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
if (gScanStateDir == SCAN_OFF && gCssScanMode == CSS_SCAN_MODE_OFF && gEeprom.DUAL_WATCH == DUAL_WATCH_OFF)
|
if (gScanStateDir == SCAN_OFF && !gCssBackgroundScan && gEeprom.DUAL_WATCH == DUAL_WATCH_OFF)
|
||||||
if (gIsNoaaMode && gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT)
|
if (gIsNoaaMode && gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT)
|
||||||
if (gCurrentFunction != FUNCTION_RECEIVE)
|
if (gCurrentFunction != FUNCTION_RECEIVE)
|
||||||
DECREMENT_AND_TRIGGER(gNOAA_Countdown_10ms, gScheduleNOAA);
|
DECREMENT_AND_TRIGGER(gNOAA_Countdown_10ms, gScheduleNOAA);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gScanStateDir != SCAN_OFF || gCssScanMode == CSS_SCAN_MODE_SCANNING)
|
if (gScanStateDir != SCAN_OFF)
|
||||||
if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT)
|
if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT)
|
||||||
DECREMENT_AND_TRIGGER(gScanPauseDelayIn_10ms, gScheduleScanListen);
|
DECREMENT_AND_TRIGGER(gScanPauseDelayIn_10ms, gScheduleScanListen);
|
||||||
|
|
||||||
|
|||||||
639
settings.c
639
settings.c
@@ -16,16 +16,424 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "app/dtmf.h"
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
#include "app/fm.h"
|
#include "app/fm.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "driver/bk4819.h"
|
||||||
#include "driver/eeprom.h"
|
#include "driver/eeprom.h"
|
||||||
#include "driver/uart.h"
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "ui/menu.h"
|
||||||
|
|
||||||
|
static const uint32_t gDefaultFrequencyTable[] =
|
||||||
|
{
|
||||||
|
14500000, //
|
||||||
|
14550000, //
|
||||||
|
43300000, //
|
||||||
|
43320000, //
|
||||||
|
43350000 //
|
||||||
|
};
|
||||||
|
|
||||||
EEPROM_Config_t gEeprom;
|
EEPROM_Config_t gEeprom;
|
||||||
|
|
||||||
|
void SETTINGS_InitEEPROM(void)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
uint8_t Data[16];
|
||||||
|
|
||||||
|
memset(Data, 0, sizeof(Data));
|
||||||
|
memset(&gEeprom, 0, sizeof(gEeprom));
|
||||||
|
|
||||||
|
// 0E70..0E77
|
||||||
|
EEPROM_ReadBuffer(0x0E70, Data, 8);
|
||||||
|
gEeprom.CHAN_1_CALL = IS_MR_CHANNEL(Data[0]) ? Data[0] : MR_CHANNEL_FIRST;
|
||||||
|
gEeprom.SQUELCH_LEVEL = (Data[1] < 10) ? Data[1] : 1;
|
||||||
|
gEeprom.TX_TIMEOUT_TIMER = (Data[2] < 11) ? Data[2] : 1;
|
||||||
|
#ifdef ENABLE_NOAA
|
||||||
|
gEeprom.NOAA_AUTO_SCAN = (Data[3] < 2) ? Data[3] : false;
|
||||||
|
#endif
|
||||||
|
gEeprom.KEY_LOCK = (Data[4] < 2) ? Data[4] : false;
|
||||||
|
#ifdef ENABLE_VOX
|
||||||
|
gEeprom.VOX_SWITCH = (Data[5] < 2) ? Data[5] : false;
|
||||||
|
gEeprom.VOX_LEVEL = (Data[6] < 10) ? Data[6] : 1;
|
||||||
|
#endif
|
||||||
|
gEeprom.MIC_SENSITIVITY = (Data[7] < 5) ? Data[7] : 4;
|
||||||
|
|
||||||
|
// 0E78..0E7F
|
||||||
|
EEPROM_ReadBuffer(0x0E78, Data, 8);
|
||||||
|
gEeprom.BACKLIGHT_MAX = (Data[0] & 0xF) <= 10 ? (Data[0] & 0xF) : 10;
|
||||||
|
gEeprom.BACKLIGHT_MIN = (Data[0] >> 4) < gEeprom.BACKLIGHT_MAX ? (Data[0] >> 4) : 0;
|
||||||
|
#ifdef ENABLE_BLMIN_TMP_OFF
|
||||||
|
gEeprom.BACKLIGHT_MIN_STAT = BLMIN_STAT_ON;
|
||||||
|
#endif
|
||||||
|
gEeprom.CHANNEL_DISPLAY_MODE = (Data[1] < 4) ? Data[1] : MDF_FREQUENCY; // 4 instead of 3 - extra display mode
|
||||||
|
gEeprom.CROSS_BAND_RX_TX = (Data[2] < 3) ? Data[2] : CROSS_BAND_OFF;
|
||||||
|
gEeprom.BATTERY_SAVE = (Data[3] < 5) ? Data[3] : 4;
|
||||||
|
gEeprom.DUAL_WATCH = (Data[4] < 3) ? Data[4] : DUAL_WATCH_CHAN_A;
|
||||||
|
gEeprom.BACKLIGHT_TIME = (Data[5] < ARRAY_SIZE(gSubMenu_BACKLIGHT)) ? Data[5] : 3;
|
||||||
|
gEeprom.TAIL_TONE_ELIMINATION = (Data[6] < 2) ? Data[6] : false;
|
||||||
|
gEeprom.VFO_OPEN = (Data[7] < 2) ? Data[7] : true;
|
||||||
|
|
||||||
|
// 0E80..0E87
|
||||||
|
EEPROM_ReadBuffer(0x0E80, Data, 8);
|
||||||
|
gEeprom.ScreenChannel[0] = IS_VALID_CHANNEL(Data[0]) ? Data[0] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
||||||
|
gEeprom.ScreenChannel[1] = IS_VALID_CHANNEL(Data[3]) ? Data[3] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
||||||
|
gEeprom.MrChannel[0] = IS_MR_CHANNEL(Data[1]) ? Data[1] : MR_CHANNEL_FIRST;
|
||||||
|
gEeprom.MrChannel[1] = IS_MR_CHANNEL(Data[4]) ? Data[4] : MR_CHANNEL_FIRST;
|
||||||
|
gEeprom.FreqChannel[0] = IS_FREQ_CHANNEL(Data[2]) ? Data[2] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
||||||
|
gEeprom.FreqChannel[1] = IS_FREQ_CHANNEL(Data[5]) ? Data[5] : (FREQ_CHANNEL_FIRST + BAND6_400MHz);
|
||||||
|
#ifdef ENABLE_NOAA
|
||||||
|
gEeprom.NoaaChannel[0] = IS_NOAA_CHANNEL(Data[6]) ? Data[6] : NOAA_CHANNEL_FIRST;
|
||||||
|
gEeprom.NoaaChannel[1] = IS_NOAA_CHANNEL(Data[7]) ? Data[7] : NOAA_CHANNEL_FIRST;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_FMRADIO
|
||||||
|
{ // 0E88..0E8F
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint16_t SelectedFrequency;
|
||||||
|
uint8_t SelectedChannel;
|
||||||
|
uint8_t IsMrMode;
|
||||||
|
uint8_t Padding[8];
|
||||||
|
} __attribute__((packed)) FM;
|
||||||
|
|
||||||
|
EEPROM_ReadBuffer(0x0E88, &FM, 8);
|
||||||
|
gEeprom.FM_LowerLimit = 760;
|
||||||
|
gEeprom.FM_UpperLimit = 1080;
|
||||||
|
if (FM.SelectedFrequency < gEeprom.FM_LowerLimit || FM.SelectedFrequency > gEeprom.FM_UpperLimit)
|
||||||
|
gEeprom.FM_SelectedFrequency = 960;
|
||||||
|
else
|
||||||
|
gEeprom.FM_SelectedFrequency = FM.SelectedFrequency;
|
||||||
|
|
||||||
|
gEeprom.FM_SelectedChannel = FM.SelectedChannel;
|
||||||
|
gEeprom.FM_IsMrMode = (FM.IsMrMode < 2) ? FM.IsMrMode : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0E40..0E67
|
||||||
|
EEPROM_ReadBuffer(0x0E40, gFM_Channels, sizeof(gFM_Channels));
|
||||||
|
FM_ConfigureChannelState();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 0E90..0E97
|
||||||
|
EEPROM_ReadBuffer(0x0E90, Data, 8);
|
||||||
|
gEeprom.BEEP_CONTROL = Data[0] & 1;
|
||||||
|
gEeprom.KEY_M_LONG_PRESS_ACTION = ((Data[0] >> 1) < ACTION_OPT_LEN) ? (Data[0] >> 1) : ACTION_OPT_NONE;
|
||||||
|
gEeprom.KEY_1_SHORT_PRESS_ACTION = (Data[1] < ACTION_OPT_LEN) ? Data[1] : ACTION_OPT_MONITOR;
|
||||||
|
gEeprom.KEY_1_LONG_PRESS_ACTION = (Data[2] < ACTION_OPT_LEN) ? Data[2] : ACTION_OPT_NONE;
|
||||||
|
gEeprom.KEY_2_SHORT_PRESS_ACTION = (Data[3] < ACTION_OPT_LEN) ? Data[3] : ACTION_OPT_SCAN;
|
||||||
|
gEeprom.KEY_2_LONG_PRESS_ACTION = (Data[4] < ACTION_OPT_LEN) ? Data[4] : ACTION_OPT_NONE;
|
||||||
|
gEeprom.SCAN_RESUME_MODE = (Data[5] < 3) ? Data[5] : SCAN_RESUME_CO;
|
||||||
|
gEeprom.AUTO_KEYPAD_LOCK = (Data[6] < 2) ? Data[6] : false;
|
||||||
|
gEeprom.POWER_ON_DISPLAY_MODE = (Data[7] < 4) ? Data[7] : POWER_ON_DISPLAY_MODE_VOLTAGE;
|
||||||
|
|
||||||
|
// 0E98..0E9F
|
||||||
|
EEPROM_ReadBuffer(0x0E98, Data, 8);
|
||||||
|
memmove(&gEeprom.POWER_ON_PASSWORD, Data, 4);
|
||||||
|
|
||||||
|
// 0EA0..0EA7
|
||||||
|
EEPROM_ReadBuffer(0x0EA0, Data, 8);
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
gEeprom.VOICE_PROMPT = (Data[0] < 3) ? Data[0] : VOICE_PROMPT_ENGLISH;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_RSSI_BAR
|
||||||
|
if((Data[1] < 200 && Data[1] > 90) && (Data[2] < Data[1]-9 && Data[1] < 160 && Data[2] > 50)) {
|
||||||
|
gEeprom.S0_LEVEL = Data[1];
|
||||||
|
gEeprom.S9_LEVEL = Data[2];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gEeprom.S0_LEVEL = 130;
|
||||||
|
gEeprom.S9_LEVEL = 76;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 0EA8..0EAF
|
||||||
|
EEPROM_ReadBuffer(0x0EA8, Data, 8);
|
||||||
|
#ifdef ENABLE_ALARM
|
||||||
|
gEeprom.ALARM_MODE = (Data[0] < 2) ? Data[0] : true;
|
||||||
|
#endif
|
||||||
|
gEeprom.ROGER = (Data[1] < 3) ? Data[1] : ROGER_MODE_OFF;
|
||||||
|
gEeprom.REPEATER_TAIL_TONE_ELIMINATION = (Data[2] < 11) ? Data[2] : 0;
|
||||||
|
gEeprom.TX_VFO = (Data[3] < 2) ? Data[3] : 0;
|
||||||
|
gEeprom.BATTERY_TYPE = (Data[4] < BATTERY_TYPE_UNKNOWN) ? Data[4] : BATTERY_TYPE_1600_MAH;
|
||||||
|
|
||||||
|
// 0ED0..0ED7
|
||||||
|
EEPROM_ReadBuffer(0x0ED0, Data, 8);
|
||||||
|
gEeprom.DTMF_SIDE_TONE = (Data[0] < 2) ? Data[0] : true;
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
gEeprom.DTMF_SEPARATE_CODE = DTMF_ValidateCodes((char *)(Data + 1), 1) ? Data[1] : '*';
|
||||||
|
gEeprom.DTMF_GROUP_CALL_CODE = DTMF_ValidateCodes((char *)(Data + 2), 1) ? Data[2] : '#';
|
||||||
|
gEeprom.DTMF_DECODE_RESPONSE = (Data[3] < 4) ? Data[3] : 0;
|
||||||
|
gEeprom.DTMF_auto_reset_time = (Data[4] < 61) ? Data[4] : (Data[4] >= 5) ? Data[4] : 10;
|
||||||
|
#endif
|
||||||
|
gEeprom.DTMF_PRELOAD_TIME = (Data[5] < 101) ? Data[5] * 10 : 300;
|
||||||
|
gEeprom.DTMF_FIRST_CODE_PERSIST_TIME = (Data[6] < 101) ? Data[6] * 10 : 100;
|
||||||
|
gEeprom.DTMF_HASH_CODE_PERSIST_TIME = (Data[7] < 101) ? Data[7] * 10 : 100;
|
||||||
|
|
||||||
|
// 0ED8..0EDF
|
||||||
|
EEPROM_ReadBuffer(0x0ED8, Data, 8);
|
||||||
|
gEeprom.DTMF_CODE_PERSIST_TIME = (Data[0] < 101) ? Data[0] * 10 : 100;
|
||||||
|
gEeprom.DTMF_CODE_INTERVAL_TIME = (Data[1] < 101) ? Data[1] * 10 : 100;
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
gEeprom.PERMIT_REMOTE_KILL = (Data[2] < 2) ? Data[2] : true;
|
||||||
|
|
||||||
|
// 0EE0..0EE7
|
||||||
|
|
||||||
|
EEPROM_ReadBuffer(0x0EE0, Data, 8);
|
||||||
|
if (DTMF_ValidateCodes((char *)Data, 8))
|
||||||
|
memmove(gEeprom.ANI_DTMF_ID, Data, 8);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(gEeprom.ANI_DTMF_ID, 0, sizeof(gEeprom.ANI_DTMF_ID));
|
||||||
|
strcpy(gEeprom.ANI_DTMF_ID, "123");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 0EE8..0EEF
|
||||||
|
EEPROM_ReadBuffer(0x0EE8, Data, 8);
|
||||||
|
if (DTMF_ValidateCodes((char *)Data, 8))
|
||||||
|
memmove(gEeprom.KILL_CODE, Data, 8);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(gEeprom.KILL_CODE, 0, sizeof(gEeprom.KILL_CODE));
|
||||||
|
strcpy(gEeprom.KILL_CODE, "ABCD9");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0EF0..0EF7
|
||||||
|
EEPROM_ReadBuffer(0x0EF0, Data, 8);
|
||||||
|
if (DTMF_ValidateCodes((char *)Data, 8))
|
||||||
|
memmove(gEeprom.REVIVE_CODE, Data, 8);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(gEeprom.REVIVE_CODE, 0, sizeof(gEeprom.REVIVE_CODE));
|
||||||
|
strcpy(gEeprom.REVIVE_CODE, "9DCBA");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 0EF8..0F07
|
||||||
|
EEPROM_ReadBuffer(0x0EF8, Data, 16);
|
||||||
|
if (DTMF_ValidateCodes((char *)Data, 16))
|
||||||
|
memmove(gEeprom.DTMF_UP_CODE, Data, 16);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(gEeprom.DTMF_UP_CODE, 0, sizeof(gEeprom.DTMF_UP_CODE));
|
||||||
|
strcpy(gEeprom.DTMF_UP_CODE, "12345");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0F08..0F17
|
||||||
|
EEPROM_ReadBuffer(0x0F08, Data, 16);
|
||||||
|
if (DTMF_ValidateCodes((char *)Data, 16))
|
||||||
|
memmove(gEeprom.DTMF_DOWN_CODE, Data, 16);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(gEeprom.DTMF_DOWN_CODE, 0, sizeof(gEeprom.DTMF_DOWN_CODE));
|
||||||
|
strcpy(gEeprom.DTMF_DOWN_CODE, "54321");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0F18..0F1F
|
||||||
|
EEPROM_ReadBuffer(0x0F18, Data, 8);
|
||||||
|
// gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 2) ? Data[0] : false;
|
||||||
|
gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 3) ? Data[0] : false; // we now have 'all' channel scan option
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
const unsigned int j = 1 + (i * 3);
|
||||||
|
gEeprom.SCAN_LIST_ENABLED[i] = (Data[j + 0] < 2) ? Data[j] : false;
|
||||||
|
gEeprom.SCANLIST_PRIORITY_CH1[i] = Data[j + 1];
|
||||||
|
gEeprom.SCANLIST_PRIORITY_CH2[i] = Data[j + 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0F40..0F47
|
||||||
|
EEPROM_ReadBuffer(0x0F40, Data, 8);
|
||||||
|
gSetting_F_LOCK = (Data[0] < F_LOCK_LEN) ? Data[0] : F_LOCK_DEF;
|
||||||
|
gSetting_350TX = (Data[1] < 2) ? Data[1] : false; // was true
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
gSetting_KILLED = (Data[2] < 2) ? Data[2] : false;
|
||||||
|
#endif
|
||||||
|
gSetting_200TX = (Data[3] < 2) ? Data[3] : false;
|
||||||
|
gSetting_500TX = (Data[4] < 2) ? Data[4] : false;
|
||||||
|
gSetting_350EN = (Data[5] < 2) ? Data[5] : true;
|
||||||
|
gSetting_ScrambleEnable = (Data[6] < 2) ? Data[6] : true;
|
||||||
|
//gSetting_TX_EN = (Data[7] & (1u << 0)) ? true : false;
|
||||||
|
gSetting_live_DTMF_decoder = (Data[7] & (1u << 1)) ? true : false;
|
||||||
|
gSetting_battery_text = (((Data[7] >> 2) & 3u) <= 2) ? (Data[7] >> 2) & 3 : 2;
|
||||||
|
#ifdef ENABLE_AUDIO_BAR
|
||||||
|
gSetting_mic_bar = (Data[7] & (1u << 4)) ? true : false;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AM_FIX
|
||||||
|
gSetting_AM_fix = (Data[7] & (1u << 5)) ? true : false;
|
||||||
|
#endif
|
||||||
|
gSetting_backlight_on_tx_rx = (Data[7] >> 6) & 3u;
|
||||||
|
|
||||||
|
if (!gEeprom.VFO_OPEN)
|
||||||
|
{
|
||||||
|
gEeprom.ScreenChannel[0] = gEeprom.MrChannel[0];
|
||||||
|
gEeprom.ScreenChannel[1] = gEeprom.MrChannel[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0D60..0E27
|
||||||
|
EEPROM_ReadBuffer(0x0D60, gMR_ChannelAttributes, sizeof(gMR_ChannelAttributes));
|
||||||
|
for(uint16_t i = 0; i < sizeof(gMR_ChannelAttributes); i++) {
|
||||||
|
ChannelAttributes_t *att = &gMR_ChannelAttributes[i];
|
||||||
|
if(att->__val == 0xff){
|
||||||
|
att->__val = 0;
|
||||||
|
att->band = 0xf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0F30..0F3F
|
||||||
|
EEPROM_ReadBuffer(0x0F30, gCustomAesKey, sizeof(gCustomAesKey));
|
||||||
|
bHasCustomAesKey = false;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(gCustomAesKey); i++)
|
||||||
|
{
|
||||||
|
if (gCustomAesKey[i] != 0xFFFFFFFFu)
|
||||||
|
{
|
||||||
|
bHasCustomAesKey = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SETTINGS_LoadCalibration(void)
|
||||||
|
{
|
||||||
|
// uint8_t Mic;
|
||||||
|
|
||||||
|
EEPROM_ReadBuffer(0x1EC0, gEEPROM_RSSI_CALIB[3], 8);
|
||||||
|
memcpy(gEEPROM_RSSI_CALIB[4], gEEPROM_RSSI_CALIB[3], 8);
|
||||||
|
memcpy(gEEPROM_RSSI_CALIB[5], gEEPROM_RSSI_CALIB[3], 8);
|
||||||
|
memcpy(gEEPROM_RSSI_CALIB[6], gEEPROM_RSSI_CALIB[3], 8);
|
||||||
|
|
||||||
|
EEPROM_ReadBuffer(0x1EC8, gEEPROM_RSSI_CALIB[0], 8);
|
||||||
|
memcpy(gEEPROM_RSSI_CALIB[1], gEEPROM_RSSI_CALIB[0], 8);
|
||||||
|
memcpy(gEEPROM_RSSI_CALIB[2], gEEPROM_RSSI_CALIB[0], 8);
|
||||||
|
|
||||||
|
EEPROM_ReadBuffer(0x1F40, gBatteryCalibration, 12);
|
||||||
|
if (gBatteryCalibration[0] >= 5000)
|
||||||
|
{
|
||||||
|
gBatteryCalibration[0] = 1900;
|
||||||
|
gBatteryCalibration[1] = 2000;
|
||||||
|
}
|
||||||
|
gBatteryCalibration[5] = 2300;
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOX
|
||||||
|
EEPROM_ReadBuffer(0x1F50 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX1_THRESHOLD, 2);
|
||||||
|
EEPROM_ReadBuffer(0x1F68 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX0_THRESHOLD, 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//EEPROM_ReadBuffer(0x1F80 + gEeprom.MIC_SENSITIVITY, &Mic, 1);
|
||||||
|
//gEeprom.MIC_SENSITIVITY_TUNING = (Mic < 32) ? Mic : 15;
|
||||||
|
gEeprom.MIC_SENSITIVITY_TUNING = gMicGain_dB2[gEeprom.MIC_SENSITIVITY];
|
||||||
|
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int16_t BK4819_XtalFreqLow;
|
||||||
|
uint16_t EEPROM_1F8A;
|
||||||
|
uint16_t EEPROM_1F8C;
|
||||||
|
uint8_t VOLUME_GAIN;
|
||||||
|
uint8_t DAC_GAIN;
|
||||||
|
} __attribute__((packed)) Misc;
|
||||||
|
|
||||||
|
// radio 1 .. 04 00 46 00 50 00 2C 0E
|
||||||
|
// radio 2 .. 05 00 46 00 50 00 2C 0E
|
||||||
|
EEPROM_ReadBuffer(0x1F88, &Misc, 8);
|
||||||
|
|
||||||
|
gEeprom.BK4819_XTAL_FREQ_LOW = (Misc.BK4819_XtalFreqLow >= -1000 && Misc.BK4819_XtalFreqLow <= 1000) ? Misc.BK4819_XtalFreqLow : 0;
|
||||||
|
gEEPROM_1F8A = Misc.EEPROM_1F8A & 0x01FF;
|
||||||
|
gEEPROM_1F8C = Misc.EEPROM_1F8C & 0x01FF;
|
||||||
|
gEeprom.VOLUME_GAIN = (Misc.VOLUME_GAIN < 64) ? Misc.VOLUME_GAIN : 58;
|
||||||
|
gEeprom.DAC_GAIN = (Misc.DAC_GAIN < 16) ? Misc.DAC_GAIN : 8;
|
||||||
|
|
||||||
|
BK4819_WriteRegister(BK4819_REG_3B, 22656 + gEeprom.BK4819_XTAL_FREQ_LOW);
|
||||||
|
// BK4819_WriteRegister(BK4819_REG_3C, gEeprom.BK4819_XTAL_FREQ_HIGH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SETTINGS_FetchChannelFrequency(const int channel)
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t frequency;
|
||||||
|
uint32_t offset;
|
||||||
|
} __attribute__((packed)) info;
|
||||||
|
|
||||||
|
EEPROM_ReadBuffer(channel * 16, &info, sizeof(info));
|
||||||
|
|
||||||
|
return info.frequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SETTINGS_FetchChannelName(char *s, const int channel)
|
||||||
|
{
|
||||||
|
if (s == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memset(s, 0, 11); // 's' had better be large enough !
|
||||||
|
|
||||||
|
if (channel < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!RADIO_CheckValidChannel(channel, false, 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
EEPROM_ReadBuffer(0x0F50 + (channel * 16), s + 0, 8);
|
||||||
|
EEPROM_ReadBuffer(0x0F58 + (channel * 16), s + 8, 2);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
if (s[i] < 32 || s[i] > 127)
|
||||||
|
break; // invalid char
|
||||||
|
|
||||||
|
s[i--] = 0; // null term
|
||||||
|
|
||||||
|
while (i >= 0 && s[i] == 32) // trim trailing spaces
|
||||||
|
s[i--] = 0; // null term
|
||||||
|
}
|
||||||
|
|
||||||
|
void SETTINGS_FactoryReset(bool bIsAll)
|
||||||
|
{
|
||||||
|
uint16_t i;
|
||||||
|
uint8_t Template[8];
|
||||||
|
|
||||||
|
memset(Template, 0xFF, sizeof(Template));
|
||||||
|
|
||||||
|
for (i = 0x0C80; i < 0x1E00; i += 8)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
!(i >= 0x0EE0 && i < 0x0F18) && // ANI ID + DTMF codes
|
||||||
|
!(i >= 0x0F30 && i < 0x0F50) && // AES KEY + F LOCK + Scramble Enable
|
||||||
|
!(i >= 0x1C00 && i < 0x1E00) && // DTMF contacts
|
||||||
|
!(i >= 0x0EB0 && i < 0x0ED0) && // Welcome strings
|
||||||
|
!(i >= 0x0EA0 && i < 0x0EA8) && // Voice Prompt
|
||||||
|
(bIsAll ||
|
||||||
|
(
|
||||||
|
!(i >= 0x0D60 && i < 0x0E28) && // MR Channel Attributes
|
||||||
|
!(i >= 0x0F18 && i < 0x0F30) && // Scan List
|
||||||
|
!(i >= 0x0F50 && i < 0x1C00) && // MR Channel Names
|
||||||
|
!(i >= 0x0E40 && i < 0x0E70) && // FM Channels
|
||||||
|
!(i >= 0x0E88 && i < 0x0E90) // FM settings
|
||||||
|
))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EEPROM_WriteBuffer(i, Template);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bIsAll)
|
||||||
|
{
|
||||||
|
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_FIRST + BAND6_400MHz, 43350000);
|
||||||
|
|
||||||
|
// set the first few memory channels
|
||||||
|
for (i = 0; i < ARRAY_SIZE(gDefaultFrequencyTable); i++)
|
||||||
|
{
|
||||||
|
const uint32_t Frequency = gDefaultFrequencyTable[i];
|
||||||
|
gRxVfo->freq_config_RX.Frequency = Frequency;
|
||||||
|
gRxVfo->freq_config_TX.Frequency = Frequency;
|
||||||
|
gRxVfo->Band = FREQUENCY_GetBand(Frequency);
|
||||||
|
SETTINGS_SaveChannel(MR_CHANNEL_FIRST + i, 0, gRxVfo, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
void SETTINGS_SaveFM(void)
|
void SETTINGS_SaveFM(void)
|
||||||
{
|
{
|
||||||
@@ -96,17 +504,18 @@ void SETTINGS_SaveSettings(void)
|
|||||||
State[7] = gEeprom.MIC_SENSITIVITY;
|
State[7] = gEeprom.MIC_SENSITIVITY;
|
||||||
EEPROM_WriteBuffer(0x0E70, State);
|
EEPROM_WriteBuffer(0x0E70, State);
|
||||||
|
|
||||||
State[0] = 0xFF;
|
State[0] = (gEeprom.BACKLIGHT_MIN << 4) + gEeprom.BACKLIGHT_MAX;
|
||||||
State[1] = gEeprom.CHANNEL_DISPLAY_MODE;
|
State[1] = gEeprom.CHANNEL_DISPLAY_MODE;
|
||||||
State[2] = gEeprom.CROSS_BAND_RX_TX;
|
State[2] = gEeprom.CROSS_BAND_RX_TX;
|
||||||
State[3] = gEeprom.BATTERY_SAVE;
|
State[3] = gEeprom.BATTERY_SAVE;
|
||||||
State[4] = gEeprom.DUAL_WATCH;
|
State[4] = gEeprom.DUAL_WATCH;
|
||||||
State[5] = gEeprom.BACKLIGHT;
|
State[5] = gEeprom.BACKLIGHT_TIME;
|
||||||
State[6] = gEeprom.TAIL_NOTE_ELIMINATION;
|
State[6] = gEeprom.TAIL_TONE_ELIMINATION;
|
||||||
State[7] = gEeprom.VFO_OPEN;
|
State[7] = gEeprom.VFO_OPEN;
|
||||||
EEPROM_WriteBuffer(0x0E78, State);
|
EEPROM_WriteBuffer(0x0E78, State);
|
||||||
|
|
||||||
State[0] = gEeprom.BEEP_CONTROL;
|
State[0] = gEeprom.BEEP_CONTROL;
|
||||||
|
State[0] |= gEeprom.KEY_M_LONG_PRESS_ACTION << 1;
|
||||||
State[1] = gEeprom.KEY_1_SHORT_PRESS_ACTION;
|
State[1] = gEeprom.KEY_1_SHORT_PRESS_ACTION;
|
||||||
State[2] = gEeprom.KEY_1_LONG_PRESS_ACTION;
|
State[2] = gEeprom.KEY_1_LONG_PRESS_ACTION;
|
||||||
State[3] = gEeprom.KEY_2_SHORT_PRESS_ACTION;
|
State[3] = gEeprom.KEY_2_SHORT_PRESS_ACTION;
|
||||||
@@ -122,11 +531,16 @@ void SETTINGS_SaveSettings(void)
|
|||||||
#endif
|
#endif
|
||||||
EEPROM_WriteBuffer(0x0E98, Password);
|
EEPROM_WriteBuffer(0x0E98, Password);
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
memset(State, 0xFF, sizeof(State));
|
||||||
memset(State, 0xFF, sizeof(State));
|
#ifdef ENABLE_VOICE
|
||||||
State[0] = gEeprom.VOICE_PROMPT;
|
State[0] = gEeprom.VOICE_PROMPT;
|
||||||
EEPROM_WriteBuffer(0x0EA0, State);
|
#endif
|
||||||
#endif
|
#ifdef ENABLE_RSSI_BAR
|
||||||
|
State[1] = gEeprom.S0_LEVEL;
|
||||||
|
State[2] = gEeprom.S9_LEVEL;
|
||||||
|
#endif
|
||||||
|
EEPROM_WriteBuffer(0x0EA0, State);
|
||||||
|
|
||||||
|
|
||||||
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
|
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
|
||||||
State[0] = gEeprom.ALARM_MODE;
|
State[0] = gEeprom.ALARM_MODE;
|
||||||
@@ -136,13 +550,16 @@ void SETTINGS_SaveSettings(void)
|
|||||||
State[1] = gEeprom.ROGER;
|
State[1] = gEeprom.ROGER;
|
||||||
State[2] = gEeprom.REPEATER_TAIL_TONE_ELIMINATION;
|
State[2] = gEeprom.REPEATER_TAIL_TONE_ELIMINATION;
|
||||||
State[3] = gEeprom.TX_VFO;
|
State[3] = gEeprom.TX_VFO;
|
||||||
|
State[4] = gEeprom.BATTERY_TYPE;
|
||||||
EEPROM_WriteBuffer(0x0EA8, State);
|
EEPROM_WriteBuffer(0x0EA8, State);
|
||||||
|
|
||||||
State[0] = gEeprom.DTMF_SIDE_TONE;
|
State[0] = gEeprom.DTMF_SIDE_TONE;
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
State[1] = gEeprom.DTMF_SEPARATE_CODE;
|
State[1] = gEeprom.DTMF_SEPARATE_CODE;
|
||||||
State[2] = gEeprom.DTMF_GROUP_CALL_CODE;
|
State[2] = gEeprom.DTMF_GROUP_CALL_CODE;
|
||||||
State[3] = gEeprom.DTMF_DECODE_RESPONSE;
|
State[3] = gEeprom.DTMF_DECODE_RESPONSE;
|
||||||
State[4] = gEeprom.DTMF_auto_reset_time;
|
State[4] = gEeprom.DTMF_auto_reset_time;
|
||||||
|
#endif
|
||||||
State[5] = gEeprom.DTMF_PRELOAD_TIME / 10U;
|
State[5] = gEeprom.DTMF_PRELOAD_TIME / 10U;
|
||||||
State[6] = gEeprom.DTMF_FIRST_CODE_PERSIST_TIME / 10U;
|
State[6] = gEeprom.DTMF_FIRST_CODE_PERSIST_TIME / 10U;
|
||||||
State[7] = gEeprom.DTMF_HASH_CODE_PERSIST_TIME / 10U;
|
State[7] = gEeprom.DTMF_HASH_CODE_PERSIST_TIME / 10U;
|
||||||
@@ -151,7 +568,9 @@ void SETTINGS_SaveSettings(void)
|
|||||||
memset(State, 0xFF, sizeof(State));
|
memset(State, 0xFF, sizeof(State));
|
||||||
State[0] = gEeprom.DTMF_CODE_PERSIST_TIME / 10U;
|
State[0] = gEeprom.DTMF_CODE_PERSIST_TIME / 10U;
|
||||||
State[1] = gEeprom.DTMF_CODE_INTERVAL_TIME / 10U;
|
State[1] = gEeprom.DTMF_CODE_INTERVAL_TIME / 10U;
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
State[2] = gEeprom.PERMIT_REMOTE_KILL;
|
State[2] = gEeprom.PERMIT_REMOTE_KILL;
|
||||||
|
#endif
|
||||||
EEPROM_WriteBuffer(0x0ED8, State);
|
EEPROM_WriteBuffer(0x0ED8, State);
|
||||||
|
|
||||||
State[0] = gEeprom.SCAN_LIST_DEFAULT;
|
State[0] = gEeprom.SCAN_LIST_DEFAULT;
|
||||||
@@ -167,12 +586,14 @@ void SETTINGS_SaveSettings(void)
|
|||||||
memset(State, 0xFF, sizeof(State));
|
memset(State, 0xFF, sizeof(State));
|
||||||
State[0] = gSetting_F_LOCK;
|
State[0] = gSetting_F_LOCK;
|
||||||
State[1] = gSetting_350TX;
|
State[1] = gSetting_350TX;
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
State[2] = gSetting_KILLED;
|
State[2] = gSetting_KILLED;
|
||||||
|
#endif
|
||||||
State[3] = gSetting_200TX;
|
State[3] = gSetting_200TX;
|
||||||
State[4] = gSetting_500TX;
|
State[4] = gSetting_500TX;
|
||||||
State[5] = gSetting_350EN;
|
State[5] = gSetting_350EN;
|
||||||
State[6] = gSetting_ScrambleEnable;
|
State[6] = gSetting_ScrambleEnable;
|
||||||
if (!gSetting_TX_EN) State[7] &= ~(1u << 0);
|
//if (!gSetting_TX_EN) State[7] &= ~(1u << 0);
|
||||||
if (!gSetting_live_DTMF_decoder) State[7] &= ~(1u << 1);
|
if (!gSetting_live_DTMF_decoder) State[7] &= ~(1u << 1);
|
||||||
State[7] = (State[7] & ~(3u << 2)) | ((gSetting_battery_text & 3u) << 2);
|
State[7] = (State[7] & ~(3u << 2)) | ((gSetting_battery_text & 3u) << 2);
|
||||||
#ifdef ENABLE_AUDIO_BAR
|
#ifdef ENABLE_AUDIO_BAR
|
||||||
@@ -189,61 +610,56 @@ void SETTINGS_SaveSettings(void)
|
|||||||
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode)
|
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
if (IS_NOT_NOAA_CHANNEL(Channel))
|
if (!IS_NOAA_CHANNEL(Channel))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
const uint16_t OffsetMR = Channel * 16;
|
uint16_t OffsetVFO = Channel * 16;
|
||||||
uint16_t OffsetVFO = OffsetMR;
|
|
||||||
|
|
||||||
if (Channel > MR_CHANNEL_LAST)
|
if (!IS_MR_CHANNEL(Channel))
|
||||||
{ // it's a VFO, not a channel
|
{ // it's a VFO, not a channel
|
||||||
OffsetVFO = (VFO == 0) ? 0x0C80 : 0x0C90;
|
OffsetVFO = (VFO == 0) ? 0x0C80 : 0x0C90;
|
||||||
OffsetVFO += (Channel - FREQ_CHANNEL_FIRST) * 32;
|
OffsetVFO += (Channel - FREQ_CHANNEL_FIRST) * 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Mode >= 2 || Channel > MR_CHANNEL_LAST)
|
if (Mode >= 2 || !IS_MR_CHANNEL(Channel))
|
||||||
{ // copy VFO to a channel
|
{ // copy VFO to a channel
|
||||||
|
|
||||||
uint8_t State[8];
|
union {
|
||||||
|
uint8_t _8[8];
|
||||||
|
uint32_t _32[2];
|
||||||
|
} State;
|
||||||
|
|
||||||
((uint32_t *)State)[0] = pVFO->freq_config_RX.Frequency;
|
State._32[0] = pVFO->freq_config_RX.Frequency;
|
||||||
((uint32_t *)State)[1] = pVFO->TX_OFFSET_FREQUENCY;
|
State._32[1] = pVFO->TX_OFFSET_FREQUENCY;
|
||||||
EEPROM_WriteBuffer(OffsetVFO + 0, State);
|
EEPROM_WriteBuffer(OffsetVFO + 0, State._32);
|
||||||
|
|
||||||
State[0] = pVFO->freq_config_RX.Code;
|
State._8[0] = pVFO->freq_config_RX.Code;
|
||||||
State[1] = pVFO->freq_config_TX.Code;
|
State._8[1] = pVFO->freq_config_TX.Code;
|
||||||
State[2] = (pVFO->freq_config_TX.CodeType << 4) | pVFO->freq_config_RX.CodeType;
|
State._8[2] = (pVFO->freq_config_TX.CodeType << 4) | pVFO->freq_config_RX.CodeType;
|
||||||
State[3] = ((pVFO->AM_mode & 1u) << 4) | pVFO->TX_OFFSET_FREQUENCY_DIRECTION;
|
State._8[3] = (pVFO->Modulation << 4) | pVFO->TX_OFFSET_FREQUENCY_DIRECTION;
|
||||||
State[4] = 0
|
State._8[4] = 0
|
||||||
| (pVFO->BUSY_CHANNEL_LOCK << 4)
|
| (pVFO->BUSY_CHANNEL_LOCK << 4)
|
||||||
| (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 & 7u) << 1) | ((pVFO->DTMF_DECODING_ENABLE & 1u) << 0);
|
State._8[5] = ((pVFO->DTMF_PTT_ID_TX_MODE & 7u) << 1)
|
||||||
State[6] = pVFO->STEP_SETTING;
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
State[7] = pVFO->SCRAMBLING_TYPE;
|
| ((pVFO->DTMF_DECODING_ENABLE & 1u) << 0)
|
||||||
EEPROM_WriteBuffer(OffsetVFO + 8, State);
|
#endif
|
||||||
|
;
|
||||||
|
State._8[6] = pVFO->STEP_SETTING;
|
||||||
|
State._8[7] = pVFO->SCRAMBLING_TYPE;
|
||||||
|
EEPROM_WriteBuffer(OffsetVFO + 8, State._8);
|
||||||
|
|
||||||
SETTINGS_UpdateChannel(Channel, pVFO, true);
|
SETTINGS_UpdateChannel(Channel, pVFO, true);
|
||||||
|
|
||||||
if (Channel <= MR_CHANNEL_LAST)
|
if (IS_MR_CHANNEL(Channel)) {
|
||||||
{ // it's a memory channel
|
|
||||||
|
|
||||||
#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));
|
SETTINGS_SaveChannelName(Channel, "");
|
||||||
memset(&State, 0x00, sizeof(State)); // follow the QS way
|
|
||||||
EEPROM_WriteBuffer(0x0F50 + OffsetMR, State);
|
|
||||||
EEPROM_WriteBuffer(0x0F58 + OffsetMR, State);
|
|
||||||
#else
|
#else
|
||||||
if (Mode >= 3)
|
if (Mode >= 3) {
|
||||||
{ // save the channel name
|
SETTINGS_SaveChannelName(Channel, pVFO->Name);
|
||||||
memmove(State, pVFO->Name + 0, 8);
|
|
||||||
EEPROM_WriteBuffer(0x0F50 + OffsetMR, State);
|
|
||||||
//memset(State, 0xFF, sizeof(State));
|
|
||||||
memset(State, 0x00, sizeof(State)); // follow the QS way
|
|
||||||
memmove(State, pVFO->Name + 8, 2);
|
|
||||||
EEPROM_WriteBuffer(0x0F58 + OffsetMR, State);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -251,55 +667,112 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep)
|
void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_NOAA
|
uint16_t buf[4];
|
||||||
if (IS_NOT_NOAA_CHANNEL(Channel))
|
EEPROM_WriteBuffer(0x1F40, batteryCalibration);
|
||||||
#endif
|
EEPROM_ReadBuffer( 0x1F48, buf, sizeof(buf));
|
||||||
|
buf[0] = batteryCalibration[4];
|
||||||
|
buf[1] = batteryCalibration[5];
|
||||||
|
EEPROM_WriteBuffer(0x1F48, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SETTINGS_SaveChannelName(uint8_t channel, const char * name)
|
||||||
|
{
|
||||||
|
uint16_t offset = channel * 16;
|
||||||
|
uint8_t buf[16];
|
||||||
|
memset(&buf, 0x00, sizeof(buf));
|
||||||
|
memcpy(buf, name, MIN(strlen(name),10u));
|
||||||
|
EEPROM_WriteBuffer(0x0F50 + offset, buf);
|
||||||
|
EEPROM_WriteBuffer(0x0F58 + offset, buf + 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep)
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_NOAA
|
||||||
|
if (!IS_NOAA_CHANNEL(channel))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
uint8_t State[8];
|
uint8_t state[8];
|
||||||
uint8_t Attributes = 0xFF; // default attributes
|
ChannelAttributes_t att = {
|
||||||
uint16_t Offset = 0x0D60 + (Channel & ~7u);
|
.band = 0xf,
|
||||||
|
.compander = 0,
|
||||||
|
.scanlist1 = 0,
|
||||||
|
.scanlist2 = 0,
|
||||||
|
}; // default attributes
|
||||||
|
|
||||||
Attributes &= (uint8_t)(~MR_CH_COMPAND); // default to '0' = compander disabled
|
uint16_t offset = 0x0D60 + (channel & ~7u);
|
||||||
|
EEPROM_ReadBuffer(offset, state, sizeof(state));
|
||||||
|
|
||||||
EEPROM_ReadBuffer(Offset, State, sizeof(State));
|
if (keep) {
|
||||||
|
att.band = pVFO->Band;
|
||||||
if (keep)
|
att.scanlist1 = pVFO->SCANLIST1_PARTICIPATION;
|
||||||
{
|
att.scanlist2 = pVFO->SCANLIST2_PARTICIPATION;
|
||||||
Attributes = (pVFO->SCANLIST1_PARTICIPATION << 7) | (pVFO->SCANLIST2_PARTICIPATION << 6) | (pVFO->Compander << 4) | (pVFO->Band << 0);
|
att.compander = pVFO->Compander;
|
||||||
if (State[Channel & 7u] == Attributes)
|
if (state[channel & 7u] == att.__val)
|
||||||
return; // no change in the attributes
|
return; // no change in the attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
State[Channel & 7u] = Attributes;
|
state[channel & 7u] = att.__val;
|
||||||
|
EEPROM_WriteBuffer(offset, state);
|
||||||
|
|
||||||
EEPROM_WriteBuffer(Offset, State);
|
gMR_ChannelAttributes[channel] = att;
|
||||||
|
|
||||||
gMR_ChannelAttributes[Channel] = Attributes;
|
if (IS_MR_CHANNEL(channel)) { // it's a memory channel
|
||||||
|
if (!keep) {
|
||||||
// #ifndef ENABLE_KEEP_MEM_NAME
|
// clear/reset the channel name
|
||||||
if (Channel <= MR_CHANNEL_LAST)
|
SETTINGS_SaveChannelName(channel, "");
|
||||||
{ // it's a memory channel
|
|
||||||
|
|
||||||
const uint16_t OffsetMR = Channel * 16;
|
|
||||||
if (!keep)
|
|
||||||
{ // clear/reset the channel name
|
|
||||||
//memset(&State, 0xFF, sizeof(State));
|
|
||||||
memset(&State, 0x00, sizeof(State)); // follow the QS way
|
|
||||||
EEPROM_WriteBuffer(0x0F50 + OffsetMR, State);
|
|
||||||
EEPROM_WriteBuffer(0x0F58 + OffsetMR, State);
|
|
||||||
}
|
|
||||||
// else
|
|
||||||
// { // update the channel name
|
|
||||||
// memmove(State, pVFO->Name + 0, 8);
|
|
||||||
// EEPROM_WriteBuffer(0x0F50 + OffsetMR, State);
|
|
||||||
// //memset(State, 0xFF, sizeof(State));
|
|
||||||
// memset(State, 0x00, sizeof(State)); // follow the QS way
|
|
||||||
// memmove(State, pVFO->Name + 8, 2);
|
|
||||||
// EEPROM_WriteBuffer(0x0F58 + OffsetMR, State);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
// #endif
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SETTINGS_WriteBuildOptions(void)
|
||||||
|
{
|
||||||
|
uint8_t buf[8]= {};
|
||||||
|
buf[0] = 0
|
||||||
|
#ifdef ENABLE_FMRADIO
|
||||||
|
| (1 << 0)
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_NOAA
|
||||||
|
| (1 << 1)
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
| (1 << 2)
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_VOX
|
||||||
|
| (1 << 3)
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_ALARM
|
||||||
|
| (1 << 4)
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_TX1750
|
||||||
|
| (1 << 5)
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_PWRON_PASSWORD
|
||||||
|
| (1 << 6)
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
| (1 << 7)
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
buf[1] = 0
|
||||||
|
#ifdef ENABLE_FLASHLIGHT
|
||||||
|
| (1 << 0)
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_WIDE_RX
|
||||||
|
| (1 << 1)
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_BYP_RAW_DEMODULATORS
|
||||||
|
| (1 << 2)
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_BLMIN_TMP_OFF
|
||||||
|
| (1 << 3)
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AM_FIX
|
||||||
|
| (1 << 4)
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
EEPROM_WriteBuffer(0x1FF0, buf);
|
||||||
|
}
|
||||||
63
settings.h
63
settings.h
@@ -21,7 +21,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "frequencies.h"
|
#include "frequencies.h"
|
||||||
|
#include <helper/battery.h>
|
||||||
#include "radio.h"
|
#include "radio.h"
|
||||||
|
#include <driver/backlight.h>
|
||||||
|
|
||||||
enum POWER_OnDisplayMode_t {
|
enum POWER_OnDisplayMode_t {
|
||||||
POWER_ON_DISPLAY_MODE_FULL_SCREEN = 0,
|
POWER_ON_DISPLAY_MODE_FULL_SCREEN = 0,
|
||||||
@@ -31,13 +33,16 @@ enum POWER_OnDisplayMode_t {
|
|||||||
};
|
};
|
||||||
typedef enum POWER_OnDisplayMode_t POWER_OnDisplayMode_t;
|
typedef enum POWER_OnDisplayMode_t POWER_OnDisplayMode_t;
|
||||||
|
|
||||||
enum {
|
enum TxLockModes_t {
|
||||||
F_LOCK_OFF = 0,
|
F_LOCK_DEF, //all default frequencies + configurable
|
||||||
F_LOCK_FCC,
|
F_LOCK_FCC,
|
||||||
F_LOCK_CE,
|
F_LOCK_CE,
|
||||||
F_LOCK_GB,
|
F_LOCK_GB,
|
||||||
F_LOCK_430,
|
F_LOCK_430,
|
||||||
F_LOCK_438
|
F_LOCK_438,
|
||||||
|
F_LOCK_ALL, // disable TX on all frequencies
|
||||||
|
F_LOCK_NONE, // enable TX on all frequencies
|
||||||
|
F_LOCK_LEN
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -70,7 +75,7 @@ enum {
|
|||||||
OUTPUT_POWER_HIGH
|
OUTPUT_POWER_HIGH
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum ACTION_OPT_t {
|
||||||
ACTION_OPT_NONE = 0,
|
ACTION_OPT_NONE = 0,
|
||||||
ACTION_OPT_FLASHLIGHT,
|
ACTION_OPT_FLASHLIGHT,
|
||||||
ACTION_OPT_POWER,
|
ACTION_OPT_POWER,
|
||||||
@@ -80,6 +85,11 @@ enum {
|
|||||||
ACTION_OPT_ALARM,
|
ACTION_OPT_ALARM,
|
||||||
ACTION_OPT_FM,
|
ACTION_OPT_FM,
|
||||||
ACTION_OPT_1750,
|
ACTION_OPT_1750,
|
||||||
|
ACTION_OPT_KEYLOCK,
|
||||||
|
ACTION_OPT_A_B,
|
||||||
|
ACTION_OPT_VFO_MR,
|
||||||
|
ACTION_OPT_SWITCH_DEMODUL,
|
||||||
|
ACTION_OPT_BLMIN_TMP_OFF, //BackLight Minimum Temporay OFF
|
||||||
ACTION_OPT_LEN
|
ACTION_OPT_LEN
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -115,13 +125,19 @@ enum CHANNEL_DisplayMode_t {
|
|||||||
typedef enum CHANNEL_DisplayMode_t CHANNEL_DisplayMode_t;
|
typedef enum CHANNEL_DisplayMode_t CHANNEL_DisplayMode_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t ScreenChannel[2];
|
uint8_t ScreenChannel[2]; // current channels set in the radio (memory or frequency channels)
|
||||||
uint8_t FreqChannel[2];
|
uint8_t FreqChannel[2]; // last frequency channels used
|
||||||
uint8_t MrChannel[2];
|
uint8_t MrChannel[2]; // last memory channels used
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
uint8_t NoaaChannel[2];
|
uint8_t NoaaChannel[2];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// The actual VFO index (0-upper/1-lower) that is now used for RX,
|
||||||
|
// It is being alternated by dual watch, and flipped by crossband
|
||||||
uint8_t RX_VFO;
|
uint8_t RX_VFO;
|
||||||
|
|
||||||
|
// The main VFO index (0-upper/1-lower) selected by the user
|
||||||
|
//
|
||||||
uint8_t TX_VFO;
|
uint8_t TX_VFO;
|
||||||
|
|
||||||
uint8_t field7_0xa;
|
uint8_t field7_0xa;
|
||||||
@@ -146,12 +162,12 @@ typedef struct {
|
|||||||
#endif
|
#endif
|
||||||
bool BEEP_CONTROL;
|
bool BEEP_CONTROL;
|
||||||
uint8_t CHANNEL_DISPLAY_MODE;
|
uint8_t CHANNEL_DISPLAY_MODE;
|
||||||
bool TAIL_NOTE_ELIMINATION;
|
bool TAIL_TONE_ELIMINATION;
|
||||||
bool VFO_OPEN;
|
bool VFO_OPEN;
|
||||||
uint8_t DUAL_WATCH;
|
uint8_t DUAL_WATCH;
|
||||||
uint8_t CROSS_BAND_RX_TX;
|
uint8_t CROSS_BAND_RX_TX;
|
||||||
uint8_t BATTERY_SAVE;
|
uint8_t BATTERY_SAVE;
|
||||||
uint8_t BACKLIGHT;
|
uint8_t BACKLIGHT_TIME;
|
||||||
uint8_t SCAN_RESUME_MODE;
|
uint8_t SCAN_RESUME_MODE;
|
||||||
uint8_t SCAN_LIST_DEFAULT;
|
uint8_t SCAN_LIST_DEFAULT;
|
||||||
bool SCAN_LIST_ENABLED[2];
|
bool SCAN_LIST_ENABLED[2];
|
||||||
@@ -178,9 +194,11 @@ typedef struct {
|
|||||||
uint8_t MIC_SENSITIVITY;
|
uint8_t MIC_SENSITIVITY;
|
||||||
uint8_t MIC_SENSITIVITY_TUNING;
|
uint8_t MIC_SENSITIVITY_TUNING;
|
||||||
uint8_t CHAN_1_CALL;
|
uint8_t CHAN_1_CALL;
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
char ANI_DTMF_ID[8];
|
char ANI_DTMF_ID[8];
|
||||||
char KILL_CODE[8];
|
char KILL_CODE[8];
|
||||||
char REVIVE_CODE[8];
|
char REVIVE_CODE[8];
|
||||||
|
#endif
|
||||||
char DTMF_UP_CODE[16];
|
char DTMF_UP_CODE[16];
|
||||||
|
|
||||||
uint8_t field57_0x6c;
|
uint8_t field57_0x6c;
|
||||||
@@ -191,17 +209,21 @@ typedef struct {
|
|||||||
uint8_t field60_0x7e;
|
uint8_t field60_0x7e;
|
||||||
uint8_t field61_0x7f;
|
uint8_t field61_0x7f;
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
char DTMF_SEPARATE_CODE;
|
char DTMF_SEPARATE_CODE;
|
||||||
char DTMF_GROUP_CALL_CODE;
|
char DTMF_GROUP_CALL_CODE;
|
||||||
uint8_t DTMF_DECODE_RESPONSE;
|
uint8_t DTMF_DECODE_RESPONSE;
|
||||||
uint8_t DTMF_auto_reset_time;
|
uint8_t DTMF_auto_reset_time;
|
||||||
|
#endif
|
||||||
uint16_t DTMF_PRELOAD_TIME;
|
uint16_t DTMF_PRELOAD_TIME;
|
||||||
uint16_t DTMF_FIRST_CODE_PERSIST_TIME;
|
uint16_t DTMF_FIRST_CODE_PERSIST_TIME;
|
||||||
uint16_t DTMF_HASH_CODE_PERSIST_TIME;
|
uint16_t DTMF_HASH_CODE_PERSIST_TIME;
|
||||||
uint16_t DTMF_CODE_PERSIST_TIME;
|
uint16_t DTMF_CODE_PERSIST_TIME;
|
||||||
uint16_t DTMF_CODE_INTERVAL_TIME;
|
uint16_t DTMF_CODE_INTERVAL_TIME;
|
||||||
bool DTMF_SIDE_TONE;
|
bool DTMF_SIDE_TONE;
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
bool PERMIT_REMOTE_KILL;
|
bool PERMIT_REMOTE_KILL;
|
||||||
|
#endif
|
||||||
int16_t BK4819_XTAL_FREQ_LOW;
|
int16_t BK4819_XTAL_FREQ_LOW;
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
bool NOAA_AUTO_SCAN;
|
bool NOAA_AUTO_SCAN;
|
||||||
@@ -218,16 +240,35 @@ typedef struct {
|
|||||||
uint8_t field78_0x96;
|
uint8_t field78_0x96;
|
||||||
uint8_t field79_0x97;
|
uint8_t field79_0x97;
|
||||||
|
|
||||||
uint8_t _pad[1];
|
uint8_t KEY_M_LONG_PRESS_ACTION;
|
||||||
|
uint8_t BACKLIGHT_MIN;
|
||||||
|
#ifdef ENABLE_BLMIN_TMP_OFF
|
||||||
|
BLMIN_STAT_t BACKLIGHT_MIN_STAT;
|
||||||
|
#endif
|
||||||
|
uint8_t BACKLIGHT_MAX;
|
||||||
|
BATTERY_Type_t BATTERY_TYPE;
|
||||||
|
#ifdef ENABLE_RSSI_BAR
|
||||||
|
uint8_t S0_LEVEL;
|
||||||
|
uint8_t S9_LEVEL;
|
||||||
|
#endif
|
||||||
} EEPROM_Config_t;
|
} EEPROM_Config_t;
|
||||||
|
|
||||||
extern EEPROM_Config_t gEeprom;
|
extern EEPROM_Config_t gEeprom;
|
||||||
|
|
||||||
|
void SETTINGS_InitEEPROM(void);
|
||||||
|
void SETTINGS_LoadCalibration(void);
|
||||||
|
uint32_t SETTINGS_FetchChannelFrequency(const int channel);
|
||||||
|
void SETTINGS_FetchChannelName(char *s, const int channel);
|
||||||
|
void SETTINGS_FactoryReset(bool bIsAll);
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
void SETTINGS_SaveFM(void);
|
void SETTINGS_SaveFM(void);
|
||||||
#endif
|
#endif
|
||||||
void SETTINGS_SaveVfoIndices(void);
|
void SETTINGS_SaveVfoIndices(void);
|
||||||
void SETTINGS_SaveSettings(void);
|
void SETTINGS_SaveSettings(void);
|
||||||
|
void SETTINGS_SaveChannelName(uint8_t channel, const char * name);
|
||||||
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode);
|
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode);
|
||||||
void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep);
|
void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration);
|
||||||
|
void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep);
|
||||||
|
void SETTINGS_WriteBuildOptions(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
17
ui/aircopy.c
17
ui/aircopy.c
@@ -44,12 +44,19 @@ void UI_DisplayAircopy(void)
|
|||||||
|
|
||||||
if (gInputBoxIndex == 0)
|
if (gInputBoxIndex == 0)
|
||||||
{
|
{
|
||||||
NUMBER_ToDigits(gRxVfo->freq_config_RX.Frequency, String);
|
uint32_t frequency = gRxVfo->freq_config_RX.Frequency;
|
||||||
UI_DisplayFrequency(String, 16, 2, 0, 0);
|
sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000);
|
||||||
UI_DisplaySmallDigits(2, String + 6, 97, 3, true);
|
// show the remaining 2 small frequency digits
|
||||||
|
UI_PrintStringSmall(String + 7, 97, 0, 3);
|
||||||
|
String[7] = 0;
|
||||||
|
// show the main large frequency digits
|
||||||
|
UI_DisplayFrequency(String, 16, 2, false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const char * ascii = INPUTBOX_GetAscii();
|
||||||
|
sprintf(String, "%.3s.%.3s",ascii, ascii + 3);
|
||||||
|
UI_DisplayFrequency(String, 16, 2, false);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
UI_DisplayFrequency(gInputBox, 16, 2, 1, 0);
|
|
||||||
|
|
||||||
memset(String, 0, sizeof(String));
|
memset(String, 0, sizeof(String));
|
||||||
if (gAirCopyIsSendMode == 0)
|
if (gAirCopyIsSendMode == 0)
|
||||||
|
|||||||
48
ui/battery.c
48
ui/battery.c
@@ -21,37 +21,35 @@
|
|||||||
#include "driver/st7565.h"
|
#include "driver/st7565.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "ui/battery.h"
|
#include "ui/battery.h"
|
||||||
|
#include "../misc.h"
|
||||||
|
|
||||||
void UI_DrawBattery(uint8_t* bitmap, uint8_t level, uint8_t blink)
|
void UI_DrawBattery(uint8_t* bitmap, uint8_t level, uint8_t blink)
|
||||||
{
|
{
|
||||||
memmove(bitmap, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
|
if (level < 2 && blink == 1) {
|
||||||
|
memset(bitmap, 0, sizeof(BITMAP_BatteryLevel1));
|
||||||
if (level >= 1)
|
return;
|
||||||
{
|
}
|
||||||
unsigned int i;
|
|
||||||
uint8_t bars = level > 0 ? level - 1 : 0;
|
memcpy(bitmap, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
|
||||||
if(bars>4) bars = 4;
|
|
||||||
for (i = 0; i < bars; i++)
|
if (level <= 2) {
|
||||||
{
|
return;
|
||||||
#ifndef ENABLE_REVERSE_BAT_SYMBOL
|
}
|
||||||
memcpy(bitmap + sizeof(bitmap) - 4 - (i * 3), BITMAP_BatteryLevel, 2);
|
|
||||||
#else
|
const uint8_t bars = MIN(4, level - 2);
|
||||||
memcpy(bitmap + 3 + (i * 3) + 0, BITMAP_BatteryLevel, 2);
|
|
||||||
#endif
|
for (int i = 0; i < bars; i++) {
|
||||||
}
|
#ifndef ENABLE_REVERSE_BAT_SYMBOL
|
||||||
|
memcpy(bitmap + sizeof(BITMAP_BatteryLevel1) - 4 - (i * 3), BITMAP_BatteryLevel, 2);
|
||||||
|
#else
|
||||||
|
memcpy(bitmap + 3 + (i * 3) + 0, BITMAP_BatteryLevel, 2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if (blink == 0)
|
|
||||||
memset(bitmap, 0, sizeof(bitmap));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI_DisplayBattery(uint8_t level, uint8_t blink)
|
void UI_DisplayBattery(uint8_t level, uint8_t blink)
|
||||||
{
|
{
|
||||||
if (gCurrentFunction != FUNCTION_TRANSMIT) {
|
uint8_t bitmap[sizeof(BITMAP_BatteryLevel1)];
|
||||||
uint8_t bitmap[sizeof(BITMAP_BatteryLevel1)];
|
UI_DrawBattery(bitmap, level, blink);
|
||||||
|
ST7565_DrawLine(LCD_WIDTH - sizeof(bitmap), 0, bitmap, sizeof(bitmap));
|
||||||
UI_DrawBattery(bitmap, level, blink);
|
|
||||||
memmove(bitmap, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
|
|
||||||
ST7565_DrawLine(LCD_WIDTH - sizeof(bitmap), 0, sizeof(bitmap), bitmap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
11
ui/fmradio.c
11
ui/fmradio.c
@@ -90,11 +90,14 @@ void UI_DisplayFM(void)
|
|||||||
{
|
{
|
||||||
if (gInputBoxIndex == 0)
|
if (gInputBoxIndex == 0)
|
||||||
{
|
{
|
||||||
NUMBER_ToDigits(gEeprom.FM_FrequencyPlaying * 10000, String);
|
sprintf(String, "%3d.%d", gEeprom.FM_FrequencyPlaying / 10, gEeprom.FM_FrequencyPlaying % 10);
|
||||||
UI_DisplayFrequency(String, 23, 4, false, true);
|
UI_DisplayFrequency(String, 32, 4, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const char * ascii = INPUTBOX_GetAscii();
|
||||||
|
sprintf(String, "%.3s.%.1s",ascii, ascii + 3);
|
||||||
|
UI_DisplayFrequency(String, 32, 4, false);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
UI_DisplayFrequency(gInputBox, 23, 4, true, false);
|
|
||||||
|
|
||||||
ST7565_BlitFullScreen();
|
ST7565_BlitFullScreen();
|
||||||
return;
|
return;
|
||||||
|
|||||||
201
ui/helper.c
201
ui/helper.c
@@ -21,6 +21,7 @@
|
|||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "ui/helper.h"
|
#include "ui/helper.h"
|
||||||
#include "ui/inputbox.h"
|
#include "ui/inputbox.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
#ifndef ARRAY_SIZE
|
#ifndef ARRAY_SIZE
|
||||||
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]))
|
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]))
|
||||||
@@ -72,12 +73,12 @@ void UI_PrintString(const char *pString, uint8_t Start, uint8_t End, uint8_t Lin
|
|||||||
|
|
||||||
for (i = 0; i < Length; i++)
|
for (i = 0; i < Length; i++)
|
||||||
{
|
{
|
||||||
if (pString[i] >= ' ' && pString[i] < 127)
|
const unsigned int ofs = (unsigned int)Start + (i * Width);
|
||||||
|
if (pString[i] > ' ' && pString[i] < 127)
|
||||||
{
|
{
|
||||||
const unsigned int index = pString[i] - ' ';
|
const unsigned int index = pString[i] - ' ' - 1;
|
||||||
const unsigned int ofs = (unsigned int)Start + (i * Width);
|
memcpy(gFrameBuffer[Line + 0] + ofs, &gFontBig[index][0], 7);
|
||||||
memmove(gFrameBuffer[Line + 0] + ofs, &gFontBig[index][0], 8);
|
memcpy(gFrameBuffer[Line + 1] + ofs, &gFontBig[index][7], 7);
|
||||||
memmove(gFrameBuffer[Line + 1] + ofs, &gFontBig[index][8], 7);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,19 +88,21 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_
|
|||||||
const size_t Length = strlen(pString);
|
const size_t Length = strlen(pString);
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (End > Start)
|
|
||||||
Start += (((End - Start) - (Length * 8)) + 1) / 2;
|
|
||||||
|
|
||||||
const unsigned int char_width = ARRAY_SIZE(gFontSmall[0]);
|
const unsigned int char_width = ARRAY_SIZE(gFontSmall[0]);
|
||||||
const unsigned int char_spacing = char_width + 1;
|
const unsigned int char_spacing = char_width + 1;
|
||||||
|
|
||||||
|
if (End > Start)
|
||||||
|
Start += (((End - Start) - (Length * char_spacing)) + 1) / 2;
|
||||||
|
|
||||||
|
|
||||||
uint8_t *pFb = gFrameBuffer[Line] + Start;
|
uint8_t *pFb = gFrameBuffer[Line] + Start;
|
||||||
for (i = 0; i < Length; i++)
|
for (i = 0; i < Length; i++)
|
||||||
{
|
{
|
||||||
if (pString[i] >= 32)
|
if (pString[i] > ' ')
|
||||||
{
|
{
|
||||||
const unsigned int index = (unsigned int)pString[i] - 32;
|
const unsigned int index = (unsigned int)pString[i] - ' ' - 1;
|
||||||
if (index < ARRAY_SIZE(gFontSmall))
|
if (index < ARRAY_SIZE(gFontSmall))
|
||||||
memmove(pFb + (i * char_spacing) + 1, &gFontSmall[index], char_width);
|
memcpy(pFb + (i * char_spacing) + 1, &gFontSmall[index], char_width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,11 +121,11 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_
|
|||||||
uint8_t *pFb = gFrameBuffer[Line] + Start;
|
uint8_t *pFb = gFrameBuffer[Line] + Start;
|
||||||
for (i = 0; i < Length; i++)
|
for (i = 0; i < Length; i++)
|
||||||
{
|
{
|
||||||
if (pString[i] >= 32)
|
if (pString[i] > ' ')
|
||||||
{
|
{
|
||||||
const unsigned int index = (unsigned int)pString[i] - 32;
|
const unsigned int index = (unsigned int)pString[i] - ' ' - 1;
|
||||||
if (index < ARRAY_SIZE(gFontSmallBold))
|
if (index < ARRAY_SIZE(gFontSmallBold))
|
||||||
memmove(pFb + (i * char_spacing) + 1, &gFontSmallBold[index], char_width);
|
memcpy(pFb + (i * char_spacing) + 1, &gFontSmallBold[index], char_width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,126 +138,116 @@ void UI_PrintStringSmallBuffer(const char *pString, uint8_t *buffer)
|
|||||||
const unsigned int char_spacing = char_width + 1;
|
const unsigned int char_spacing = char_width + 1;
|
||||||
for (i = 0; i < strlen(pString); i++)
|
for (i = 0; i < strlen(pString); i++)
|
||||||
{
|
{
|
||||||
if (pString[i] >= 32)
|
if (pString[i] > ' ')
|
||||||
{
|
{
|
||||||
const unsigned int index = (unsigned int)pString[i] - 32;
|
const unsigned int index = (unsigned int)pString[i] - ' ' - 1;
|
||||||
if (index < ARRAY_SIZE(gFontSmall))
|
if (index < ARRAY_SIZE(gFontSmall))
|
||||||
memmove(buffer + (i * char_spacing) + 1, &gFontSmall[index], char_width);
|
memcpy(buffer + (i * char_spacing) + 1, &gFontSmall[index], char_width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI_DisplayFrequency(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero, bool bFlag)
|
void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center)
|
||||||
{
|
{
|
||||||
const unsigned int char_width = 13;
|
const unsigned int char_width = 13;
|
||||||
uint8_t *pFb0 = gFrameBuffer[Y] + X;
|
uint8_t *pFb0 = gFrameBuffer[Y] + X;
|
||||||
uint8_t *pFb1 = pFb0 + 128;
|
uint8_t *pFb1 = pFb0 + 128;
|
||||||
bool bCanDisplay = false;
|
bool bCanDisplay = false;
|
||||||
unsigned int i = 0;
|
|
||||||
|
|
||||||
// MHz
|
uint8_t len = strlen(string);
|
||||||
while (i < 3)
|
for(int i = 0; i < len; i++) {
|
||||||
{
|
char c = string[i];
|
||||||
const unsigned int Digit = pDigits[i++];
|
if(c=='-') c = '9' + 1;
|
||||||
if (bDisplayLeadingZero || bCanDisplay || Digit > 0)
|
if (bCanDisplay || c != ' ')
|
||||||
{
|
{
|
||||||
bCanDisplay = true;
|
bCanDisplay = true;
|
||||||
memmove(pFb0, gFontBigDigits[Digit], char_width);
|
if(c>='0' && c<='9' + 1) {
|
||||||
memmove(pFb1, gFontBigDigits[Digit] + char_width, char_width);
|
memcpy(pFb0 + 2, gFontBigDigits[c-'0'], char_width - 3);
|
||||||
|
memcpy(pFb1 + 2, gFontBigDigits[c-'0'] + char_width - 3, char_width - 3);
|
||||||
|
}
|
||||||
|
else if(c=='.') {
|
||||||
|
*pFb1 = 0x60; pFb0++; pFb1++;
|
||||||
|
*pFb1 = 0x60; pFb0++; pFb1++;
|
||||||
|
*pFb1 = 0x60; pFb0++; pFb1++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else if (center) {
|
||||||
if (bFlag)
|
|
||||||
{
|
|
||||||
pFb0 -= 6;
|
pFb0 -= 6;
|
||||||
pFb1 -= 6;
|
pFb1 -= 6;
|
||||||
}
|
}
|
||||||
pFb0 += char_width;
|
pFb0 += char_width;
|
||||||
pFb1 += char_width;
|
pFb1 += char_width;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// decimal point
|
void UI_DrawPixelBuffer(uint8_t (*buffer)[128], uint8_t x, uint8_t y, bool black)
|
||||||
*pFb1 = 0x60; pFb0++; pFb1++;
|
{
|
||||||
*pFb1 = 0x60; pFb0++; pFb1++;
|
const uint8_t pattern = 1 << (y % 8);
|
||||||
*pFb1 = 0x60; pFb0++; pFb1++;
|
if(black)
|
||||||
|
buffer[y/8][x] |= pattern;
|
||||||
|
else
|
||||||
|
buffer[y/8][x] &= ~pattern;
|
||||||
|
}
|
||||||
|
|
||||||
// kHz
|
static void sort(int16_t *a, int16_t *b)
|
||||||
while (i < 6)
|
{
|
||||||
{
|
if(*a > *b) {
|
||||||
const unsigned int Digit = pDigits[i++];
|
int16_t t = *a;
|
||||||
memmove(pFb0, gFontBigDigits[Digit], char_width);
|
*a = *b;
|
||||||
memmove(pFb1, gFontBigDigits[Digit] + char_width, char_width);
|
*b = t;
|
||||||
pFb0 += char_width;
|
|
||||||
pFb1 += char_width;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI_DisplayFrequencySmall(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero)
|
void UI_DrawLineBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black)
|
||||||
{
|
{
|
||||||
const unsigned int char_width = ARRAY_SIZE(gFontSmall[0]);
|
if(x2==x1) {
|
||||||
const unsigned int spacing = 1 + char_width;
|
sort(&y1, &y2);
|
||||||
uint8_t *pFb = gFrameBuffer[Y] + X;
|
for(int16_t i = y1; i <= y2; i++) {
|
||||||
bool bCanDisplay = false;
|
UI_DrawPixelBuffer(buffer, x1, i, black);
|
||||||
unsigned int i = 0;
|
|
||||||
|
|
||||||
// MHz
|
|
||||||
while (i < 3)
|
|
||||||
{
|
|
||||||
const unsigned int c = pDigits[i++];
|
|
||||||
if (bDisplayLeadingZero || bCanDisplay || c > 0)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
memmove(pFb + 1, gFontSmallDigits[c], char_width);
|
|
||||||
#else
|
|
||||||
const unsigned int index = (c < 10) ? '0' - 32 + c : '-' - 32;
|
|
||||||
memmove(pFb + 1, gFontSmall[index], char_width);
|
|
||||||
#endif
|
|
||||||
pFb += spacing;
|
|
||||||
bCanDisplay = true;
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
const int multipl = 1000;
|
||||||
|
int a = (y2-y1)*multipl / (x2-x1);
|
||||||
|
int b = y1 - a * x1 / multipl;
|
||||||
|
|
||||||
// decimal point
|
sort(&x1, &x2);
|
||||||
pFb++;
|
for(int i = x1; i<= x2; i++)
|
||||||
pFb++;
|
|
||||||
*pFb++ = 0x60;
|
|
||||||
*pFb++ = 0x60;
|
|
||||||
pFb++;
|
|
||||||
|
|
||||||
// kHz
|
|
||||||
while (i < 8)
|
|
||||||
{
|
|
||||||
const unsigned int c = pDigits[i++];
|
|
||||||
#if 0
|
|
||||||
memmove(pFb + 1, gFontSmallDigits[c], char_width);
|
|
||||||
#else
|
|
||||||
const unsigned int index = (c < 10) ? '0' - 32 + c : '-' - 32;
|
|
||||||
memmove(pFb + 1, gFontSmall[index], char_width);
|
|
||||||
#endif
|
|
||||||
pFb += spacing;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UI_DisplaySmallDigits(const uint8_t size, const char *str, const uint8_t x, const uint8_t y, const bool display_leading_zeros)
|
|
||||||
{
|
|
||||||
const unsigned int char_width = ARRAY_SIZE(gFontSmall[0]);
|
|
||||||
const unsigned int spacing = 1 + char_width;
|
|
||||||
bool display = display_leading_zeros;
|
|
||||||
unsigned int xx;
|
|
||||||
unsigned int i;
|
|
||||||
for (i = 0, xx = x; i < size; i++)
|
|
||||||
{
|
|
||||||
const unsigned int c = (unsigned int)str[i];
|
|
||||||
if (c > 0)
|
|
||||||
display = true; // non '0'
|
|
||||||
if (display && c < 11)
|
|
||||||
{
|
{
|
||||||
#if 0
|
UI_DrawPixelBuffer(buffer, i, i*a/multipl +b, black);
|
||||||
memmove(gFrameBuffer[y] + xx, gFontSmallDigits[c], char_width);
|
|
||||||
#else
|
|
||||||
const unsigned int index = (c < 10) ? '0' - 32 + c : '-' - 32;
|
|
||||||
memmove(gFrameBuffer[y] + xx + 1, gFontSmall[index], char_width);
|
|
||||||
#endif
|
|
||||||
xx += spacing;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UI_DrawRectangleBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black)
|
||||||
|
{
|
||||||
|
UI_DrawLineBuffer(buffer, x1,y1, x1,y2, black);
|
||||||
|
UI_DrawLineBuffer(buffer, x1,y1, x2,y1, black);
|
||||||
|
UI_DrawLineBuffer(buffer, x2,y1, x2,y2, black);
|
||||||
|
UI_DrawLineBuffer(buffer, x1,y2, x2,y2, black);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UI_DisplayPopup(const char *string)
|
||||||
|
{
|
||||||
|
for(uint8_t i = 0; i < 7; i++) {
|
||||||
|
memset(gFrameBuffer[i], 0x00, 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for(uint8_t i = 1; i < 5; i++) {
|
||||||
|
// memset(gFrameBuffer[i]+8, 0x00, 111);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for(uint8_t x = 10; x < 118; x++) {
|
||||||
|
// UI_DrawPixelBuffer(x, 10, true);
|
||||||
|
// UI_DrawPixelBuffer(x, 46-9, true);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for(uint8_t y = 11; y < 37; y++) {
|
||||||
|
// UI_DrawPixelBuffer(10, y, true);
|
||||||
|
// UI_DrawPixelBuffer(117, y, true);
|
||||||
|
// }
|
||||||
|
// DrawRectangle(9,9, 118,38, true);
|
||||||
|
UI_PrintString(string, 9, 118, 2, 8);
|
||||||
|
UI_PrintStringSmall("Press EXIT", 9, 118, 6);
|
||||||
|
}
|
||||||
11
ui/helper.h
11
ui/helper.h
@@ -28,9 +28,12 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_
|
|||||||
void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line);
|
void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line);
|
||||||
#endif
|
#endif
|
||||||
void UI_PrintStringSmallBuffer(const char *pString, uint8_t *buffer);
|
void UI_PrintStringSmallBuffer(const char *pString, uint8_t *buffer);
|
||||||
void UI_DisplayFrequency(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero, bool bFlag);
|
void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center);
|
||||||
void UI_DisplayFrequencySmall(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero);
|
|
||||||
void UI_DisplaySmallDigits(const uint8_t size, const char *str, const uint8_t x, const uint8_t y, const bool display_leading_zeros);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void UI_DisplayPopup(const char *string);
|
||||||
|
|
||||||
|
void UI_DrawPixelBuffer(uint8_t (*buffer)[128], uint8_t x, uint8_t y, bool black);
|
||||||
|
void UI_DrawLineBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black);
|
||||||
|
void UI_DrawRectangleBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black);
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "ui/inputbox.h"
|
#include "ui/inputbox.h"
|
||||||
|
|
||||||
char gInputBox[8];
|
char gInputBox[8];
|
||||||
|
char inputBoxAscii[9];
|
||||||
uint8_t gInputBoxIndex;
|
uint8_t gInputBoxIndex;
|
||||||
|
|
||||||
void INPUTBOX_Append(const KEY_Code_t Digit)
|
void INPUTBOX_Append(const KEY_Code_t Digit)
|
||||||
@@ -29,7 +30,15 @@ void INPUTBOX_Append(const KEY_Code_t Digit)
|
|||||||
if (gInputBoxIndex == 0)
|
if (gInputBoxIndex == 0)
|
||||||
memset(gInputBox, 10, sizeof(gInputBox));
|
memset(gInputBox, 10, sizeof(gInputBox));
|
||||||
|
|
||||||
if (Digit >= KEY_0 && Digit != KEY_INVALID)
|
if (Digit != KEY_INVALID)
|
||||||
gInputBox[gInputBoxIndex++] = (char)(Digit - KEY_0);
|
gInputBox[gInputBoxIndex++] = (char)(Digit - KEY_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* INPUTBOX_GetAscii()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 8; i++) {
|
||||||
|
char c = gInputBox[i];
|
||||||
|
inputBoxAscii[i] = (c==10)? '-' : '0' + c;
|
||||||
|
}
|
||||||
|
return inputBoxAscii;
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ extern char gInputBox[8];
|
|||||||
extern uint8_t gInputBoxIndex;
|
extern uint8_t gInputBoxIndex;
|
||||||
|
|
||||||
void INPUTBOX_Append(const KEY_Code_t Digit);
|
void INPUTBOX_Append(const KEY_Code_t Digit);
|
||||||
|
const char* INPUTBOX_GetAscii();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -102,10 +102,9 @@ void UI_DisplayLock(void)
|
|||||||
uint32_t Password;
|
uint32_t Password;
|
||||||
|
|
||||||
gInputBoxIndex = 0;
|
gInputBoxIndex = 0;
|
||||||
|
Password = StrToUL(INPUTBOX_GetAscii());
|
||||||
|
|
||||||
NUMBER_Get(gInputBox, &Password);
|
if ((gEeprom.POWER_ON_PASSWORD) == Password)
|
||||||
|
|
||||||
if ((gEeprom.POWER_ON_PASSWORD * 100) == Password)
|
|
||||||
{
|
{
|
||||||
AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL);
|
AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL);
|
||||||
return;
|
return;
|
||||||
@@ -144,13 +143,14 @@ void UI_DisplayLock(void)
|
|||||||
gKeyReading0 = Key;
|
gKeyReading0 = Key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_UART
|
||||||
if (UART_IsCommandAvailable())
|
if (UART_IsCommandAvailable())
|
||||||
{
|
{
|
||||||
__disable_irq();
|
__disable_irq();
|
||||||
UART_HandleCommand();
|
UART_HandleCommand();
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (gUpdateDisplay)
|
if (gUpdateDisplay)
|
||||||
{
|
{
|
||||||
Render();
|
Render();
|
||||||
|
|||||||
11
ui/main.h
11
ui/main.h
@@ -26,13 +26,20 @@ enum center_line_t {
|
|||||||
CENTER_LINE_DTMF_DEC,
|
CENTER_LINE_DTMF_DEC,
|
||||||
CENTER_LINE_CHARGE_DATA
|
CENTER_LINE_CHARGE_DATA
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Vfo_txtr_mode{
|
||||||
|
VFO_MODE_NONE = 0,
|
||||||
|
VFO_MODE_TX = 1,
|
||||||
|
VFO_MODE_RX = 2,
|
||||||
|
};
|
||||||
|
|
||||||
typedef enum center_line_t center_line_t;
|
typedef enum center_line_t center_line_t;
|
||||||
|
|
||||||
extern center_line_t center_line;
|
extern center_line_t center_line;
|
||||||
|
extern const int8_t dBmCorrTable[7];
|
||||||
|
|
||||||
void UI_DisplayAudioBar(void);
|
void UI_DisplayAudioBar(void);
|
||||||
void UI_UpdateRSSI(const int16_t rssi, const int vfo);
|
void UI_MAIN_TimeSlice500ms(void);
|
||||||
void UI_DisplayMain(void);
|
void UI_DisplayMain(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
526
ui/menu.c
526
ui/menu.c
@@ -36,133 +36,141 @@
|
|||||||
#include "ui/menu.h"
|
#include "ui/menu.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
|
||||||
// NOTE. this menu list is half way through a change, what might seem
|
|
||||||
// pointless at this time is for there for a reason.
|
|
||||||
//
|
|
||||||
const t_menu_item MenuList[] =
|
const t_menu_item MenuList[] =
|
||||||
{
|
{
|
||||||
// text, voice ID, menu ID
|
// text, voice ID, menu ID
|
||||||
|
{"Step", VOICE_ID_FREQUENCY_STEP, MENU_STEP },
|
||||||
{"SQL", VOICE_ID_SQUELCH, MENU_SQL },
|
{"TxPwr", VOICE_ID_POWER, MENU_TXP }, // was "TXP"
|
||||||
{"STEP", VOICE_ID_FREQUENCY_STEP, MENU_STEP },
|
{"RxDCS", VOICE_ID_DCS, MENU_R_DCS }, // was "R_DCS"
|
||||||
{"T PWR", VOICE_ID_POWER, MENU_TXP }, // was "TXP"
|
{"RxCTCS", VOICE_ID_CTCSS, MENU_R_CTCS }, // was "R_CTCS"
|
||||||
{"R DCS", VOICE_ID_DCS, MENU_R_DCS }, // was "R_DCS"
|
{"TxDCS", VOICE_ID_DCS, MENU_T_DCS }, // was "T_DCS"
|
||||||
{"R CTCS", VOICE_ID_CTCSS, MENU_R_CTCS }, // was "R_CTCS"
|
{"TxCTCS", VOICE_ID_CTCSS, MENU_T_CTCS }, // was "T_CTCS"
|
||||||
{"T DCS", VOICE_ID_DCS, MENU_T_DCS }, // was "T_DCS"
|
{"TxODir", VOICE_ID_TX_OFFSET_FREQUENCY_DIRECTION, MENU_SFT_D }, // was "SFT_D"
|
||||||
{"T CTCS", VOICE_ID_CTCSS, MENU_T_CTCS }, // was "T_CTCS"
|
{"TxOffs", VOICE_ID_TX_OFFSET_FREQUENCY, MENU_OFFSET }, // was "OFFSET"
|
||||||
{"T DIR", VOICE_ID_TX_OFFSET_FREQUENCY_DIRECTION, MENU_SFT_D }, // was "SFT_D"
|
|
||||||
{"T OFFS", VOICE_ID_TX_OFFSET_FREQUENCY, MENU_OFFSET }, // was "OFFSET"
|
|
||||||
{"T VFO", VOICE_ID_INVALID, MENU_XB }, // was "WX"
|
|
||||||
{"T TOUT", VOICE_ID_TRANSMIT_OVER_TIME, MENU_TOT }, // was "TOT"
|
|
||||||
{"W/N", VOICE_ID_CHANNEL_BANDWIDTH, MENU_W_N },
|
{"W/N", VOICE_ID_CHANNEL_BANDWIDTH, MENU_W_N },
|
||||||
{"SCRAM", VOICE_ID_SCRAMBLER_ON, MENU_SCR }, // was "SCR"
|
{"Scramb", VOICE_ID_SCRAMBLER_ON, MENU_SCR }, // was "SCR"
|
||||||
{"BUSYCL", VOICE_ID_BUSY_LOCKOUT, MENU_BCL }, // was "BCL"
|
{"BusyCL", VOICE_ID_BUSY_LOCKOUT, MENU_BCL }, // was "BCL"
|
||||||
{"CH SAV", VOICE_ID_MEMORY_CHANNEL, MENU_MEM_CH }, // was "MEM-CH"
|
{"Compnd", VOICE_ID_INVALID, MENU_COMPAND },
|
||||||
{"CH DEL", VOICE_ID_DELETE_CHANNEL, MENU_DEL_CH }, // was "DEL-CH"
|
{"Demodu", VOICE_ID_INVALID, MENU_AM }, // was "AM"
|
||||||
{"CH NAM", VOICE_ID_INVALID, MENU_MEM_NAME },
|
{"ScAdd1", VOICE_ID_INVALID, MENU_S_ADD1 },
|
||||||
{"CH DIS", VOICE_ID_INVALID, MENU_MDF }, // was "MDF"
|
{"ScAdd2", VOICE_ID_INVALID, MENU_S_ADD2 },
|
||||||
{"BATSAV", VOICE_ID_SAVE_MODE, MENU_SAVE }, // was "SAVE"
|
{"ChSave", VOICE_ID_MEMORY_CHANNEL, MENU_MEM_CH }, // was "MEM-CH"
|
||||||
#ifdef ENABLE_VOX
|
{"ChDele", VOICE_ID_DELETE_CHANNEL, MENU_DEL_CH }, // was "DEL-CH"
|
||||||
{"VOX", VOICE_ID_VOX, MENU_VOX },
|
{"ChName", VOICE_ID_INVALID, MENU_MEM_NAME },
|
||||||
#endif
|
|
||||||
{"BLT", VOICE_ID_INVALID, MENU_ABR }, // was "ABR"
|
{"SList", VOICE_ID_INVALID, MENU_S_LIST },
|
||||||
{"BLTTRX", VOICE_ID_INVALID, MENU_ABR_ON_TX_RX },
|
{"SList1", VOICE_ID_INVALID, MENU_SLIST1 },
|
||||||
{"DUALRX", VOICE_ID_DUAL_STANDBY, MENU_TDR }, // was "TDR"
|
{"SList2", VOICE_ID_INVALID, MENU_SLIST2 },
|
||||||
{"BEEP", VOICE_ID_BEEP_PROMPT, MENU_BEEP },
|
{"ScnRev", VOICE_ID_INVALID, MENU_SC_REV },
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
{"VOICE", VOICE_ID_VOICE_PROMPT, MENU_VOICE },
|
|
||||||
#endif
|
|
||||||
{"SC REV", VOICE_ID_INVALID, MENU_SC_REV },
|
|
||||||
{"KEYLOC", VOICE_ID_INVALID, MENU_AUTOLK }, // was "AUTOLk"
|
|
||||||
{"S ADD1", VOICE_ID_INVALID, MENU_S_ADD1 },
|
|
||||||
{"S ADD2", VOICE_ID_INVALID, MENU_S_ADD2 },
|
|
||||||
{"STE", VOICE_ID_INVALID, MENU_STE },
|
|
||||||
{"RP STE", VOICE_ID_INVALID, MENU_RP_STE },
|
|
||||||
{"MIC", VOICE_ID_INVALID, MENU_MIC },
|
|
||||||
#ifdef ENABLE_AUDIO_BAR
|
|
||||||
{"MICBAR", VOICE_ID_INVALID, MENU_MIC_BAR },
|
|
||||||
#endif
|
|
||||||
{"COMPND", VOICE_ID_INVALID, MENU_COMPAND },
|
|
||||||
{"1 CALL", VOICE_ID_INVALID, MENU_1_CALL },
|
|
||||||
{"SLIST", VOICE_ID_INVALID, MENU_S_LIST },
|
|
||||||
{"SLIST1", VOICE_ID_INVALID, MENU_SLIST1 },
|
|
||||||
{"SLIST2", VOICE_ID_INVALID, MENU_SLIST2 },
|
|
||||||
#ifdef ENABLE_ALARM
|
|
||||||
{"AL-MOD", VOICE_ID_INVALID, MENU_AL_MOD },
|
|
||||||
#endif
|
|
||||||
{"ANI ID", VOICE_ID_ANI_CODE, MENU_ANI_ID },
|
|
||||||
{"UPCODE", VOICE_ID_INVALID, MENU_UPCODE },
|
|
||||||
{"DWCODE", VOICE_ID_INVALID, MENU_DWCODE },
|
|
||||||
{"PTT ID", VOICE_ID_INVALID, MENU_PTT_ID },
|
|
||||||
{"D ST", VOICE_ID_INVALID, MENU_D_ST },
|
|
||||||
{"D RSP", VOICE_ID_INVALID, MENU_D_RSP },
|
|
||||||
{"D HOLD", VOICE_ID_INVALID, MENU_D_HOLD },
|
|
||||||
{"D PRE", VOICE_ID_INVALID, MENU_D_PRE },
|
|
||||||
{"D DCD", VOICE_ID_INVALID, MENU_D_DCD },
|
|
||||||
{"D LIST", VOICE_ID_INVALID, MENU_D_LIST },
|
|
||||||
{"D LIVE", VOICE_ID_INVALID, MENU_D_LIVE_DEC }, // live DTMF decoder
|
|
||||||
{"PONMSG", VOICE_ID_INVALID, MENU_PONMSG },
|
|
||||||
{"ROGER", VOICE_ID_INVALID, MENU_ROGER },
|
|
||||||
{"BATVOL", VOICE_ID_INVALID, MENU_VOL }, // was "VOL"
|
|
||||||
{"BATTXT", VOICE_ID_INVALID, MENU_BAT_TXT },
|
|
||||||
{"MODE", VOICE_ID_INVALID, MENU_AM }, // was "AM"
|
|
||||||
#ifdef ENABLE_AM_FIX
|
|
||||||
{"AM FIX", VOICE_ID_INVALID, MENU_AM_FIX },
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_AM_FIX_TEST1
|
|
||||||
{"AM FT1", VOICE_ID_INVALID, MENU_AM_FIX_TEST1 },
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
{"NOAA-S", VOICE_ID_INVALID, MENU_NOAA_S },
|
{"NOAA-S", VOICE_ID_INVALID, MENU_NOAA_S },
|
||||||
#endif
|
#endif
|
||||||
{"RESET", VOICE_ID_INITIALISATION, MENU_RESET }, // might be better to move this to the hidden menu items ?
|
|
||||||
|
{"F1Shrt", VOICE_ID_INVALID, MENU_F1SHRT },
|
||||||
|
{"F1Long", VOICE_ID_INVALID, MENU_F1LONG },
|
||||||
|
{"F2Shrt", VOICE_ID_INVALID, MENU_F2SHRT },
|
||||||
|
{"F2Long", VOICE_ID_INVALID, MENU_F2LONG },
|
||||||
|
{"M Long", VOICE_ID_INVALID, MENU_MLONG },
|
||||||
|
|
||||||
|
{"KeyLck", VOICE_ID_INVALID, MENU_AUTOLK }, // was "AUTOLk"
|
||||||
|
{"TxTOut", VOICE_ID_TRANSMIT_OVER_TIME, MENU_TOT }, // was "TOT"
|
||||||
|
{"BatSav", VOICE_ID_SAVE_MODE, MENU_SAVE }, // was "SAVE"
|
||||||
|
{"Mic", VOICE_ID_INVALID, MENU_MIC },
|
||||||
|
#ifdef ENABLE_AUDIO_BAR
|
||||||
|
{"MicBar", VOICE_ID_INVALID, MENU_MIC_BAR },
|
||||||
|
#endif
|
||||||
|
{"ChDisp", VOICE_ID_INVALID, MENU_MDF }, // was "MDF"
|
||||||
|
{"POnMsg", VOICE_ID_INVALID, MENU_PONMSG },
|
||||||
|
{"BatTxt", VOICE_ID_INVALID, MENU_BAT_TXT },
|
||||||
|
{"BackLt", VOICE_ID_INVALID, MENU_ABR }, // was "ABR"
|
||||||
|
{"BLMin", VOICE_ID_INVALID, MENU_ABR_MIN },
|
||||||
|
{"BLMax", VOICE_ID_INVALID, MENU_ABR_MAX },
|
||||||
|
{"BltTRX", VOICE_ID_INVALID, MENU_ABR_ON_TX_RX },
|
||||||
|
{"Beep", VOICE_ID_BEEP_PROMPT, MENU_BEEP },
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
{"Voice", VOICE_ID_VOICE_PROMPT, MENU_VOICE },
|
||||||
|
#endif
|
||||||
|
{"Roger", VOICE_ID_INVALID, MENU_ROGER },
|
||||||
|
{"STE", VOICE_ID_INVALID, MENU_STE },
|
||||||
|
{"RP STE", VOICE_ID_INVALID, MENU_RP_STE },
|
||||||
|
{"1 Call", VOICE_ID_INVALID, MENU_1_CALL },
|
||||||
|
#ifdef ENABLE_ALARM
|
||||||
|
{"AlarmT", VOICE_ID_INVALID, MENU_AL_MOD },
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
{"ANI ID", VOICE_ID_ANI_CODE, MENU_ANI_ID },
|
||||||
|
#endif
|
||||||
|
{"UPCode", VOICE_ID_INVALID, MENU_UPCODE },
|
||||||
|
{"DWCode", VOICE_ID_INVALID, MENU_DWCODE },
|
||||||
|
{"PTT ID", VOICE_ID_INVALID, MENU_PTT_ID },
|
||||||
|
{"D ST", VOICE_ID_INVALID, MENU_D_ST },
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
{"D Resp", VOICE_ID_INVALID, MENU_D_RSP },
|
||||||
|
{"D Hold", VOICE_ID_INVALID, MENU_D_HOLD },
|
||||||
|
#endif
|
||||||
|
{"D Prel", VOICE_ID_INVALID, MENU_D_PRE },
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
{"D Decd", VOICE_ID_INVALID, MENU_D_DCD },
|
||||||
|
{"D List", VOICE_ID_INVALID, MENU_D_LIST },
|
||||||
|
#endif
|
||||||
|
{"D Live", VOICE_ID_INVALID, MENU_D_LIVE_DEC }, // live DTMF decoder
|
||||||
|
#ifdef ENABLE_AM_FIX
|
||||||
|
{"AM Fix", VOICE_ID_INVALID, MENU_AM_FIX },
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_VOX
|
||||||
|
{"VOX", VOICE_ID_VOX, MENU_VOX },
|
||||||
|
#endif
|
||||||
|
{"BatVol", VOICE_ID_INVALID, MENU_VOL }, // was "VOL"
|
||||||
|
{"RxMode", VOICE_ID_DUAL_STANDBY, MENU_TDR },
|
||||||
|
{"Sql", VOICE_ID_SQUELCH, MENU_SQL },
|
||||||
|
|
||||||
// hidden menu items from here on
|
// hidden menu items from here on
|
||||||
// enabled if pressing both the PTT and upper side button at power-on
|
// enabled if pressing both the PTT and upper side button at power-on
|
||||||
|
{"F Lock", VOICE_ID_INVALID, MENU_F_LOCK },
|
||||||
{"F LOCK", VOICE_ID_INVALID, MENU_F_LOCK },
|
{"Tx 200", VOICE_ID_INVALID, MENU_200TX }, // was "200TX"
|
||||||
{"TX 200", VOICE_ID_INVALID, MENU_200TX }, // was "200TX"
|
{"Tx 350", VOICE_ID_INVALID, MENU_350TX }, // was "350TX"
|
||||||
{"TX 350", VOICE_ID_INVALID, MENU_350TX }, // was "350TX"
|
{"Tx 500", VOICE_ID_INVALID, MENU_500TX }, // was "500TX"
|
||||||
{"TX 500", VOICE_ID_INVALID, MENU_500TX }, // was "500TX"
|
{"350 En", VOICE_ID_INVALID, MENU_350EN }, // was "350EN"
|
||||||
{"350 EN", VOICE_ID_INVALID, MENU_350EN }, // was "350EN"
|
{"ScraEn", VOICE_ID_INVALID, MENU_SCREN }, // was "SCREN"
|
||||||
{"SCR EN", VOICE_ID_INVALID, MENU_SCREN }, // was "SCREN"
|
|
||||||
|
|
||||||
{"TX EN", VOICE_ID_INVALID, MENU_TX_EN }, // enable TX
|
|
||||||
#ifdef ENABLE_F_CAL_MENU
|
#ifdef ENABLE_F_CAL_MENU
|
||||||
{"F CALI", VOICE_ID_INVALID, MENU_F_CALI }, // reference xtal calibration
|
{"FrCali", VOICE_ID_INVALID, MENU_F_CALI }, // reference xtal calibration
|
||||||
#endif
|
#endif
|
||||||
{"BATCAL", VOICE_ID_INVALID, MENU_BATCAL }, // battery voltage calibration
|
{"BatCal", VOICE_ID_INVALID, MENU_BATCAL }, // battery voltage calibration
|
||||||
|
{"BatTyp", VOICE_ID_INVALID, MENU_BATTYP }, // battery type 1600/2200mAh
|
||||||
|
{"Reset", VOICE_ID_INITIALISATION, MENU_RESET }, // might be better to move this to the hidden menu items ?
|
||||||
|
|
||||||
{"", VOICE_ID_INVALID, 0xff } // end of list - DO NOT delete or move this this
|
{"", VOICE_ID_INVALID, 0xff } // end of list - DO NOT delete or move this this
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_TXP[3][5] =
|
const uint8_t FIRST_HIDDEN_MENU_ITEM = MENU_F_LOCK;
|
||||||
|
|
||||||
|
const char gSubMenu_TXP[][5] =
|
||||||
{
|
{
|
||||||
"LOW",
|
"LOW",
|
||||||
"MID",
|
"MID",
|
||||||
"HIGH"
|
"HIGH"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_SFT_D[3][4] =
|
const char gSubMenu_SFT_D[][4] =
|
||||||
{
|
{
|
||||||
"OFF",
|
"OFF",
|
||||||
"+",
|
"+",
|
||||||
"-"
|
"-"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_W_N[2][7] =
|
const char gSubMenu_W_N[][7] =
|
||||||
{
|
{
|
||||||
"WIDE",
|
"WIDE",
|
||||||
"NARROW"
|
"NARROW"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_OFF_ON[2][4] =
|
const char gSubMenu_OFF_ON[][4] =
|
||||||
{
|
{
|
||||||
"OFF",
|
"OFF",
|
||||||
"ON"
|
"ON"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_SAVE[5][4] =
|
const char gSubMenu_SAVE[][4] =
|
||||||
{
|
{
|
||||||
"OFF",
|
"OFF",
|
||||||
"1:1",
|
"1:1",
|
||||||
@@ -171,7 +179,7 @@ const char gSubMenu_SAVE[5][4] =
|
|||||||
"1:4"
|
"1:4"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_TOT[11][7] =
|
const char gSubMenu_TOT[][7] =
|
||||||
{
|
{
|
||||||
"30 sec",
|
"30 sec",
|
||||||
"1 min",
|
"1 min",
|
||||||
@@ -186,22 +194,16 @@ const char gSubMenu_TOT[11][7] =
|
|||||||
"15 min"
|
"15 min"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_CHAN[3][10] =
|
const char* gSubMenu_RXMode[] =
|
||||||
{
|
{
|
||||||
"OFF",
|
"MAIN\nONLY", // TX and RX on main only
|
||||||
"UPPER\nVFO",
|
"DUAL RX\nRESPOND", // Watch both and respond
|
||||||
"LOWER\nVFO"
|
"CROSS\nBAND", // TX on main, RX on secondary
|
||||||
};
|
"MAIN TX\nDUAL RX" // always TX on main, but RX on both
|
||||||
|
|
||||||
const char gSubMenu_XB[3][10] =
|
|
||||||
{
|
|
||||||
"RX\nVFO",
|
|
||||||
"UPPER\nVFO",
|
|
||||||
"LOWER\nVFO"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
const char gSubMenu_VOICE[3][4] =
|
const char gSubMenu_VOICE[][4] =
|
||||||
{
|
{
|
||||||
"OFF",
|
"OFF",
|
||||||
"CHI",
|
"CHI",
|
||||||
@@ -209,14 +211,14 @@ const char gSubMenu_XB[3][10] =
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char gSubMenu_SC_REV[3][13] =
|
const char gSubMenu_SC_REV[][8] =
|
||||||
{
|
{
|
||||||
"TIME",
|
"TIMEOUT",
|
||||||
"CARRIER",
|
"CARRIER",
|
||||||
"SEARCH"
|
"STOP"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_MDF[4][15] =
|
const char* gSubMenu_MDF[] =
|
||||||
{
|
{
|
||||||
"FREQ",
|
"FREQ",
|
||||||
"CHANNEL\nNUMBER",
|
"CHANNEL\nNUMBER",
|
||||||
@@ -225,31 +227,33 @@ const char gSubMenu_MDF[4][15] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ENABLE_ALARM
|
#ifdef ENABLE_ALARM
|
||||||
const char gSubMenu_AL_MOD[2][5] =
|
const char gSubMenu_AL_MOD[][5] =
|
||||||
{
|
{
|
||||||
"SITE",
|
"SITE",
|
||||||
"TONE"
|
"TONE"
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char gSubMenu_D_RSP[4][11] =
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
const char gSubMenu_D_RSP[][11] =
|
||||||
{
|
{
|
||||||
"DO\nNOTHING",
|
"DO\nNOTHING",
|
||||||
"RING",
|
"RING",
|
||||||
"REPLY",
|
"REPLY",
|
||||||
"BOTH"
|
"BOTH"
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
const char gSubMenu_PTT_ID[5][15] =
|
const char* gSubMenu_PTT_ID[] =
|
||||||
{
|
{
|
||||||
"OFF",
|
"OFF",
|
||||||
"KEY\nUP",
|
"UP CODE",
|
||||||
"KEY\nDOWN",
|
"DOWN CODE",
|
||||||
"KEY\nUP+DOWN",
|
"UP+DOWN\nCODE",
|
||||||
"APOLLO\nQUINDAR"
|
"APOLLO\nQUINDAR"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_PONMSG[4][8] =
|
const char gSubMenu_PONMSG[][8] =
|
||||||
{
|
{
|
||||||
"FULL",
|
"FULL",
|
||||||
"MESSAGE",
|
"MESSAGE",
|
||||||
@@ -257,30 +261,32 @@ const char gSubMenu_PONMSG[4][8] =
|
|||||||
"NONE"
|
"NONE"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_ROGER[3][9] =
|
const char gSubMenu_ROGER[][6] =
|
||||||
{
|
{
|
||||||
"OFF",
|
"OFF",
|
||||||
"ROGER",
|
"ROGER",
|
||||||
"MDC\n1200"
|
"MDC"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_RESET[2][4] =
|
const char gSubMenu_RESET[][4] =
|
||||||
{
|
{
|
||||||
"VFO",
|
"VFO",
|
||||||
"ALL"
|
"ALL"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_F_LOCK[6][4] =
|
const char * gSubMenu_F_LOCK[] =
|
||||||
{
|
{
|
||||||
"OFF",
|
"DEFAULT+\n137-174\n400-470",
|
||||||
"FCC",
|
"FCC HAM\n144-148\n420-450",
|
||||||
"CE",
|
"CE HAM\n144-146\n430-440",
|
||||||
"GB",
|
"GB HAM\n144-148\n430-440",
|
||||||
"430",
|
"137-174\n400-430",
|
||||||
"438"
|
"137-174\n400-438",
|
||||||
|
"DISABLE\nALL",
|
||||||
|
"UNLOCK\nALL",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_BACKLIGHT[8][7] =
|
const char gSubMenu_BACKLIGHT[][7] =
|
||||||
{
|
{
|
||||||
"OFF",
|
"OFF",
|
||||||
"5 sec",
|
"5 sec",
|
||||||
@@ -292,7 +298,7 @@ const char gSubMenu_BACKLIGHT[8][7] =
|
|||||||
"ON"
|
"ON"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_RX_TX[4][6] =
|
const char gSubMenu_RX_TX[][6] =
|
||||||
{
|
{
|
||||||
"OFF",
|
"OFF",
|
||||||
"TX",
|
"TX",
|
||||||
@@ -300,24 +306,20 @@ const char gSubMenu_RX_TX[4][6] =
|
|||||||
"TX/RX"
|
"TX/RX"
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX_TEST1
|
const char gSubMenu_BAT_TXT[][8] =
|
||||||
const char gSubMenu_AM_fix_test1[4][8] =
|
|
||||||
{
|
|
||||||
"LNA-S 0",
|
|
||||||
"LNA-S 1",
|
|
||||||
"LNA-S 2",
|
|
||||||
"LNA-S 3"
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char gSubMenu_BAT_TXT[3][8] =
|
|
||||||
{
|
{
|
||||||
"NONE",
|
"NONE",
|
||||||
"VOLTAGE",
|
"VOLTAGE",
|
||||||
"PERCENT"
|
"PERCENT"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char gSubMenu_SCRAMBLER[11][7] =
|
const char gSubMenu_BATTYP[][9] =
|
||||||
|
{
|
||||||
|
"1600mAh",
|
||||||
|
"2200mAh"
|
||||||
|
};
|
||||||
|
|
||||||
|
const char gSubMenu_SCRAMBLER[][7] =
|
||||||
{
|
{
|
||||||
"OFF",
|
"OFF",
|
||||||
"2600Hz",
|
"2600Hz",
|
||||||
@@ -332,9 +334,55 @@ const char gSubMenu_SCRAMBLER[11][7] =
|
|||||||
"3500Hz"
|
"3500Hz"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const t_sidefunction gSubMenu_SIDEFUNCTIONS[] =
|
||||||
|
{
|
||||||
|
{"NONE", ACTION_OPT_NONE},
|
||||||
|
#ifdef ENABLE_FLASHLIGHT
|
||||||
|
{"FLASH\nLIGHT", ACTION_OPT_FLASHLIGHT},
|
||||||
|
#endif
|
||||||
|
{"POWER", ACTION_OPT_POWER},
|
||||||
|
{"MONITOR", ACTION_OPT_MONITOR},
|
||||||
|
{"SCAN", ACTION_OPT_SCAN},
|
||||||
|
#ifdef ENABLE_VOX
|
||||||
|
{"VOX", ACTION_OPT_VOX},
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_ALARM
|
||||||
|
{"ALARM", ACTION_OPT_ALARM},
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_FMRADIO
|
||||||
|
{"FM RADIO", ACTION_OPT_FM},
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_TX1750
|
||||||
|
{"1750HZ", ACTION_OPT_1750},
|
||||||
|
#endif
|
||||||
|
{"LOCK\nKEYPAD", ACTION_OPT_KEYLOCK},
|
||||||
|
{"SWITCH\nVFO", ACTION_OPT_A_B},
|
||||||
|
{"VFO/MR", ACTION_OPT_VFO_MR},
|
||||||
|
{"SWITCH\nDEMODUL", ACTION_OPT_SWITCH_DEMODUL},
|
||||||
|
#ifdef ENABLE_BLMIN_TMP_OFF
|
||||||
|
{"BLMIN\nTMP OFF", ACTION_OPT_BLMIN_TMP_OFF}, //BackLight Minimum Temporay OFF
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t gSubMenu_SIDEFUNCTIONS_size = ARRAY_SIZE(gSubMenu_SIDEFUNCTIONS);
|
||||||
|
|
||||||
bool gIsInSubMenu;
|
bool gIsInSubMenu;
|
||||||
uint8_t gMenuCursor;
|
uint8_t gMenuCursor;
|
||||||
int8_t gMenuScrollDirection;
|
int UI_MENU_GetCurrentMenuId() {
|
||||||
|
if(gMenuCursor < ARRAY_SIZE(MenuList))
|
||||||
|
return MenuList[gMenuCursor].menu_id;
|
||||||
|
else
|
||||||
|
return MenuList[ARRAY_SIZE(MenuList)-1].menu_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t UI_MENU_GetMenuIdx(uint8_t id)
|
||||||
|
{
|
||||||
|
for(uint8_t i = 0; i < ARRAY_SIZE(MenuList); i++)
|
||||||
|
if(MenuList[i].menu_id == id)
|
||||||
|
return i;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t gSubMenuSelection;
|
int32_t gSubMenuSelection;
|
||||||
|
|
||||||
// edit box
|
// edit box
|
||||||
@@ -349,7 +397,10 @@ void UI_DisplayMenu(void)
|
|||||||
const unsigned int menu_item_x2 = LCD_WIDTH - 1;
|
const unsigned int menu_item_x2 = LCD_WIDTH - 1;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char String[64]; // bigger cuz we can now do multi-line in one string (use '\n' char)
|
char String[64]; // bigger cuz we can now do multi-line in one string (use '\n' char)
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
char Contact[16];
|
char Contact[16];
|
||||||
|
#endif
|
||||||
|
|
||||||
// clear the screen buffer
|
// clear the screen buffer
|
||||||
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
|
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
|
||||||
@@ -375,7 +426,7 @@ void UI_DisplayMenu(void)
|
|||||||
|
|
||||||
// draw the little sub-menu triangle marker
|
// draw the little sub-menu triangle marker
|
||||||
if (gIsInSubMenu)
|
if (gIsInSubMenu)
|
||||||
memmove(gFrameBuffer[0] + (8 * menu_list_width) + 1, BITMAP_CurrentIndicator, sizeof(BITMAP_CurrentIndicator));
|
memcpy(gFrameBuffer[0] + (8 * menu_list_width) + 1, BITMAP_CurrentIndicator, sizeof(BITMAP_CurrentIndicator));
|
||||||
|
|
||||||
// draw the menu index number/count
|
// draw the menu index number/count
|
||||||
sprintf(String, "%2u.%u", 1 + gMenuCursor, gMenuListCount);
|
sprintf(String, "%2u.%u", 1 + gMenuCursor, gMenuListCount);
|
||||||
@@ -437,10 +488,13 @@ void UI_DisplayMenu(void)
|
|||||||
|
|
||||||
bool already_printed = false;
|
bool already_printed = false;
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
/* Brightness is set to max in some entries of this menu. Return it to the configured brightness
|
||||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
|
level the "next" time we enter here.I.e., when we move from one menu to another.
|
||||||
|
It also has to be set back to max when pressing the Exit key. */
|
||||||
|
|
||||||
switch (gMenuCursor)
|
BACKLIGHT_TurnOn();
|
||||||
|
|
||||||
|
switch (UI_MENU_GetCurrentMenuId())
|
||||||
{
|
{
|
||||||
case MENU_SQL:
|
case MENU_SQL:
|
||||||
sprintf(String, "%d", gSubMenuSelection);
|
sprintf(String, "%d", gSubMenuSelection);
|
||||||
@@ -459,9 +513,11 @@ void UI_DisplayMenu(void)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case MENU_STEP:
|
case MENU_STEP: {
|
||||||
sprintf(String, "%d.%02ukHz", StepFrequencyTable[gSubMenuSelection] / 100, abs(StepFrequencyTable[gSubMenuSelection]) % 100);
|
uint16_t step = gStepFrequencyTable[FREQUENCY_GetStepIdxFromSortedIdx(gSubMenuSelection)];
|
||||||
|
sprintf(String, "%d.%02ukHz", step / 100, step % 100);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MENU_TXP:
|
case MENU_TXP:
|
||||||
strcpy(String, gSubMenu_TXP[gSubMenuSelection]);
|
strcpy(String, gSubMenu_TXP[gSubMenuSelection]);
|
||||||
@@ -471,8 +527,7 @@ void UI_DisplayMenu(void)
|
|||||||
case MENU_T_DCS:
|
case MENU_T_DCS:
|
||||||
if (gSubMenuSelection == 0)
|
if (gSubMenuSelection == 0)
|
||||||
strcpy(String, "OFF");
|
strcpy(String, "OFF");
|
||||||
else
|
else if (gSubMenuSelection < 105)
|
||||||
if (gSubMenuSelection < 105)
|
|
||||||
sprintf(String, "D%03oN", DCS_Options[gSubMenuSelection - 1]);
|
sprintf(String, "D%03oN", DCS_Options[gSubMenuSelection - 1]);
|
||||||
else
|
else
|
||||||
sprintf(String, "D%03oI", DCS_Options[gSubMenuSelection - 105]);
|
sprintf(String, "D%03oI", DCS_Options[gSubMenuSelection - 105]);
|
||||||
@@ -481,38 +536,10 @@ void UI_DisplayMenu(void)
|
|||||||
case MENU_R_CTCS:
|
case MENU_R_CTCS:
|
||||||
case MENU_T_CTCS:
|
case MENU_T_CTCS:
|
||||||
{
|
{
|
||||||
#if 1
|
if (gSubMenuSelection == 0)
|
||||||
unsigned int Code;
|
strcpy(String, "OFF");
|
||||||
FREQ_Config_t *pConfig = (gMenuCursor == MENU_R_CTCS) ? &gTxVfo->freq_config_RX : &gTxVfo->freq_config_TX;
|
else
|
||||||
if (gSubMenuSelection == 0)
|
sprintf(String, "%u.%uHz", CTCSS_Options[gSubMenuSelection - 1] / 10, CTCSS_Options[gSubMenuSelection - 1] % 10);
|
||||||
{
|
|
||||||
strcpy(String, "OFF");
|
|
||||||
|
|
||||||
if (pConfig->CodeType != CODE_TYPE_CONTINUOUS_TONE)
|
|
||||||
break;
|
|
||||||
Code = 0;
|
|
||||||
pConfig->CodeType = CODE_TYPE_OFF;
|
|
||||||
pConfig->Code = Code;
|
|
||||||
|
|
||||||
BK4819_ExitSubAu();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf(String, "%u.%uHz", CTCSS_Options[gSubMenuSelection - 1] / 10, CTCSS_Options[gSubMenuSelection - 1] % 10);
|
|
||||||
|
|
||||||
pConfig->CodeType = CODE_TYPE_CONTINUOUS_TONE;
|
|
||||||
Code = gSubMenuSelection - 1;
|
|
||||||
pConfig->Code = Code;
|
|
||||||
|
|
||||||
BK4819_SetCTCSSFrequency(CTCSS_Options[Code]);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (gSubMenuSelection == 0)
|
|
||||||
strcpy(String, "OFF");
|
|
||||||
else
|
|
||||||
sprintf(String, "%u.%uHz", CTCSS_Options[gSubMenuSelection - 1] / 10, CTCSS_Options[gSubMenuSelection - 1] % 10);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,21 +550,13 @@ void UI_DisplayMenu(void)
|
|||||||
case MENU_OFFSET:
|
case MENU_OFFSET:
|
||||||
if (!gIsInSubMenu || gInputBoxIndex == 0)
|
if (!gIsInSubMenu || gInputBoxIndex == 0)
|
||||||
{
|
{
|
||||||
sprintf(String, "%d.%05u", gSubMenuSelection / 100000, abs(gSubMenuSelection) % 100000);
|
sprintf(String, "%3d.%05u", gSubMenuSelection / 100000, abs(gSubMenuSelection) % 100000);
|
||||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8);
|
UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < 3; i++)
|
const char * ascii = INPUTBOX_GetAscii();
|
||||||
String[i ] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0';
|
sprintf(String, "%.3s.%.3s ",ascii, ascii + 3);
|
||||||
String[3] = '.';
|
|
||||||
for (i = 3; i < 6; i++)
|
|
||||||
String[i + 1] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0';
|
|
||||||
String[ 7] = '-';
|
|
||||||
String[ 8] = '-';
|
|
||||||
String[ 9] = 0;
|
|
||||||
String[10] = 0;
|
|
||||||
String[11] = 0;
|
|
||||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8);
|
UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,19 +590,23 @@ void UI_DisplayMenu(void)
|
|||||||
|
|
||||||
case MENU_ABR:
|
case MENU_ABR:
|
||||||
strcpy(String, gSubMenu_BACKLIGHT[gSubMenuSelection]);
|
strcpy(String, gSubMenu_BACKLIGHT[gSubMenuSelection]);
|
||||||
|
if(BACKLIGHT_GetBrightness() < 4)
|
||||||
|
BACKLIGHT_SetBrightness(4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MENU_ABR_MIN:
|
||||||
|
case MENU_ABR_MAX:
|
||||||
|
sprintf(String, "%d", gSubMenuSelection);
|
||||||
|
if(gIsInSubMenu)
|
||||||
|
BACKLIGHT_SetBrightness(gSubMenuSelection);
|
||||||
|
else if(BACKLIGHT_GetBrightness() < 4)
|
||||||
|
BACKLIGHT_SetBrightness(4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_AM:
|
case MENU_AM:
|
||||||
strcpy(String, (gSubMenuSelection == 0) ? "FM" : "AM");
|
strcpy(String, gModulationStr[gSubMenuSelection]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef ENABLE_AM_FIX_TEST1
|
|
||||||
case MENU_AM_FIX_TEST1:
|
|
||||||
strcpy(String, gSubMenu_AM_fix_test1[gSubMenuSelection]);
|
|
||||||
// gSetting_AM_fix = gSubMenuSelection;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case MENU_AUTOLK:
|
case MENU_AUTOLK:
|
||||||
strcpy(String, (gSubMenuSelection == 0) ? "OFF" : "AUTO");
|
strcpy(String, (gSubMenuSelection == 0) ? "OFF" : "AUTO");
|
||||||
break;
|
break;
|
||||||
@@ -602,7 +625,9 @@ void UI_DisplayMenu(void)
|
|||||||
case MENU_S_ADD2:
|
case MENU_S_ADD2:
|
||||||
case MENU_STE:
|
case MENU_STE:
|
||||||
case MENU_D_ST:
|
case MENU_D_ST:
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
case MENU_D_DCD:
|
case MENU_D_DCD:
|
||||||
|
#endif
|
||||||
case MENU_D_LIVE_DEC:
|
case MENU_D_LIVE_DEC:
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
case MENU_NOAA_S:
|
case MENU_NOAA_S:
|
||||||
@@ -612,7 +637,6 @@ void UI_DisplayMenu(void)
|
|||||||
case MENU_500TX:
|
case MENU_500TX:
|
||||||
case MENU_350EN:
|
case MENU_350EN:
|
||||||
case MENU_SCREN:
|
case MENU_SCREN:
|
||||||
case MENU_TX_EN:
|
|
||||||
strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]);
|
strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -627,7 +651,7 @@ void UI_DisplayMenu(void)
|
|||||||
|
|
||||||
if (valid && !gAskForConfirmation)
|
if (valid && !gAskForConfirmation)
|
||||||
{ // show the frequency so that the user knows the channels frequency
|
{ // show the frequency so that the user knows the channels frequency
|
||||||
const uint32_t frequency = BOARD_fetchChannelFrequency(gSubMenuSelection);
|
const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection);
|
||||||
sprintf(String, "%u.%05u", frequency / 100000, frequency % 100000);
|
sprintf(String, "%u.%05u", frequency / 100000, frequency % 100000);
|
||||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8);
|
UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8);
|
||||||
}
|
}
|
||||||
@@ -645,11 +669,11 @@ void UI_DisplayMenu(void)
|
|||||||
|
|
||||||
if (valid)
|
if (valid)
|
||||||
{
|
{
|
||||||
const uint32_t frequency = BOARD_fetchChannelFrequency(gSubMenuSelection);
|
const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection);
|
||||||
|
|
||||||
if (!gIsInSubMenu || edit_index < 0)
|
if (!gIsInSubMenu || edit_index < 0)
|
||||||
{ // show the channel name
|
{ // show the channel name
|
||||||
BOARD_fetchChannelName(String, gSubMenuSelection);
|
SETTINGS_FetchChannelName(String, gSubMenuSelection);
|
||||||
if (String[0] == 0)
|
if (String[0] == 0)
|
||||||
strcpy(String, "--");
|
strcpy(String, "--");
|
||||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 2, 8);
|
UI_PrintString(String, menu_item_x1, menu_item_x2, 2, 8);
|
||||||
@@ -680,11 +704,7 @@ void UI_DisplayMenu(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_TDR:
|
case MENU_TDR:
|
||||||
strcpy(String, gSubMenu_CHAN[gSubMenuSelection]);
|
strcpy(String, gSubMenu_RXMode[gSubMenuSelection]);
|
||||||
break;
|
|
||||||
|
|
||||||
case MENU_XB:
|
|
||||||
strcpy(String, gSubMenu_XB[gSubMenuSelection]);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_TOT:
|
case MENU_TOT:
|
||||||
@@ -725,18 +745,20 @@ void UI_DisplayMenu(void)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
case MENU_ANI_ID:
|
case MENU_ANI_ID:
|
||||||
strcpy(String, gEeprom.ANI_DTMF_ID);
|
strcpy(String, gEeprom.ANI_DTMF_ID);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case MENU_UPCODE:
|
case MENU_UPCODE:
|
||||||
strcpy(String, gEeprom.DTMF_UP_CODE);
|
sprintf(String, "%.8s\n%.8s", gEeprom.DTMF_UP_CODE, gEeprom.DTMF_UP_CODE + 8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_DWCODE:
|
case MENU_DWCODE:
|
||||||
strcpy(String, gEeprom.DTMF_DOWN_CODE);
|
sprintf(String, "%.8s\n%.8s", gEeprom.DTMF_DOWN_CODE, gEeprom.DTMF_DOWN_CODE + 8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
case MENU_D_RSP:
|
case MENU_D_RSP:
|
||||||
strcpy(String, gSubMenu_D_RSP[gSubMenuSelection]);
|
strcpy(String, gSubMenu_D_RSP[gSubMenuSelection]);
|
||||||
break;
|
break;
|
||||||
@@ -744,7 +766,7 @@ void UI_DisplayMenu(void)
|
|||||||
case MENU_D_HOLD:
|
case MENU_D_HOLD:
|
||||||
sprintf(String, "%ds", gSubMenuSelection);
|
sprintf(String, "%ds", gSubMenuSelection);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case MENU_D_PRE:
|
case MENU_D_PRE:
|
||||||
sprintf(String, "%d*10ms", gSubMenuSelection);
|
sprintf(String, "%d*10ms", gSubMenuSelection);
|
||||||
break;
|
break;
|
||||||
@@ -757,13 +779,15 @@ void UI_DisplayMenu(void)
|
|||||||
strcpy(String, gSubMenu_BAT_TXT[gSubMenuSelection]);
|
strcpy(String, gSubMenu_BAT_TXT[gSubMenuSelection]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
case MENU_D_LIST:
|
case MENU_D_LIST:
|
||||||
gIsDtmfContactValid = DTMF_GetContact((int)gSubMenuSelection - 1, Contact);
|
gIsDtmfContactValid = DTMF_GetContact((int)gSubMenuSelection - 1, Contact);
|
||||||
if (!gIsDtmfContactValid)
|
if (!gIsDtmfContactValid)
|
||||||
strcpy(String, "NULL");
|
strcpy(String, "NULL");
|
||||||
else
|
else
|
||||||
memmove(String, Contact, 8);
|
memcpy(String, Contact, 8);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case MENU_PONMSG:
|
case MENU_PONMSG:
|
||||||
strcpy(String, gSubMenu_PONMSG[gSubMenuSelection]);
|
strcpy(String, gSubMenu_PONMSG[gSubMenuSelection]);
|
||||||
@@ -784,7 +808,10 @@ void UI_DisplayMenu(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_F_LOCK:
|
case MENU_F_LOCK:
|
||||||
strcpy(String, gSubMenu_F_LOCK[gSubMenuSelection]);
|
if(!gIsInSubMenu && gUnlockAllTxConfCnt>0 && gUnlockAllTxConfCnt<10)
|
||||||
|
strcpy(String, "READ\nMANUAL");
|
||||||
|
else
|
||||||
|
strcpy(String, gSubMenu_F_LOCK[gSubMenuSelection]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef ENABLE_F_CAL_MENU
|
#ifdef ENABLE_F_CAL_MENU
|
||||||
@@ -808,9 +835,20 @@ void UI_DisplayMenu(void)
|
|||||||
sprintf(String, "%u.%02uV\n%u", vol / 100, vol % 100, gSubMenuSelection);
|
sprintf(String, "%u.%02uV\n%u", vol / 100, vol % 100, gSubMenuSelection);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#pragma GCC diagnostic pop
|
case MENU_BATTYP:
|
||||||
|
strcpy(String, gSubMenu_BATTYP[gSubMenuSelection]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MENU_F1SHRT:
|
||||||
|
case MENU_F1LONG:
|
||||||
|
case MENU_F2SHRT:
|
||||||
|
case MENU_F2LONG:
|
||||||
|
case MENU_MLONG:
|
||||||
|
strcpy(String, gSubMenu_SIDEFUNCTIONS[gSubMenuSelection].name);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
@@ -866,9 +904,9 @@ void UI_DisplayMenu(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gMenuCursor == MENU_SLIST1 || gMenuCursor == MENU_SLIST2)
|
if (UI_MENU_GetCurrentMenuId() == MENU_SLIST1 || UI_MENU_GetCurrentMenuId() == MENU_SLIST2)
|
||||||
{
|
{
|
||||||
i = (gMenuCursor == MENU_SLIST1) ? 0 : 1;
|
i = (UI_MENU_GetCurrentMenuId() == MENU_SLIST1) ? 0 : 1;
|
||||||
|
|
||||||
// if (gSubMenuSelection == 0xFF)
|
// if (gSubMenuSelection == 0xFF)
|
||||||
if (gSubMenuSelection < 0)
|
if (gSubMenuSelection < 0)
|
||||||
@@ -883,7 +921,7 @@ void UI_DisplayMenu(void)
|
|||||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8);
|
UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8);
|
||||||
|
|
||||||
// channel name
|
// channel name
|
||||||
BOARD_fetchChannelName(String, gSubMenuSelection);
|
SETTINGS_FetchChannelName(String, gSubMenuSelection);
|
||||||
if (String[0] == 0)
|
if (String[0] == 0)
|
||||||
strcpy(String, "--");
|
strcpy(String, "--");
|
||||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 2, 8);
|
UI_PrintString(String, menu_item_x1, menu_item_x2, 2, 8);
|
||||||
@@ -894,7 +932,7 @@ void UI_DisplayMenu(void)
|
|||||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8);
|
UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8);
|
||||||
|
|
||||||
// channel name
|
// channel name
|
||||||
BOARD_fetchChannelName(String, gSubMenuSelection);
|
SETTINGS_FetchChannelName(String, gSubMenuSelection);
|
||||||
if (String[0] == 0)
|
if (String[0] == 0)
|
||||||
strcpy(String, "--");
|
strcpy(String, "--");
|
||||||
UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 2);
|
UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 2);
|
||||||
@@ -913,52 +951,48 @@ void UI_DisplayMenu(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gMenuCursor == MENU_MEM_CH ||
|
if (UI_MENU_GetCurrentMenuId() == MENU_MEM_CH ||
|
||||||
gMenuCursor == MENU_DEL_CH ||
|
UI_MENU_GetCurrentMenuId() == MENU_DEL_CH ||
|
||||||
gMenuCursor == MENU_1_CALL)
|
UI_MENU_GetCurrentMenuId() == MENU_1_CALL)
|
||||||
{ // display the channel name
|
{ // display the channel name
|
||||||
char s[11];
|
char s[11];
|
||||||
BOARD_fetchChannelName(s, gSubMenuSelection);
|
SETTINGS_FetchChannelName(s, gSubMenuSelection);
|
||||||
if (s[0] == 0)
|
if (s[0] == 0)
|
||||||
strcpy(s, "--");
|
strcpy(s, "--");
|
||||||
UI_PrintString(s, menu_item_x1, menu_item_x2, 2, 8);
|
UI_PrintString(s, menu_item_x1, menu_item_x2, 2, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gMenuCursor == MENU_R_CTCS || gMenuCursor == MENU_R_DCS) && gCssScanMode != CSS_SCAN_MODE_OFF)
|
if ((UI_MENU_GetCurrentMenuId() == MENU_R_CTCS || UI_MENU_GetCurrentMenuId() == MENU_R_DCS) && gCssBackgroundScan)
|
||||||
UI_PrintString("SCAN", menu_item_x1, menu_item_x2, 4, 8);
|
UI_PrintString("SCAN", menu_item_x1, menu_item_x2, 4, 8);
|
||||||
|
|
||||||
if (gMenuCursor == MENU_UPCODE)
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
if (strlen(gEeprom.DTMF_UP_CODE) > 8)
|
if (UI_MENU_GetCurrentMenuId() == MENU_D_LIST && gIsDtmfContactValid)
|
||||||
UI_PrintString(gEeprom.DTMF_UP_CODE + 8, menu_item_x1, menu_item_x2, 4, 8);
|
|
||||||
|
|
||||||
if (gMenuCursor == MENU_DWCODE)
|
|
||||||
if (strlen(gEeprom.DTMF_DOWN_CODE) > 8)
|
|
||||||
UI_PrintString(gEeprom.DTMF_DOWN_CODE + 8, menu_item_x1, menu_item_x2, 4, 8);
|
|
||||||
|
|
||||||
if (gMenuCursor == MENU_D_LIST && gIsDtmfContactValid)
|
|
||||||
{
|
{
|
||||||
Contact[11] = 0;
|
Contact[11] = 0;
|
||||||
memmove(&gDTMF_ID, Contact + 8, 4);
|
memcpy(&gDTMF_ID, Contact + 8, 4);
|
||||||
sprintf(String, "ID:%s", Contact + 8);
|
sprintf(String, "ID:%s", Contact + 8);
|
||||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8);
|
UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (UI_MENU_GetCurrentMenuId() == MENU_R_CTCS ||
|
||||||
|
UI_MENU_GetCurrentMenuId() == MENU_T_CTCS ||
|
||||||
|
UI_MENU_GetCurrentMenuId() == MENU_R_DCS ||
|
||||||
|
UI_MENU_GetCurrentMenuId() == MENU_T_DCS
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
|
|| UI_MENU_GetCurrentMenuId() == MENU_D_LIST
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
|
||||||
if (gMenuCursor == MENU_R_CTCS ||
|
|
||||||
gMenuCursor == MENU_T_CTCS ||
|
|
||||||
gMenuCursor == MENU_R_DCS ||
|
|
||||||
gMenuCursor == MENU_T_DCS ||
|
|
||||||
gMenuCursor == MENU_D_LIST)
|
|
||||||
{
|
{
|
||||||
unsigned int Offset;
|
sprintf(String, "%2d", gSubMenuSelection);
|
||||||
NUMBER_ToDigits(gSubMenuSelection, String);
|
UI_PrintStringSmall(String, 105, 0, 0);
|
||||||
Offset = (gMenuCursor == MENU_D_LIST) ? 2 : 3;
|
|
||||||
UI_DisplaySmallDigits(Offset, String + (8 - Offset), 105, 0, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gMenuCursor == MENU_RESET ||
|
if ((UI_MENU_GetCurrentMenuId() == MENU_RESET ||
|
||||||
gMenuCursor == MENU_MEM_CH ||
|
UI_MENU_GetCurrentMenuId() == MENU_MEM_CH ||
|
||||||
gMenuCursor == MENU_MEM_NAME ||
|
UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME ||
|
||||||
gMenuCursor == MENU_DEL_CH) && gAskForConfirmation)
|
UI_MENU_GetCurrentMenuId() == MENU_DEL_CH) && gAskForConfirmation)
|
||||||
{ // display confirmation
|
{ // display confirmation
|
||||||
strcpy(String, (gAskForConfirmation == 1) ? "SURE?" : "WAIT!");
|
strcpy(String, (gAskForConfirmation == 1) ? "SURE?" : "WAIT!");
|
||||||
UI_PrintString(String, menu_item_x1, menu_item_x2, 5, 8);
|
UI_PrintString(String, menu_item_x1, menu_item_x2, 5, 8);
|
||||||
|
|||||||
56
ui/menu.h
56
ui/menu.h
@@ -21,6 +21,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "audio.h" // VOICE_ID_t
|
#include "audio.h" // VOICE_ID_t
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char name[7]; // menu display area only has room for 6 characters
|
const char name[7]; // menu display area only has room for 6 characters
|
||||||
@@ -39,7 +40,6 @@ enum
|
|||||||
MENU_T_CTCS,
|
MENU_T_CTCS,
|
||||||
MENU_SFT_D,
|
MENU_SFT_D,
|
||||||
MENU_OFFSET,
|
MENU_OFFSET,
|
||||||
MENU_XB,
|
|
||||||
MENU_TOT,
|
MENU_TOT,
|
||||||
MENU_W_N,
|
MENU_W_N,
|
||||||
MENU_SCR,
|
MENU_SCR,
|
||||||
@@ -54,6 +54,8 @@ enum
|
|||||||
#endif
|
#endif
|
||||||
MENU_ABR,
|
MENU_ABR,
|
||||||
MENU_ABR_ON_TX_RX,
|
MENU_ABR_ON_TX_RX,
|
||||||
|
MENU_ABR_MIN,
|
||||||
|
MENU_ABR_MAX,
|
||||||
MENU_TDR,
|
MENU_TDR,
|
||||||
MENU_BEEP,
|
MENU_BEEP,
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
@@ -77,16 +79,22 @@ enum
|
|||||||
#ifdef ENABLE_ALARM
|
#ifdef ENABLE_ALARM
|
||||||
MENU_AL_MOD,
|
MENU_AL_MOD,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
MENU_ANI_ID,
|
MENU_ANI_ID,
|
||||||
|
#endif
|
||||||
MENU_UPCODE,
|
MENU_UPCODE,
|
||||||
MENU_DWCODE,
|
MENU_DWCODE,
|
||||||
MENU_PTT_ID,
|
MENU_PTT_ID,
|
||||||
MENU_D_ST,
|
MENU_D_ST,
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
MENU_D_RSP,
|
MENU_D_RSP,
|
||||||
MENU_D_HOLD,
|
MENU_D_HOLD,
|
||||||
|
#endif
|
||||||
MENU_D_PRE,
|
MENU_D_PRE,
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
MENU_D_DCD,
|
MENU_D_DCD,
|
||||||
MENU_D_LIST,
|
MENU_D_LIST,
|
||||||
|
#endif
|
||||||
MENU_D_LIVE_DEC,
|
MENU_D_LIVE_DEC,
|
||||||
MENU_PONMSG,
|
MENU_PONMSG,
|
||||||
MENU_ROGER,
|
MENU_ROGER,
|
||||||
@@ -96,30 +104,29 @@ enum
|
|||||||
#ifdef ENABLE_AM_FIX
|
#ifdef ENABLE_AM_FIX
|
||||||
MENU_AM_FIX,
|
MENU_AM_FIX,
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_AM_FIX_TEST1
|
|
||||||
MENU_AM_FIX_TEST1,
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
MENU_NOAA_S,
|
MENU_NOAA_S,
|
||||||
#endif
|
#endif
|
||||||
MENU_RESET,
|
MENU_RESET,
|
||||||
|
|
||||||
// items after here are normally hidden
|
|
||||||
|
|
||||||
MENU_F_LOCK,
|
MENU_F_LOCK,
|
||||||
MENU_200TX,
|
MENU_200TX,
|
||||||
MENU_350TX,
|
MENU_350TX,
|
||||||
MENU_500TX,
|
MENU_500TX,
|
||||||
MENU_350EN,
|
MENU_350EN,
|
||||||
MENU_SCREN,
|
MENU_SCREN,
|
||||||
|
|
||||||
MENU_TX_EN, // enable TX
|
|
||||||
#ifdef ENABLE_F_CAL_MENU
|
#ifdef ENABLE_F_CAL_MENU
|
||||||
MENU_F_CALI, // reference xtal calibration
|
MENU_F_CALI, // reference xtal calibration
|
||||||
#endif
|
#endif
|
||||||
MENU_BATCAL // battery voltage calibration
|
MENU_BATCAL, // battery voltage calibration
|
||||||
|
MENU_F1SHRT,
|
||||||
|
MENU_F1LONG,
|
||||||
|
MENU_F2SHRT,
|
||||||
|
MENU_F2LONG,
|
||||||
|
MENU_MLONG,
|
||||||
|
MENU_BATTYP
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const uint8_t FIRST_HIDDEN_MENU_ITEM;
|
||||||
extern const t_menu_item MenuList[];
|
extern const t_menu_item MenuList[];
|
||||||
|
|
||||||
extern const char gSubMenu_TXP[3][5];
|
extern const char gSubMenu_TXP[3][5];
|
||||||
@@ -128,35 +135,38 @@ extern const char gSubMenu_W_N[2][7];
|
|||||||
extern const char gSubMenu_OFF_ON[2][4];
|
extern const char gSubMenu_OFF_ON[2][4];
|
||||||
extern const char gSubMenu_SAVE[5][4];
|
extern const char gSubMenu_SAVE[5][4];
|
||||||
extern const char gSubMenu_TOT[11][7];
|
extern const char gSubMenu_TOT[11][7];
|
||||||
extern const char gSubMenu_CHAN[3][10];
|
extern const char* gSubMenu_RXMode[4];
|
||||||
extern const char gSubMenu_XB[3][10];
|
|
||||||
#ifdef ENABLE_VOICE
|
#ifdef ENABLE_VOICE
|
||||||
extern const char gSubMenu_VOICE[3][4];
|
extern const char gSubMenu_VOICE[3][4];
|
||||||
#endif
|
#endif
|
||||||
extern const char gSubMenu_SC_REV[3][13];
|
extern const char gSubMenu_SC_REV[3][8];
|
||||||
extern const char gSubMenu_MDF[4][15];
|
extern const char* gSubMenu_MDF[4];
|
||||||
#ifdef ENABLE_ALARM
|
#ifdef ENABLE_ALARM
|
||||||
extern const char gSubMenu_AL_MOD[2][5];
|
extern const char gSubMenu_AL_MOD[2][5];
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
extern const char gSubMenu_D_RSP[4][11];
|
extern const char gSubMenu_D_RSP[4][11];
|
||||||
extern const char gSubMenu_PTT_ID[5][15];
|
#endif
|
||||||
|
extern const char* gSubMenu_PTT_ID[5];
|
||||||
extern const char gSubMenu_PONMSG[4][8];
|
extern const char gSubMenu_PONMSG[4][8];
|
||||||
extern const char gSubMenu_ROGER[3][9];
|
extern const char gSubMenu_ROGER[3][6];
|
||||||
extern const char gSubMenu_RESET[2][4];
|
extern const char gSubMenu_RESET[2][4];
|
||||||
extern const char gSubMenu_F_LOCK[6][4];
|
extern const char* gSubMenu_F_LOCK[F_LOCK_LEN];
|
||||||
extern const char gSubMenu_BACKLIGHT[8][7];
|
extern const char gSubMenu_BACKLIGHT[8][7];
|
||||||
extern const char gSubMenu_RX_TX[4][6];
|
extern const char gSubMenu_RX_TX[4][6];
|
||||||
#ifdef ENABLE_AM_FIX_TEST1
|
|
||||||
extern const char gSubMenu_AM_fix_test1[4][8];
|
|
||||||
#endif
|
|
||||||
extern const char gSubMenu_BAT_TXT[3][8];
|
extern const char gSubMenu_BAT_TXT[3][8];
|
||||||
|
extern const char gSubMenu_BATTYP[2][9];
|
||||||
extern const char gSubMenu_SCRAMBLER[11][7];
|
extern const char gSubMenu_SCRAMBLER[11][7];
|
||||||
|
|
||||||
|
typedef struct {char* name; uint8_t id;} t_sidefunction;
|
||||||
|
extern const uint8_t gSubMenu_SIDEFUNCTIONS_size;
|
||||||
|
extern const t_sidefunction gSubMenu_SIDEFUNCTIONS[];
|
||||||
|
|
||||||
extern bool gIsInSubMenu;
|
extern bool gIsInSubMenu;
|
||||||
|
|
||||||
extern uint8_t gMenuCursor;
|
extern uint8_t gMenuCursor;
|
||||||
extern int8_t gMenuScrollDirection;
|
|
||||||
extern int32_t gSubMenuSelection;
|
extern int32_t gSubMenuSelection;
|
||||||
|
|
||||||
extern char edit_original[17];
|
extern char edit_original[17];
|
||||||
@@ -164,5 +174,7 @@ extern char edit[17];
|
|||||||
extern int edit_index;
|
extern int edit_index;
|
||||||
|
|
||||||
void UI_DisplayMenu(void);
|
void UI_DisplayMenu(void);
|
||||||
|
int UI_MENU_GetCurrentMenuId();
|
||||||
|
uint8_t UI_MENU_GetMenuIdx(uint8_t id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
12
ui/scanner.c
12
ui/scanner.c
@@ -50,7 +50,7 @@ void UI_DisplayScanner(void)
|
|||||||
UI_PrintString(String, 2, 0, 3, 8);
|
UI_PrintString(String, 2, 0, 3, 8);
|
||||||
|
|
||||||
memset(String, 0, sizeof(String));
|
memset(String, 0, sizeof(String));
|
||||||
if (gScannerEditState == 2)
|
if (gScannerSaveState == SCAN_SAVE_CHANNEL)
|
||||||
{
|
{
|
||||||
strcpy(String, "SAVE?");
|
strcpy(String, "SAVE?");
|
||||||
|
|
||||||
@@ -59,19 +59,15 @@ void UI_DisplayScanner(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (gScannerEditState == 1)
|
if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
|
||||||
{
|
|
||||||
strcpy(String, "SAVE:");
|
strcpy(String, "SAVE:");
|
||||||
UI_GenerateChannelStringEx(String + 5, gShowChPrefix, gScanChannel);
|
UI_GenerateChannelStringEx(String + 5, gShowChPrefix, gScanChannel);
|
||||||
}
|
}
|
||||||
else
|
else if (gScanCssState < SCAN_CSS_STATE_FOUND) {
|
||||||
if (gScanCssState < SCAN_CSS_STATE_FOUND)
|
|
||||||
{
|
|
||||||
strcpy(String, "SCAN");
|
strcpy(String, "SCAN");
|
||||||
memset(String + 4, '.', (gScanProgressIndicator & 7) + 1);
|
memset(String + 4, '.', (gScanProgressIndicator & 7) + 1);
|
||||||
}
|
}
|
||||||
else
|
else if (gScanCssState == SCAN_CSS_STATE_FOUND)
|
||||||
if (gScanCssState == SCAN_CSS_STATE_FOUND)
|
|
||||||
strcpy(String, "SCAN CMP.");
|
strcpy(String, "SCAN CMP.");
|
||||||
else
|
else
|
||||||
strcpy(String, "SCAN FAIL.");
|
strcpy(String, "SCAN FAIL.");
|
||||||
|
|||||||
216
ui/status.c
216
ui/status.c
@@ -16,10 +16,11 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "app/scanner.h"
|
#include "app/chFrScanner.h"
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
#include "app/fm.h"
|
#include "app/fm.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "app/scanner.h"
|
||||||
#include "bitmaps.h"
|
#include "bitmaps.h"
|
||||||
#include "driver/keyboard.h"
|
#include "driver/keyboard.h"
|
||||||
#include "driver/st7565.h"
|
#include "driver/st7565.h"
|
||||||
@@ -33,192 +34,153 @@
|
|||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
#include "ui/status.h"
|
#include "ui/status.h"
|
||||||
|
|
||||||
void UI_DisplayStatus(const bool test_display)
|
void UI_DisplayStatus()
|
||||||
{
|
{
|
||||||
uint8_t *line = gStatusLine;
|
|
||||||
unsigned int x = 0;
|
|
||||||
unsigned int x1 = 0;
|
|
||||||
|
|
||||||
gUpdateStatus = false;
|
gUpdateStatus = false;
|
||||||
|
|
||||||
memset(gStatusLine, 0, sizeof(gStatusLine));
|
memset(gStatusLine, 0, sizeof(gStatusLine));
|
||||||
|
|
||||||
|
uint8_t *line = gStatusLine;
|
||||||
|
unsigned int x = 0;
|
||||||
// **************
|
// **************
|
||||||
|
|
||||||
// POWER-SAVE indicator
|
// POWER-SAVE indicator
|
||||||
if (gCurrentFunction == FUNCTION_TRANSMIT)
|
if (gCurrentFunction == FUNCTION_TRANSMIT) {
|
||||||
{
|
memcpy(line + x, BITMAP_TX, sizeof(BITMAP_TX));
|
||||||
memmove(line + x, BITMAP_TX, sizeof(BITMAP_TX));
|
|
||||||
x1 = x + sizeof(BITMAP_TX);
|
|
||||||
}
|
}
|
||||||
else
|
else if (FUNCTION_IsRx()) {
|
||||||
if (gCurrentFunction == FUNCTION_RECEIVE ||
|
memcpy(line + x, BITMAP_RX, sizeof(BITMAP_RX));
|
||||||
gCurrentFunction == FUNCTION_MONITOR ||
|
|
||||||
gCurrentFunction == FUNCTION_INCOMING)
|
|
||||||
{
|
|
||||||
memmove(line + x, BITMAP_RX, sizeof(BITMAP_RX));
|
|
||||||
x1 = x + sizeof(BITMAP_RX);
|
|
||||||
}
|
}
|
||||||
else
|
else if (gCurrentFunction == FUNCTION_POWER_SAVE) {
|
||||||
if (gCurrentFunction == FUNCTION_POWER_SAVE || test_display)
|
memcpy(line + x, BITMAP_POWERSAVE, sizeof(BITMAP_POWERSAVE));
|
||||||
{
|
|
||||||
memmove(line + x, BITMAP_POWERSAVE, sizeof(BITMAP_POWERSAVE));
|
|
||||||
x1 = x + sizeof(BITMAP_POWERSAVE);
|
|
||||||
}
|
}
|
||||||
x += sizeof(BITMAP_POWERSAVE);
|
x += 8;
|
||||||
|
unsigned int x1 = x;
|
||||||
|
|
||||||
#ifdef ENABLE_NOAA
|
#ifdef ENABLE_NOAA
|
||||||
// NOASS SCAN indicator
|
if (gIsNoaaMode) { // NOASS SCAN indicator
|
||||||
if (gIsNoaaMode || test_display)
|
memcpy(line + x, BITMAP_NOAA, sizeof(BITMAP_NOAA));
|
||||||
{
|
x1 = x + sizeof(BITMAP_NOAA);
|
||||||
memmove(line + x, BITMAP_NOAA, sizeof(BITMAP_NOAA));
|
}
|
||||||
x1 = x + sizeof(BITMAP_NOAA);
|
x += sizeof(BITMAP_NOAA);
|
||||||
}
|
#endif
|
||||||
x += sizeof(BITMAP_NOAA);
|
|
||||||
#else
|
|
||||||
// hmmm, what to put in it's place
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (gSetting_KILLED)
|
#ifdef ENABLE_DTMF_CALLING
|
||||||
{
|
if (gSetting_KILLED) {
|
||||||
memset(line + x, 0xFF, 10);
|
memset(line + x, 0xFF, 10);
|
||||||
x1 = x + 10;
|
x1 = x + 10;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#ifdef ENABLE_FMRADIO
|
#endif
|
||||||
// FM indicator
|
#ifdef ENABLE_FMRADIO
|
||||||
if (gFmRadioMode || test_display)
|
if (gFmRadioMode) { // FM indicator
|
||||||
{
|
memcpy(line + x, BITMAP_FM, sizeof(BITMAP_FM));
|
||||||
memmove(line + x, BITMAP_FM, sizeof(BITMAP_FM));
|
x1 = x + sizeof(BITMAP_FM);
|
||||||
x1 = x + sizeof(BITMAP_FM);
|
}
|
||||||
}
|
else
|
||||||
else
|
#endif
|
||||||
#endif
|
{ // SCAN indicator
|
||||||
// SCAN indicator
|
if (gScanStateDir != SCAN_OFF || SCANNER_IsScanning()) {
|
||||||
if (gScanStateDir != SCAN_OFF || gScreenToDisplay == DISPLAY_SCANNER || test_display)
|
char * s = "";
|
||||||
{
|
if (IS_MR_CHANNEL(gNextMrChannel) && !SCANNER_IsScanning()) { // channel mode
|
||||||
if (gNextMrChannel <= MR_CHANNEL_LAST)
|
switch(gEeprom.SCAN_LIST_DEFAULT) {
|
||||||
{ // channel mode
|
case 0: s = "1"; break;
|
||||||
if (gEeprom.SCAN_LIST_DEFAULT == 0)
|
case 1: s = "2"; break;
|
||||||
UI_PrintStringSmallBuffer("1", line + x);
|
case 2: s = "*"; break;
|
||||||
else
|
}
|
||||||
if (gEeprom.SCAN_LIST_DEFAULT == 1)
|
|
||||||
UI_PrintStringSmallBuffer("2", line + x);
|
|
||||||
else
|
|
||||||
if (gEeprom.SCAN_LIST_DEFAULT == 2)
|
|
||||||
UI_PrintStringSmallBuffer("*", line + x);
|
|
||||||
}
|
}
|
||||||
|
else { // frequency mode
|
||||||
|
s = "S";
|
||||||
|
}
|
||||||
|
UI_PrintStringSmallBuffer(s, line + x + 1);
|
||||||
|
x1 = x + 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x += 10; // font character width
|
||||||
|
|
||||||
|
#ifdef ENABLE_VOICE
|
||||||
|
// VOICE indicator
|
||||||
|
if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF){
|
||||||
|
memcpy(line + x, BITMAP_VoicePrompt, sizeof(BITMAP_VoicePrompt));
|
||||||
|
x1 = x + sizeof(BITMAP_VoicePrompt);
|
||||||
|
}
|
||||||
|
x += sizeof(BITMAP_VoicePrompt);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!SCANNER_IsScanning()) {
|
||||||
|
uint8_t dw = (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2;
|
||||||
|
if(dw == 1 || dw == 3) { // DWR - dual watch + respond
|
||||||
|
if(gDualWatchActive)
|
||||||
|
memcpy(line + x + (dw==1?0:2), BITMAP_TDR1, sizeof(BITMAP_TDR1) - (dw==1?0:5));
|
||||||
else
|
else
|
||||||
{ // frequency mode
|
memcpy(line + x + 3, BITMAP_TDR2, sizeof(BITMAP_TDR2));
|
||||||
UI_PrintStringSmallBuffer("S", line + x);
|
|
||||||
}
|
|
||||||
x1 = x + 7;
|
|
||||||
}
|
}
|
||||||
x += 7; // font character width
|
else if(dw == 2) { // XB - crossband
|
||||||
|
memcpy(line + x + 2, BITMAP_XB, sizeof(BITMAP_XB));
|
||||||
#ifdef ENABLE_VOICE
|
|
||||||
// VOICE indicator
|
|
||||||
if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF || test_display)
|
|
||||||
{
|
|
||||||
memmove(line + x, BITMAP_VoicePrompt, sizeof(BITMAP_VoicePrompt));
|
|
||||||
x1 = x + sizeof(BITMAP_VoicePrompt);
|
|
||||||
}
|
}
|
||||||
x += sizeof(BITMAP_VoicePrompt);
|
|
||||||
#else
|
|
||||||
// hmmm, what to put in it's place
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// DUAL-WATCH indicator
|
|
||||||
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF || test_display)
|
|
||||||
{
|
|
||||||
if (gDualWatchActive || test_display)
|
|
||||||
memmove(line + x, BITMAP_TDR1, sizeof(BITMAP_TDR1));
|
|
||||||
else
|
|
||||||
memmove(line + x, BITMAP_TDR2, sizeof(BITMAP_TDR2));
|
|
||||||
}
|
}
|
||||||
x += sizeof(BITMAP_TDR1);
|
x += sizeof(BITMAP_TDR1) + 1;
|
||||||
|
|
||||||
// CROSS-VFO indicator
|
#ifdef ENABLE_VOX
|
||||||
if (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF || test_display)
|
// VOX indicator
|
||||||
{
|
if (gEeprom.VOX_SWITCH) {
|
||||||
memmove(line + x, BITMAP_XB, sizeof(BITMAP_XB));
|
memcpy(line + x, BITMAP_VOX, sizeof(BITMAP_VOX));
|
||||||
x1 = x + sizeof(BITMAP_XB);
|
x1 = x + sizeof(BITMAP_VOX) + 1;
|
||||||
}
|
}
|
||||||
x += sizeof(BITMAP_XB);
|
x += sizeof(BITMAP_VOX) + 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_VOX
|
x = MAX(x1, 61u);
|
||||||
// VOX indicator
|
|
||||||
if (gEeprom.VOX_SWITCH || test_display)
|
|
||||||
{
|
|
||||||
memmove(line + x, BITMAP_VOX, sizeof(BITMAP_VOX));
|
|
||||||
x1 = x + sizeof(BITMAP_VOX);
|
|
||||||
}
|
|
||||||
x += sizeof(BITMAP_VOX);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// KEY-LOCK indicator
|
// KEY-LOCK indicator
|
||||||
if (gEeprom.KEY_LOCK || test_display)
|
if (gEeprom.KEY_LOCK) {
|
||||||
{
|
memcpy(line + x, BITMAP_KeyLock, sizeof(BITMAP_KeyLock));
|
||||||
memmove(line + x, BITMAP_KeyLock, sizeof(BITMAP_KeyLock));
|
|
||||||
x += sizeof(BITMAP_KeyLock);
|
x += sizeof(BITMAP_KeyLock);
|
||||||
x1 = x;
|
x1 = x;
|
||||||
}
|
}
|
||||||
else
|
else if (gWasFKeyPressed) {
|
||||||
if (gWasFKeyPressed)
|
memcpy(line + x, BITMAP_F_Key, sizeof(BITMAP_F_Key));
|
||||||
{
|
|
||||||
memmove(line + x, BITMAP_F_Key, sizeof(BITMAP_F_Key));
|
|
||||||
x += sizeof(BITMAP_F_Key);
|
x += sizeof(BITMAP_F_Key);
|
||||||
x1 = x;
|
x1 = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // battery voltage or percentage
|
{ // battery voltage or percentage
|
||||||
char s[8];
|
char s[8] = "";
|
||||||
unsigned int space_needed;
|
unsigned int x2 = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - 0;
|
||||||
|
|
||||||
unsigned int x2 = LCD_WIDTH - sizeof(BITMAP_BatteryLevel5) - 3;
|
|
||||||
|
|
||||||
if (gChargingWithTypeC)
|
if (gChargingWithTypeC)
|
||||||
x2 -= sizeof(BITMAP_USB_C); // the radio is on charge
|
x2 -= sizeof(BITMAP_USB_C); // the radio is on charge
|
||||||
|
|
||||||
switch (gSetting_battery_text)
|
switch (gSetting_battery_text) {
|
||||||
{
|
|
||||||
default:
|
default:
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // voltage
|
case 1: { // voltage
|
||||||
{
|
|
||||||
const uint16_t voltage = (gBatteryVoltageAverage <= 999) ? gBatteryVoltageAverage : 999; // limit to 9.99V
|
const uint16_t voltage = (gBatteryVoltageAverage <= 999) ? gBatteryVoltageAverage : 999; // limit to 9.99V
|
||||||
sprintf(s, "%u.%02uV", voltage / 100, voltage % 100);
|
sprintf(s, "%u.%02uV", voltage / 100, voltage % 100);
|
||||||
space_needed = (7 * strlen(s));
|
|
||||||
if (x2 >= (x1 + space_needed))
|
|
||||||
{
|
|
||||||
UI_PrintStringSmallBuffer(s, line + x2 - space_needed);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 2: // percentage
|
case 2: // percentage
|
||||||
{
|
|
||||||
sprintf(s, "%u%%", BATTERY_VoltsToPercent(gBatteryVoltageAverage));
|
sprintf(s, "%u%%", BATTERY_VoltsToPercent(gBatteryVoltageAverage));
|
||||||
space_needed = (7 * strlen(s));
|
|
||||||
if (x2 >= (x1 + space_needed))
|
|
||||||
UI_PrintStringSmallBuffer(s, line + x2 - space_needed);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int space_needed = (7 * strlen(s));
|
||||||
|
if (x2 >= (x1 + space_needed))
|
||||||
|
UI_PrintStringSmallBuffer(s, line + x2 - space_needed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// move to right side of the screen
|
// move to right side of the screen
|
||||||
x = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - sizeof(BITMAP_USB_C);
|
x = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - sizeof(BITMAP_USB_C);
|
||||||
|
|
||||||
// USB-C charge indicator
|
// USB-C charge indicator
|
||||||
if (gChargingWithTypeC || test_display)
|
if (gChargingWithTypeC)
|
||||||
memmove(line + x, BITMAP_USB_C, sizeof(BITMAP_USB_C));
|
memcpy(line + x, BITMAP_USB_C, sizeof(BITMAP_USB_C));
|
||||||
x += sizeof(BITMAP_USB_C);
|
x += sizeof(BITMAP_USB_C);
|
||||||
|
|
||||||
// BATTERY LEVEL indicator
|
// BATTERY LEVEL indicator
|
||||||
UI_DrawBattery(line + x, gBatteryDisplayLevel, gLowBattery);
|
UI_DrawBattery(line + x, gBatteryDisplayLevel, gLowBatteryBlink);
|
||||||
|
|
||||||
// **************
|
// **************
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
#ifndef UI_STATUS_H
|
#ifndef UI_STATUS_H
|
||||||
#define UI_STATUS_H
|
#define UI_STATUS_H
|
||||||
|
|
||||||
void UI_DisplayStatus(const bool test_display);
|
void UI_DisplayStatus();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
53
ui/ui.c
53
ui/ui.c
@@ -14,13 +14,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "app/chFrScanner.h"
|
||||||
#include "app/dtmf.h"
|
#include "app/dtmf.h"
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
#include "app/fm.h"
|
#include "app/fm.h"
|
||||||
#endif
|
#endif
|
||||||
#include "app/scanner.h"
|
|
||||||
#include "driver/keyboard.h"
|
#include "driver/keyboard.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#ifdef ENABLE_AIRCOPY
|
#ifdef ENABLE_AIRCOPY
|
||||||
@@ -34,6 +35,7 @@
|
|||||||
#include "ui/menu.h"
|
#include "ui/menu.h"
|
||||||
#include "ui/scanner.h"
|
#include "ui/scanner.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
#include "../misc.h"
|
||||||
|
|
||||||
GUI_DisplayType_t gScreenToDisplay;
|
GUI_DisplayType_t gScreenToDisplay;
|
||||||
GUI_DisplayType_t gRequestDisplayScreen = DISPLAY_INVALID;
|
GUI_DisplayType_t gRequestDisplayScreen = DISPLAY_INVALID;
|
||||||
@@ -42,36 +44,27 @@ uint8_t gAskForConfirmation;
|
|||||||
bool gAskToSave;
|
bool gAskToSave;
|
||||||
bool gAskToDelete;
|
bool gAskToDelete;
|
||||||
|
|
||||||
|
|
||||||
|
void (*UI_DisplayFunctions[])(void) = {
|
||||||
|
[DISPLAY_MAIN] = &UI_DisplayMain,
|
||||||
|
[DISPLAY_MENU] = &UI_DisplayMenu,
|
||||||
|
[DISPLAY_SCANNER] = &UI_DisplayScanner,
|
||||||
|
|
||||||
|
#ifdef ENABLE_FMRADIO
|
||||||
|
[DISPLAY_FM] = &UI_DisplayFM,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_AIRCOPY
|
||||||
|
[DISPLAY_AIRCOPY] = &UI_DisplayAircopy,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(ARRAY_SIZE(UI_DisplayFunctions) == DISPLAY_N_ELEM);
|
||||||
|
|
||||||
void GUI_DisplayScreen(void)
|
void GUI_DisplayScreen(void)
|
||||||
{
|
{
|
||||||
switch (gScreenToDisplay)
|
if (gScreenToDisplay != DISPLAY_INVALID) {
|
||||||
{
|
UI_DisplayFunctions[gScreenToDisplay]();
|
||||||
case DISPLAY_MAIN:
|
|
||||||
UI_DisplayMain();
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
|
||||||
case DISPLAY_FM:
|
|
||||||
UI_DisplayFM();
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case DISPLAY_MENU:
|
|
||||||
UI_DisplayMenu();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DISPLAY_SCANNER:
|
|
||||||
UI_DisplayScanner();
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef ENABLE_AIRCOPY
|
|
||||||
case DISPLAY_AIRCOPY:
|
|
||||||
UI_DisplayAircopy();
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +79,7 @@ void GUI_SelectNextDisplay(GUI_DisplayType_t Display)
|
|||||||
|
|
||||||
gInputBoxIndex = 0;
|
gInputBoxIndex = 0;
|
||||||
gIsInSubMenu = false;
|
gIsInSubMenu = false;
|
||||||
gCssScanMode = CSS_SCAN_MODE_OFF;
|
gCssBackgroundScan = false;
|
||||||
gScanStateDir = SCAN_OFF;
|
gScanStateDir = SCAN_OFF;
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
gFM_ScanState = FM_SCAN_OFF;
|
gFM_ScanState = FM_SCAN_OFF;
|
||||||
|
|||||||
11
ui/ui.h
11
ui/ui.h
@@ -23,10 +23,18 @@
|
|||||||
enum GUI_DisplayType_t
|
enum GUI_DisplayType_t
|
||||||
{
|
{
|
||||||
DISPLAY_MAIN = 0,
|
DISPLAY_MAIN = 0,
|
||||||
DISPLAY_FM,
|
|
||||||
DISPLAY_MENU,
|
DISPLAY_MENU,
|
||||||
DISPLAY_SCANNER,
|
DISPLAY_SCANNER,
|
||||||
|
|
||||||
|
#ifdef ENABLE_FMRADIO
|
||||||
|
DISPLAY_FM,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_AIRCOPY
|
||||||
DISPLAY_AIRCOPY,
|
DISPLAY_AIRCOPY,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DISPLAY_N_ELEM,
|
||||||
DISPLAY_INVALID = 0xFFu
|
DISPLAY_INVALID = 0xFFu
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -43,4 +51,3 @@ void GUI_DisplayScreen(void);
|
|||||||
void GUI_SelectNextDisplay(GUI_DisplayType_t Display);
|
void GUI_SelectNextDisplay(GUI_DisplayType_t Display);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
18
ui/welcome.c
18
ui/welcome.c
@@ -43,7 +43,6 @@ void UI_DisplayWelcome(void)
|
|||||||
{
|
{
|
||||||
char WelcomeString0[16];
|
char WelcomeString0[16];
|
||||||
char WelcomeString1[16];
|
char WelcomeString1[16];
|
||||||
char WelcomeString2[16];
|
|
||||||
|
|
||||||
memset(gStatusLine, 0, sizeof(gStatusLine));
|
memset(gStatusLine, 0, sizeof(gStatusLine));
|
||||||
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
|
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
|
||||||
@@ -61,7 +60,6 @@ void UI_DisplayWelcome(void)
|
|||||||
{
|
{
|
||||||
memset(WelcomeString0, 0, sizeof(WelcomeString0));
|
memset(WelcomeString0, 0, sizeof(WelcomeString0));
|
||||||
memset(WelcomeString1, 0, sizeof(WelcomeString1));
|
memset(WelcomeString1, 0, sizeof(WelcomeString1));
|
||||||
memset(WelcomeString2, 0, sizeof(WelcomeString2));
|
|
||||||
|
|
||||||
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_VOLTAGE)
|
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_VOLTAGE)
|
||||||
{
|
{
|
||||||
@@ -70,10 +68,6 @@ void UI_DisplayWelcome(void)
|
|||||||
gBatteryVoltageAverage / 100,
|
gBatteryVoltageAverage / 100,
|
||||||
gBatteryVoltageAverage % 100,
|
gBatteryVoltageAverage % 100,
|
||||||
BATTERY_VoltsToPercent(gBatteryVoltageAverage));
|
BATTERY_VoltsToPercent(gBatteryVoltageAverage));
|
||||||
|
|
||||||
#if 0
|
|
||||||
sprintf(WelcomeString2, "Current %u", gBatteryCurrent); // needs scaling into mA
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -83,17 +77,9 @@ void UI_DisplayWelcome(void)
|
|||||||
|
|
||||||
UI_PrintString(WelcomeString0, 0, 127, 0, 10);
|
UI_PrintString(WelcomeString0, 0, 127, 0, 10);
|
||||||
UI_PrintString(WelcomeString1, 0, 127, 2, 10);
|
UI_PrintString(WelcomeString1, 0, 127, 2, 10);
|
||||||
#if 0
|
UI_PrintStringSmall(Version, 0, 128, 6);
|
||||||
UI_PrintStringSmall(WelcomeString2, 0, 127, 4);
|
|
||||||
#endif
|
|
||||||
UI_PrintStringSmall(Version, 0, 0, 6);
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
ST7565_BlitStatusLine(); // blank status line
|
|
||||||
#else
|
|
||||||
UI_DisplayStatus(true); // show all status line symbols (test)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
ST7565_BlitStatusLine(); // blank status line
|
||||||
ST7565_BlitFullScreen();
|
ST7565_BlitFullScreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
version.c
19
version.c
@@ -1,16 +1,11 @@
|
|||||||
|
|
||||||
#define ONE_OF_ELEVEN_VER
|
#ifdef VERSION_STRING
|
||||||
|
#define VER " "VERSION_STRING
|
||||||
#ifdef GIT_HASH
|
|
||||||
#define VER GIT_HASH
|
|
||||||
#else
|
#else
|
||||||
#define VER "231004"
|
#define VER ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ONE_OF_ELEVEN_VER
|
|
||||||
const char Version[] = "OEFW-"VER;
|
const char Version[] = AUTHOR_STRING VER;
|
||||||
const char UART_Version[] = "UV-K5 Firmware, Open Edition, OEFW-"VER"\r\n";
|
const char UART_Version[] = "UV-K5 Firmware, Open Edition, " AUTHOR_STRING VER "\r\n";
|
||||||
#else
|
|
||||||
const char Version[] = "1o11+fagci-"VER;
|
|
||||||
const char UART_Version[] = "UV-K5 Firmware, Open Edition, 1o11+fagci-"VER"\r\n";
|
|
||||||
#endif
|
|
||||||
|
|||||||
17
win_make.bat
17
win_make.bat
@@ -18,15 +18,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
:: Delete any left over files from previous compile
|
|
||||||
::
|
|
||||||
del /S /Q *.o >nul 2>nul
|
|
||||||
del /S /Q *.d >nul 2>nul
|
|
||||||
del /Q firmware >nul 2>nul
|
|
||||||
del /Q *.bin >nul 2>nul
|
|
||||||
|
|
||||||
:: You may need to edit/change these three paths to suit your setup
|
:: You may need to edit/change these three paths to suit your setup
|
||||||
::
|
::
|
||||||
:: Temporarily add the compiler and make program directories to the system PATH ..
|
:: Temporarily add the compiler and make program directories to the system PATH ..
|
||||||
@@ -40,14 +31,6 @@ del /Q *.bin >nul 2>nul
|
|||||||
make clean
|
make clean
|
||||||
make
|
make
|
||||||
|
|
||||||
:: Delete the spent files
|
|
||||||
::
|
|
||||||
del /S /Q *.o >nul 2>nul
|
|
||||||
del /S /Q *.d >nul 2>nul
|
|
||||||
del /Q firmware >nul 2>nul
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
:: If you have python installed, you can create a 'packed' .bin from the compiled firmware.bin file.
|
:: If you have python installed, you can create a 'packed' .bin from the compiled firmware.bin file.
|
||||||
:: The Quansheng windows upload-to-radio program requires a 'packed' .bin file.
|
:: The Quansheng windows upload-to-radio program requires a 'packed' .bin file.
|
||||||
|
|||||||
Reference in New Issue
Block a user