84 Commits

Author SHA1 Message Date
Krzysiek Egzmont
f85ed9440d Refactor 2024-01-28 23:57:15 +01:00
Krzysiek Egzmont
604a5b430f PTTID sanity check 2024-01-28 22:07:08 +01:00
Krzysiek Egzmont
ed5ebc4854 FIX #441: Setting ENABLE_NO_CODE_SCAN_TIMEOUT at 1 or 0 has no effect 2024-01-28 21:59:20 +01:00
egzumer
c74c0d20fc README.md, recommend other forks 2024-01-22 00:03:43 +01:00
Krzysiek Egzmont
46e2d1a0fd FM radio band selection #230 2024-01-15 22:30:12 +01:00
Krzysiek Egzmont
adbc466c49 Refactor 2024-01-15 17:01:42 +01:00
Krzysiek Egzmont
f8ff71aaa3 Fix #193: DTMF interrupt temporarily disabled after TX causing DTMF tones lost 2024-01-14 00:58:40 +01:00
Krzysiek Egzmont
ea3b5b23a9 Refactor 2024-01-14 00:25:02 +01:00
Krzysiek Egzmont
8941576887 Fix #286: Lack of continuous tuning and monitor lockout while holding up/down button in monitor mode. 2024-01-13 23:35:33 +01:00
Krzysiek Egzmont
04b0bd8c93 Refactor 2024-01-13 23:30:44 +01:00
wu58430
4efabfc2b6 Prohibit entering submenus when displaying DTMF information 2024-01-12 17:51:36 +01:00
Krzysiek Egzmont
9472bbb58b Fix #384: FM radio getting stuck off on unrecognized incoming CTCSS tone 2024-01-12 15:54:36 +01:00
Krzysiek Egzmont
685ecb062b Refactor 2024-01-12 15:54:35 +01:00
Krzysiek Egzmont
3bf993d8b8 Cleanup the ENABLE_SQUELCH_MORE_SENSITIVE option, it was still applying some corrections even if disabled 2024-01-09 02:42:47 +01:00
Yuri_su
01ccaaf212 Update app.c fix DTMF not reply
If set DTMF reply only, sometimes the DTMF call will not reply.
2024-01-08 23:40:01 +01:00
Krzysiek Egzmont
ed5ae7842b Fix #366: Scan list 2 ignored everywhere 2024-01-01 20:50:21 +01:00
Krzysiek Egzmont
ac8c51d605 Fix s-meter and DTMF overlaying problem 2023-12-31 13:31:39 +01:00
Wouter van Gulik
429cffc0bc ui/menu.c: Simplify code; move name printing into main switch statement.
This saves a few bytes of flash.
2023-12-30 20:38:59 +01:00
Wouter van Gulik
fbdaf6631d menu: use const char* const 2023-12-30 20:35:11 +01:00
Krzysiek Egzmont
f8feef1ad5 Refactor 2023-12-30 20:22:55 +01:00
Krzysiek Egzmont
42a45a7ef2 Update README 2023-12-30 15:35:28 +01:00
Krzysiek Egzmont
3f012b3afe Fix uart BK regs reading/writing 2023-12-30 15:32:11 +01:00
Juan Antonio
289418f1c7 Reduce nesting 2023-12-28 22:08:57 +01:00
Juan Antonio
ea733115de init.c: Declare loop variables in the loop 2023-12-28 22:08:57 +01:00
Juan Antonio
e5cff16d98 Merge guarded code. Simplify DTMF_CheckGroupCall 2023-12-28 22:08:56 +01:00
Krzysiek Egzmont
f35ce8d789 Menu style build option ENABLE_CUSTOM_MENU_LAYOUT 2023-12-28 22:08:56 +01:00
Juan Antonio
36ecde86e9 Reduce nesting 2023-12-28 22:08:56 +01:00
Krzysiek Egzmont
8f6e1be5e0 Refactor 2023-12-28 22:08:56 +01:00
Juan Antonio
cceba5a474 Add missing UI_DisplayClear() 2023-12-26 03:01:24 +01:00
Krzysiek Egzmont
1882ab0cc1 Refactor 2023-12-26 01:40:04 +01:00
Krzysiek Egzmont
995045006f Read/write BK4819 regs through UART 2023-12-25 23:52:15 +01:00
Krzysiek Egzmont
38ec40b0db Faster AGC debugging print 2023-12-25 22:49:58 +01:00
Juan Antonio
cbf4a7c140 Use function table. Simplify logic
Size: 60364 -> 60220
2023-12-25 22:49:06 +01:00
Juan Antonio
7a7010da55 Unify PrintSmall functions
Size: 60420 -> 60364
2023-12-25 22:49:06 +01:00
Juan Antonio
78a45d9bbd Create function to zero gFrameBuffer
Size: 60464 -> 60420
2023-12-25 22:49:06 +01:00
Juan Antonio
f8ef687026 Use pointers to avoid some string copying
Size: 60664 -> 60464
2023-12-25 22:49:06 +01:00
Juan Antonio
1281bbf033 Remove redundant mensets. Memmove -> memcpy
* The whole gEeprom has been zero'd before. Moreover, strcpy null-terminates.
* There's no aliasing between gEeprom.* and Data.

Size: 60760 -> 60664
2023-12-25 22:49:06 +01:00
Juan Antonio
edf1f983d6 Ignore k5_eeprom.raw 2023-12-25 22:49:06 +01:00
Juan Antonio
b0d131d546 Fix include directives 2023-12-25 22:49:06 +01:00
Wouter van Gulik
ab61c4e74f Makefile: always provide VERSION_STRING if none set.
Without this set the compile-without-docker script did not work. They do
not have git installed.
2023-12-25 01:01:53 +01:00
Juan Antonio
986c0ce368 Fix RX not honoring Backlight on TX/RX settings properly
Fixes #317
2023-12-24 22:56:35 +01:00
Juan Antonio
e929a79765 Move variable declaration outside of guarded region
Fixes #328
2023-12-24 20:55:29 +01:00
Juan Antonio
d75209bad0 Rename str_ptr to adhere to the current style 2023-12-24 13:34:05 +01:00
Juan Antonio
ee0ba9886d Simplify DTMF_FindContact 2023-12-24 13:34:05 +01:00
Juan Antonio
084fe4dd26 Fix 1750Hz so that it can perform STE
1750Hz and CTCSS tones can be send together.
2023-12-24 13:34:05 +01:00
Juan Antonio
a715389a8b Add Doxygen configuration file and makefile target
It can be used to generate sometimes useful call-graphs.
2023-12-24 13:34:05 +01:00
Juan Antonio
6f1cabc807 Simplify gSchedulePowerSave logic
There was quite convoluted logic there, and what I believe, was a bug.

Rationale:

Both,
- gBatterySaveCountdown_10ms = battery_save_count_10ms;, and
- gSchedulePowerSave = false
are always executed inside FUNCTION_Select().

So the code is equivalent to:

if (any of those OR'd) {
	gBatterySaveCountdown_10ms = battery_save_count_10ms;
	gSchedulePowerSave = false; (but only if we have NOAA disabled)
} else {
	[other stuff from FUNCTION_Select()]
	gBatterySaveCountdown_10ms = battery_save_count_10ms;
	gSchedulePowerSave = false; (regarless of having NOAA or not)
}

So:
- OR is true, have NOAA-> don't clear gSchedulePowerSave
	-> implies we will enter here, again, until the OR is false, but only if we have NOAA.
- OR is False -> clear gSchedulePowerSave.

Moreover, checking with DualTachyon code at
6f8afac886/app/app.c (L747)
gSchedulePowerSave is always set to false if it was true.
2023-12-24 13:34:05 +01:00
Juan Antonio
a08420a0b7 Simply some logic. Unify some #ifdef regions 2023-12-24 13:34:05 +01:00
Juan Antonio
1f4f026162 Simplify APP_EndTransmission
* Unify Roger-Beep selection
 * Extract function for DTMF EoT
2023-12-24 13:34:05 +01:00
Juan Antonio
34f2168856 Spectrum warp-around when switching steps 2023-12-24 13:34:05 +01:00
Juan Antonio
bc9bb489e6 Un-unroll some loops and save a few bytes 2023-12-24 13:34:05 +01:00
Juan Antonio
7d982f1f8d Correct include guard #endif placement 2023-12-22 20:26:07 +01:00
Krzysiek Egzmont
2cc60da9ab Fix #314:Reset current bar when blacklisting in scan range 2023-12-22 20:22:39 +01:00
Krzysiek Egzmont
39eb3e835e Scan range in spectrum 2023-12-19 18:25:45 +01:00
egzumer
0d66eb8577 Update README.md 2023-12-19 17:37:24 +01:00
Krzysiek Egzmont
13b6bb06b2 Spectrum analyzer, more frequency steps 2023-12-19 03:08:18 +01:00
Krzysiek Egzmont
88f3537af0 9kHz, 20kHz, 200kHz frequency steps added #295 2023-12-18 17:12:33 +01:00
Krzysiek Egzmont
de8c501d65 S0, S9 settings even more constrained 2023-12-18 15:27:31 +01:00
egzumer
76bbaf9442 Update README.md 2023-12-18 15:23:02 +01:00
Krzysiek Egzmont
c4d9cfc895 Add AM-fix build option to EEPROM 2023-12-17 03:47:17 +01:00
Juan Antonio
2a75f8a9be Refactoring #285
Signed-off-by: Krzysiek Egzmont <egzumer@gmail.com>
2023-12-16 18:34:54 +01:00
Krzysiek Egzmont
e7a21c470f Makefile Mac build fix #284 2023-12-15 21:08:50 +01:00
Krzysiek Egzmont
fc679c77a4 Fix other backlight menu issues #275 2023-12-15 18:08:40 +01:00
Krzysiek Egzmont
1151cf8667 Backlight brightness tuned down for backlight menu entries #275 2023-12-15 16:54:18 +01:00
Krzysiek Egzmont
af6b542da1 Cleanup 2023-12-15 13:47:07 +01:00
Juan Antonio
cc49a5007c Fix #275 Backlight does not get back to MAX brightness after exiting backlight menu entries
Backlight is set to FULL when interacting with backlight menu entries,
but it is not set back to MAX when exiting from those entries. This
commit corrects that behaviour.
2023-12-15 13:00:08 +01:00
Juan Antonio
a99d2dd1b1 Fix #272: Backlight time doubled 2023-12-15 02:56:25 +01:00
Juan Antonio
9dc79ce868 Fix compilation errors when UART is disabled 2023-12-14 22:03:44 +01:00
Juan Antonio
80fa310646 Fix use of wrong ENABLE guard 2023-12-14 22:03:44 +01:00
Juan Antonio
7f5236c44e Fix compilation errors when FM radio is disabled 2023-12-14 22:03:44 +01:00
Juan Antonio
4b583bf2bd Assign NOP function when the flashlight is disabled 2023-12-14 22:03:44 +01:00
Krzysiek Egzmont
fa5d3c1594 FIX #269: battery indicator always at 4 bars 2023-12-14 15:07:33 +01:00
Juan Antonio
1a53586922 Simplify logic in radio.c 2023-12-14 11:11:06 +01:00
Juan Antonio
687b63abb6 Fix signature 2023-12-14 11:11:06 +01:00
Juan Antonio
06f1c651bc Make LogUart receive a const char* const 2023-12-14 11:11:06 +01:00
Juan Antonio
33e4e3c4e0 Make AUDIO_PlayVoice static as it is only used inside of its module 2023-12-14 11:11:06 +01:00
Krzysiek Egzmont
93b97eff0a FIX #264: compilation error 2023-12-14 11:05:46 +01:00
egzumer
8638d37431 Update README.md 2023-12-13 19:19:29 +01:00
Krzysiek Egzmont
716e9e23b8 README.md - add Github Codespace building manual 2023-12-13 19:04:29 +01:00
Juan Antonio
d0ae34f9b4 Replace memmove by memcpy 2023-12-13 16:07:07 +01:00
Juan Antonio
bd17aea72b Make SETTINGS_InitEEPROM zero struct gEeprom 2023-12-13 16:07:07 +01:00
Juan Antonio
34d688b101 Logic simplification. Replace memmove by memcpy 2023-12-13 16:07:07 +01:00
Juan Antonio
8c7f736797 Simplify come battery logic 2023-12-13 16:07:07 +01:00
Juan Antonio
a19579a888 Make makefile options settable from envars 2023-12-13 16:07:07 +01:00
69 changed files with 2473 additions and 2586 deletions

4
.gitignore vendored
View File

@@ -6,4 +6,6 @@ firmware
/compiled-firmware
.cache
compile_commands.json
.vscode
.vscode
/docs
k5_eeprom.raw

17
Doxyfile Normal file
View File

@@ -0,0 +1,17 @@
OUTPUT_DIRECTORY = docs
GENERATE_LATEX = NO
GENERATE_RTF = NO
GENERATE_MAN = NO
OPTIMIZE_OUTPUT_FOR_C = YES
HAVE_DOT = YES
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
CALL_GRAPH = YES
CALLER_GRAPH = YES
DISABLE_INDEX = YES
GENERATE_TREEVIEW = YES
RECURSIVE = YES
COLLABORATION_GRAPH = YES
GRAPHICAL_HIERARCHY = YES
DOT_MULTI_TARGETS = YES

132
Makefile
View File

@@ -3,52 +3,54 @@
# 0 = disable
# 1 = enable
# ---- COMPILER/LINKER OPTIONS ----
ENABLE_CLANG := 0
ENABLE_SWD := 0
ENABLE_OVERLAY := 0
ENABLE_LTO := 1
# ---- STOCK QUANSHENG FERATURES ----
ENABLE_UART := 1
ENABLE_AIRCOPY := 0
ENABLE_FMRADIO := 1
ENABLE_NOAA := 0
ENABLE_VOICE := 0
ENABLE_VOX := 1
ENABLE_ALARM := 0
ENABLE_TX1750 := 0
ENABLE_PWRON_PASSWORD := 0
ENABLE_DTMF_CALLING := 1
ENABLE_FLASHLIGHT := 1
ENABLE_UART ?= 1
ENABLE_AIRCOPY ?= 0
ENABLE_FMRADIO ?= 1
ENABLE_NOAA ?= 0
ENABLE_VOICE ?= 0
ENABLE_VOX ?= 1
ENABLE_ALARM ?= 0
ENABLE_TX1750 ?= 0
ENABLE_PWRON_PASSWORD ?= 0
ENABLE_DTMF_CALLING ?= 1
ENABLE_FLASHLIGHT ?= 1
# ---- CUSTOM MODS ----
ENABLE_BIG_FREQ := 1
ENABLE_SMALL_BOLD := 1
ENABLE_KEEP_MEM_NAME := 1
ENABLE_WIDE_RX := 1
ENABLE_TX_WHEN_AM := 0
ENABLE_F_CAL_MENU := 0
ENABLE_CTCSS_TAIL_PHASE_SHIFT := 0
ENABLE_BOOT_BEEPS := 0
ENABLE_SHOW_CHARGE_LEVEL := 0
ENABLE_REVERSE_BAT_SYMBOL := 0
ENABLE_NO_CODE_SCAN_TIMEOUT := 1
ENABLE_AM_FIX := 1
ENABLE_SQUELCH_MORE_SENSITIVE := 1
ENABLE_FASTER_CHANNEL_SCAN := 1
ENABLE_RSSI_BAR := 1
ENABLE_AUDIO_BAR := 1
ENABLE_COPY_CHAN_TO_VFO := 1
ENABLE_SPECTRUM := 1
ENABLE_REDUCE_LOW_MID_TX_POWER:= 0
ENABLE_BYP_RAW_DEMODULATORS := 0
ENABLE_BLMIN_TMP_OFF := 0
ENABLE_SCAN_RANGES := 1
ENABLE_BIG_FREQ ?= 1
ENABLE_SMALL_BOLD ?= 1
ENABLE_CUSTOM_MENU_LAYOUT ?= 1
ENABLE_KEEP_MEM_NAME ?= 1
ENABLE_WIDE_RX ?= 1
ENABLE_TX_WHEN_AM ?= 0
ENABLE_F_CAL_MENU ?= 0
ENABLE_CTCSS_TAIL_PHASE_SHIFT ?= 0
ENABLE_BOOT_BEEPS ?= 0
ENABLE_SHOW_CHARGE_LEVEL ?= 0
ENABLE_REVERSE_BAT_SYMBOL ?= 0
ENABLE_NO_CODE_SCAN_TIMEOUT ?= 1
ENABLE_AM_FIX ?= 1
ENABLE_SQUELCH_MORE_SENSITIVE ?= 1
ENABLE_FASTER_CHANNEL_SCAN ?= 1
ENABLE_RSSI_BAR ?= 1
ENABLE_AUDIO_BAR ?= 1
ENABLE_COPY_CHAN_TO_VFO ?= 1
ENABLE_SPECTRUM ?= 1
ENABLE_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
ENABLE_AM_FIX_SHOW_DATA ?= 0
ENABLE_AGC_SHOW_DATA ?= 0
ENABLE_UART_RW_BK_REGS ?= 0
# ---- COMPILER/LINKER OPTIONS ----
ENABLE_CLANG ?= 0
ENABLE_SWD ?= 0
ENABLE_OVERLAY ?= 0
ENABLE_LTO ?= 1
#############################################################
@@ -167,24 +169,18 @@ OBJS += ui/welcome.o
OBJS += version.o
OBJS += main.o
ifeq ($(OS), Windows_NT)
TOP := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
else
TOP := $(shell pwd)
endif
ifdef OS # windows
RM = del /Q
FixPath = $(subst /,\,$1)
WHERE = where
NULL_OUTPUT = nul
ifeq ($(OS), Windows_NT) # windows
TOP := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
RM = del /Q
FixPath = $(subst /,\,$1)
WHERE = where
NULL_OUTPUT = nul
else # unix
ifeq ($(shell uname), Linux)
RM = rm -f
FixPath = $1
WHERE = which
NULL_OUTPUT = /dev/null
endif
TOP := $(shell pwd)
RM = rm -f
FixPath = $1
WHERE = which
NULL_OUTPUT = /dev/null
endif
AS = arm-none-eabi-gcc
@@ -204,15 +200,20 @@ endif
OBJCOPY = arm-none-eabi-objcopy
SIZE = arm-none-eabi-size
AUTHOR_STRING := EGZUMER
AUTHOR_STRING ?= EGZUMER
# the user might not have/want git installed
# can set own version string here (max 7 chars)
ifneq (, $(shell $(WHERE) git))
VERSION_STRING := $(shell git describe --tags --exact-match 2>$(NULL_OUTPUT))
VERSION_STRING ?= $(shell git describe --tags --exact-match 2>$(NULL_OUTPUT))
ifeq (, $(VERSION_STRING))
VERSION_STRING := $(shell git rev-parse --short HEAD)
endif
endif
# If there is still no VERSION_STRING we need to make one.
# It is needed for the firmware packing script
ifeq (, $(VERSION_STRING))
VERSION_STRING := NOGIT
endif
#VERSION_STRING := 230930b
@@ -317,7 +318,7 @@ ifeq ($(ENABLE_REVERSE_BAT_SYMBOL),1)
CFLAGS += -DENABLE_REVERSE_BAT_SYMBOL
endif
ifeq ($(ENABLE_NO_CODE_SCAN_TIMEOUT),1)
CFLAGS += -DENABLE_CODE_SCAN_TIMEOUT
CFLAGS += -DENABLE_NO_CODE_SCAN_TIMEOUT
endif
ifeq ($(ENABLE_AM_FIX),1)
CFLAGS += -DENABLE_AM_FIX
@@ -370,6 +371,12 @@ endif
ifeq ($(ENABLE_FLASHLIGHT),1)
CFLAGS += -DENABLE_FLASHLIGHT
endif
ifeq ($(ENABLE_UART_RW_BK_REGS),1)
CFLAGS += -DENABLE_UART_RW_BK_REGS
endif
ifeq ($(ENABLE_CUSTOM_MENU_LAYOUT),1)
CFLAGS += -DENABLE_CUSTOM_MENU_LAYOUT
endif
LDFLAGS =
LDFLAGS += -z noexecstack -mcpu=cortex-m0 -nostartfiles -Wl,-T,firmware.ld -Wl,--gc-sections
@@ -447,3 +454,6 @@ bsp/dp32g030/%.h: hardware/dp32g030/%.def
clean:
$(RM) $(call FixPath, $(TARGET).bin $(TARGET).packed.bin $(TARGET) $(OBJS) $(DEPS))
doxygen:
doxygen

149
README.md
View File

@@ -1,10 +1,13 @@
# Open re-implementation of the Quansheng UV-K5 v2.1.27 firmware
# Open re-implementation of the Quansheng UV-K5/K6/5R v2.1.27 firmware
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.
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 !
All is a cloned and customized version of DualTachyon's open firmware found here ..
https://github.com/DualTachyon/uv-k5-firmware .. a cool achievement !
> [!TIP]
> There is a work done by others on forks of this repository. I encourage you to take a look at those too.
You can use below links to see comparison between forks.<br>
https://gitpop2.vercel.app/egzumer/uv-k5-firmware-custom<br>
https://useful-forks.github.io/?repo=egzumer/uv-k5-firmware-custom
> [!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.
@@ -19,6 +22,7 @@ Anyway, have fun.
* [Compiler](#compiler)
* [Building](#building)
* [Credits](#credits)
* [Other sources of information](#other-sources-of-information)
* [License](#license)
* [Example changes/updates](#example-changesupdates)
@@ -47,24 +51,15 @@ Anyway, have fun.
* 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 s-meter style
* 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
* [Radio operation](https://github.com/egzumer/uv-k5-firmware-custom/wiki/Radio-operation)
* [Menu](https://github.com/egzumer/uv-k5-firmware-custom/wiki/Menu)
* [Button functions](https://github.com/egzumer/uv-k5-firmware-custom/wiki/Button-functions)
* [Spectrum analyzer](https://github.com/egzumer/uv-k5-firmware-custom/wiki/Spectrum-analyzer)
* [Flashing the firmware](https://github.com/egzumer/uv-k5-firmware-custom/wiki/Flashing-the-firmware)
<img src="images/main.jpg" width=300 /><img src="images/spectrum.jpg" width=300 /><img src="images/audiobar.jpg" width=300 /><img src="images/rssibar.jpg" width=300 />
Up to date manual is available in the [Wiki section](https://github.com/egzumer/uv-k5-firmware-custom/wiki)
## Radio performance
@@ -88,49 +83,55 @@ You can customize the firmware by enabling/disabling various compile options, th
us to remove certain firmware features in order to make room in the flash for others.
You'll find the options at the top of "Makefile" ('0' = disable, '1' = enable) ..
```
ENABLE_CLANG := 0 **experimental, builds with clang instead of gcc (LTO will be disabled if you enable this)
ENABLE_SWD := 0 only needed if using CPU's SWD port (debugging/programming)
ENABLE_OVERLAY := 0 cpu FLASH stuff, not needed
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_AIRCOPY := 0 easier to just enter frequency with butts
ENABLE_FMRADIO := 1 WBFM VHF broadcast band receiver
ENABLE_NOAA := 0 everything NOAA (only of any use in the USA)
ENABLE_VOICE := 0 want to hear voices ?
ENABLE_VOX := 1
ENABLE_ALARM := 0 TX alarms
ENABLE_TX1750 := 0 side key 1750Hz TX tone (older style repeater access)
ENABLE_PWRON_PASSWORD := 0 power-on password stuff
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_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_TX_WHEN_AM := 0 allow TX (always FM) when RX is set to AM
ENABLE_F_CAL_MENU := 0 enable the radios hidden frequency calibration menu
ENABLE_CTCSS_TAIL_PHASE_SHIFT := 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_SHOW_CHARGE_LEVEL := 1 show the charge level when the radio is on charge
ENABLE_REVERSE_BAT_SYMBOL := 0 mirror the battery symbol on the status bar (+ pole on the right)
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 help prevent AM demodulator saturation, ignore the on-screen RSSI level (for now)
ENABLE_AM_FIX_SHOW_DATA := 0 show debug data for the AM fix
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 := 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 in place of the little antenna symbols
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 `1 BAND` when in channel mode
ENABLE_SPECTRUM := 1 fagci spectrum analyzer, activated with `F` + `5 NOAA`
ENABLE_REDUCE_LOW_MID_TX_POWER:= 0 makes medium and low power settings even lower
ENABLE_BYP_RAW_DEMODULATORS := 0 additional BYP (bypass?) and RAW demodulation options, 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)
```
|Build option | Description |
| --- | ---- |
|🧰 **STOCK QUANSHENG FERATURES**||
| ENABLE_UART | without this you can't configure radio via PC ! |
| ENABLE_AIRCOPY | easier to just enter frequency with butts |
| ENABLE_FMRADIO | WBFM VHF broadcast band receiver |
| ENABLE_NOAA | everything NOAA (only of any use in the USA) |
| ENABLE_VOICE | want to hear voices ? |
| ENABLE_VOX | |
| ENABLE_ALARM | TX alarms |
| ENABLE_TX1750 | side key 1750Hz TX tone (older style repeater access)|
| ENABLE_PWRON_PASSWORD | power-on password stuff |
| ENABLE_DTMF_CALLING | DTMF calling fuctionality, sending calls, receiving calls, group calls, contacts list etc. |
| ENABLE_FLASHLIGHT | enable top flashlight LED (on, blink, SOS) |
|🧰 **CUSTOM MODS**||
| ENABLE_BIG_FREQ | big font frequencies (like original QS firmware) |
| ENABLE_SMALL_BOLD | bold channel name/no. (when name + freq channel display mode) |
| ENABLE_CUSTOM_MENU_LAYOUT | changes how the menu looks like |
| ENABLE_KEEP_MEM_NAME | maintain channel name when (re)saving memory channel|
| ENABLE_WIDE_RX | full 18MHz to 1300MHz RX (though front-end/PA not designed for full range)|
| ENABLE_TX_WHEN_AM | allow TX (always FM) when RX is set to AM|
| ENABLE_F_CAL_MENU | enable the radios hidden frequency calibration menu |
| ENABLE_CTCSS_TAIL_PHASE_SHIFT | standard CTCSS tail phase shift rather than QS's own 55Hz tone method|
| ENABLE_BOOT_BEEPS | gives user audio feedback on volume knob position at boot-up |
| ENABLE_SHOW_CHARGE_LEVEL | show the charge level when the radio is on charge |
| ENABLE_REVERSE_BAT_SYMBOL | mirror the battery symbol on the status bar (+ pole on the right) |
| ENABLE_NO_CODE_SCAN_TIMEOUT | disable 32-sec CTCSS/DCS scan timeout (press exit butt instead of time-out to end scan) |
| ENABLE_AM_FIX | 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 | show debug data for the AM fix |
| ENABLE_SQUELCH_MORE_SENSITIVE | make squelch levels a little bit more sensitive - I plan to let user adjust the values themselves |
| ENABLE_FASTER_CHANNEL_SCAN | increases the channel scan speed, but the squelch is also made more twitchy |
| ENABLE_RSSI_BAR | enable a dBm/Sn RSSI bar graph level in place of the little antenna symbols |
| ENABLE_AUDIO_BAR | experimental, display an audio bar level when TX'ing |
| ENABLE_COPY_CHAN_TO_VFO | copy current channel settings into frequency mode. Long press `1 BAND` when in channel mode |
| ENABLE_SPECTRUM | fagci spectrum analyzer, activated with `F` + `5 NOAA`|
| ENABLE_REDUCE_LOW_MID_TX_POWER | makes medium and low power settings even lower |
| ENABLE_BYP_RAW_DEMODULATORS | 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 | additional function for configurable buttons that toggles `BLMin` on and off wihout saving it to the EEPROM |
| ENABLE_SCAN_RANGES | scan range mode for frequency scanning, see wiki for instructions (radio operation -> frequency scanning) |
|🧰 **DEBUGGING** ||
| ENABLE_AM_FIX_SHOW_DATA| displays settings used by AM-fix when AM transmission is received |
| ENABLE_AGC_SHOW_DATA | displays AGC settings |
| ENABLE_UART_RW_BK_REGS | adds 2 extra commands that allow to read and write BK4819 registers |
|🧰 **COMPILER/LINKER OPTIONS**||
| ENABLE_CLANG | **experimental, builds with clang instead of gcc (LTO will be disabled if you enable this) |
| ENABLE_SWD | only needed if using CPU's SWD port (debugging/programming) |
| ENABLE_OVERLAY | cpu FLASH stuff, not needed |
| ENABLE_LTO | reduces size of compiled firmware but might break EEPROM reads (OVERLAY will be disabled if you enable this) |
## Compiler
@@ -143,10 +144,31 @@ You can get it from: https://releases.llvm.org/download.html
## Building
### 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.
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.
To compile directly in windows:
### Windows environment build method
1. Open windows command line and run:
```
@@ -191,6 +213,11 @@ Many thanks to various people on Telegram for putting up with me during this eff
* @d1ced95
* and others I forget
## 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

View File

@@ -30,6 +30,9 @@
#include "functions.h"
#include "misc.h"
#include "settings.h"
#ifdef ENABLE_AGC_SHOW_DATA
#include "ui/main.h"
#endif
#ifdef ENABLE_AM_FIX
@@ -120,7 +123,7 @@ static const t_gain_table gain_table[] =
{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
{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
@@ -140,8 +143,8 @@ static const t_gain_table gain_table[] =
{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
@@ -260,22 +263,11 @@ void AM_fix_10ms(const unsigned vfo)
if(!gSetting_AM_fix || !enabled || vfo > 1 )
return;
switch (gCurrentFunction)
{
case FUNCTION_TRANSMIT:
case FUNCTION_BAND_SCOPE:
case FUNCTION_POWER_SAVE:
if (gCurrentFunction != FUNCTION_FOREGROUND && !FUNCTION_IsRx()) {
#ifdef ENABLE_AM_FIX_SHOW_DATA
counter = display_update_rate; // queue up a display update as soon as we switch to RX mode
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
case FUNCTION_FOREGROUND:
case FUNCTION_RECEIVE:
case FUNCTION_MONITOR:
case FUNCTION_INCOMING:
break;
return;
}
#ifdef ENABLE_AM_FIX_SHOW_DATA
@@ -304,11 +296,11 @@ void AM_fix_10ms(const unsigned vfo)
#ifdef ENABLE_AM_FIX_SHOW_DATA
{
static int16_t lastRssi;
if (lastRssi != rssi) { // rssi changed
lastRssi = rssi;
if (counter == 0) {
if (counter == 0) {
counter = 1;
gUpdateDisplay = true; // trigger a display update
}
@@ -370,6 +362,9 @@ void AM_fix_10ms(const unsigned vfo)
gain_table_index_prev[vfo] = index;
currentGainDiff = gain_table[0].gain_dB - gain_table[index].gain_dB;
BK4819_WriteRegister(BK4819_REG_13, gain_table[index].reg_val);
#ifdef ENABLE_AGC_SHOW_DATA
UI_MAIN_PrintAGC(true);
#endif
}
#ifdef ENABLE_AM_FIX_SHOW_DATA

View File

@@ -57,7 +57,6 @@ inline static void ACTION_ScanRestart() { ACTION_Scan(true); };
void (*action_opt_table[])(void) = {
[ACTION_OPT_NONE] = &FUNCTION_NOP,
[ACTION_OPT_FLASHLIGHT] = &ACTION_FlashLight,
[ACTION_OPT_POWER] = &ACTION_Power,
[ACTION_OPT_MONITOR] = &ACTION_Monitor,
[ACTION_OPT_SCAN] = &ACTION_ScanRestart,
@@ -66,6 +65,12 @@ void (*action_opt_table[])(void) = {
[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
@@ -119,7 +124,7 @@ void ACTION_Monitor(void)
if (gCurrentFunction != FUNCTION_MONITOR) { // enable the monitor
RADIO_SelectVfos();
#ifdef ENABLE_NOAA
if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST && gIsNoaaMode)
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gIsNoaaMode)
gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
#endif
RADIO_SetupRegisters(true);
@@ -151,7 +156,7 @@ void ACTION_Monitor(void)
}
else
#endif
gRequestDisplayScreen = gScreenToDisplay;
gRequestDisplayScreen = gScreenToDisplay;
}
void ACTION_Scan(bool bRestart)
@@ -341,9 +346,8 @@ void ACTION_FM(void)
static void ACTION_Scan_FM(bool bRestart)
{
if (FUNCTION_IsRx()) {
if (FUNCTION_IsRx())
return;
}
GUI_SelectNextDisplay(DISPLAY_FM);
@@ -358,21 +362,21 @@ static void ACTION_Scan_FM(bool bRestart)
return;
}
uint16_t Frequency;
uint16_t freq;
if (bRestart) {
gFM_AutoScan = true;
gFM_AutoScan = true;
gFM_ChannelPosition = 0;
FM_EraseChannels();
Frequency = gEeprom.FM_LowerLimit;
freq = BK1080_GetFreqLoLimit(gEeprom.FM_Band);
} else {
gFM_AutoScan = false;
gFM_AutoScan = false;
gFM_ChannelPosition = 0;
Frequency = gEeprom.FM_FrequencyPlaying;
freq = gEeprom.FM_FrequencyPlaying;
}
BK1080_GetFrequencyDeviation(Frequency);
FM_Tune(Frequency, 1, bRestart);
BK1080_GetFrequencyDeviation(freq);
FM_Tune(freq, 1, bRestart);
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;

1030
app/app.c

File diff suppressed because it is too large Load Diff

View File

@@ -11,6 +11,7 @@ bool gScanPauseMode;
#ifdef ENABLE_SCAN_RANGES
uint32_t gScanRangeStart;
uint32_t gScanRangeStop;
#endif
typedef enum {
@@ -157,9 +158,7 @@ static void NextFreqChannel(void)
{
#ifdef ENABLE_SCAN_RANGES
if(gScanRangeStart) {
uint32_t start = gScanRangeStart;
uint32_t end = gEeprom.VfoInfo[(gEeprom.TX_VFO+1)%2].freq_config_RX.Frequency;
gRxVfo->freq_config_RX.Frequency = APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, MIN(start, end), MAX(start, end));
gRxVfo->freq_config_RX.Frequency = APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, gScanRangeStart, gScanRangeStop);
}
else
#endif

View File

@@ -12,6 +12,7 @@ extern bool gScanPauseMode;
#ifdef ENABLE_SCAN_RANGES
extern uint32_t gScanRangeStart;
extern uint32_t gScanRangeStop;
#endif
void CHFRSCANNER_Found(void);

View File

@@ -78,6 +78,40 @@ void DTMF_clear_RX(void)
}
#endif
void DTMF_SendEndOfTransmission(void)
{
if (gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO) {
BK4819_PlaySingleTone(2475, 250, 28, gEeprom.DTMF_SIDE_TONE);
}
if ((gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_TX_DOWN || gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_BOTH)
#ifdef ENABLE_DTMF_CALLING
&& gDTMF_CallState == DTMF_CALL_STATE_NONE
#endif
) { // end-of-tx
if (gEeprom.DTMF_SIDE_TONE) {
AUDIO_AudioPathOn();
gEnableSpeaker = true;
SYSTEM_DelayMs(60);
}
BK4819_EnterDTMF_TX(gEeprom.DTMF_SIDE_TONE);
BK4819_PlayDTMFString(
gEeprom.DTMF_DOWN_CODE,
0,
gEeprom.DTMF_FIRST_CODE_PERSIST_TIME,
gEeprom.DTMF_HASH_CODE_PERSIST_TIME,
gEeprom.DTMF_CODE_PERSIST_TIME,
gEeprom.DTMF_CODE_INTERVAL_TIME);
AUDIO_AudioPathOff();
gEnableSpeaker = false;
}
BK4819_ExitDTMF_TX(true);
}
bool DTMF_ValidateCodes(char *pCode, const unsigned int size)
{
unsigned int i;
@@ -103,34 +137,28 @@ bool DTMF_ValidateCodes(char *pCode, const unsigned int size)
#ifdef ENABLE_DTMF_CALLING
bool DTMF_GetContact(const int Index, char *pContact)
{
int i = -1;
if (Index >= 0 && Index < MAX_DTMF_CONTACTS && pContact != NULL)
{
EEPROM_ReadBuffer(0x1C00 + (Index * 16), pContact, 16);
i = (int)pContact[0] - ' ';
if (Index < 0 || Index >= MAX_DTMF_CONTACTS || pContact == NULL) {
return false;
}
return (i < 0 || i >= 95) ? false : true;
EEPROM_ReadBuffer(0x1C00 + (Index * 16), pContact, 16);
// check whether the first character is printable or not
return (pContact[0] >= ' ' && pContact[0] < 127);
}
bool DTMF_FindContact(const char *pContact, char *pResult)
{
char Contact[16];
unsigned int i;
pResult[0] = 0;
for (i = 0; i < MAX_DTMF_CONTACTS; i++)
{
unsigned int j;
if (!DTMF_GetContact(i, Contact))
for (unsigned int i = 0; i < MAX_DTMF_CONTACTS; i++) {
char Contact[16];
if (!DTMF_GetContact(i, Contact)) {
return false;
}
for (j = 0; j < 3; j++)
if (pContact[j] != Contact[j + 8])
break;
if (j == 3)
{
memmove(pResult, Contact, 8);
if (memcmp(pContact, Contact + 8, 3) == 0) {
memcpy(pResult, Contact, 8);
pResult[8] = 0;
return true;
}
@@ -183,12 +211,12 @@ static bool CompareMessage(const char *pMsg, const char *pTemplate, const unsign
DTMF_CallMode_t DTMF_CheckGroupCall(const char *pMsg, const unsigned int size)
{
unsigned int i;
for (i = 0; i < size; i++)
if (pMsg[i] == gEeprom.DTMF_GROUP_CALL_CODE)
break;
for (unsigned int i = 0; i < size; i++)
if (pMsg[i] == gEeprom.DTMF_GROUP_CALL_CODE) {
return DTMF_CALL_MODE_GROUP;
}
return (i < size) ? DTMF_CALL_MODE_GROUP : DTMF_CALL_MODE_NOT_GROUP;
return DTMF_CALL_MODE_NOT_GROUP;
}
#endif
@@ -303,13 +331,12 @@ void DTMF_HandleRequest(void)
if (gDTMF_RX_index >= 2)
{ // look for ACK reply
char *pPrintStr = "AB";
strcpy(String, "AB");
Offset = gDTMF_RX_index - strlen(pPrintStr);
Offset = gDTMF_RX_index - strlen(String);
if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
{ // ends with "AB"
if (CompareMessage(gDTMF_RX + Offset, pPrintStr, strlen(pPrintStr), true)) {
// ends with "AB"
if (gDTMF_ReplyState != DTMF_REPLY_NONE) // 1of11
// if (gDTMF_CallState != DTMF_CALL_STATE_NONE) // 1of11
@@ -361,8 +388,8 @@ void DTMF_HandleRequest(void)
memset(gDTMF_Callee, 0, sizeof(gDTMF_Callee));
memset(gDTMF_Caller, 0, sizeof(gDTMF_Caller));
memmove(gDTMF_Callee, gDTMF_RX + Offset + 0, 3);
memmove(gDTMF_Caller, gDTMF_RX + Offset + 4, 3);
memcpy(gDTMF_Callee, gDTMF_RX + Offset + 0, 3);
memcpy(gDTMF_Caller, gDTMF_RX + Offset + 4, 3);
DTMF_clear_RX();
@@ -410,7 +437,7 @@ void DTMF_Reply(void)
sprintf(String, "%s%c%s", gDTMF_String, gEeprom.DTMF_SEPARATE_CODE, gEeprom.ANI_DTMF_ID);
pString = String;
}
else
else
#endif
{
pString = gDTMF_String;

View File

@@ -78,7 +78,17 @@ extern uint8_t gDTMF_PreviousIndex;
extern char gDTMF_RX_live[20];
extern uint8_t gDTMF_RX_live_timeout;
extern DTMF_ReplyState_t gDTMF_ReplyState;
bool DTMF_ValidateCodes(char *pCode, const unsigned int size);
char DTMF_GetCharacter(const unsigned int code);
void DTMF_clear_input_box(void);
void DTMF_Append(const char code);
void DTMF_Reply(void);
void DTMF_SendEndOfTransmission(void);
#ifdef ENABLE_DTMF_CALLING
extern char gDTMF_RX[17];
extern uint8_t gDTMF_RX_index;
extern uint8_t gDTMF_RX_timeout;
@@ -97,21 +107,13 @@ extern DTMF_CallState_t gDTMF_CallState;
extern DTMF_CallMode_t gDTMF_CallMode;
extern bool gDTMF_IsTx;
extern uint8_t gDTMF_TxStopCountdown_500ms;
#endif
extern DTMF_ReplyState_t gDTMF_ReplyState;
bool DTMF_ValidateCodes(char *pCode, const unsigned int size);
char DTMF_GetCharacter(const unsigned int code);
void DTMF_clear_input_box(void);
void DTMF_Append(const char vode);
void DTMF_Reply(void);
#ifdef ENABLE_DTMF_CALLING
void DTMF_clear_RX(void);
DTMF_CallMode_t DTMF_CheckGroupCall(const char *pDTMF, const unsigned int size);
bool DTMF_GetContact(const int Index, char *pContact);
bool DTMF_FindContact(const char *pContact, char *pResult);
void DTMF_HandleRequest(void);
#endif
#endif

294
app/fm.c
View File

@@ -62,19 +62,17 @@ static void Key_FUNC(KEY_Code_t Key, uint8_t state);
bool FM_CheckValidChannel(uint8_t Channel)
{
return (Channel < ARRAY_SIZE(gFM_Channels) && (gFM_Channels[Channel] >= 760 && gFM_Channels[Channel] < 1080));
return Channel < ARRAY_SIZE(gFM_Channels) &&
gFM_Channels[Channel] >= BK1080_GetFreqLoLimit(gEeprom.FM_Band) &&
gFM_Channels[Channel] < BK1080_GetFreqHiLimit(gEeprom.FM_Band);
}
uint8_t FM_FindNextChannel(uint8_t Channel, uint8_t Direction)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(gFM_Channels); i++)
{
for (unsigned i = 0; i < ARRAY_SIZE(gFM_Channels); i++) {
if (Channel == 0xFF)
Channel = ARRAY_SIZE(gFM_Channels) - 1;
else
if (Channel >= ARRAY_SIZE(gFM_Channels))
else if (Channel >= ARRAY_SIZE(gFM_Channels))
Channel = 0;
if (FM_CheckValidChannel(Channel))
return Channel;
@@ -88,11 +86,9 @@ int FM_ConfigureChannelState(void)
{
gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency;
if (gEeprom.FM_IsMrMode)
{
if (gEeprom.FM_IsMrMode) {
const uint8_t Channel = FM_FindNextChannel(gEeprom.FM_SelectedChannel, FM_CHANNEL_UP);
if (Channel == 0xFF)
{
if (Channel == 0xFF) {
gEeprom.FM_IsMrMode = false;
return -1;
}
@@ -110,21 +106,19 @@ void FM_TurnOff(void)
gFM_RestoreCountdown_10ms = 0;
AUDIO_AudioPathOff();
gEnableSpeaker = false;
BK1080_Init(0, false);
BK1080_Init0();
gUpdateStatus = true;
}
void FM_EraseChannels(void)
{
unsigned int i;
uint8_t Template[8];
memset(Template, 0xFF, sizeof(Template));
for (i = 0; i < 5; i++)
for (unsigned i = 0; i < 5; i++)
EEPROM_WriteBuffer(0x0E40 + (i * 8), Template);
memset(gFM_Channels, 0xFF, sizeof(gFM_Channels));
@@ -144,35 +138,32 @@ void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag)
gAskToDelete = false;
gEeprom.FM_FrequencyPlaying = Frequency;
if (!bFlag)
{
if (!bFlag) {
Frequency += Step;
if (Frequency < gEeprom.FM_LowerLimit)
Frequency = gEeprom.FM_UpperLimit;
else
if (Frequency > gEeprom.FM_UpperLimit)
Frequency = gEeprom.FM_LowerLimit;
if (Frequency < BK1080_GetFreqLoLimit(gEeprom.FM_Band))
Frequency = BK1080_GetFreqHiLimit(gEeprom.FM_Band);
else if (Frequency > BK1080_GetFreqHiLimit(gEeprom.FM_Band))
Frequency = BK1080_GetFreqLoLimit(gEeprom.FM_Band);
gEeprom.FM_FrequencyPlaying = Frequency;
}
gFM_ScanState = Step;
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/);
}
void FM_PlayAndUpdate(void)
{
gFM_ScanState = FM_SCAN_OFF;
if (gFM_AutoScan)
{
if (gFM_AutoScan) {
gEeprom.FM_IsMrMode = true;
gEeprom.FM_SelectedChannel = 0;
}
FM_ConfigureChannelState();
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/);
SETTINGS_SaveFM();
gFmPlayCountdown_10ms = 0;
@@ -193,7 +184,7 @@ int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit)
// This is supposed to be a signed value, but above function is unsigned
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;
}
@@ -219,7 +210,6 @@ int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit)
if (Frequency >= LowerLimit && (BK1080_BaseFrequency - Frequency) == 1) {
if ((BK1080_FrequencyDeviation & 0x800) == 0 || (BK1080_FrequencyDeviation > 4075))
goto Bail;
}
ret = 0;
@@ -236,93 +226,93 @@ static void Key_DIGITS(KEY_Code_t Key, uint8_t state)
enum { STATE_FREQ_MODE, STATE_MR_MODE, STATE_SAVE };
if (state == BUTTON_EVENT_SHORT && !gWasFKeyPressed) {
uint8_t State;
uint8_t State;
if (gAskToDelete) {
if (gAskToDelete) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gAskToSave) {
State = STATE_SAVE;
}
else {
if (gFM_ScanState != FM_SCAN_OFF) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gAskToSave) {
State = STATE_SAVE;
State = gEeprom.FM_IsMrMode ? STATE_MR_MODE : STATE_FREQ_MODE;
}
INPUTBOX_Append(Key);
gRequestDisplayScreen = DISPLAY_FM;
if (State == STATE_FREQ_MODE) {
if (gInputBoxIndex == 1) {
if (gInputBox[0] > 1) {
gInputBox[1] = gInputBox[0];
gInputBox[0] = 0;
gInputBoxIndex = 2;
}
}
else {
if (gFM_ScanState != FM_SCAN_OFF) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
else if (gInputBoxIndex > 3) {
uint32_t Frequency;
gInputBoxIndex = 0;
Frequency = StrToUL(INPUTBOX_GetAscii());
if (Frequency < BK1080_GetFreqLoLimit(gEeprom.FM_Band) || BK1080_GetFreqHiLimit(gEeprom.FM_Band) < Frequency) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
gRequestDisplayScreen = DISPLAY_FM;
return;
}
State = gEeprom.FM_IsMrMode ? STATE_MR_MODE : STATE_FREQ_MODE;
gEeprom.FM_SelectedFrequency = (uint16_t)Frequency;
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency;
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/);
gRequestSaveFM = true;
return;
}
}
else if (gInputBoxIndex == 2) {
uint8_t Channel;
INPUTBOX_Append(Key);
gInputBoxIndex = 0;
Channel = ((gInputBox[0] * 10) + gInputBox[1]) - 1;
gRequestDisplayScreen = DISPLAY_FM;
if (State == STATE_FREQ_MODE) {
if (gInputBoxIndex == 1) {
if (gInputBox[0] > 1) {
gInputBox[1] = gInputBox[0];
gInputBox[0] = 0;
gInputBoxIndex = 2;
}
}
else if (gInputBoxIndex > 3) {
uint32_t Frequency;
gInputBoxIndex = 0;
Frequency = StrToUL(INPUTBOX_GetAscii());
if (Frequency < gEeprom.FM_LowerLimit || gEeprom.FM_UpperLimit < Frequency) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
gRequestDisplayScreen = DISPLAY_FM;
return;
}
gEeprom.FM_SelectedFrequency = (uint16_t)Frequency;
if (State == STATE_MR_MODE) {
if (FM_CheckValidChannel(Channel)) {
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency;
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
gEeprom.FM_SelectedChannel = Channel;
gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel];
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/);
gRequestSaveFM = true;
return;
}
}
else if (gInputBoxIndex == 2) {
uint8_t Channel;
else if (Channel < 20) {
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gRequestDisplayScreen = DISPLAY_FM;
gInputBoxIndex = 0;
Channel = ((gInputBox[0] * 10) + gInputBox[1]) - 1;
if (State == STATE_MR_MODE) {
if (FM_CheckValidChannel(Channel)) {
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gEeprom.FM_SelectedChannel = Channel;
gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel];
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
gRequestSaveFM = true;
return;
}
}
else if (Channel < 20) {
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gRequestDisplayScreen = DISPLAY_FM;
gInputBoxIndex = 0;
gFM_ChannelPosition = Channel;
return;
}
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
gFM_ChannelPosition = Channel;
return;
}
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
}
else
@@ -331,8 +321,7 @@ static void Key_DIGITS(KEY_Code_t Key, uint8_t state)
static void Key_FUNC(KEY_Code_t Key, uint8_t state)
{
if (state == BUTTON_EVENT_SHORT || state == BUTTON_EVENT_HELD)
{
if (state == BUTTON_EVENT_SHORT || state == BUTTON_EVENT_HELD) {
bool autoScan = gWasFKeyPressed || (state == BUTTON_EVENT_HELD);
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
@@ -345,12 +334,21 @@ static void Key_FUNC(KEY_Code_t Key, uint8_t state)
ACTION_FM();
break;
case KEY_1:
gEeprom.FM_Band++;
gRequestSaveFM = true;
break;
// case KEY_2:
// gEeprom.FM_Space = (gEeprom.FM_Space + 1) % 3;
// gRequestSaveFM = true;
// break;
case KEY_3:
gEeprom.FM_IsMrMode = !gEeprom.FM_IsMrMode;
if (!FM_ConfigureChannelState())
{
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
if (!FM_ConfigureChannelState()) {
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/);
gRequestSaveFM = true;
}
else
@@ -375,12 +373,9 @@ static void Key_EXIT(uint8_t state)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gFM_ScanState == FM_SCAN_OFF)
{
if (gInputBoxIndex == 0)
{
if (!gAskToSave && !gAskToDelete)
{
if (gFM_ScanState == FM_SCAN_OFF) {
if (gInputBoxIndex == 0) {
if (!gAskToSave && !gAskToDelete) {
ACTION_FM();
return;
}
@@ -388,38 +383,32 @@ static void Key_EXIT(uint8_t state)
gAskToSave = false;
gAskToDelete = false;
}
else
{
else {
gInputBox[--gInputBoxIndex] = 10;
if (gInputBoxIndex)
{
if (gInputBoxIndex != 1)
{
if (gInputBoxIndex) {
if (gInputBoxIndex != 1) {
gRequestDisplayScreen = DISPLAY_FM;
return;
}
if (gInputBox[0] != 0)
{
if (gInputBox[0] != 0) {
gRequestDisplayScreen = DISPLAY_FM;
return;
}
}
gInputBoxIndex = 0;
}
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
}
else
{
else {
FM_PlayAndUpdate();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
gRequestDisplayScreen = DISPLAY_FM;
@@ -434,43 +423,34 @@ static void Key_MENU(uint8_t state)
gRequestDisplayScreen = DISPLAY_FM;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gFM_ScanState == FM_SCAN_OFF)
{
if (!gEeprom.FM_IsMrMode)
{
if (gAskToSave)
{
if (gFM_ScanState == FM_SCAN_OFF) {
if (!gEeprom.FM_IsMrMode) {
if (gAskToSave) {
gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying;
gRequestSaveFM = true;
}
gAskToSave = !gAskToSave;
}
else
{
if (gAskToDelete)
{
else {
if (gAskToDelete) {
gFM_Channels[gEeprom.FM_SelectedChannel] = 0xFFFF;
FM_ConfigureChannelState();
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/);
gRequestSaveFM = true;
}
gAskToDelete = !gAskToDelete;
}
}
else
{
if (gFM_AutoScan || !gFM_FoundFrequency)
{
else {
if (gFM_AutoScan || !gFM_FoundFrequency) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
gInputBoxIndex = 0;
return;
}
if (gAskToSave)
{
if (gAskToSave) {
gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying;
gRequestSaveFM = true;
}
@@ -519,11 +499,10 @@ static void Key_UP_DOWN(uint8_t state, int8_t Step)
else {
uint16_t Frequency = gEeprom.FM_SelectedFrequency + Step;
if (Frequency < gEeprom.FM_LowerLimit)
Frequency = gEeprom.FM_UpperLimit;
else
if (Frequency > gEeprom.FM_UpperLimit)
Frequency = gEeprom.FM_LowerLimit;
if (Frequency < BK1080_GetFreqLoLimit(gEeprom.FM_Band))
Frequency = BK1080_GetFreqHiLimit(gEeprom.FM_Band);
else if (Frequency > BK1080_GetFreqHiLimit(gEeprom.FM_Band))
Frequency = BK1080_GetFreqLoLimit(gEeprom.FM_Band);
gEeprom.FM_FrequencyPlaying = Frequency;
gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying;
@@ -532,7 +511,7 @@ static void Key_UP_DOWN(uint8_t state, int8_t Step)
gRequestSaveFM = true;
Bail:
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/);
gRequestDisplayScreen = DISPLAY_FM;
}
@@ -541,18 +520,8 @@ void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
uint8_t state = bKeyPressed + 2 * bKeyHeld;
switch (Key)
{
case KEY_0:
case KEY_1:
case KEY_2:
case KEY_3:
case KEY_4:
case KEY_5:
case KEY_6:
case KEY_7:
case KEY_8:
case KEY_9:
switch (Key) {
case KEY_0...KEY_9:
Key_DIGITS(Key, state);
break;
case KEY_STAR:
@@ -585,10 +554,8 @@ void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
void FM_Play(void)
{
if (!FM_CheckFrequencyLock(gEeprom.FM_FrequencyPlaying, gEeprom.FM_LowerLimit))
{
if (!gFM_AutoScan)
{
if (!FM_CheckFrequencyLock(gEeprom.FM_FrequencyPlaying, BK1080_GetFreqLoLimit(gEeprom.FM_Band))) {
if (!gFM_AutoScan) {
gFmPlayCountdown_10ms = 0;
gFM_FoundFrequency = true;
@@ -605,15 +572,14 @@ void FM_Play(void)
if (gFM_ChannelPosition < 20)
gFM_Channels[gFM_ChannelPosition++] = gEeprom.FM_FrequencyPlaying;
if (gFM_ChannelPosition >= 20)
{
if (gFM_ChannelPosition >= 20) {
FM_PlayAndUpdate();
GUI_SelectNextDisplay(DISPLAY_FM);
return;
}
}
if (gFM_AutoScan && gEeprom.FM_FrequencyPlaying >= gEeprom.FM_UpperLimit)
if (gFM_AutoScan && gEeprom.FM_FrequencyPlaying >= BK1080_GetFreqHiLimit(1))
FM_PlayAndUpdate();
else
FM_Tune(gEeprom.FM_FrequencyPlaying, gFM_ScanState, false);
@@ -628,7 +594,7 @@ void FM_Start(void)
gFM_ScanState = FM_SCAN_OFF;
gFM_RestoreCountdown_10ms = 0;
BK1080_Init(gEeprom.FM_FrequencyPlaying, true);
BK1080_Init(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/);
AUDIO_AudioPathOn();

View File

@@ -41,6 +41,7 @@ extern bool gFM_FoundFrequency;
extern uint16_t gFM_RestoreCountdown_10ms;
bool FM_CheckValidChannel(uint8_t Channel);
// returns first valid channel starting at Channel
uint8_t FM_FindNextChannel(uint8_t Channel, uint8_t Direction);
int FM_ConfigureChannelState(void);
void FM_TurnOff(void);

View File

@@ -39,17 +39,14 @@
void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
{
if (gInputBoxIndex > 0)
{
if (gInputBoxIndex > 0) {
if (!bKeyHeld && bKeyPressed) // short pressed
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (bKeyHeld || !bKeyPressed) // held or released
{
if (bKeyHeld || bKeyPressed) // held or pressed (cannot be held and not pressed I guess, so it checks only if HELD?)
{
if (bKeyHeld || !bKeyPressed) { // held or released
if (bKeyHeld || bKeyPressed) { // held or pressed (cannot be held and not pressed I guess, so it checks only if HELD?)
if (!bKeyHeld) // won't ever pass
return;
@@ -58,47 +55,43 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
COMMON_KeypadLockToggle();
}
else // released
{
#ifdef ENABLE_FMRADIO
if ((gFmRadioMode || gScreenToDisplay != DISPLAY_MAIN) && gScreenToDisplay != DISPLAY_FM)
return;
#else
if (gScreenToDisplay != DISPLAY_MAIN)
return;
#endif
else { // released
#ifdef ENABLE_FMRADIO
if ((gFmRadioMode || gScreenToDisplay != DISPLAY_MAIN) && gScreenToDisplay != DISPLAY_FM)
return;
#else
if (gScreenToDisplay != DISPLAY_MAIN)
return;
#endif
gWasFKeyPressed = !gWasFKeyPressed; // toggle F function
if (gWasFKeyPressed)
gKeyInputCountdown = key_input_timeout_500ms;
#ifdef ENABLE_VOICE
if (!gWasFKeyPressed)
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
#ifdef ENABLE_VOICE
if (!gWasFKeyPressed)
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
gUpdateStatus = true;
}
}
else // short pressed
{
else { // short pressed
#ifdef ENABLE_FMRADIO
if (gScreenToDisplay != DISPLAY_FM)
#endif
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
#ifdef ENABLE_FMRADIO
if (gFM_ScanState == FM_SCAN_OFF) // not scanning
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
#endif
#ifdef ENABLE_FMRADIO
if (gFM_ScanState == FM_SCAN_OFF) { // not scanning
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
#endif
gBeepToPlay = BEEP_440HZ_500MS;
gPttWasReleased = true;
}
}
@@ -109,29 +102,24 @@ void GENERIC_Key_PTT(bool bKeyPressed)
if (!bKeyPressed || SerialConfigInProgress())
{ // PTT released
if (gCurrentFunction == FUNCTION_TRANSMIT)
{ // we are transmitting .. stop
if (gFlagEndTransmission)
{
if (gCurrentFunction == FUNCTION_TRANSMIT) {
// we are transmitting .. stop
if (gFlagEndTransmission) {
FUNCTION_Select(FUNCTION_FOREGROUND);
}
else
{
else {
APP_EndTransmission();
if (gEeprom.REPEATER_TAIL_TONE_ELIMINATION == 0)
FUNCTION_Select(FUNCTION_FOREGROUND);
else
gRTTECountdown = gEeprom.REPEATER_TAIL_TONE_ELIMINATION * 10;
gRTTECountdown_10ms = gEeprom.REPEATER_TAIL_TONE_ELIMINATION * 10;
}
gFlagEndTransmission = false;
#ifdef ENABLE_VOX
gVOX_NoiseDetected = false;
#endif
#ifdef ENABLE_VOX
gVOX_NoiseDetected = false;
#endif
RADIO_SetVfoState(VFO_STATE_NORMAL);
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
@@ -144,27 +132,24 @@ void GENERIC_Key_PTT(bool bKeyPressed)
// PTT pressed
if (SCANNER_IsScanning())
{ // CTCSS/CDCSS scanning .. stop
SCANNER_Stop();
if (SCANNER_IsScanning()) {
SCANNER_Stop(); // CTCSS/CDCSS scanning .. stop
goto cancel_tx;
}
if (gScanStateDir != SCAN_OFF)
{ // frequency/channel scanning . .stop
CHFRSCANNER_Stop();
if (gScanStateDir != SCAN_OFF) {
CHFRSCANNER_Stop(); // frequency/channel scanning . .stop
goto cancel_tx;
}
#ifdef ENABLE_FMRADIO
if (gFM_ScanState != FM_SCAN_OFF)
{ // FM radio is scanning .. stop
if (gFM_ScanState != FM_SCAN_OFF) { // FM radio is scanning .. stop
FM_PlayAndUpdate();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
gRequestDisplayScreen = DISPLAY_FM;
goto cancel_tx;
}
@@ -175,8 +160,7 @@ void GENERIC_Key_PTT(bool bKeyPressed)
goto start_tx; // listening to the FM radio .. start TX'ing
#endif
if (gCurrentFunction == FUNCTION_TRANSMIT && gRTTECountdown == 0)
{ // already transmitting
if (gCurrentFunction == FUNCTION_TRANSMIT && gRTTECountdown_10ms == 0) {// already transmitting
gInputBoxIndex = 0;
return;
}
@@ -190,9 +174,7 @@ void GENERIC_Key_PTT(bool bKeyPressed)
// was entering a DTMF string
if (gDTMF_InputBox_Index > 0 || gDTMF_PreviousIndex > 0)
{ // going to transmit a DTMF string
if (gDTMF_InputBox_Index > 0 || gDTMF_PreviousIndex > 0) { // going to transmit a DTMF string
if (gDTMF_InputBox_Index == 0 && gDTMF_PreviousIndex > 0)
gDTMF_InputBox_Index = gDTMF_PreviousIndex; // use the previous DTMF string
@@ -221,17 +203,23 @@ start_tx:
// request start TX
gFlagPrepareTX = true;
goto done;
cancel_tx:
if (gPttIsPressed)
{
if (gPttIsPressed) {
gPttWasPressed = true;
}
done:
done:
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;
}
gUpdateStatus = true;
gUpdateDisplay = true;
}

View File

@@ -52,6 +52,9 @@ void toggle_chan_scanlist(void)
if(!IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
#ifdef ENABLE_SCAN_RANGES
gScanRangeStart = gScanRangeStart ? 0 : gTxVfo->pRX->Frequency;
gScanRangeStop = gEeprom.VfoInfo[!gEeprom.TX_VFO].freq_config_RX.Frequency;
if(gScanRangeStart > gScanRangeStop)
SWAP(gScanRangeStart, gScanRangeStop);
#endif
return;
}
@@ -72,27 +75,17 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
{
uint8_t Vfo = gEeprom.TX_VFO;
if (gScreenToDisplay == DISPLAY_MENU)
{
// if (beep)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
if (gScreenToDisplay == DISPLAY_MENU) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
// if (beep)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
switch (Key)
{
switch (Key) {
case KEY_0:
#ifdef ENABLE_FMRADIO
ACTION_FM();
#else
// TODO: make use of this function key
#endif
break;
@@ -103,14 +96,12 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
#ifdef ENABLE_COPY_CHAN_TO_VFO
if (!gEeprom.VFO_OPEN || gCssBackgroundScan)
{
if (!gEeprom.VFO_OPEN || gCssBackgroundScan) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gScanStateDir != SCAN_OFF)
{
if (gScanStateDir != SCAN_OFF) {
if (gCurrentFunction != FUNCTION_INCOMING ||
gRxReceptionMode == RX_MODE_NONE ||
gScanPauseDelayIn_10ms == 0)
@@ -146,7 +137,6 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
return;
}
#endif
gTxVfo->Band += 1;
if (gTxVfo->Band == BAND5_350MHz && !gSetting_350EN) {
@@ -201,13 +191,10 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
case KEY_5:
if(beep) {
#ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_VFO];
}
else
{
else {
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_VFO];
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
@@ -246,8 +233,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break;
case KEY_9:
if (RADIO_CheckValidChannel(gEeprom.CHAN_1_CALL, false, 0))
{
if (RADIO_CheckValidChannel(gEeprom.CHAN_1_CALL, false, 0)) {
gEeprom.MrChannel[Vfo] = gEeprom.CHAN_1_CALL;
gEeprom.ScreenChannel[Vfo] = gEeprom.CHAN_1_CALL;
#ifdef ENABLE_VOICE
@@ -276,15 +262,10 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
if (bKeyHeld)
{ // key held down
if (bKeyPressed)
{
if (gScreenToDisplay == DISPLAY_MAIN)
{
if (gInputBoxIndex > 0)
{ // delete any inputted chars
if (bKeyHeld) { // key held down
if (bKeyPressed) {
if (gScreenToDisplay == DISPLAY_MAIN) {
if (gInputBoxIndex > 0) { // delete any inputted chars
gInputBoxIndex = 0;
gRequestDisplayScreen = DISPLAY_MAIN;
}
@@ -295,7 +276,6 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
processFKeyFunction(Key, false);
}
}
return;
}
@@ -305,22 +285,15 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
return; // don't use the key till it's released
}
if (!gWasFKeyPressed)
{ // F-key wasn't pressed
if (!gWasFKeyPressed) { // F-key wasn't pressed
const uint8_t Vfo = gEeprom.TX_VFO;
gKeyInputCountdown = key_input_timeout_500ms;
INPUTBOX_Append(Key);
gRequestDisplayScreen = DISPLAY_MAIN;
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // user is entering channel number
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) { // user is entering channel number
if (gInputBoxIndex != 3)
{
if (gInputBoxIndex != 3) {
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
@@ -332,8 +305,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
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)) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
@@ -360,8 +332,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
bool isGigaF = gTxVfo->pRX->Frequency >= _1GHz_in_KHz;
if (gInputBoxIndex < 6 + isGigaF)
{
if (gInputBoxIndex < 6 + isGigaF) {
return;
}
@@ -369,26 +340,20 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
uint32_t Frequency = StrToUL(INPUTBOX_GetAscii()) * 100;
// clamp the frequency entered to some valid value
if (Frequency < frequencyBandTable[0].lower)
{
if (Frequency < frequencyBandTable[0].lower) {
Frequency = frequencyBandTable[0].lower;
}
else
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
{
else if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) {
const uint32_t center = (BX4819_band1.upper + BX4819_band2.lower) / 2;
Frequency = (Frequency < center) ? BX4819_band1.upper : BX4819_band2.lower;
}
else
if (Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper)
{
else if (Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper) {
Frequency = frequencyBandTable[BAND_N_ELEM - 1].upper;
}
const FREQUENCY_Band_t band = FREQUENCY_GetBand(Frequency);
if (gTxVfo->Band != band)
{
if (gTxVfo->Band != band) {
gTxVfo->Band = band;
gEeprom.ScreenChannel[Vfo] = band + FREQ_CHANNEL_FIRST;
gEeprom.FreqChannel[Vfo] = band + FREQ_CHANNEL_FIRST;
@@ -416,8 +381,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
else
if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // user is entering NOAA channel
if (gInputBoxIndex != 2)
{
if (gInputBoxIndex != 2) {
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
@@ -428,8 +392,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gInputBoxIndex = 0;
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;
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
@@ -456,9 +419,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{ // exit key pressed
if (!bKeyHeld && bKeyPressed) { // exit key pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
#ifdef ENABLE_DTMF_CALLING
@@ -470,47 +431,42 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
}
#endif
#ifdef ENABLE_FMRADIO
if (!gFmRadioMode)
#endif
#ifdef ENABLE_FMRADIO
if (!gFmRadioMode)
#endif
{
if (gScanStateDir == SCAN_OFF)
{
if (gScanStateDir == SCAN_OFF) {
if (gInputBoxIndex == 0)
return;
gInputBox[--gInputBoxIndex] = 10;
gKeyInputCountdown = key_input_timeout_500ms;
#ifdef ENABLE_VOICE
if (gInputBoxIndex == 0)
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
#ifdef ENABLE_VOICE
if (gInputBoxIndex == 0)
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
}
else
{
else {
gScanKeepResult = false;
CHFRSCANNER_Stop();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
gRequestDisplayScreen = DISPLAY_MAIN;
return;
}
#ifdef ENABLE_FMRADIO
ACTION_FM();
#endif
#ifdef ENABLE_FMRADIO
ACTION_FM();
#endif
return;
}
if (bKeyHeld && bKeyPressed)
{ // exit key held down
if (bKeyHeld && bKeyPressed) { // exit key held down
if (gInputBoxIndex > 0 || gDTMF_InputBox_Index > 0 || gDTMF_InputMode)
{ // cancel key input mode (channel/frequency entry)
gDTMF_InputMode = false;
@@ -525,22 +481,16 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
{
if (bKeyPressed && !bKeyHeld)
// menu key pressed
if (bKeyPressed && !bKeyHeld) // menu key pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (bKeyHeld)
{ // menu key held down (long press)
if (bKeyPressed)
{ // long press MENU key
if (bKeyHeld) { // menu key held down (long press)
if (bKeyPressed) { // long press MENU key
gWasFKeyPressed = false;
if (gScreenToDisplay == DISPLAY_MAIN)
{
if (gInputBoxIndex > 0)
{ // delete any inputted chars
if (gScreenToDisplay == DISPLAY_MAIN) {
if (gInputBoxIndex > 0) { // delete any inputted chars
gInputBoxIndex = 0;
gRequestDisplayScreen = DISPLAY_MAIN;
}
@@ -555,13 +505,11 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
return;
}
if (!bKeyPressed && !gDTMF_InputMode)
{ // menu key released
if (!bKeyPressed && !gDTMF_InputMode) { // menu key released
const bool bFlag = !gInputBoxIndex;
gInputBoxIndex = 0;
if (bFlag)
{
if (bFlag) {
if (gScanStateDir != SCAN_OFF) {
CHFRSCANNER_Stop();
return;
@@ -573,8 +521,7 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
gAnotherVoiceID = VOICE_ID_MENU;
#endif
}
else
{
else {
gRequestDisplayScreen = DISPLAY_MAIN;
}
}
@@ -585,15 +532,13 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
if (gCurrentFunction == FUNCTION_TRANSMIT)
return;
if (gInputBoxIndex)
{
if (gInputBoxIndex) {
if (!bKeyHeld && bKeyPressed)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (bKeyHeld && !gWasFKeyPressed) // long press
{
if (bKeyHeld && !gWasFKeyPressed){ // long press
if (!bKeyPressed) // released
return;
@@ -603,8 +548,7 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
return;
}
if (bKeyPressed) // just pressed
{
if (bKeyPressed) { // just pressed
return;
}
@@ -622,7 +566,7 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
)
{ // 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_InputMode = true;
@@ -643,7 +587,6 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
return;
}
#endif
// scan the CTCSS/DCS code
gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
@@ -659,58 +602,45 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
{
uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO];
if (bKeyHeld || !bKeyPressed)
{
if (bKeyHeld || !bKeyPressed) { // key held or released
if (gInputBoxIndex > 0)
return;
return; // leave if input box active
if (!bKeyPressed)
{
if (!bKeyHeld)
if (!bKeyPressed) {
if (!bKeyHeld || IS_FREQ_CHANNEL(Channel))
return;
if (IS_FREQ_CHANNEL(Channel))
return;
#ifdef ENABLE_VOICE
AUDIO_SetDigitVoice(0, gTxVfo->CHANNEL_SAVE + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
// if released long button press and not in freq mode
#ifdef ENABLE_VOICE
AUDIO_SetDigitVoice(0, gTxVfo->CHANNEL_SAVE + 1); // say channel number
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
return;
}
}
else
{
if (gInputBoxIndex > 0)
{
else { // short pressed
if (gInputBoxIndex > 0) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
}
if (gScanStateDir == SCAN_OFF)
{
#ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(Channel))
#endif
if (gScanStateDir == SCAN_OFF) {
#ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(Channel))
#endif
{
uint8_t Next;
if (IS_FREQ_CHANNEL(Channel))
{ // step/down in frequency
if (IS_FREQ_CHANNEL(Channel)) { // step/down in frequency
const uint32_t frequency = APP_SetFrequencyByStep(gTxVfo, Direction);
if (RX_freq_check(frequency) < 0)
{ // frequency not allowed
if (RX_freq_check(frequency) < 0) { // frequency not allowed
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
gTxVfo->freq_config_RX.Frequency = frequency;
BK4819_SetFrequency(frequency);
BK4819_RX_TurnOn();
gRequestSaveChannel = 1;
return;
}
@@ -718,29 +648,25 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
Next = RADIO_FindNextChannel(Channel + Direction, Direction, false, 0);
if (Next == 0xFF)
return;
if (Channel == Next)
return;
gEeprom.MrChannel[gEeprom.TX_VFO] = Next;
gEeprom.MrChannel[gEeprom.TX_VFO] = Next;
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Next;
if (!bKeyHeld)
{
#ifdef ENABLE_VOICE
AUDIO_SetDigitVoice(0, Next + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
if (!bKeyHeld) {
#ifdef ENABLE_VOICE
AUDIO_SetDigitVoice(0, Next + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
}
}
#ifdef ENABLE_NOAA
else
{
Channel = NOAA_CHANNEL_FIRST + NUMBER_AddWithWraparound(gEeprom.ScreenChannel[gEeprom.TX_VFO] - NOAA_CHANNEL_FIRST, Direction, 0, 9);
gEeprom.NoaaChannel[gEeprom.TX_VFO] = Channel;
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel;
}
#endif
#ifdef ENABLE_NOAA
else {
Channel = NOAA_CHANNEL_FIRST + NUMBER_AddWithWraparound(gEeprom.ScreenChannel[gEeprom.TX_VFO] - NOAA_CHANNEL_FIRST, Direction, 0, 9);
gEeprom.NoaaChannel[gEeprom.TX_VFO] = Channel;
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel;
}
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
@@ -750,24 +676,22 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
// jump to the next channel
CHFRSCANNER_Start(false, Direction);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;
gScheduleScanListen = false;
gPttWasReleased = true;
}
void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
#ifdef ENABLE_FMRADIO
if (gFmRadioMode && Key != KEY_PTT && Key != KEY_EXIT)
{
if (!bKeyHeld && bKeyPressed)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
#endif
#ifdef ENABLE_FMRADIO
if (gFmRadioMode && Key != KEY_PTT && Key != KEY_EXIT) {
if (!bKeyHeld && bKeyPressed)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
#endif
if (gDTMF_InputMode && bKeyPressed && !bKeyHeld)
{
if (gDTMF_InputMode && bKeyPressed && !bKeyHeld) {
const char Character = DTMF_GetCharacter(Key);
if (Character != 0xFF)
{ // add key to DTMF string
@@ -786,18 +710,8 @@ void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
// Key = KEY_SIDE2; // what's this doing ???
// }
switch (Key)
{
case KEY_0:
case KEY_1:
case KEY_2:
case KEY_3:
case KEY_4:
case KEY_5:
case KEY_6:
case KEY_7:
case KEY_8:
case KEY_9:
switch (Key) {
case KEY_0...KEY_9:
MAIN_Key_DIGITS(Key, bKeyPressed, bKeyHeld);
break;
case KEY_MENU:

View File

@@ -103,7 +103,7 @@ void MENU_CssScanFound(void)
void MENU_StopCssScan(void)
{
gCssBackgroundScan = false;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
@@ -133,12 +133,12 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
case MENU_ABR_MIN:
*pMin = 0;
*pMax = 9;
break;
break;
case MENU_ABR_MAX:
*pMin = 1;
*pMax = 10;
break;
break;
case MENU_F_LOCK:
*pMin = 0;
@@ -303,7 +303,7 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
*pMin = 0;
*pMax = 2;
break;
#ifdef ENABLE_DTMF_CALLING
case MENU_D_RSP:
*pMin = 0;
@@ -500,7 +500,7 @@ void MENU_AcceptSetting(void)
break;
edit[i] = ' ';
}
SETTINGS_SaveChannelName(gSubMenuSelection, edit);
return;
@@ -531,7 +531,7 @@ void MENU_AcceptSetting(void)
case MENU_ABR_MAX:
gEeprom.BACKLIGHT_MAX = gSubMenuSelection;
gEeprom.BACKLIGHT_MIN = MIN(gSubMenuSelection - 1, gEeprom.BACKLIGHT_MIN);
break;
break;
case MENU_ABR_ON_TX_RX:
gSetting_backlight_on_tx_rx = gSubMenuSelection;
@@ -681,7 +681,7 @@ void MENU_AcceptSetting(void)
GUI_SelectNextDisplay(DISPLAY_MAIN);
gDTMF_InputMode = true;
gDTMF_InputBox_Index = 3;
memmove(gDTMF_InputBox, gDTMF_ID, 4);
memcpy(gDTMF_InputBox, gDTMF_ID, 4);
gRequestDisplayScreen = DISPLAY_INVALID;
}
return;
@@ -835,9 +835,9 @@ void MENU_ShowCurrentSetting(void)
case MENU_RESET:
gSubMenuSelection = 0;
break;
break;
case MENU_R_DCS:
case MENU_R_DCS:
case MENU_R_CTCS:
{
DCS_CodeType_t type = gTxVfo->freq_config_RX.CodeType;
@@ -940,7 +940,7 @@ void MENU_ShowCurrentSetting(void)
case MENU_ABR_MAX:
gSubMenuSelection = gEeprom.BACKLIGHT_MAX;
break;
break;
case MENU_ABR_ON_TX_RX:
gSubMenuSelection = gSetting_backlight_on_tx_rx;
@@ -1133,7 +1133,7 @@ void MENU_ShowCurrentSetting(void)
case MENU_BATTYP:
gSubMenuSelection = gEeprom.BATTERY_TYPE;
break;
break;
case MENU_F1SHRT:
case MENU_F1LONG:
@@ -1154,7 +1154,7 @@ void MENU_ShowCurrentSetting(void)
gSubMenuSelection = i;
break;
}
}
break;
}
@@ -1256,17 +1256,17 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
Frequency = StrToUL(INPUTBOX_GetAscii())*100;
gSubMenuSelection = FREQUENCY_RoundToStep(Frequency, gTxVfo->StepFrequency);
gInputBoxIndex = 0;
return;
}
if (UI_MENU_GetCurrentMenuId() == MENU_MEM_CH ||
UI_MENU_GetCurrentMenuId() == MENU_DEL_CH ||
UI_MENU_GetCurrentMenuId() == MENU_1_CALL ||
if (UI_MENU_GetCurrentMenuId() == MENU_MEM_CH ||
UI_MENU_GetCurrentMenuId() == MENU_DEL_CH ||
UI_MENU_GetCurrentMenuId() == MENU_1_CALL ||
UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME)
{ // enter 3-digit channel number
@@ -1339,6 +1339,10 @@ static void MENU_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
if (!gCssBackgroundScan)
{
/* Backlight related menus set full brightness. Set it back to the configured value,
just in case we are exiting from one of them. */
BACKLIGHT_TurnOn();
if (gIsInSubMenu)
{
if (gInputBoxIndex == 0 || UI_MENU_GetCurrentMenuId() != MENU_OFFSET)
@@ -1400,7 +1404,8 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
if (UI_MENU_GetCurrentMenuId() != MENU_SCR)
gAnotherVoiceID = MenuList[gMenuCursor].voice_id;
#endif
if (UI_MENU_GetCurrentMenuId() == MENU_ANI_ID || UI_MENU_GetCurrentMenuId() == MENU_UPCODE|| UI_MENU_GetCurrentMenuId() == MENU_DWCODE)
return;
#if 1
if (UI_MENU_GetCurrentMenuId() == MENU_DEL_CH || UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME)
if (!RADIO_CheckValidChannel(gSubMenuSelection, false, 0))
@@ -1436,7 +1441,7 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
edit_index = 0; // 'edit_index' is going to be used as the cursor position
// make a copy so we can test for change when exiting the menu item
memmove(edit_original, edit, sizeof(edit_original));
memcpy(edit_original, edit, sizeof(edit_original));
return;
}
@@ -1448,16 +1453,11 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
return; // next char
// exit
if (memcmp(edit_original, edit, sizeof(edit_original)) == 0)
{ // no change - drop it
gFlagAcceptSetting = false;
gIsInSubMenu = false;
gAskForConfirmation = 0;
}
else
{
gFlagAcceptSetting = false;
gAskForConfirmation = 0;
gFlagAcceptSetting = false;
gAskForConfirmation = 0;
if (memcmp(edit_original, edit, sizeof(edit_original)) == 0) {
// no change - drop it
gIsInSubMenu = false;
}
}
}
@@ -1624,7 +1624,10 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
gRequestDisplayScreen = DISPLAY_MENU;
if (UI_MENU_GetCurrentMenuId() != MENU_ABR && gEeprom.BACKLIGHT_TIME == 0) // backlight always off and not in the backlight menu
if (UI_MENU_GetCurrentMenuId() != MENU_ABR
&& UI_MENU_GetCurrentMenuId() != MENU_ABR_MIN
&& UI_MENU_GetCurrentMenuId() != MENU_ABR_MAX
&& gEeprom.BACKLIGHT_TIME == 0) // backlight always off and not in the backlight menu
{
BACKLIGHT_TurnOff();
}

View File

@@ -505,7 +505,7 @@ void SCANNER_TimeSlice500ms(void)
{
if (SCANNER_IsScanning() && gScannerSaveState == SCAN_SAVE_NO_PROMPT && gScanCssState < SCAN_CSS_STATE_FOUND) {
gScanProgressIndicator++;
#ifdef ENABLE_NO_CODE_SCAN_TIMEOUT
#ifndef ENABLE_NO_CODE_SCAN_TIMEOUT
if (gScanProgressIndicator > 32) {
if (gScanCssState == SCAN_CSS_STATE_SCANNING && !gScanSingleFrequency)
gScanCssState = SCAN_CSS_STATE_FOUND;

View File

@@ -13,10 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app/spectrum.h"
#include "am_fix.h"
#include "audio.h"
#include "misc.h"
#ifdef ENABLE_SCAN_RANGES
#include "chFrScanner.h"
#endif
#include "driver/backlight.h"
#include "frequencies.h"
#include "ui/helper.h"
@@ -33,7 +38,6 @@ struct FrequencyBandInfo {
const uint16_t RSSI_MAX_VALUE = 65535;
static uint16_t R30, R37, R3D, R43, R47, R48, R7E;
static uint32_t initialFreq;
static char String[32];
@@ -53,6 +57,11 @@ PeakInfo peak;
ScanInfo scanInfo;
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 uint8_t modulationTypeTuneSteps[] = {100, 50, 10};
const uint8_t modTypeReg47Values[] = {1, 7, 5};
@@ -212,24 +221,29 @@ static void ToggleAFBit(bool on) {
BK4819_WriteRegister(BK4819_REG_47, reg);
}
static const BK4819_REGISTER_t registers_to_save[] ={
BK4819_REG_30,
BK4819_REG_37,
BK4819_REG_3D,
BK4819_REG_43,
BK4819_REG_47,
BK4819_REG_48,
BK4819_REG_7E,
};
static uint16_t registers_stack [sizeof(registers_to_save)];
static void BackupRegisters() {
R30 = BK4819_ReadRegister(BK4819_REG_30);
R37 = BK4819_ReadRegister(BK4819_REG_37);
R3D = BK4819_ReadRegister(BK4819_REG_3D);
R43 = BK4819_ReadRegister(BK4819_REG_43);
R47 = BK4819_ReadRegister(BK4819_REG_47);
R48 = BK4819_ReadRegister(BK4819_REG_48);
R7E = BK4819_ReadRegister(BK4819_REG_7E);
for (uint32_t i = 0; i < ARRAY_SIZE(registers_to_save); i++){
registers_stack[i] = BK4819_ReadRegister(registers_to_save[i]);
}
}
static void RestoreRegisters() {
BK4819_WriteRegister(BK4819_REG_30, R30);
BK4819_WriteRegister(BK4819_REG_37, R37);
BK4819_WriteRegister(BK4819_REG_3D, R3D);
BK4819_WriteRegister(BK4819_REG_43, R43);
BK4819_WriteRegister(BK4819_REG_47, R47);
BK4819_WriteRegister(BK4819_REG_48, R48);
BK4819_WriteRegister(BK4819_REG_7E, R7E);
for (uint32_t i = 0; i < ARRAY_SIZE(registers_to_save); i++){
BK4819_WriteRegister(registers_to_save[i], registers_stack[i]);
}
}
static void ToggleAFDAC(bool on) {
@@ -260,12 +274,24 @@ static void ResetPeak() {
}
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 GetStepsCount()
{
#ifdef ENABLE_SCAN_RANGES
if(gScanRangeStart) {
return (gScanRangeStop - gScanRangeStart) / GetScanStep();
}
#endif
return 128 >> settings.stepsCount;
}
uint32_t GetBW() { return GetStepsCount() * GetScanStep(); }
uint32_t GetFStart() {
return IsCenterMode() ? currentFreq - (GetBW() >> 1) : currentFreq;
}
uint32_t GetFEnd() { return currentFreq + GetBW(); }
static void TuneToPeak() {
@@ -352,6 +378,10 @@ static void ResetBlacklist() {
if (rssiHistory[i] == RSSI_MAX_VALUE)
rssiHistory[i] = 0;
}
#ifdef ENABLE_SCAN_RANGES
memset(blacklistFreqs, 0, sizeof(blacklistFreqs));
blacklistFreqsIdx = 0;
#endif
}
static void RelaunchScan() {
@@ -398,7 +428,25 @@ static void UpdatePeakInfo() {
UpdatePeakInfoForce();
}
static void Measure() { rssiHistory[scanInfo.i] = scanInfo.rssi = GetRssi(); }
static void SetRssiHistory(uint16_t idx, uint16_t rssi)
{
#ifdef ENABLE_SCAN_RANGES
if(scanInfo.measurementsCount > 128) {
uint8_t i = (uint32_t)ARRAY_SIZE(rssiHistory) * 1000 / scanInfo.measurementsCount * idx / 1000;
if(rssiHistory[i] < rssi || isListening)
rssiHistory[i] = rssi;
rssiHistory[(i+1)%128] = 0;
return;
}
#endif
rssiHistory[idx] = rssi;
}
static void Measure()
{
uint16_t rssi = scanInfo.rssi = GetRssi();
SetRssiHistory(scanInfo.i, rssi);
}
// Update things by keypress
@@ -440,13 +488,12 @@ static void UpdateDBMax(bool inc) {
}
static void UpdateScanStep(bool inc) {
if (inc && settings.scanStepIndex < S_STEP_100_0kHz) {
settings.scanStepIndex++;
} else if (!inc && settings.scanStepIndex > 0) {
settings.scanStepIndex--;
if (inc) {
settings.scanStepIndex = settings.scanStepIndex != S_STEP_100_0kHz ? settings.scanStepIndex + 1 : 0;
} else {
return;
settings.scanStepIndex = settings.scanStepIndex != 0 ? settings.scanStepIndex - 1 : S_STEP_100_0kHz;
}
settings.frequencyChangeStep = GetBW() >> 1;
RelaunchScan();
ResetBlacklist();
@@ -595,12 +642,26 @@ static void UpdateFreqInput(KEY_Code_t key) {
}
static void Blacklist() {
rssiHistory[peak.i] = RSSI_MAX_VALUE;
#ifdef ENABLE_SCAN_RANGES
blacklistFreqs[blacklistFreqsIdx++ % ARRAY_SIZE(blacklistFreqs)] = peak.i;
#endif
SetRssiHistory(peak.i, RSSI_MAX_VALUE);
ResetPeak();
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
// applied x2 to prevent initial rounding
@@ -665,7 +726,7 @@ static void DrawStatus() {
static void DrawF(uint32_t f) {
sprintf(String, "%u.%05u", f / 100000, f % 100000);
UI_PrintStringSmall(String, 8, 127, 0);
UI_PrintStringSmallNormal(String, 8, 127, 0);
sprintf(String, "%3s", gModulationStr[settings.modulationType]);
GUI_DisplaySmallest(String, 116, 1, false, true);
@@ -710,9 +771,11 @@ static void DrawRssiTriggerLevel() {
}
static void DrawTicks() {
uint32_t f = GetFStart() % 100000;
uint32_t step = GetScanStep();
for (uint8_t i = 0; i < 128; i += (1 << settings.stepsCount), f += step) {
uint32_t f = GetFStart();
uint32_t span = GetFEnd() - GetFStart();
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;
(f % 10000) < step && (barValue |= 0b00000010);
(f % 50000) < step && (barValue |= 0b00000100);
@@ -764,10 +827,16 @@ static void OnKeyDown(uint8_t key) {
UpdateFreqChangeStep(false);
break;
case KEY_UP:
UpdateCurrentFreq(true);
#ifdef ENABLE_SCAN_RANGES
if(!gScanRangeStart)
#endif
UpdateCurrentFreq(true);
break;
case KEY_DOWN:
UpdateCurrentFreq(false);
#ifdef ENABLE_SCAN_RANGES
if(!gScanRangeStart)
#endif
UpdateCurrentFreq(false);
break;
case KEY_SIDE1:
Blacklist();
@@ -779,7 +848,10 @@ static void OnKeyDown(uint8_t key) {
UpdateRssiTriggerLevel(false);
break;
case KEY_5:
FreqInput();
#ifdef ENABLE_SCAN_RANGES
if(!gScanRangeStart)
#endif
FreqInput();
break;
case KEY_0:
ToggleModulation();
@@ -788,7 +860,10 @@ static void OnKeyDown(uint8_t key) {
ToggleListeningBW();
break;
case KEY_4:
ToggleStepsCount();
#ifdef ENABLE_SCAN_RANGES
if(!gScanRangeStart)
#endif
ToggleStepsCount();
break;
case KEY_SIDE2:
ToggleBacklight();
@@ -932,7 +1007,7 @@ static void RenderStatus() {
static void RenderSpectrum() {
DrawTicks();
DrawArrow(peak.i << settings.stepsCount);
DrawArrow(128u * peak.i / GetStepsCount());
DrawSpectrum();
DrawRssiTriggerLevel();
DrawF(peak.f);
@@ -1000,7 +1075,7 @@ static void RenderStill() {
}
static void Render() {
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
UI_DisplayClear();
switch (currentState) {
case SPECTRUM:
@@ -1049,7 +1124,11 @@ bool HandleUserInput() {
}
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);
Measure();
UpdateScanInfo();
@@ -1070,6 +1149,10 @@ static void UpdateScan() {
return;
}
if(scanInfo.measurementsCount < 128)
memset(&rssiHistory[scanInfo.measurementsCount], 0,
sizeof(rssiHistory) - scanInfo.measurementsCount*sizeof(rssiHistory[0]));
redrawScreen = true;
preventKeypress = false;
@@ -1122,7 +1205,7 @@ static void UpdateListening() {
}
ToggleRX(false);
newScanStart = true;
ResetScanStats();
}
static void Tick() {
@@ -1135,6 +1218,26 @@ static void Tick() {
}
#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) {
HandleUserInput();
}
@@ -1166,18 +1269,32 @@ void APP_RunSpectrum() {
// TX here coz it always? set to active VFO
vfo = gEeprom.TX_VFO;
// set the current frequency in the middle of the display
currentFreq = initialFreq = gEeprom.VfoInfo[vfo].pRX->Frequency -
((GetStepsCount() / 2) * GetScanStep());
#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();
isListening = true; // to turn off RX later
redrawStatus = true;
redrawScreen = false; // we will wait until scan done
redrawScreen = true;
newScanStart = true;
ToggleRX(true), ToggleRX(false); // hack to prevent noise when squelch off
RADIO_SetModulation(settings.modulationType = gRxVfo->Modulation);
RADIO_SetModulation(settings.modulationType = gTxVfo->Modulation);
BK4819_SetFilterBandwidth(settings.listenBw = BK4819_FILTER_BW_WIDE, false);

View File

@@ -45,9 +45,8 @@ static const uint8_t U8RssiMap[] = {
};
static const uint16_t scanStepValues[] = {
1, 10, 50, 100,
250, 500, 625, 833, 1000, 1250, 2500, 10000,
1, 10, 50, 100, 250, 500, 625, 833,
1000, 1250, 1500, 2000, 2500, 5000, 10000,
};
static const uint16_t scanStepBWRegValues[] = {
@@ -110,7 +109,10 @@ typedef enum ScanStep {
S_STEP_8_33kHz,
S_STEP_10_0kHz,
S_STEP_12_5kHz,
S_STEP_15_0kHz,
S_STEP_20_0kHz,
S_STEP_25_0kHz,
S_STEP_50_0kHz,
S_STEP_100_0kHz,
} ScanStep;
@@ -136,17 +138,17 @@ typedef struct KeyboardState {
typedef struct ScanInfo {
uint16_t rssi, rssiMin, rssiMax;
uint8_t i, iPeak;
uint16_t i, iPeak;
uint32_t f, fPeak;
uint16_t scanStep;
uint8_t measurementsCount;
uint16_t measurementsCount;
} ScanInfo;
typedef struct PeakInfo {
uint16_t t;
uint16_t rssi;
uint32_t f;
uint8_t i;
uint16_t i;
} PeakInfo;
void APP_RunSpectrum(void);

View File

@@ -395,6 +395,11 @@ static void CMD_052D(const uint8_t *pBuffer)
SendReply(&Reply, sizeof(Reply));
}
// session init, sends back version info and state
// timestamp is a session id really
// this command also disables dual watch, crossband,
// DTMF side tones, freq reverse, PTT ID, DTMF decoding, frequency offset
// exits power save, sets main VFO to upper,
static void CMD_052F(const uint8_t *pBuffer)
{
const CMD_052F_t *pCmd = (const CMD_052F_t *)pBuffer;
@@ -429,6 +434,44 @@ static void CMD_052F(const uint8_t *pBuffer)
SendVersion();
}
#ifdef ENABLE_UART_RW_BK_REGS
static void CMD_0601_ReadBK4819Reg(const uint8_t *pBuffer)
{
typedef struct __attribute__((__packed__)) {
Header_t header;
uint8_t reg;
} CMD_0601_t;
CMD_0601_t *cmd = (CMD_0601_t*) pBuffer;
struct __attribute__((__packed__)) {
Header_t header;
struct __attribute__((__packed__)) {
uint8_t reg;
uint16_t value;
} data;
} reply;
reply.header.ID = 0x0601;
reply.header.Size = sizeof(reply.data);
reply.data.reg = cmd->reg;
reply.data.value = BK4819_ReadRegister(cmd->reg);
SendReply(&reply, sizeof(reply));
}
static void CMD_0602_WriteBK4819Reg(const uint8_t *pBuffer)
{
typedef struct __attribute__((__packed__)) {
Header_t header;
uint8_t reg;
uint16_t value;
} CMD_0602_t;
CMD_0602_t *cmd = (CMD_0602_t*) pBuffer;
BK4819_WriteRegister(cmd->reg, cmd->value);
}
#endif
bool UART_IsCommandAvailable(void)
{
uint16_t Index;
@@ -487,11 +530,11 @@ bool UART_IsCommandAvailable(void)
if (TailIndex < Index)
{
const uint16_t ChunkSize = sizeof(UART_DMA_Buffer) - Index;
memmove(UART_Command.Buffer, UART_DMA_Buffer + Index, ChunkSize);
memmove(UART_Command.Buffer + ChunkSize, UART_DMA_Buffer, TailIndex);
memcpy(UART_Command.Buffer, UART_DMA_Buffer + Index, ChunkSize);
memcpy(UART_Command.Buffer + ChunkSize, UART_DMA_Buffer, TailIndex);
}
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);
if (TailIndex < gUART_WriteIndex)
@@ -567,5 +610,15 @@ void UART_HandleCommand(void)
NVIC_SystemReset();
#endif
break;
#ifdef ENABLE_UART_RW_BK_REGS
case 0x0601:
CMD_0601_ReadBK4819Reg(UART_Command.Buffer);
break;
case 0x0602:
CMD_0602_WriteBK4819Reg(UART_Command.Buffer);
break;
#endif
}
}

View File

@@ -205,7 +205,7 @@ volatile bool gFlagPlayQueuedVoice;
VOICE_ID_t gAnotherVoiceID = VOICE_ID_INVALID;
void AUDIO_PlayVoice(uint8_t VoiceID)
static void AUDIO_PlayVoice(uint8_t VoiceID)
{
unsigned int i;

View File

@@ -149,7 +149,6 @@ static inline void AUDIO_AudioPathOff(void) {
extern volatile bool gFlagPlayQueuedVoice;
extern VOICE_ID_t gAnotherVoiceID;
void AUDIO_PlayVoice(uint8_t VoiceID);
void AUDIO_PlaySingleVoice(bool bFlag);
void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID);
uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value);
@@ -157,4 +156,3 @@ static inline void AUDIO_AudioPathOff(void) {
#endif
#endif

View File

@@ -312,3 +312,16 @@ const uint8_t BITMAP_compand[6] =
0b01000010,
0b00100100
};
#ifndef ENABLE_CUSTOM_MENU_LAYOUT
const uint8_t BITMAP_CurrentIndicator[8] = {
0xFF,
0xFF,
0x7E,
0x7E,
0x3C,
0x3C,
0x18,
0x18
};
#endif

View File

@@ -44,5 +44,8 @@ extern const uint8_t BITMAP_ScanList2[6];
extern const uint8_t BITMAP_compand[6];
#ifndef ENABLE_CUSTOM_MENU_LAYOUT
extern const uint8_t BITMAP_CurrentIndicator[8];
#endif
#endif

16
board.c
View File

@@ -50,10 +50,10 @@
FLASH_Init(FLASH_READ_MODE_1_CYCLE);
FLASH_ConfigureTrimValues();
SYSTEM_ConfigureClocks();
overlay_FLASH_MainClock = 48000000;
overlay_FLASH_ClockMultiplier = 48;
FLASH_Init(FLASH_READ_MODE_2_CYCLE);
}
#endif
@@ -494,10 +494,12 @@ void BOARD_Init(void)
BACKLIGHT_InitHardware();
BOARD_ADC_Init();
ST7565_Init();
#ifdef ENABLE_FMRADIO
BK1080_Init(0, false);
#endif
#ifdef ENABLE_FMRADIO
BK1080_Init0();
#endif
#if defined(ENABLE_UART) || defined(ENABLED_AIRCOPY)
CRC_Init();
#endif
}

View File

@@ -1,35 +1,48 @@
#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(char * str)
static inline void LogUart(const char *const str)
{
UART_Send(str, strlen(str));
UART_Send(str, strlen(str));
}
static inline void LogUartf(const char* format, ...)
{
char buffer[128];
va_list va;
va_start(va, format);
vsnprintf(buffer, (size_t)-1, format, va);
va_end(va);
UART_Send(buffer, strlen(buffer));
}
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);
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);
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
#endif

View File

@@ -67,12 +67,12 @@ void BACKLIGHT_TurnOn(void)
case 1: // 5 sec
case 2: // 10 sec
case 3: // 20 sec
gBacklightCountdown_500ms = 1 + (2 << (gEeprom.BACKLIGHT_TIME - 1)) * 10;
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)) * 120;
gBacklightCountdown_500ms = 1 + (2 << (gEeprom.BACKLIGHT_TIME - 4)) * 60;
break;
case 7: // always on
gBacklightCountdown_500ms = 0;
@@ -103,8 +103,16 @@ 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;
}

View File

@@ -36,5 +36,6 @@ void BACKLIGHT_TurnOn();
void BACKLIGHT_TurnOff();
bool BACKLIGHT_IsOn();
void BACKLIGHT_SetBrightness(uint8_t brigtness);
uint8_t BACKLIGHT_GetBrightness(void);
#endif

View File

@@ -39,16 +39,19 @@ static bool gIsInitBK1080;
uint16_t BK1080_BaseFrequency;
uint16_t BK1080_FrequencyDeviation;
void BK1080_Init(uint16_t Frequency, bool bDoScan)
void BK1080_Init0(void)
{
BK1080_Init(0,0/*,0*/);
}
void BK1080_Init(uint16_t freq, uint8_t band/*, uint8_t space*/)
{
unsigned int i;
if (bDoScan)
{
if (freq) {
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BK1080);
if (!gIsInitBK1080)
{
if (!gIsInitBK1080) {
for (i = 0; i < ARRAY_SIZE(BK1080_RegisterTable); i++)
BK1080_WriteRegister(i, BK1080_RegisterTable[i]);
@@ -61,20 +64,14 @@ void BK1080_Init(uint16_t Frequency, bool bDoScan)
gIsInitBK1080 = true;
}
else
{
else {
BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x0201);
}
BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, 0x0A5F);
BK1080_WriteRegister(BK1080_REG_03_CHANNEL, Frequency - 760);
SYSTEM_DelayMs(10);
BK1080_WriteRegister(BK1080_REG_03_CHANNEL, (Frequency - 760) | 0x8000);
BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, 0x0A1F);
BK1080_SetFrequency(freq, band/*, space*/);
}
else
{
else {
BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x0241);
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BK1080);
}
@@ -108,11 +105,22 @@ void BK1080_Mute(bool Mute)
BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, Mute ? 0x4201 : 0x0201);
}
void BK1080_SetFrequency(uint16_t Frequency)
void BK1080_SetFrequency(uint16_t frequency, uint8_t band/*, uint8_t space*/)
{
BK1080_WriteRegister(BK1080_REG_03_CHANNEL, Frequency - 760);
//uint8_t spacings[] = {20,10,5};
//space %= 3;
uint16_t channel = (frequency - BK1080_GetFreqLoLimit(band))/* * 10 / spacings[space]*/;
uint16_t regval = BK1080_ReadRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2);
regval = (regval & ~(0b11 << 6)) | ((band & 0b11) << 6);
//regval = (regval & ~(0b11 << 4)) | ((space & 0b11) << 4);
BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, regval);
BK1080_WriteRegister(BK1080_REG_03_CHANNEL, channel);
SYSTEM_DelayMs(10);
BK1080_WriteRegister(BK1080_REG_03_CHANNEL, (Frequency - 760) | 0x8000);
BK1080_WriteRegister(BK1080_REG_03_CHANNEL, channel | 0x8000);
}
void BK1080_GetFrequencyDeviation(uint16_t Frequency)
@@ -120,3 +128,17 @@ void BK1080_GetFrequencyDeviation(uint16_t Frequency)
BK1080_BaseFrequency = Frequency;
BK1080_FrequencyDeviation = BK1080_ReadRegister(BK1080_REG_07) / 16;
}
uint16_t BK1080_GetFreqLoLimit(uint8_t band)
{
uint16_t lim[] = {875, 760, 760, 640};
return lim[band % 4];
}
uint16_t BK1080_GetFreqHiLimit(uint8_t band)
{
band %= 4;
uint16_t lim[] = {1080, 1080, 900, 760};
return lim[band % 4];
}

View File

@@ -24,11 +24,14 @@
extern uint16_t BK1080_BaseFrequency;
extern uint16_t BK1080_FrequencyDeviation;
void BK1080_Init(uint16_t Frequency, bool bDoScan);
void BK1080_Init0(void);
void BK1080_Init(uint16_t Frequency, uint8_t band/*, uint8_t space*/);
uint16_t BK1080_ReadRegister(BK1080_Register_t Register);
void BK1080_WriteRegister(BK1080_Register_t Register, uint16_t Value);
void BK1080_Mute(bool Mute);
void BK1080_SetFrequency(uint16_t Frequency);
uint16_t BK1080_GetFreqLoLimit(uint8_t band);
uint16_t BK1080_GetFreqHiLimit(uint8_t band);
void BK1080_SetFrequency(uint16_t frequency, uint8_t band/*, uint8_t space*/);
void BK1080_GetFrequencyDeviation(uint16_t Frequency);
#endif

View File

@@ -17,6 +17,7 @@
#ifndef BK4819_REGS_H
#define BK4819_REGS_H
#include <stdint.h>
typedef struct {
const char *name;
@@ -387,4 +388,3 @@ enum {
};
#endif

View File

@@ -14,15 +14,20 @@
* limitations under the License.
*/
#include <stdio.h> // NULL
#include <stdint.h>
#include <stdio.h>
#include "settings.h"
#include "../audio.h"
#include "../bsp/dp32g030/gpio.h"
#include "../bsp/dp32g030/portcon.h"
#include "audio.h"
#include "bk4819.h"
#include "bsp/dp32g030/gpio.h"
#include "bsp/dp32g030/portcon.h"
#include "driver/gpio.h"
#include "driver/system.h"
#include "driver/systick.h"
#include "gpio.h"
#include "system.h"
#include "systick.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
@@ -127,7 +132,6 @@ static uint16_t BK4819_ReadU16(void)
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;
SYSTICK_DelayUs(1);
Value = 0;
for (i = 0; i < 16; i++)
{
@@ -242,7 +246,7 @@ void BK4819_SetAGC(bool enable)
if(!(regVal & (1 << 15)) == enable)
return;
BK4819_WriteRegister(BK4819_REG_7E, (regVal & ~(1 << 15) & ~(0b111 << 12))
BK4819_WriteRegister(BK4819_REG_7E, (regVal & ~(1 << 15) & ~(0b111 << 12))
| (!enable << 15) // 0 AGC fix mode
| (3u << 12) // 3 AGC fix index
);
@@ -271,7 +275,7 @@ void BK4819_InitAGC(bool amModulation)
//
// <15:10> ???
//
// <9:8> LNA Gain Short
// <9:8> LNA Gain Short
// 3 = 0dB <<< 1o11 read from spectrum reference manual
// 2 = -24dB -19 -11
// 1 = -30dB -24 -16
@@ -309,12 +313,12 @@ void BK4819_InitAGC(bool amModulation)
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_14, 0x0000);
BK4819_WriteRegister(BK4819_REG_49, (0 << 14) | (50 << 7) | (32 << 0));
}
else{
BK4819_WriteRegister(BK4819_REG_14, 0x0019); // 0x0019 / 000000 00 000 11 001 / -79dB
BK4819_WriteRegister(BK4819_REG_49, (0 << 14) | (84 << 7) | (56 << 0)); //0x2A38 / 00 1010100 0111000 / 84, 56
BK4819_WriteRegister(BK4819_REG_49, (0 << 14) | (84 << 7) | (56 << 0)); //0x2A38 / 00 1010100 0111000 / 84, 56
}
BK4819_WriteRegister(BK4819_REG_7B, 0x8420);
@@ -337,7 +341,7 @@ int8_t BK4819_GetRxGain_dB(void)
struct {
uint16_t _ : 5;
uint16_t agcSigStrength : 7;
int16_t gainIdx : 3;
int16_t gainIdx : 3;
uint16_t agcEnab : 1;
};
uint16_t __raw;
@@ -604,89 +608,54 @@ void BK4819_SetFilterBandwidth(const BK4819_FilterBandwidth_t Bandwidth, const b
//
// <1:0> 0 ???
uint16_t val;
uint16_t val = 0;
switch (Bandwidth)
{
default:
case BK4819_FILTER_BW_WIDE: // 25kHz
if (weak_no_different)
{ // make the RX bandwidth the same with weak signals
val =
(0u << 15) | // 0
(4u << 12) | // *3 RF filter bandwidth
(4u << 9) | // *0 RF filter bandwidth when signal is weak
(6u << 6) | // *0 AFTxLPF2 filter Band Width
(2u << 4) | // 2 BW Mode Selection
(1u << 3) | // 1
(0u << 2) | // 0 Gain after FM Demodulation
(0u << 0); // 0
}
else
{ // with weak RX signals the RX bandwidth is reduced
val = // 0x3028); // 0 011 000 000 10 1 0 00
(0u << 15) | // 0
(4u << 12) | // *3 RF filter bandwidth
(2u << 9) | // *0 RF filter bandwidth when signal is weak
(6u << 6) | // *0 AFTxLPF2 filter Band Width
(2u << 4) | // 2 BW Mode Selection
(1u << 3) | // 1
(0u << 2) | // 0 Gain after FM Demodulation
(0u << 0); // 0
val = (4u << 12) | // *3 RF filter bandwidth
(6u << 6) | // *0 AFTxLPF2 filter Band Width
(2u << 4) | // 2 BW Mode Selection
(1u << 3) | // 1
(0u << 2); // 0 Gain after FM Demodulation
if (weak_no_different) {
// make the RX bandwidth the same with weak signals
val |= (4u << 9); // *0 RF filter bandwidth when signal is weak
} else {
/// with weak RX signals the RX bandwidth is reduced
val |= (2u << 9); // *0 RF filter bandwidth when signal is weak
}
break;
case BK4819_FILTER_BW_NARROW: // 12.5kHz
if (weak_no_different)
{
val =
(0u << 15) | // 0
(4u << 12) | // *4 RF filter bandwidth
(4u << 9) | // *0 RF filter bandwidth when signal is weak
(0u << 6) | // *1 AFTxLPF2 filter Band Width
(0u << 4) | // 0 BW Mode Selection
(1u << 3) | // 1
(0u << 2) | // 0 Gain after FM Demodulation
(0u << 0); // 0
}
else
{
val = // 0x4048); // 0 100 000 001 00 1 0 00
(0u << 15) | // 0
(4u << 12) | // *4 RF filter bandwidth
(2u << 9) | // *0 RF filter bandwidth when signal is weak
(0u << 6) | // *1 AFTxLPF2 filter Band Width
(0u << 4) | // 0 BW Mode Selection
(1u << 3) | // 1
(0u << 2) | // 0 Gain after FM Demodulation
(0u << 0); // 0
val = (4u << 12) | // *4 RF filter bandwidth
(0u << 6) | // *1 AFTxLPF2 filter Band Width
(0u << 4) | // 0 BW Mode Selection
(1u << 3) | // 1
(0u << 2); // 0 Gain after FM Demodulation
if (weak_no_different) {
val |= (4u << 9); // *0 RF filter bandwidth when signal is weak
} else {
val |= (2u << 9);
}
break;
case BK4819_FILTER_BW_NARROWER: // 6.25kHz
if (weak_no_different)
{
val =
(0u << 15) | // 0
(3u << 12) | // 3 RF filter bandwidth
(3u << 9) | // *0 RF filter bandwidth when signal is weak
(1u << 6) | // 1 AFTxLPF2 filter Band Width
(1u << 4) | // 1 BW Mode Selection
(1u << 3) | // 1
(0u << 2) | // 0 Gain after FM Demodulation
(0u << 0); // 0
}
else
{
val =
(0u << 15) | // 0
(3u << 12) | // 3 RF filter bandwidth
(0u << 9) | // 0 RF filter bandwidth when signal is weak
(1u << 6) | // 1 AFTxLPF2 filter Band Width
(1u << 4) | // 1 BW Mode Selection
(1u << 3) | // 1
(0u << 2) | // 1 Gain after FM Demodulation
(0u << 0); // 0
val = (3u << 12) | // 3 RF filter bandwidth
(3u << 9) | // *0 RF filter bandwidth when signal is weak
(1u << 6) | // 1 AFTxLPF2 filter Band Width
(1u << 4) | // 1 BW Mode Selection
(1u << 3) | // 1
(0u << 2); // 0 Gain after FM Demodulation
if (weak_no_different) {
val |= (3u << 9);
} else {
val |= (0u << 9); // 0 RF filter bandwidth when signal is weak
}
break;
}
@@ -842,7 +811,7 @@ void BK4819_RX_TurnOn(void)
BK4819_WriteRegister(BK4819_REG_30, 0);
BK4819_WriteRegister(BK4819_REG_30,
BK4819_WriteRegister(BK4819_REG_30,
BK4819_REG_30_ENABLE_VCO_CALIB |
BK4819_REG_30_DISABLE_UNKNOWN |
BK4819_REG_30_ENABLE_RX_LINK |
@@ -1023,7 +992,7 @@ void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch)
void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay, const unsigned int level, const bool play_speaker)
{
BK4819_EnterTxMute();
if (play_speaker)
{
AUDIO_AudioPathOn();
@@ -1032,7 +1001,7 @@ void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay,
else
BK4819_SetAF(BK4819_AF_MUTE);
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | ((level & 0x7f) << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
BK4819_EnableTXLink();
@@ -1049,7 +1018,7 @@ void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay,
AUDIO_AudioPathOff();
BK4819_SetAF(BK4819_AF_MUTE);
}
BK4819_WriteRegister(BK4819_REG_70, 0x0000);
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE);
BK4819_ExitTxMute();
@@ -1149,7 +1118,7 @@ void BK4819_ExitBypass(void)
uint16_t regVal = BK4819_ReadRegister(BK4819_REG_7E);
// 0x302E / 0 011 000000 101 110
BK4819_WriteRegister(BK4819_REG_7E, (regVal & ~(0b111 << 3))
BK4819_WriteRegister(BK4819_REG_7E, (regVal & ~(0b111 << 3))
| (5u << 3) // 5 DC Filter band width for Tx (MIC In)
@@ -1265,33 +1234,46 @@ void BK4819_EnableTXLink(void)
void BK4819_PlayDTMF(char Code)
{
uint16_t tone1 = 0;
uint16_t tone2 = 0;
struct DTMF_TonePair {
uint16_t tone1;
uint16_t tone2;
};
const struct DTMF_TonePair tones[] = {
{941, 1336},
{697, 1209},
{697, 1336},
{697, 1477},
{770, 1209},
{770, 1336},
{770, 1477},
{852, 1209},
{852, 1336},
{852, 1477},
{697, 1633},
{770, 1633},
{852, 1633},
{941, 1633},
{941, 1209},
{941, 1477},
};
const struct DTMF_TonePair *pSelectedTone = NULL;
switch (Code)
{
case '0': tone1 = 941; tone2 = 1336; break;
case '1': tone1 = 697; tone2 = 1209; break;
case '2': tone1 = 697; tone2 = 1336; break;
case '3': tone1 = 697; tone2 = 1477; break;
case '4': tone1 = 770; tone2 = 1209; break;
case '5': tone1 = 770; tone2 = 1336; break;
case '6': tone1 = 770; tone2 = 1477; break;
case '7': tone1 = 852; tone2 = 1209; break;
case '8': tone1 = 852; tone2 = 1336; break;
case '9': tone1 = 852; tone2 = 1477; break;
case 'A': tone1 = 697; tone2 = 1633; break;
case 'B': tone1 = 770; tone2 = 1633; break;
case 'C': tone1 = 852; tone2 = 1633; break;
case 'D': tone1 = 941; tone2 = 1633; break;
case '*': tone1 = 941; tone2 = 1209; break;
case '#': tone1 = 941; tone2 = 1477; break;
case '0'...'9': pSelectedTone = &tones[0 + Code - '0']; break;
case 'A'...'D': pSelectedTone = &tones[10 + Code - 'A']; break;
case '*': pSelectedTone = &tones[14]; break;
case '#': pSelectedTone = &tones[15]; break;
default: pSelectedTone = NULL;
}
if (tone1 > 0)
BK4819_WriteRegister(BK4819_REG_71, (((uint32_t)tone1 * 103244) + 5000) / 10000); // with rounding
if (tone2 > 0)
BK4819_WriteRegister(BK4819_REG_72, (((uint32_t)tone2 * 103244) + 5000) / 10000); // with rounding
if (pSelectedTone) {
BK4819_WriteRegister(BK4819_REG_71, (((uint32_t)pSelectedTone->tone1 * 103244) + 5000) / 10000); // with rounding
BK4819_WriteRegister(BK4819_REG_72, (((uint32_t)pSelectedTone->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)
@@ -1706,7 +1688,7 @@ void BK4819_PrepareFSKReceive(void)
BK4819_WriteRegister(BK4819_REG_59, 0x3068);
}
void BK4819_PlayRoger(void)
static void BK4819_PlayRogerNormal(void)
{
#if 0
const uint32_t tone1_Hz = 500;
@@ -1717,6 +1699,7 @@ void BK4819_PlayRoger(void)
const uint32_t tone2_Hz = 1310;
#endif
BK4819_EnterTxMute();
BK4819_SetAF(BK4819_AF_MUTE);
@@ -1741,30 +1724,41 @@ void BK4819_PlayRoger(void)
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); // 1 1 0000 0 1 1111 1 1 1 0
}
void BK4819_PlayRogerMDC(void)
{
unsigned int i;
struct reg_value {
BK4819_REGISTER_t reg;
uint16_t value;
};
struct reg_value RogerMDC_Configuration [] = {
{ BK4819_REG_58, 0x37C3 }, // FSK Enable,
// RX Bandwidth FFSK 1200/1800
// 0xAA or 0x55 Preamble
// 11 RX Gain,
// 101 RX Mode
// TX FFSK 1200/1800
{ BK4819_REG_72, 0x3065 }, // Set Tone-2 to 1200Hz
{ BK4819_REG_70, 0x00E0 }, // Enable Tone-2 and Set Tone2 Gain
{ BK4819_REG_5D, 0x0D00 }, // Set FSK data length to 13 bytes
{ BK4819_REG_59, 0x8068 }, // 4 byte sync length, 6 byte preamble, clear TX FIFO
{ BK4819_REG_59, 0x0068 }, // Same, but clear TX FIFO is now unset (clearing done)
{ BK4819_REG_5A, 0x5555 }, // First two sync bytes
{ BK4819_REG_5B, 0x55AA }, // End of sync bytes. Total 4 bytes: 555555aa
{ BK4819_REG_5C, 0xAA30 }, // Disable CRC
};
BK4819_SetAF(BK4819_AF_MUTE);
BK4819_WriteRegister(BK4819_REG_58, 0x37C3); // FSK Enable,
// RX Bandwidth FFSK 1200/1800
// 0xAA or 0x55 Preamble
// 11 RX Gain,
// 101 RX Mode
// TX FFSK 1200/1800
BK4819_WriteRegister(BK4819_REG_72, 0x3065); // Set Tone-2 to 1200Hz
BK4819_WriteRegister(BK4819_REG_70, 0x00E0); // Enable Tone-2 and Set Tone2 Gain
BK4819_WriteRegister(BK4819_REG_5D, 0x0D00); // Set FSK data length to 13 bytes
BK4819_WriteRegister(BK4819_REG_59, 0x8068); // 4 byte sync length, 6 byte preamble, clear TX FIFO
BK4819_WriteRegister(BK4819_REG_59, 0x0068); // Same, but clear TX FIFO is now unset (clearing done)
BK4819_WriteRegister(BK4819_REG_5A, 0x5555); // First two sync bytes
BK4819_WriteRegister(BK4819_REG_5B, 0x55AA); // End of sync bytes. Total 4 bytes: 555555aa
BK4819_WriteRegister(BK4819_REG_5C, 0xAA30); // Disable CRC
for (unsigned int i = 0; i < ARRAY_SIZE(RogerMDC_Configuration); i++) {
BK4819_WriteRegister(RogerMDC_Configuration[i].reg, RogerMDC_Configuration[i].value);
}
// Send the data from the roger table
for (i = 0; i < 7; i++)
for (unsigned int i = 0; i < ARRAY_SIZE(FSK_RogerTable); i++) {
BK4819_WriteRegister(BK4819_REG_5F, FSK_RogerTable[i]);
}
SYSTEM_DelayMs(20);
@@ -1779,6 +1773,15 @@ void BK4819_PlayRogerMDC(void)
BK4819_WriteRegister(BK4819_REG_58, 0x0000);
}
void BK4819_PlayRoger(void)
{
if (gEeprom.ROGER == ROGER_MODE_ROGER) {
BK4819_PlayRogerNormal();
} else if (gEeprom.ROGER == ROGER_MODE_MDC) {
BK4819_PlayRogerMDC();
}
}
void BK4819_Enable_AfDac_DiscMode_TxDsp(void)
{
BK4819_WriteRegister(BK4819_REG_30, 0x0000);

View File

@@ -38,7 +38,7 @@ enum BK4819_AF_Type_t
BK4819_AF_UNKNOWN5 = 11u, // distorted
BK4819_AF_UNKNOWN6 = 12u, // distorted
BK4819_AF_UNKNOWN7 = 13u, // interesting
BK4819_AF_UNKNOWN8 = 14u, // interesting
BK4819_AF_UNKNOWN8 = 14u, // interesting
BK4819_AF_UNKNOWN9 = 15u // not a lot
};
@@ -161,15 +161,13 @@ uint8_t BK4819_GetCTCType(void);
void BK4819_SendFSKData(uint16_t *pData);
void BK4819_PrepareFSKReceive(void);
void BK4819_PlayRoger(void);
void BK4819_PlayRogerMDC(void);
void BK4819_Enable_AfDac_DiscMode_TxDsp(void);
void BK4819_GetVoxAmp(uint16_t *pResult);
void BK4819_SetScrambleFrequencyControlWord(uint32_t Frequency);
void BK4819_PlayDTMFEx(bool bLocalLoopback, char Code);
#endif

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#include "bsp/dp32g030/crc.h"
#include "driver/crc.h"
#include "../bsp/dp32g030/crc.h"
#include "crc.h"
void CRC_Init(void)
{
@@ -47,4 +47,3 @@ uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size)
return Crc;
}

View File

@@ -47,16 +47,17 @@ void EEPROM_WriteBuffer(uint16_t Address, const void *pBuffer)
uint8_t buffer[8];
EEPROM_ReadBuffer(Address, buffer, 8);
if (memcmp(pBuffer, buffer, 8) != 0)
{
I2C_Start();
I2C_Write(0xA0);
I2C_Write((Address >> 8) & 0xFF);
I2C_Write((Address >> 0) & 0xFF);
I2C_WriteBuffer(pBuffer, 8);
I2C_Stop();
if (memcmp(pBuffer, buffer, 8) == 0) {
return;
}
I2C_Start();
I2C_Write(0xA0);
I2C_Write((Address >> 8) & 0xFF);
I2C_Write((Address >> 0) & 0xFF);
I2C_WriteBuffer(pBuffer, 8);
I2C_Stop();
// give the EEPROM time to burn the data in (apparently takes 5ms)
SYSTEM_DelayMs(8);
}

View File

@@ -137,18 +137,13 @@ int I2C_ReadBuffer(void *pBuffer, uint8_t Size)
uint8_t *pData = (uint8_t *)pBuffer;
uint8_t i;
if (Size == 1) {
*pData = I2C_Read(true);
return 1;
}
for (i = 0; i < Size - 1; i++) {
SYSTICK_DelayUs(1);
pData[i] = I2C_Read(false);
}
SYSTICK_DelayUs(1);
pData[i++] = I2C_Read(true);
pData[i] = I2C_Read(true);
return Size;
}

View File

@@ -117,19 +117,13 @@ KEY_Code_t KEYBOARD_Poll(void)
GPIOA->DATA &= keyboard[j].set_to_zero_mask;
// Read all 4 GPIO pins at once .. with de-noise, max of 8 sample loops
for (i = 0, k = 0, reg = 0; i < 3 && k < 8; i++, k++)
{
uint16_t reg2;
for (i = 0, k = 0, reg = 0; i < 3 && k < 8; i++, k++) {
SYSTICK_DelayUs(1);
reg2 = GPIOA->DATA;
if (reg != reg2)
{ // noise
reg = reg2;
i = 0;
}
uint16_t reg2 = GPIOA->DATA;
i *= reg == reg2;
reg = reg2;
}
if (i < 3)
break; // noise is too bad

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
#include "bsp/dp32g030/pmu.h"
#include "bsp/dp32g030/syscon.h"
#include "driver/system.h"
#include "driver/systick.h"
#include "../bsp/dp32g030/pmu.h"
#include "../bsp/dp32g030/syscon.h"
#include "system.h"
#include "systick.h"
void SYSTEM_DelayMs(uint32_t Delay)
{

View File

@@ -15,8 +15,8 @@
*/
#include "ARMCM0.h"
#include "driver/systick.h"
#include "misc.h"
#include "systick.h"
#include "../misc.h"
// 0x20000324
static uint32_t gTickMultiplier;
@@ -29,17 +29,21 @@ void SYSTICK_Init(void)
void SYSTICK_DelayUs(uint32_t Delay)
{
const uint32_t ticks = Delay * gTickMultiplier;
uint32_t i = 0;
uint32_t Start = SysTick->LOAD;
uint32_t Previous = SysTick->VAL;
const uint32_t ticks = Delay * gTickMultiplier;
uint32_t elapsed_ticks = 0;
uint32_t Start = SysTick->LOAD;
uint32_t Previous = SysTick->VAL;
do {
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);
}

View File

@@ -65,35 +65,38 @@ const freq_band_table_t frequencyBandTable[] =
// this order of steps has to be preserved for backwards compatibility with other/stock firmwares
const uint16_t gStepFrequencyTable[] = {
// standard steps
[STEP_2_5kHz] = 250,
[STEP_5kHz] = 500,
[STEP_6_25kHz] = 625,
[STEP_10kHz] = 1000,
[STEP_12_5kHz] = 1250,
[STEP_25kHz] = 2500,
[STEP_2_5kHz] = 250,
[STEP_5kHz] = 500,
[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_15kHz] = 1500,
[STEP_30kHz] = 3000,
[STEP_50kHz] = 5000,
[STEP_100kHz] = 10000,
[STEP_125kHz] = 12500,
[STEP_250kHz] = 25000,
[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_10kHz, STEP_12_5kHz, STEP_15kHz, STEP_25kHz, STEP_30kHz, STEP_50kHz, STEP_100kHz,
STEP_125kHz, STEP_250kHz, STEP_500kHz
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)

View File

@@ -45,27 +45,30 @@ extern const freq_band_table_t frequencyBandTable[];
typedef enum {
// standard steps
STEP_2_5kHz,
STEP_5kHz,
STEP_6_25kHz,
STEP_10kHz,
STEP_12_5kHz,
STEP_25kHz,
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_0_01kHz,
STEP_0_05kHz,
STEP_0_1kHz,
STEP_0_25kHz,
STEP_0_5kHz,
STEP_1kHz,
STEP_1_25kHz,
STEP_9kHz,
STEP_15kHz,
STEP_30kHz,
STEP_50kHz,
STEP_100kHz,
STEP_125kHz,
STEP_250kHz,
STEP_20kHz,
STEP_30kHz,
STEP_50kHz,
STEP_100kHz,
STEP_125kHz,
STEP_200kHz,
STEP_250kHz,
STEP_500kHz,
STEP_N_ELEM
} STEP_Setting_t;

View File

@@ -42,39 +42,19 @@
FUNCTION_Type_t gCurrentFunction;
inline bool FUNCTION_IsRx()
bool FUNCTION_IsRx()
{
return gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING ||
gCurrentFunction == FUNCTION_RECEIVE;
}
void FUNCTION_Init(void)
{
#ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif
{
gCurrentCodeType = (gRxVfo->Modulation != MODULATION_FM) ? CODE_TYPE_OFF : gRxVfo->pRX->CodeType;
}
#ifdef ENABLE_NOAA
else
gCurrentCodeType = CODE_TYPE_CONTINUOUS_TONE;
#endif
#ifdef ENABLE_DTMF_CALLING
DTMF_clear_RX();
#endif
g_CxCSS_TAIL_Found = false;
g_CDCSS_Lost = false;
g_CTCSS_Lost = false;
#ifdef ENABLE_VOX
g_VOX_Lost = false;
#endif
g_SquelchLost = false;
gFlagTailNoteEliminationComplete = false;
@@ -85,9 +65,23 @@ void FUNCTION_Init(void)
gFoundCDCSSCountdown_10ms = 0;
gEndOfRxDetectedMaybe = false;
#ifdef ENABLE_NOAA
gNOAACountdown_10ms = 0;
#endif
gCurrentCodeType = (gRxVfo->Modulation != MODULATION_FM) ? CODE_TYPE_OFF : gRxVfo->pRX->CodeType;
#ifdef ENABLE_VOX
g_VOX_Lost = false;
#endif
#ifdef ENABLE_DTMF_CALLING
DTMF_clear_RX();
#endif
#ifdef ENABLE_NOAA
gNOAACountdown_10ms = 0;
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) {
gCurrentCodeType = CODE_TYPE_CONTINUOUS_TONE;
}
#endif
gUpdateStatus = true;
}
@@ -98,6 +92,7 @@ void FUNCTION_Foreground(const FUNCTION_Type_t PreviousFunction)
if (gDTMF_ReplyState != DTMF_REPLY_NONE)
RADIO_PrepareCssTX();
#endif
if (PreviousFunction == FUNCTION_TRANSMIT) {
ST7565_FixInterfGlitch();
gVFO_RSSI_bar_level[0] = 0;
@@ -153,12 +148,11 @@ void FUNCTION_Transmit()
// 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);
BK1080_Init0();
#endif
#ifdef ENABLE_ALARM
@@ -239,15 +233,13 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
gCurrentFunction = Function;
if (bWasPowerSave && Function != FUNCTION_POWER_SAVE)
{
if (bWasPowerSave && Function != FUNCTION_POWER_SAVE) {
BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable();
gRxIdleMode = false;
UI_DisplayStatus();
}
switch (Function)
{
switch (Function) {
case FUNCTION_FOREGROUND:
FUNCTION_Foreground(PreviousFunction);
return;
@@ -267,6 +259,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
case FUNCTION_INCOMING:
case FUNCTION_RECEIVE:
case FUNCTION_BAND_SCOPE:
default:
break;
}
@@ -274,6 +267,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
gSchedulePowerSave = false;
#if defined(ENABLE_FMRADIO)
gFM_RestoreCountdown_10ms = 0;
if(Function != FUNCTION_INCOMING)
gFM_RestoreCountdown_10ms = 0;
#endif
}

View File

@@ -27,7 +27,8 @@ enum FUNCTION_Type_t
FUNCTION_INCOMING, // receiving a signal (squelch is open)
FUNCTION_RECEIVE, // RX mode, squelch closed
FUNCTION_POWER_SAVE, // sleeping
FUNCTION_BAND_SCOPE // bandscope mode (panadpter/spectrum) .. not yet implemented
FUNCTION_BAND_SCOPE, // bandscope mode (panadpter/spectrum) .. not yet implemented
FUNCTION_N_ELEM
};
typedef enum FUNCTION_Type_t FUNCTION_Type_t;

View File

@@ -14,6 +14,8 @@
* limitations under the License.
*/
#include <assert.h>
#include "battery.h"
#include "driver/backlight.h"
#include "driver/st7565.h"
@@ -49,48 +51,45 @@ const uint16_t lowBatteryPeriod = 30;
volatile uint16_t gPowerSave_10ms;
unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV)
{
const uint16_t crv1600[][2] = {
const uint16_t Voltage2PercentageTable[][7][2] = {
[BATTERY_TYPE_1600_MAH] = {
{828, 100},
{814, 97 },
{760, 25 },
{729, 6 },
{630, 0 },
{0, 0 }
};
{0, 0 },
{0, 0 },
},
const uint16_t crv2200[][2] = {
[BATTERY_TYPE_2200_MAH] = {
{832, 100},
{813, 95 },
{740, 60 },
{707, 21 },
{682, 5 },
{630, 0 },
{0, 0 }
};
const BATTERY_Type_t type = gEeprom.BATTERY_TYPE;
const uint16_t(*crv)[2];
uint8_t size;
if (type == BATTERY_TYPE_2200_MAH) {
crv = crv2200;
size = ARRAY_SIZE(crv2200);
}
else {
crv = crv1600;
size = ARRAY_SIZE(crv1600);
}
{0, 0 },
},
};
static_assert(ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_1600_MAH]) ==
ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_2200_MAH]));
unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV)
{
const uint16_t (*crv)[2] = Voltage2PercentageTable[gEeprom.BATTERY_TYPE];
const int mulipl = 1000;
for (int i = 1; i < size; i++) {
for (unsigned int i = 1; i < ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_2200_MAH]); i++) {
if (voltage_10mV > crv[i][0]) {
int a = (crv[i - 1][1] - crv[i][1]) * mulipl / (crv[i - 1][0] - crv[i][0]);
int b = crv[i][1] - a * crv[i][0] / mulipl;
int p = a * voltage_10mV / mulipl + b;
const int a = (crv[i - 1][1] - crv[i][1]) * mulipl / (crv[i - 1][0] - crv[i][0]);
const int b = crv[i][1] - a * crv[i][0] / mulipl;
const int p = a * voltage_10mV / mulipl + b;
return MIN(p, 100);
}
}
return 0;
}
@@ -99,8 +98,6 @@ void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
const uint8_t PreviousBatteryLevel = gBatteryDisplayLevel;
const uint16_t Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] + gBatteryVoltages[3]) / 4;
gBatteryVoltageAverage = (Voltage * 760) / gBatteryCalibration[3];
if(gBatteryVoltageAverage > 890)
@@ -116,7 +113,7 @@ void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
gBatteryDisplayLevel = i;
break;
}
}
}
}
@@ -160,7 +157,7 @@ void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
if (bDisplayBatteryLevel)
UI_DisplayBattery(gBatteryDisplayLevel, gLowBatteryBlink);
}
if(!gLowBatteryConfirmed)
gUpdateDisplay = true;
@@ -168,56 +165,61 @@ void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
}
}
void BATTERY_TimeSlice500ms(void)
void BATTERY_TimeSlice500ms(void)
{
if (gLowBattery)
{
gLowBatteryBlink = ++lowBatteryCountdown & 1;
UI_DisplayBattery(0, gLowBatteryBlink);
if (gCurrentFunction != FUNCTION_TRANSMIT)
{ // not transmitting
if (lowBatteryCountdown < lowBatteryPeriod)
{
if (lowBatteryCountdown == lowBatteryPeriod-1 && !gChargingWithTypeC && !gLowBatteryConfirmed)
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP);
}
else
{
lowBatteryCountdown = 0;
if (!gChargingWithTypeC)
{ // not on charge
if(!gLowBatteryConfirmed) {
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP);
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_LOW_VOLTAGE);
#endif
}
if (gBatteryDisplayLevel == 0)
{
#ifdef ENABLE_VOICE
AUDIO_PlaySingleVoice(true);
#endif
gReducedService = true;
//if (gCurrentFunction != FUNCTION_POWER_SAVE)
FUNCTION_Select(FUNCTION_POWER_SAVE);
ST7565_HardwareReset();
if (gEeprom.BACKLIGHT_TIME < (ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1))
BACKLIGHT_TurnOff(); // turn the backlight off
}
#ifdef ENABLE_VOICE
else
AUDIO_PlaySingleVoice(false);
#endif
}
}
}
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();
}
}

View File

@@ -40,9 +40,9 @@ typedef enum {
BATTERY_TYPE_UNKNOWN
} BATTERY_Type_t;
unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV);
void BATTERY_GetReadings(const bool bDisplayBatteryLevel);
unsigned int BATTERY_VoltsToPercent(unsigned int voltage_10mV);
void BATTERY_GetReadings(bool bDisplayBatteryLevel);
void BATTERY_TimeSlice500ms(void);
#endif

BIN
images/codespace1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
images/codespace2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

9
init.c
View File

@@ -17,6 +17,7 @@
*/
#include <stdint.h>
#include <string.h>
extern uint32_t __bss_start__[];
extern uint32_t __bss_end__[];
@@ -29,9 +30,9 @@ void DATA_Init(void);
void BSS_Init(void)
{
uint32_t *pBss;
for (pBss = __bss_start__; pBss < __bss_end__; pBss++)
for (uint32_t *pBss = __bss_start__; pBss < __bss_end__; pBss++) {
*pBss = 0;
}
}
void DATA_Init(void)
@@ -39,8 +40,8 @@ void DATA_Init(void)
volatile uint32_t *pDataRam = (volatile uint32_t *)sram_data_start;
volatile uint32_t *pDataFlash = (volatile uint32_t *)flash_data_start;
uint32_t Size = (uint32_t)sram_data_end - (uint32_t)sram_data_start;
unsigned int i;
for (i = 0; i < (Size / 4); i++)
for (unsigned int i = 0; i < (Size / 4); i++) {
*pDataRam++ = *pDataFlash++;
}
}

76
main.c
View File

@@ -14,44 +14,52 @@
* limitations under the License.
*/
#include <stdint.h>
#include <string.h>
#include <stdio.h> // NULL
#ifdef ENABLE_AM_FIX
#include "am_fix.h"
#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/dtmf.h"
#include "audio.h"
#include "bsp/dp32g030/gpio.h"
#include "bsp/dp32g030/syscon.h"
#include "board.h"
#include "driver/backlight.h"
#include "driver/bk4819.h"
#include "driver/gpio.h"
#include "driver/system.h"
#include "driver/systick.h"
#include "driver/uart.h"
#ifdef ENABLE_UART
#include "driver/uart.h"
#endif
#include "helper/battery.h"
#include "helper/boot.h"
#include "misc.h"
#include "radio.h"
#include "settings.h"
#include "ui/lock.h"
#include "ui/welcome.h"
#include "ui/menu.h"
#include "version.h"
void _putchar(char c)
void _putchar(__attribute__((unused)) char c)
{
#ifdef ENABLE_UART
UART_Send((uint8_t *)&c, 1);
#endif
}
void Main(void)
{
unsigned int i;
BOOT_Mode_t BootMode;
// Enable clock gating of blocks we need
SYSCON_DEV_CLK_GATE = 0
| SYSCON_DEV_CLK_GATE_GPIOA_BITS_ENABLE
@@ -64,18 +72,19 @@ void Main(void)
| SYSCON_DEV_CLK_GATE_AES_BITS_ENABLE
| SYSCON_DEV_CLK_GATE_PWM_PLUS0_BITS_ENABLE;
SYSTICK_Init();
BOARD_Init();
UART_Init();
boot_counter_10ms = 250; // 2.5 sec
#ifdef ENABLE_UART
UART_Init();
UART_Send(UART_Version, strlen(UART_Version));
#endif
// Not implementing authentic device checks
memset(&gEeprom, 0, sizeof(gEeprom));
memset(gDTMF_String, '-', sizeof(gDTMF_String));
gDTMF_String[sizeof(gDTMF_String) - 1] = 0;
@@ -94,17 +103,17 @@ void Main(void)
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);
BATTERY_GetReadings(false);
#ifdef ENABLE_AM_FIX
AM_fix_init();
#endif
#ifdef ENABLE_AM_FIX
AM_fix_init();
#endif
const BOOT_Mode_t BootMode = BOOT_GetMode();
BootMode = BOOT_GetMode();
if (BootMode == BOOT_MODE_F_LOCK)
{
gF_LOCK = true; // flag to say include the hidden menu items
@@ -126,8 +135,9 @@ void Main(void)
{ // keys are pressed
UI_DisplayReleaseKeys();
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;
SYSTEM_DelayMs(10);
@@ -207,24 +217,18 @@ void Main(void)
#ifdef ENABLE_NOAA
RADIO_ConfigureNOAA();
#endif
// ******************
}
while (1)
{
while (true) {
APP_Update();
if (gNextTimeslice)
{
APP_TimeSlice10ms();
gNextTimeslice = false;
}
if (gNextTimeslice) {
if (gNextTimeslice_500ms)
{
APP_TimeSlice500ms();
gNextTimeslice_500ms = false;
APP_TimeSlice10ms();
if (gNextTimeslice_500ms) {
APP_TimeSlice500ms();
}
}
}
}

5
misc.c
View File

@@ -143,7 +143,7 @@ volatile uint8_t gVFOStateResumeCountdown_500ms;
bool gEnableSpeaker;
uint8_t gKeyInputCountdown = 0;
uint8_t gKeyLockCountdown;
uint8_t gRTTECountdown;
uint8_t gRTTECountdown_10ms;
bool bIsInLockScreen;
uint8_t gUpdateStatus;
uint8_t gFoundCTCSS;
@@ -181,9 +181,6 @@ bool gFlagPrepareTX;
bool gFlagAcceptSetting;
bool gFlagRefreshSetting;
bool gFlagSaveVfo;
bool gFlagSaveSettings;
bool gFlagSaveChannel;
#ifdef ENABLE_FMRADIO
bool gFlagSaveFM;
#endif

14
misc.h
View File

@@ -32,6 +32,10 @@
#define MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
#endif
#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_VALID_CHANNEL(x) ((x) < LAST_CHANNEL)
@@ -171,7 +175,7 @@ extern uint16_t gEEPROM_RSSI_CALIB[7][4];
extern uint16_t gEEPROM_1F8A;
extern uint16_t gEEPROM_1F8C;
typedef union {
typedef union {
struct {
uint8_t
band : 4,
@@ -203,16 +207,13 @@ extern volatile bool gTxTimeoutReached;
extern volatile uint16_t gTailNoteEliminationCountdown_10ms;
#ifdef ENABLE_FMRADIO
extern volatile uint16_t gFmPlayCountdown_10ms;
#endif
#ifdef ENABLE_NOAA
extern volatile uint16_t gNOAA_Countdown_10ms;
#endif
extern bool gEnableSpeaker;
extern uint8_t gKeyInputCountdown;
extern uint8_t gKeyLockCountdown;
extern uint8_t gRTTECountdown;
extern uint8_t gRTTECountdown_10ms;
extern bool bIsInLockScreen;
extern uint8_t gUpdateStatus;
extern uint8_t gFoundCTCSS;
@@ -259,9 +260,6 @@ extern bool gFlagPrepareTX;
extern bool gFlagAcceptSetting; // accept menu setting
extern bool gFlagRefreshSetting; // refresh menu display
extern bool gFlagSaveVfo;
extern bool gFlagSaveSettings;
extern bool gFlagSaveChannel;
#ifdef ENABLE_FMRADIO
extern bool gFlagSaveFM;
#endif

250
radio.c
View File

@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include "driver/bk4819-regs.h"
#include <string.h>
#include "am_fix.h"
@@ -55,69 +56,41 @@ const char gModulationStr[MODULATION_UKNOWN][4] = {
bool RADIO_CheckValidChannel(uint16_t Channel, bool bCheckScanList, uint8_t VFO)
{ // return true if the channel appears valid
ChannelAttributes_t att;
uint8_t PriorityCh1;
uint8_t PriorityCh2;
if (!IS_MR_CHANNEL(Channel))
bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanList)
{
// return true if the channel appears valid
if (!IS_MR_CHANNEL(channel))
return false;
att = gMR_ChannelAttributes[Channel];
const ChannelAttributes_t att = gMR_ChannelAttributes[channel];
if (att.band > BAND7_470MHz)
return false;
if (bCheckScanList) {
switch (VFO) {
case 0:
if (!att.scanlist1)
return false;
if (!checkScanList || scanList > 1)
return true;
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[0];
PriorityCh2 = gEeprom.SCANLIST_PRIORITY_CH2[0];
break;
if (scanList ? !att.scanlist2 : !att.scanlist1)
return false;
case 1:
if (!att.scanlist2)
return false;
const uint8_t PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[scanList];
const uint8_t PriorityCh2 = gEeprom.SCANLIST_PRIORITY_CH2[scanList];
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[1];
PriorityCh2 = gEeprom.SCANLIST_PRIORITY_CH2[1];
break;
default:
return true;
}
if (PriorityCh1 == Channel)
return false;
if (PriorityCh2 == Channel)
return false;
}
return true;
return PriorityCh1 != channel && PriorityCh2 != channel;
}
uint8_t RADIO_FindNextChannel(uint8_t Channel, int8_t Direction, bool bCheckScanList, uint8_t VFO)
{
unsigned int i;
for (i = 0; IS_MR_CHANNEL(i); i++)
{
if (Channel == 0xFF)
for (unsigned int i = 0; IS_MR_CHANNEL(i); i++, Channel += Direction) {
if (Channel == 0xFF) {
Channel = MR_CHANNEL_LAST;
else
if (!IS_MR_CHANNEL(Channel))
} else if (!IS_MR_CHANNEL(Channel)) {
Channel = MR_CHANNEL_FIRST;
}
if (RADIO_CheckValidChannel(Channel, bCheckScanList, VFO))
if (RADIO_CheckValidChannel(Channel, bCheckScanList, VFO)) {
return Channel;
Channel += Direction;
}
}
return 0xFF;
@@ -165,7 +138,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
if (IS_VALID_CHANNEL(channel)) {
#ifdef ENABLE_NOAA
if (channel >= NOAA_CHANNEL_FIRST)
if (IS_NOAA_CHANNEL(channel))
{
RADIO_InitInfo(pVfo, gEeprom.ScreenChannel[VFO], NoaaFrequencyTable[channel - NOAA_CHANNEL_FIRST]);
@@ -338,7 +311,8 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
#ifdef ENABLE_DTMF_CALLING
pVfo->DTMF_DECODING_ENABLE = ((data[5] >> 0) & 1u) ? true : false;
#endif
pVfo->DTMF_PTT_ID_TX_MODE = ((data[5] >> 1) & 7u);
uint8_t pttId = ((data[5] >> 1) & 7u);
pVfo->DTMF_PTT_ID_TX_MODE = pttId < ARRAY_SIZE(gSubMenu_PTT_ID) ? pttId : PTT_ID_OFF;
}
// ***************
@@ -443,56 +417,37 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
EEPROM_ReadBuffer(Base + 0x40, &pInfo->SquelchCloseGlitchThresh, 1); // 90 90
EEPROM_ReadBuffer(Base + 0x50, &pInfo->SquelchOpenGlitchThresh, 1); // 100 100
uint16_t rssi_open = pInfo->SquelchOpenRSSIThresh;
uint16_t rssi_close = pInfo->SquelchCloseRSSIThresh;
uint16_t noise_open = pInfo->SquelchOpenNoiseThresh;
uint16_t noise_close = pInfo->SquelchCloseNoiseThresh;
#if ENABLE_SQUELCH_MORE_SENSITIVE
uint16_t rssi_open = pInfo->SquelchOpenRSSIThresh;
uint16_t rssi_close = pInfo->SquelchCloseRSSIThresh;
uint16_t glitch_open = pInfo->SquelchOpenGlitchThresh;
uint16_t glitch_close = pInfo->SquelchCloseGlitchThresh;
#if ENABLE_SQUELCH_MORE_SENSITIVE
// make squelch a little more sensitive
//
// getting the best setting here is still experimental, bare with me
//
// note that 'noise' and 'glitch' values are inverted compared to 'rssi' values
#if 0
rssi_open = (rssi_open * 8) / 9;
noise_open = (noise_open * 9) / 8;
glitch_open = (glitch_open * 9) / 8;
#else
// even more sensitive .. use when RX bandwidths are fixed (no weak signal auto adjust)
rssi_open = (rssi_open * 1) / 2;
noise_open = (noise_open * 2) / 1;
glitch_open = (glitch_open * 2) / 1;
#endif
#else
// more sensitive .. use when RX bandwidths are fixed (no weak signal auto adjust)
rssi_open = (rssi_open * 3) / 4;
noise_open = (noise_open * 4) / 3;
glitch_open = (glitch_open * 4) / 3;
#endif
rssi_close = (rssi_open * 9) / 10;
noise_close = (noise_open * 10) / 9;
glitch_close = (glitch_open * 10) / 9;
// make squelch more sensitive
// note that 'noise' and 'glitch' values are inverted compared to 'rssi' values
rssi_open = (rssi_open * 1) / 2;
noise_open = (noise_open * 2) / 1;
glitch_open = (glitch_open * 2) / 1;
// ensure the 'close' threshold is lower than the 'open' threshold
if (rssi_close == rssi_open && rssi_close >= 2)
if (rssi_close == rssi_open && rssi_close >= 2)
rssi_close -= 2;
if (noise_close == noise_open && noise_close <= 125)
if (noise_close == noise_open && noise_close <= 125)
noise_close += 2;
if (glitch_close == glitch_open && glitch_close <= 253)
glitch_close += 2;
pInfo->SquelchOpenRSSIThresh = (rssi_open > 255) ? 255 : rssi_open;
pInfo->SquelchCloseRSSIThresh = (rssi_close > 255) ? 255 : rssi_close;
pInfo->SquelchOpenNoiseThresh = (noise_open > 127) ? 127 : noise_open;
pInfo->SquelchCloseNoiseThresh = (noise_close > 127) ? 127 : noise_close;
pInfo->SquelchOpenGlitchThresh = (glitch_open > 255) ? 255 : glitch_open;
pInfo->SquelchCloseGlitchThresh = (glitch_close > 255) ? 255 : glitch_close;
#endif
pInfo->SquelchOpenNoiseThresh = (noise_open > 127) ? 127 : noise_open;
pInfo->SquelchCloseNoiseThresh = (noise_close > 127) ? 127 : noise_close;
}
// *******************************
@@ -723,53 +678,29 @@ void RADIO_SetupRegisters(bool switchToForeground)
}
#endif
#ifdef ENABLE_VOX
#ifdef ENABLE_NOAA
#ifdef ENABLE_FMRADIO
if (gEeprom.VOX_SWITCH && !gFmRadioMode && !IS_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE) && gCurrentVfo->Modulation == MODULATION_FM)
#else
if (gEeprom.VOX_SWITCH && !IS_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE) && gCurrentVfo->Modulation == MODULATION_FM)
#endif
#else
#ifdef ENABLE_FMRADIO
if (gEeprom.VOX_SWITCH && !gFmRadioMode && gCurrentVfo->Modulation == MODULATION_FM)
#else
if (gEeprom.VOX_SWITCH && gCurrentVfo->Modulation == MODULATION_FM)
#endif
#endif
{
BK4819_EnableVox(gEeprom.VOX1_THRESHOLD, gEeprom.VOX0_THRESHOLD);
InterruptMask |= BK4819_REG_3F_VOX_FOUND | BK4819_REG_3F_VOX_LOST;
}
else
#endif
#ifdef ENABLE_VOX
if (gEeprom.VOX_SWITCH && gCurrentVfo->Modulation == MODULATION_FM
#ifdef ENABLE_NOAA
&& !IS_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE)
#endif
#ifdef ENABLE_FMRADIO
&& !gFmRadioMode
#endif
){
BK4819_EnableVox(gEeprom.VOX1_THRESHOLD, gEeprom.VOX0_THRESHOLD);
InterruptMask |= BK4819_REG_3F_VOX_FOUND | BK4819_REG_3F_VOX_LOST;
}
else
#endif
{
BK4819_DisableVox();
}
// RX expander
BK4819_SetCompander((gRxVfo->Modulation == MODULATION_FM && gRxVfo->Compander >= 2) ? gRxVfo->Compander : 0);
#if 0
if (!gRxVfo->DTMF_DECODING_ENABLE && !gSetting_KILLED)
{
BK4819_DisableDTMF();
}
else
{
BK4819_EnableDTMF();
InterruptMask |= BK4819_REG_3F_DTMF_5TONE_FOUND;
}
#else
if (gCurrentFunction != FUNCTION_TRANSMIT)
{
BK4819_DisableDTMF();
BK4819_EnableDTMF();
InterruptMask |= BK4819_REG_3F_DTMF_5TONE_FOUND;
}
else
{
BK4819_DisableDTMF();
}
#endif
BK4819_EnableDTMF();
InterruptMask |= BK4819_REG_3F_DTMF_5TONE_FOUND;
RADIO_SetupAGC(gRxVfo->Modulation == MODULATION_AM, false);
@@ -812,7 +743,7 @@ void RADIO_SetupRegisters(bool switchToForeground)
return;
}
if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST)
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
{
gIsNoaaMode = true;
gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
@@ -938,7 +869,7 @@ void RADIO_SetupAGC(bool listeningAM, bool disable)
BK4819_InitAGC(false);
}
else {
#ifdef ENABLE_AM_FIX
#ifdef ENABLE_AM_FIX
if(gSetting_AM_fix) { // if AM fix active lock AGC so AM-fix can do it's job
BK4819_SetAGC(0);
AM_fix_enable(!disable);
@@ -1042,15 +973,12 @@ void RADIO_PrepareTX(void)
#ifdef ENABLE_DTMF_CALLING
if (gDTMF_ReplyState == DTMF_REPLY_ANI)
{
if (gDTMF_CallMode == DTMF_CALL_MODE_DTMF)
{
gDTMF_IsTx = true;
gDTMF_IsTx = gDTMF_CallMode == DTMF_CALL_MODE_DTMF;
if (gDTMF_IsTx) {
gDTMF_CallState = DTMF_CALL_STATE_NONE;
gDTMF_TxStopCountdown_500ms = DTMF_txstop_countdown_500ms;
}
else
{
gDTMF_IsTx = false;
} else {
gDTMF_CallState = DTMF_CALL_STATE_CALL_OUT;
}
}
@@ -1074,7 +1002,7 @@ void RADIO_PrepareTX(void)
gTxTimeoutReached = false;
gFlagEndTransmission = false;
gRTTECountdown = 0;
gRTTECountdown_10ms = 0;
#ifdef ENABLE_DTMF_CALLING
gDTMF_ReplyState = DTMF_REPLY_NONE;
@@ -1096,6 +1024,16 @@ void RADIO_EnableCxCSS(void)
SYSTEM_DelayMs(200);
}
void RADIO_SendEndOfTransmission(void)
{
BK4819_PlayRoger();
DTMF_SendEndOfTransmission();
// send the CTCSS/DCS tail tone - allows the receivers to mute the usual FM squelch tail/crash
RADIO_EnableCxCSS();
RADIO_SetupRegisters(false);
}
void RADIO_PrepareCssTX(void)
{
RADIO_PrepareTX();
@@ -1105,45 +1043,3 @@ void RADIO_PrepareCssTX(void)
RADIO_EnableCxCSS();
RADIO_SetupRegisters(true);
}
void RADIO_SendEndOfTransmission(void)
{
if (gEeprom.ROGER == ROGER_MODE_ROGER)
BK4819_PlayRoger();
else
if (gEeprom.ROGER == ROGER_MODE_MDC)
BK4819_PlayRogerMDC();
if (gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO)
BK4819_PlaySingleTone(2475, 250, 28, gEeprom.DTMF_SIDE_TONE);
if (
#ifdef ENABLE_DTMF_CALLING
gDTMF_CallState == DTMF_CALL_STATE_NONE &&
#endif
(gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_TX_DOWN ||
gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_BOTH))
{ // end-of-tx
if (gEeprom.DTMF_SIDE_TONE)
{
AUDIO_AudioPathOn();
gEnableSpeaker = true;
SYSTEM_DelayMs(60);
}
BK4819_EnterDTMF_TX(gEeprom.DTMF_SIDE_TONE);
BK4819_PlayDTMFString(
gEeprom.DTMF_DOWN_CODE,
0,
gEeprom.DTMF_FIRST_CODE_PERSIST_TIME,
gEeprom.DTMF_HASH_CODE_PERSIST_TIME,
gEeprom.DTMF_CODE_PERSIST_TIME,
gEeprom.DTMF_CODE_INTERVAL_TIME);
AUDIO_AudioPathOff();
gEnableSpeaker = false;
}
BK4819_ExitDTMF_TX(true);
}

View File

@@ -148,14 +148,14 @@ extern DCS_CodeType_t gCurrentCodeType;
extern VfoState_t VfoState[2];
bool RADIO_CheckValidChannel(uint16_t ChNum, bool bCheckScanList, uint8_t RadioNum);
bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanList);
uint8_t RADIO_FindNextChannel(uint8_t ChNum, int8_t Direction, bool bCheckScanList, uint8_t RadioNum);
void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t Frequency);
void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure);
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo);
void RADIO_ApplyOffset(VFO_Info_t *pInfo);
void RADIO_SelectVfos(void);
void RADIO_SetupRegisters(bool bSwitchToFunction0);
void RADIO_SetupRegisters(bool switchToForeground);
#ifdef ENABLE_NOAA
void RADIO_ConfigureNOAA(void);
#endif
@@ -168,5 +168,4 @@ void RADIO_EnableCxCSS(void);
void RADIO_PrepareCssTX(void);
void RADIO_SendEndOfTransmission(void);
#endif

View File

@@ -53,8 +53,7 @@ void SystickHandler(void)
gNextTimeslice = true;
if ((gGlobalSysTickCounter % 50) == 0)
{
if ((gGlobalSysTickCounter % 50) == 0) {
gNextTimeslice_500ms = true;
DECREMENT_AND_TRIGGER(gTxTimerCountdown_500ms, gTxTimeoutReached);
@@ -64,9 +63,9 @@ void SystickHandler(void)
if ((gGlobalSysTickCounter & 3) == 0)
gNextTimeslice40ms = true;
#ifdef ENABLE_NOAA
DECREMENT(gNOAACountdown_10ms);
#endif
#ifdef ENABLE_NOAA
DECREMENT(gNOAACountdown_10ms);
#endif
DECREMENT(gFoundCDCSSCountdown_10ms);
@@ -82,12 +81,12 @@ void SystickHandler(void)
if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_RECEIVE)
DECREMENT_AND_TRIGGER(gDualWatchCountdown_10ms, gScheduleDualWatch);
#ifdef ENABLE_NOAA
if (gScanStateDir == SCAN_OFF && !gCssBackgroundScan && gEeprom.DUAL_WATCH == DUAL_WATCH_OFF)
if (gIsNoaaMode && gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT)
if (gCurrentFunction != FUNCTION_RECEIVE)
DECREMENT_AND_TRIGGER(gNOAA_Countdown_10ms, gScheduleNOAA);
#endif
#ifdef ENABLE_NOAA
if (gScanStateDir == SCAN_OFF && !gCssBackgroundScan && gEeprom.DUAL_WATCH == DUAL_WATCH_OFF)
if (gIsNoaaMode && gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT)
if (gCurrentFunction != FUNCTION_RECEIVE)
DECREMENT_AND_TRIGGER(gNOAA_Countdown_10ms, gScheduleNOAA);
#endif
if (gScanStateDir != SCAN_OFF)
if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT)
@@ -95,19 +94,19 @@ void SystickHandler(void)
DECREMENT_AND_TRIGGER(gTailNoteEliminationCountdown_10ms, gFlagTailNoteEliminationComplete);
#ifdef ENABLE_VOICE
DECREMENT_AND_TRIGGER(gCountdownToPlayNextVoice_10ms, gFlagPlayQueuedVoice);
#endif
#ifdef ENABLE_FMRADIO
if (gFM_ScanState != FM_SCAN_OFF && gCurrentFunction != FUNCTION_MONITOR)
if (gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_RECEIVE)
DECREMENT_AND_TRIGGER(gFmPlayCountdown_10ms, gScheduleFM);
#endif
#ifdef ENABLE_VOICE
DECREMENT_AND_TRIGGER(gCountdownToPlayNextVoice_10ms, gFlagPlayQueuedVoice);
#endif
#ifdef ENABLE_VOX
DECREMENT(gVoxStopCountdown_10ms);
#endif
#ifdef ENABLE_FMRADIO
if (gFM_ScanState != FM_SCAN_OFF && gCurrentFunction != FUNCTION_MONITOR)
if (gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_RECEIVE)
DECREMENT_AND_TRIGGER(gFmPlayCountdown_10ms, gScheduleFM);
#endif
#ifdef ENABLE_VOX
DECREMENT(gVoxStopCountdown_10ms);
#endif
DECREMENT(boot_counter_10ms);
}

View File

@@ -20,9 +20,9 @@
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif
#include "driver/bk1080.h"
#include "driver/bk4819.h"
#include "driver/eeprom.h"
#include "driver/uart.h"
#include "misc.h"
#include "settings.h"
#include "ui/menu.h"
@@ -36,15 +36,11 @@ static const uint32_t gDefaultFrequencyTable[] =
43350000 //
};
EEPROM_Config_t gEeprom;
EEPROM_Config_t gEeprom = { 0 };
void SETTINGS_InitEEPROM(void)
{
unsigned int i;
uint8_t Data[16];
memset(Data, 0, sizeof(Data));
uint8_t Data[16] = {0};
// 0E70..0E77
EEPROM_ReadBuffer(0x0E70, Data, 8);
gEeprom.CHAN_1_CALL = IS_MR_CHANNEL(Data[0]) ? Data[0] : MR_CHANNEL_FIRST;
@@ -83,31 +79,31 @@ void SETTINGS_InitEEPROM(void)
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_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;
uint16_t selFreq;
uint8_t selChn;
uint8_t isMrMode:1;
uint8_t band:2;
//uint8_t space:2;
} __attribute__((packed)) fmCfg;
EEPROM_ReadBuffer(0x0E88, &fmCfg, 4);
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;
gEeprom.FM_Band = fmCfg.band;
//gEeprom.FM_Space = fmCfg.space;
gEeprom.FM_SelectedFrequency =
(fmCfg.selFreq >= BK1080_GetFreqLoLimit(gEeprom.FM_Band) && fmCfg.selFreq <= BK1080_GetFreqHiLimit(gEeprom.FM_Band)) ?
fmCfg.selFreq : BK1080_GetFreqLoLimit(gEeprom.FM_Band);
gEeprom.FM_SelectedChannel = fmCfg.selChn;
gEeprom.FM_IsMrMode = fmCfg.isMrMode;
}
// 0E40..0E67
@@ -129,15 +125,15 @@ void SETTINGS_InitEEPROM(void)
// 0E98..0E9F
EEPROM_ReadBuffer(0x0E98, Data, 8);
memmove(&gEeprom.POWER_ON_PASSWORD, Data, 4);
memcpy(&gEeprom.POWER_ON_PASSWORD, Data, 4);
// 0EA0..0EA7
EEPROM_ReadBuffer(0x0EA0, Data, 8);
#ifdef ENABLE_VOICE
#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[2] > 50)) {
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];
}
@@ -166,7 +162,7 @@ void SETTINGS_InitEEPROM(void)
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
#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;
@@ -180,62 +176,51 @@ void SETTINGS_InitEEPROM(void)
// 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));
EEPROM_ReadBuffer(0x0EE0, Data, sizeof(gEeprom.ANI_DTMF_ID));
if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.ANI_DTMF_ID))) {
memcpy(gEeprom.ANI_DTMF_ID, Data, sizeof(gEeprom.ANI_DTMF_ID));
} else {
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));
EEPROM_ReadBuffer(0x0EE8, Data, sizeof(gEeprom.KILL_CODE));
if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.KILL_CODE))) {
memcpy(gEeprom.KILL_CODE, Data, sizeof(gEeprom.KILL_CODE));
} else {
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));
EEPROM_ReadBuffer(0x0EF0, Data, sizeof(gEeprom.REVIVE_CODE));
if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.REVIVE_CODE))) {
memcpy(gEeprom.REVIVE_CODE, Data, sizeof(gEeprom.REVIVE_CODE));
} else {
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));
EEPROM_ReadBuffer(0x0EF8, Data, sizeof(gEeprom.DTMF_UP_CODE));
if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.DTMF_UP_CODE))) {
memcpy(gEeprom.DTMF_UP_CODE, Data, sizeof(gEeprom.DTMF_UP_CODE));
} else {
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));
EEPROM_ReadBuffer(0x0F08, Data, sizeof(gEeprom.DTMF_DOWN_CODE));
if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.DTMF_DOWN_CODE))) {
memcpy(gEeprom.DTMF_DOWN_CODE, Data, sizeof(gEeprom.DTMF_DOWN_CODE));
} else {
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++)
gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 3) ? Data[0] : 0; // we now have 'all' channel scan option
for (unsigned int i = 0; i < 2; i++)
{
const unsigned int j = 1 + (i * 3);
gEeprom.SCAN_LIST_ENABLED[i] = (Data[j + 0] < 2) ? Data[j] : false;
@@ -255,13 +240,13 @@ void SETTINGS_InitEEPROM(void)
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_live_DTMF_decoder = !!(Data[7] & (1u << 1));
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;
gSetting_mic_bar = !!(Data[7] & (1u << 4));
#endif
#ifdef ENABLE_AM_FIX
gSetting_AM_fix = (Data[7] & (1u << 5)) ? true : false;
gSetting_AM_fix = !!(Data[7] & (1u << 5));
#endif
gSetting_backlight_on_tx_rx = (Data[7] >> 6) & 3u;
@@ -278,13 +263,13 @@ void SETTINGS_InitEEPROM(void)
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++)
for (unsigned int i = 0; i < ARRAY_SIZE(gCustomAesKey); i++)
{
if (gCustomAesKey[i] != 0xFFFFFFFFu)
{
@@ -319,7 +304,7 @@ void SETTINGS_LoadCalibration(void)
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];
@@ -358,7 +343,7 @@ uint32_t SETTINGS_FetchChannelFrequency(const int channel)
} __attribute__((packed)) info;
EEPROM_ReadBuffer(channel * 16, &info, sizeof(info));
return info.frequency;
}
@@ -366,17 +351,16 @@ void SETTINGS_FetchChannelName(char *s, const int channel)
{
if (s == NULL)
return;
memset(s, 0, 11); // 's' had better be large enough !
s[0] = 0;
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);
EEPROM_ReadBuffer(0x0F50 + (channel * 16), s, 10);
int i;
for (i = 0; i < 10; i++)
@@ -435,25 +419,28 @@ void SETTINGS_FactoryReset(bool bIsAll)
}
#ifdef ENABLE_FMRADIO
void SETTINGS_SaveFM(void)
void SETTINGS_SaveFM(void)
{
unsigned int i;
union {
struct {
uint16_t selFreq;
uint8_t selChn;
uint8_t isMrMode:1;
uint8_t band:2;
//uint8_t space:2;
};
uint8_t __raw[8];
} __attribute__((packed)) fmCfg;
struct
{
uint16_t Frequency;
uint8_t Channel;
bool IsChannelSelected;
uint8_t Padding[4];
} State;
memset(fmCfg.__raw, 0xFF, sizeof(fmCfg.__raw));
fmCfg.selChn = gEeprom.FM_SelectedChannel;
fmCfg.selFreq = gEeprom.FM_SelectedFrequency;
fmCfg.isMrMode = gEeprom.FM_IsMrMode;
fmCfg.band = gEeprom.FM_Band;
//fmCfg.space = gEeprom.FM_Space;
EEPROM_WriteBuffer(0x0E88, fmCfg.__raw);
memset(&State, 0xFF, sizeof(State));
State.Channel = gEeprom.FM_SelectedChannel;
State.Frequency = gEeprom.FM_SelectedFrequency;
State.IsChannelSelected = gEeprom.FM_IsMrMode;
EEPROM_WriteBuffer(0x0E88, &State);
for (i = 0; i < 5; i++)
for (unsigned i = 0; i < 5; i++)
EEPROM_WriteBuffer(0x0E40 + (i * 8), &gFM_Channels[i * 4]);
}
#endif
@@ -538,7 +525,7 @@ void SETTINGS_SaveSettings(void)
#ifdef ENABLE_RSSI_BAR
State[1] = gEeprom.S0_LEVEL;
State[2] = gEeprom.S9_LEVEL;
#endif
#endif
EEPROM_WriteBuffer(0x0EA0, State);
@@ -559,7 +546,7 @@ void SETTINGS_SaveSettings(void)
State[2] = gEeprom.DTMF_GROUP_CALL_CODE;
State[3] = gEeprom.DTMF_DECODE_RESPONSE;
State[4] = gEeprom.DTMF_auto_reset_time;
#endif
#endif
State[5] = gEeprom.DTMF_PRELOAD_TIME / 10U;
State[6] = gEeprom.DTMF_FIRST_CODE_PERSIST_TIME / 10U;
State[7] = gEeprom.DTMF_HASH_CODE_PERSIST_TIME / 10U;
@@ -603,68 +590,66 @@ void SETTINGS_SaveSettings(void)
if (!gSetting_AM_fix) State[7] &= ~(1u << 5);
#endif
State[7] = (State[7] & ~(3u << 6)) | ((gSetting_backlight_on_tx_rx & 3u) << 6);
EEPROM_WriteBuffer(0x0F40, State);
}
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode)
{
#ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(Channel))
#endif
{
uint16_t OffsetVFO = Channel * 16;
if (!IS_MR_CHANNEL(Channel))
{ // it's a VFO, not a channel
OffsetVFO = (VFO == 0) ? 0x0C80 : 0x0C90;
OffsetVFO += (Channel - FREQ_CHANNEL_FIRST) * 32;
}
if (Mode >= 2 || !IS_MR_CHANNEL(Channel))
{ // copy VFO to a channel
union {
uint8_t _8[8];
uint32_t _32[2];
} State;
State._32[0] = pVFO->freq_config_RX.Frequency;
State._32[1] = pVFO->TX_OFFSET_FREQUENCY;
EEPROM_WriteBuffer(OffsetVFO + 0, State._32);
State._8[0] = pVFO->freq_config_RX.Code;
State._8[1] = pVFO->freq_config_TX.Code;
State._8[2] = (pVFO->freq_config_TX.CodeType << 4) | pVFO->freq_config_RX.CodeType;
State._8[3] = (pVFO->Modulation << 4) | pVFO->TX_OFFSET_FREQUENCY_DIRECTION;
State._8[4] = 0
| (pVFO->BUSY_CHANNEL_LOCK << 4)
| (pVFO->OUTPUT_POWER << 2)
| (pVFO->CHANNEL_BANDWIDTH << 1)
| (pVFO->FrequencyReverse << 0);
State._8[5] = ((pVFO->DTMF_PTT_ID_TX_MODE & 7u) << 1)
#ifdef ENABLE_DTMF_CALLING
| ((pVFO->DTMF_DECODING_ENABLE & 1u) << 0)
#ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(Channel))
return;
#endif
;
State._8[6] = pVFO->STEP_SETTING;
State._8[7] = pVFO->SCRAMBLING_TYPE;
EEPROM_WriteBuffer(OffsetVFO + 8, State._8);
SETTINGS_UpdateChannel(Channel, pVFO, true);
uint16_t OffsetVFO = Channel * 16;
if (IS_MR_CHANNEL(Channel)) {
#ifndef ENABLE_KEEP_MEM_NAME
// clear/reset the channel name
SETTINGS_SaveChannelName(Channel, "");
#else
if (Mode >= 3) {
SETTINGS_SaveChannelName(Channel, pVFO->Name);
}
#endif
if (IS_FREQ_CHANNEL(Channel)) { // it's a VFO, not a channel
OffsetVFO = (VFO == 0) ? 0x0C80 : 0x0C90;
OffsetVFO += (Channel - FREQ_CHANNEL_FIRST) * 32;
}
if (Mode >= 2 || IS_FREQ_CHANNEL(Channel)) { // copy VFO to a channel
union {
uint8_t _8[8];
uint32_t _32[2];
} State;
State._32[0] = pVFO->freq_config_RX.Frequency;
State._32[1] = pVFO->TX_OFFSET_FREQUENCY;
EEPROM_WriteBuffer(OffsetVFO + 0, State._32);
State._8[0] = pVFO->freq_config_RX.Code;
State._8[1] = pVFO->freq_config_TX.Code;
State._8[2] = (pVFO->freq_config_TX.CodeType << 4) | pVFO->freq_config_RX.CodeType;
State._8[3] = (pVFO->Modulation << 4) | pVFO->TX_OFFSET_FREQUENCY_DIRECTION;
State._8[4] = 0
| (pVFO->BUSY_CHANNEL_LOCK << 4)
| (pVFO->OUTPUT_POWER << 2)
| (pVFO->CHANNEL_BANDWIDTH << 1)
| (pVFO->FrequencyReverse << 0);
State._8[5] = ((pVFO->DTMF_PTT_ID_TX_MODE & 7u) << 1)
#ifdef ENABLE_DTMF_CALLING
| ((pVFO->DTMF_DECODING_ENABLE & 1u) << 0)
#endif
;
State._8[6] = pVFO->STEP_SETTING;
State._8[7] = pVFO->SCRAMBLING_TYPE;
EEPROM_WriteBuffer(OffsetVFO + 8, State._8);
SETTINGS_UpdateChannel(Channel, pVFO, true);
if (IS_MR_CHANNEL(Channel)) {
#ifndef ENABLE_KEEP_MEM_NAME
// clear/reset the channel name
SETTINGS_SaveChannelName(Channel, "");
#else
if (Mode >= 3) {
SETTINGS_SaveChannelName(Channel, pVFO->Name);
}
#endif
}
}
}
void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration)
@@ -680,9 +665,8 @@ void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration)
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));
uint8_t buf[16] = {0};
memcpy(buf, name, MIN(strlen(name), 10u));
EEPROM_WriteBuffer(0x0F50 + offset, buf);
EEPROM_WriteBuffer(0x0F58 + offset, buf + 8);
}
@@ -729,7 +713,7 @@ void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep)
void SETTINGS_WriteBuildOptions(void)
{
uint8_t buf[8]= {};
uint8_t buf[8] = {0};
buf[0] = 0
#ifdef ENABLE_FMRADIO
| (1 << 0)
@@ -770,6 +754,9 @@ buf[1] = 0
#ifdef ENABLE_BLMIN_TMP_OFF
| (1 << 3)
#endif
#ifdef ENABLE_AM_FIX
| (1 << 4)
#endif
;
EEPROM_WriteBuffer(0x1FF0, buf);
}

View File

@@ -128,9 +128,9 @@ typedef struct {
uint8_t ScreenChannel[2]; // current channels set in the radio (memory or frequency channels)
uint8_t FreqChannel[2]; // last frequency channels used
uint8_t MrChannel[2]; // last memory channels used
#ifdef ENABLE_NOAA
uint8_t NoaaChannel[2];
#endif
#ifdef ENABLE_NOAA
uint8_t NoaaChannel[2];
#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
@@ -143,23 +143,23 @@ typedef struct {
uint8_t field7_0xa;
uint8_t field8_0xb;
#ifdef ENABLE_FMRADIO
uint16_t FM_SelectedFrequency;
uint8_t FM_SelectedChannel;
bool FM_IsMrMode;
uint16_t FM_FrequencyPlaying;
uint16_t FM_LowerLimit;
uint16_t FM_UpperLimit;
#endif
#ifdef ENABLE_FMRADIO
uint16_t FM_SelectedFrequency;
uint8_t FM_SelectedChannel;
bool FM_IsMrMode;
uint16_t FM_FrequencyPlaying;
uint8_t FM_Band : 2;
//uint8_t FM_Space : 2;
#endif
uint8_t SQUELCH_LEVEL;
uint8_t TX_TIMEOUT_TIMER;
bool KEY_LOCK;
bool VOX_SWITCH;
uint8_t VOX_LEVEL;
#ifdef ENABLE_VOICE
VOICE_Prompt_t VOICE_PROMPT;
#endif
#ifdef ENABLE_VOICE
VOICE_Prompt_t VOICE_PROMPT;
#endif
bool BEEP_CONTROL;
uint8_t CHANNEL_DISPLAY_MODE;
bool TAIL_TONE_ELIMINATION;
@@ -181,9 +181,9 @@ typedef struct {
uint8_t field38_0x33;
bool AUTO_KEYPAD_LOCK;
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
ALARM_Mode_t ALARM_MODE;
#endif
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
ALARM_Mode_t ALARM_MODE;
#endif
POWER_OnDisplayMode_t POWER_ON_DISPLAY_MODE;
ROGER_Mode_t ROGER;
uint8_t REPEATER_TAIL_TONE_ELIMINATION;
@@ -225,9 +225,9 @@ typedef struct {
bool PERMIT_REMOTE_KILL;
#endif
int16_t BK4819_XTAL_FREQ_LOW;
#ifdef ENABLE_NOAA
bool NOAA_AUTO_SCAN;
#endif
#ifdef ENABLE_NOAA
bool NOAA_AUTO_SCAN;
#endif
uint8_t VOLUME_GAIN;
uint8_t DAC_GAIN;

View File

@@ -29,41 +29,41 @@
void UI_DisplayAircopy(void)
{
char String[16];
char String[16] = { 0 };
char *pPrintStr = { 0 };
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
UI_DisplayClear();
if (gAircopyState == AIRCOPY_READY)
strcpy(String, "AIR COPY(RDY)");
else
if (gAircopyState == AIRCOPY_TRANSFER)
strcpy(String, "AIR COPY");
else
strcpy(String, "AIR COPY(CMP)");
UI_PrintString(String, 2, 127, 0, 8);
if (gAircopyState == AIRCOPY_READY) {
pPrintStr = "AIR COPY(RDY)";
} else if (gAircopyState == AIRCOPY_TRANSFER) {
pPrintStr = "AIR COPY";
} else {
pPrintStr = "AIR COPY(CMP)";
}
if (gInputBoxIndex == 0)
{
UI_PrintString(pPrintStr, 2, 127, 0, 8);
if (gInputBoxIndex == 0) {
uint32_t frequency = gRxVfo->freq_config_RX.Frequency;
sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000);
// show the remaining 2 small frequency digits
UI_PrintStringSmall(String + 7, 97, 0, 3);
UI_PrintStringSmallNormal(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);
} else {
const char *ascii = INPUTBOX_GetAscii();
sprintf(String, "%.3s.%.3s", ascii, ascii + 3);
UI_DisplayFrequency(String, 16, 2, false);
}
memset(String, 0, sizeof(String));
if (gAirCopyIsSendMode == 0)
if (gAirCopyIsSendMode == 0) {
sprintf(String, "RCV:%u E:%u", gAirCopyBlockNumber, gErrorsDuringAirCopy);
else
if (gAirCopyIsSendMode == 1)
} else if (gAirCopyIsSendMode == 1) {
sprintf(String, "SND:%u", gAirCopyBlockNumber);
}
UI_PrintString(String, 2, 127, 4, 8);
ST7565_BlitFullScreen();

View File

@@ -21,30 +21,29 @@
#include "driver/st7565.h"
#include "functions.h"
#include "ui/battery.h"
#include "../misc.h"
void UI_DrawBattery(uint8_t* bitmap, uint8_t level, uint8_t blink)
{
if (level < 2 && blink == 1) {
memset(bitmap, 0, sizeof(BITMAP_BatteryLevel1));
return;
}
else
{
memmove(bitmap, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
if (level > 2)
{
unsigned int i;
uint8_t bars = level - 2;
if (bars > 4)
bars = 4;
for (i = 0; i < bars; i++)
{
#ifndef ENABLE_REVERSE_BAT_SYMBOL
memcpy(bitmap + sizeof(BITMAP_BatteryLevel1) - 4 - (i * 3), BITMAP_BatteryLevel, 2);
#else
memcpy(bitmap + 3 + (i * 3) + 0, BITMAP_BatteryLevel, 2);
#endif
}
}
memcpy(bitmap, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1));
if (level <= 2) {
return;
}
const uint8_t bars = MIN(4, level - 2);
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
}
}

View File

@@ -19,6 +19,7 @@
#include <string.h>
#include "app/fm.h"
#include "driver/bk1080.h"
#include "driver/st7565.h"
#include "external/printf/printf.h"
#include "misc.h"
@@ -30,83 +31,70 @@
void UI_DisplayFM(void)
{
unsigned int i;
char String[16];
char String[16] = {0};
char *pPrintStr = String;
UI_DisplayClear();
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
UI_PrintString("FM", 2, 0, 0, 8);
memset(String, 0, sizeof(String));
strcpy(String, "FM");
UI_PrintString(String, 0, 127, 0, 12);
sprintf(String, "%d%s-%dM",
BK1080_GetFreqLoLimit(gEeprom.FM_Band)/10,
gEeprom.FM_Band == 0 ? ".5" : "",
BK1080_GetFreqHiLimit(gEeprom.FM_Band)/10
);
UI_PrintStringSmallNormal(String, 1, 0, 6);
memset(String, 0, sizeof(String));
if (gAskToSave)
{
strcpy(String, "SAVE?");
}
else
if (gAskToDelete)
{
strcpy(String, "DEL?");
}
else
{
if (gFM_ScanState == FM_SCAN_OFF)
{
if (!gEeprom.FM_IsMrMode)
{
for (i = 0; i < 20; i++)
{
if (gEeprom.FM_FrequencyPlaying == gFM_Channels[i])
{
sprintf(String, "VFO(CH%02u)", i + 1);
break;
}
//uint8_t spacings[] = {20,10,5};
//sprintf(String, "%d0k", spacings[gEeprom.FM_Space % 3]);
//UI_PrintStringSmallNormal(String, 127 - 4*7, 0, 6);
if (gAskToSave) {
pPrintStr = "SAVE?";
} else if (gAskToDelete) {
pPrintStr = "DEL?";
} else if (gFM_ScanState == FM_SCAN_OFF) {
if (gEeprom.FM_IsMrMode) {
sprintf(String, "MR(CH%02u)", gEeprom.FM_SelectedChannel + 1);
pPrintStr = String;
} else {
pPrintStr = "VFO";
for (unsigned int i = 0; i < 20; i++) {
if (gEeprom.FM_FrequencyPlaying == gFM_Channels[i]) {
sprintf(String, "VFO(CH%02u)", i + 1);
pPrintStr = String;
break;
}
if (i == 20)
strcpy(String, "VFO");
}
else
sprintf(String, "MR(CH%02u)", gEeprom.FM_SelectedChannel + 1);
}
else
{
if (!gFM_AutoScan)
strcpy(String, "M-SCAN");
else
sprintf(String, "A-SCAN(%u)", gFM_ChannelPosition + 1);
}
} else if (gFM_AutoScan) {
sprintf(String, "A-SCAN(%u)", gFM_ChannelPosition + 1);
pPrintStr = String;
} else {
pPrintStr = "M-SCAN";
}
UI_PrintString(String, 0, 127, 2, 10);
UI_PrintString(pPrintStr, 0, 127, 3, 10); // memory, vfo, scan
memset(String, 0, sizeof(String));
if (gAskToSave || (gEeprom.FM_IsMrMode && gInputBoxIndex > 0))
{
if (gAskToSave || (gEeprom.FM_IsMrMode && gInputBoxIndex > 0)) {
UI_GenerateChannelString(String, gFM_ChannelPosition);
}
else
if (!gAskToDelete)
{
if (gInputBoxIndex == 0)
{
} else if (gAskToDelete) {
sprintf(String, "CH-%02u", gEeprom.FM_SelectedChannel + 1);
} else {
if (gInputBoxIndex == 0) {
sprintf(String, "%3d.%d", gEeprom.FM_FrequencyPlaying / 10, gEeprom.FM_FrequencyPlaying % 10);
UI_DisplayFrequency(String, 32, 4, true);
}
else {
} else {
const char * ascii = INPUTBOX_GetAscii();
sprintf(String, "%.3s.%.1s",ascii, ascii + 3);
UI_DisplayFrequency(String, 32, 4, false);
}
UI_DisplayFrequency(String, 36, 1, gInputBoxIndex == 0); // frequency
ST7565_BlitFullScreen();
return;
}
else
{
sprintf(String, "CH-%02u", gEeprom.FM_SelectedChannel + 1);
}
UI_PrintString(String, 0, 127, 4, 10);
UI_PrintString(String, 0, 127, 1, 10);
ST7565_BlitFullScreen();
}

View File

@@ -46,21 +46,36 @@ void UI_GenerateChannelString(char *pString, const uint8_t Channel)
void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uint8_t ChannelNumber)
{
if (gInputBoxIndex > 0)
{
unsigned int i;
for (i = 0; i < 3; i++)
if (gInputBoxIndex > 0) {
for (unsigned int i = 0; i < 3; i++) {
pString[i] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0';
}
pString[3] = 0;
return;
}
if (bShowPrefix)
if (bShowPrefix) {
// BUG here? Prefixed NULLs are allowed
sprintf(pString, "CH-%03u", ChannelNumber + 1);
else
if (ChannelNumber == 0xFF)
} else if (ChannelNumber == 0xFF) {
strcpy(pString, "NULL");
else
} else {
sprintf(pString, "%03u", ChannelNumber + 1);
}
}
void UI_PrintStringBuffer(const char *pString, uint8_t * buffer, uint32_t char_width, const uint8_t *font)
{
const size_t Length = strlen(pString);
const unsigned int char_spacing = char_width + 1;
for (size_t i = 0; i < Length; i++) {
const unsigned int index = pString[i] - ' ' - 1;
if (pString[i] > ' ' && pString[i] < 127) {
const uint32_t offset = i * char_spacing + 1;
memcpy(buffer + offset, font + index * char_width, char_width);
}
}
}
void UI_PrintString(const char *pString, uint8_t Start, uint8_t End, uint8_t Line, uint8_t Width)
@@ -77,74 +92,57 @@ void UI_PrintString(const char *pString, uint8_t Start, uint8_t End, uint8_t Lin
if (pString[i] > ' ' && pString[i] < 127)
{
const unsigned int index = pString[i] - ' ' - 1;
memmove(gFrameBuffer[Line + 0] + ofs, &gFontBig[index][0], 7);
memmove(gFrameBuffer[Line + 1] + ofs, &gFontBig[index][7], 7);
memcpy(gFrameBuffer[Line + 0] + ofs, &gFontBig[index][0], 7);
memcpy(gFrameBuffer[Line + 1] + ofs, &gFontBig[index][7], 7);
}
}
}
void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_t Line)
void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_t Line, uint8_t char_width, const uint8_t *font)
{
const size_t Length = strlen(pString);
size_t i;
const unsigned int char_width = ARRAY_SIZE(gFontSmall[0]);
const unsigned int char_spacing = char_width + 1;
if (End > Start)
Start += (((End - Start) - (Length * char_spacing)) + 1) / 2;
uint8_t *pFb = gFrameBuffer[Line] + Start;
for (i = 0; i < Length; i++)
{
if (pString[i] > ' ')
{
const unsigned int index = (unsigned int)pString[i] - ' ' - 1;
if (index < ARRAY_SIZE(gFontSmall))
memmove(pFb + (i * char_spacing) + 1, &gFontSmall[index], char_width);
}
if (End > Start) {
Start += (((End - Start) - Length * char_spacing) + 1) / 2;
}
UI_PrintStringBuffer(pString, gFrameBuffer[Line] + Start, char_width, font);
}
void UI_PrintStringSmallNormal(const char *pString, uint8_t Start, uint8_t End, uint8_t Line)
{
UI_PrintStringSmall(pString, Start, End, Line, ARRAY_SIZE(gFontSmall[0]), (const uint8_t *)gFontSmall);
}
void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line)
{
#ifdef ENABLE_SMALL_BOLD
void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line)
{
const size_t Length = strlen(pString);
size_t i;
if (End > Start)
Start += (((End - Start) - (Length * 8)) + 1) / 2;
const unsigned int char_width = ARRAY_SIZE(gFontSmallBold[0]);
const unsigned int char_spacing = char_width + 1;
uint8_t *pFb = gFrameBuffer[Line] + Start;
for (i = 0; i < Length; i++)
{
if (pString[i] > ' ')
{
const unsigned int index = (unsigned int)pString[i] - ' ' - 1;
if (index < ARRAY_SIZE(gFontSmallBold))
memmove(pFb + (i * char_spacing) + 1, &gFontSmallBold[index], char_width);
}
}
}
const uint8_t *font = (uint8_t *)gFontSmallBold;
const uint8_t char_width = ARRAY_SIZE(gFontSmallBold[0]);
#else
const uint8_t *font = (uint8_t *)gFontSmall;
const uint8_t char_width = ARRAY_SIZE(gFontSmall[0]);
#endif
void UI_PrintStringSmallBuffer(const char *pString, uint8_t *buffer)
UI_PrintStringSmall(pString, Start, End, Line, char_width, font);
}
void UI_PrintStringSmallBufferNormal(const char *pString, uint8_t * buffer)
{
size_t i;
const unsigned int char_width = ARRAY_SIZE(gFontSmall[0]);
const unsigned int char_spacing = char_width + 1;
for (i = 0; i < strlen(pString); i++)
{
if (pString[i] > ' ')
{
const unsigned int index = (unsigned int)pString[i] - ' ' - 1;
if (index < ARRAY_SIZE(gFontSmall))
memmove(buffer + (i * char_spacing) + 1, &gFontSmall[index], char_width);
}
}
UI_PrintStringBuffer(pString, buffer, ARRAY_SIZE(gFontSmall[0]), (uint8_t *)gFontSmall);
}
void UI_PrintStringSmallBufferBold(const char *pString, uint8_t * buffer)
{
#ifdef ENABLE_SMALL_BOLD
const uint8_t *font = (uint8_t *)gFontSmallBold;
const uint8_t char_width = ARRAY_SIZE(gFontSmallBold[0]);
#else
const uint8_t *font = (uint8_t *)gFontSmall;
const uint8_t char_width = ARRAY_SIZE(gFontSmall[0]);
#endif
UI_PrintStringBuffer(pString, buffer, char_width, font);
}
void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center)
@@ -171,7 +169,7 @@ void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center)
*pFb1 = 0x60; pFb0++; pFb1++;
continue;
}
}
else if (center) {
pFb0 -= 6;
@@ -182,7 +180,7 @@ void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center)
}
}
void UI_DrawPixelBuffer(uint8_t (*buffer)[128], uint8_t x, uint8_t y, bool black)
void UI_DrawPixelBuffer(uint8_t (*buffer)[128], uint8_t x, uint8_t y, bool black)
{
const uint8_t pattern = 1 << (y % 8);
if(black)
@@ -228,11 +226,10 @@ void UI_DrawRectangleBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int1
UI_DrawLineBuffer(buffer, x1,y2, x2,y2, black);
}
void UI_DisplayPopup(const char *string)
void UI_DisplayPopup(const char *string)
{
for(uint8_t i = 0; i < 7; i++) {
memset(gFrameBuffer[i], 0x00, 128);
}
UI_DisplayClear();
// for(uint8_t i = 1; i < 5; i++) {
// memset(gFrameBuffer[i]+8, 0x00, 111);
@@ -249,5 +246,10 @@ void UI_DisplayPopup(const char *string)
// }
// DrawRectangle(9,9, 118,38, true);
UI_PrintString(string, 9, 118, 2, 8);
UI_PrintStringSmall("Press EXIT", 9, 118, 6);
}
UI_PrintStringSmallNormal("Press EXIT", 9, 118, 6);
}
void UI_DisplayClear()
{
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
}

View File

@@ -23,13 +23,11 @@
void UI_GenerateChannelString(char *pString, const uint8_t Channel);
void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uint8_t ChannelNumber);
void UI_PrintString(const char *pString, uint8_t Start, uint8_t End, uint8_t Line, uint8_t Width);
void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_t Line);
#ifdef ENABLE_SMALL_BOLD
void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line);
#endif
void UI_PrintStringSmallBuffer(const char *pString, uint8_t *buffer);
void UI_PrintStringSmallNormal(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);
void UI_PrintStringSmallBufferNormal(const char *pString, uint8_t *buffer);
void UI_PrintStringSmallBufferBold(const char *pString, uint8_t * buffer);
void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center);
#endif
void UI_DisplayPopup(const char *string);
@@ -37,3 +35,6 @@ 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);
void UI_DisplayClear();
#endif

View File

@@ -35,10 +35,9 @@ static void Render(void)
char String[7];
memset(gStatusLine, 0, sizeof(gStatusLine));
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
UI_DisplayClear();
strcpy(String, "LOCK");
UI_PrintString(String, 0, 127, 1, 10);
UI_PrintString("LOCK", 0, 127, 1, 10);
for (i = 0; i < 6; i++)
String[i] = (gInputBox[i] == 10) ? '-' : '*';
String[6] = 0;
@@ -143,13 +142,14 @@ void UI_DisplayLock(void)
gKeyReading0 = Key;
}
#ifdef ENABLE_UART
if (UART_IsCommandAvailable())
{
__disable_irq();
UART_HandleCommand();
__enable_irq();
}
#endif
if (gUpdateDisplay)
{
Render();

236
ui/main.c
View File

@@ -19,7 +19,7 @@
#include "app/chFrScanner.h"
#include "app/dtmf.h"
#ifdef ENABLE_AM_FIX_SHOW_DATA
#ifdef ENABLE_AM_FIX
#include "am_fix.h"
#endif
#include "bitmaps.h"
@@ -37,8 +37,6 @@
#include "ui/main.h"
#include "ui/ui.h"
#include "debugging.h"
center_line_t center_line = CENTER_LINE_NONE;
const int8_t dBmCorrTable[7] = {
@@ -138,7 +136,7 @@ void UI_DisplayAudioBar(void)
{
return; // screen is in use
}
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
if (gAlarmState != ALARM_STATE_OFF)
return;
@@ -183,7 +181,7 @@ void DisplayRSSIBar(const bool now)
0b00011000,
};
if (gEeprom.KEY_LOCK && gKeypadLocked > 0)
if ((gEeprom.KEY_LOCK && gKeypadLocked > 0) || center_line != CENTER_LINE_RSSI)
return; // display is in use
if (gCurrentFunction == FUNCTION_TRANSMIT ||
@@ -196,21 +194,21 @@ void DisplayRSSIBar(const bool now)
if (now)
memset(p_line, 0, LCD_WIDTH);
const int16_t s0_dBm = -gEeprom.S0_LEVEL; // S0 .. base level
const int16_t rssi_dBm =
const int16_t rssi_dBm =
BK4819_GetRSSI_dBm()
#ifdef ENABLE_AM_FIX
+ ((gSetting_AM_fix && gRxVfo->Modulation == MODULATION_AM) ? AM_fix_get_gain_diff() : 0)
#endif
#endif
+ dBmCorrTable[gRxVfo->Band];
int s0_9 = gEeprom.S0_LEVEL - gEeprom.S9_LEVEL;
const uint8_t s_level = MIN(MAX((int32_t)(rssi_dBm - s0_dBm)*100 / (s0_9*100/9), 0), 9); // S0 - S9
uint8_t overS9dBm = MIN(MAX(rssi_dBm + gEeprom.S9_LEVEL, 0), 99);
uint8_t overS9Bars = MIN(overS9dBm/10, 4);
if(overS9Bars == 0) {
sprintf(str, "% 4d S%d", rssi_dBm, s_level);
}
@@ -219,7 +217,7 @@ void DisplayRSSIBar(const bool now)
memcpy(p_line + 2 + 7*5, &plus, ARRAY_SIZE(plus));
}
UI_PrintStringSmall(str, 2, 0, line);
UI_PrintStringSmallNormal(str, 2, 0, line);
DrawLevelBar(bar_x, line, s_level + overS9Bars);
if (now)
ST7565_BlitLine(line);
@@ -244,13 +242,13 @@ void DisplayRSSIBar(const bool now)
memset(pLine, 0, 23);
DrawSmallAntennaAndBars(pLine, Level);
if (now)
ST7565_BlitFullScreen();
ST7565_BlitFullScreen();
#endif
}
#ifdef ENABLE_AGC_SHOW_DATA
static void PrintAGC(bool now)
void UI_MAIN_PrintAGC(bool now)
{
char buf[20];
memset(gFrameBuffer[3], 0, 128);
@@ -258,7 +256,7 @@ static void PrintAGC(bool now)
struct {
uint16_t _ : 5;
uint16_t agcSigStrength : 7;
int16_t gainIdx : 3;
int16_t gainIdx : 3;
uint16_t agcEnab : 1;
};
uint16_t __raw;
@@ -282,7 +280,7 @@ static void PrintAGC(bool now)
int16_t agcGain = lnaShortTab[agcGainReg.lnaS] + lnaTab[agcGainReg.lna] + mixerTab[agcGainReg.mixer] + pgaTab[agcGainReg.pga];
sprintf(buf, "%d%2d %2d %2d %3d", reg7e.agcEnab, reg7e.gainIdx, -agcGain, reg7e.agcSigStrength, BK4819_GetRSSI());
UI_PrintStringSmall(buf, 2, 0, 3);
UI_PrintStringSmallNormal(buf, 2, 0, 3);
if(now)
ST7565_BlitLine(3);
}
@@ -292,17 +290,13 @@ void UI_MAIN_TimeSlice500ms(void)
{
if(gScreenToDisplay==DISPLAY_MAIN) {
#ifdef ENABLE_AGC_SHOW_DATA
PrintAGC(true);
UI_MAIN_PrintAGC(true);
return;
#endif
const bool rx = (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING);
if(rx)
if(FUNCTION_IsRx()) {
DisplayRSSIBar(true);
}
}
}
@@ -315,7 +309,7 @@ void UI_DisplayMain(void)
center_line = CENTER_LINE_NONE;
// clear the screen
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
UI_DisplayClear();
if(gLowBattery && !gLowBatteryConfirmed) {
UI_DisplayPopup("LOW BATTERY");
@@ -330,7 +324,7 @@ void UI_DisplayMain(void)
ST7565_BlitFullScreen();
return;
}
unsigned int activeTxVFO = gRxVfoIsActive ? gEeprom.RX_VFO : gEeprom.TX_VFO;
for (unsigned int vfo_num = 0; vfo_num < 2; vfo_num++)
@@ -347,75 +341,71 @@ void UI_DisplayMain(void)
{
#ifdef ENABLE_SCAN_RANGES
if(gScanRangeStart) {
UI_PrintString("ScnRng", 5, 0, line, 8);
sprintf(String, "%3u.%05u", gScanRangeStart / 100000, gScanRangeStart % 100000);
UI_PrintStringSmall(String, 56, 0, line);
uint32_t frq = gEeprom.VfoInfo[vfo_num].pRX->Frequency;
sprintf(String, "%3u.%05u", frq / 100000, frq % 100000);
UI_PrintStringSmall(String, 56, 0, line + 1);
UI_PrintString("ScnRng", 5, 0, line, 8);
sprintf(String, "%3u.%05u", gScanRangeStart / 100000, gScanRangeStart % 100000);
UI_PrintStringSmallNormal(String, 56, 0, line);
sprintf(String, "%3u.%05u", gScanRangeStop / 100000, gScanRangeStop % 100000);
UI_PrintStringSmallNormal(String, 56, 0, line + 1);
continue;
}
#endif
if (
if (gDTMF_InputMode
#ifdef ENABLE_DTMF_CALLING
gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_IsTx ||
#endif
gDTMF_InputMode)
{ // show DTMF stuff
|| gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_IsTx
#endif
) {
char *pPrintStr = "";
// show DTMF stuff
#ifdef ENABLE_DTMF_CALLING
char Contact[16];
if (!gDTMF_InputMode) {
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT) {
pPrintStr = DTMF_FindContact(gDTMF_String, Contact) ? Contact : gDTMF_String;
} else if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED || gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY){
pPrintStr = DTMF_FindContact(gDTMF_Callee, Contact) ? Contact : gDTMF_Callee;
}else if (gDTMF_IsTx) {
pPrintStr = gDTMF_String;
}
}
if (!gDTMF_InputMode)
{
UI_PrintString(pPrintStr, 2, 0, 2 + (vfo_num * 3), 8);
memset(Contact, 0, sizeof(Contact));
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT)
strcpy(String, (gDTMF_State == DTMF_STATE_CALL_OUT_RSP) ? "CALL OUT(RSP)" : "CALL OUT");
else
if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED || gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY)
pPrintStr = "";
if (!gDTMF_InputMode) {
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT) {
pPrintStr = (gDTMF_State == DTMF_STATE_CALL_OUT_RSP) ? "CALL OUT(RSP)" : "CALL OUT";
} else if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED || gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY) {
sprintf(String, "CALL FRM:%s", (DTMF_FindContact(gDTMF_Caller, Contact)) ? Contact : gDTMF_Caller);
else
if (gDTMF_IsTx)
strcpy(String, (gDTMF_State == DTMF_STATE_TX_SUCC) ? "DTMF TX(SUCC)" : "DTMF TX");
pPrintStr = String;
} else if (gDTMF_IsTx) {
pPrintStr = (gDTMF_State == DTMF_STATE_TX_SUCC) ? "DTMF TX(SUCC)" : "DTMF TX";
}
}
else
#endif
#endif
{
sprintf(String, ">%s", gDTMF_InputBox);
}
UI_PrintString(String, 2, 0, 0 + (vfo_num * 3), 8);
#ifdef ENABLE_DTMF_CALLING
memset(String, 0, sizeof(String));
if (!gDTMF_InputMode) {
memset(Contact, 0, sizeof(Contact));
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT)
sprintf(String, ">%s", (DTMF_FindContact(gDTMF_String, Contact)) ? Contact : gDTMF_String);
else
if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED || gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY)
sprintf(String, ">%s", (DTMF_FindContact(gDTMF_Callee, Contact)) ? Contact : gDTMF_Callee);
else
if (gDTMF_IsTx)
sprintf(String, ">%s", gDTMF_String);
pPrintStr = String;
}
UI_PrintString(String, 2, 0, 2 + (vfo_num * 3), 8);
#endif
UI_PrintString(pPrintStr, 2, 0, 0 + (vfo_num * 3), 8);
center_line = CENTER_LINE_IN_USE;
continue;
}
// highlight the selected/used VFO with a marker
if (isMainVFO)
memmove(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default));
memcpy(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default));
}
else // active TX VFO
{ // highlight the selected/used VFO with a marker
if (isMainVFO)
memmove(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default));
memcpy(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default));
else
memmove(p_line0 + 0, BITMAP_VFO_NotDefault, sizeof(BITMAP_VFO_NotDefault));
memcpy(p_line0 + 0, BITMAP_VFO_NotDefault, sizeof(BITMAP_VFO_NotDefault));
}
if (gCurrentFunction == FUNCTION_TRANSMIT)
@@ -430,11 +420,7 @@ void UI_DisplayMain(void)
if (activeTxVFO == vfo_num)
{ // show the TX symbol
mode = VFO_MODE_TX;
#ifdef ENABLE_SMALL_BOLD
UI_PrintStringSmallBold("TX", 14, 0, line);
#else
UI_PrintStringSmall("TX", 14, 0, line);
#endif
}
}
}
@@ -442,23 +428,19 @@ void UI_DisplayMain(void)
{ // receiving .. show the RX symbol
mode = VFO_MODE_RX;
if (FUNCTION_IsRx() && gEeprom.RX_VFO == vfo_num) {
#ifdef ENABLE_SMALL_BOLD
UI_PrintStringSmallBold("RX", 14, 0, line);
#else
UI_PrintStringSmall("RX", 14, 0, line);
#endif
}
}
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num]))
{ // channel mode
const unsigned int x = 2;
const bool inputting = (gInputBoxIndex == 0 || gEeprom.TX_VFO != vfo_num) ? false : true;
const bool inputting = gInputBoxIndex != 0 && gEeprom.TX_VFO == vfo_num;
if (!inputting)
sprintf(String, "M%u", gEeprom.ScreenChannel[vfo_num] + 1);
else
sprintf(String, "M%.3s", INPUTBOX_GetAscii()); // show the input text
UI_PrintStringSmall(String, x, 0, line + 1);
UI_PrintStringSmallNormal(String, x, 0, line + 1);
}
else if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]))
{ // frequency mode
@@ -466,7 +448,7 @@ void UI_DisplayMain(void)
const unsigned int x = 2;
char * buf = gEeprom.VfoInfo[vfo_num].pRX->Frequency < _1GHz_in_KHz ? "" : "+";
sprintf(String, "F%u%s", 1 + gEeprom.ScreenChannel[vfo_num] - FREQ_CHANNEL_FIRST, buf);
UI_PrintStringSmall(String, x, 0, line + 1);
UI_PrintStringSmallNormal(String, x, 0, line + 1);
}
#ifdef ENABLE_NOAA
else
@@ -479,7 +461,7 @@ void UI_DisplayMain(void)
{ // user entering channel number
sprintf(String, "N%u%u", '0' + gInputBox[0], '0' + gInputBox[1]);
}
UI_PrintStringSmall(String, 7, 0, line + 1);
UI_PrintStringSmallNormal(String, 7, 0, line + 1);
}
#endif
@@ -509,7 +491,7 @@ void UI_DisplayMain(void)
#ifdef ENABLE_BIG_FREQ
if(!isGigaF) {
// show the remaining 2 small frequency digits
UI_PrintStringSmall(String + 7, 113, 0, line + 1);
UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1);
String[7] = 0;
// show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false);
@@ -537,14 +519,14 @@ void UI_DisplayMain(void)
// show the scan list assigment symbols
const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
if (att.scanlist1)
memmove(p_line0 + 113, BITMAP_ScanList1, sizeof(BITMAP_ScanList1));
memcpy(p_line0 + 113, BITMAP_ScanList1, sizeof(BITMAP_ScanList1));
if (att.scanlist2)
memmove(p_line0 + 120, BITMAP_ScanList2, sizeof(BITMAP_ScanList2));
memcpy(p_line0 + 120, BITMAP_ScanList2, sizeof(BITMAP_ScanList2));
// compander symbol
#ifndef ENABLE_BIG_FREQ
if (att.compander)
memmove(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
memcpy(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
#else
// TODO: // find somewhere else to put the symbol
#endif
@@ -556,7 +538,7 @@ void UI_DisplayMain(void)
#ifdef ENABLE_BIG_FREQ
if(frequency < _1GHz_in_KHz) {
// show the remaining 2 small frequency digits
UI_PrintStringSmall(String + 7, 113, 0, line + 1);
UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1);
String[7] = 0;
// show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false);
@@ -588,14 +570,10 @@ void UI_DisplayMain(void)
UI_PrintString(String, 32, 0, line, 8);
}
else {
#ifdef ENABLE_SMALL_BOLD
UI_PrintStringSmallBold(String, 32 + 4, 0, line);
#else
UI_PrintStringSmall(String, 32 + 4, 0, line);
#endif
// show the channel frequency below the channel number/name
sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000);
UI_PrintStringSmall(String, 32 + 4, 0, line + 1);
UI_PrintStringSmallNormal(String, 32 + 4, 0, line + 1);
}
break;
@@ -608,7 +586,7 @@ void UI_DisplayMain(void)
#ifdef ENABLE_BIG_FREQ
if(frequency < _1GHz_in_KHz) {
// show the remaining 2 small frequency digits
UI_PrintStringSmall(String + 7, 113, 0, line + 1);
UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1);
String[7] = 0;
// show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false);
@@ -624,9 +602,9 @@ void UI_DisplayMain(void)
const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
if (att.compander)
#ifdef ENABLE_BIG_FREQ
memmove(p_line0 + 120, BITMAP_compand, sizeof(BITMAP_compand));
memcpy(p_line0 + 120, BITMAP_compand, sizeof(BITMAP_compand));
#else
memmove(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
memcpy(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
#endif
}
}
@@ -661,13 +639,14 @@ void UI_DisplayMain(void)
// ************
String[0] = '\0';
const VFO_Info_t *vfoInfo = &gEeprom.VfoInfo[vfo_num];
// show the modulation symbol
const char * s = "";
const ModulationMode_t mod = gEeprom.VfoInfo[vfo_num].Modulation;
const ModulationMode_t mod = vfoInfo->Modulation;
switch (mod){
case MODULATION_FM: {
const FREQ_Config_t *pConfig = (mode == VFO_MODE_TX) ? gEeprom.VfoInfo[vfo_num].pTX : gEeprom.VfoInfo[vfo_num].pRX;
const FREQ_Config_t *pConfig = (mode == VFO_MODE_TX) ? vfoInfo->pTX : vfoInfo->pRX;
const unsigned int code_type = pConfig->CodeType;
const char *code_list[] = {"", "CT", "DCS", "DCR"};
if (code_type < ARRAY_SIZE(code_list))
@@ -677,55 +656,44 @@ void UI_DisplayMain(void)
default:
s = gModulationStr[mod];
break;
}
UI_PrintStringSmall(s, LCD_WIDTH + 24, 0, line + 1);
}
UI_PrintStringSmallNormal(s, LCD_WIDTH + 24, 0, line + 1);
if (state == VFO_STATE_NORMAL || state == VFO_STATE_ALARM)
{ // show the TX power
const char pwr_list[] = "LMH";
const unsigned int i = gEeprom.VfoInfo[vfo_num].OUTPUT_POWER;
String[0] = (i < ARRAY_SIZE(pwr_list)) ? pwr_list[i] : '\0';
String[1] = '\0';
UI_PrintStringSmall(String, LCD_WIDTH + 46, 0, line + 1);
const char pwr_list[][2] = {"L","M","H"};
int i = vfoInfo->OUTPUT_POWER % 3;
UI_PrintStringSmallNormal(pwr_list[i], LCD_WIDTH + 46, 0, line + 1);
}
if (gEeprom.VfoInfo[vfo_num].freq_config_RX.Frequency != gEeprom.VfoInfo[vfo_num].freq_config_TX.Frequency)
if (vfoInfo->freq_config_RX.Frequency != vfoInfo->freq_config_TX.Frequency)
{ // show the TX offset symbol
const char dir_list[] = "\0+-";
const unsigned int i = gEeprom.VfoInfo[vfo_num].TX_OFFSET_FREQUENCY_DIRECTION;
String[0] = (i < sizeof(dir_list)) ? dir_list[i] : '?';
String[1] = '\0';
UI_PrintStringSmall(String, LCD_WIDTH + 54, 0, line + 1);
const char dir_list[][2] = {"", "+", "-"};
int i = vfoInfo->TX_OFFSET_FREQUENCY_DIRECTION % 3;
UI_PrintStringSmallNormal(dir_list[i], LCD_WIDTH + 54, 0, line + 1);
}
// show the TX/RX reverse symbol
if (gEeprom.VfoInfo[vfo_num].FrequencyReverse)
UI_PrintStringSmall("R", LCD_WIDTH + 62, 0, line + 1);
if (vfoInfo->FrequencyReverse)
UI_PrintStringSmallNormal("R", LCD_WIDTH + 62, 0, line + 1);
{ // show the narrow band symbol
String[0] = '\0';
if (gEeprom.VfoInfo[vfo_num].CHANNEL_BANDWIDTH == BANDWIDTH_NARROW)
{
String[0] = 'N';
String[1] = '\0';
}
UI_PrintStringSmall(String, LCD_WIDTH + 70, 0, line + 1);
}
if (vfoInfo->CHANNEL_BANDWIDTH == BANDWIDTH_NARROW)
UI_PrintStringSmallNormal("N", LCD_WIDTH + 70, 0, line + 1);
#ifdef ENABLE_DTMF_CALLING
// show the DTMF decoding symbol
if (gEeprom.VfoInfo[vfo_num].DTMF_DECODING_ENABLE || gSetting_KILLED)
UI_PrintStringSmall("DTMF", LCD_WIDTH + 78, 0, line + 1);
if (vfoInfo->DTMF_DECODING_ENABLE || gSetting_KILLED)
UI_PrintStringSmallNormal("DTMF", LCD_WIDTH + 78, 0, line + 1);
#endif
// show the audio scramble symbol
if (gEeprom.VfoInfo[vfo_num].SCRAMBLING_TYPE > 0 && gSetting_ScrambleEnable)
UI_PrintStringSmall("SCR", LCD_WIDTH + 106, 0, line + 1);
if (vfoInfo->SCRAMBLING_TYPE > 0 && gSetting_ScrambleEnable)
UI_PrintStringSmallNormal("SCR", LCD_WIDTH + 106, 0, line + 1);
}
#ifdef ENABLE_AGC_SHOW_DATA
center_line = CENTER_LINE_IN_USE;
PrintAGC(false);
UI_MAIN_PrintAGC(false);
#endif
if (center_line == CENTER_LINE_NONE)
@@ -744,7 +712,7 @@ void UI_DisplayMain(void)
#if defined(ENABLE_AM_FIX) && defined(ENABLE_AM_FIX_SHOW_DATA)
if (rx && gEeprom.VfoInfo[gEeprom.RX_VFO].Modulation == MODULATION_AM && gSetting_AM_fix)
{
if (gScreenToDisplay != DISPLAY_MAIN
if (gScreenToDisplay != DISPLAY_MAIN
#ifdef ENABLE_DTMF_CALLING
|| gDTMF_CallState != DTMF_CALL_STATE_NONE
#endif
@@ -753,7 +721,7 @@ void UI_DisplayMain(void)
center_line = CENTER_LINE_AM_FIX_DATA;
AM_fix_print_data(gEeprom.RX_VFO, String);
UI_PrintStringSmall(String, 2, 0, 3);
UI_PrintStringSmallNormal(String, 2, 0, 3);
}
else
#endif
@@ -779,12 +747,11 @@ void UI_DisplayMain(void)
#endif
)
return;
center_line = CENTER_LINE_DTMF_DEC;
strcpy(String, "DTMF ");
strcat(String, gDTMF_RX_live + idx);
UI_PrintStringSmall(String, 2, 0, 3);
sprintf(String, "DTMF %s", gDTMF_RX_live + idx);
UI_PrintStringSmallNormal(String, 2, 0, 3);
}
#else
if (gSetting_live_DTMF_decoder && gDTMF_RX_index > 0)
@@ -797,10 +764,9 @@ void UI_DisplayMain(void)
return;
center_line = CENTER_LINE_DTMF_DEC;
strcpy(String, "DTMF ");
strcat(String, gDTMF_RX + idx);
UI_PrintStringSmall(String, 2, 0, 3);
sprintf(String, "DTMF %s", gDTMF_RX_live + idx);
UI_PrintStringSmallNormal(String, 2, 0, 3);
}
#endif
@@ -813,13 +779,13 @@ void UI_DisplayMain(void)
#endif
)
return;
center_line = CENTER_LINE_CHARGE_DATA;
sprintf(String, "Charge %u.%02uV %u%%",
gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100,
BATTERY_VoltsToPercent(gBatteryVoltageAverage));
UI_PrintStringSmall(String, 2, 0, 3);
UI_PrintStringSmallNormal(String, 2, 0, 3);
}
#endif
}

View File

@@ -42,4 +42,8 @@ void UI_DisplayAudioBar(void);
void UI_MAIN_TimeSlice500ms(void);
void UI_DisplayMain(void);
#ifdef ENABLE_AGC_SHOW_DATA
void UI_MAIN_PrintAGC(bool force);
#endif
#endif

255
ui/menu.c
View File

@@ -15,26 +15,27 @@
*/
#include <string.h>
#include <stdlib.h> // abs()
#include <stdlib.h>
#include "../app/dtmf.h"
#include "../app/menu.h"
#include "../bitmaps.h"
#include "../board.h"
#include "../dcs.h"
#include "../driver/backlight.h"
#include "../driver/bk4819.h"
#include "../driver/eeprom.h"
#include "../driver/st7565.h"
#include "../external/printf/printf.h"
#include "../frequencies.h"
#include "../helper/battery.h"
#include "../misc.h"
#include "../settings.h"
#include "helper.h"
#include "inputbox.h"
#include "menu.h"
#include "ui.h"
#include "app/dtmf.h"
#include "app/menu.h"
#include "bitmaps.h"
#include "board.h"
#include "dcs.h"
#include "driver/backlight.h"
#include "driver/bk4819.h"
#include "driver/eeprom.h" // EEPROM_ReadBuffer()
#include "driver/st7565.h"
#include "external/printf/printf.h"
#include "frequencies.h"
#include "helper/battery.h"
#include "misc.h"
#include "settings.h"
#include "ui/helper.h"
#include "ui/inputbox.h"
#include "ui/menu.h"
#include "ui/ui.h"
const t_menu_item MenuList[] =
{
@@ -56,7 +57,7 @@ const t_menu_item MenuList[] =
{"ScAdd2", VOICE_ID_INVALID, MENU_S_ADD2 },
{"ChSave", VOICE_ID_MEMORY_CHANNEL, MENU_MEM_CH }, // was "MEM-CH"
{"ChDele", VOICE_ID_DELETE_CHANNEL, MENU_DEL_CH }, // was "DEL-CH"
{"ChName", VOICE_ID_INVALID, MENU_MEM_NAME },
{"ChName", VOICE_ID_INVALID, MENU_MEM_NAME },
{"SList", VOICE_ID_INVALID, MENU_S_LIST },
{"SList1", VOICE_ID_INVALID, MENU_SLIST1 },
@@ -65,7 +66,6 @@ const t_menu_item MenuList[] =
#ifdef ENABLE_NOAA
{"NOAA-S", VOICE_ID_INVALID, MENU_NOAA_S },
#endif
{"F1Shrt", VOICE_ID_INVALID, MENU_F1SHRT },
{"F1Long", VOICE_ID_INVALID, MENU_F1LONG },
{"F2Shrt", VOICE_ID_INVALID, MENU_F2SHRT },
@@ -78,10 +78,10 @@ const t_menu_item MenuList[] =
{"Mic", VOICE_ID_INVALID, MENU_MIC },
#ifdef ENABLE_AUDIO_BAR
{"MicBar", VOICE_ID_INVALID, MENU_MIC_BAR },
#endif
#endif
{"ChDisp", VOICE_ID_INVALID, MENU_MDF }, // was "MDF"
{"POnMsg", VOICE_ID_INVALID, MENU_PONMSG },
{"BatTxt", VOICE_ID_INVALID, MENU_BAT_TXT },
{"BatTxt", VOICE_ID_INVALID, MENU_BAT_TXT },
{"BackLt", VOICE_ID_INVALID, MENU_ABR }, // was "ABR"
{"BLMin", VOICE_ID_INVALID, MENU_ABR_MIN },
{"BLMax", VOICE_ID_INVALID, MENU_ABR_MAX },
@@ -194,7 +194,7 @@ const char gSubMenu_TOT[][7] =
"15 min"
};
const char* gSubMenu_RXMode[] =
const char* const gSubMenu_RXMode[] =
{
"MAIN\nONLY", // TX and RX on main only
"DUAL RX\nRESPOND", // Watch both and respond
@@ -218,7 +218,7 @@ const char gSubMenu_SC_REV[][8] =
"STOP"
};
const char* gSubMenu_MDF[] =
const char* const gSubMenu_MDF[] =
{
"FREQ",
"CHANNEL\nNUMBER",
@@ -244,7 +244,7 @@ const char gSubMenu_D_RSP[][11] =
};
#endif
const char* gSubMenu_PTT_ID[] =
const char* const gSubMenu_PTT_ID[] =
{
"OFF",
"UP CODE",
@@ -274,7 +274,7 @@ const char gSubMenu_RESET[][4] =
"ALL"
};
const char * gSubMenu_F_LOCK[] =
const char * const gSubMenu_F_LOCK[] =
{
"DEFAULT+\n137-174\n400-470",
"FCC HAM\n144-148\n420-450",
@@ -346,13 +346,13 @@ const t_sidefunction gSubMenu_SIDEFUNCTIONS[] =
#ifdef ENABLE_VOX
{"VOX", ACTION_OPT_VOX},
#endif
#ifdef ENABLE_ALARM
#ifdef ENABLE_ALARM
{"ALARM", ACTION_OPT_ALARM},
#endif
#ifdef ENABLE_FMRADIO
{"FM RADIO", ACTION_OPT_FM},
#endif
#ifdef ENABLE_TX1750
#endif
#ifdef ENABLE_TX1750
{"1750HZ", ACTION_OPT_1750},
#endif
{"LOCK\nKEYPAD", ACTION_OPT_KEYLOCK},
@@ -371,8 +371,8 @@ uint8_t gMenuCursor;
int UI_MENU_GetCurrentMenuId() {
if(gMenuCursor < ARRAY_SIZE(MenuList))
return MenuList[gMenuCursor].menu_id;
else
return MenuList[ARRAY_SIZE(MenuList)-1].menu_id;
return MenuList[ARRAY_SIZE(MenuList)-1].menu_id;
}
uint8_t UI_MENU_GetMenuIdx(uint8_t id)
@@ -402,52 +402,48 @@ void UI_DisplayMenu(void)
char Contact[16];
#endif
// clear the screen buffer
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
UI_DisplayClear();
#if 0
#ifndef ENABLE_CUSTOM_MENU_LAYOUT
// original menu layout
for (i = 0; i < 3; i++)
if (gMenuCursor > 0 || i > 0)
if ((gMenuListCount - 1) != gMenuCursor || i != 2)
UI_PrintString(MenuList[gMenuCursor + i - 1].name, 0, 0, i * 2, 8);
for (i = 0; i < 3; i++)
if (gMenuCursor > 0 || i > 0)
if ((gMenuListCount - 1) != gMenuCursor || i != 2)
UI_PrintString(MenuList[gMenuCursor + i - 1].name, 0, 0, i * 2, 8);
// invert the current menu list item pixels
for (i = 0; i < (8 * menu_list_width); i++)
{
gFrameBuffer[2][i] ^= 0xFF;
gFrameBuffer[3][i] ^= 0xFF;
}
// invert the current menu list item pixels
for (i = 0; i < (8 * menu_list_width); i++)
{
gFrameBuffer[2][i] ^= 0xFF;
gFrameBuffer[3][i] ^= 0xFF;
}
// draw vertical separating dotted line
for (i = 0; i < 7; i++)
gFrameBuffer[i][(8 * menu_list_width) + 1] = 0xAA;
// draw vertical separating dotted line
for (i = 0; i < 7; i++)
gFrameBuffer[i][(8 * menu_list_width) + 1] = 0xAA;
// draw the little sub-menu triangle marker
if (gIsInSubMenu)
memcpy(gFrameBuffer[0] + (8 * menu_list_width) + 1, BITMAP_CurrentIndicator, sizeof(BITMAP_CurrentIndicator));
// draw the little sub-menu triangle marker
if (gIsInSubMenu)
memmove(gFrameBuffer[0] + (8 * menu_list_width) + 1, BITMAP_CurrentIndicator, sizeof(BITMAP_CurrentIndicator));
// draw the menu index number/count
sprintf(String, "%2u.%u", 1 + gMenuCursor, gMenuListCount);
// draw the menu index number/count
sprintf(String, "%2u.%u", 1 + gMenuCursor, gMenuListCount);
UI_PrintStringSmall(String, 2, 0, 6);
UI_PrintStringSmallNormal(String, 2, 0, 6);
#else
#else
{ // new menu layout .. experimental & unfinished
const int menu_index = gMenuCursor; // current selected menu item
i = 1;
if (!gIsInSubMenu)
{
if (!gIsInSubMenu) {
while (i < 2)
{ // leading menu items - small text
const int k = menu_index + i - 2;
if (k < 0)
UI_PrintStringSmall(MenuList[gMenuListCount + k].name, 0, 0, i); // wrap-a-round
else
if (k >= 0 && k < (int)gMenuListCount)
UI_PrintStringSmall(MenuList[k].name, 0, 0, i);
UI_PrintStringSmallNormal(MenuList[gMenuListCount + k].name, 0, 0, i); // wrap-a-round
else if (k >= 0 && k < (int)gMenuListCount)
UI_PrintStringSmallNormal(MenuList[k].name, 0, 0, i);
i++;
}
@@ -460,27 +456,24 @@ void UI_DisplayMenu(void)
{ // trailing menu item - small text
const int k = menu_index + i - 2;
if (k >= 0 && k < (int)gMenuListCount)
UI_PrintStringSmall(MenuList[k].name, 0, 0, 1 + i);
else
if (k >= (int)gMenuListCount)
UI_PrintStringSmall(MenuList[gMenuListCount - k].name, 0, 0, 1 + i); // wrap-a-round
UI_PrintStringSmallNormal(MenuList[k].name, 0, 0, 1 + i);
else if (k >= (int)gMenuListCount)
UI_PrintStringSmallNormal(MenuList[gMenuListCount - k].name, 0, 0, 1 + i); // wrap-a-round
i++;
}
// draw the menu index number/count
sprintf(String, "%2u.%u", 1 + gMenuCursor, gMenuListCount);
UI_PrintStringSmall(String, 2, 0, 6);
UI_PrintStringSmallNormal(String, 2, 0, 6);
}
else
if (menu_index >= 0 && menu_index < (int)gMenuListCount)
else if (menu_index >= 0 && menu_index < (int)gMenuListCount)
{ // current menu item
strcpy(String, MenuList[menu_index].name);
// strcat(String, ":");
UI_PrintString(String, 0, 0, 0, 8);
// UI_PrintStringSmall(String, 0, 0, 0);
UI_PrintString(MenuList[menu_index].name, 0, 0, 0, 8);
// UI_PrintStringSmallNormal(String, 0, 0, 0);
}
}
#endif
#endif
// **************
@@ -488,6 +481,12 @@ void UI_DisplayMenu(void)
bool already_printed = false;
/* Brightness is set to max in some entries of this menu. Return it to the configured brightness
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. */
BACKLIGHT_TurnOn();
switch (UI_MENU_GetCurrentMenuId())
{
case MENU_SQL:
@@ -584,7 +583,8 @@ void UI_DisplayMenu(void)
case MENU_ABR:
strcpy(String, gSubMenu_BACKLIGHT[gSubMenuSelection]);
BACKLIGHT_SetBrightness(-1);
if(BACKLIGHT_GetBrightness() < 4)
BACKLIGHT_SetBrightness(4);
break;
case MENU_ABR_MIN:
@@ -592,9 +592,9 @@ void UI_DisplayMenu(void)
sprintf(String, "%d", gSubMenuSelection);
if(gIsInSubMenu)
BACKLIGHT_SetBrightness(gSubMenuSelection);
else
BACKLIGHT_SetBrightness(-1);
break;
else if(BACKLIGHT_GetBrightness() < 4)
BACKLIGHT_SetBrightness(4);
break;
case MENU_AM:
strcpy(String, gModulationStr[gSubMenuSelection]);
@@ -649,6 +649,8 @@ void UI_DisplayMenu(void)
UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8);
}
SETTINGS_FetchChannelName(String, gSubMenuSelection);
UI_PrintString(String[0] ? String : "--", menu_item_x1, menu_item_x2, 2, 8);
already_printed = true;
break;
}
@@ -667,24 +669,20 @@ void UI_DisplayMenu(void)
if (!gIsInSubMenu || edit_index < 0)
{ // show the channel name
SETTINGS_FetchChannelName(String, gSubMenuSelection);
if (String[0] == 0)
strcpy(String, "--");
UI_PrintString(String, menu_item_x1, menu_item_x2, 2, 8);
char *pPrintStr = String[0] ? String : "--";
UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 2, 8);
}
else
{ // show the channel name being edited
UI_PrintString(edit, menu_item_x1, 0, 2, 8);
if (edit_index < 10)
UI_PrintString( "^", menu_item_x1 + (8 * edit_index), 0, 4, 8); // show the cursor
UI_PrintString("^", menu_item_x1 + (8 * edit_index), 0, 4, 8); // show the cursor
}
if (!gAskForConfirmation)
{ // show the frequency so that the user knows the channels frequency
sprintf(String, "%u.%05u", frequency / 100000, frequency % 100000);
if (!gIsInSubMenu || edit_index < 0)
UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8);
else
UI_PrintString(String, menu_item_x1, menu_item_x2, 5, 8);
UI_PrintString(String, menu_item_x1, menu_item_x2, 4 + (gIsInSubMenu && edit_index >= 0), 8);
}
}
@@ -778,7 +776,7 @@ void UI_DisplayMenu(void)
if (!gIsDtmfContactValid)
strcpy(String, "NULL");
else
memmove(String, Contact, 8);
memcpy(String, Contact, 8);
break;
#endif
@@ -831,7 +829,7 @@ void UI_DisplayMenu(void)
case MENU_BATTYP:
strcpy(String, gSubMenu_BATTYP[gSubMenuSelection]);
break;
break;
case MENU_F1SHRT:
case MENU_F1LONG:
@@ -880,7 +878,7 @@ void UI_DisplayMenu(void)
for (i = 0; i < len && lines > 0; lines--)
{
if (small)
UI_PrintStringSmall(String + i, menu_item_x1, menu_item_x2, y);
UI_PrintStringSmallNormal(String + i, menu_item_x1, menu_item_x2, y);
else
UI_PrintString(String + i, menu_item_x1, menu_item_x2, y, 8);
@@ -900,70 +898,47 @@ void UI_DisplayMenu(void)
if (UI_MENU_GetCurrentMenuId() == MENU_SLIST1 || UI_MENU_GetCurrentMenuId() == MENU_SLIST2)
{
i = (UI_MENU_GetCurrentMenuId() == MENU_SLIST1) ? 0 : 1;
char *pPrintStr = String;
// if (gSubMenuSelection == 0xFF)
if (gSubMenuSelection < 0)
strcpy(String, "NULL");
else
if (gSubMenuSelection < 0) {
pPrintStr = "NULL";
} else {
UI_GenerateChannelStringEx(String, true, gSubMenuSelection);
// if (gSubMenuSelection == 0xFF || !gEeprom.SCAN_LIST_ENABLED[i])
if (gSubMenuSelection < 0 || !gEeprom.SCAN_LIST_ENABLED[i])
{
// channel number
UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8);
// channel name
SETTINGS_FetchChannelName(String, gSubMenuSelection);
if (String[0] == 0)
strcpy(String, "--");
UI_PrintString(String, menu_item_x1, menu_item_x2, 2, 8);
pPrintStr = String;
}
else
{
// channel number
UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8);
// channel name
SETTINGS_FetchChannelName(String, gSubMenuSelection);
if (String[0] == 0)
strcpy(String, "--");
UI_PrintStringSmall(String, menu_item_x1, menu_item_x2, 2);
// channel number
UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 0, 8);
if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH1[i]))
{
sprintf(String, "PRI1:%u", gEeprom.SCANLIST_PRIORITY_CH1[i] + 1);
SETTINGS_FetchChannelName(String, gSubMenuSelection);
pPrintStr = String[0] ? String : "--";
// channel name and scan-list
if (gSubMenuSelection < 0 || !gEeprom.SCAN_LIST_ENABLED[i]) {
UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 2, 8);
} else {
UI_PrintStringSmallNormal(pPrintStr, menu_item_x1, menu_item_x2, 2);
if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH1[i])) {
sprintf(String, "PRI%d:%u", 1, gEeprom.SCANLIST_PRIORITY_CH1[i] + 1);
UI_PrintString(String, menu_item_x1, menu_item_x2, 3, 8);
}
if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH2[i]))
{
sprintf(String, "PRI2:%u", gEeprom.SCANLIST_PRIORITY_CH2[i] + 1);
if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH2[i])) {
sprintf(String, "PRI%d:%u", 2, gEeprom.SCANLIST_PRIORITY_CH2[i] + 1);
UI_PrintString(String, menu_item_x1, menu_item_x2, 5, 8);
}
}
}
if (UI_MENU_GetCurrentMenuId() == MENU_MEM_CH ||
UI_MENU_GetCurrentMenuId() == MENU_DEL_CH ||
UI_MENU_GetCurrentMenuId() == MENU_1_CALL)
{ // display the channel name
char s[11];
SETTINGS_FetchChannelName(s, gSubMenuSelection);
if (s[0] == 0)
strcpy(s, "--");
UI_PrintString(s, menu_item_x1, menu_item_x2, 2, 8);
}
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);
#ifdef ENABLE_DTMF_CALLING
if (UI_MENU_GetCurrentMenuId() == MENU_D_LIST && gIsDtmfContactValid)
{
if (UI_MENU_GetCurrentMenuId() == MENU_D_LIST && gIsDtmfContactValid) {
Contact[11] = 0;
memmove(&gDTMF_ID, Contact + 8, 4);
sprintf(String, "ID:%s", Contact + 8);
memcpy(&gDTMF_ID, Contact + 8, 4);
sprintf(String, "ID:%4s", gDTMF_ID);
UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8);
}
#endif
@@ -974,12 +949,10 @@ void UI_DisplayMenu(void)
UI_MENU_GetCurrentMenuId() == MENU_T_DCS
#ifdef ENABLE_DTMF_CALLING
|| UI_MENU_GetCurrentMenuId() == MENU_D_LIST
#endif
)
{
#endif
) {
sprintf(String, "%2d", gSubMenuSelection);
UI_PrintStringSmall(String, 105, 0, 0);
UI_PrintStringSmallNormal(String, 105, 0, 0);
}
if ((UI_MENU_GetCurrentMenuId() == MENU_RESET ||
@@ -987,8 +960,8 @@ void UI_DisplayMenu(void)
UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME ||
UI_MENU_GetCurrentMenuId() == MENU_DEL_CH) && gAskForConfirmation)
{ // display confirmation
strcpy(String, (gAskForConfirmation == 1) ? "SURE?" : "WAIT!");
UI_PrintString(String, menu_item_x1, menu_item_x2, 5, 8);
char *pPrintStr = (gAskForConfirmation == 1) ? "SURE?" : "WAIT!";
UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 5, 8);
}
ST7565_BlitFullScreen();

View File

@@ -135,24 +135,24 @@ extern const char gSubMenu_W_N[2][7];
extern const char gSubMenu_OFF_ON[2][4];
extern const char gSubMenu_SAVE[5][4];
extern const char gSubMenu_TOT[11][7];
extern const char* gSubMenu_RXMode[4];
extern const char* const gSubMenu_RXMode[4];
#ifdef ENABLE_VOICE
extern const char gSubMenu_VOICE[3][4];
#endif
extern const char gSubMenu_SC_REV[3][8];
extern const char* gSubMenu_MDF[4];
extern const char* const gSubMenu_MDF[4];
#ifdef ENABLE_ALARM
extern const char gSubMenu_AL_MOD[2][5];
#endif
#ifdef ENABLE_DTMF_CALLING
extern const char gSubMenu_D_RSP[4][11];
#endif
extern const char* gSubMenu_PTT_ID[5];
extern const char* const gSubMenu_PTT_ID[5];
extern const char gSubMenu_PONMSG[4][8];
extern const char gSubMenu_ROGER[3][6];
extern const char gSubMenu_RESET[2][4];
extern const char* gSubMenu_F_LOCK[F_LOCK_LEN];
extern const char* const gSubMenu_F_LOCK[F_LOCK_LEN];
extern const char gSubMenu_BACKLIGHT[8][7];
extern const char gSubMenu_RX_TX[4][6];
extern const char gSubMenu_BAT_TXT[3][8];

View File

@@ -26,56 +26,58 @@
void UI_DisplayScanner(void)
{
char String[16];
bool bCentered;
char String[16] = {0};
char *pPrintStr = String;
bool bCentered;
uint8_t Start;
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
UI_DisplayClear();
memset(String, 0, sizeof(String));
if (gScanSingleFrequency || (gScanCssState != SCAN_CSS_STATE_OFF && gScanCssState != SCAN_CSS_STATE_FAILED))
if (gScanSingleFrequency || (gScanCssState != SCAN_CSS_STATE_OFF && gScanCssState != SCAN_CSS_STATE_FAILED)) {
sprintf(String, "FREQ:%u.%05u", gScanFrequency / 100000, gScanFrequency % 100000);
else
strcpy(String, "FREQ:**.*****");
UI_PrintString(String, 2, 0, 1, 8);
pPrintStr = String;
} else {
pPrintStr = "FREQ:**.*****";
}
memset(String, 0, sizeof(String));
if (gScanCssState < SCAN_CSS_STATE_FOUND || !gScanUseCssResult)
strcpy(String, "CTC:******");
else
if (gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE)
UI_PrintString(pPrintStr, 2, 0, 1, 8);
if (gScanCssState < SCAN_CSS_STATE_FOUND || !gScanUseCssResult) {
pPrintStr = "CTC:******";
} else if (gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) {
sprintf(String, "CTC:%u.%uHz", CTCSS_Options[gScanCssResultCode] / 10, CTCSS_Options[gScanCssResultCode] % 10);
else
pPrintStr = String;
} else {
sprintf(String, "DCS:D%03oN", DCS_Options[gScanCssResultCode]);
UI_PrintString(String, 2, 0, 3, 8);
pPrintStr = String;
}
UI_PrintString(pPrintStr, 2, 0, 3, 8);
memset(String, 0, sizeof(String));
if (gScannerSaveState == SCAN_SAVE_CHANNEL)
{
strcpy(String, "SAVE?");
if (gScannerSaveState == SCAN_SAVE_CHANNEL) {
pPrintStr = "SAVE?";
Start = 0;
bCentered = 1;
}
else
{
} else {
Start = 2;
bCentered = 0;
if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
strcpy(String, "SAVE:");
UI_GenerateChannelStringEx(String + 5, gShowChPrefix, gScanChannel);
}
else if (gScanCssState < SCAN_CSS_STATE_FOUND) {
pPrintStr = String;
} else if (gScanCssState < SCAN_CSS_STATE_FOUND) {
strcpy(String, "SCAN");
memset(String + 4, '.', (gScanProgressIndicator & 7) + 1);
pPrintStr = String;
} else if (gScanCssState == SCAN_CSS_STATE_FOUND) {
pPrintStr = "SCAN CMP.";
} else {
pPrintStr = "SCAN FAIL.";
}
else if (gScanCssState == SCAN_CSS_STATE_FOUND)
strcpy(String, "SCAN CMP.");
else
strcpy(String, "SCAN FAIL.");
Start = 2;
bCentered = 0;
}
UI_PrintString(String, Start, bCentered ? 127 : 0, 5, 8);
UI_PrintString(pPrintStr, Start, bCentered ? 127 : 0, 5, 8);
ST7565_BlitFullScreen();
}

View File

@@ -36,7 +36,7 @@
void UI_DisplayStatus()
{
gUpdateStatus = false;
gUpdateStatus = false;
memset(gStatusLine, 0, sizeof(gStatusLine));
uint8_t *line = gStatusLine;
@@ -69,7 +69,7 @@ void UI_DisplayStatus()
memset(line + x, 0xFF, 10);
x1 = x + 10;
}
else
else
#endif
#ifdef ENABLE_FMRADIO
if (gFmRadioMode) { // FM indicator
@@ -91,7 +91,7 @@ void UI_DisplayStatus()
else { // frequency mode
s = "S";
}
UI_PrintStringSmallBuffer(s, line + x + 1);
UI_PrintStringSmallBufferNormal(s, line + x + 1);
x1 = x + 10;
}
}
@@ -109,9 +109,9 @@ void UI_DisplayStatus()
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)
if(gDualWatchActive)
memcpy(line + x + (dw==1?0:2), BITMAP_TDR1, sizeof(BITMAP_TDR1) - (dw==1?0:5));
else
else
memcpy(line + x + 3, BITMAP_TDR2, sizeof(BITMAP_TDR2));
}
else if(dw == 2) { // XB - crossband
@@ -119,7 +119,7 @@ void UI_DisplayStatus()
}
}
x += sizeof(BITMAP_TDR1) + 1;
#ifdef ENABLE_VOX
// VOX indicator
if (gEeprom.VOX_SWITCH) {
@@ -144,7 +144,7 @@ void UI_DisplayStatus()
}
{ // battery voltage or percentage
char s[8] = "";
char s[8] = "";
unsigned int x2 = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - 0;
if (gChargingWithTypeC)
@@ -154,13 +154,13 @@ void UI_DisplayStatus()
default:
case 0:
break;
case 1: { // voltage
const uint16_t voltage = (gBatteryVoltageAverage <= 999) ? gBatteryVoltageAverage : 999; // limit to 9.99V
sprintf(s, "%u.%02uV", voltage / 100, voltage % 100);
break;
}
case 2: // percentage
sprintf(s, "%u%%", BATTERY_VoltsToPercent(gBatteryVoltageAverage));
break;
@@ -168,12 +168,12 @@ void UI_DisplayStatus()
unsigned int space_needed = (7 * strlen(s));
if (x2 >= (x1 + space_needed))
UI_PrintStringSmallBuffer(s, line + x2 - space_needed);
UI_PrintStringSmallBufferNormal(s, line + x2 - space_needed);
}
// move to right side of the screen
x = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - sizeof(BITMAP_USB_C);
// USB-C charge indicator
if (gChargingWithTypeC)
memcpy(line + x, BITMAP_USB_C, sizeof(BITMAP_USB_C));
@@ -181,7 +181,7 @@ void UI_DisplayStatus()
// BATTERY LEVEL indicator
UI_DrawBattery(line + x, gBatteryDisplayLevel, gLowBatteryBlink);
// **************
ST7565_BlitStatusLine();

View File

@@ -30,7 +30,7 @@
void UI_DisplayReleaseKeys(void)
{
memset(gStatusLine, 0, sizeof(gStatusLine));
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
UI_DisplayClear();
UI_PrintString("RELEASE", 0, 127, 1, 10);
UI_PrintString("ALL KEYS", 0, 127, 3, 10);
@@ -43,21 +43,13 @@ void UI_DisplayWelcome(void)
{
char WelcomeString0[16];
char WelcomeString1[16];
memset(gStatusLine, 0, sizeof(gStatusLine));
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_NONE)
{
memset(gStatusLine, 0, sizeof(gStatusLine));
UI_DisplayClear();
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_NONE || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_FULL_SCREEN) {
ST7565_FillScreen(0xFF);
}
else
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_FULL_SCREEN)
{
ST7565_FillScreen(0xFF);
}
else
{
} else {
memset(WelcomeString0, 0, sizeof(WelcomeString0));
memset(WelcomeString1, 0, sizeof(WelcomeString1));
@@ -77,10 +69,9 @@ void UI_DisplayWelcome(void)
UI_PrintString(WelcomeString0, 0, 127, 0, 10);
UI_PrintString(WelcomeString1, 0, 127, 2, 10);
UI_PrintStringSmall(Version, 0, 128, 6);
UI_PrintStringSmallNormal(Version, 0, 128, 6);
ST7565_BlitStatusLine(); // blank status line
ST7565_BlitFullScreen();
}
}