Compare commits

...

33 Commits

Author SHA1 Message Date
1ec2e15de8 Free up space
All checks were successful
Build Firmware / build (push) Successful in 2m20s
2025-07-04 22:24:10 +02:00
23dbad1a53 Support older standard
All checks were successful
Build Firmware / build (push) Successful in 21s
2025-06-03 23:56:25 +02:00
6d98e23202 Variable entry
All checks were successful
Build Firmware / build (push) Successful in 19s
2025-06-03 22:43:14 +02:00
8e48a5f4c5 Testing
All checks were successful
Build Firmware / build (push) Successful in 2m2s
2025-06-03 22:17:31 +02:00
bbeb1d8fab Remove redundant 1750(rely on button when TX)
All checks were successful
Build Firmware / build (push) Successful in 20s
2025-04-01 17:48:00 +02:00
c0d3ba51a2 Fix up FSK
All checks were successful
Build Firmware / build (push) Successful in 25s
2025-04-01 17:40:08 +02:00
7b1d31fdef Start implementing ack
All checks were successful
Build Firmware / build (push) Successful in 1m1s
2025-04-01 14:47:18 +02:00
0ea8767a8b Remove some stuff to make space
All checks were successful
Build Firmware / build (push) Successful in 32s
2025-03-31 22:00:54 +02:00
f1904e03fe Try out the fsk
All checks were successful
Build Firmware / build (push) Successful in 2m30s
2025-03-31 21:53:23 +02:00
101bde7463 fix power bug
All checks were successful
Build Firmware / build (push) Successful in 37s
2025-03-31 11:51:11 +02:00
85fb527020 Do some stuff
All checks were successful
Build Firmware / build (push) Successful in 2m19s
2025-03-28 22:07:50 +01:00
4fe99744e1 Do some stuff
All checks were successful
Build Firmware / build (push) Successful in 27s
2025-03-10 21:48:58 +01:00
8dd68d74a6 Test out some things
All checks were successful
Build Firmware / build (push) Successful in 22s
2025-03-05 22:35:45 +01:00
72558f93f3 Do some stuff
All checks were successful
Build Firmware / build (push) Successful in 3m32s
2025-03-04 16:46:02 +01:00
fabf38f1bc Upload entire dir
All checks were successful
Build Firmware / build (push) Successful in 20s
2025-02-27 17:54:15 +01:00
00786c683d Upload entire dir
All checks were successful
Build Firmware / build (push) Successful in 19s
2025-02-27 17:52:12 +01:00
c5464994ed Upload entire dir
All checks were successful
Build Firmware / build (push) Successful in 24s
2025-02-27 17:47:48 +01:00
f1b2d085d5 Add ls
All checks were successful
Build Firmware / build (push) Successful in 19s
2025-02-27 17:43:30 +01:00
ac6e59044d Yet another test
All checks were successful
Build Firmware / build (push) Successful in 22s
2025-02-27 17:40:40 +01:00
3850025e63 Yet another test
All checks were successful
Build Firmware / build (push) Successful in 20s
2025-02-27 17:36:40 +01:00
dc5919ac6f Another test
All checks were successful
Build Firmware / build (push) Successful in 22s
2025-02-27 17:35:25 +01:00
3e1756697f Forgot important files
All checks were successful
Build Firmware / build (push) Successful in 21s
2025-02-27 17:24:49 +01:00
62f73f8c6c Try to fix the CI
Some checks failed
Build Firmware / build (push) Failing after 18s
2025-02-27 17:23:44 +01:00
f4ff2e6048 Apply my changes v1
Some checks failed
Build Firmware / build (push) Failing after 3m21s
2025-02-27 16:49:04 +01:00
Armel FAUVEAU
ba5257f2f6 Merge pull request #367 from armel/feature_update_v4
Feature update v4
2025-02-22 02:48:10 +01:00
Armel FAUVEAU
aee4406cff Prepare new v4.0 2025-02-22 02:46:47 +01:00
Armel FAUVEAU
448a201308 Update README 2025-02-20 03:59:31 +01:00
Armel FAUVEAU
9a312c3526 Rename Voxless to Basic 2025-02-20 03:56:05 +01:00
Armel FAUVEAU
7f146a5857 Fix bug if BOOT_MODE_F_LOCK 2025-02-19 02:11:39 +01:00
Armel FAUVEAU
710ff8fac1 Fix directive 2025-02-19 01:44:30 +01:00
Armel FAUVEAU
08af06564c Refactoring 2025-02-19 00:43:00 +01:00
Armel FAUVEAU
03f761348b Fix condition 2025-02-18 23:26:58 +01:00
Armel FAUVEAU
96acae8014 Remove comment 2025-02-18 22:14:51 +01:00
85 changed files with 6107 additions and 6851 deletions

View File

@@ -15,10 +15,16 @@ jobs:
- name: Compile firmware - name: Compile firmware
run: | run: |
chmod +x compile-with-docker.sh chmod +x compile-with-docker.sh
./compile-with-docker.sh ./compile-with-docker.sh custom
- name: Debug files
run: ls -lah
- name: Debug compiled firmware
run: ls -lah compiled-firmware
- name: Upload firmware artifact - name: Upload firmware artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: firmware-artifact name: firmware-artifact
path: compiled-firmware/f4hwn.packed.bin path: compiled-firmware/*

8
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

7
.idea/discord.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="ASK" />
<option name="description" value="" />
</component>
</project>

18
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MakefileSettings">
<option name="linkedExternalProjectsSettings">
<MakefileProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
<option name="version" value="2" />
</MakefileProjectSettings>
</option>
</component>
<component name="MakefileWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@@ -4,28 +4,28 @@
# 1 = enable # 1 = enable
# ---- STOCK QUANSHENG FEATURES ---- # ---- STOCK QUANSHENG FEATURES ----
ENABLE_FMRADIO ?= 0 ENABLE_FMRADIO ?= 1
ENABLE_UART ?= 1 ENABLE_UART ?= 1
ENABLE_AIRCOPY ?= 0 ENABLE_AIRCOPY ?= 0
ENABLE_NOAA ?= 0 ENABLE_NOAA ?= 0
ENABLE_VOICE ?= 0 ENABLE_VOICE ?= 0
ENABLE_VOX ?= 1 ENABLE_VOX ?= 0
ENABLE_ALARM ?= 0 ENABLE_ALARM ?= 0
ENABLE_TX1750 ?= 1 ENABLE_TX1750 ?= 0
ENABLE_PWRON_PASSWORD ?= 0 ENABLE_PWRON_PASSWORD ?= 0
ENABLE_DTMF_CALLING ?= 0 ENABLE_DTMF_CALLING ?= 0
ENABLE_FLASHLIGHT ?= 1 ENABLE_FLASHLIGHT ?= 1
# ---- CUSTOM MODS ---- # ---- CUSTOM MODS ----
ENABLE_SPECTRUM ?= 0 ENABLE_SPECTRUM ?= 1
ENABLE_BIG_FREQ ?= 1 ENABLE_BIG_FREQ ?= 0
ENABLE_SMALL_BOLD ?= 1 ENABLE_SMALL_BOLD ?= 0
ENABLE_CUSTOM_MENU_LAYOUT ?= 1 ENABLE_CUSTOM_MENU_LAYOUT ?= 1
ENABLE_KEEP_MEM_NAME ?= 1 ENABLE_KEEP_MEM_NAME ?= 1
ENABLE_WIDE_RX ?= 1 ENABLE_WIDE_RX ?= 1
ENABLE_TX_WHEN_AM ?= 0 ENABLE_TX_WHEN_AM ?= 0
ENABLE_F_CAL_MENU ?= 0 ENABLE_F_CAL_MENU ?= 1
ENABLE_CTCSS_TAIL_PHASE_SHIFT ?= 0 ENABLE_CTCSS_TAIL_PHASE_SHIFT ?= 1
ENABLE_BOOT_BEEPS ?= 0 ENABLE_BOOT_BEEPS ?= 0
ENABLE_SHOW_CHARGE_LEVEL ?= 0 ENABLE_SHOW_CHARGE_LEVEL ?= 0
ENABLE_REVERSE_BAT_SYMBOL ?= 0 ENABLE_REVERSE_BAT_SYMBOL ?= 0
@@ -36,26 +36,25 @@ ENABLE_FASTER_CHANNEL_SCAN ?= 1
ENABLE_RSSI_BAR ?= 1 ENABLE_RSSI_BAR ?= 1
ENABLE_AUDIO_BAR ?= 1 ENABLE_AUDIO_BAR ?= 1
ENABLE_COPY_CHAN_TO_VFO ?= 1 ENABLE_COPY_CHAN_TO_VFO ?= 1
ENABLE_REDUCE_LOW_MID_TX_POWER ?= 0 ENABLE_REDUCE_LOW_MID_TX_POWER ?= 1
ENABLE_BYP_RAW_DEMODULATORS ?= 0 ENABLE_BYP_RAW_DEMODULATORS ?= 1
ENABLE_BLMIN_TMP_OFF ?= 0 ENABLE_BLMIN_TMP_OFF ?= 0
ENABLE_SCAN_RANGES ?= 1 ENABLE_SCAN_RANGES ?= 1
ENABLE_FEAT_F4HWN ?= 1 ENABLE_FEAT_F4HWN ?= 1
ENABLE_FEAT_F4HWN_SCREENSHOT ?= 0 ENABLE_FEAT_F4HWN_SCREENSHOT ?= 0
ENABLE_FEAT_F4HWN_SPECTRUM ?= 1 ENABLE_FEAT_F4HWN_SPECTRUM ?= 1
ENABLE_FEAT_F4HWN_RX_TX_TIMER ?= 1 ENABLE_FEAT_F4HWN_RX_TX_TIMER ?= 0
ENABLE_FEAT_F4HWN_CHARGING_C ?= 0 ENABLE_FEAT_F4HWN_CHARGING_C ?= 0
ENABLE_FEAT_F4HWN_SLEEP ?= 1 ENABLE_FEAT_F4HWN_SLEEP ?= 1
ENABLE_FEAT_F4HWN_RESUME_STATE ?= 1 ENABLE_FEAT_F4HWN_RESUME_STATE ?= 1
ENABLE_FEAT_F4HWN_NARROWER ?= 1
ENABLE_FEAT_F4HWN_INV ?= 1 ENABLE_FEAT_F4HWN_INV ?= 1
ENABLE_FEAT_F4HWN_CTR ?= 1 ENABLE_FEAT_F4HWN_CTR ?= 0
ENABLE_FEAT_F4HWN_RESCUE_OPS ?= 0 ENABLE_FEAT_F4HWN_RESCUE_OPS ?= 0
ENABLE_FEAT_F4HWN_VOL ?= 0 ENABLE_FEAT_F4HWN_VOL ?= 1
ENABLE_FEAT_F4HWN_RESET_CHANNEL ?= 0 ENABLE_FEAT_F4HWN_RESET_CHANNEL ?= 0
ENABLE_FEAT_F4HWN_PMR ?= 0 ENABLE_FEAT_F4HWN_PMR ?= 0
ENABLE_FEAT_F4HWN_GMRS_FRS_MURS ?= 0 ENABLE_FEAT_F4HWN_GMRS_FRS_MURS ?= 0
ENABLE_FEAT_F4HWN_CA ?= 1 ENABLE_FEAT_F4HWN_CA ?= 0
ENABLE_FEAT_F4HWN_DEBUG ?= 0 ENABLE_FEAT_F4HWN_DEBUG ?= 0
ENABLE_REGA ?= 0 ENABLE_REGA ?= 0
@@ -67,7 +66,7 @@ ENABLE_UART_RW_BK_REGS ?= 0
# ---- COMPILER/LINKER OPTIONS ---- # ---- COMPILER/LINKER OPTIONS ----
ENABLE_CLANG ?= 0 ENABLE_CLANG ?= 0
ENABLE_SWD ?= 0 ENABLE_SWD ?= 0
ENABLE_OVERLAY ?= 0 ENABLE_OVERLAY ?= 1
ENABLE_LTO ?= 1 ENABLE_LTO ?= 1
############################################################# #############################################################
@@ -138,6 +137,8 @@ OBJS += app/app.o
OBJS += app/chFrScanner.o OBJS += app/chFrScanner.o
OBJS += app/common.o OBJS += app/common.o
OBJS += app/dtmf.o OBJS += app/dtmf.o
OBJS += app/fskmodem.o
OBJS += app/messages.o
ifeq ($(ENABLE_REGA),1) ifeq ($(ENABLE_REGA),1)
OBJS += app/rega.o OBJS += app/rega.o
endif endif
@@ -176,6 +177,7 @@ OBJS += settings.o
ifeq ($(ENABLE_AIRCOPY),1) ifeq ($(ENABLE_AIRCOPY),1)
OBJS += ui/aircopy.o OBJS += ui/aircopy.o
endif endif
OBJS += ui/messages.o
OBJS += ui/battery.o OBJS += ui/battery.o
ifeq ($(ENABLE_FMRADIO),1) ifeq ($(ENABLE_FMRADIO),1)
OBJS += ui/fmradio.o OBJS += ui/fmradio.o
@@ -448,9 +450,6 @@ endif
ifeq ($(ENABLE_FEAT_F4HWN_RESUME_STATE),1) ifeq ($(ENABLE_FEAT_F4HWN_RESUME_STATE),1)
CFLAGS += -DENABLE_FEAT_F4HWN_RESUME_STATE CFLAGS += -DENABLE_FEAT_F4HWN_RESUME_STATE
endif endif
ifeq ($(ENABLE_FEAT_F4HWN_NARROWER),1)
CFLAGS += -DENABLE_FEAT_F4HWN_NARROWER
endif
ifeq ($(ENABLE_FEAT_F4HWN_INV),1) ifeq ($(ENABLE_FEAT_F4HWN_INV),1)
CFLAGS += -DENABLE_FEAT_F4HWN_INV CFLAGS += -DENABLE_FEAT_F4HWN_INV
endif endif

View File

@@ -97,6 +97,8 @@ Special thanks to Jean-Cyrille F6IWW (2 times), Fabrice 14RC123, David F4BPP, Ol
* improve ScnRev menu (CARRIER from 250ms to 20s, STOP, TIMEOUT from 5s to 2m) * improve ScnRev menu (CARRIER from 250ms to 20s, STOP, TIMEOUT from 5s to 2m)
* improve KeyLck menu (OFF, delay from 15s to 10m) * improve KeyLck menu (OFF, delay from 15s to 10m)
* add HAM CA F Lock band (for Canadian zone), * add HAM CA F Lock band (for Canadian zone),
* add PMR 446 F Lock band,
* add FRS/GMRS/MURS F Lock band,
* remove blink and SOS functionality, * remove blink and SOS functionality,
* remove AM Fix menu (AM Fix is ENABLED by default), * remove AM Fix menu (AM Fix is ENABLED by default),
* add support of 3500mAh battery, * add support of 3500mAh battery,
@@ -116,13 +118,14 @@ Special thanks to Jean-Cyrille F6IWW (2 times), Fabrice 14RC123, David F4BPP, Ol
* scan lists [1, 2, 3], * scan lists [1, 2, 3],
* scan all (all channels with ou without list), * scan all (all channels with ou without list),
* add scan list shortcuts, * add scan list shortcuts,
* add scan resume mode on startup, * add resume mode on startup (scan, bandscope and broadcast FM),
* new actions: * new actions:
* RX MODE, * RX MODE,
* MAIN ONLY, * MAIN ONLY,
* PTT, * PTT,
* WIDE NARROW, * WIDE NARROW,
* 1750Hz, * 1750Hz,
* MUTE,
* POWER HIGH (RescueOps), * POWER HIGH (RescueOps),
* REMOVE OFFSET (RescueOps), * REMOVE OFFSET (RescueOps),
* new key combinations: * new key combinations:

View File

@@ -42,6 +42,9 @@
#include "settings.h" #include "settings.h"
#include "ui/inputbox.h" #include "ui/inputbox.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "driver/st7565.h"
#include "ui/menu.h"
#ifdef ENABLE_REGA #ifdef ENABLE_REGA
#include "app/rega.h" #include "app/rega.h"
#endif #endif
@@ -110,7 +113,6 @@ void (*action_opt_table[])(void) = {
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
[ACTION_OPT_RXMODE] = &ACTION_RxMode, [ACTION_OPT_RXMODE] = &ACTION_RxMode,
[ACTION_OPT_MAINONLY] = &ACTION_MainOnly,
[ACTION_OPT_PTT] = &ACTION_Ptt, [ACTION_OPT_PTT] = &ACTION_Ptt,
[ACTION_OPT_WN] = &ACTION_Wn, [ACTION_OPT_WN] = &ACTION_Wn,
[ACTION_OPT_BACKLIGHT] = &ACTION_BackLight, [ACTION_OPT_BACKLIGHT] = &ACTION_BackLight,
@@ -119,10 +121,6 @@ void (*action_opt_table[])(void) = {
#else #else
[ACTION_OPT_MUTE] = &FUNCTION_NOP, [ACTION_OPT_MUTE] = &FUNCTION_NOP,
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
[ACTION_OPT_POWER_HIGH] = &ACTION_Power_High,
[ACTION_OPT_REMOVE_OFFSET] = &ACTION_Remove_Offset,
#endif
#else #else
[ACTION_OPT_RXMODE] = &FUNCTION_NOP, [ACTION_OPT_RXMODE] = &FUNCTION_NOP,
#endif #endif
@@ -136,8 +134,9 @@ static_assert(ARRAY_SIZE(action_opt_table) == ACTION_OPT_LEN);
void ACTION_Power(void) void ACTION_Power(void)
{ {
if (++gTxVfo->OUTPUT_POWER > OUTPUT_POWER_HIGH) gTxVfo->OUTPUT_POWER++;
gTxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW1; if (gTxVfo->OUTPUT_POWER >= ARRAY_SIZE(gSubMenu_TXP))
gTxVfo->OUTPUT_POWER = 0;
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
@@ -440,7 +439,7 @@ static void ACTION_Scan_FM(bool bRestart)
static void ACTION_AlarmOr1750(const bool b1750) static void ACTION_AlarmOr1750(const bool b1750)
{ {
if(gEeprom.KEY_LOCK && gEeprom.KEY_LOCK_PTT) if(gEeprom.KEY_LOCK)
return; return;
#if defined(ENABLE_ALARM) #if defined(ENABLE_ALARM)
@@ -552,40 +551,12 @@ void ACTION_Ptt(void)
void ACTION_Wn(void) void ACTION_Wn(void)
{ {
#ifdef ENABLE_FEAT_F4HWN_NARROWER
bool narrower = 0;
if (FUNCTION_IsRx()) if (FUNCTION_IsRx())
{ {
gRxVfo->CHANNEL_BANDWIDTH = (gRxVfo->CHANNEL_BANDWIDTH == 0) ? 1: 0; gRxVfo->CHANNEL_BANDWIDTH++;
if(gRxVfo->CHANNEL_BANDWIDTH == BANDWIDTH_NARROW && gSetting_set_nfm == 1) if (gRxVfo->CHANNEL_BANDWIDTH > BK4819_FILTER_BW_NARROWER) {
{ gRxVfo->CHANNEL_BANDWIDTH = BK4819_FILTER_BW_WIDE;
narrower = 1;
} }
#ifdef ENABLE_AM_FIX
BK4819_SetFilterBandwidth(gRxVfo->CHANNEL_BANDWIDTH + narrower, true);
#else
BK4819_SetFilterBandwidth(gRxVfo->CHANNEL_BANDWIDTH + narrower, false);
#endif
}
else
{
gTxVfo->CHANNEL_BANDWIDTH = (gTxVfo->CHANNEL_BANDWIDTH == 0) ? 1: 0;
if(gTxVfo->CHANNEL_BANDWIDTH == BANDWIDTH_NARROW && gSetting_set_nfm == 1)
{
narrower = 1;
}
#ifdef ENABLE_AM_FIX
BK4819_SetFilterBandwidth(gTxVfo->CHANNEL_BANDWIDTH, true);
#else
BK4819_SetFilterBandwidth(gTxVfo->CHANNEL_BANDWIDTH, false);
#endif
}
#else
if (FUNCTION_IsRx())
{
gRxVfo->CHANNEL_BANDWIDTH = (gRxVfo->CHANNEL_BANDWIDTH == 0) ? 1: 0;
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
BK4819_SetFilterBandwidth(gRxVfo->CHANNEL_BANDWIDTH, true); BK4819_SetFilterBandwidth(gRxVfo->CHANNEL_BANDWIDTH, true);
#else #else
@@ -594,14 +565,16 @@ void ACTION_Wn(void)
} }
else else
{ {
gTxVfo->CHANNEL_BANDWIDTH = (gTxVfo->CHANNEL_BANDWIDTH == 0) ? 1: 0; gRxVfo->CHANNEL_BANDWIDTH++;
if (gRxVfo->CHANNEL_BANDWIDTH > BK4819_FILTER_BW_NARROWER) {
gRxVfo->CHANNEL_BANDWIDTH = BK4819_FILTER_BW_WIDE;
}
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
BK4819_SetFilterBandwidth(gTxVfo->CHANNEL_BANDWIDTH, true); BK4819_SetFilterBandwidth(gTxVfo->CHANNEL_BANDWIDTH, true);
#else #else
BK4819_SetFilterBandwidth(gTxVfo->CHANNEL_BANDWIDTH, false); BK4819_SetFilterBandwidth(gTxVfo->CHANNEL_BANDWIDTH, false);
#endif #endif
} }
#endif
} }
void ACTION_BackLight(void) void ACTION_BackLight(void)
@@ -657,18 +630,4 @@ void ACTION_BackLightOnDemand(void)
gUpdateStatus = true; gUpdateStatus = true;
} }
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
void ACTION_Power_High(void)
{
gPowerHigh = !gPowerHigh;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
}
void ACTION_Remove_Offset(void)
{
gRemoveOffset = !gRemoveOffset;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
}
#endif
#endif #endif

View File

@@ -45,10 +45,6 @@ void ACTION_SwitchDemodul(void);
#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO) #if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO)
void ACTION_Mute(void); void ACTION_Mute(void);
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
void ACTION_Power_High(void);
void ACTION_Remove_Offset(void);
#endif
#endif #endif
void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);

View File

@@ -36,7 +36,7 @@
#include "screenshot.h" #include "screenshot.h"
#endif #endif
static const uint16_t Obfuscation[8] = { 0x6C16, 0xE614, 0x912E, 0x400D, 0x3521, 0x40D5, 0x0313, 0x80E9 }; static const uint16_t Obfuscation[8] = {0x6C16, 0xE614, 0x912E, 0x400D, 0x3521, 0x40D5, 0x0313, 0x80E9};
AIRCOPY_State_t gAircopyState; AIRCOPY_State_t gAircopyState;
uint16_t gAirCopyBlockNumber; uint16_t gAirCopyBlockNumber;
@@ -45,16 +45,13 @@ uint8_t gAirCopyIsSendMode;
uint16_t g_FSK_Buffer[36]; uint16_t g_FSK_Buffer[36];
static void AIRCOPY_clear() static void AIRCOPY_clear() {
{ for (uint8_t i = 0; i < 15; i++) {
for (uint8_t i = 0; i < 15; i++)
{
crc[i] = 0; crc[i] = 0;
} }
} }
bool AIRCOPY_SendMessage(void) bool AIRCOPY_SendMessage(void) {
{
static uint8_t gAircopySendCountdown = 1; static uint8_t gAircopySendCountdown = 1;
if (gAircopyState != AIRCOPY_TRANSFER) { if (gAircopyState != AIRCOPY_TRANSFER) {
@@ -77,9 +74,9 @@ bool AIRCOPY_SendMessage(void)
if (++gAirCopyBlockNumber >= 0x78) { if (++gAirCopyBlockNumber >= 0x78) {
gAircopyState = AIRCOPY_COMPLETE; gAircopyState = AIRCOPY_COMPLETE;
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT #ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
getScreenShot(); getScreenShot();
#endif #endif
//NVIC_SystemReset(); //NVIC_SystemReset();
} }
@@ -94,8 +91,7 @@ bool AIRCOPY_SendMessage(void)
return 0; return 0;
} }
void AIRCOPY_StorePacket(void) void AIRCOPY_StorePacket(void) {
{
if (gFSKWriteIndex < 36) { if (gFSKWriteIndex < 36) {
return; return;
} }
@@ -138,16 +134,15 @@ void AIRCOPY_StorePacket(void)
if (Offset == 0x1E00) { if (Offset == 0x1E00) {
gAircopyState = AIRCOPY_COMPLETE; gAircopyState = AIRCOPY_COMPLETE;
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT #ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
getScreenShot(); getScreenShot();
#endif #endif
} }
gAirCopyBlockNumber++; gAirCopyBlockNumber++;
} }
static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
{
if (bKeyHeld || !bKeyPressed) { if (bKeyHeld || !bKeyPressed) {
return; return;
} }
@@ -194,8 +189,7 @@ static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gRequestDisplayScreen = DISPLAY_AIRCOPY; gRequestDisplayScreen = DISPLAY_AIRCOPY;
} }
static void AIRCOPY_Key_EXIT(bool bKeyPressed, bool bKeyHeld) static void AIRCOPY_Key_EXIT(bool bKeyPressed, bool bKeyHeld) {
{
if (bKeyHeld || !bKeyPressed) { if (bKeyHeld || !bKeyPressed) {
return; return;
} }
@@ -220,8 +214,7 @@ static void AIRCOPY_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
gRequestDisplayScreen = DISPLAY_AIRCOPY; gRequestDisplayScreen = DISPLAY_AIRCOPY;
} }
static void AIRCOPY_Key_MENU(bool bKeyPressed, bool bKeyHeld) static void AIRCOPY_Key_MENU(bool bKeyPressed, bool bKeyHeld) {
{
if (bKeyHeld || !bKeyPressed) { if (bKeyHeld || !bKeyPressed) {
return; return;
} }
@@ -242,8 +235,7 @@ static void AIRCOPY_Key_MENU(bool bKeyPressed, bool bKeyHeld)
gAircopyState = AIRCOPY_TRANSFER; gAircopyState = AIRCOPY_TRANSFER;
} }
void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
{
switch (Key) { switch (Key) {
case KEY_0: case KEY_0:
case KEY_1: case KEY_1:

694
app/app.c

File diff suppressed because it is too large Load Diff

View File

@@ -24,12 +24,20 @@
#include "radio.h" #include "radio.h"
void APP_EndTransmission(void); void APP_EndTransmission(void);
void APP_StartListening(FUNCTION_Type_t function); void APP_StartListening(FUNCTION_Type_t function);
uint32_t APP_SetFreqByStepAndLimits(VFO_Info_t *pInfo, int8_t direction, uint32_t lower, uint32_t upper); uint32_t APP_SetFreqByStepAndLimits(VFO_Info_t *pInfo, int8_t direction, uint32_t lower, uint32_t upper);
uint32_t APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t direction); uint32_t APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t direction);
void APP_Update(void); void APP_Update(void);
void APP_TimeSlice10ms(void); void APP_TimeSlice10ms(void);
void APP_TimeSlice500ms(void); void APP_TimeSlice500ms(void);
void APP_EndTransmission(void);
#endif #endif

View File

@@ -248,7 +248,7 @@ void DTMF_HandleRequest(void)
return; return;
} }
if (!gRxVfo->DTMF_DECODING_ENABLE && !gSetting_KILLED) if (!gRxVfo->DTMF_DECODING_ENABLE)
{ // D-DCD is disabled or we're alive { // D-DCD is disabled or we're alive
DTMF_clear_RX(); DTMF_clear_RX();
return; return;
@@ -266,28 +266,28 @@ void DTMF_HandleRequest(void)
if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true)) if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
{ // bugger { // bugger
if (gEeprom.PERMIT_REMOTE_KILL) // if (gEeprom.PERMIT_REMOTE_KILL)
{ // {
gSetting_KILLED = true; // oooerr ! // gSetting_KILLED = true; // oooerr !
//
DTMF_clear_RX(); // DTMF_clear_RX();
//
SETTINGS_SaveSettings(); // SETTINGS_SaveSettings();
//
gDTMF_ReplyState = DTMF_REPLY_AB; // gDTMF_ReplyState = DTMF_REPLY_AB;
//
#ifdef ENABLE_FMRADIO // #ifdef ENABLE_FMRADIO
if (gFmRadioMode) // if (gFmRadioMode)
{ // {
FM_TurnOff(); // FM_TurnOff();
GUI_SelectNextDisplay(DISPLAY_MAIN); // GUI_SelectNextDisplay(DISPLAY_MAIN);
} // }
#endif // #endif
} // }
else // else
{ // {
gDTMF_ReplyState = DTMF_REPLY_NONE; gDTMF_ReplyState = DTMF_REPLY_NONE;
} // }
gDTMF_CallState = DTMF_CALL_STATE_NONE; gDTMF_CallState = DTMF_CALL_STATE_NONE;
@@ -297,30 +297,30 @@ void DTMF_HandleRequest(void)
} }
} }
if (gDTMF_RX_index >= 9) // if (gDTMF_RX_index >= 9)
{ // look for the REVIVE code // { // look for the REVIVE code
//
sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, gEeprom.REVIVE_CODE); // sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, gEeprom.REVIVE_CODE);
//
Offset = gDTMF_RX_index - strlen(String); // Offset = gDTMF_RX_index - strlen(String);
//
if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true)) // if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true))
{ // shit, we're back ! // { // shit, we're back !
//
gSetting_KILLED = false; // gSetting_KILLED = false;
//
DTMF_clear_RX(); // DTMF_clear_RX();
//
SETTINGS_SaveSettings(); // SETTINGS_SaveSettings();
//
gDTMF_ReplyState = DTMF_REPLY_AB; // gDTMF_ReplyState = DTMF_REPLY_AB;
gDTMF_CallState = DTMF_CALL_STATE_NONE; // gDTMF_CallState = DTMF_CALL_STATE_NONE;
//
gUpdateDisplay = true; // gUpdateDisplay = true;
gUpdateStatus = true; // gUpdateStatus = true;
return; // return;
} // }
} // }
if (gDTMF_RX_index >= 2) if (gDTMF_RX_index >= 2)
{ // look for ACK reply { // look for ACK reply
@@ -360,7 +360,7 @@ void DTMF_HandleRequest(void)
} }
} }
if (gSetting_KILLED || gDTMF_CallState != DTMF_CALL_STATE_NONE) if (gDTMF_CallState != DTMF_CALL_STATE_NONE)
{ // we've been killed or expecting a reply { // we've been killed or expecting a reply
return; return;
} }

View File

@@ -5,11 +5,9 @@
#include "flashlight.h" #include "flashlight.h"
#if !defined(ENABLE_FEAT_F4HWN) || defined(ENABLE_FEAT_F4HWN_RESCUE_OPS) enum FlashlightMode_t gFlashLightState;
enum FlashlightMode_t gFlashLightState;
void FlashlightTimeSlice() void FlashlightTimeSlice() {
{
if (gFlashLightState == FLASHLIGHT_BLINK && (gFlashLightBlinkCounter & 15u) == 0) { if (gFlashLightState == FLASHLIGHT_BLINK && (gFlashLightBlinkCounter & 15u) == 0) {
GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
return; return;
@@ -27,7 +25,7 @@
} }
if (gFlashLightBlinkCounter == next) { if (gFlashLightBlinkCounter == next) {
if (c==0) { if (c == 0) {
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
} else { } else {
GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
@@ -36,7 +34,7 @@
if (c >= 18) { if (c >= 18) {
next = gFlashLightBlinkCounter + 7 * u; next = gFlashLightBlinkCounter + 7 * u;
c = 0; c = 0;
} else if(c==7 || c==9 || c==11) { } else if (c == 7 || c == 9 || c == 11) {
next = gFlashLightBlinkCounter + 3 * u; next = gFlashLightBlinkCounter + 3 * u;
} else { } else {
next = gFlashLightBlinkCounter + u; next = gFlashLightBlinkCounter + u;
@@ -44,10 +42,9 @@
c++; c++;
} }
} }
} }
void ACTION_FlashLight(void) void ACTION_FlashLight(void) {
{
switch (gFlashLightState) { switch (gFlashLightState) {
case FLASHLIGHT_OFF: case FLASHLIGHT_OFF:
gFlashLightState++; gFlashLightState++;
@@ -62,22 +59,6 @@
gFlashLightState = 0; gFlashLightState = 0;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
} }
} }
#else
void ACTION_FlashLight(void)
{
static bool gFlashLightState = false;
if(gFlashLightState)
{
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
}
else
{
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
}
gFlashLightState = (gFlashLightState) ? false : true;
}
#endif
#endif #endif

View File

@@ -5,7 +5,6 @@
#include <stdint.h> #include <stdint.h>
#if !defined(ENABLE_FEAT_F4HWN) || defined(ENABLE_FEAT_F4HWN_RESCUE_OPS)
enum FlashlightMode_t { enum FlashlightMode_t {
FLASHLIGHT_OFF = 0, FLASHLIGHT_OFF = 0,
FLASHLIGHT_ON, FLASHLIGHT_ON,
@@ -17,7 +16,6 @@
extern volatile uint16_t gFlashLightBlinkCounter; extern volatile uint16_t gFlashLightBlinkCounter;
void FlashlightTimeSlice(void); void FlashlightTimeSlice(void);
#endif
void ACTION_FlashLight(void); void ACTION_FlashLight(void);
#endif #endif

149
app/fm.c
View File

@@ -31,9 +31,10 @@
#include "settings.h" #include "settings.h"
#include "ui/inputbox.h" #include "ui/inputbox.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "driver/systick.h"
#ifndef ARRAY_SIZE #ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#endif #endif
uint16_t gFM_Channels[20]; uint16_t gFM_Channels[20];
@@ -48,7 +49,6 @@ bool gFM_AutoScan;
uint16_t gFM_RestoreCountdown_10ms; uint16_t gFM_RestoreCountdown_10ms;
const uint8_t BUTTON_STATE_PRESSED = 1 << 0; const uint8_t BUTTON_STATE_PRESSED = 1 << 0;
const uint8_t BUTTON_STATE_HELD = 1 << 1; const uint8_t BUTTON_STATE_HELD = 1 << 1;
@@ -60,15 +60,13 @@ const uint8_t BUTTON_EVENT_LONG = BUTTON_STATE_HELD;
static void Key_FUNC(KEY_Code_t Key, uint8_t state); static void Key_FUNC(KEY_Code_t Key, uint8_t state);
bool FM_CheckValidChannel(uint8_t Channel) bool FM_CheckValidChannel(uint8_t Channel) {
{
return Channel < ARRAY_SIZE(gFM_Channels) && return Channel < ARRAY_SIZE(gFM_Channels) &&
gFM_Channels[Channel] >= BK1080_GetFreqLoLimit(gEeprom.FM_Band) && gFM_Channels[Channel] >= BK1080_GetFreqLoLimit(gEeprom.FM_Band) &&
gFM_Channels[Channel] < BK1080_GetFreqHiLimit(gEeprom.FM_Band); gFM_Channels[Channel] < BK1080_GetFreqHiLimit(gEeprom.FM_Band);
} }
uint8_t FM_FindNextChannel(uint8_t Channel, uint8_t Direction) uint8_t FM_FindNextChannel(uint8_t Channel, uint8_t Direction) {
{
for (unsigned i = 0; i < ARRAY_SIZE(gFM_Channels); i++) { for (unsigned i = 0; i < ARRAY_SIZE(gFM_Channels); i++) {
if (Channel == 0xFF) if (Channel == 0xFF)
Channel = ARRAY_SIZE(gFM_Channels) - 1; Channel = ARRAY_SIZE(gFM_Channels) - 1;
@@ -82,8 +80,7 @@ uint8_t FM_FindNextChannel(uint8_t Channel, uint8_t Direction)
return 0xFF; return 0xFF;
} }
int FM_ConfigureChannelState(void) int FM_ConfigureChannelState(void) {
{
gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency; gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency;
if (gEeprom.FM_IsMrMode) { if (gEeprom.FM_IsMrMode) {
@@ -99,8 +96,7 @@ int FM_ConfigureChannelState(void)
return 0; return 0;
} }
void FM_TurnOff(void) void FM_TurnOff(void) {
{
gFmRadioMode = false; gFmRadioMode = false;
gFM_ScanState = FM_SCAN_OFF; gFM_ScanState = FM_SCAN_OFF;
gFM_RestoreCountdown_10ms = 0; gFM_RestoreCountdown_10ms = 0;
@@ -112,14 +108,13 @@ void FM_TurnOff(void)
gUpdateStatus = true; gUpdateStatus = true;
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE #ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
gEeprom.CURRENT_STATE = 0; gEeprom.CURRENT_STATE = 0;
SETTINGS_WriteCurrentState(); SETTINGS_WriteCurrentState();
#endif #endif
} }
void FM_EraseChannels(void) void FM_EraseChannels(void) {
{
uint8_t Template[8]; uint8_t Template[8];
memset(Template, 0xFF, sizeof(Template)); memset(Template, 0xFF, sizeof(Template));
@@ -129,13 +124,13 @@ void FM_EraseChannels(void)
memset(gFM_Channels, 0xFF, sizeof(gFM_Channels)); memset(gFM_Channels, 0xFF, sizeof(gFM_Channels));
} }
void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag) void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag) {
{
AUDIO_AudioPathOff(); AUDIO_AudioPathOff();
gEnableSpeaker = false; gEnableSpeaker = false;
gFmPlayCountdown_10ms = (gFM_ScanState == FM_SCAN_OFF) ? fm_play_countdown_noscan_10ms : fm_play_countdown_scan_10ms; gFmPlayCountdown_10ms = (gFM_ScanState == FM_SCAN_OFF) ? fm_play_countdown_noscan_10ms
: fm_play_countdown_scan_10ms;
gScheduleFM = false; gScheduleFM = false;
gFM_FoundFrequency = false; gFM_FoundFrequency = false;
@@ -158,8 +153,7 @@ void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag)
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/);
} }
void FM_PlayAndUpdate(void) void FM_PlayAndUpdate(void) {
{
gFM_ScanState = FM_SCAN_OFF; gFM_ScanState = FM_SCAN_OFF;
if (gFM_AutoScan) { if (gFM_AutoScan) {
@@ -180,11 +174,10 @@ void FM_PlayAndUpdate(void)
gEnableSpeaker = true; gEnableSpeaker = true;
} }
int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit) int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit) {
{
int ret = -1; int ret = -1;
const uint16_t Test2 = BK1080_ReadRegister(BK1080_REG_07); const uint16_t Test2 = BK1080_ReadRegister(BK1080_REG_07_TEST1);
// This is supposed to be a signed value, but above function is unsigned // This is supposed to be a signed value, but above function is unsigned
const uint16_t Deviation = BK1080_REG_07_GET_FREQD(Test2); const uint16_t Deviation = BK1080_REG_07_GET_FREQD(Test2);
@@ -196,7 +189,7 @@ int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit)
return ret; return ret;
} }
const uint16_t Status = BK1080_ReadRegister(BK1080_REG_10); const uint16_t Status = BK1080_ReadRegister(BK1080_REG_10_RSSI_STATUS);
if ((Status & BK1080_REG_10_MASK_AFCRL) != BK1080_REG_10_AFCRL_NOT_RAILED || BK1080_REG_10_GET_RSSI(Status) < 10) { if ((Status & BK1080_REG_10_MASK_AFCRL) != BK1080_REG_10_AFCRL_NOT_RAILED || BK1080_REG_10_GET_RSSI(Status) < 10) {
BK1080_FrequencyDeviation = Deviation; BK1080_FrequencyDeviation = Deviation;
@@ -215,8 +208,7 @@ int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit)
// not BLE(less than or equal) // not BLE(less than or equal)
if (Frequency > LowerLimit && (Frequency - BK1080_BaseFrequency) == 1) { if (Frequency > LowerLimit && (Frequency - BK1080_BaseFrequency) == 1) {
if (BK1080_FrequencyDeviation & 0x800 || (BK1080_FrequencyDeviation < 20)) if (BK1080_FrequencyDeviation & 0x800 || (BK1080_FrequencyDeviation < 20)) {
{
BK1080_FrequencyDeviation = Deviation; BK1080_FrequencyDeviation = Deviation;
BK1080_BaseFrequency = Frequency; BK1080_BaseFrequency = Frequency;
@@ -227,8 +219,7 @@ int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit)
// not BLT(less than) // not BLT(less than)
if (Frequency >= LowerLimit && (BK1080_BaseFrequency - Frequency) == 1) { if (Frequency >= LowerLimit && (BK1080_BaseFrequency - Frequency) == 1) {
if ((BK1080_FrequencyDeviation & 0x800) == 0 || (BK1080_FrequencyDeviation > 4075)) if ((BK1080_FrequencyDeviation & 0x800) == 0 || (BK1080_FrequencyDeviation > 4075)) {
{
BK1080_FrequencyDeviation = Deviation; BK1080_FrequencyDeviation = Deviation;
BK1080_BaseFrequency = Frequency; BK1080_BaseFrequency = Frequency;
@@ -243,9 +234,10 @@ int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit)
return ret; return ret;
} }
static void Key_DIGITS(KEY_Code_t Key, uint8_t state) static void Key_DIGITS(KEY_Code_t Key, uint8_t state) {
{ enum {
enum { STATE_FREQ_MODE, STATE_MR_MODE, STATE_SAVE }; STATE_FREQ_MODE, STATE_MR_MODE, STATE_SAVE
};
if (state == BUTTON_EVENT_SHORT && !gWasFKeyPressed) { if (state == BUTTON_EVENT_SHORT && !gWasFKeyPressed) {
uint8_t State; uint8_t State;
@@ -257,8 +249,7 @@ static void Key_DIGITS(KEY_Code_t Key, uint8_t state)
if (gAskToSave) { if (gAskToSave) {
State = STATE_SAVE; State = STATE_SAVE;
} } else {
else {
if (gFM_ScanState != FM_SCAN_OFF) { if (gFM_ScanState != FM_SCAN_OFF) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return; return;
@@ -278,20 +269,20 @@ static void Key_DIGITS(KEY_Code_t Key, uint8_t state)
gInputBox[0] = 0; gInputBox[0] = 0;
gInputBoxIndex = 2; gInputBoxIndex = 2;
} }
} } else if (gInputBoxIndex > 3) {
else if (gInputBoxIndex > 3) {
uint32_t Frequency; uint32_t Frequency;
gInputBoxIndex = 0; gInputBoxIndex = 0;
Frequency = StrToUL(INPUTBOX_GetAscii()); Frequency = StrToUL(INPUTBOX_GetAscii());
if (Frequency < BK1080_GetFreqLoLimit(gEeprom.FM_Band) || BK1080_GetFreqHiLimit(gEeprom.FM_Band) < Frequency) { if (Frequency < BK1080_GetFreqLoLimit(gEeprom.FM_Band) ||
BK1080_GetFreqHiLimit(gEeprom.FM_Band) < Frequency) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
gRequestDisplayScreen = DISPLAY_FM; gRequestDisplayScreen = DISPLAY_FM;
return; return;
} }
gEeprom.FM_SelectedFrequency = (uint16_t)Frequency; gEeprom.FM_SelectedFrequency = (uint16_t) Frequency;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
#endif #endif
@@ -300,8 +291,7 @@ static void Key_DIGITS(KEY_Code_t Key, uint8_t state)
gRequestSaveFM = true; gRequestSaveFM = true;
return; return;
} }
} } else if (gInputBoxIndex == 2) {
else if (gInputBoxIndex == 2) {
uint8_t Channel; uint8_t Channel;
gInputBoxIndex = 0; gInputBoxIndex = 0;
@@ -318,8 +308,7 @@ static void Key_DIGITS(KEY_Code_t Key, uint8_t state)
gRequestSaveFM = true; gRequestSaveFM = true;
return; return;
} }
} } else if (Channel < 20) {
else if (Channel < 20) {
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
#endif #endif
@@ -336,13 +325,11 @@ static void Key_DIGITS(KEY_Code_t Key, uint8_t state)
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
#endif #endif
} } else
else
Key_FUNC(Key, state); Key_FUNC(Key, state);
} }
static void Key_FUNC(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); bool autoScan = gWasFKeyPressed || (state == BUTTON_EVENT_HELD);
@@ -372,11 +359,30 @@ static void Key_FUNC(KEY_Code_t Key, uint8_t state)
if (!FM_ConfigureChannelState()) { if (!FM_ConfigureChannelState()) {
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/);
gRequestSaveFM = true; gRequestSaveFM = true;
} } else
else
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
break; break;
case KEY_4:
gEeprom.BK1080_AGC_ENABLED = !gEeprom.BK1080_AGC_ENABLED;
BK1080_UpdateSysconf();
gRequestSaveSettings = true;
gRequestSaveFM = true;
break;
case KEY_5:
gEeprom.BK1080_DEEMPHASIS_CONFIG++;
BK1080_UpdateSysconf();
gRequestSaveSettings = true;
gRequestSaveFM = true;
break;
case KEY_6:
gEeprom.BK1080_BLEND_CONFIG++;
BK1080_UpdateSysconf();
gRequestSaveSettings = true;
gRequestSaveFM = true;
break;
case KEY_STAR: case KEY_STAR:
ACTION_Scan(autoScan); ACTION_Scan(autoScan);
break; break;
@@ -388,14 +394,14 @@ static void Key_FUNC(KEY_Code_t Key, uint8_t state)
} }
} }
static void Key_EXIT(uint8_t state) static void Key_EXIT(uint8_t state) {
{
if (state != BUTTON_EVENT_SHORT)
return;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gFM_ScanState == FM_SCAN_OFF) { if (state == BUTTON_EVENT_SHORT) {
return;
}
if (gFM_ScanState == FM_SCAN_OFF || state == BUTTON_EVENT_LONG) {
if (gInputBoxIndex == 0) { if (gInputBoxIndex == 0) {
if (!gAskToSave && !gAskToDelete) { if (!gAskToSave && !gAskToDelete) {
ACTION_FM(); ACTION_FM();
@@ -404,8 +410,7 @@ static void Key_EXIT(uint8_t state)
gAskToSave = false; gAskToSave = false;
gAskToDelete = false; gAskToDelete = false;
} } else {
else {
gInputBox[--gInputBoxIndex] = 10; gInputBox[--gInputBoxIndex] = 10;
if (gInputBoxIndex) { if (gInputBoxIndex) {
@@ -425,8 +430,7 @@ static void Key_EXIT(uint8_t state)
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL; gAnotherVoiceID = VOICE_ID_CANCEL;
#endif #endif
} } else {
else {
FM_PlayAndUpdate(); FM_PlayAndUpdate();
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP; gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
@@ -436,8 +440,7 @@ static void Key_EXIT(uint8_t state)
gRequestDisplayScreen = DISPLAY_FM; gRequestDisplayScreen = DISPLAY_FM;
} }
static void Key_MENU(uint8_t state) static void Key_MENU(uint8_t state) {
{
if (state != BUTTON_EVENT_SHORT) if (state != BUTTON_EVENT_SHORT)
return; return;
@@ -452,8 +455,7 @@ static void Key_MENU(uint8_t state)
gRequestSaveFM = true; gRequestSaveFM = true;
} }
gAskToSave = !gAskToSave; gAskToSave = !gAskToSave;
} } else {
else {
if (gAskToDelete) { if (gAskToDelete) {
gFM_Channels[gEeprom.FM_SelectedChannel] = 0xFFFF; gFM_Channels[gEeprom.FM_SelectedChannel] = 0xFFFF;
@@ -464,8 +466,7 @@ static void Key_MENU(uint8_t state)
} }
gAskToDelete = !gAskToDelete; gAskToDelete = !gAskToDelete;
} }
} } else {
else {
if (gFM_AutoScan || !gFM_FoundFrequency) { if (gFM_AutoScan || !gFM_FoundFrequency) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
gInputBoxIndex = 0; gInputBoxIndex = 0;
@@ -480,8 +481,7 @@ static void Key_MENU(uint8_t state)
} }
} }
static void Key_UP_DOWN(uint8_t state, int8_t Step) static void Key_UP_DOWN(uint8_t state, int8_t Step) {
{
if (state == BUTTON_EVENT_PRESSED) { if (state == BUTTON_EVENT_PRESSED) {
if (gInputBoxIndex) { if (gInputBoxIndex) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
@@ -489,7 +489,7 @@ static void Key_UP_DOWN(uint8_t state, int8_t Step)
} }
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
} else if (gInputBoxIndex || state!=BUTTON_EVENT_HELD) { } else if (gInputBoxIndex || state != BUTTON_EVENT_HELD) {
return; return;
} }
@@ -517,8 +517,7 @@ static void Key_UP_DOWN(uint8_t state, int8_t Step)
gEeprom.FM_SelectedChannel = Channel; gEeprom.FM_SelectedChannel = Channel;
gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel]; gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel];
} } else {
else {
uint16_t Frequency = gEeprom.FM_SelectedFrequency + Step; uint16_t Frequency = gEeprom.FM_SelectedFrequency + Step;
if (Frequency < BK1080_GetFreqLoLimit(gEeprom.FM_Band)) if (Frequency < BK1080_GetFreqLoLimit(gEeprom.FM_Band))
@@ -532,14 +531,13 @@ static void Key_UP_DOWN(uint8_t state, int8_t Step)
gRequestSaveFM = true; gRequestSaveFM = true;
Bail: Bail:
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/);
gRequestDisplayScreen = DISPLAY_FM; gRequestDisplayScreen = DISPLAY_FM;
} }
void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
{
uint8_t state = bKeyPressed + 2 * bKeyHeld; uint8_t state = bKeyPressed + 2 * bKeyHeld;
switch (Key) { switch (Key) {
@@ -572,10 +570,10 @@ void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
break; break;
} }
GUI_DisplayScreen();
} }
void FM_Play(void) void FM_Play(void) {
{
if (!FM_CheckFrequencyLock(gEeprom.FM_FrequencyPlaying, BK1080_GetFreqLoLimit(gEeprom.FM_Band))) { if (!FM_CheckFrequencyLock(gEeprom.FM_FrequencyPlaying, BK1080_GetFreqLoLimit(gEeprom.FM_Band))) {
if (!gFM_AutoScan) { if (!gFM_AutoScan) {
gFmPlayCountdown_10ms = 0; gFmPlayCountdown_10ms = 0;
@@ -609,8 +607,7 @@ void FM_Play(void)
GUI_SelectNextDisplay(DISPLAY_FM); GUI_SelectNextDisplay(DISPLAY_FM);
} }
void FM_Start(void) void FM_Start(void) {
{
gDualWatchActive = false; gDualWatchActive = false;
gFmRadioMode = true; gFmRadioMode = true;
gFM_ScanState = FM_SCAN_OFF; gFM_ScanState = FM_SCAN_OFF;
@@ -623,10 +620,10 @@ void FM_Start(void)
gEnableSpeaker = true; gEnableSpeaker = true;
gUpdateStatus = true; gUpdateStatus = true;
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE #ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
gEeprom.CURRENT_STATE = 3; gEeprom.CURRENT_STATE = 3;
SETTINGS_WriteCurrentState(); SETTINGS_WriteCurrentState();
#endif #endif
} }
#endif #endif

427
app/fskmodem.c Normal file
View File

@@ -0,0 +1,427 @@
//
// Created by bruno on 25.2.2025.
//
#include "fskmodem.h"
//#include "messages.h"
#include "driver/uart.h"
#include "../ui/messages.h"
uint16_t TONE2_FREQ;
DataPacket dataPacket;
DataPacket inBoundPacket;
uint8_t *dataPTR = dataPacket.data;
SMSEnteringState gEnteringSMS = SMS_NOT_ENTERING;
SMSResponseState gSMSResponseState = SMS_RESPONSE_IDLE;
bool gGotACK = false;
uint8_t SMSResponseCounter = 0;
typedef enum {
Receiving,
Ready
} RXState;
RXState rxState = Ready;
uint8_t SMSResponseCounterTarget = 6;
void FSKModem_TimeSlice500ms(void) {
if (SMSResponseCounter && FUNCTION_IsRx() && SMSResponseCounter++ > SMSResponseCounterTarget) {
switch (gSMSResponseState) {
case SMS_RESPONSE_ACK:
MSG_FSKSendData(&inBoundPacket);
gSMSResponseState = SMS_RESPONSE_IDLE;
SMSResponseCounter = 0;
break;
case SMS_RESPONSE_RETRANSMIT:
MSG_FSKSendData(&inBoundPacket);
gSMSResponseState = SMS_RESPONSE_IDLE;
SMSResponseCounter = 0;
break;
case SMS_RESPONSE_RESEND:
MSG_FSKSendData(&dataPacket);
gSMSResponseState = SMS_RESPONSE_IDLE;
SMSResponseCounter = 0;
break;
case SMS_RESPONSE_ACK_LIGHT:
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false);
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
gSMSResponseState = SMS_RESPONSE_IDLE;
SMSResponseCounter = 0;
break;
default:
break;
}
}
}
void MSG_ConfigureFSK(bool rx) {
BK4819_WriteRegister(BK4819_REG_70, TONE2_ENABLE_BIT | (96U << 0));
switch (gEeprom.FSKMode) {
case MOD_AFSK_2400:
TONE2_FREQ = 24779U; // Estimated
break;
case MOD_AFSK_1200:
TONE2_FREQ = 12389U;
break;
case MOD_FSK_700:
TONE2_FREQ = 7227U;
break;
case MOD_FSK_450:
TONE2_FREQ = 4646U;
break;
case MOD_FSK_1200_2400:
TONE2_FREQ = 12389U; // Default to 1200Hz, dynamic switching may be required
break;
case MOD_NOAA_SAME:
TONE2_FREQ = 2083U; // NOAA SAME uses 2083.3 Hz for mark and 1562.5 Hz for space
break;
}
BK4819_WriteRegister(BK4819_REG_72, TONE2_FREQ);
// uint16_t fskConfig = FSK_ENABLE_BIT | FSK_RX_BW_1_2K | FSK_RX_GAIN_DEFAULT | FSK_PREAMBLE_TYPE_AA;
// if (gEeprom.FSKMode == MOD_AFSK_1200) {
// fskConfig = FSK_ENABLE_BIT | FSK_TX_MODE_FSK_1_2K_2_4K | FSK_RX_MODE_FSK_1_2K_2_4K_NOAA;
// }
uint16_t fskConfig = FSK_ENABLE_BIT | FSK_PREAMBLE_TYPE_AA;
switch (gEeprom.FSKMode) {
case MOD_FSK_700:
case MOD_FSK_450:
case MOD_FSK_1200_2400:
fskConfig |= FSK_TX_MODE_FSK_1_2K_2_4K | FSK_RX_MODE_FSK_1_2K_2_4K_NOAA | FSK_RX_BW_1_2K;
break;
case MOD_AFSK_1200:
fskConfig |= FSK_TX_MODE_FFSK_1200_1800 | FSK_RX_MODE_FFSK_1200_1800 | FSK_RX_BW_FFSK_1200_1800;
break;
case MOD_AFSK_2400:
fskConfig |= FSK_TX_MODE_FFSK_1200_2400 | FSK_RX_MODE_FFSK_1200_2400 | FSK_RX_BW_2_4K_FFSK_1200_2400;
break;
case MOD_NOAA_SAME:
fskConfig |= FSK_TX_MODE_NOAA_SAME | FSK_RX_MODE_FSK_1_2K_2_4K_NOAA | FSK_RX_BW_NOAA_SAME;
break;
default:
// Unsupported mode; keep previous setting
break;
}
BK4819_WriteRegister(BK4819_REG_58, fskConfig);
BK4819_WriteRegister(BK4819_REG_5A, FSK_SYNC_BYTE0 << 8 | FSK_SYNC_BYTE1);
BK4819_WriteRegister(BK4819_REG_5B, FSK_SYNC_BYTE2 << 8 | FSK_SYNC_BYTE3);
BK4819_WriteRegister(BK4819_REG_5C, FSK_CRC_ON);
if (rx) {
BK4819_WriteRegister(BK4819_REG_5E, (64U << 3) | (1U << 0));
}
size_t size = sizeof(dataPacket);
if (rx) {
size = (((size + 1) / 2) * 2) + 2;
}
BK4819_WriteRegister(BK4819_REG_5D, (size << 8));
BK4819_FskClearFifo();
uint16_t fskParams = FSK_SYNC_LEN_BIT | ((rx ? 0U : 15U) << 4);
if (gCurrentVfo->SCRAMBLING_TYPE > 0) {
fskParams |= FSK_SCRAMBLE_ENABLE;
}
BK4819_WriteRegister(BK4819_REG_59, fskParams);
BK4819_WriteRegister(BK4819_REG_02, 0);
}
uint16_t calculateCRC(uint8_t *data, size_t length) {
uint16_t crc = 0xFFFF; // Example CRC-16 initialization
for (size_t i = 0; i < length; i++) {
crc ^= data[i];
for (uint8_t j = 0; j < 8; j++) {
if (crc & 1) {
crc = (crc >> 1) ^ 0xA001; // Example polynomial (CRC-16-IBM)
} else {
crc >>= 1;
}
}
}
return crc;
}
void processReceivedPacket(DataPacket *packet) {
char String[18];
char numBuf[11]; // Enough for any 64-bit unsigned integer
const unsigned int vfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO
: gEeprom.TX_VFO;
UART_Send(packet, sizeof(DataPacket));
if (packet->dest == gEeprom.FSKSRCAddress) {
if ((packet->flags & 0x80)) {
if (packet->flags & 0x40) {
uint16_t crcSent = calculateCRC(dataPacket.data, 20);
uint16_t crcGot = inBoundPacket.data[0] | (inBoundPacket.data[1] << 8);
if (crcSent == crcGot) {
gGotACK = true;
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true);
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, true);
SMSResponseCounter = 1;
gSMSResponseState = SMS_RESPONSE_ACK_LIGHT;
} else {
if (--dataPacket.ttl) {
gSMSResponseState = SMS_RESPONSE_RESEND;
SMSResponseCounter = 1;
}
}
} else {
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP);
BK4819_PlaySingleTone(1000, 250, 127, true);
strcpy(String, "SMS by ");
itoa(packet->src, numBuf); // Convert number to string
strcat(String, numBuf);
MESSAGES_SAVE();
UI_DisplayPopup(String);
inBoundPacket.flags |= 0x40;
inBoundPacket.dest = inBoundPacket.src;
inBoundPacket.src = gEeprom.FSKSRCAddress;
uint16_t crcTest = calculateCRC(inBoundPacket.data, 20);
memset(inBoundPacket.data, 0, DataPacketDataSize);
inBoundPacket.data[0] = crcTest & 0xFF;
inBoundPacket.data[1] = (crcTest >> 8) & 0xFF;
gSMSResponseState = SMS_RESPONSE_ACK;
SMSResponseCounter = 1;
UI_PrintStringSmallNormal(String, 2, 0, 4);
}
}
} else if (VfoState[vfo] == VFO_STATE_NORMAL && !TX_freq_check(gCurrentVfo->freq_config_TX.Frequency)) {
if (packet->ttl--) {
SMSResponseCounter = 1;
gSMSResponseState = SMS_RESPONSE_RETRANSMIT;
}
}
}
void MSG_EnableRX(const bool enable) {
if (enable) {
MSG_ConfigureFSK(true);
//if(gEeprom.MESSENGER_CONFIG.data.receive)
BK4819_FskEnableRx();
} else {
BK4819_WriteRegister(BK4819_REG_70, 0);
BK4819_WriteRegister(BK4819_REG_58, 0);
}
}
void MSG_FSKSendData(DataPacket *dataPacketIn) {
const unsigned int vfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO
: gEeprom.TX_VFO;
if (VfoState[vfo] == VFO_STATE_NORMAL &&
!TX_freq_check(gCurrentVfo->freq_config_TX.Frequency)) {
RADIO_PrepareTX();
BK4819_SetScramble(gCurrentVfo->SCRAMBLING_TYPE);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true);
bool isAudioOn = gEnableSpeaker;
if (gEnableSpeaker) {
AUDIO_AudioPathOff();
BK4819_EnterTxMute();
gEnableSpeaker = false;
}
// turn off CTCSS/CDCSS during FFSK
const uint16_t css_val = BK4819_ReadRegister(BK4819_REG_51);
BK4819_WriteRegister(BK4819_REG_51, 0);
// set the FM deviation level
const uint16_t dev_val = BK4819_ReadRegister(BK4819_REG_40);
{
uint16_t deviation;
switch (gEeprom.VfoInfo[gEeprom.TX_VFO].CHANNEL_BANDWIDTH) {
case BK4819_FILTER_BW_WIDE:
deviation = 1300;
break; // 20k // measurements by kamilsss655
case BK4819_FILTER_BW_NARROW:
deviation = 1200;
break; // 10k
// case BK4819_FILTER_BW_NARROWAVIATION: deviation = 850; break; // 5k
// case BK4819_FILTER_BW_NARROWER: deviation = 850; break; // 5k
// case BK4819_FILTER_BW_NARROWEST: deviation = 850; break; // 5k
default:
deviation = 850;
break; // 5k
}
//BK4819_WriteRegister(0x40, (3u << 12) | (deviation & 0xfff));
BK4819_WriteRegister(BK4819_REG_40, (dev_val & 0xf000) | (deviation & 0xfff));
}
// REG_2B 0
//
// <15> 1 Enable CTCSS/CDCSS DC cancellation after FM Demodulation 1 = enable 0 = disable
// <14> 1 Enable AF DC cancellation after FM Demodulation 1 = enable 0 = disable
// <10> 0 AF RX HPF 300Hz filter 0 = enable 1 = disable
// <9> 0 AF RX LPF 3kHz filter 0 = enable 1 = disable
// <8> 0 AF RX de-emphasis filter 0 = enable 1 = disable
// <2> 0 AF TX HPF 300Hz filter 0 = enable 1 = disable
// <1> 0 AF TX LPF filter 0 = enable 1 = disable
// <0> 0 AF TX pre-emphasis filter 0 = enable 1 = disable
//
// disable the 300Hz HPF and FM pre-emphasis filter
//
const uint16_t filt_val = BK4819_ReadRegister(BK4819_REG_2B);
BK4819_WriteRegister(BK4819_REG_2B, (1u << 2) | (1u << 0));
MSG_ConfigureFSK(false);
SYSTEM_DelayMs(100);
{ // load the entire packet data into the TX FIFO buffer
uint16_t *ptr = (uint16_t *) dataPacketIn;
size_t wordCount = sizeof(*dataPacketIn) / sizeof(uint16_t);
for (size_t i = 0; i < wordCount; i++) {
BK4819_WriteRegister(BK4819_REG_5F, ptr[i]);
}
}
// enable FSK TX
BK4819_FskEnableTx();
{
// allow up to 310ms for the TX to complete
// if it takes any longer then somethings gone wrong, we shut the TX down
unsigned int timeout = 1000 / 5;
while (timeout-- > 0) {
SYSTEM_DelayMs(5);
if (BK4819_ReadRegister(BK4819_REG_0C) & (1u << 0)) { // we have interrupt flags
BK4819_WriteRegister(BK4819_REG_02, 0);
if (BK4819_ReadRegister(BK4819_REG_02) & BK4819_REG_02_FSK_TX_FINISHED)
timeout = 0; // TX is complete
}
}
}
//BK4819_WriteRegister(BK4819_REG_02, 0);
SYSTEM_DelayMs(100);
// disable TX
MSG_ConfigureFSK(true);
// restore FM deviation level
BK4819_WriteRegister(BK4819_REG_40, dev_val);
// restore TX/RX filtering
BK4819_WriteRegister(BK4819_REG_2B, filt_val);
// restore the CTCSS/CDCSS setting
BK4819_WriteRegister(BK4819_REG_51, css_val);
SYSTEM_DelayMs(50);
APP_EndTransmission();
FUNCTION_Select(FUNCTION_FOREGROUND);
gUpdateStatus = true;
gUpdateDisplay = true;
gFlagEndTransmission = false;
if (isAudioOn) {
AUDIO_AudioPathOn();
gEnableSpeaker = true;
BK4819_ExitTxMute();
}
if (!(dataPacketIn->flags & 0x64)) {
gGotACK = false;
}
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false);
MSG_EnableRX(true);
gVfoConfigureMode = VFO_CONFIGURE;
dataPTR = dataPacket.data;
}
}
void prepareDataPacket() {
dataPacket.src = gEeprom.FSKSRCAddress;
uint8_t Data[8];
EEPROM_ReadBuffer(SEQParameterEEPROM, Data, 8);
dataPacket.seq = Data[0];
Data[0]++;
EEPROM_WriteBuffer(SEQParameterEEPROM, Data);
dataPacket.ttl = 20;
}
void FSK_HANDLE_IRQ(unsigned short irq) {
//const uint16_t rx_sync_flags = BK4819_ReadRegister(BK4819_REG_0B);
const bool rx_sync = (irq & BK4819_REG_02_FSK_RX_SYNC) != 0;
const bool rx_fifo_almost_full = (irq & BK4819_REG_02_FSK_FIFO_ALMOST_FULL) != 0;
const bool rx_finished = (irq & BK4819_REG_02_FSK_RX_FINISHED) != 0;
//UART_printf("\nMSG : S%i, F%i, E%i | %i", rx_sync, rx_fifo_almost_full, rx_finished, irq);
if (rx_sync) {
// prevent listening to fsk data and squelch (kamilsss655)
// CTCSS codes seem to false trigger the rx_sync
if (gCurrentCodeType == CODE_TYPE_OFF)
AUDIO_AudioPathOff();
gFSKWriteIndex = 0;
memset(&inBoundPacket, 0, sizeof(DataPacket));
rxState = Receiving;
}
if (rx_fifo_almost_full && rxState == Receiving) {
const uint16_t count = BK4819_ReadRegister(BK4819_REG_5E) & (7u << 0); // Almost full threshold
uint16_t *ptr = (uint16_t *) &inBoundPacket;
size_t wordCount = sizeof(inBoundPacket) / sizeof(uint16_t);
for (uint16_t i = 0; i < count && gFSKWriteIndex < wordCount; i++) {
ptr[gFSKWriteIndex++] = BK4819_ReadRegister(BK4819_REG_5F);
UART_Send((const void *) &ptr[gFSKWriteIndex - 1], 2);
}
SYSTEM_DelayMs(10);
}
if (rx_finished) {
// Turn off green LED
BK4819_FskClearFifo();
rxState = Ready;
if (gFSKWriteIndex > 2) {
// Validate checksum (assuming last 2 bytes are CRC-16)
//size_t dataLength = sizeof(inBoundPacket.data) - 2;
//uint16_t receivedCRC = (inBoundPacket.data[dataLength] << 8) | inBoundPacket.data[dataLength + 1];
//uint16_t calculatedCRC = calculateCRC(inBoundPacket.data, dataLength);
//if (receivedCRC == calculatedCRC) {
processReceivedPacket(&inBoundPacket);
//}
}
APP_EndTransmission();
FUNCTION_Select(FUNCTION_FOREGROUND);
gUpdateStatus = true;
gUpdateDisplay = true;
gFlagEndTransmission = false;
gFSKWriteIndex = 0;
}
}

135
app/fskmodem.h Normal file
View File

@@ -0,0 +1,135 @@
//
// Created by bruno on 25.2.2025.
//
#ifndef UV_K5_FIRMWARE_CUSTOM_FSKMODEM_H
#define UV_K5_FIRMWARE_CUSTOM_FSKMODEM_H
#include <stdint.h>
#include <stdbool.h>
#include "../driver/bk4819.h"
#include "../driver/bk4819-regs.h"
#include "../settings.h"
#include "stddef.h"
#include "../driver/system.h"
#include "../misc.h"
#include "../app/app.h"
#include <string.h>
#include "../audio.h"
#include <stdio.h>
#include "../ui/helper.h"
#include "../ui/main.h"
// REG_70 bit definitions
#define TONE1_ENABLE_BIT (1U << 15)
#define TONE1_GAIN_MASK (0x7FU << 8)
#define TONE2_ENABLE_BIT (1U << 7)
#define TONE2_GAIN_MASK (0x7FU << 0)
// REG_58 bit definitions
// FSK Tx Mode Selection (REG_58<15:13>)
#define FSK_TX_MODE_FSK_1_2K_2_4K (0U << 13) // 000
#define FSK_TX_MODE_FFSK_1200_1800 (1U << 13) // 001
#define FSK_TX_MODE_FFSK_1200_2400 (3U << 13) // 011
#define FSK_TX_MODE_NOAA_SAME (5U << 13) // 101
// FSK Rx Mode Selection (REG_58<12:10>)
#define FSK_RX_MODE_FSK_1_2K_2_4K_NOAA (0U << 10) // 000
#define FSK_RX_MODE_FFSK_1200_1800 (7U << 10) // 111
#define FSK_RX_MODE_FFSK_1200_2400 (4U << 10) // 100
// FSK Rx Gain (REG_58<9:8>)
#define FSK_RX_GAIN_DEFAULT (0U << 8) // 00
#define FSK_RX_GAIN_TYPE_C (1U << 8) // 01
#define FSK_RX_GAIN_TYPE_B (2U << 8) // 10
#define FSK_UNKNOWN_MASK (3U << 6)
// FSK Preamble Type Selection (REG_58<5:4>)
#define FSK_PREAMBLE_TYPE_AA (3U << 4) // 11
#define FSK_PREAMBLE_TYPE_55 (2U << 4) // 10
#define FSK_PREAMBLE_TYPE_UNKNOWN (0U << 4) // 00
// FSK Rx Bandwidth Setting (REG_58<3:1>)
#define FSK_RX_BW_2_4K_FFSK_1200_2400 (4U << 1) // 100
#define FSK_RX_BW_1_2K (0U << 1) // 000
#define FSK_RX_BW_FFSK_1200_1800 (1U << 1) // 001
#define FSK_RX_BW_NOAA_SAME (2U << 1) // 010
#define FSK_ENABLE_BIT (1U << 0)
// REG_59 bit definitions
#define FSK_CLEAR_TX_FIFO (1U << 15)
#define FSK_CLEAR_RX_FIFO (1U << 14)
#define FSK_SCRAMBLE_ENABLE (1U << 13)
#define FSK_RX_ENABLE (1U << 12)
#define FSK_TX_ENABLE (1U << 11)
#define FSK_INVERT_RX (1U << 10)
#define FSK_INVERT_TX (1U << 9)
#define FSK_PREAMBLE_LEN_MASK (15U << 4)
#define FSK_SYNC_LEN_BIT (1U << 3)
//#define FSK_SYNC_BYTE0 0x30
//#define FSK_SYNC_BYTE1 0x72
//#define FSK_SYNC_BYTE2 0x57
//#define FSK_SYNC_BYTE3 0x6c
#define FSK_SYNC_BYTE0 0x42
#define FSK_SYNC_BYTE1 0x52
#define FSK_SYNC_BYTE2 0x4E
#define FSK_SYNC_BYTE3 0x51
#define FSK_CRC_ON (1U << 6)
#define FSK_CRC_OFF (0U << 6)
#define DataPacketDataSize (21)
#define SEQParameterEEPROM 0x1BD0
typedef struct {
uint32_t dest; //4bytes
uint32_t src; //4bytes
uint8_t seq; //1bytes
uint8_t ttl; //1bytes
uint8_t flags; //1bytes
uint8_t data[DataPacketDataSize];
} DataPacket;
void prepareDataPacket();
void MSG_FSKSendData(DataPacket *dataPacketIn);
void MSG_EnableRX(bool enable);
void processReceivedPacket(DataPacket *packet);
uint16_t calculateCRC(uint8_t *data, size_t length);
extern DataPacket dataPacket;
extern DataPacket inBoundPacket;
typedef enum {
SMS_NOT_ENTERING = 0,
SMS_ENTERING_DEST,
SMS_ENTERING_MESSAGE
} SMSEnteringState;
typedef enum {
SMS_RESPONSE_IDLE,
SMS_RESPONSE_ACK,
SMS_RESPONSE_ACK_LIGHT,
SMS_RESPONSE_RETRANSMIT,
SMS_RESPONSE_RESEND
} SMSResponseState;
extern SMSEnteringState gEnteringSMS;
extern SMSResponseState gSMSResponseState;
extern uint8_t *dataPTR;
extern bool gGotACK;
extern uint8_t SMSResponseCounter;
void FSK_HANDLE_IRQ(unsigned short irq);
void FSKModem_TimeSlice500ms(void);
#endif //UV_K5_FIRMWARE_CUSTOM_FSKMODEM_H

View File

@@ -20,15 +20,21 @@
#include "app/app.h" #include "app/app.h"
#include "app/chFrScanner.h" #include "app/chFrScanner.h"
#include "app/common.h" #include "app/common.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h"
#include "app/fm.h"
#endif #endif
#include "app/generic.h" #include "app/generic.h"
#include "app/main.h" #include "app/main.h"
#include "app/scanner.h" #include "app/scanner.h"
#ifdef ENABLE_SPECTRUM #ifdef ENABLE_SPECTRUM
#include "app/spectrum.h" #include "app/spectrum.h"
#endif #endif
#include "audio.h" #include "audio.h"
@@ -43,32 +49,31 @@
#include "ui/ui.h" #include "ui/ui.h"
#include <stdlib.h> #include <stdlib.h>
static void toggle_chan_scanlist(void) static void toggle_chan_scanlist(void) { // toggle the selected channels scanlist setting
{ // toggle the selected channels scanlist setting
if (SCANNER_IsScanning()) if (SCANNER_IsScanning())
return; return;
if(!IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) { if (!IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
#ifdef ENABLE_SCAN_RANGES #ifdef ENABLE_SCAN_RANGES
gScanRangeStart = gScanRangeStart ? 0 : gTxVfo->pRX->Frequency; gScanRangeStart = gScanRangeStart ? 0 : gTxVfo->pRX->Frequency;
gScanRangeStop = gEeprom.VfoInfo[!gEeprom.TX_VFO].freq_config_RX.Frequency; gScanRangeStop = gEeprom.VfoInfo[!gEeprom.TX_VFO].freq_config_RX.Frequency;
if(gScanRangeStart > gScanRangeStop) if (gScanRangeStart > gScanRangeStop)
SWAP(gScanRangeStart, gScanRangeStop); SWAP(gScanRangeStart, gScanRangeStop);
#endif #endif
return; return;
} }
// Remove exclude // Remove exclude
if(gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] == true) if (gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] == true) {
{
gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] = false; gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] = false;
return; return;
} }
uint8_t scanTmp = gTxVfo->SCANLIST1_PARTICIPATION | (gTxVfo->SCANLIST2_PARTICIPATION << 1) | (gTxVfo->SCANLIST3_PARTICIPATION << 2); uint8_t scanTmp = gTxVfo->SCANLIST1_PARTICIPATION | (gTxVfo->SCANLIST2_PARTICIPATION << 1) |
(gTxVfo->SCANLIST3_PARTICIPATION << 2);
scanTmp = (scanTmp++ < 7) ? scanTmp: 0; scanTmp = (scanTmp++ < 7) ? scanTmp : 0;
gTxVfo->SCANLIST1_PARTICIPATION = (scanTmp >> 0) & 0x01; gTxVfo->SCANLIST1_PARTICIPATION = (scanTmp >> 0) & 0x01;
gTxVfo->SCANLIST2_PARTICIPATION = (scanTmp >> 1) & 0x01; gTxVfo->SCANLIST2_PARTICIPATION = (scanTmp >> 1) & 0x01;
@@ -80,8 +85,7 @@ static void toggle_chan_scanlist(void)
gFlagResetVfos = true; gFlagResetVfos = true;
} }
static void processFKeyFunction(const KEY_Code_t Key, const bool beep) static void processFKeyFunction(const KEY_Code_t Key, const bool beep) {
{
uint8_t Vfo = gEeprom.TX_VFO; uint8_t Vfo = gEeprom.TX_VFO;
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS #ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
@@ -106,9 +110,9 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
switch (Key) { switch (Key) {
case KEY_0: case KEY_0:
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
ACTION_FM(); ACTION_FM();
#endif #endif
break; break;
case KEY_1: case KEY_1:
@@ -126,16 +130,14 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
if (gScanStateDir != SCAN_OFF) { if (gScanStateDir != SCAN_OFF) {
if (gCurrentFunction != FUNCTION_INCOMING || if (gCurrentFunction != FUNCTION_INCOMING ||
gRxReceptionMode == RX_MODE_NONE || gRxReceptionMode == RX_MODE_NONE ||
gScanPauseDelayIn_10ms == 0) gScanPauseDelayIn_10ms == 0) { // scan is running (not paused)
{ // scan is running (not paused)
return; return;
} }
} }
const uint8_t vfo = gEeprom.TX_VFO; const uint8_t vfo = gEeprom.TX_VFO;
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo])) if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo])) { // copy channel to VFO, then swap to the VFO
{ // copy channel to VFO, then swap to the VFO
gEeprom.ScreenChannel[vfo] = FREQ_CHANNEL_FIRST + gEeprom.VfoInfo[vfo].Band; gEeprom.ScreenChannel[vfo] = FREQ_CHANNEL_FIRST + gEeprom.VfoInfo[vfo].Band;
gEeprom.VfoInfo[vfo].CHANNEL_SAVE = gEeprom.ScreenChannel[vfo]; gEeprom.VfoInfo[vfo].CHANNEL_SAVE = gEeprom.ScreenChannel[vfo];
@@ -156,17 +158,17 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
} }
#ifdef ENABLE_WIDE_RX #ifdef ENABLE_WIDE_RX
if(gTxVfo->Band == BAND7_470MHz && gTxVfo->pRX->Frequency < _1GHz_in_KHz) { if (gTxVfo->Band == BAND7_470MHz && gTxVfo->pRX->Frequency < _1GHz_in_KHz) {
gTxVfo->pRX->Frequency = _1GHz_in_KHz; gTxVfo->pRX->Frequency = _1GHz_in_KHz;
return; return;
} }
#endif #endif
gTxVfo->Band += 1; gTxVfo->Band += 1;
if (gTxVfo->Band == BAND5_350MHz && !gSetting_350EN) { if (gTxVfo->Band == BAND5_350MHz) {
// skip if not enabled // skip if not enabled
gTxVfo->Band += 1; gTxVfo->Band += 1;
} else if (gTxVfo->Band >= BAND_N_ELEM){ } else if (gTxVfo->Band >= BAND_N_ELEM) {
// go arround if overflowed // go arround if overflowed
gTxVfo->Band = BAND1_50MHz; gTxVfo->Band = BAND1_50MHz;
} }
@@ -185,18 +187,18 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break; break;
case KEY_2: case KEY_2:
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
gVfoConfigureMode = VFO_CONFIGURE; gVfoConfigureMode = VFO_CONFIGURE;
#endif #endif
COMMON_SwitchVFOs(); COMMON_SwitchVFOs();
if (beep) if (beep)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
break; break;
case KEY_3: case KEY_3:
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
gVfoConfigureMode = VFO_CONFIGURE; gVfoConfigureMode = VFO_CONFIGURE;
#endif #endif
COMMON_SwitchVFOMode(); COMMON_SwitchVFOMode();
if (beep) if (beep)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
@@ -217,7 +219,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break; break;
case KEY_5: case KEY_5:
if(beep) { if (beep) {
#ifdef ENABLE_NOAA #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]; gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_VFO];
@@ -234,8 +236,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
APP_RunSpectrum(); APP_RunSpectrum();
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
#endif #endif
} } else {
else {
toggle_chan_scanlist(); toggle_chan_scanlist();
} }
@@ -254,7 +255,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break; break;
case KEY_8: case KEY_8:
gTxVfo->FrequencyReverse = gTxVfo->FrequencyReverse == false; gTxVfo->FrequencyReverse = !gTxVfo->FrequencyReverse;
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
break; break;
@@ -278,24 +279,22 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
#ifdef ENABLE_FEAT_F4HWN // Set Squelch F + UP or Down and Step F + SIDE1 or F + SIDE2 #ifdef ENABLE_FEAT_F4HWN // Set Squelch F + UP or Down and Step F + SIDE1 or F + SIDE2
case KEY_UP: case KEY_UP:
gEeprom.SQUELCH_LEVEL = (gEeprom.SQUELCH_LEVEL < 9) ? gEeprom.SQUELCH_LEVEL + 1: 9; gEeprom.SQUELCH_LEVEL = (gEeprom.SQUELCH_LEVEL < 9) ? gEeprom.SQUELCH_LEVEL + 1 : 9;
gVfoConfigureMode = VFO_CONFIGURE; gVfoConfigureMode = VFO_CONFIGURE;
gWasFKeyPressed = false; gWasFKeyPressed = false;
break; break;
case KEY_DOWN: case KEY_DOWN:
gEeprom.SQUELCH_LEVEL = (gEeprom.SQUELCH_LEVEL > 0) ? gEeprom.SQUELCH_LEVEL - 1: 0; gEeprom.SQUELCH_LEVEL = (gEeprom.SQUELCH_LEVEL > 0) ? gEeprom.SQUELCH_LEVEL - 1 : 0;
gVfoConfigureMode = VFO_CONFIGURE; gVfoConfigureMode = VFO_CONFIGURE;
gWasFKeyPressed = false; gWasFKeyPressed = false;
break; break;
case KEY_SIDE1: case KEY_SIDE1:
uint8_t a = FREQUENCY_GetSortedIdxFromStepIdx(gTxVfo->STEP_SETTING); uint8_t a = FREQUENCY_GetSortedIdxFromStepIdx(gTxVfo->STEP_SETTING);
if (a < STEP_N_ELEM - 1) if (a < STEP_N_ELEM - 1) {
{
gTxVfo->STEP_SETTING = FREQUENCY_GetStepIdxFromSortedIdx(a + 1); gTxVfo->STEP_SETTING = FREQUENCY_GetStepIdxFromSortedIdx(a + 1);
} }
if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
{
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
} }
gVfoConfigureMode = VFO_CONFIGURE; gVfoConfigureMode = VFO_CONFIGURE;
@@ -303,12 +302,10 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break; break;
case KEY_SIDE2: case KEY_SIDE2:
uint8_t b = FREQUENCY_GetSortedIdxFromStepIdx(gTxVfo->STEP_SETTING); uint8_t b = FREQUENCY_GetSortedIdxFromStepIdx(gTxVfo->STEP_SETTING);
if (b > 0) if (b > 0) {
{
gTxVfo->STEP_SETTING = FREQUENCY_GetStepIdxFromSortedIdx(b - 1); gTxVfo->STEP_SETTING = FREQUENCY_GetStepIdxFromSortedIdx(b - 1);
} }
if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
{
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
} }
gVfoConfigureMode = VFO_CONFIGURE; gVfoConfigureMode = VFO_CONFIGURE;
@@ -326,8 +323,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
} }
} }
void channelMove(uint16_t Channel) void channelMove(uint16_t Channel) {
{
const uint8_t Vfo = gEeprom.TX_VFO; const uint8_t Vfo = gEeprom.TX_VFO;
if (!RADIO_CheckValidChannel(Channel, false, 0)) { if (!RADIO_CheckValidChannel(Channel, false, 0)) {
@@ -340,19 +336,17 @@ void channelMove(uint16_t Channel)
gBeepToPlay = BEEP_NONE; gBeepToPlay = BEEP_NONE;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
#endif #endif
gEeprom.MrChannel[Vfo] = (uint8_t)Channel; gEeprom.MrChannel[Vfo] = (uint8_t) Channel;
gEeprom.ScreenChannel[Vfo] = (uint8_t)Channel; gEeprom.ScreenChannel[Vfo] = (uint8_t) Channel;
//gRequestSaveVFO = true; //gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD; gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
gRemoveOffset = false; gRemoveOffset = false;
gPowerHigh = false; gPowerHigh = false;
#endif
RADIO_ConfigureChannel(gEeprom.TX_VFO, gVfoConfigureMode); RADIO_ConfigureChannel(gEeprom.TX_VFO, gVfoConfigureMode);
@@ -400,8 +394,7 @@ void channelMoveSwitch(void) {
} }
} }
static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
{
if (bKeyHeld) { // key held down if (bKeyHeld) { // key held down
if (bKeyPressed) { if (bKeyPressed) {
if (gScreenToDisplay == DISPLAY_MAIN) { if (gScreenToDisplay == DISPLAY_MAIN) {
@@ -419,21 +412,20 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
return; return;
} }
if (bKeyPressed) if (bKeyPressed) { // key is pressed
{ // key is pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; // beep when key is pressed gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; // beep when key is pressed
return; // don't use the key till it's released return; // don't use the key till it's released
} }
if (!gWasFKeyPressed) { // F-key wasn't pressed if (!gWasFKeyPressed) { // F-key wasn't pressed
if (gScanStateDir != SCAN_OFF){ if (gScanStateDir != SCAN_OFF) {
switch(Key) { switch (Key) {
case KEY_0...KEY_5: case KEY_0...KEY_5:
gEeprom.SCAN_LIST_DEFAULT = Key; gEeprom.SCAN_LIST_DEFAULT = Key;
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE #ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
SETTINGS_WriteCurrentState(); SETTINGS_WriteCurrentState();
#endif #endif
break; break;
default: default:
break; break;
@@ -453,9 +445,9 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gKeyInputCountdown = (key_input_timeout_500ms / 4); // short time... gKeyInputCountdown = (key_input_timeout_500ms / 4); // short time...
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
#endif #endif
return; return;
} }
@@ -463,8 +455,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
// #ifdef ENABLE_NOAA // #ifdef ENABLE_NOAA
// if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) // if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
// #endif // #endif
if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) { // user is entering a frequency
{ // user is entering a frequency
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
@@ -479,7 +470,8 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
return; return;
} }
gKeyInputCountdown = (gInputBoxIndex == totalDigits) ? (key_input_timeout_500ms / 16) : (key_input_timeout_500ms / 3); gKeyInputCountdown = (gInputBoxIndex == totalDigits) ? (key_input_timeout_500ms / 16) : (
key_input_timeout_500ms / 3);
const char *inputStr = INPUTBOX_GetAscii(); const char *inputStr = INPUTBOX_GetAscii();
uint8_t inputLength = gInputBoxIndex; uint8_t inputLength = gInputBoxIndex;
@@ -500,12 +492,10 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
// clamp the frequency entered to some valid value // clamp the frequency entered to some valid value
if (Frequency < frequencyBandTable[0].lower) { if (Frequency < frequencyBandTable[0].lower) {
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; const uint32_t center = (BX4819_band1.upper + BX4819_band2.lower) / 2;
Frequency = (Frequency < center) ? BX4819_band1.upper : BX4819_band2.lower; 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; Frequency = frequencyBandTable[BAND_N_ELEM - 1].upper;
} }
@@ -523,8 +513,8 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
Frequency = FREQUENCY_RoundToStep(Frequency, gTxVfo->StepFrequency); Frequency = FREQUENCY_RoundToStep(Frequency, gTxVfo->StepFrequency);
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) if (Frequency >= BX4819_band1.upper &&
{ // clamp the frequency to the limit Frequency < BX4819_band2.lower) { // clamp the frequency to the limit
const uint32_t center = (BX4819_band1.upper + BX4819_band2.lower) / 2; const uint32_t center = (BX4819_band1.upper + BX4819_band2.lower) / 2;
Frequency = (Frequency < center) ? BX4819_band1.upper - gTxVfo->StepFrequency : BX4819_band2.lower; Frequency = (Frequency < center) ? BX4819_band1.upper - gTxVfo->StepFrequency : BX4819_band2.lower;
} }
@@ -535,14 +525,14 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
return; return;
} }
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
else else
if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // user is entering NOAA channel { // user is entering NOAA channel
if (gInputBoxIndex != 2) { if (gInputBoxIndex != 2) {
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
#endif #endif
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
return; return;
} }
@@ -552,9 +542,9 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
uint8_t Channel = (gInputBox[0] * 10) + gInputBox[1]; uint8_t Channel = (gInputBox[0] * 10) + gInputBox[1];
if (Channel >= 1 && Channel <= ARRAY_SIZE(NoaaFrequencyTable)) { if (Channel >= 1 && Channel <= ARRAY_SIZE(NoaaFrequencyTable)) {
Channel += NOAA_CHANNEL_FIRST; Channel += NOAA_CHANNEL_FIRST;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
#endif #endif
gEeprom.NoaaChannel[Vfo] = Channel; gEeprom.NoaaChannel[Vfo] = Channel;
gEeprom.ScreenChannel[Vfo] = Channel; gEeprom.ScreenChannel[Vfo] = Channel;
gRequestSaveVFO = true; gRequestSaveVFO = true;
@@ -562,7 +552,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
return; return;
} }
} }
#endif #endif
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
@@ -572,13 +562,10 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gWasFKeyPressed = false; gWasFKeyPressed = false;
gUpdateStatus = true; gUpdateStatus = true;
if(Key == 8) if (Key == 8) {
{
ACTION_BackLightOnDemand(); ACTION_BackLightOnDemand();
return; return;
} } else if (Key == 9) {
else if(Key == 9)
{
ACTION_BackLight(); ACTION_BackLight();
return; return;
} }
@@ -586,8 +573,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
processFKeyFunction(Key, true); processFKeyFunction(Key, true);
} }
static void MAIN_Key_EXIT(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; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
@@ -615,8 +601,7 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
if (gInputBoxIndex == 0) if (gInputBoxIndex == 0)
gAnotherVoiceID = VOICE_ID_CANCEL; gAnotherVoiceID = VOICE_ID_CANCEL;
#endif #endif
} } else {
else {
gScanKeepResult = false; gScanKeepResult = false;
CHFRSCANNER_Stop(); CHFRSCANNER_Stop();
@@ -636,8 +621,8 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
} }
if (bKeyHeld && bKeyPressed) { // exit key held down if (bKeyHeld && bKeyPressed) { // exit key held down
if (gInputBoxIndex > 0 || gDTMF_InputBox_Index > 0 || gDTMF_InputMode) if (gInputBoxIndex > 0 || gDTMF_InputBox_Index > 0 ||
{ // cancel key input mode (channel/frequency entry) gDTMF_InputMode) { // cancel key input mode (channel/frequency entry)
gDTMF_InputMode = false; gDTMF_InputMode = false;
gDTMF_InputBox_Index = 0; gDTMF_InputBox_Index = 0;
memset(gDTMF_String, 0, sizeof(gDTMF_String)); memset(gDTMF_String, 0, sizeof(gDTMF_String));
@@ -648,20 +633,17 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
} }
} }
static void MAIN_Key_MENU(bool bKeyPressed, bool bKeyHeld) static void MAIN_Key_MENU(bool bKeyPressed, bool bKeyHeld) {
{
if (bKeyPressed && !bKeyHeld) // menu key pressed if (bKeyPressed && !bKeyHeld) // menu key pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (bKeyHeld) { // menu key held down (long press) if (bKeyHeld) { // menu key held down (long press)
if (bKeyPressed) { // long press MENU key if (bKeyPressed) { // long press MENU key
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
// Exclude work with list 1, 2, 3 or all list // Exclude work with list 1, 2, 3 or all list
if(gScanStateDir != SCAN_OFF) if (gScanStateDir != SCAN_OFF) {
{ if (FUNCTION_IsRx() || gScanPauseDelayIn_10ms > 9) {
if(FUNCTION_IsRx())
{
gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] = true; gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] = true;
gVfoConfigureMode = VFO_CONFIGURE; gVfoConfigureMode = VFO_CONFIGURE;
@@ -674,7 +656,7 @@ static void MAIN_Key_MENU(bool bKeyPressed, bool bKeyHeld)
return; return;
} }
#endif #endif
gWasFKeyPressed = false; gWasFKeyPressed = false;
@@ -694,6 +676,11 @@ static void MAIN_Key_MENU(bool bKeyPressed, bool bKeyHeld)
return; return;
} }
if (gWasFKeyPressed && bKeyPressed) {
gRequestDisplayScreen = DISPLAY_MESSAGES;
return;
}
if (!bKeyPressed && !gDTMF_InputMode) { // menu key released if (!bKeyPressed && !gDTMF_InputMode) { // menu key released
const bool bFlag = !gInputBoxIndex; const bool bFlag = !gInputBoxIndex;
gInputBoxIndex = 0; gInputBoxIndex = 0;
@@ -704,28 +691,26 @@ static void MAIN_Key_MENU(bool bKeyPressed, bool bKeyHeld)
return; return;
} }
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS #ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
if(gEeprom.MENU_LOCK == false) { if(gEeprom.MENU_LOCK == false) {
#endif #endif
gFlagRefreshSetting = true; gFlagRefreshSetting = true;
gRequestDisplayScreen = DISPLAY_MENU; gRequestDisplayScreen = DISPLAY_MENU;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_MENU; gAnotherVoiceID = VOICE_ID_MENU;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS #ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
} }
#endif #endif
} } else {
else {
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
} }
} }
} }
static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld) static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld) {
{
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS #ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
if(gEeprom.MENU_LOCK == true) { if(gEeprom.MENU_LOCK == true) {
@@ -742,7 +727,7 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
return; return;
} }
if (bKeyHeld && !gWasFKeyPressed){ // long press if (bKeyHeld && !gWasFKeyPressed) { // long press
if (!bKeyPressed) // released if (!bKeyPressed) // released
return; return;
@@ -774,14 +759,13 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
if (!gWasFKeyPressed) // pressed without the F-key if (!gWasFKeyPressed) // pressed without the F-key
{ {
if (gScanStateDir == SCAN_OFF if (gScanStateDir == SCAN_OFF
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
&& !IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE) && !IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)
#endif #endif
#ifdef ENABLE_SCAN_RANGES #ifdef ENABLE_SCAN_RANGES
&& gScanRangeStart == 0 && gScanRangeStart == 0
#endif #endif
) ) { // start entering a DTMF string
{ // start entering a DTMF string
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
memcpy(gDTMF_InputBox, gDTMF_String, MIN(sizeof(gDTMF_InputBox), sizeof(gDTMF_String) - 1)); memcpy(gDTMF_InputBox, gDTMF_String, MIN(sizeof(gDTMF_InputBox), sizeof(gDTMF_String) - 1));
gDTMF_InputBox_Index = 0; gDTMF_InputBox_Index = 0;
@@ -790,12 +774,9 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
gKeyInputCountdown = key_input_timeout_500ms; gKeyInputCountdown = key_input_timeout_500ms;
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
} } else
else
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
} } else { // with the F-key
else
{ // with the F-key
gWasFKeyPressed = false; gWasFKeyPressed = false;
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
@@ -816,13 +797,11 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
gUpdateStatus = true; gUpdateStatus = true;
} }
static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction) static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction) {
{
#ifdef ENABLE_FEAT_F4HWN // Set Squelch F + UP or Down #ifdef ENABLE_FEAT_F4HWN // Set Squelch F + UP or Down
if(gWasFKeyPressed) { if (gWasFKeyPressed) {
switch(Direction) switch (Direction) {
{
case 1: case 1:
processFKeyFunction(KEY_UP, false); processFKeyFunction(KEY_UP, false);
break; break;
@@ -834,10 +813,8 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
} }
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
gRemoveOffset = false; gRemoveOffset = false;
gPowerHigh = false; gPowerHigh = false;
#endif
uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO]; uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO];
@@ -855,8 +832,7 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
#endif #endif
return; return;
} }
} } else { // short pressed
else { // short pressed
if (gInputBoxIndex > 0) { if (gInputBoxIndex > 0) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return; return;
@@ -920,8 +896,8 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
gPttWasReleased = true; gPttWasReleased = true;
} }
void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{ void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (gFmRadioMode && Key != KEY_PTT && Key != KEY_EXIT) { if (gFmRadioMode && Key != KEY_PTT && Key != KEY_EXIT) {
if (!bKeyHeld && bKeyPressed) if (!bKeyHeld && bKeyPressed)
@@ -932,8 +908,7 @@ void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
if (gDTMF_InputMode && bKeyPressed && !bKeyHeld) { if (gDTMF_InputMode && bKeyPressed && !bKeyHeld) {
const char Character = DTMF_GetCharacter(Key); const char Character = DTMF_GetCharacter(Key);
if (Character != 0xFF) if (Character != 0xFF) { // add key to DTMF string
{ // add key to DTMF string
DTMF_Append(Character); DTMF_Append(Character);
gKeyInputCountdown = key_input_timeout_500ms; gKeyInputCountdown = key_input_timeout_500ms;
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
@@ -954,26 +929,35 @@ void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
case KEY_SIDE1: case KEY_SIDE1:
case KEY_SIDE2: case KEY_SIDE2:
#endif #endif
case KEY_0...KEY_9: case
MAIN_Key_DIGITS(Key, bKeyPressed, bKeyHeld); KEY_0...KEY_9
:
MAIN_Key_DIGITS(Key, bKeyPressed, bKeyHeld
);
break; break;
case KEY_MENU: case KEY_MENU:
MAIN_Key_MENU(bKeyPressed, bKeyHeld); MAIN_Key_MENU(bKeyPressed, bKeyHeld
);
break; break;
case KEY_UP: case KEY_UP:
MAIN_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1); MAIN_Key_UP_DOWN(bKeyPressed, bKeyHeld,
1);
break; break;
case KEY_DOWN: case KEY_DOWN:
MAIN_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1); MAIN_Key_UP_DOWN(bKeyPressed, bKeyHeld,
-1);
break; break;
case KEY_EXIT: case KEY_EXIT:
MAIN_Key_EXIT(bKeyPressed, bKeyHeld); MAIN_Key_EXIT(bKeyPressed, bKeyHeld
);
break; break;
case KEY_STAR: case KEY_STAR:
MAIN_Key_STAR(bKeyPressed, bKeyHeld); MAIN_Key_STAR(bKeyPressed, bKeyHeld
);
break; break;
case KEY_F: case KEY_F:
GENERIC_Key_F(bKeyPressed, bKeyHeld); GENERIC_Key_F(bKeyPressed, bKeyHeld
);
break; break;
case KEY_PTT: case KEY_PTT:
GENERIC_Key_PTT(bKeyPressed); GENERIC_Key_PTT(bKeyPressed);

File diff suppressed because it is too large Load Diff

264
app/messages.c Normal file
View File

@@ -0,0 +1,264 @@
//
// Created by bruno on 3/30/25.
//
#include "messages.h"
#include "ui/ui.h"
#include "driver/uart.h"
#include "driver/systick.h"
#define T9Count 9
const char T9Table[10][T9Count] = {
{'#', '(', ')', ';', ':', '<', '>', '/', '0'},
{',', '.', '?', '&', '!', ' ', '-', '_', '1'},
{'a', 'b', 'c', 'A', 'B', 'C', '[', ']', '2'},
{'d', 'e', 'f', 'D', 'E', 'F', '@', '%', '3'},
{'g', 'h', 'i', 'G', 'H', 'I', '~', '$', '4'},
{'j', 'k', 'l', 'J', 'K', 'L', '|', '*', '5'},
{'m', 'n', 'o', 'M', 'N', 'O', '{', '}', '6'},
{'p', 'q', 'r', 's', 'P', 'Q', 'R', 'S', '7'},
{'t', 'u', 'v', 'T', 'U', 'V', '"', '\'', '8'},
{'w', 'x', 'y', 'z', 'W', 'X', 'Y', 'Z', '9'}
};
uint8_t gActiveMessage = 0;
StoredPacket loadedPacket;
uint8_t gKeyTimeout = 0;
void MESSAGES_SAVE() {
uint8_t Data[8];
EEPROM_ReadBuffer(SEQParameterEEPROM, Data, 8);
uint8_t msgIndex = Data[1];
if (msgIndex >= MESSAGES_COUNT) {
msgIndex = 0;
}
Data[1]++;
EEPROM_WriteBuffer(SEQParameterEEPROM, Data);
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 0,
(uint8_t *) &inBoundPacket + 4); // metadata
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 8,
(uint8_t *) &inBoundPacket + 12); // message part 1
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 16,
(uint8_t *) &inBoundPacket + 20); // message part 2
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 24,
(uint8_t *) &inBoundPacket + 28); // message part 3
EEPROM_WriteBuffer(MESSAGES_START + (msgIndex * sizeof(StoredPacket)) + 32,
(uint8_t *) &inBoundPacket + 36); // message part 4
}
void MESSAGES_GET() {
if (gActiveMessage == MESSAGES_COUNT) {
memcpy(&loadedPacket, (uint8_t *) &dataPacket + (sizeof(DataPacket) - sizeof(StoredPacket)),
sizeof(StoredPacket));
} else {
EEPROM_ReadBuffer(MESSAGES_START + (gActiveMessage * sizeof(StoredPacket)), &loadedPacket,
sizeof(StoredPacket));
}
}
void MESSAGES_DELETE() {
}
void updatePrevChar(KEY_Code_t Key) {
if (Key != prevKey) {
prevKey = Key;
}
}
void MESSAGES_TimeSlice500ms(void) {
if (gKeyTimeout && gKeyTimeout++ > 2) {
gKeyTimeout = 0;
prevKey = KEY_EXIT;
}
}
void MESSAGES_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
gKeyTimeout = 1;
if (gEnteringSMS != SMS_NOT_ENTERING && !bKeyHeld && Key <= KEY_9) {
if (!dataPTR || dataPTR < dataPacket.data) {
dataPTR = dataPacket.data;
}
if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
if (bKeyPressed) {
if (prevKey != Key) {
dataPTR++;
if (dataPTR - dataPacket.data >= DataPacketDataSize) {
dataPTR = dataPacket.data;
}
prevLetter = 0;
}
*(dataPTR - 1) = T9Table[Key][(prevLetter++) % T9Count];
updatePrevChar(Key);
}
return;
} else if (gEnteringSMS == SMS_ENTERING_DEST) {
if (bKeyPressed) {
dataPacket.dest *= 10;
dataPacket.dest += Key;
prevLetter = 0;
}
return;
}
}
switch (Key) {
case KEY_PTT:
case KEY_MENU:
if (gEnteringSMS == SMS_NOT_ENTERING) {
if (bKeyPressed) {
gEnteringSMS = SMS_ENTERING_DEST;
updatePrevChar(Key);
}
} else if (gEnteringSMS == SMS_ENTERING_DEST) {
if (bKeyPressed) {
memset(dataPacket.data, 0, DataPacketDataSize);
prepareDataPacket();
//dataPacket.flags = 0x80 | (gCurrentVfo->OUTPUT_POWER & 0x07);
if (dataPacket.src == 665 || dataPacket.src == 664) {
uint8_t out[5];
if (dataPacket.src == 665) {
const uint32_t id24 = 0xFFFFFF & (dataPacket.dest >> 4);
const uint8_t btn = 0x0F & (dataPacket.dest);
// mask just in case
// uint32_t id24 = 0x00A38C;
// uint8_t btn = 0x04;
// 3-byte big-endian ID
out[0] = (id24 >> 16) & 0xFF;
out[1] = (id24 >> 8) & 0xFF;
out[2] = (id24 >> 0) & 0xFF;
// first nibble redundancy copy: 0xBB if btn=0xB
out[3] = (btn << 4) | 0x04;
// second copy with MSB flipped (btn ^ 0x8) in the high nibble
out[4] = ((btn ^ 0x8) << 4);
}
else {
out[0] = (dataPacket.dest >> 8) & 0xFF;
out[1] = dataPacket.dest & 0xFF;
}
BK4819_EnterTxMute();
RADIO_SetTxParameters();
uint16_t datX = BK4819_REG_30_ENABLE_VCO_CALIB |
BK4819_REG_30_ENABLE_UNKNOWN |
BK4819_REG_30_DISABLE_RX_LINK |
BK4819_REG_30_DISABLE_AF_DAC |
BK4819_REG_30_ENABLE_DISC_MODE |
BK4819_REG_30_ENABLE_PLL_VCO |
BK4819_REG_30_ENABLE_PA_GAIN |
BK4819_REG_30_DISABLE_MIC_ADC |
BK4819_REG_30_ENABLE_TX_DSP |
BK4819_REG_30_DISABLE_RX_DSP;
BK4819_WriteRegister(BK4819_REG_30,
datX);
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
SYSTEM_DelayMs(20);
for (unsigned int x = 0; x < 15; x++) {
for (unsigned int y = 0; y < (dataPacket.src == 665 ? 5 : 2); y++) {
for (unsigned char i = 7; i < 8; i--) {
if ((out[y] >> i) & 1) {
// datX |= BK4819_REG_30_ENABLE_PA_GAIN;
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, true);
SYSTICK_DelayUs(400 * (dataPacket.src == 665 ? 3 : 2) - 325);
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
// datX &= ~BK4819_REG_30_ENABLE_PA_GAIN;
SYSTICK_DelayUs(400 * 1 - 325);
} else {
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, true);
// datX |= BK4819_REG_30_ENABLE_PA_GAIN;
SYSTICK_DelayUs(400 * 1 - 325);
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
// datX &= ~BK4819_REG_30_ENABLE_PA_GAIN;
SYSTICK_DelayUs(400 * (dataPacket.src == 665 ? 3 : 2) - 325);
}
}
}
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
SYSTEM_DelayMs((dataPacket.src == 665 ? 3 : 15));
}
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
SYSTEM_DelayMs(100);
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE);
gEnteringSMS = SMS_NOT_ENTERING;
} else {
gEnteringSMS = SMS_ENTERING_MESSAGE;
}
}
return;
} else if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
if (bKeyPressed) {
if (strlen((char *) dataPacket.data)) {
MSG_FSKSendData(&dataPacket);
gEnteringSMS = SMS_NOT_ENTERING;
}
}
return;
}
break;
case KEY_UP:
if (bKeyPressed) {
gActiveMessage++;
if (gActiveMessage > MESSAGES_COUNT) {
gActiveMessage = 0;
}
MESSAGES_GET();
}
break;
case KEY_DOWN:
if (bKeyPressed) {
gActiveMessage--;
if (gActiveMessage > MESSAGES_COUNT) {
gActiveMessage = MESSAGES_COUNT - 1;
}
MESSAGES_GET();
}
break;
case KEY_EXIT:
if (gEnteringSMS != SMS_NOT_ENTERING) {
if (bKeyHeld) {
if (bKeyPressed) {
gEnteringSMS = SMS_NOT_ENTERING;
dataPTR = dataPacket.data;
memset(dataPacket.data, 0, DataPacketDataSize);
}
} else {
if (bKeyPressed) {
if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
if (dataPacket.data <= dataPTR) {
*dataPTR = '\0';
if (dataPacket.data < dataPTR) {
dataPTR--;
}
*dataPTR = '\0';
}
} else if (gEnteringSMS == SMS_ENTERING_DEST) {
dataPacket.dest /= 10;
}
}
}
} else {
if (bKeyPressed) {
gRequestDisplayScreen = DISPLAY_MAIN;
}
}
updatePrevChar(Key);
break;
default:
if (!bKeyHeld && bKeyPressed)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
break;
}
}

34
app/messages.h Normal file
View File

@@ -0,0 +1,34 @@
//
// Created by bruno on 3/30/25.
//
//#ifndef BRNQUANFW_MESSAGES_H
//#define BRNQUANFW_MESSAGES_H
#include "fskmodem.h"
#include "../driver/keyboard.h"
#include "../driver/eeprom.h"
#define MESSAGES_START (0x1D00)
#define MESSAGES_COUNT (6)
typedef struct {
uint32_t src;
uint8_t seq;
uint8_t ttl;
uint8_t flags;
uint8_t data[DataPacketDataSize];
} StoredPacket;
extern uint8_t gActiveMessage;
extern StoredPacket loadedPacket;
extern uint8_t gKeyTimeout;
void MESSAGES_GET();
void MESSAGES_DELETE();
void MESSAGES_SAVE();
void MESSAGES_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
void MESSAGES_TimeSlice500ms(void);
//#endif //BRNQUANFW_MESSAGES_H

File diff suppressed because it is too large Load Diff

View File

@@ -180,8 +180,9 @@ typedef struct PeakInfo
uint16_t i; uint16_t i;
} PeakInfo; } PeakInfo;
#ifdef ENABLE_SPECTRUM
void APP_RunSpectrum(void); void APP_RunSpectrum(void);
#endif
#endif /* ifndef SPECTRUM_H */ #endif /* ifndef SPECTRUM_H */
// vim: ft=c // vim: ft=c

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -44,19 +44,6 @@ const uint8_t gFontKeyLock[9] =
0x7c, 0x46, 0x45, 0x45, 0x45, 0x45, 0x45, 0x46, 0x7c 0x7c, 0x46, 0x45, 0x45, 0x45, 0x45, 0x45, 0x46, 0x7c
}; };
const uint8_t gFontLight[9] =
{
0b00001100,
0b00010010,
0b00100001,
0b01101101,
0b01111001,
0b01101101,
0b00100001,
0b00010010,
0b00001100,
};
const uint8_t gFontMute[12] = const uint8_t gFontMute[12] =
{ {
0b00011100, 0b00011100,
@@ -166,17 +153,6 @@ const uint8_t BITMAP_Antenna[5] =
0b00000011 0b00000011
}; };
const uint8_t BITMAP_VFO_Lock[7] =
{
0b01111100,
0b01000110,
0b01000101,
0b01000101,
0b01000101,
0b01000110,
0b01111100,
};
const uint8_t BITMAP_VFO_Default[7] = const uint8_t BITMAP_VFO_Default[7] =
{ {
0b01111111, 0b01111111,
@@ -302,16 +278,6 @@ const uint8_t BITMAP_ScanListAll[19] =
0b01111111 0b01111111
}; };
const uint8_t BITMAP_compand[6] =
{
0b00000000,
0b00111100,
0b01000010,
0b01000010,
0b01000010,
0b00100100
};
/* /*
const uint8_t BITMAP_Ready[7] = const uint8_t BITMAP_Ready[7] =
{ {

View File

@@ -11,7 +11,6 @@ extern const uint8_t gFontF[8];
extern const uint8_t gFontS[6]; extern const uint8_t gFontS[6];
extern const uint8_t gFontKeyLock[9]; extern const uint8_t gFontKeyLock[9];
extern const uint8_t gFontLight[9];
extern const uint8_t gFontMute[12]; extern const uint8_t gFontMute[12];
extern const uint8_t gFontXB[2][6]; extern const uint8_t gFontXB[2][6];
@@ -38,7 +37,6 @@ extern const uint8_t BITMAP_NotReady[7];
extern const uint8_t BITMAP_Antenna[5]; extern const uint8_t BITMAP_Antenna[5];
extern const uint8_t BITMAP_VFO_Default[7]; extern const uint8_t BITMAP_VFO_Default[7];
extern const uint8_t BITMAP_VFO_NotDefault[7]; extern const uint8_t BITMAP_VFO_NotDefault[7];
extern const uint8_t BITMAP_VFO_Lock[7];
extern const uint8_t BITMAP_ScanList0[7]; extern const uint8_t BITMAP_ScanList0[7];
extern const uint8_t BITMAP_ScanList1[7]; extern const uint8_t BITMAP_ScanList1[7];
extern const uint8_t BITMAP_ScanList2[7]; extern const uint8_t BITMAP_ScanList2[7];
@@ -47,8 +45,6 @@ extern const uint8_t BITMAP_ScanList123[19];
extern const uint8_t BITMAP_ScanListAll[19]; extern const uint8_t BITMAP_ScanListAll[19];
extern const uint8_t BITMAP_ScanListE[7]; extern const uint8_t BITMAP_ScanListE[7];
extern const uint8_t BITMAP_PowerUser[3]; extern const uint8_t BITMAP_PowerUser[3];
extern const uint8_t BITMAP_compand[6];
extern const uint8_t BITMAP_NOAA[12]; extern const uint8_t BITMAP_NOAA[12];
#ifndef ENABLE_CUSTOM_MENU_LAYOUT #ifndef ENABLE_CUSTOM_MENU_LAYOUT

View File

@@ -2,7 +2,8 @@
#export DOCKER_DEFAULT_PLATFORM=linux/amd64 #export DOCKER_DEFAULT_PLATFORM=linux/amd64
#export DOCKER_NETWORK="--network=host" #export DOCKER_NETWORK="--network=host"
IMAGE_NAME="uvk5" IMAGE_NAME="uvk5"
rm "${PWD}/compiled-firmware/*" rm -rf "${PWD}/compiled-firmware/*"
mkdir -p "${PWD}/compiled-firmware"
echo "Building docker image $IMAGE_NAME" echo "Building docker image $IMAGE_NAME"
if ! docker build -t $DOCKER_NETWORK $IMAGE_NAME . if ! docker build -t $DOCKER_NETWORK $IMAGE_NAME .
then then
@@ -10,121 +11,6 @@ then
exit 1 exit 1
fi fi
custom() {
echo "Custom compilation..." echo "Custom compilation..."
docker run --rm -v "${PWD}/compiled-firmware/:/app/compiled-firmware" $IMAGE_NAME /bin/bash -c "rm ./compiled-firmware/*; cd /app && make -s \ docker run --rm -v "${PWD}/compiled-firmware:/app/compiled-firmware" $IMAGE_NAME \
EDITION_STRING=Custom \ /bin/bash -c "cd /app && make -j && cp f4hwn* /app/compiled-firmware/ && ls -l /app/compiled-firmware/ || echo 'No files to copy'"
TARGET=f4hwn.custom \
&& cp f4hwn.custom* compiled-firmware/"
}
standard() {
echo "Standard compilation..."
docker run --rm -v "${PWD}/compiled-firmware:/app/compiled-firmware" $IMAGE_NAME /bin/bash -c "rm ./compiled-firmware/*; cd /app && make -s \
ENABLE_SPECTRUM=0 \
ENABLE_FMRADIO=0 \
ENABLE_AIRCOPY=0 \
ENABLE_NOAA=0 \
EDITION_STRING=Standard \
TARGET=f4hwn.standard \
&& cp f4hwn.standard* compiled-firmware/"
}
bandscope() {
echo "Bandscope compilation..."
docker run --rm -v "${PWD}/compiled-firmware/:/app/compiled-firmware" $IMAGE_NAME /bin/bash -c "rm ./compiled-firmware/*; cd /app && make -s \
ENABLE_SPECTRUM=1 \
ENABLE_FMRADIO=0 \
ENABLE_AIRCOPY=1 \
ENABLE_FEAT_F4HWN_PMR=1 \
ENABLE_FEAT_F4HWN_GMRS_FRS_MURS=1 \
ENABLE_NOAA=0 \
ENABLE_FEAT_F4HWN_RESCUE_OPS=0 \
EDITION_STRING=Bandscope \
TARGET=f4hwn.bandscope \
&& cp f4hwn.bandscope* compiled-firmware/"
}
broadcast() {
echo "Broadcast compilation..."
docker run --rm -v "${PWD}/compiled-firmware:/app/compiled-firmware" $IMAGE_NAME /bin/bash -c "cd /app && make -s \
ENABLE_SPECTRUM=0 \
ENABLE_FMRADIO=1 \
ENABLE_AIRCOPY=1 \
ENABLE_FEAT_F4HWN_PMR=1 \
ENABLE_FEAT_F4HWN_GMRS_FRS_MURS=1 \
ENABLE_NOAA=0 \
EDITION_STRING=Broadcast \
ENABLE_FEAT_F4HWN_RESCUE_OPS=0 \
TARGET=f4hwn.broadcast \
&& cp f4hwn.broadcast* compiled-firmware/"
}
voxless() {
echo "Voxless compilation..."
docker run --rm -v "${PWD}/compiled-firmware:/app/compiled-firmware" $IMAGE_NAME /bin/bash -c "cd /app && make -s \
ENABLE_SPECTRUM=1 \
ENABLE_FMRADIO=1 \
ENABLE_VOX=0 \
ENABLE_AIRCOPY=0 \
ENABLE_AUDIO_BAR=0 \
ENABLE_FEAT_F4HWN_SPECTRUM=0 \
ENABLE_FEAT_F4HWN_PMR=1 \
ENABLE_FEAT_F4HWN_GMRS_FRS_MURS=1 \
ENABLE_NOAA=0 \
ENABLE_FEAT_F4HWN_RESUME_STATE=0 \
ENABLE_FEAT_F4HWN_CHARGING_C=0 \
ENABLE_FEAT_F4HWN_INV=1 \
ENABLE_FEAT_F4HWN_CTR=0 \
ENABLE_FEAT_F4HWN_NARROWER=0 \
ENABLE_FEAT_F4HWN_RESCUE_OPS=0 \
EDITION_STRING=Voxless \
TARGET=f4hwn.voxless \
&& cp f4hwn.voxless* compiled-firmware/"
}
rescueops() {
echo "RescueOps compilation..."
docker run --rm -v "${PWD}/compiled-firmware:/app/compiled-firmware" $IMAGE_NAME /bin/bash -c "cd /app && make -s \
ENABLE_SPECTRUM=0 \
ENABLE_FMRADIO=0 \
ENABLE_AIRCOPY=1 \
ENABLE_FEAT_F4HWN_PMR=1 \
ENABLE_FEAT_F4HWN_GMRS_FRS_MURS=1 \
ENABLE_NOAA=1 \
ENABLE_FEAT_F4HWN_RESCUE_OPS=1 \
EDITION_STRING=RescueOps \
TARGET=f4hwn.rescueops \
&& cp f4hwn.rescueops* compiled-firmware/"
}
case "$1" in
custom)
custom
;;
standard)
standard
;;
bandscope)
bandscope
;;
broadcast)
broadcast
;;
voxless)
voxless
;;
rescueops)
rescueops
;;
all)
bandscope
broadcast
rescueops
voxless
;;
*)
echo "Usage: $0 {custom|bandscope|broadcast|voxless|standard|all}"
exit 1
;;
esac

View File

@@ -66,18 +66,6 @@ void BACKLIGHT_InitHardware()
0; 0;
} }
static void BACKLIGHT_Sound(void)
{
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_SOUND || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_ALL)
{
AUDIO_PlayBeep(BEEP_880HZ_60MS_DOUBLE_BEEP);
AUDIO_PlayBeep(BEEP_880HZ_60MS_DOUBLE_BEEP);
}
gK5startup = false;
}
void BACKLIGHT_TurnOn(void) void BACKLIGHT_TurnOn(void)
{ {
#ifdef ENABLE_FEAT_F4HWN_SLEEP #ifdef ENABLE_FEAT_F4HWN_SLEEP
@@ -90,38 +78,11 @@ void BACKLIGHT_TurnOn(void)
if (gEeprom.BACKLIGHT_TIME == 0) { if (gEeprom.BACKLIGHT_TIME == 0) {
BACKLIGHT_TurnOff(); BACKLIGHT_TurnOff();
#ifdef ENABLE_FEAT_F4HWN
if(gK5startup == true)
{
BACKLIGHT_Sound();
}
#endif
return; return;
} }
backlightOn = true; backlightOn = true;
#ifdef ENABLE_FEAT_F4HWN
if(gK5startup == true) {
#if defined(ENABLE_FMRADIO) && defined(ENABLE_SPECTRUM)
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX); BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX);
#else
for(uint8_t i = 0; i <= gEeprom.BACKLIGHT_MAX; i++)
{
BACKLIGHT_SetBrightness(i);
SYSTEM_DelayMs(50);
}
#endif
BACKLIGHT_Sound();
}
else
{
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX);
}
#else
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX);
#endif
switch (gEeprom.BACKLIGHT_TIME) { switch (gEeprom.BACKLIGHT_TIME) {
default: default:

View File

@@ -19,14 +19,42 @@
enum BK1080_Register_t { enum BK1080_Register_t {
BK1080_REG_00 = 0x00U, BK1080_REG_00 = 0x00U,
BK1080_REG_01_CHIP_ID = 0x01U,
BK1080_REG_02_POWER_CONFIGURATION = 0x02U, BK1080_REG_02_POWER_CONFIGURATION = 0x02U,
BK1080_REG_03_CHANNEL = 0x03U, BK1080_REG_03_CHANNEL = 0x03U,
BK1080_REG_04_SYSTEM_CONFIGURATION1 = 0x04U,
BK1080_REG_05_SYSTEM_CONFIGURATION2 = 0x05U, BK1080_REG_05_SYSTEM_CONFIGURATION2 = 0x05U,
BK1080_REG_07 = 0x07U, BK1080_REG_06_SYSTEM_CONFIGURATION3 = 0x06U,
BK1080_REG_10 = 0x0AU, BK1080_REG_07_TEST1 = 0x07U,
BK1080_REG_08_TEST2 = 0x08U,
BK1080_REG_09_BOOT_CONFIGURATION = 0x09U,
BK1080_REG_10_RSSI_STATUS = 0x0AU,
BK1080_REG_11_RSSI_THRESHOLD = 0x0BU,
BK1080_REG_12_INTERNAL = 0x0CU,
BK1080_REG_13_INTERNAL = 0x0DU,
BK1080_REG_14_INTERNAL = 0x0EU,
BK1080_REG_15_INTERNAL = 0x0FU,
BK1080_REG_16_INTERNAL = 0x10U,
BK1080_REG_17_INTERNAL = 0x11U,
BK1080_REG_18_INTERNAL = 0x12U,
BK1080_REG_19_INTERNAL = 0x13U,
BK1080_REG_20_INTERNAL = 0x14U,
BK1080_REG_21_INTERNAL = 0x15U,
BK1080_REG_22_INTERNAL = 0x16U,
BK1080_REG_23_INTERNAL = 0x17U,
BK1080_REG_24_INTERNAL = 0x18U,
BK1080_REG_25_INTERNAL = 0x19U, BK1080_REG_25_INTERNAL = 0x19U,
BK1080_REG_26_INTERNAL = 0x1AU,
BK1080_REG_27_INTERNAL = 0x1BU,
BK1080_REG_28_INTERNAL = 0x1CU,
BK1080_REG_29_INTERNAL = 0x1DU,
BK1080_REG_30_INTERNAL = 0x1EU,
BK1080_REG_31_INTERNAL = 0x1FU,
BK1080_REG_32_INTERNAL = 0x20U,
BK1080_REG_33_INTERNAL = 0x21U,
}; };
typedef enum BK1080_Register_t BK1080_Register_t; typedef enum BK1080_Register_t BK1080_Register_t;
// REG 07 // REG 07

View File

@@ -19,6 +19,7 @@
#include "driver/gpio.h" #include "driver/gpio.h"
#include "driver/i2c.h" #include "driver/i2c.h"
#include "driver/system.h" #include "driver/system.h"
#include "../settings.h"
#include "misc.h" #include "misc.h"
#ifndef ARRAY_SIZE #ifndef ARRAY_SIZE
@@ -69,10 +70,11 @@ void BK1080_Init(uint16_t freq, uint8_t band/*, uint8_t space*/)
} }
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, gMute ? 0x0A10 : 0x0A1F); BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, 0x0A10 | (gEeprom.VOLUME_GAIN >> 2));
#else #else
BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, 0x0A1F); BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, 0x0A1F);
#endif #endif
BK1080_UpdateSysconf();
BK1080_SetFrequency(freq, band/*, space*/); BK1080_SetFrequency(freq, band/*, space*/);
} }
else { else {
@@ -104,6 +106,15 @@ void BK1080_WriteRegister(BK1080_Register_t Register, uint16_t Value)
I2C_Stop(); I2C_Stop();
} }
void BK1080_UpdateSysconf(void) {
BK1080_WriteRegister(BK1080_REG_04_SYSTEM_CONFIGURATION1,
(gEeprom.BK1080_DEEMPHASIS_CONFIG == DEEMPHASIS_OFF ? BK1080_DEEMPHASIS_OFF : BK1080_DEEMPHASIS_ON) |
(gEeprom.BK1080_DEEMPHASIS_CONFIG == DEEMPHASIS_EUR ? BK1080_DEEMPHASIS_EUR : BK1080_DEEMPHASIS_USA) |
(gEeprom.BK1080_AGC_ENABLED ? BK1080_AGC_ON : BK1080_AGC_OFF) |
(gEeprom.BK1080_BLEND_CONFIG << 6)
);
}
void BK1080_Mute(bool Mute) void BK1080_Mute(bool Mute)
{ {
BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, Mute ? 0x4201 : 0x0201); BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, Mute ? 0x4201 : 0x0201);
@@ -130,7 +141,7 @@ void BK1080_SetFrequency(uint16_t frequency, uint8_t band/*, uint8_t space*/)
void BK1080_GetFrequencyDeviation(uint16_t Frequency) void BK1080_GetFrequencyDeviation(uint16_t Frequency)
{ {
BK1080_BaseFrequency = Frequency; BK1080_BaseFrequency = Frequency;
BK1080_FrequencyDeviation = BK1080_ReadRegister(BK1080_REG_07) / 16; BK1080_FrequencyDeviation = BK1080_ReadRegister(BK1080_REG_07_TEST1) / 16;
} }
uint16_t BK1080_GetFreqLoLimit(uint8_t band) uint16_t BK1080_GetFreqLoLimit(uint8_t band)

View File

@@ -24,10 +24,20 @@
extern uint16_t BK1080_BaseFrequency; extern uint16_t BK1080_BaseFrequency;
extern uint16_t BK1080_FrequencyDeviation; extern uint16_t BK1080_FrequencyDeviation;
#define BK1080_DEEMPHASIS_USA (0 << 11)
#define BK1080_DEEMPHASIS_EUR (1 << 11)
#define BK1080_DEEMPHASIS_ON (0 << 13)
#define BK1080_DEEMPHASIS_OFF (1 << 13)
#define BK1080_AGC_ON (0 << 10)
#define BK1080_AGC_OFF (1 << 10)
void BK1080_Init0(void); void BK1080_Init0(void);
void BK1080_Init(uint16_t Frequency, uint8_t band/*, uint8_t space*/); void BK1080_Init(uint16_t Frequency, uint8_t band/*, uint8_t space*/);
uint16_t BK1080_ReadRegister(BK1080_Register_t Register); uint16_t BK1080_ReadRegister(BK1080_Register_t Register);
void BK1080_WriteRegister(BK1080_Register_t Register, uint16_t Value); void BK1080_WriteRegister(BK1080_Register_t Register, uint16_t Value);
void BK1080_UpdateSysconf(void);
void BK1080_Mute(bool Mute); void BK1080_Mute(bool Mute);
uint16_t BK1080_GetFreqLoLimit(uint8_t band); uint16_t BK1080_GetFreqLoLimit(uint8_t band);
uint16_t BK1080_GetFreqHiLimit(uint8_t band); uint16_t BK1080_GetFreqHiLimit(uint8_t band);

View File

@@ -74,6 +74,7 @@ enum BK4819_REGISTER_t {
BK4819_REG_3D = 0x3DU, BK4819_REG_3D = 0x3DU,
BK4819_REG_3E = 0x3EU, BK4819_REG_3E = 0x3EU,
BK4819_REG_3F = 0x3FU, BK4819_REG_3F = 0x3FU,
BK4819_REG_40 = 0x40U,
BK4819_REG_43 = 0x43U, BK4819_REG_43 = 0x43U,
BK4819_REG_46 = 0x46U, BK4819_REG_46 = 0x46U,
BK4819_REG_47 = 0x47U, BK4819_REG_47 = 0x47U,
@@ -96,6 +97,7 @@ enum BK4819_REGISTER_t {
BK4819_REG_5A = 0x5AU, BK4819_REG_5A = 0x5AU,
BK4819_REG_5B = 0x5BU, BK4819_REG_5B = 0x5BU,
BK4819_REG_5C = 0x5CU, BK4819_REG_5C = 0x5CU,
BK4819_REG_5E = 0x5EU,
BK4819_REG_5D = 0x5DU, BK4819_REG_5D = 0x5DU,
BK4819_REG_5F = 0x5FU, BK4819_REG_5F = 0x5FU,
BK4819_REG_63 = 0x63U, BK4819_REG_63 = 0x63U,

View File

@@ -42,12 +42,33 @@ static uint16_t gBK4819_GpioOutState;
bool gRxIdleMode; bool gRxIdleMode;
__inline uint16_t scale_freq(const uint16_t freq) __inline uint16_t scale_freq(uint16_t freq)
{ {
// return (((uint32_t)freq * 1032444u) + 50000u) / 100000u; // with rounding // return (((uint32_t)freq * 1032444u) + 50000u) / 100000u; // with rounding
return (((uint32_t)freq * 1353245u) + (1u << 16)) >> 17; // with rounding return (((uint32_t)freq * 1353245u) + (1u << 16)) >> 17; // with rounding
} }
__inline uint16_t inverse_scale_freq(uint16_t scaled_freq)
{
return (((uint32_t)scaled_freq << 17) - (1u << 16)) / 1353245u;
}
void BK4819_FskEnableTx(void){
const uint16_t fsk_reg59 = BK4819_ReadRegister(BK4819_REG_59);
BK4819_WriteRegister(BK4819_REG_59, (1u << 11) | fsk_reg59);
}
void BK4819_FskClearFifo(void){
const uint16_t fsk_reg59 = BK4819_ReadRegister(BK4819_REG_59);
BK4819_WriteRegister(BK4819_REG_59, (1u << 15) | (1u << 14) | fsk_reg59);
}
void BK4819_FskEnableRx(void){
const uint16_t fsk_reg59 = BK4819_ReadRegister(BK4819_REG_59);
BK4819_WriteRegister(BK4819_REG_59, (1u << 12) | fsk_reg59);
}
void BK4819_Init(void) void BK4819_Init(void)
{ {
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN);
@@ -839,18 +860,18 @@ void BK4819_PickRXFilterPathBasedOnFrequency(uint32_t Frequency)
} }
} }
void BK4819_DisableScramble(void) void BK4819_SetScramble(uint16_t Freq)
{ {
const uint16_t Value = BK4819_ReadRegister(BK4819_REG_31); uint16_t Value = BK4819_ReadRegister(BK4819_REG_31);
BK4819_WriteRegister(BK4819_REG_31, Value & ~(1u << 1)); if (Freq) {
} Value |= (1u << 1);
} else {
Value &= ~(1u << 1);
}
BK4819_WriteRegister(BK4819_REG_31, Value);
void BK4819_EnableScramble(uint8_t Type) //BK4819_WriteRegister(BK4819_REG_71, 0x68DC + (Freq * 1032)); // 0110 1000 1101 1100
{ BK4819_WriteRegister(BK4819_REG_71, Freq);
const uint16_t Value = BK4819_ReadRegister(BK4819_REG_31);
BK4819_WriteRegister(BK4819_REG_31, Value | (1u << 1));
BK4819_WriteRegister(BK4819_REG_71, 0x68DC + (Type * 1032)); // 0110 1000 1101 1100
} }
bool BK4819_CompanderEnabled(void) bool BK4819_CompanderEnabled(void)

View File

@@ -65,6 +65,9 @@ typedef enum BK4819_CssScanResult_t BK4819_CssScanResult_t;
// radio is asleep, not listening // radio is asleep, not listening
extern bool gRxIdleMode; extern bool gRxIdleMode;
uint16_t inverse_scale_freq(uint16_t scaled_freq);
uint16_t scale_freq(uint16_t freq);
void BK4819_Init(void); void BK4819_Init(void);
uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register); uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register);
void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data); void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data);
@@ -77,6 +80,11 @@ void BK4819_InitAGC(bool amModulation);
void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet); void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet);
void BK4819_ResetFSK(void);
void BK4819_FskClearFifo(void);
void BK4819_FskEnableRx(void);
void BK4819_FskEnableTx(void);
void BK4819_SetCDCSSCodeWord(uint32_t CodeWord); void BK4819_SetCDCSSCodeWord(uint32_t CodeWord);
void BK4819_SetCTCSSFrequency(uint32_t BaudRate); void BK4819_SetCTCSSFrequency(uint32_t BaudRate);
void BK4819_SetTailDetection(const uint32_t freq_10Hz); void BK4819_SetTailDetection(const uint32_t freq_10Hz);
@@ -95,8 +103,7 @@ void BK4819_SetupSquelch(
void BK4819_SetAF(BK4819_AF_Type_t AF); void BK4819_SetAF(BK4819_AF_Type_t AF);
void BK4819_RX_TurnOn(void); void BK4819_RX_TurnOn(void);
void BK4819_PickRXFilterPathBasedOnFrequency(uint32_t Frequency); void BK4819_PickRXFilterPathBasedOnFrequency(uint32_t Frequency);
void BK4819_DisableScramble(void); void BK4819_SetScramble(uint16_t Freq);
void BK4819_EnableScramble(uint8_t Type);
bool BK4819_CompanderEnabled(void); bool BK4819_CompanderEnabled(void);
void BK4819_SetCompander(const unsigned int mode); void BK4819_SetCompander(const unsigned int mode);

View File

@@ -26,6 +26,8 @@ KEY_Code_t gKeyReading0 = KEY_INVALID;
KEY_Code_t gKeyReading1 = KEY_INVALID; KEY_Code_t gKeyReading1 = KEY_INVALID;
uint16_t gDebounceCounter = 0; uint16_t gDebounceCounter = 0;
bool gWasFKeyPressed = false; bool gWasFKeyPressed = false;
uint8_t prevLetter = 0;
KEY_Code_t prevKey = KEY_INVALID;
static const struct { static const struct {

View File

@@ -49,6 +49,8 @@ extern KEY_Code_t gKeyReading0;
extern KEY_Code_t gKeyReading1; extern KEY_Code_t gKeyReading1;
extern uint16_t gDebounceCounter; extern uint16_t gDebounceCounter;
extern bool gWasFKeyPressed; extern bool gWasFKeyPressed;
extern uint8_t prevLetter;
extern KEY_Code_t prevKey;
KEY_Code_t KEYBOARD_Poll(void); KEY_Code_t KEYBOARD_Poll(void);

View File

@@ -202,7 +202,7 @@ uint8_t cmds[] = {
ST7565_WriteByte(ST7565_CMD_INVERSE_DISPLAY | gSetting_set_inv); ST7565_WriteByte(ST7565_CMD_INVERSE_DISPLAY | gSetting_set_inv);
break; break;
case 7: case 7:
ST7565_WriteByte(21 + gSetting_set_ctr); ST7565_WriteByte(21 + ST7565_CTR_SETTING_VAL);
break; break;
default: default:
ST7565_WriteByte(cmds[i]); ST7565_WriteByte(cmds[i]);
@@ -226,22 +226,22 @@ uint8_t cmds[] = {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
} }
#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO) // #if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO)
void ST7565_Gauge(uint8_t line, uint8_t min, uint8_t max, uint8_t value) // void ST7565_Gauge(uint8_t line, uint8_t min, uint8_t max, uint8_t value)
{ // {
gFrameBuffer[line][54] = 0x0c; // gFrameBuffer[line][54] = 0x0c;
gFrameBuffer[line][55] = 0x12; // gFrameBuffer[line][55] = 0x12;
//
gFrameBuffer[line][121] = 0x12; // gFrameBuffer[line][121] = 0x12;
gFrameBuffer[line][122] = 0x0c; // gFrameBuffer[line][122] = 0x0c;
//
uint8_t filled = map(value, min, max, 56, 120); // uint8_t filled = map(value, min, max, 56, 120);
//
for (uint8_t i = 56; i <= 120; i++) { // for (uint8_t i = 56; i <= 120; i++) {
gFrameBuffer[line][i] = (i <= filled) ? 0x2d : 0x21; // gFrameBuffer[line][i] = (i <= filled) ? 0x2d : 0x21;
} // }
} // }
#endif // #endif
#endif #endif
void ST7565_Init(void) void ST7565_Init(void)

View File

@@ -27,6 +27,8 @@
extern uint8_t gStatusLine[LCD_WIDTH]; extern uint8_t gStatusLine[LCD_WIDTH];
extern uint8_t gFrameBuffer[FRAME_LINES][LCD_WIDTH]; extern uint8_t gFrameBuffer[FRAME_LINES][LCD_WIDTH];
#define ST7565_CTR_SETTING_VAL (15)
void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const uint8_t *pBitmap, const unsigned int Size); void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const uint8_t *pBitmap, const unsigned int Size);
void ST7565_BlitFullScreen(void); void ST7565_BlitFullScreen(void);
void ST7565_BlitLine(unsigned line); void ST7565_BlitLine(unsigned line);

View File

@@ -15,6 +15,7 @@
*/ */
#include <stdbool.h> #include <stdbool.h>
#include <string.h>
#include "bsp/dp32g030/dma.h" #include "bsp/dp32g030/dma.h"
#include "bsp/dp32g030/syscon.h" #include "bsp/dp32g030/syscon.h"
#include "bsp/dp32g030/uart.h" #include "bsp/dp32g030/uart.h"
@@ -23,8 +24,7 @@
static bool UART_IsLogEnabled; static bool UART_IsLogEnabled;
uint8_t UART_DMA_Buffer[256]; uint8_t UART_DMA_Buffer[256];
void UART_Init(void) void UART_Init(void) {
{
uint32_t Delta; uint32_t Delta;
uint32_t Positive; uint32_t Positive;
uint32_t Frequency; uint32_t Frequency;
@@ -48,8 +48,8 @@ void UART_Init(void)
DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_DISABLE; DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_DISABLE;
DMA_CH0->MSADDR = (uint32_t)(uintptr_t)&UART1->RDR; DMA_CH0->MSADDR = (uint32_t) (uintptr_t) &UART1->RDR;
DMA_CH0->MDADDR = (uint32_t)(uintptr_t)UART_DMA_Buffer; DMA_CH0->MDADDR = (uint32_t) (uintptr_t) UART_DMA_Buffer;
DMA_CH0->MOD = 0 DMA_CH0->MOD = 0
// Source // Source
| DMA_CH_MOD_MS_ADDMOD_BITS_NONE | DMA_CH_MOD_MS_ADDMOD_BITS_NONE
@@ -58,8 +58,7 @@ void UART_Init(void)
// Destination // Destination
| DMA_CH_MOD_MD_ADDMOD_BITS_INCREMENT | DMA_CH_MOD_MD_ADDMOD_BITS_INCREMENT
| DMA_CH_MOD_MD_SIZE_BITS_8BIT | DMA_CH_MOD_MD_SIZE_BITS_8BIT
| DMA_CH_MOD_MD_SEL_BITS_SRAM | DMA_CH_MOD_MD_SEL_BITS_SRAM;
;
DMA_INTEN = 0; DMA_INTEN = 0;
DMA_INTST = 0 DMA_INTST = 0
| DMA_INTST_CH0_TC_INTST_BITS_SET | DMA_INTST_CH0_TC_INTST_BITS_SET
@@ -69,14 +68,12 @@ void UART_Init(void)
| DMA_INTST_CH0_THC_INTST_BITS_SET | DMA_INTST_CH0_THC_INTST_BITS_SET
| DMA_INTST_CH1_THC_INTST_BITS_SET | DMA_INTST_CH1_THC_INTST_BITS_SET
| DMA_INTST_CH2_THC_INTST_BITS_SET | DMA_INTST_CH2_THC_INTST_BITS_SET
| DMA_INTST_CH3_THC_INTST_BITS_SET | DMA_INTST_CH3_THC_INTST_BITS_SET;
;
DMA_CH0->CTR = 0 DMA_CH0->CTR = 0
| DMA_CH_CTR_CH_EN_BITS_ENABLE | DMA_CH_CTR_CH_EN_BITS_ENABLE
| ((0xFF << DMA_CH_CTR_LENGTH_SHIFT) & DMA_CH_CTR_LENGTH_MASK) | ((0xFF << DMA_CH_CTR_LENGTH_SHIFT) & DMA_CH_CTR_LENGTH_MASK)
| DMA_CH_CTR_LOOP_BITS_ENABLE | DMA_CH_CTR_LOOP_BITS_ENABLE
| DMA_CH_CTR_PRI_BITS_MEDIUM | DMA_CH_CTR_PRI_BITS_MEDIUM;
;
UART1->IF = UART_IF_RXTO_BITS_SET; UART1->IF = UART_IF_RXTO_BITS_SET;
DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_ENABLE; DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_ENABLE;
@@ -84,9 +81,8 @@ void UART_Init(void)
UART1->CTRL |= UART_CTRL_UARTEN_BITS_ENABLE; UART1->CTRL |= UART_CTRL_UARTEN_BITS_ENABLE;
} }
void UART_Send(const void *pBuffer, uint32_t Size) void UART_Send(const void *pBuffer, uint32_t Size) {
{ const uint8_t *pData = (const uint8_t *) pBuffer;
const uint8_t *pData = (const uint8_t *)pBuffer;
uint32_t i; uint32_t i;
for (i = 0; i < Size; i++) { for (i = 0; i < Size; i++) {
@@ -96,8 +92,11 @@ void UART_Send(const void *pBuffer, uint32_t Size)
} }
} }
void UART_LogSend(const void *pBuffer, uint32_t Size) void UART_String(const char *str) {
{ UART_Send(str, strlen(str));
}
void UART_LogSend(const void *pBuffer, uint32_t Size) {
if (UART_IsLogEnabled) { if (UART_IsLogEnabled) {
UART_Send(pBuffer, Size); UART_Send(pBuffer, Size);
} }

View File

@@ -25,6 +25,7 @@ extern uint8_t UART_DMA_Buffer[256];
void UART_Init(void); void UART_Init(void);
void UART_Send(const void *pBuffer, uint32_t Size); void UART_Send(const void *pBuffer, uint32_t Size);
void UART_LogSend(const void *pBuffer, uint32_t Size); void UART_LogSend(const void *pBuffer, uint32_t Size);
void UART_String(const char *str);
#endif #endif

View File

@@ -4084,9 +4084,9 @@ called in the following order:
a=>b [label="GetVersion ()", textcolor="gray", linecolor="gray"]; a=>b [label="GetVersion ()", textcolor="gray", linecolor="gray"];
--- [label="Obtain driver features"]; --- [label="Obtain driver features"];
a=>b [label="GetCapabilities (...)", textcolor="gray", linecolor="gray"]; a=>b [label="GetCapabilities (...)", textcolor="gray", linecolor="gray"];
--- [label="Setup software resources"]; --- [label="Sup software resources"];
a=>b [label="Initialize (...)", textcolor="red", linecolor="red"]; a=>b [label="Initialize (...)", textcolor="red", linecolor="red"];
--- [label="Setup the peripheral"]; --- [label="Sup the peripheral"];
a=>b [label="PowerControl (ARM_POWER_FULL)", textcolor="red", linecolor="red"]; a=>b [label="PowerControl (ARM_POWER_FULL)", textcolor="red", linecolor="red"];
--- [label="Operate with the peripheral"]; --- [label="Operate with the peripheral"];
a=>b [label="Data Transfer Functions"]; a=>b [label="Data Transfer Functions"];

View File

@@ -40,7 +40,10 @@
// printf_config.h header file // printf_config.h header file
// default: undefined // default: undefined
#ifdef PRINTF_INCLUDE_CONFIG_H #ifdef PRINTF_INCLUDE_CONFIG_H
#include "printf_config.h" #define PRINTF_DISABLE_SUPPORT_LONG_LONG
#define PRINTF_DISABLE_SUPPORT_EXPONENTIAL
#define PRINTF_DISABLE_SUPPORT_PTRDIFF_T
#define PRINTF_DISABLE_SUPPORT_FLOAT
#endif #endif
@@ -119,36 +122,39 @@
// output function type // output function type
typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen); typedef void (*out_fct_type)(char character, void *buffer, size_t idx, size_t maxlen);
// wrapper (used as buffer) for output function type // wrapper (used as buffer) for output function type
typedef struct { typedef struct {
void (*fct)(char character, void* arg); void (*fct)(char character, void *arg);
void* arg;
void *arg;
} out_fct_wrap_type; } out_fct_wrap_type;
// internal buffer output // internal buffer output
static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) static inline void _out_buffer(char character, void *buffer, size_t idx, size_t maxlen) {
{
if (idx < maxlen) { if (idx < maxlen) {
((char*)buffer)[idx] = character; ((char *) buffer)[idx] = character;
} }
} }
// internal null output // internal null output
static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) static inline void _out_null(char character, void *buffer, size_t idx, size_t maxlen) {
{ (void) character;
(void)character; (void)buffer; (void)idx; (void)maxlen; (void) buffer;
(void) idx;
(void) maxlen;
} }
// internal _putchar wrapper // internal _putchar wrapper
static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen) static inline void _out_char(char character, void *buffer, size_t idx, size_t maxlen) {
{ (void) buffer;
(void)buffer; (void)idx; (void)maxlen; (void) idx;
(void) maxlen;
if (character) { if (character) {
_putchar(character); _putchar(character);
} }
@@ -156,48 +162,46 @@ static inline void _out_char(char character, void* buffer, size_t idx, size_t ma
// internal output function wrapper // internal output function wrapper
static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen) static inline void _out_fct(char character, void *buffer, size_t idx, size_t maxlen) {
{ (void) idx;
(void)idx; (void)maxlen; (void) maxlen;
if (character) { if (character) {
// buffer is the output fct pointer // buffer is the output fct pointer
((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg); ((out_fct_wrap_type *) buffer)->fct(character, ((out_fct_wrap_type *) buffer)->arg);
} }
} }
// internal secure strlen // internal secure strlen
// \return The length of the string (excluding the terminating 0) limited by 'maxsize' // \return The length of the string (excluding the terminating 0) limited by 'maxsize'
static inline unsigned int _strnlen_s(const char* str, size_t maxsize) static inline unsigned int _strnlen_s(const char *str, size_t maxsize) {
{ const char *s;
const char* s;
for (s = str; *s && maxsize--; ++s); for (s = str; *s && maxsize--; ++s);
return (unsigned int)(s - str); return (unsigned int) (s - str);
} }
// internal test if char is a digit (0-9) // internal test if char is a digit (0-9)
// \return true if char is a digit // \return true if char is a digit
static inline bool _is_digit(char ch) static inline bool _is_digit(char ch) {
{
return (ch >= '0') && (ch <= '9'); return (ch >= '0') && (ch <= '9');
} }
// internal ASCII string to unsigned int conversion // internal ASCII string to unsigned int conversion
static unsigned int _atoi(const char** str) static unsigned int _atoi(const char **str) {
{
unsigned int i = 0U; unsigned int i = 0U;
while (_is_digit(**str)) { while (_is_digit(**str)) {
i = i * 10U + (unsigned int)(*((*str)++) - '0'); i = i * 10U + (unsigned int) (*((*str)++) - '0');
} }
return i; return i;
} }
// output the specified string in reverse, taking care of any zero-padding // output the specified string in reverse, taking care of any zero-padding
static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags) static size_t
{ _out_rev(out_fct_type out, char *buffer, size_t idx, size_t maxlen, const char *buf, size_t len, unsigned int width,
unsigned int flags) {
const size_t start_idx = idx; const size_t start_idx = idx;
// pad spaces up to given width // pad spaces up to given width
@@ -224,8 +228,9 @@ static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen
// internal itoa format // internal itoa format
static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) static size_t
{ _ntoa_format(out_fct_type out, char *buffer, size_t idx, size_t maxlen, char *buf, size_t len, bool negative,
unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) {
// pad leading zeros // pad leading zeros
if (!(flags & FLAGS_LEFT)) { if (!(flags & FLAGS_LEFT)) {
if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
@@ -249,11 +254,9 @@ static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t ma
} }
if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'x'; buf[len++] = 'x';
} } else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'X'; buf[len++] = 'X';
} } else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'b'; buf[len++] = 'b';
} }
if (len < PRINTF_NTOA_BUFFER_SIZE) { if (len < PRINTF_NTOA_BUFFER_SIZE) {
@@ -264,11 +267,9 @@ static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t ma
if (len < PRINTF_NTOA_BUFFER_SIZE) { if (len < PRINTF_NTOA_BUFFER_SIZE) {
if (negative) { if (negative) {
buf[len++] = '-'; buf[len++] = '-';
} } else if (flags & FLAGS_PLUS) {
else if (flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists buf[len++] = '+'; // ignore the space if the '+' exists
} } else if (flags & FLAGS_SPACE) {
else if (flags & FLAGS_SPACE) {
buf[len++] = ' '; buf[len++] = ' ';
} }
} }
@@ -278,8 +279,8 @@ static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t ma
// internal itoa for 'long' type // internal itoa for 'long' type
static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) static size_t _ntoa_long(out_fct_type out, char *buffer, size_t idx, size_t maxlen, unsigned long value, bool negative,
{ unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) {
char buf[PRINTF_NTOA_BUFFER_SIZE]; char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U; size_t len = 0U;
@@ -291,13 +292,13 @@ static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxl
// write if precision != 0 and value is != 0 // write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || value) { if (!(flags & FLAGS_PRECISION) || value) {
do { do {
const char digit = (char)(value % base); const char digit = (char) (value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base; value /= base;
} while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); } while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
} }
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int) base, prec, width, flags);
} }
@@ -574,8 +575,7 @@ static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d
// internal vsnprintf // internal vsnprintf
static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) static int _vsnprintf(out_fct_type out, char *buffer, const size_t maxlen, const char *format, va_list va) {
{
unsigned int flags, width, precision, n; unsigned int flags, width, precision, n;
size_t idx = 0U; size_t idx = 0U;
@@ -584,16 +584,14 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
out = _out_null; out = _out_null;
} }
while (*format) while (*format) {
{
// format specifier? %[flags][width][.precision][length] // format specifier? %[flags][width][.precision][length]
if (*format != '%') { if (*format != '%') {
// no // no
out(*format, buffer, idx++, maxlen); out(*format, buffer, idx++, maxlen);
format++; format++;
continue; continue;
} } else {
else {
// yes, evaluate it // yes, evaluate it
format++; format++;
} }
@@ -602,12 +600,34 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
flags = 0U; flags = 0U;
do { do {
switch (*format) { switch (*format) {
case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break; case '0':
case '-': flags |= FLAGS_LEFT; format++; n = 1U; break; flags |= FLAGS_ZEROPAD;
case '+': flags |= FLAGS_PLUS; format++; n = 1U; break; format++;
case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break; n = 1U;
case '#': flags |= FLAGS_HASH; format++; n = 1U; break; break;
default : n = 0U; break; case '-':
flags |= FLAGS_LEFT;
format++;
n = 1U;
break;
case '+':
flags |= FLAGS_PLUS;
format++;
n = 1U;
break;
case ' ':
flags |= FLAGS_SPACE;
format++;
n = 1U;
break;
case '#':
flags |= FLAGS_HASH;
format++;
n = 1U;
break;
default :
n = 0U;
break;
} }
} while (n); } while (n);
@@ -615,15 +635,13 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
width = 0U; width = 0U;
if (_is_digit(*format)) { if (_is_digit(*format)) {
width = _atoi(&format); width = _atoi(&format);
} } else if (*format == '*') {
else if (*format == '*') {
const int w = va_arg(va, int); const int w = va_arg(va, int);
if (w < 0) { if (w < 0) {
flags |= FLAGS_LEFT; // reverse padding flags |= FLAGS_LEFT; // reverse padding
width = (unsigned int)-w; width = (unsigned int) -w;
} } else {
else { width = (unsigned int) w;
width = (unsigned int)w;
} }
format++; format++;
} }
@@ -635,10 +653,9 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
format++; format++;
if (_is_digit(*format)) { if (_is_digit(*format)) {
precision = _atoi(&format); precision = _atoi(&format);
} } else if (*format == '*') {
else if (*format == '*') { const int prec = (int) va_arg(va, int);
const int prec = (int)va_arg(va, int); precision = prec > 0 ? (unsigned int) prec : 0U;
precision = prec > 0 ? (unsigned int)prec : 0U;
format++; format++;
} }
} }
@@ -692,14 +709,11 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
unsigned int base; unsigned int base;
if (*format == 'x' || *format == 'X') { if (*format == 'x' || *format == 'X') {
base = 16U; base = 16U;
} } else if (*format == 'o') {
else if (*format == 'o') {
base = 8U; base = 8U;
} } else if (*format == 'b') {
else if (*format == 'b') {
base = 2U; base = 2U;
} } else {
else {
base = 10U; base = 10U;
flags &= ~FLAGS_HASH; // no hash for dec format flags &= ~FLAGS_HASH; // no hash for dec format
} }
@@ -726,28 +740,32 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
const long long value = va_arg(va, long long); const long long value = va_arg(va, long long);
idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
#endif #endif
} } else if (flags & FLAGS_LONG) {
else if (flags & FLAGS_LONG) {
const long value = va_arg(va, long); const long value = va_arg(va, long);
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long) (value > 0 ? value : 0 - value),
value < 0, base, precision, width, flags);
} else {
const int value = (flags & FLAGS_CHAR) ? (char) va_arg(va, int) : (flags & FLAGS_SHORT)
? (short int) va_arg(va, int)
: va_arg(va, int);
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int) (value > 0 ? value : 0 - value),
value < 0, base, precision, width, flags);
} }
else { } else {
const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int);
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
}
}
else {
// unsigned // unsigned
if (flags & FLAGS_LONG_LONG) { if (flags & FLAGS_LONG_LONG) {
#if defined(PRINTF_SUPPORT_LONG_LONG) #if defined(PRINTF_SUPPORT_LONG_LONG)
idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags);
#endif #endif
} } else if (flags & FLAGS_LONG) {
else if (flags & FLAGS_LONG) { idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision,
idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); width, flags);
} } else {
else { const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char) va_arg(va, unsigned int)
const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); : (flags & FLAGS_SHORT)
? (unsigned short int) va_arg(va,
unsigned int)
: va_arg(va, unsigned int);
idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags);
} }
} }
@@ -782,7 +800,7 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
} }
} }
// char output // char output
out((char)va_arg(va, int), buffer, idx++, maxlen); out((char) va_arg(va, int), buffer, idx++, maxlen);
// post padding // post padding
if (flags & FLAGS_LEFT) { if (flags & FLAGS_LEFT) {
while (l++ < width) { while (l++ < width) {
@@ -794,8 +812,8 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
} }
case 's' : { case 's' : {
const char* p = va_arg(va, char*); const char *p = va_arg(va, char*);
unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1); unsigned int l = _strnlen_s(p, precision ? precision : (size_t) -1);
// pre padding // pre padding
if (flags & FLAGS_PRECISION) { if (flags & FLAGS_PRECISION) {
l = (l < precision ? l : precision); l = (l < precision ? l : precision);
@@ -820,7 +838,7 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
} }
case 'p' : { case 'p' : {
width = sizeof(void*) * 2U; width = sizeof(void *) * 2U;
flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE;
#if defined(PRINTF_SUPPORT_LONG_LONG) #if defined(PRINTF_SUPPORT_LONG_LONG)
const bool is_ll = sizeof(uintptr_t) == sizeof(long long); const bool is_ll = sizeof(uintptr_t) == sizeof(long long);
@@ -829,7 +847,8 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
} }
else { else {
#endif #endif
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long) ((uintptr_t) va_arg(va, void*)), false, 16U,
precision, width, flags);
#if defined(PRINTF_SUPPORT_LONG_LONG) #if defined(PRINTF_SUPPORT_LONG_LONG)
} }
#endif #endif
@@ -850,38 +869,35 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
} }
// termination // termination
out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); out((char) 0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen);
// return written chars without terminating \0 // return written chars without terminating \0
return (int)idx; return (int) idx;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
int printf_(const char* format, ...) int printf_(const char *format, ...) {
{
va_list va; va_list va;
va_start(va, format); va_start(va, format);
char buffer[1]; char buffer[1];
const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va); const int ret = _vsnprintf(_out_char, buffer, (size_t) -1, format, va);
va_end(va); va_end(va);
return ret; return ret;
} }
int sprintf_(char* buffer, const char* format, ...) int sprintf_(char *buffer, const char *format, ...) {
{
va_list va; va_list va;
va_start(va, format); va_start(va, format);
const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va); const int ret = _vsnprintf(_out_buffer, buffer, (size_t) -1, format, va);
va_end(va); va_end(va);
return ret; return ret;
} }
int snprintf_(char* buffer, size_t count, const char* format, ...) int snprintf_(char *buffer, size_t count, const char *format, ...) {
{
va_list va; va_list va;
va_start(va, format); va_start(va, format);
const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); const int ret = _vsnprintf(_out_buffer, buffer, count, format, va);
@@ -890,25 +906,22 @@ int snprintf_(char* buffer, size_t count, const char* format, ...)
} }
int vprintf_(const char* format, va_list va) int vprintf_(const char *format, va_list va) {
{
char buffer[1]; char buffer[1];
return _vsnprintf(_out_char, buffer, (size_t)-1, format, va); return _vsnprintf(_out_char, buffer, (size_t) -1, format, va);
} }
int vsnprintf_(char* buffer, size_t count, const char* format, va_list va) int vsnprintf_(char *buffer, size_t count, const char *format, va_list va) {
{
return _vsnprintf(_out_buffer, buffer, count, format, va); return _vsnprintf(_out_buffer, buffer, count, format, va);
} }
int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) int fctprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...) {
{
va_list va; va_list va;
va_start(va, format); va_start(va, format);
const out_fct_wrap_type out_fct_wrap = { out, arg }; const out_fct_wrap_type out_fct_wrap = {out, arg};
const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); const int ret = _vsnprintf(_out_fct, (char *) (uintptr_t) &out_fct_wrap, (size_t) -1, format, va);
va_end(va); va_end(va);
return ret; return ret;
} }

420
font.c
View File

@@ -18,202 +18,202 @@
// removed last and middle column which was all 0x00 // removed last and middle column which was all 0x00
// also the space char is not needed // also the space char is not needed
const uint8_t gFontBig[95 - 1][16 - 2] = //const uint8_t gFontBig[95 - 1][16 - 2] =
{ //{
#if 0 //#if 0
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // ' ' //// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // ' '
{0x00, 0x00, 0x70, 0xF8, 0xF8, 0x70, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '!' // {0x00, 0x00, 0x70, 0xF8, 0xF8, 0x70, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '!'
{0x00, 0x1E, 0x3E, 0x00, 0x00, 0x3E, 0x1E, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '"' // {0x00, 0x1E, 0x3E, 0x00, 0x00, 0x3E, 0x1E, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '"'
{0x40, 0xF0, 0xF0, 0x40, 0xF0, 0xF0, 0x40, /*0x00,*/ 0x04, 0x1F, 0x1F, 0x04, 0x1F, 0x1F, 0x04}, // , 0x00}, // '#' // {0x40, 0xF0, 0xF0, 0x40, 0xF0, 0xF0, 0x40, /*0x00,*/ 0x04, 0x1F, 0x1F, 0x04, 0x1F, 0x1F, 0x04}, // , 0x00}, // '#'
{0x70, 0xF8, 0x88, 0x8F, 0x8F, 0x98, 0x30, /*0x00,*/ 0x06, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // , 0x00}, // '$' // {0x70, 0xF8, 0x88, 0x8F, 0x8F, 0x98, 0x30, /*0x00,*/ 0x06, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // , 0x00}, // '$'
{0x60, 0x60, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x18, 0x18}, // , 0x00}, // '%' // {0x60, 0x60, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x18, 0x18}, // , 0x00}, // '%'
{0x00, 0xB0, 0xF8, 0xC8, 0x78, 0xB0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // '&' // {0x00, 0xB0, 0xF8, 0xC8, 0x78, 0xB0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // '&'
{0x00, 0x20, 0x3E, 0x1E, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // ''' // {0x00, 0x20, 0x3E, 0x1E, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '''
{0x00, 0x00, 0xE0, 0xF0, 0x18, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x00}, // , 0x00}, // '(' // {0x00, 0x00, 0xE0, 0xF0, 0x18, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x00}, // , 0x00}, // '('
{0x00, 0x00, 0x08, 0x18, 0xF0, 0xE0, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x18, 0x0F, 0x07, 0x00}, // , 0x00}, // ')' // {0x00, 0x00, 0x08, 0x18, 0xF0, 0xE0, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x18, 0x0F, 0x07, 0x00}, // , 0x00}, // ')'
{0x00, 0x40, 0xC0, 0x80, 0x80, 0xC0, 0x40, /*0x00,*/ 0x01, 0x05, 0x07, 0x03, 0x03, 0x07, 0x05}, // , 0x01}, // '*' // {0x00, 0x40, 0xC0, 0x80, 0x80, 0xC0, 0x40, /*0x00,*/ 0x01, 0x05, 0x07, 0x03, 0x03, 0x07, 0x05}, // , 0x01}, // '*'
{0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, /*0x00,*/ 0x00, 0x01, 0x01, 0x07, 0x07, 0x01, 0x01}, // , 0x00}, // '+' // {0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, /*0x00,*/ 0x00, 0x01, 0x01, 0x07, 0x07, 0x01, 0x01}, // , 0x00}, // '+'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x20, 0x3C, 0x1C, 0x00, 0x00}, // , 0x00}, // ',' // {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x20, 0x3C, 0x1C, 0x00, 0x00}, // , 0x00}, // ','
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, // , 0x00}, // '-' // {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, // , 0x00}, // '-'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, // , 0x00}, // '.' // {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, // , 0x00}, // '.'
{0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00}, // , 0x00}, // '/' // {0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00}, // , 0x00}, // '/'
{0xF0, 0xF8, 0x08, 0x88, 0x48, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x12, 0x11, 0x10, 0x1F, 0x0F}, // , 0x00}, // '0' // {0xF0, 0xF8, 0x08, 0x88, 0x48, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x12, 0x11, 0x10, 0x1F, 0x0F}, // , 0x00}, // '0'
{0x00, 0x20, 0x30, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10}, // , 0x00}, // '1' // {0x00, 0x20, 0x30, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10}, // , 0x00}, // '1'
{0x10, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x18}, // , 0x00}, // '2' // {0x10, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x18}, // , 0x00}, // '2'
{0x10, 0x18, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '3' // {0x10, 0x18, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '3'
{0x80, 0xC0, 0x60, 0x30, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x11, 0x1F, 0x1F, 0x11}, // , 0x00}, // '4' // {0x80, 0xC0, 0x60, 0x30, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x11, 0x1F, 0x1F, 0x11}, // , 0x00}, // '4'
{0xF8, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x08, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x11, 0x1F, 0x0F}, // , 0x00}, // '5' // {0xF8, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x08, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x11, 0x1F, 0x0F}, // , 0x00}, // '5'
{0xE0, 0xF0, 0x98, 0x88, 0x88, 0x80, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '6' // {0xE0, 0xF0, 0x98, 0x88, 0x88, 0x80, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '6'
{0x18, 0x18, 0x08, 0x08, 0x88, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x1E, 0x1F, 0x01, 0x00, 0x00}, // , 0x00}, // '7' // {0x18, 0x18, 0x08, 0x08, 0x88, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x1E, 0x1F, 0x01, 0x00, 0x00}, // , 0x00}, // '7'
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '8' // {0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '8'
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0xF0, /*0x00,*/ 0x00, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // '9' // {0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0xF0, /*0x00,*/ 0x00, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // '9'
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // , 0x00}, // ':' // {0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // , 0x00}, // ':'
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1C, 0x0C, 0x00, 0x00}, // , 0x00}, // ';' // {0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1C, 0x0C, 0x00, 0x00}, // , 0x00}, // ';'
{0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x10, /*0x00,*/ 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18, 0x10}, // , 0x00}, // '<' // {0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x10, /*0x00,*/ 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18, 0x10}, // , 0x00}, // '<'
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, // , 0x00}, // '=' // {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, // , 0x00}, // '='
{0x00, 0x10, 0x30, 0x60, 0xC0, 0x80, 0x00, /*0x00,*/ 0x00, 0x10, 0x18, 0x0C, 0x06, 0x03, 0x01}, // , 0x00}, // '>' // {0x00, 0x10, 0x30, 0x60, 0xC0, 0x80, 0x00, /*0x00,*/ 0x00, 0x10, 0x18, 0x0C, 0x06, 0x03, 0x01}, // , 0x00}, // '>'
{0x30, 0x38, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '?' // {0x30, 0x38, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '?'
{0xE0, 0xF0, 0x10, 0x90, 0x90, 0xF0, 0xE0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x17, 0x17, 0x17, 0x03}, // , 0x00}, // '@' // {0xE0, 0xF0, 0x10, 0x90, 0x90, 0xF0, 0xE0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x17, 0x17, 0x17, 0x03}, // , 0x00}, // '@'
{0xC0, 0xE0, 0x30, 0x18, 0x30, 0xE0, 0xC0, /*0x00,*/ 0x1F, 0x1F, 0x01, 0x01, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'A' // {0xC0, 0xE0, 0x30, 0x18, 0x30, 0xE0, 0xC0, /*0x00,*/ 0x1F, 0x1F, 0x01, 0x01, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'A'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'B' // {0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'B'
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x10, 0x18, 0x0C}, // , 0x00}, // 'C' // {0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x10, 0x18, 0x0C}, // , 0x00}, // 'C'
{0x08, 0xF8, 0xF8, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'D' // {0x08, 0xF8, 0xF8, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'D'
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x11, 0x18, 0x1C}, // , 0x00}, // 'E' // {0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x11, 0x18, 0x1C}, // , 0x00}, // 'E'
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x01, 0x00, 0x00}, // , 0x00}, // 'F' // {0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x01, 0x00, 0x00}, // , 0x00}, // 'F'
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x11, 0x11, 0x0F, 0x1F}, // , 0x00}, // 'G' // {0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x11, 0x11, 0x0F, 0x1F}, // , 0x00}, // 'G'
{0xF8, 0xF8, 0x80, 0x80, 0x80, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'H' // {0xF8, 0xF8, 0x80, 0x80, 0x80, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'H'
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'I' // {0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'I'
{0x00, 0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, /*0x00,*/ 0x0E, 0x1E, 0x10, 0x10, 0x1F, 0x0F, 0x00}, // , 0x00}, // 'J' // {0x00, 0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, /*0x00,*/ 0x0E, 0x1E, 0x10, 0x10, 0x1F, 0x0F, 0x00}, // , 0x00}, // 'J'
{0x08, 0xF8, 0xF8, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x01, 0x03, 0x1E, 0x1C}, // , 0x00}, // 'K' // {0x08, 0xF8, 0xF8, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x01, 0x03, 0x1E, 0x1C}, // , 0x00}, // 'K'
{0x08, 0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x18, 0x1C}, // , 0x00}, // 'L' // {0x08, 0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x18, 0x1C}, // , 0x00}, // 'L'
{0xF8, 0xF8, 0x70, 0xE0, 0x70, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'M' // {0xF8, 0xF8, 0x70, 0xE0, 0x70, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'M'
{0xF8, 0xF8, 0x70, 0xE0, 0xC0, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'N' // {0xF8, 0xF8, 0x70, 0xE0, 0xC0, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'N'
{0xE0, 0xF0, 0x18, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'O' // {0xE0, 0xF0, 0x18, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'O'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'P' // {0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'P'
{0xF0, 0xF8, 0x08, 0x08, 0x08, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x1C, 0x78, 0x7F, 0x4F}, // , 0x00}, // 'Q' // {0xF0, 0xF8, 0x08, 0x08, 0x08, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x1C, 0x78, 0x7F, 0x4F}, // , 0x00}, // 'Q'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x01, 0x1F, 0x1E}, // , 0x00}, // 'R' // {0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x01, 0x1F, 0x1E}, // , 0x00}, // 'R'
{0x30, 0x78, 0xC8, 0x88, 0x88, 0x38, 0x30, /*0x00,*/ 0x0C, 0x1C, 0x10, 0x10, 0x11, 0x1F, 0x0E}, // , 0x00}, // 'S' // {0x30, 0x78, 0xC8, 0x88, 0x88, 0x38, 0x30, /*0x00,*/ 0x0C, 0x1C, 0x10, 0x10, 0x11, 0x1F, 0x0E}, // , 0x00}, // 'S'
{0x00, 0x38, 0x18, 0xF8, 0xF8, 0x18, 0x38, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'T' // {0x00, 0x38, 0x18, 0xF8, 0xF8, 0x18, 0x38, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'T'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'U' // {0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'U'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x03, 0x07, 0x0C, 0x18, 0x0C, 0x07, 0x03}, // , 0x00}, // 'V' // {0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x03, 0x07, 0x0C, 0x18, 0x0C, 0x07, 0x03}, // , 0x00}, // 'V'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x07, 0x1F, 0x1C, 0x07, 0x1C, 0x1F, 0x07}, // , 0x00}, // 'W' // {0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x07, 0x1F, 0x1C, 0x07, 0x1C, 0x1F, 0x07}, // , 0x00}, // 'W'
{0x18, 0x78, 0xE0, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x18, 0x1E, 0x07, 0x01, 0x07, 0x1E, 0x18}, // , 0x00}, // 'X' // {0x18, 0x78, 0xE0, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x18, 0x1E, 0x07, 0x01, 0x07, 0x1E, 0x18}, // , 0x00}, // 'X'
{0x00, 0x78, 0xF8, 0x80, 0x80, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'Y' // {0x00, 0x78, 0xF8, 0x80, 0x80, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'Y'
{0x38, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x38, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x1C}, // , 0x00}, // 'Z' // {0x38, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x38, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x1C}, // , 0x00}, // 'Z'
{0x00, 0x00, 0xF8, 0xF8, 0x08, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x00}, // , 0x00}, // '[' // {0x00, 0x00, 0xF8, 0xF8, 0x08, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x00}, // , 0x00}, // '['
{0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x1C}, // , 0x00}, // '"\' // {0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x1C}, // , 0x00}, // '"\'
{0x00, 0x00, 0x08, 0x08, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x00}, // , 0x00}, // ']' // {0x00, 0x00, 0x08, 0x08, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x00}, // , 0x00}, // ']'
{0x10, 0x18, 0x0E, 0x07, 0x0E, 0x18, 0x10, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '^' // {0x10, 0x18, 0x0E, 0x07, 0x0E, 0x18, 0x10, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '^'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, // , 0x40}, // '_' // {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, // , 0x40}, // '_'
{0x00, 0x00, 0x07, 0x0F, 0x08, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '`' // {0x00, 0x00, 0x07, 0x0F, 0x08, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '`'
{0x00, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x0E, 0x1F, 0x11, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'a' // {0x00, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x0E, 0x1F, 0x11, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'a'
{0x08, 0xF8, 0xF8, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x10, 0x1F, 0x0F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'b' // {0x08, 0xF8, 0xF8, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x10, 0x1F, 0x0F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'b'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x18, 0x08}, // , 0x00}, // 'c' // {0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x18, 0x08}, // , 0x00}, // 'c'
{0x00, 0x80, 0xC0, 0x48, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'd' // {0x00, 0x80, 0xC0, 0x48, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'd'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x11, 0x11, 0x11, 0x19, 0x09}, // , 0x00}, // 'e' // {0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x11, 0x11, 0x11, 0x19, 0x09}, // , 0x00}, // 'e'
{0x80, 0xF0, 0xF8, 0x88, 0x18, 0x30, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'f' // {0x80, 0xF0, 0xF8, 0x88, 0x18, 0x30, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'f'
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x4F, 0xDF, 0x90, 0x90, 0xFF, 0x7F, 0x00}, // , 0x00}, // 'g' // {0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x4F, 0xDF, 0x90, 0x90, 0xFF, 0x7F, 0x00}, // , 0x00}, // 'g'
{0x08, 0xF8, 0xF8, 0x80, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'h' // {0x08, 0xF8, 0xF8, 0x80, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'h'
{0x00, 0x00, 0x40, 0xD8, 0xD8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'i' // {0x00, 0x00, 0x40, 0xD8, 0xD8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'i'
{0x00, 0x00, 0x00, 0x00, 0x40, 0xD8, 0xD8, /*0x00,*/ 0x00, 0x60, 0xE0, 0x80, 0x80, 0xFF, 0x7F}, // , 0x00}, // 'j' // {0x00, 0x00, 0x00, 0x00, 0x40, 0xD8, 0xD8, /*0x00,*/ 0x00, 0x60, 0xE0, 0x80, 0x80, 0xFF, 0x7F}, // , 0x00}, // 'j'
{0x08, 0xF8, 0xF8, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x03, 0x07, 0x1C, 0x18}, // , 0x00}, // 'k' // {0x08, 0xF8, 0xF8, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x03, 0x07, 0x1C, 0x18}, // , 0x00}, // 'k'
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'l' // {0x00, 0x00, 0x08, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'l'
{0xC0, 0xC0, 0xC0, 0x80, 0xC0, 0xC0, 0x80, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'm' // {0xC0, 0xC0, 0xC0, 0x80, 0xC0, 0xC0, 0x80, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'm'
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'n' // {0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'n'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'o' // {0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'o'
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x80, 0xFF, 0xFF, 0x90, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'p' // {0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x80, 0xFF, 0xFF, 0x90, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'p'
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x90, 0xFF, 0xFF, 0x80}, // , 0x00}, // 'q' // {0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x90, 0xFF, 0xFF, 0x80}, // , 0x00}, // 'q'
{0x40, 0xC0, 0x80, 0xC0, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x01}, // , 0x00}, // 'r' // {0x40, 0xC0, 0x80, 0xC0, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x01}, // , 0x00}, // 'r'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x08, 0x19, 0x13, 0x12, 0x16, 0x1C, 0x08}, // , 0x00}, // 's' // {0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x08, 0x19, 0x13, 0x12, 0x16, 0x1C, 0x08}, // , 0x00}, // 's'
{0x40, 0x40, 0xF0, 0xF8, 0x40, 0x40, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x18, 0x08}, // , 0x00}, // 't' // {0x40, 0x40, 0xF0, 0xF8, 0x40, 0x40, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x18, 0x08}, // , 0x00}, // 't'
{0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'u' // {0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'u'
{0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x00, 0x07, 0x0F, 0x18, 0x18, 0x0F, 0x07}, // , 0x00}, // 'v' // {0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x00, 0x07, 0x0F, 0x18, 0x18, 0x0F, 0x07}, // , 0x00}, // 'v'
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x0F, 0x1F, 0x18, 0x0E, 0x18, 0x1F, 0x0F}, // , 0x00}, // 'w' // {0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x0F, 0x1F, 0x18, 0x0E, 0x18, 0x1F, 0x0F}, // , 0x00}, // 'w'
{0x40, 0xC0, 0x80, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x18, 0x0F, 0x07, 0x0F, 0x18, 0x10}, // , 0x00}, // 'x' // {0x40, 0xC0, 0x80, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x18, 0x0F, 0x07, 0x0F, 0x18, 0x10}, // , 0x00}, // 'x'
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x8F, 0x9F, 0x90, 0x90, 0xD0, 0x7F, 0x3F}, // , 0x00}, // 'y' // {0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x8F, 0x9F, 0x90, 0x90, 0xD0, 0x7F, 0x3F}, // , 0x00}, // 'y'
{0xC0, 0xC0, 0x40, 0x40, 0xC0, 0xC0, 0x40, /*0x00,*/ 0x18, 0x1C, 0x16, 0x13, 0x11, 0x18, 0x18}, // , 0x00}, // 'z' // {0xC0, 0xC0, 0x40, 0x40, 0xC0, 0xC0, 0x40, /*0x00,*/ 0x18, 0x1C, 0x16, 0x13, 0x11, 0x18, 0x18}, // , 0x00}, // 'z'
{0x00, 0x80, 0x80, 0xF0, 0x78, 0x08, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10}, // , 0x00}, // '{' // {0x00, 0x80, 0x80, 0xF0, 0x78, 0x08, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10}, // , 0x00}, // '{'
{0x00, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00}, // , 0x00}, // '|' // {0x00, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00}, // , 0x00}, // '|'
{0x00, 0x08, 0x08, 0x78, 0xF0, 0x80, 0x80, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x0F, 0x00, 0x00}, // , 0x00}, // '}' // {0x00, 0x08, 0x08, 0x78, 0xF0, 0x80, 0x80, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x0F, 0x00, 0x00}, // , 0x00}, // '}'
{0x10, 0x18, 0x08, 0x18, 0x10, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // , 0x00} // '->' // {0x10, 0x18, 0x08, 0x18, 0x10, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // , 0x00} // '->'
#else //#else
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' ' // // {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' '
{0x00, 0x00, 0x00, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '!' // {0x00, 0x00, 0x00, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '!'
{0x00, 0x0F, 0x1F, 0x00, 0x00, 0x1F, 0x0F, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '"' // {0x00, 0x0F, 0x1F, 0x00, 0x00, 0x1F, 0x0F, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '"'
{0x20, 0xF8, 0xF8, 0x20, 0xF8, 0xF8, 0x20, /*0x00,*/ 0x02, 0x0F, 0x0F, 0x02, 0x0F, 0x0F, 0x02}, // '#' // {0x20, 0xF8, 0xF8, 0x20, 0xF8, 0xF8, 0x20, /*0x00,*/ 0x02, 0x0F, 0x0F, 0x02, 0x0F, 0x0F, 0x02}, // '#'
{0x70, 0xF8, 0x88, 0x8E, 0x8E, 0x98, 0x10, /*0x00,*/ 0x04, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // '$' // {0x70, 0xF8, 0x88, 0x8E, 0x8E, 0x98, 0x10, /*0x00,*/ 0x04, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // '$'
{0x30, 0x30, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x0C, 0x0C}, // '%' // {0x30, 0x30, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x0C, 0x0C}, // '%'
{0x80, 0xD8, 0x7C, 0xE4, 0xBC, 0xD8, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x07, 0x0F, 0x08}, // '&' // {0x80, 0xD8, 0x7C, 0xE4, 0xBC, 0xD8, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x07, 0x0F, 0x08}, // '&'
{0x00, 0x10, 0x1F, 0x0F, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ''' // {0x00, 0x10, 0x1F, 0x0F, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '''
{0x00, 0x00, 0xF0, 0xF8, 0x0C, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x03, 0x07, 0x0C, 0x08, 0x00}, // '(' // {0x00, 0x00, 0xF0, 0xF8, 0x0C, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x03, 0x07, 0x0C, 0x08, 0x00}, // '('
{0x00, 0x00, 0x04, 0x0C, 0xF8, 0xF0, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0C, 0x07, 0x03, 0x00}, // ')' // {0x00, 0x00, 0x04, 0x0C, 0xF8, 0xF0, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0C, 0x07, 0x03, 0x00}, // ')'
{0x00, 0x80, 0xA0, 0xE0, 0xC0, 0xE0, 0xA0, /*0x80,*/ 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x02}, // '*' // {0x00, 0x80, 0xA0, 0xE0, 0xC0, 0xE0, 0xA0, /*0x80,*/ 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x02}, // '*'
{0x00, 0x80, 0x80, 0xE0, 0xE0, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00}, // '+' // {0x00, 0x80, 0x80, 0xE0, 0xE0, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00}, // '+'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1E, 0x0E, 0x00, 0x00}, // ',' // {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1E, 0x0E, 0x00, 0x00}, // ','
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '-' // {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '-'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // '.' // {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // '.'
{0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00}, // '/' // {0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00}, // '/'
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '0' // {0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '0'
{0x00, 0x10, 0x18, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08}, // '1' // {0x00, 0x10, 0x18, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08}, // '1'
{0x18, 0x1C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // '2' // {0x18, 0x1C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // '2'
{0x18, 0x1C, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '3' // {0x18, 0x1C, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '3'
{0x80, 0xC0, 0x60, 0x30, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x0F}, // '4' // {0x80, 0xC0, 0x60, 0x30, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x0F}, // '4'
{0x7C, 0x7C, 0x44, 0x44, 0x44, 0xC4, 0x84, /*0x00,*/ 0x04, 0x0C, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '5' // {0x7C, 0x7C, 0x44, 0x44, 0x44, 0xC4, 0x84, /*0x00,*/ 0x04, 0x0C, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '5'
{0xF0, 0xF8, 0x4C, 0x44, 0x44, 0xC4, 0x80, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '6' // {0xF0, 0xF8, 0x4C, 0x44, 0x44, 0xC4, 0x80, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '6'
{0x04, 0x04, 0x04, 0x84, 0xE4, 0x7C, 0x1C, /*0x00,*/ 0x00, 0x00, 0x0E, 0x0F, 0x01, 0x00, 0x00}, // '7' // {0x04, 0x04, 0x04, 0x84, 0xE4, 0x7C, 0x1C, /*0x00,*/ 0x00, 0x00, 0x0E, 0x0F, 0x01, 0x00, 0x00}, // '7'
{0xB8, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '8' // {0xB8, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '8'
{0x78, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x00, 0x08, 0x08, 0x08, 0x0C, 0x07, 0x03}, // '9' // {0x78, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x00, 0x08, 0x08, 0x08, 0x0C, 0x07, 0x03}, // '9'
{0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00}, // ':' // {0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00}, // ':'
{0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0E, 0x06, 0x00, 0x00}, // ';' // {0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0E, 0x06, 0x00, 0x00}, // ';'
{0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x08}, // '<' // {0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x08}, // '<'
{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /*0x00,*/ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}, // '=' // {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /*0x00,*/ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}, // '='
{0x00, 0x08, 0x18, 0x30, 0x60, 0xC0, 0x80, /*0x00,*/ 0x00, 0x08, 0x0C, 0x06, 0x03, 0x01, 0x00}, // '>' // {0x00, 0x08, 0x18, 0x30, 0x60, 0xC0, 0x80, /*0x00,*/ 0x00, 0x08, 0x0C, 0x06, 0x03, 0x01, 0x00}, // '>'
{0x38, 0x3C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '?' // {0x38, 0x3C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '?'
{0xF0, 0xF8, 0x08, 0xC8, 0xC8, 0xF8, 0xF0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x01}, // '@' // {0xF0, 0xF8, 0x08, 0xC8, 0xC8, 0xF8, 0xF0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x01}, // '@'
{0xF8, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'A' // {0xF8, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'A'
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'B' // {0xFC, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'B'
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0x1C, 0x18, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0E, 0x06}, // 'C' // {0xF8, 0xFC, 0x04, 0x04, 0x04, 0x1C, 0x18, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0E, 0x06}, // 'C'
{0xFC, 0xFC, 0x04, 0x04, 0x0C, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x0C, 0x07, 0x03}, // 'D' // {0xFC, 0xFC, 0x04, 0x04, 0x0C, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x0C, 0x07, 0x03}, // 'D'
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'E' // {0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'E'
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'F' // {0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'F'
{0xF8, 0xFC, 0x04, 0x84, 0x84, 0x9C, 0x98, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'G' // {0xF8, 0xFC, 0x04, 0x84, 0x84, 0x9C, 0x98, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'G'
{0xFC, 0xFC, 0x40, 0x40, 0x40, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'H' // {0xFC, 0xFC, 0x40, 0x40, 0x40, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'H'
{0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'I' // {0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'I'
{0x00, 0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x0F, 0x07, 0x00}, // 'J' // {0x00, 0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x0F, 0x07, 0x00}, // 'J'
{0xFC, 0xFC, 0xE0, 0x30, 0x18, 0x0C, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'K' // {0xFC, 0xFC, 0xE0, 0x30, 0x18, 0x0C, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'K'
{0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'L' // {0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'L'
{0xFC, 0xFC, 0x18, 0x70, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'M' // {0xFC, 0xFC, 0x18, 0x70, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'M'
{0xFC, 0xFC, 0x60, 0xC0, 0x80, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0F}, // 'N' // {0xFC, 0xFC, 0x60, 0xC0, 0x80, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0F}, // 'N'
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'O' // {0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'O'
{0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'P' // {0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'P'
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0C, 0x0C, 0x1F, 0x17}, // 'Q' // {0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0C, 0x0C, 0x1F, 0x17}, // 'Q'
{0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'R' // {0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'R'
{0x38, 0x7C, 0x44, 0x44, 0x44, 0xCC, 0x88, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'S' // {0x38, 0x7C, 0x44, 0x44, 0x44, 0xCC, 0x88, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'S'
{0x00, 0x04, 0x04, 0xFC, 0xFC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'T' // {0x00, 0x04, 0x04, 0xFC, 0xFC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'T'
{0xFC, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'U' // {0xFC, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'U'
{0x7C, 0xFC, 0x80, 0x00, 0x80, 0xFC, 0x7C, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'V' // {0x7C, 0xFC, 0x80, 0x00, 0x80, 0xFC, 0x7C, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'V'
{0xFC, 0xFC, 0x00, 0x80, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x06, 0x03, 0x06, 0x0F, 0x0F}, // 'W' // {0xFC, 0xFC, 0x00, 0x80, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x06, 0x03, 0x06, 0x0F, 0x0F}, // 'W'
{0x0C, 0x3C, 0xF0, 0xC0, 0xF0, 0x3C, 0x0C, /*0x00,*/ 0x0C, 0x0F, 0x03, 0x00, 0x03, 0x0F, 0x0C}, // 'X' // {0x0C, 0x3C, 0xF0, 0xC0, 0xF0, 0x3C, 0x0C, /*0x00,*/ 0x0C, 0x0F, 0x03, 0x00, 0x03, 0x0F, 0x0C}, // 'X'
{0x00, 0x3C, 0x7C, 0xC0, 0xC0, 0x7C, 0x3C, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'Y' // {0x00, 0x3C, 0x7C, 0xC0, 0xC0, 0x7C, 0x3C, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'Y'
{0x04, 0x04, 0x84, 0xC4, 0x64, 0x3C, 0x1C, /*0x00,*/ 0x0E, 0x0F, 0x09, 0x08, 0x08, 0x08, 0x08}, // 'Z' // {0x04, 0x04, 0x84, 0xC4, 0x64, 0x3C, 0x1C, /*0x00,*/ 0x0E, 0x0F, 0x09, 0x08, 0x08, 0x08, 0x08}, // 'Z'
{0x00, 0x00, 0xFC, 0xFC, 0x04, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x00}, // '[' // {0x00, 0x00, 0xFC, 0xFC, 0x04, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x00}, // '['
{0x38, 0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E}, // '"\' // {0x38, 0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E}, // '"\'
{0x00, 0x00, 0x04, 0x04, 0xFC, 0xFC, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x00}, // ']' // {0x00, 0x00, 0x04, 0x04, 0xFC, 0xFC, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x00}, // ']'
{0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '^' // {0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '^'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, // '_' // {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, // '_'
{0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '`' // {0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '`'
{0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'a' // {0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'a'
{0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'b' // {0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'b'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0x60, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0C, 0x04}, // 'c' // {0xC0, 0xE0, 0x20, 0x20, 0x20, 0x60, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0C, 0x04}, // 'c'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'd' // {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'd'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x09, 0x09, 0x09, 0x09, 0x01}, // 'e' // {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x09, 0x09, 0x09, 0x09, 0x01}, // 'e'
{0x20, 0x20, 0xF8, 0xFC, 0x24, 0x24, 0x04, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00}, // 'f' // {0x20, 0x20, 0xF8, 0xFC, 0x24, 0x24, 0x04, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00}, // 'f'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'g' // {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'g'
{0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'h' // {0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'h'
{0x00, 0x00, 0x20, 0xEC, 0xEC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'i' // {0x00, 0x00, 0x20, 0xEC, 0xEC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'i'
{0x00, 0x00, 0x00, 0x00, 0x20, 0xEC, 0xEC, /*0x00,*/ 0x00, 0x30, 0x70, 0x40, 0x40, 0x7F, 0x3F}, // 'j' // {0x00, 0x00, 0x00, 0x00, 0x20, 0xEC, 0xEC, /*0x00,*/ 0x00, 0x30, 0x70, 0x40, 0x40, 0x7F, 0x3F}, // 'j'
{0xFC, 0xFC, 0x00, 0x80, 0xC0, 0x60, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'k' // {0xFC, 0xFC, 0x00, 0x80, 0xC0, 0x60, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'k'
{0x00, 0x00, 0x04, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'l' // {0x00, 0x00, 0x04, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'l'
{0xE0, 0xE0, 0x20, 0xE0, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x0F}, // 'm' // {0xE0, 0xE0, 0x20, 0xE0, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x0F}, // 'm'
{0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'n' // {0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'n'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'o' // {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'o'
{0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x7F, 0x7F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'p' // {0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x7F, 0x7F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'p'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x7F, 0x7F}, // 'q' // {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x7F, 0x7F}, // 'q'
{0xE0, 0xE0, 0x60, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'r' // {0xE0, 0xE0, 0x60, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'r'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x08, 0x09, 0x09, 0x09, 0x09, 0x0F, 0x06}, // 's' // {0xC0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x08, 0x09, 0x09, 0x09, 0x09, 0x0F, 0x06}, // 's'
{0x20, 0x20, 0xFC, 0xFC, 0x20, 0x20, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08}, // 't' // {0x20, 0x20, 0xFC, 0xFC, 0x20, 0x20, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08}, // 't'
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'u' // {0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'u'
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'v' // {0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'v'
{0xE0, 0xE0, 0x00, 0x80, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0F, 0x08, 0x0F, 0x07}, // 'w' // {0xE0, 0xE0, 0x00, 0x80, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0F, 0x08, 0x0F, 0x07}, // 'w'
{0x60, 0xE0, 0x80, 0x00, 0x80, 0xE0, 0x60, /*0x00,*/ 0x0C, 0x0E, 0x03, 0x01, 0x03, 0x0E, 0x0C}, // 'x' // {0x60, 0xE0, 0x80, 0x00, 0x80, 0xE0, 0x60, /*0x00,*/ 0x0C, 0x0E, 0x03, 0x01, 0x03, 0x0E, 0x0C}, // 'x'
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'y' // {0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'y'
{0x20, 0x20, 0x20, 0xA0, 0xE0, 0x60, 0x20, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // 'z' // {0x20, 0x20, 0x20, 0xA0, 0xE0, 0x60, 0x20, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // 'z'
{0x00, 0x00, 0x40, 0xF8, 0xBC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08}, // '{' // {0x00, 0x00, 0x40, 0xF8, 0xBC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08}, // '{'
{0x00, 0x00, 0x00, 0xBC, 0xBC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // '|' // {0x00, 0x00, 0x00, 0xBC, 0xBC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // '|'
{0x00, 0x04, 0x04, 0xBC, 0xF8, 0x40, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x07, 0x00, 0x00}, // '}' // {0x00, 0x04, 0x04, 0xBC, 0xF8, 0x40, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x07, 0x00, 0x00}, // '}'
{0x08, 0x0C, 0x04, 0x0C, 0x08, 0x0C, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // '->' // {0x08, 0x0C, 0x04, 0x0C, 0x08, 0x0C, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // '->'
#endif //#endif
}; //};
#if 0 #if 0
// original font // original font
@@ -252,20 +252,20 @@ const uint8_t gFontBig[95 - 1][16 - 2] =
#else #else
// Terminus font // Terminus font
const uint8_t gFontBigDigits[11][26 - 6] = // const uint8_t gFontBigDigits[11][26 - 6] =
{ // {
{/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/}, // {/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/},
{/*0x00, 0x00,*/ 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x7F, 0x60, 0x60, 0x00, /*0x00*/}, // {/*0x00, 0x00,*/ 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x7F, 0x60, 0x60, 0x00, /*0x00*/},
{/*0x00, 0x00,*/ 0x1C, 0x1E, 0x1E, 0x06, 0x06, 0x06, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x60, 0x70, 0x78, 0x7C, 0x6E, 0x67, 0x63, 0x61, 0x60, 0x60, /*0x00*/}, // {/*0x00, 0x00,*/ 0x1C, 0x1E, 0x1E, 0x06, 0x06, 0x06, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x60, 0x70, 0x78, 0x7C, 0x6E, 0x67, 0x63, 0x61, 0x60, 0x60, /*0x00*/},
{/*0x00, 0x00,*/ 0x0C, 0x0E, 0x0E, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3E, /*0x00*/}, // {/*0x00, 0x00,*/ 0x0C, 0x0E, 0x0E, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3E, /*0x00*/},
{/*0x00, 0x00,*/ 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0xFE, 0xFE, 0xFE, /*0x00,*/ /*0x00, 0x00,*/ 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x7F, 0x7F, 0x7F, /*0x00*/}, // {/*0x00, 0x00,*/ 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0xFE, 0xFE, 0xFE, /*0x00,*/ /*0x00, 0x00,*/ 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x7F, 0x7F, 0x7F, /*0x00*/},
{/*0x00, 0x00,*/ 0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x86, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/}, // {/*0x00, 0x00,*/ 0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x86, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/},
{/*0x00, 0x00,*/ 0xF8, 0xFC, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x80, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/}, // {/*0x00, 0x00,*/ 0xF8, 0xFC, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x80, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/},
{/*0x00, 0x00,*/ 0x0E, 0x0E, 0x0E, 0x06, 0x06, 0x86, 0xE6, 0xFE, 0x7E, 0x1E, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7F, 0x7F, 0x03, 0x00, 0x00, /*0x00*/}, // {/*0x00, 0x00,*/ 0x0E, 0x0E, 0x0E, 0x06, 0x06, 0x86, 0xE6, 0xFE, 0x7E, 0x1E, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7F, 0x7F, 0x03, 0x00, 0x00, /*0x00*/},
{/*0x00, 0x00,*/ 0x7C, 0xFE, 0xFE, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3F, /*0x00*/}, // {/*0x00, 0x00,*/ 0x7C, 0xFE, 0xFE, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3F, /*0x00*/},
{/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x01, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7F, 0x3F, 0x1F, /*0x00*/}, // {/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x01, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7F, 0x3F, 0x1F, /*0x00*/},
{/*0x00, 0x00,*/ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, /*0x00*/} // {/*0x00, 0x00,*/ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, /*0x00*/}
}; // };
#endif #endif
/* /*
const uint8_t gFontSmallDigits[11][7] = const uint8_t gFontSmallDigits[11][7] =

View File

@@ -28,26 +28,26 @@ const freq_band_table_t BX4819_band1 = {BX4819_band1_lower, 63000000};
const freq_band_table_t BX4819_band2 = {84000000, BX4819_band2_upper}; const freq_band_table_t BX4819_band2 = {84000000, BX4819_band2_upper};
const freq_band_table_t frequencyBandTable[] = const freq_band_table_t frequencyBandTable[] =
{ {
#ifndef ENABLE_WIDE_RX #ifndef ENABLE_WIDE_RX
// QS original // QS original
[BAND1_50MHz ]={.lower = 5000000, .upper = 7600000}, [BAND1_50MHz ]={.lower = 5000000, .upper = 7600000},
[BAND7_470MHz]={.lower = 47000000, .upper = 60000000}, [BAND7_470MHz]={.lower = 47000000, .upper = 60000000},
#else #else
// extended range // extended range
[BAND1_50MHz ]={.lower = BX4819_band1_lower, .upper = 10800000}, [BAND1_50MHz]={.lower = BX4819_band1_lower, .upper = 10800000},
[BAND7_470MHz]={.lower = 47000000, .upper = BX4819_band2_upper}, [BAND7_470MHz]={.lower = 47000000, .upper = BX4819_band2_upper},
#endif #endif
[BAND2_108MHz]={.lower = 10800000, .upper = 13700000}, [BAND2_108MHz]={.lower = 10800000, .upper = 13700000},
[BAND3_137MHz]={.lower = 13700000, .upper = 17400000}, [BAND3_137MHz]={.lower = 13700000, .upper = 17400000},
[BAND4_174MHz]={.lower = 17400000, .upper = 35000000}, [BAND4_174MHz]={.lower = 17400000, .upper = 35000000},
[BAND5_350MHz]={.lower = 35000000, .upper = 40000000}, [BAND5_350MHz]={.lower = 35000000, .upper = 40000000},
[BAND6_400MHz]={.lower = 40000000, .upper = 47000000} [BAND6_400MHz]={.lower = 40000000, .upper = 47000000}
}; };
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
const uint32_t NoaaFrequencyTable[10] = const uint32_t NoaaFrequencyTable[10] =
{ {
16255000, 16255000,
16240000, 16240000,
16247500, 16247500,
@@ -58,7 +58,7 @@ const freq_band_table_t frequencyBandTable[] =
16152500, 16152500,
16177500, 16177500,
16327500 16327500
}; };
#endif #endif
@@ -94,20 +94,20 @@ const uint16_t gStepFrequencyTable[] = {
const STEP_Setting_t StepSortedIndexes[] = { 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_0_01kHz, STEP_0_05kHz, STEP_0_1kHz, STEP_0_25kHz, STEP_0_5kHz, STEP_1kHz, STEP_1_25kHz, STEP_2_5kHz,
STEP_8_33kHz, STEP_9kHz, STEP_10kHz, STEP_12_5kHz, STEP_15kHz, STEP_20kHz, STEP_25kHz, STEP_30kHz, STEP_50kHz, STEP_100kHz, STEP_5kHz, STEP_6_25kHz,
STEP_8_33kHz, STEP_9kHz, STEP_10kHz, STEP_12_5kHz, STEP_15kHz, STEP_20kHz, STEP_25kHz, STEP_30kHz, STEP_50kHz,
STEP_100kHz,
STEP_125kHz, STEP_200kHz, STEP_250kHz, STEP_500kHz STEP_125kHz, STEP_200kHz, STEP_250kHz, STEP_500kHz
}; };
STEP_Setting_t FREQUENCY_GetStepIdxFromSortedIdx(uint8_t sortedIdx) STEP_Setting_t FREQUENCY_GetStepIdxFromSortedIdx(uint8_t sortedIdx) {
{
return StepSortedIndexes[sortedIdx]; return StepSortedIndexes[sortedIdx];
} }
uint32_t FREQUENCY_GetSortedIdxFromStepIdx(uint8_t stepIdx) uint32_t FREQUENCY_GetSortedIdxFromStepIdx(uint8_t stepIdx) {
{ for (uint8_t i = 0; i < ARRAY_SIZE(gStepFrequencyTable); i++)
for(uint8_t i = 0; i < ARRAY_SIZE(gStepFrequencyTable); i++) if (StepSortedIndexes[i] == stepIdx)
if(StepSortedIndexes[i] == stepIdx)
return i; return i;
return 0; return 0;
} }
@@ -115,25 +115,24 @@ uint32_t FREQUENCY_GetSortedIdxFromStepIdx(uint8_t stepIdx)
static_assert(ARRAY_SIZE(gStepFrequencyTable) == STEP_N_ELEM); static_assert(ARRAY_SIZE(gStepFrequencyTable) == STEP_N_ELEM);
FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency) FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency) {
{
for (int32_t band = BAND_N_ELEM - 1; band >= 0; band--) for (int32_t band = BAND_N_ELEM - 1; band >= 0; band--)
if (Frequency >= frequencyBandTable[band].lower) if (Frequency >= frequencyBandTable[band].lower)
return (FREQUENCY_Band_t)band; return (FREQUENCY_Band_t) band;
return BAND1_50MHz; return BAND1_50MHz;
} }
uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, int32_t LowerLimit, int32_t Middle, int32_t UpperLimit, int32_t Frequency) uint8_t
{ FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, int32_t LowerLimit, int32_t Middle,
int32_t UpperLimit, int32_t Frequency) {
if (Frequency <= LowerLimit) if (Frequency <= LowerLimit)
return TxpLow; return TxpLow;
if (UpperLimit <= Frequency) if (UpperLimit <= Frequency)
return TxpHigh; return TxpHigh;
if (Frequency <= Middle) if (Frequency <= Middle) {
{
TxpMid += ((TxpMid - TxpLow) * (Frequency - LowerLimit)) / (Middle - LowerLimit); TxpMid += ((TxpMid - TxpLow) * (Frequency - LowerLimit)) / (Middle - LowerLimit);
return TxpMid; return TxpMid;
} }
@@ -144,23 +143,22 @@ uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t T
} }
uint32_t FREQUENCY_RoundToStep(uint32_t freq, uint16_t step) uint32_t FREQUENCY_RoundToStep(uint32_t freq, uint16_t step) {
{ if (step == 833) {
if(step == 833) { uint32_t base = freq / 2500 * 2500;
uint32_t base = freq/2500*2500; int chno =
int chno = (freq - base) / 700; // convert entered aviation 8.33Khz channel number scheme to actual frequency. (freq - base) / 700; // convert entered aviation 8.33Khz channel number scheme to actual frequency.
return base + (chno * 833) + (chno == 3); return base + (chno * 833) + (chno == 3);
} }
if(step == 1) if (step == 1)
return freq; return freq;
if(step >= 1000) if (step >= 1000)
step = step/2; step = step / 2;
return (freq + (step + 1) / 2) / step * step; return (freq + (step + 1) / 2) / step * step;
} }
int32_t TX_freq_check(const uint32_t Frequency) int32_t TX_freq_check(const uint32_t Frequency) { // return '0' if TX frequency is allowed
{ // return '0' if TX frequency is allowed
// otherwise return '-1' // otherwise return '-1'
if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper) if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper)
@@ -169,66 +167,58 @@ int32_t TX_freq_check(const uint32_t Frequency)
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
return -1; // BX chip does not work in this range return -1; // BX chip does not work in this range
switch (gSetting_F_LOCK) switch (gSetting_F_LOCK) {
{
case F_LOCK_DEF: case F_LOCK_DEF:
if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < frequencyBandTable[BAND3_137MHz].upper) if (Frequency >= frequencyBandTable[BAND3_137MHz].lower &&
Frequency < frequencyBandTable[BAND3_137MHz].upper)
return 0; return 0;
if (Frequency >= frequencyBandTable[BAND4_174MHz].lower && Frequency < frequencyBandTable[BAND4_174MHz].upper) if (Frequency >= frequencyBandTable[BAND4_174MHz].lower &&
#ifndef ENABLE_FEAT_F4HWN Frequency < frequencyBandTable[BAND4_174MHz].upper)
if (gSetting_200TX)
#endif
return 0; return 0;
if (Frequency >= frequencyBandTable[BAND5_350MHz].lower && Frequency < frequencyBandTable[BAND5_350MHz].upper) if (Frequency >= frequencyBandTable[BAND5_350MHz].lower &&
#ifndef ENABLE_FEAT_F4HWN Frequency < frequencyBandTable[BAND5_350MHz].upper)
if (gSetting_350TX && gSetting_350EN)
#else
if (gSetting_350EN)
#endif
return 0; return 0;
if (Frequency >= frequencyBandTable[BAND6_400MHz].lower && Frequency < frequencyBandTable[BAND6_400MHz].upper) if (Frequency >= frequencyBandTable[BAND6_400MHz].lower &&
Frequency < frequencyBandTable[BAND6_400MHz].upper)
return 0; return 0;
if (Frequency >= frequencyBandTable[BAND7_470MHz].lower && Frequency <= 60000000) if (Frequency >= frequencyBandTable[BAND7_470MHz].lower && Frequency <= 60000000)
#ifndef ENABLE_FEAT_F4HWN
if (gSetting_500TX)
#endif
return 0; return 0;
break; break;
case F_LOCK_FCC: // case F_LOCK_FCC:
if (Frequency >= 14400000 && Frequency < 14800000) // if (Frequency >= 14400000 && Frequency < 14800000)
return 0; // return 0;
if (Frequency >= 42000000 && Frequency < 45000000) // if (Frequency >= 42000000 && Frequency < 45000000)
return 0; // return 0;
break; // break;
//
case F_LOCK_CE: // case F_LOCK_CE:
if (Frequency >= 14400000 && Frequency < 14600000) // if (Frequency >= 14400000 && Frequency < 14600000)
return 0; // return 0;
if (Frequency >= 43000000 && Frequency < 44000000) // if (Frequency >= 43000000 && Frequency < 44000000)
return 0; // return 0;
break; // break;
//
case F_LOCK_GB: // case F_LOCK_GB:
if (Frequency >= 14400000 && Frequency < 14800000) // if (Frequency >= 14400000 && Frequency < 14800000)
return 0; // return 0;
if (Frequency >= 43000000 && Frequency < 44000000) // if (Frequency >= 43000000 && Frequency < 44000000)
return 0; // return 0;
break; // break;
//
case F_LOCK_430: // case F_LOCK_430:
if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000) // if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000)
return 0; // return 0;
if (Frequency >= 40000000 && Frequency < 43000000) // if (Frequency >= 40000000 && Frequency < 43000000)
return 0; // return 0;
break; // break;
//
case F_LOCK_438: // case F_LOCK_438:
if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000) // if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000)
return 0; // return 0;
if (Frequency >= 40000000 && Frequency < 43800000) // if (Frequency >= 40000000 && Frequency < 43800000)
return 0; // return 0;
break; // break;
#ifdef ENABLE_FEAT_F4HWN_PMR #ifdef ENABLE_FEAT_F4HWN_PMR
case F_LOCK_PMR: case F_LOCK_PMR:
@@ -275,8 +265,7 @@ int32_t TX_freq_check(const uint32_t Frequency)
return -1; return -1;
} }
int32_t RX_freq_check(const uint32_t Frequency) int32_t RX_freq_check(const uint32_t Frequency) { // return '0' if RX frequency is allowed
{ // return '0' if RX frequency is allowed
// otherwise return '-1' // otherwise return '-1'
if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper) if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper)

View File

@@ -17,16 +17,24 @@
#include <string.h> #include <string.h>
#include "app/dtmf.h" #include "app/dtmf.h"
#if defined(ENABLE_FMRADIO) #if defined(ENABLE_FMRADIO)
#include "app/fm.h"
#include "app/fm.h"
#endif #endif
#include "audio.h" #include "audio.h"
#include "bsp/dp32g030/gpio.h" #include "bsp/dp32g030/gpio.h"
#include "dcs.h" #include "dcs.h"
#include "driver/backlight.h" #include "driver/backlight.h"
#if defined(ENABLE_FMRADIO) #if defined(ENABLE_FMRADIO)
#include "driver/bk1080.h"
#include "driver/bk1080.h"
#endif #endif
#include "driver/bk4819.h" #include "driver/bk4819.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "driver/system.h" #include "driver/system.h"
@@ -39,18 +47,19 @@
#include "settings.h" #include "settings.h"
#include "ui/status.h" #include "ui/status.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "app/app.h"
#include "driver/systick.h"
FUNCTION_Type_t gCurrentFunction; FUNCTION_Type_t gCurrentFunction;
bool FUNCTION_IsRx() bool FUNCTION_IsRx() {
{
return gCurrentFunction == FUNCTION_MONITOR || return gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING || gCurrentFunction == FUNCTION_INCOMING ||
gCurrentFunction == FUNCTION_RECEIVE; gCurrentFunction == FUNCTION_RECEIVE;
} }
void FUNCTION_Init(void) void FUNCTION_Init(void) {
{
g_CxCSS_TAIL_Found = false; g_CxCSS_TAIL_Found = false;
g_CDCSS_Lost = false; g_CDCSS_Lost = false;
g_CTCSS_Lost = false; g_CTCSS_Lost = false;
@@ -86,8 +95,7 @@ void FUNCTION_Init(void)
gUpdateStatus = true; gUpdateStatus = true;
} }
void FUNCTION_Foreground(const FUNCTION_Type_t PreviousFunction) void FUNCTION_Foreground(const FUNCTION_Type_t PreviousFunction) {
{
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
if (gDTMF_ReplyState != DTMF_REPLY_NONE) if (gDTMF_ReplyState != DTMF_REPLY_NONE)
RADIO_PrepareCssTX(); RADIO_PrepareCssTX();
@@ -109,8 +117,7 @@ void FUNCTION_Foreground(const FUNCTION_Type_t PreviousFunction)
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT || if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT ||
gDTMF_CallState == DTMF_CALL_STATE_RECEIVED || gDTMF_CallState == DTMF_CALL_STATE_RECEIVED ||
gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY) gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY) {
{
gDTMF_auto_reset_time_500ms = gEeprom.DTMF_auto_reset_time * 2; gDTMF_auto_reset_time_500ms = gEeprom.DTMF_auto_reset_time * 2;
} }
#endif #endif
@@ -118,18 +125,15 @@ void FUNCTION_Foreground(const FUNCTION_Type_t PreviousFunction)
} }
void FUNCTION_PowerSave() { void FUNCTION_PowerSave() {
#ifdef ENABLE_FEAT_F4HWN_SLEEP #ifdef ENABLE_FEAT_F4HWN_SLEEP
if(gWakeUp) if (gWakeUp) {
{
gPowerSave_10ms = gEeprom.BATTERY_SAVE * 200; // deep sleep now indexed on BatSav gPowerSave_10ms = gEeprom.BATTERY_SAVE * 200; // deep sleep now indexed on BatSav
} } else {
else
{
gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10; gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10;
} }
#else #else
gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10; gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10;
#endif #endif
gPowerSaveCountdownExpired = false; gPowerSaveCountdownExpired = false;
gRxIdleMode = true; gRxIdleMode = true;
@@ -147,9 +151,11 @@ void FUNCTION_PowerSave() {
GUI_SelectNextDisplay(DISPLAY_MAIN); GUI_SelectNextDisplay(DISPLAY_MAIN);
} }
void FUNCTION_Transmit() void FUNCTION_Transmit() {
{
// if DTMF is enabled when TX'ing, it changes the TX audio filtering !! .. 1of11 // if DTMF is enabled when TX'ing, it changes the TX audio filtering !! .. 1of11
MSG_EnableRX(false);
BK4819_DisableDTMF(); BK4819_DisableDTMF();
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
@@ -167,8 +173,7 @@ void FUNCTION_Transmit()
#endif #endif
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
if (gAlarmState == ALARM_STATE_SITE_ALARM) if (gAlarmState == ALARM_STATE_SITE_ALARM) {
{
GUI_DisplayScreen(); GUI_DisplayScreen();
AUDIO_AudioPathOff(); AUDIO_AudioPathOff();
@@ -200,40 +205,37 @@ void FUNCTION_Transmit()
DTMF_Reply(); DTMF_Reply();
BK4819_SetScramble(gCurrentVfo->SCRAMBLING_TYPE);
if (gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO) if (gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO)
BK4819_PlaySingleTone(2525, 250, 0, gEeprom.DTMF_SIDE_TONE); BK4819_PlaySingleTone(2525, 250, 0, gEeprom.DTMF_SIDE_TONE);
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
if (gAlarmState != ALARM_STATE_OFF) { if (gAlarmState != ALARM_STATE_OFF) {
#ifdef ENABLE_TX1750 #ifdef ENABLE_TX1750
if (gAlarmState == ALARM_STATE_TX1750) if (gAlarmState == ALARM_STATE_TX1750) {
BK4819_TransmitTone(true, 1750); BK4819_TransmitTone(gEeprom.DTMF_SIDE_TONE, 1750);
#endif gAlarmState = ALARM_STATE_OFF;
}
#endif
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
if (gAlarmState == ALARM_STATE_TXALARM) if (gAlarmState == ALARM_STATE_TXALARM)
BK4819_TransmitTone(true, 500); BK4819_TransmitTone(true, 500);
gAlarmToneCounter = 0; gAlarmToneCounter = 0;
#endif #endif
SYSTEM_DelayMs(2); SYSTEM_DelayMs(2);
AUDIO_AudioPathOn(); AUDIO_AudioPathOn();
gEnableSpeaker = true; gEnableSpeaker = true;
BK4819_ExitTxMute();
gVfoConfigureMode = VFO_CONFIGURE; gVfoConfigureMode = VFO_CONFIGURE;
return; return;
} }
#endif #endif
#ifdef ENABLE_FEAT_F4HWN
BK4819_DisableScramble();
#else
if (gCurrentVfo->SCRAMBLING_TYPE > 0 && gSetting_ScrambleEnable)
BK4819_EnableScramble(gCurrentVfo->SCRAMBLING_TYPE - 1);
else
BK4819_DisableScramble();
#endif
if (gSetting_backlight_on_tx_rx & BACKLIGHT_ON_TR_TX) { if (gSetting_backlight_on_tx_rx & BACKLIGHT_ON_TR_TX) {
BACKLIGHT_TurnOn(); BACKLIGHT_TurnOn();
@@ -241,9 +243,7 @@ void FUNCTION_Transmit()
} }
void FUNCTION_Select(FUNCTION_Type_t Function) {
void FUNCTION_Select(FUNCTION_Type_t Function)
{
const FUNCTION_Type_t PreviousFunction = gCurrentFunction; const FUNCTION_Type_t PreviousFunction = gCurrentFunction;
const bool bWasPowerSave = PreviousFunction == FUNCTION_POWER_SAVE; const bool bWasPowerSave = PreviousFunction == FUNCTION_POWER_SAVE;
@@ -301,7 +301,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
gSchedulePowerSave = false; gSchedulePowerSave = false;
#if defined(ENABLE_FMRADIO) #if defined(ENABLE_FMRADIO)
if(Function != FUNCTION_INCOMING) if (Function != FUNCTION_INCOMING)
gFM_RestoreCountdown_10ms = 0; gFM_RestoreCountdown_10ms = 0;
#endif #endif
} }

View File

@@ -14,13 +14,13 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef FUNCTIONS_H #ifndef FUNCTIONS_H
#define FUNCTIONS_H #define FUNCTIONS_H
#include <stdint.h> #include <stdint.h>
enum FUNCTION_Type_t enum FUNCTION_Type_t {
{
FUNCTION_FOREGROUND = 0, // ??? FUNCTION_FOREGROUND = 0, // ???
FUNCTION_TRANSMIT, // transmitting FUNCTION_TRANSMIT, // transmitting
FUNCTION_MONITOR, // receiving with squelch forced open FUNCTION_MONITOR, // receiving with squelch forced open
@@ -32,11 +32,12 @@ enum FUNCTION_Type_t
}; };
typedef enum FUNCTION_Type_t FUNCTION_Type_t; typedef enum FUNCTION_Type_t FUNCTION_Type_t;
extern FUNCTION_Type_t gCurrentFunction; extern FUNCTION_Type_t gCurrentFunction;
void FUNCTION_Init(void); void FUNCTION_Init(void);
void FUNCTION_Select(FUNCTION_Type_t Function); void FUNCTION_Select(FUNCTION_Type_t Function);
bool FUNCTION_IsRx(); bool FUNCTION_IsRx();
#endif #endif

View File

@@ -137,10 +137,6 @@ void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
} }
} }
if ((gScreenToDisplay == DISPLAY_MENU) && UI_MENU_GetCurrentMenuId() == MENU_VOL)
gUpdateDisplay = true;
if (gBatteryCurrent < 501) if (gBatteryCurrent < 501)
{ {
if (gChargingWithTypeC) if (gChargingWithTypeC)

View File

@@ -17,8 +17,9 @@
#include <string.h> #include <string.h>
#ifdef ENABLE_AIRCOPY #ifdef ENABLE_AIRCOPY
#include "app/aircopy.h" #include "app/aircopy.h"
#endif #endif
#include "bsp/dp32g030/gpio.h" #include "bsp/dp32g030/gpio.h"
#include "driver/bk4819.h" #include "driver/bk4819.h"
#include "driver/keyboard.h" #include "driver/keyboard.h"
@@ -31,60 +32,43 @@
#include "ui/menu.h" #include "ui/menu.h"
#include "ui/ui.h" #include "ui/ui.h"
BOOT_Mode_t BOOT_GetMode(void) #if defined(ENABLE_FEAT_F4HWN_RESCUE_OPS) || defined(ENABLE_AIRCOPY)
{ BOOT_Mode_t BOOT_GetMode(void) {
unsigned int i; unsigned int i;
KEY_Code_t Keys[2]; KEY_Code_t Keys[2];
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++) {
{
if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT)) if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT))
return BOOT_MODE_NORMAL; // PTT not pressed return BOOT_MODE_NORMAL; // PTT not pressed
Keys[i] = KEYBOARD_Poll(); Keys[i] = KEYBOARD_Poll();
SYSTEM_DelayMs(20); SYSTEM_DelayMs(20);
} }
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS if (Keys[0] == Keys[1]) {
if (Keys[0] == (10 + gEeprom.SET_KEY))
{
return BOOT_MODE_RESCUE_OPS; // Secret KEY pressed
}
#endif
if (Keys[0] == Keys[1])
{
gKeyReading0 = Keys[0]; gKeyReading0 = Keys[0];
gKeyReading1 = Keys[0]; gKeyReading1 = Keys[0];
gDebounceCounter = 2; gDebounceCounter = 2;
if (Keys[0] == KEY_SIDE1) #ifdef ENABLE_AIRCOPY
return BOOT_MODE_F_LOCK;
#ifdef ENABLE_AIRCOPY
if (Keys[0] == KEY_SIDE2) if (Keys[0] == KEY_SIDE2)
return BOOT_MODE_AIRCOPY; return BOOT_MODE_AIRCOPY;
#endif #endif
} }
return BOOT_MODE_NORMAL; return BOOT_MODE_NORMAL;
} }
void BOOT_ProcessMode(BOOT_Mode_t Mode) void BOOT_ProcessMode(BOOT_Mode_t Mode) {
{ Mode = Mode;
if (Mode == BOOT_MODE_F_LOCK) #ifdef ENABLE_AIRCOPY
{
GUI_SelectNextDisplay(DISPLAY_MENU);
}
#ifdef ENABLE_AIRCOPY
else
if (Mode == BOOT_MODE_AIRCOPY) if (Mode == BOOT_MODE_AIRCOPY)
{ {
gEeprom.DUAL_WATCH = DUAL_WATCH_OFF; gEeprom.DUAL_WATCH = DUAL_WATCH_OFF;
gEeprom.BATTERY_SAVE = 0; gEeprom.BATTERY_SAVE = 0;
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
gEeprom.VOX_SWITCH = false; gEeprom.VOX_SWITCH = false;
#endif #endif
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF; gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gEeprom.AUTO_KEYPAD_LOCK = false; gEeprom.AUTO_KEYPAD_LOCK = false;
gEeprom.KEY_1_SHORT_PRESS_ACTION = ACTION_OPT_NONE; gEeprom.KEY_1_SHORT_PRESS_ACTION = ACTION_OPT_NONE;
@@ -111,15 +95,14 @@ void BOOT_ProcessMode(BOOT_Mode_t Mode)
gEeprom.BACKLIGHT_TIME = 61; gEeprom.BACKLIGHT_TIME = 61;
gEeprom.KEY_LOCK = 0; gEeprom.KEY_LOCK = 0;
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
gEeprom.CURRENT_STATE = 0; // Don't scan if scan resume is active... gEeprom.CURRENT_STATE = 0; // Don't resume is active...
#endif #endif
GUI_SelectNextDisplay(DISPLAY_AIRCOPY); GUI_SelectNextDisplay(DISPLAY_AIRCOPY);
} }
#endif #endif
else
{
GUI_SelectNextDisplay(DISPLAY_MAIN); GUI_SelectNextDisplay(DISPLAY_MAIN);
}
} }
#endif

View File

@@ -20,10 +20,10 @@
#include <stdint.h> #include <stdint.h>
#include "driver/keyboard.h" #include "driver/keyboard.h"
#if defined(ENABLE_FEAT_F4HWN_RESCUE_OPS) || defined(ENABLE_AIRCOPY)
enum BOOT_Mode_t enum BOOT_Mode_t
{ {
BOOT_MODE_NORMAL = 0, BOOT_MODE_NORMAL = 0,
BOOT_MODE_F_LOCK,
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS #ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
BOOT_MODE_RESCUE_OPS, BOOT_MODE_RESCUE_OPS,
#endif #endif
@@ -38,4 +38,4 @@ BOOT_Mode_t BOOT_GetMode(void);
void BOOT_ProcessMode(BOOT_Mode_t Mode); void BOOT_ProcessMode(BOOT_Mode_t Mode);
#endif #endif
#endif

125
main.c
View File

@@ -19,7 +19,9 @@
#include <stdio.h> // NULL #include <stdio.h> // NULL
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
#include "am_fix.h"
#include "am_fix.h"
#endif #endif
#include "audio.h" #include "audio.h"
@@ -30,14 +32,20 @@
#include "version.h" #include "version.h"
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/action.h"
#include "ui/ui.h" #include "app/action.h"
#endif #include "ui/ui.h"
#ifdef ENABLE_SPECTRUM
#include "app/spectrum.h" #endif
#endif #ifdef ENABLE_SPECTRUM
#include "app/chFrScanner.h"
#include "app/spectrum.h"
#endif
#include "app/chFrScanner.h"
#endif #endif
#include "app/app.h" #include "app/app.h"
@@ -51,8 +59,11 @@
#include "driver/system.h" #include "driver/system.h"
#include "driver/systick.h" #include "driver/systick.h"
#include "driver/eeprom.h" #include "driver/eeprom.h"
#ifdef ENABLE_UART #ifdef ENABLE_UART
#include "driver/uart.h"
#include "driver/uart.h"
#endif #endif
#include "helper/battery.h" #include "helper/battery.h"
@@ -61,17 +72,16 @@
#include "ui/lock.h" #include "ui/lock.h"
#include "ui/welcome.h" #include "ui/welcome.h"
#include "ui/menu.h" #include "ui/menu.h"
void _putchar(__attribute__((unused)) char c)
{ void _putchar(__attribute__((unused)) char c) {
#ifdef ENABLE_UART #ifdef ENABLE_UART
UART_Send((uint8_t *)&c, 1); UART_Send((uint8_t *) &c, 1);
#endif #endif
} }
void Main(void) void Main(void) {
{
// Enable clock gating of blocks we need // Enable clock gating of blocks we need
SYSCON_DEV_CLK_GATE = 0 SYSCON_DEV_CLK_GATE = 0
| SYSCON_DEV_CLK_GATE_GPIOA_BITS_ENABLE | SYSCON_DEV_CLK_GATE_GPIOA_BITS_ENABLE
@@ -106,10 +116,10 @@ void Main(void)
SETTINGS_InitEEPROM(); SETTINGS_InitEEPROM();
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
gDW = gEeprom.DUAL_WATCH; gDW = gEeprom.DUAL_WATCH;
gCB = gEeprom.CROSS_BAND_RX_TX; gCB = gEeprom.CROSS_BAND_RX_TX;
#endif #endif
SETTINGS_WriteBuildOptions(); SETTINGS_WriteBuildOptions();
SETTINGS_LoadCalibration(); SETTINGS_LoadCalibration();
@@ -130,6 +140,7 @@ void Main(void)
AM_fix_init(); AM_fix_init();
#endif #endif
#if defined(ENABLE_FEAT_F4HWN_RESCUE_OPS) || defined(ENABLE_AIRCOPY)
BOOT_Mode_t BootMode = BOOT_GetMode(); BOOT_Mode_t BootMode = BOOT_GetMode();
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS #ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
@@ -150,56 +161,26 @@ void Main(void)
*/ */
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
if (BootMode == BOOT_MODE_F_LOCK && gEeprom.MENU_LOCK == true)
{
BootMode = BOOT_MODE_NORMAL;
}
#endif #endif
if (BootMode == BOOT_MODE_F_LOCK)
{
gF_LOCK = true; // flag to say include the hidden menu items
#ifdef ENABLE_FEAT_F4HWN
gEeprom.KEY_LOCK = 0;
SETTINGS_SaveSettings();
#ifndef ENABLE_VOX
gMenuCursor = 67; // move to hidden section, fix me if change... !!! Remove VOX and Mic Bar
#else
gMenuCursor = 68; // move to hidden section, fix me if change... !!!
#endif
#ifdef ENABLE_NOAA
gMenuCursor += 1; // move to hidden section, fix me if change... !!!
#endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
gMenuCursor += 1; // move to hidden section, fix me if change... !!!
#endif
gSubMenuSelection = gSetting_F_LOCK;
#endif
}
// count the number of menu items // count the number of menu items
gMenuListCount = 0; gMenuListCount = 0;
while (MenuList[gMenuListCount].name[0] != '\0') { while (MenuList[gMenuListCount].name[0] != '\0') {
if(!gF_LOCK && MenuList[gMenuListCount].menu_id == FIRST_HIDDEN_MENU_ITEM)
break;
gMenuListCount++; gMenuListCount++;
} }
// wait for user to release all butts before moving on // wait for user to release all butts before moving on
if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) ||
KEYBOARD_Poll() != KEY_INVALID || KEYBOARD_Poll() != KEY_INVALID
BootMode != BOOT_MODE_NORMAL) #if defined(ENABLE_FEAT_F4HWN_RESCUE_OPS) || defined(ENABLE_AIRCOPY)
{ // keys are pressed || BootMode != BOOT_MODE_NORMAL
#endif
) { // keys are pressed
UI_DisplayReleaseKeys(); UI_DisplayReleaseKeys();
BACKLIGHT_TurnOn(); BACKLIGHT_TurnOn();
// 500ms // 500ms
for (int i = 0; i < 50;) for (int i = 0; i < 50;) {
{
i = (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && KEYBOARD_Poll() == KEY_INVALID) ? i + 1 : 0; i = (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && KEYBOARD_Poll() == KEY_INVALID) ? i + 1 : 0;
SYSTEM_DelayMs(10); SYSTEM_DelayMs(10);
} }
@@ -208,8 +189,7 @@ void Main(void)
gDebounceCounter = 0; gDebounceCounter = 0;
} }
if (!gChargingWithTypeC && gBatteryDisplayLevel == 0) if (!gChargingWithTypeC && gBatteryDisplayLevel == 0) {
{
FUNCTION_Select(FUNCTION_POWER_SAVE); FUNCTION_Select(FUNCTION_POWER_SAVE);
if (gEeprom.BACKLIGHT_TIME < 61) // backlight is not set to be always on if (gEeprom.BACKLIGHT_TIME < 61) // backlight is not set to be always on
@@ -218,29 +198,11 @@ void Main(void)
BACKLIGHT_TurnOn(); // turn the backlight ON BACKLIGHT_TurnOn(); // turn the backlight ON
gReducedService = true; gReducedService = true;
} } else {
else
{
UI_DisplayWelcome(); UI_DisplayWelcome();
BACKLIGHT_TurnOn(); BACKLIGHT_TurnOn();
#ifdef ENABLE_FEAT_F4HWN
if (gEeprom.POWER_ON_DISPLAY_MODE != POWER_ON_DISPLAY_MODE_NONE && gEeprom.POWER_ON_DISPLAY_MODE != POWER_ON_DISPLAY_MODE_SOUND)
#else
if (gEeprom.POWER_ON_DISPLAY_MODE != POWER_ON_DISPLAY_MODE_NONE)
#endif
{ // 2.55 second boot-up screen
while (boot_counter_10ms > 0)
{
if (KEYBOARD_Poll() != KEY_INVALID)
{ // halt boot beeps
boot_counter_10ms = 0;
break;
}
}
RADIO_SetupRegisters(true); RADIO_SetupRegisters(true);
}
#ifdef ENABLE_PWRON_PASSWORD #ifdef ENABLE_PWRON_PASSWORD
if (gEeprom.POWER_ON_PASSWORD < 1000000) if (gEeprom.POWER_ON_PASSWORD < 1000000)
@@ -261,7 +223,9 @@ void Main(void)
} }
#endif #endif
#if defined(ENABLE_FEAT_F4HWN_RESCUE_OPS) || defined(ENABLE_AIRCOPY)
BOOT_ProcessMode(BootMode); BOOT_ProcessMode(BootMode);
#endif
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
@@ -335,7 +299,7 @@ void Main(void)
#endif #endif
*/ */
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE #ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
if (gEeprom.CURRENT_STATE == 2 || gEeprom.CURRENT_STATE == 5) { if (gEeprom.CURRENT_STATE == 2 || gEeprom.CURRENT_STATE == 5) {
gScanRangeStart = gScanRangeStart ? 0 : gTxVfo->pRX->Frequency; gScanRangeStart = gScanRangeStart ? 0 : gTxVfo->pRX->Frequency;
gScanRangeStop = gEeprom.VfoInfo[!gEeprom.TX_VFO].freq_config_RX.Frequency; gScanRangeStop = gEeprom.VfoInfo[!gEeprom.TX_VFO].freq_config_RX.Frequency;
@@ -351,19 +315,18 @@ void Main(void)
if (gEeprom.CURRENT_STATE == 1 || gEeprom.CURRENT_STATE == 2) { if (gEeprom.CURRENT_STATE == 1 || gEeprom.CURRENT_STATE == 2) {
CHFRSCANNER_Start(true, SCAN_FWD); CHFRSCANNER_Start(true, SCAN_FWD);
} }
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
else if (gEeprom.CURRENT_STATE == 3) { else if (gEeprom.CURRENT_STATE == 3) {
ACTION_FM(); ACTION_FM();
GUI_SelectNextDisplay(gRequestDisplayScreen); GUI_SelectNextDisplay(gRequestDisplayScreen);
} }
#endif #endif
#ifdef ENABLE_SPECTRUM #ifdef ENABLE_SPECTRUM
else if (gEeprom.CURRENT_STATE == 4 || gEeprom.CURRENT_STATE == 5) { else if (gEeprom.CURRENT_STATE == 4 || gEeprom.CURRENT_STATE == 5) {
APP_RunSpectrum(); APP_RunSpectrum();
} }
#endif #endif
// Pas besoin de `default`, aucun effet si l'état n'est pas traité. #endif
#endif
while (true) { while (true) {
APP_Update(); APP_Update();

18
misc.c
View File

@@ -91,16 +91,10 @@ const uint8_t gMicGain_dB2[5] = {3, 8, 16, 24, 31};
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
bool gSetting_350TX; bool gSetting_350TX;
#endif #endif
#ifdef ENABLE_DTMF_CALLING
bool gSetting_KILLED;
#endif
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
bool gSetting_200TX; bool gSetting_200TX;
bool gSetting_500TX; bool gSetting_500TX;
#endif #endif
bool gSetting_350EN;
uint8_t gSetting_F_LOCK; uint8_t gSetting_F_LOCK;
bool gSetting_ScrambleEnable; bool gSetting_ScrambleEnable;
@@ -116,18 +110,8 @@ enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
uint8_t gSetting_set_pwr = 1;
bool gSetting_set_ptt = 0; bool gSetting_set_ptt = 0;
uint8_t gSetting_set_tot = 0;
uint8_t gSetting_set_ctr = 10;
bool gSetting_set_inv = false; bool gSetting_set_inv = false;
uint8_t gSetting_set_eot = 0;
bool gSetting_set_lck = false;
bool gSetting_set_met = 0;
bool gSetting_set_gui = 0;
#ifdef ENABLE_FEAT_F4HWN_NARROWER
bool gSetting_set_nfm = 0;
#endif
bool gSetting_set_tmr = 0; bool gSetting_set_tmr = 0;
bool gSetting_set_ptt_session; bool gSetting_set_ptt_session;
#ifdef ENABLE_FEAT_F4HWN_DEBUG #ifdef ENABLE_FEAT_F4HWN_DEBUG
@@ -139,10 +123,8 @@ enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
uint8_t crc[15] = { 0 }; uint8_t crc[15] = { 0 };
uint8_t lErrorsDuringAirCopy = 0; uint8_t lErrorsDuringAirCopy = 0;
uint8_t gAircopyStep = 0; uint8_t gAircopyStep = 0;
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
bool gPowerHigh = false; bool gPowerHigh = false;
bool gRemoveOffset = false; bool gRemoveOffset = false;
#endif
#endif #endif
#ifdef ENABLE_AUDIO_BAR #ifdef ENABLE_AUDIO_BAR

18
misc.h
View File

@@ -143,17 +143,11 @@ extern const uint8_t gMicGain_dB2[5];
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
extern bool gSetting_350TX; extern bool gSetting_350TX;
#endif #endif
#ifdef ENABLE_DTMF_CALLING
extern bool gSetting_KILLED;
#endif
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
extern bool gSetting_200TX; extern bool gSetting_200TX;
extern bool gSetting_500TX; extern bool gSetting_500TX;
#endif #endif
extern bool gSetting_350EN;
extern uint8_t gSetting_F_LOCK; extern uint8_t gSetting_F_LOCK;
extern bool gSetting_ScrambleEnable; extern bool gSetting_ScrambleEnable;
@@ -169,18 +163,8 @@ extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
extern uint8_t gSetting_set_pwr;
extern bool gSetting_set_ptt; extern bool gSetting_set_ptt;
extern uint8_t gSetting_set_tot;
extern uint8_t gSetting_set_ctr;
extern bool gSetting_set_inv; extern bool gSetting_set_inv;
extern uint8_t gSetting_set_eot;
extern bool gSetting_set_lck;
extern bool gSetting_set_met;
extern bool gSetting_set_gui;
#ifdef ENABLE_FEAT_F4HWN_NARROWER
extern bool gSetting_set_nfm;
#endif
extern bool gSetting_set_tmr; extern bool gSetting_set_tmr;
extern bool gSetting_set_ptt_session; extern bool gSetting_set_ptt_session;
#ifdef ENABLE_FEAT_F4HWN_DEBUG #ifdef ENABLE_FEAT_F4HWN_DEBUG
@@ -192,10 +176,8 @@ extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
extern uint8_t crc[15]; extern uint8_t crc[15];
extern uint8_t lErrorsDuringAirCopy; extern uint8_t lErrorsDuringAirCopy;
extern uint8_t gAircopyStep; extern uint8_t gAircopyStep;
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
extern bool gPowerHigh; extern bool gPowerHigh;
extern bool gRemoveOffset; extern bool gRemoveOffset;
#endif
#endif #endif
#ifdef ENABLE_AUDIO_BAR #ifdef ENABLE_AUDIO_BAR

View File

@@ -1,4 +0,0 @@
#define PRINTF_DISABLE_SUPPORT_LONG_LONG
#define PRINTF_DISABLE_SUPPORT_EXPONENTIAL
#define PRINTF_DISABLE_SUPPORT_PTRDIFF_T
#define PRINTF_DISABLE_SUPPORT_FLOAT

383
radio.c
View File

@@ -19,9 +19,11 @@
#include "am_fix.h" #include "am_fix.h"
#include "app/dtmf.h" #include "app/dtmf.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h" #include "app/fm.h"
#endif #endif
#include "audio.h" #include "audio.h"
#include "bsp/dp32g030/gpio.h" #include "bsp/dp32g030/gpio.h"
#include "dcs.h" #include "dcs.h"
@@ -54,8 +56,7 @@ const char gModulationStr[MODULATION_UKNOWN][4] = {
#endif #endif
}; };
bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanList) bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanList) {
{
// return true if the channel appears valid // return true if the channel appears valid
if (!IS_MR_CHANNEL(channel)) if (!IS_MR_CHANNEL(channel))
return false; return false;
@@ -112,8 +113,7 @@ bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanL
return PriorityCh1 != channel && PriorityCh2 != channel; return PriorityCh1 != channel && PriorityCh2 != channel;
} }
uint8_t RADIO_FindNextChannel(uint8_t Channel, int8_t Direction, bool bCheckScanList, uint8_t VFO) uint8_t RADIO_FindNextChannel(uint8_t Channel, int8_t Direction, bool bCheckScanList, uint8_t VFO) {
{
for (unsigned int i = 0; IS_MR_CHANNEL(i); i++, Channel += Direction) { for (unsigned int i = 0; IS_MR_CHANNEL(i); i++, Channel += Direction) {
if (Channel == 0xFF) { if (Channel == 0xFF) {
Channel = MR_CHANNEL_LAST; Channel = MR_CHANNEL_LAST;
@@ -129,8 +129,7 @@ uint8_t RADIO_FindNextChannel(uint8_t Channel, int8_t Direction, bool bCheckScan
return 0xFF; return 0xFF;
} }
void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t Frequency) void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t Frequency) {
{
memset(pInfo, 0, sizeof(*pInfo)); memset(pInfo, 0, sizeof(*pInfo));
pInfo->Band = FREQUENCY_GetBand(Frequency); pInfo->Band = FREQUENCY_GetBand(Frequency);
@@ -141,7 +140,6 @@ void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t
pInfo->StepFrequency = gStepFrequencyTable[pInfo->STEP_SETTING]; pInfo->StepFrequency = gStepFrequencyTable[pInfo->STEP_SETTING];
pInfo->CHANNEL_SAVE = ChannelSave; pInfo->CHANNEL_SAVE = ChannelSave;
pInfo->FrequencyReverse = false; pInfo->FrequencyReverse = false;
pInfo->TX_LOCK = true;
pInfo->OUTPUT_POWER = OUTPUT_POWER_LOW1; pInfo->OUTPUT_POWER = OUTPUT_POWER_LOW1;
pInfo->freq_config_RX.Frequency = Frequency; pInfo->freq_config_RX.Frequency = Frequency;
pInfo->freq_config_TX.Frequency = Frequency; pInfo->freq_config_TX.Frequency = Frequency;
@@ -157,18 +155,9 @@ void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t
RADIO_ConfigureSquelchAndOutputPower(pInfo); RADIO_ConfigureSquelchAndOutputPower(pInfo);
} }
void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure) void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure) {
{
VFO_Info_t *pVfo = &gEeprom.VfoInfo[VFO]; VFO_Info_t *pVfo = &gEeprom.VfoInfo[VFO];
if (!gSetting_350EN) {
if (gEeprom.FreqChannel[VFO] == FREQ_CHANNEL_FIRST + BAND5_350MHz)
gEeprom.FreqChannel[VFO] = FREQ_CHANNEL_FIRST + BAND6_400MHz;
if (gEeprom.ScreenChannel[VFO] == FREQ_CHANNEL_FIRST + BAND5_350MHz)
gEeprom.ScreenChannel[VFO] = FREQ_CHANNEL_FIRST + BAND6_400MHz;
}
uint8_t channel = gEeprom.ScreenChannel[VFO]; uint8_t channel = gEeprom.ScreenChannel[VFO];
if (IS_VALID_CHANNEL(channel)) { if (IS_VALID_CHANNEL(channel)) {
@@ -192,14 +181,12 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
if (channel == 0xFF) { if (channel == 0xFF) {
channel = gEeprom.FreqChannel[VFO]; channel = gEeprom.FreqChannel[VFO];
gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO]; gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO];
} } else {
else {
gEeprom.ScreenChannel[VFO] = channel; gEeprom.ScreenChannel[VFO] = channel;
gEeprom.MrChannel[VFO] = channel; gEeprom.MrChannel[VFO] = channel;
} }
} }
} } else
else
channel = FREQ_CHANNEL_LAST - 1; channel = FREQ_CHANNEL_LAST - 1;
ChannelAttributes_t att = gMR_ChannelAttributes[channel]; ChannelAttributes_t att = gMR_ChannelAttributes[channel];
@@ -227,8 +214,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
bParticipation1 = att.scanlist1; bParticipation1 = att.scanlist1;
bParticipation2 = att.scanlist2; bParticipation2 = att.scanlist2;
bParticipation3 = att.scanlist3; bParticipation3 = att.scanlist3;
} } else {
else {
band = channel - FREQ_CHANNEL_FIRST; band = channel - FREQ_CHANNEL_FIRST;
bParticipation1 = true; bParticipation1 = true;
bParticipation2 = true; bParticipation2 = true;
@@ -243,12 +229,11 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
uint16_t base; uint16_t base;
if (IS_MR_CHANNEL(channel)) if (IS_MR_CHANNEL(channel))
base = channel * 16; base = channel * 24;
else else
base = 0x0C80 + ((channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16); base = 0x0C80 + ((channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 24);
if (configure == VFO_CONFIGURE_RELOAD || IS_FREQ_CHANNEL(channel)) if (configure == VFO_CONFIGURE_RELOAD || IS_FREQ_CHANNEL(channel)) {
{
uint8_t tmp; uint8_t tmp;
uint8_t data[8]; uint8_t data[8];
@@ -271,21 +256,11 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
pVfo->STEP_SETTING = tmp; pVfo->STEP_SETTING = tmp;
pVfo->StepFrequency = gStepFrequencyTable[tmp]; pVfo->StepFrequency = gStepFrequencyTable[tmp];
tmp = data[7];
#ifndef ENABLE_FEAT_F4HWN
if (tmp > (ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1))
tmp = 0;
pVfo->SCRAMBLING_TYPE = tmp;
#else
pVfo->SCRAMBLING_TYPE = 0;
#endif
pVfo->freq_config_RX.CodeType = (data[2] >> 0) & 0x0F; pVfo->freq_config_RX.CodeType = (data[2] >> 0) & 0x0F;
pVfo->freq_config_TX.CodeType = (data[2] >> 4) & 0x0F; pVfo->freq_config_TX.CodeType = (data[2] >> 4) & 0x0F;
tmp = data[0]; tmp = data[0];
switch (pVfo->freq_config_RX.CodeType) switch (pVfo->freq_config_RX.CodeType) {
{
default: default:
case CODE_TYPE_OFF: case CODE_TYPE_OFF:
pVfo->freq_config_RX.CodeType = CODE_TYPE_OFF; pVfo->freq_config_RX.CodeType = CODE_TYPE_OFF;
@@ -306,8 +281,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
pVfo->freq_config_RX.Code = tmp; pVfo->freq_config_RX.Code = tmp;
tmp = data[1]; tmp = data[1];
switch (pVfo->freq_config_TX.CodeType) switch (pVfo->freq_config_TX.CodeType) {
{
default: default:
case CODE_TYPE_OFF: case CODE_TYPE_OFF:
pVfo->freq_config_TX.CodeType = CODE_TYPE_OFF; pVfo->freq_config_TX.CodeType = CODE_TYPE_OFF;
@@ -327,33 +301,25 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
} }
pVfo->freq_config_TX.Code = tmp; pVfo->freq_config_TX.Code = tmp;
if (data[4] == 0xFF) if (data[4] == 0xFF) {
{
pVfo->FrequencyReverse = false; pVfo->FrequencyReverse = false;
pVfo->CHANNEL_BANDWIDTH = BK4819_FILTER_BW_WIDE; pVfo->CHANNEL_BANDWIDTH = BK4819_FILTER_BW_WIDE;
pVfo->OUTPUT_POWER = OUTPUT_POWER_LOW1; pVfo->OUTPUT_POWER = OUTPUT_POWER_LOW1;
pVfo->BUSY_CHANNEL_LOCK = false; pVfo->BUSY_CHANNEL_LOCK = false;
pVfo->TX_LOCK = true; } else {
}
else
{
const uint8_t d4 = data[4]; const uint8_t d4 = data[4];
pVfo->FrequencyReverse = !!((d4 >> 0) & 1u); pVfo->FrequencyReverse = ((d4 >> 0) & 1u) != 0;
pVfo->CHANNEL_BANDWIDTH = !!((d4 >> 1) & 1u); pVfo->CHANNEL_BANDWIDTH = ((d4 >> 1) & 3u);
pVfo->OUTPUT_POWER = ((d4 >> 2) & 7u); pVfo->OUTPUT_POWER = ((d4 >> 3) & 7u);
pVfo->BUSY_CHANNEL_LOCK = !!((d4 >> 5) & 1u); pVfo->BUSY_CHANNEL_LOCK = ((d4 >> 6) & 1u) != 0;
pVfo->TX_LOCK = !!((d4 >> 6) & 1u);
} }
if (data[5] == 0xFF) if (data[5] == 0xFF) {
{
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
pVfo->DTMF_DECODING_ENABLE = false; pVfo->DTMF_DECODING_ENABLE = false;
#endif #endif
pVfo->DTMF_PTT_ID_TX_MODE = PTT_ID_OFF; pVfo->DTMF_PTT_ID_TX_MODE = PTT_ID_OFF;
} } else {
else
{
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
pVfo->DTMF_DECODING_ENABLE = ((data[5] >> 0) & 1u) ? true : false; pVfo->DTMF_DECODING_ENABLE = ((data[5] >> 0) & 1u) ? true : false;
#endif #endif
@@ -363,12 +329,18 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
// *************** // ***************
EEPROM_ReadBuffer(base + 16, data, sizeof(data));
uint16_t * data16 = (uint16_t *)data;
pVfo->SCRAMBLING_TYPE = data16[0];
struct { struct {
uint32_t Frequency; uint32_t Frequency;
uint32_t Offset; uint32_t Offset;
} __attribute__((packed)) info; } __attribute__((packed)) info;
EEPROM_ReadBuffer(base, &info, sizeof(info)); EEPROM_ReadBuffer(base, &info, sizeof(info));
if(info.Frequency==0xFFFFFFFF) if (info.Frequency == 0xFFFFFFFF)
pVfo->freq_config_RX.Frequency = frequencyBandTable[band].lower; pVfo->freq_config_RX.Frequency = frequencyBandTable[band].lower;
else else
pVfo->freq_config_RX.Frequency = info.Frequency; pVfo->freq_config_RX.Frequency = info.Frequency;
@@ -402,32 +374,20 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
RADIO_ApplyOffset(pVfo); RADIO_ApplyOffset(pVfo);
if (IS_MR_CHANNEL(channel)) if (IS_MR_CHANNEL(channel)) { // 16 bytes allocated to the channel name but only 10 used, the rest are 0's
{ // 16 bytes allocated to the channel name but only 10 used, the rest are 0's
SETTINGS_FetchChannelName(pVfo->Name, channel); SETTINGS_FetchChannelName(pVfo->Name, channel);
} }
if (!pVfo->FrequencyReverse) if (!pVfo->FrequencyReverse) {
{
pVfo->pRX = &pVfo->freq_config_RX; pVfo->pRX = &pVfo->freq_config_RX;
pVfo->pTX = &pVfo->freq_config_TX; pVfo->pTX = &pVfo->freq_config_TX;
} } else {
else
{
pVfo->pRX = &pVfo->freq_config_TX; pVfo->pRX = &pVfo->freq_config_TX;
pVfo->pTX = &pVfo->freq_config_RX; pVfo->pTX = &pVfo->freq_config_RX;
} }
if (!gSetting_350EN)
{
FREQ_Config_t *pConfig = pVfo->pRX;
if (pConfig->Frequency >= 35000000 && pConfig->Frequency < 40000000)
pConfig->Frequency = 43300000;
}
pVfo->Compander = att.compander; pVfo->Compander = att.compander;
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
if(gRemoveOffset) if(gRemoveOffset)
{ {
pVfo->pTX = &pVfo->freq_config_RX; pVfo->pTX = &pVfo->freq_config_RX;
@@ -437,13 +397,11 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
{ {
pVfo->OUTPUT_POWER = OUTPUT_POWER_HIGH; pVfo->OUTPUT_POWER = OUTPUT_POWER_HIGH;
} }
#endif
RADIO_ConfigureSquelchAndOutputPower(pVfo); RADIO_ConfigureSquelchAndOutputPower(pVfo);
} }
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo) void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo) {
{
// ******************************* // *******************************
@@ -452,8 +410,7 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
FREQUENCY_Band_t Band = FREQUENCY_GetBand(pInfo->pRX->Frequency); FREQUENCY_Band_t Band = FREQUENCY_GetBand(pInfo->pRX->Frequency);
uint16_t Base = (Band < BAND4_174MHz) ? 0x1E60 : 0x1E00; uint16_t Base = (Band < BAND4_174MHz) ? 0x1E60 : 0x1E00;
if (gEeprom.SQUELCH_LEVEL == 0) if (gEeprom.SQUELCH_LEVEL == 0) { // squelch == 0 (off)
{ // squelch == 0 (off)
pInfo->SquelchOpenRSSIThresh = 0; // 0 ~ 255 pInfo->SquelchOpenRSSIThresh = 0; // 0 ~ 255
pInfo->SquelchOpenNoiseThresh = 127; // 127 ~ 0 pInfo->SquelchOpenNoiseThresh = 127; // 127 ~ 0
pInfo->SquelchCloseGlitchThresh = 255; // 255 ~ 0 pInfo->SquelchCloseGlitchThresh = 255; // 255 ~ 0
@@ -461,9 +418,7 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
pInfo->SquelchCloseRSSIThresh = 0; // 0 ~ 255 pInfo->SquelchCloseRSSIThresh = 0; // 0 ~ 255
pInfo->SquelchCloseNoiseThresh = 127; // 127 ~ 0 pInfo->SquelchCloseNoiseThresh = 127; // 127 ~ 0
pInfo->SquelchOpenGlitchThresh = 255; // 255 ~ 0 pInfo->SquelchOpenGlitchThresh = 255; // 255 ~ 0
} } else { // squelch >= 1
else
{ // squelch >= 1
Base += gEeprom.SQUELCH_LEVEL; // my eeprom squelch-1 Base += gEeprom.SQUELCH_LEVEL; // my eeprom squelch-1
// VHF UHF // VHF UHF
EEPROM_ReadBuffer(Base + 0x00, &pInfo->SquelchOpenRSSIThresh, 1); // 50 10 EEPROM_ReadBuffer(Base + 0x00, &pInfo->SquelchOpenRSSIThresh, 1); // 50 10
@@ -527,96 +482,28 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
uint8_t Op = 0; // Low eeprom calibration data uint8_t Op = 0; // Low eeprom calibration data
uint8_t currentPower = pInfo->OUTPUT_POWER; uint8_t currentPower = pInfo->OUTPUT_POWER;
if(currentPower == OUTPUT_POWER_USER)
{ if (currentPower == OUTPUT_POWER_MID) {
if(gSetting_set_pwr == 5)
{
Op = 1; // Mid eeprom calibration data Op = 1; // Mid eeprom calibration data
} } else if (currentPower == OUTPUT_POWER_HIGH) {
else if(gSetting_set_pwr == 6)
{
Op = 2; // High eeprom calibration data Op = 2; // High eeprom calibration data
} }
currentPower = gSetting_set_pwr;
}
else
{
if (currentPower == OUTPUT_POWER_MID)
{
Op = 1; // Mid eeprom calibration data
}
else if(currentPower == OUTPUT_POWER_HIGH)
{
Op = 2; // High eeprom calibration data
}
currentPower--;
}
EEPROM_ReadBuffer(0x1ED0 + (Band * 16) + (Op * 3), Txp, 3); EEPROM_ReadBuffer(0x1ED0 + (Band * 16) + (Op * 3), Txp, 3);
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
// make low and mid even lower static const uint8_t dividers[6] = {25, 19, 13, 10, 7, 4};
// and use calibration values
// be aware with toxic fucking closed firmwares
/* for (uint8_t p = 0; p < 3; p++) {
uint8_t shift[] = {0, 0, 0, 0, 0}; if (currentPower < 6) {
if(Band == 5) // UHF
{
shift[0] = 0;
shift[1] = 0;
shift[2] = 0;
shift[3] = 0;
shift[4] = 0;
}
*/
/*
for(uint8_t p = 0; p < 3; p++)
{
switch (currentPower)
{
case 0:
Txp[p] = (Txp[p] * 4) / 25; //+ shift[pInfo->OUTPUT_POWER];
break;
case 1:
Txp[p] = (Txp[p] * 4) / 19; // + shift[pInfo->OUTPUT_POWER];
break;
case 2:
Txp[p] = (Txp[p] * 4) / 13; // + shift[pInfo->OUTPUT_POWER];
break;
case 3:
Txp[p] = (Txp[p] * 4) / 10; // + shift[pInfo->OUTPUT_POWER];
break;
case 4:
Txp[p] = (Txp[p] * 4) / 7; // + shift[pInfo->OUTPUT_POWER];
break;
case 5:
Txp[p] = (Txp[p] * 3) / 4;
break;
case 6:
Txp[p] = Txp[p] + 30;
break;
}
}
*/
static const uint8_t dividers[6] = { 25, 19, 13, 10, 7, 4};
for (uint8_t p = 0; p < 3; p++)
{
if (currentPower < 6)
{
Txp[p] = (Txp[p] * (currentPower == 5 ? 3 : 4)) / dividers[currentPower]; Txp[p] = (Txp[p] * (currentPower == 5 ? 3 : 4)) / dividers[currentPower];
} } else // case 6
else // case 6
{ {
Txp[p] += 30; Txp[p] += 30;
} }
} }
#else #else
#ifdef ENABLE_REDUCE_LOW_MID_TX_POWER #ifdef ENABLE_REDUCE_LOW_MID_TX_POWER
// make low and mid even lower // make low and mid even lower
if (pInfo->OUTPUT_POWER == OUTPUT_POWER_LOW) { if (pInfo->OUTPUT_POWER == OUTPUT_POWER_LOW) {
Txp[0] /= 5; Txp[0] /= 5;
@@ -628,7 +515,7 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
Txp[1] /= 3; Txp[1] /= 3;
Txp[2] /= 3; Txp[2] /= 3;
} }
#endif #endif
#endif #endif
pInfo->TXP_CalculatedSetting = FREQUENCY_CalculateOutputPower( pInfo->TXP_CalculatedSetting = FREQUENCY_CalculateOutputPower(
@@ -643,12 +530,10 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
// ******************************* // *******************************
} }
void RADIO_ApplyOffset(VFO_Info_t *pInfo) void RADIO_ApplyOffset(VFO_Info_t *pInfo) {
{
uint32_t Frequency = pInfo->freq_config_RX.Frequency; uint32_t Frequency = pInfo->freq_config_RX.Frequency;
switch (pInfo->TX_OFFSET_FREQUENCY_DIRECTION) switch (pInfo->TX_OFFSET_FREQUENCY_DIRECTION) {
{
case TX_OFFSET_FREQUENCY_DIRECTION_OFF: case TX_OFFSET_FREQUENCY_DIRECTION_OFF:
break; break;
case TX_OFFSET_FREQUENCY_DIRECTION_ADD: case TX_OFFSET_FREQUENCY_DIRECTION_ADD:
@@ -662,19 +547,19 @@ void RADIO_ApplyOffset(VFO_Info_t *pInfo)
pInfo->freq_config_TX.Frequency = Frequency; pInfo->freq_config_TX.Frequency = Frequency;
} }
static void RADIO_SelectCurrentVfo(void) static void RADIO_SelectCurrentVfo(void) {
{
// if crossband is active and DW not the gCurrentVfo is gTxVfo (gTxVfo/TX_VFO is only ever changed by the user) // if crossband is active and DW not the gCurrentVfo is gTxVfo (gTxVfo/TX_VFO is only ever changed by the user)
// otherwise it is set to gRxVfo which is set to gTxVfo in RADIO_SelectVfos // otherwise it is set to gRxVfo which is set to gTxVfo in RADIO_SelectVfos
// so in the end gCurrentVfo is equal to gTxVfo unless dual watch changes it on incomming transmition (again, this can only happen when XB off) // so in the end gCurrentVfo is equal to gTxVfo unless dual watch changes it on incomming transmition (again, this can only happen when XB off)
// note: it is called only in certain situations so could be not up-to-date // note: it is called only in certain situations so could be not up-to-date
gCurrentVfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF || gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) ? gRxVfo : gTxVfo; gCurrentVfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF || gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) ? gRxVfo
: gTxVfo;
} }
void RADIO_SelectVfos(void) void RADIO_SelectVfos(void) {
{
// if crossband without DW is used then RX_VFO is the opposite to the TX_VFO // if crossband without DW is used then RX_VFO is the opposite to the TX_VFO
gEeprom.RX_VFO = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF || gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) ? gEeprom.TX_VFO : !gEeprom.TX_VFO; gEeprom.RX_VFO = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF || gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
? gEeprom.TX_VFO : !gEeprom.TX_VFO;
gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_VFO]; gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_VFO];
gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO]; gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO];
@@ -682,37 +567,28 @@ void RADIO_SelectVfos(void)
RADIO_SelectCurrentVfo(); RADIO_SelectCurrentVfo();
} }
void RADIO_SetupRegisters(bool switchToForeground) void RADIO_SetupRegisters(bool switchToForeground) {
{
BK4819_FilterBandwidth_t Bandwidth = gRxVfo->CHANNEL_BANDWIDTH; BK4819_FilterBandwidth_t Bandwidth = gRxVfo->CHANNEL_BANDWIDTH;
#ifdef ENABLE_FEAT_F4HWN_NARROWER
if(Bandwidth == BK4819_FILTER_BW_NARROW && gSetting_set_nfm == 1)
{
Bandwidth = BK4819_FILTER_BW_NARROWER;
}
#endif
AUDIO_AudioPathOff(); AUDIO_AudioPathOff();
gEnableSpeaker = false; gEnableSpeaker = false;
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false); BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
switch (Bandwidth) switch (Bandwidth) {
{
default: default:
Bandwidth = BK4819_FILTER_BW_WIDE; Bandwidth = BK4819_FILTER_BW_WIDE;
[[fallthrough]]; [[fallthrough]];
case BK4819_FILTER_BW_WIDE: case BK4819_FILTER_BW_WIDE:
case BK4819_FILTER_BW_NARROW: case BK4819_FILTER_BW_NARROW:
case BK4819_FILTER_BW_NARROWER: case BK4819_FILTER_BW_NARROWER:
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
// BK4819_SetFilterBandwidth(Bandwidth, gRxVfo->Modulation == MODULATION_AM && gSetting_AM_fix); // BK4819_SetFilterBandwidth(Bandwidth, gRxVfo->Modulation == MODULATION_AM && gSetting_AM_fix);
BK4819_SetFilterBandwidth(Bandwidth, true); BK4819_SetFilterBandwidth(Bandwidth, true);
#else #else
BK4819_SetFilterBandwidth(Bandwidth, false); BK4819_SetFilterBandwidth(Bandwidth, false);
#endif #endif
break; break;
} }
@@ -722,8 +598,7 @@ void RADIO_SetupRegisters(bool switchToForeground)
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false); BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
while (1) while (1) {
{
const uint16_t Status = BK4819_ReadRegister(BK4819_REG_0C); const uint16_t Status = BK4819_ReadRegister(BK4819_REG_0C);
if ((Status & 1u) == 0) // INTERRUPT REQUEST if ((Status & 1u) == 0) // INTERRUPT REQUEST
break; break;
@@ -737,14 +612,14 @@ void RADIO_SetupRegisters(bool switchToForeground)
BK4819_WriteRegister(BK4819_REG_7D, 0xE940 | (gEeprom.MIC_SENSITIVITY_TUNING & 0x1f)); BK4819_WriteRegister(BK4819_REG_7D, 0xE940 | (gEeprom.MIC_SENSITIVITY_TUNING & 0x1f));
uint32_t Frequency; uint32_t Frequency;
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) || !gIsNoaaMode) if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) || !gIsNoaaMode)
Frequency = gRxVfo->pRX->Frequency; Frequency = gRxVfo->pRX->Frequency;
else else
Frequency = NoaaFrequencyTable[gNoaaChannel]; Frequency = NoaaFrequencyTable[gNoaaChannel];
#else #else
Frequency = gRxVfo->pRX->Frequency; Frequency = gRxVfo->pRX->Frequency;
#endif #endif
BK4819_SetFrequency(Frequency); BK4819_SetFrequency(Frequency);
BK4819_SetupSquelch( BK4819_SetupSquelch(
@@ -761,24 +636,22 @@ void RADIO_SetupRegisters(bool switchToForeground)
//BK4819_WriteRegister(BK4819_REG_48, 0xB3A8); // 1011 00 111010 1000 //BK4819_WriteRegister(BK4819_REG_48, 0xB3A8); // 1011 00 111010 1000
BK4819_WriteRegister(BK4819_REG_48, BK4819_WriteRegister(BK4819_REG_48,
(11u << 12) | // ??? .. 0 ~ 15, doesn't seem to make any difference (11u << 12) | // ??? .. 0 ~ 15, doesn't seem to make any difference
( 0u << 10) | // AF Rx Gain-1 (0u << 10) | // AF Rx Gain-1
(gEeprom.VOLUME_GAIN << 4) | // AF Rx Gain-2 (gEeprom.VOLUME_GAIN << 4) | // AF Rx Gain-2
(gEeprom.DAC_GAIN << 0)); // AF DAC Gain (after Gain-1 and Gain-2) (gEeprom.DAC_GAIN << 0)); // AF DAC Gain (after Gain-1 and Gain-2)
uint16_t InterruptMask = BK4819_REG_3F_SQUELCH_FOUND | BK4819_REG_3F_SQUELCH_LOST; uint16_t InterruptMask = BK4819_REG_3F_SQUELCH_FOUND | BK4819_REG_3F_SQUELCH_LOST;
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif #endif
{ {
if (gRxVfo->Modulation == MODULATION_FM) if (gRxVfo->Modulation == MODULATION_FM) { // FM
{ // FM
uint8_t CodeType = gRxVfo->pRX->CodeType; uint8_t CodeType = gRxVfo->pRX->CodeType;
uint8_t Code = gRxVfo->pRX->Code; uint8_t Code = gRxVfo->pRX->Code;
switch (CodeType) switch (CodeType) {
{
default: default:
case CODE_TYPE_OFF: case CODE_TYPE_OFF:
BK4819_SetCTCSSFrequency(SQL_TONE); BK4819_SetCTCSSFrequency(SQL_TONE);
@@ -817,17 +690,12 @@ void RADIO_SetupRegisters(bool switchToForeground)
break; break;
} }
#ifndef ENABLE_FEAT_F4HWN BK4819_SetScramble(0);
if (gRxVfo->SCRAMBLING_TYPE > 0 && gSetting_ScrambleEnable) SYSTEM_DelayMs(10);
BK4819_EnableScramble(gRxVfo->SCRAMBLING_TYPE - 1); BK4819_SetScramble(gRxVfo->SCRAMBLING_TYPE);
else
BK4819_DisableScramble();
#else
BK4819_DisableScramble();
#endif
} }
} }
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
else else
{ {
BK4819_SetCTCSSFrequency(2625); BK4819_SetCTCSSFrequency(2625);
@@ -837,7 +705,7 @@ void RADIO_SetupRegisters(bool switchToForeground)
| BK4819_REG_3F_SQUELCH_FOUND | BK4819_REG_3F_SQUELCH_FOUND
| BK4819_REG_3F_SQUELCH_LOST; | BK4819_REG_3F_SQUELCH_LOST;
} }
#endif #endif
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
if (gEeprom.VOX_SWITCH && gCurrentVfo->Modulation == MODULATION_FM if (gEeprom.VOX_SWITCH && gCurrentVfo->Modulation == MODULATION_FM
@@ -847,11 +715,10 @@ void RADIO_SetupRegisters(bool switchToForeground)
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
&& !gFmRadioMode && !gFmRadioMode
#endif #endif
){ ) {
BK4819_EnableVox(gEeprom.VOX1_THRESHOLD, gEeprom.VOX0_THRESHOLD); BK4819_EnableVox(gEeprom.VOX1_THRESHOLD, gEeprom.VOX0_THRESHOLD);
InterruptMask |= BK4819_REG_3F_VOX_FOUND | BK4819_REG_3F_VOX_LOST; InterruptMask |= BK4819_REG_3F_VOX_FOUND | BK4819_REG_3F_VOX_LOST;
} } else
else
#endif #endif
{ {
BK4819_DisableVox(); BK4819_DisableVox();
@@ -865,6 +732,9 @@ void RADIO_SetupRegisters(bool switchToForeground)
RADIO_SetupAGC(gRxVfo->Modulation == MODULATION_AM, false); RADIO_SetupAGC(gRxVfo->Modulation == MODULATION_AM, false);
MSG_EnableRX(true);
InterruptMask |= BK4819_REG_3F_FSK_RX_SYNC | BK4819_REG_3F_FSK_RX_FINISHED | BK4819_REG_3F_FSK_FIFO_ALMOST_FULL | BK4819_REG_3F_FSK_TX_FINISHED;
// enable/disable BK4819 selected interrupts // enable/disable BK4819 selected interrupts
BK4819_WriteRegister(BK4819_REG_3F, InterruptMask); BK4819_WriteRegister(BK4819_REG_3F, InterruptMask);
@@ -875,8 +745,8 @@ void RADIO_SetupRegisters(bool switchToForeground)
} }
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
void RADIO_ConfigureNOAA(void) void RADIO_ConfigureNOAA(void)
{ {
uint8_t ChanAB; uint8_t ChanAB;
gUpdateStatus = true; gUpdateStatus = true;
@@ -916,47 +786,39 @@ void RADIO_SetupRegisters(bool switchToForeground)
} }
else else
gIsNoaaMode = false; gIsNoaaMode = false;
} }
#endif #endif
void RADIO_SetTxParameters(void) void RADIO_SetTxParameters(void) {
{
BK4819_FilterBandwidth_t Bandwidth = gCurrentVfo->CHANNEL_BANDWIDTH; BK4819_FilterBandwidth_t Bandwidth = gCurrentVfo->CHANNEL_BANDWIDTH;
#ifdef ENABLE_FEAT_F4HWN_NARROWER
if(Bandwidth == BK4819_FILTER_BW_NARROW && gSetting_set_nfm == 1)
{
Bandwidth = BK4819_FILTER_BW_NARROWER;
}
#endif
AUDIO_AudioPathOff(); AUDIO_AudioPathOff();
gEnableSpeaker = false; gEnableSpeaker = false;
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false); BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false);
switch (Bandwidth) switch (Bandwidth) {
{
default: default:
Bandwidth = BK4819_FILTER_BW_WIDE; Bandwidth = BK4819_FILTER_BW_WIDE;
[[fallthrough]]; [[fallthrough]];
case BK4819_FILTER_BW_WIDE: case BK4819_FILTER_BW_WIDE:
case BK4819_FILTER_BW_NARROW: case BK4819_FILTER_BW_NARROW:
case BK4819_FILTER_BW_NARROWER: case BK4819_FILTER_BW_NARROWER:
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
// BK4819_SetFilterBandwidth(Bandwidth, gCurrentVfo->Modulation == MODULATION_AM && gSetting_AM_fix); // BK4819_SetFilterBandwidth(Bandwidth, gCurrentVfo->Modulation == MODULATION_AM && gSetting_AM_fix);
BK4819_SetFilterBandwidth(Bandwidth, true); BK4819_SetFilterBandwidth(Bandwidth, true);
#else #else
BK4819_SetFilterBandwidth(Bandwidth, false); BK4819_SetFilterBandwidth(Bandwidth, false);
#endif #endif
break; break;
} }
BK4819_SetFrequency(gCurrentVfo->pTX->Frequency); BK4819_SetFrequency(gCurrentVfo->pTX->Frequency);
// TX compressor // TX compressor
BK4819_SetCompander((gRxVfo->Modulation == MODULATION_FM && (gRxVfo->Compander == 1 || gRxVfo->Compander >= 3)) ? gRxVfo->Compander : 0); BK4819_SetCompander((gRxVfo->Modulation == MODULATION_FM && (gRxVfo->Compander == 1 || gRxVfo->Compander >= 3))
? gRxVfo->Compander : 0);
BK4819_PrepareTransmit(); BK4819_PrepareTransmit();
@@ -972,8 +834,7 @@ void RADIO_SetTxParameters(void)
SYSTEM_DelayMs(10); SYSTEM_DelayMs(10);
switch (gCurrentVfo->pTX->CodeType) switch (gCurrentVfo->pTX->CodeType) {
{
default: default:
case CODE_TYPE_OFF: case CODE_TYPE_OFF:
BK4819_ExitSubAu(); BK4819_ExitSubAu();
@@ -990,10 +851,9 @@ void RADIO_SetTxParameters(void)
} }
} }
void RADIO_SetModulation(ModulationMode_t modulation) void RADIO_SetModulation(ModulationMode_t modulation) {
{
BK4819_AF_Type_t mod; BK4819_AF_Type_t mod;
switch(modulation) { switch (modulation) {
default: default:
case MODULATION_FM: case MODULATION_FM:
mod = BK4819_AF_FM; mod = BK4819_AF_FM;
@@ -1024,26 +884,23 @@ void RADIO_SetModulation(ModulationMode_t modulation)
RADIO_SetupAGC(modulation == MODULATION_AM, false); RADIO_SetupAGC(modulation == MODULATION_AM, false);
} }
void RADIO_SetupAGC(bool listeningAM, bool disable) void RADIO_SetupAGC(bool listeningAM, bool disable) {
{
static uint8_t lastSettings; static uint8_t lastSettings;
uint8_t newSettings = (listeningAM << 1) | (disable << 1); uint8_t newSettings = (listeningAM << 1) | (disable << 1);
if(lastSettings == newSettings) if (lastSettings == newSettings)
return; return;
lastSettings = newSettings; lastSettings = newSettings;
if(!listeningAM) { // if not actively listening AM we don't need any AM specific regulation if (!listeningAM) { // if not actively listening AM we don't need any AM specific regulation
BK4819_SetAGC(!disable); BK4819_SetAGC(!disable);
BK4819_InitAGC(false); BK4819_InitAGC(false);
} } else {
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 if (gSetting_AM_fix) { // if AM fix active lock AGC so AM-fix can do it's job
BK4819_SetAGC(0); BK4819_SetAGC(0);
AM_fix_enable(!disable); AM_fix_enable(!disable);
} } else
else
#endif #endif
{ {
BK4819_SetAGC(!disable); BK4819_SetAGC(!disable);
@@ -1052,8 +909,7 @@ void RADIO_SetupAGC(bool listeningAM, bool disable)
} }
} }
void RADIO_SetVfoState(VfoState_t State) void RADIO_SetVfoState(VfoState_t State) {
{
if (State == VFO_STATE_NORMAL) { if (State == VFO_STATE_NORMAL) {
VfoState[0] = VFO_STATE_NORMAL; VfoState[0] = VFO_STATE_NORMAL;
VfoState[1] = VFO_STATE_NORMAL; VfoState[1] = VFO_STATE_NORMAL;
@@ -1071,18 +927,15 @@ void RADIO_SetVfoState(VfoState_t State)
} }
void RADIO_PrepareTX(void) void RADIO_PrepareTX(void) {
{
VfoState_t State = VFO_STATE_NORMAL; // default to OK to TX VfoState_t State = VFO_STATE_NORMAL; // default to OK to TX
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) { // dual-RX is enabled
{ // dual-RX is enabled
gDualWatchCountdown_10ms = dual_watch_count_after_tx_10ms; gDualWatchCountdown_10ms = dual_watch_count_after_tx_10ms;
gScheduleDualWatch = false; gScheduleDualWatch = false;
if (!gRxVfoIsActive) if (!gRxVfoIsActive) { // use the current RX vfo
{ // use the current RX vfo
gEeprom.RX_VFO = gEeprom.TX_VFO; gEeprom.RX_VFO = gEeprom.TX_VFO;
gRxVfo = gTxVfo; gRxVfo = gTxVfo;
gRxVfoIsActive = true; gRxVfoIsActive = true;
@@ -1096,17 +949,17 @@ void RADIO_PrepareTX(void)
RADIO_SelectCurrentVfo(); RADIO_SelectCurrentVfo();
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
if(TX_freq_check(gCurrentVfo->pTX->Frequency) != 0 && gCurrentVfo->TX_LOCK == true if (TX_freq_check(gCurrentVfo->pTX->Frequency) != 0
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
&& gAlarmState != ALARM_STATE_SITE_ALARM && gAlarmState != ALARM_STATE_SITE_ALARM
#endif #endif
#else #else
if(TX_freq_check(gCurrentVfo->pTX->Frequency) != 0 if(TX_freq_check(gCurrentVfo->pTX->Frequency) != 0
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
&& gAlarmState != ALARM_STATE_SITE_ALARM && gAlarmState != ALARM_STATE_SITE_ALARM
#endif
#endif #endif
){ #endif
) {
// TX frequency not allowed // TX frequency not allowed
State = VFO_STATE_TX_DISABLE; State = VFO_STATE_TX_DISABLE;
gVfoConfigureMode = VFO_CONFIGURE; gVfoConfigureMode = VFO_CONFIGURE;
@@ -1165,22 +1018,13 @@ void RADIO_PrepareTX(void)
gTxTimerCountdown_500ms = 0; // no timeout gTxTimerCountdown_500ms = 0; // no timeout
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
if (gAlarmState == ALARM_STATE_OFF) if (gAlarmState == ALARM_STATE_OFF)
#endif #endif
{ {
gTxTimerCountdown_500ms = ((gEeprom.TX_TIMEOUT_TIMER + 1) * 5) * 2; gTxTimerCountdown_500ms = ((gEeprom.TX_TIMEOUT_TIMER + 1) * 5) * 2;
/*
if (gEeprom.TX_TIMEOUT_TIMER == 0)
gTxTimerCountdown_500ms = 60; // 30 sec
else if (gEeprom.TX_TIMEOUT_TIMER < (ARRAY_SIZE(gSubMenu_TOT) - 1))
gTxTimerCountdown_500ms = 120 * gEeprom.TX_TIMEOUT_TIMER; // minutes
else
gTxTimerCountdown_500ms = 120 * 15; // 15 minutes
*/
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
gTxTimerCountdownAlert_500ms = gTxTimerCountdown_500ms; gTxTimerCountdownAlert_500ms = gTxTimerCountdown_500ms;
#endif #endif
@@ -1200,8 +1044,7 @@ void RADIO_PrepareTX(void)
#endif #endif
} }
void RADIO_SendCssTail(void) void RADIO_SendCssTail(void) {
{
switch (gCurrentVfo->pTX->CodeType) { switch (gCurrentVfo->pTX->CodeType) {
case CODE_TYPE_DIGITAL: case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL: case CODE_TYPE_REVERSE_DIGITAL:
@@ -1215,24 +1058,22 @@ void RADIO_SendCssTail(void)
SYSTEM_DelayMs(200); SYSTEM_DelayMs(200);
} }
void RADIO_SendEndOfTransmission(void) void RADIO_SendEndOfTransmission(void) {
{
BK4819_PlayRoger(); BK4819_PlayRoger();
DTMF_SendEndOfTransmission(); DTMF_SendEndOfTransmission();
// send the CTCSS/DCS tail tone - allows the receivers to mute the usual FM squelch tail/crash // send the CTCSS/DCS tail tone - allows the receivers to mute the usual FM squelch tail/crash
if(gEeprom.TAIL_TONE_ELIMINATION) if (gEeprom.TAIL_TONE_ELIMINATION)
RADIO_SendCssTail(); RADIO_SendCssTail();
RADIO_SetupRegisters(false); RADIO_SetupRegisters(false);
} }
void RADIO_PrepareCssTX(void) void RADIO_PrepareCssTX(void) {
{
RADIO_PrepareTX(); RADIO_PrepareTX();
SYSTEM_DelayMs(200); SYSTEM_DelayMs(200);
if(gEeprom.TAIL_TONE_ELIMINATION) if (gEeprom.TAIL_TONE_ELIMINATION)
RADIO_SendCssTail(); RADIO_SendCssTail();
RADIO_SetupRegisters(true); RADIO_SetupRegisters(true);
} }

30
radio.h
View File

@@ -42,8 +42,7 @@ enum PTT_ID_t {
}; };
typedef enum PTT_ID_t PTT_ID_t; typedef enum PTT_ID_t PTT_ID_t;
enum VfoState_t enum VfoState_t {
{
VFO_STATE_NORMAL = 0, VFO_STATE_NORMAL = 0,
VFO_STATE_BUSY, VFO_STATE_BUSY,
VFO_STATE_BAT_LOW, VFO_STATE_BAT_LOW,
@@ -70,16 +69,14 @@ typedef enum {
extern const char gModulationStr[MODULATION_UKNOWN][4]; extern const char gModulationStr[MODULATION_UKNOWN][4];
typedef struct typedef struct {
{
uint32_t Frequency; uint32_t Frequency;
DCS_CodeType_t CodeType; DCS_CodeType_t CodeType;
uint8_t Code; uint8_t Code;
uint8_t Padding[2]; uint8_t Padding[2];
} FREQ_Config_t; } FREQ_Config_t;
typedef struct VFO_Info_t typedef struct VFO_Info_t {
{
FREQ_Config_t freq_config_RX; FREQ_Config_t freq_config_RX;
FREQ_Config_t freq_config_TX; FREQ_Config_t freq_config_TX;
@@ -107,12 +104,11 @@ typedef struct VFO_Info_t
uint8_t SquelchOpenGlitchThresh; uint8_t SquelchOpenGlitchThresh;
STEP_Setting_t STEP_SETTING; STEP_Setting_t STEP_SETTING;
uint8_t TX_LOCK;
uint8_t OUTPUT_POWER; uint8_t OUTPUT_POWER;
uint8_t TXP_CalculatedSetting; uint8_t TXP_CalculatedSetting;
bool FrequencyReverse; bool FrequencyReverse;
uint8_t SCRAMBLING_TYPE; uint16_t SCRAMBLING_TYPE;
uint8_t CHANNEL_BANDWIDTH; uint8_t CHANNEL_BANDWIDTH;
uint8_t SCANLIST1_PARTICIPATION; uint8_t SCANLIST1_PARTICIPATION;
@@ -151,23 +147,39 @@ extern DCS_CodeType_t gCurrentCodeType;
extern VfoState_t VfoState[2]; extern VfoState_t VfoState[2];
bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanList); 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); 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_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_ConfigureChannel(const unsigned int VFO, const unsigned int configure);
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo); void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo);
void RADIO_ApplyOffset(VFO_Info_t *pInfo); void RADIO_ApplyOffset(VFO_Info_t *pInfo);
void RADIO_SelectVfos(void); void RADIO_SelectVfos(void);
void RADIO_SetupRegisters(bool switchToForeground); void RADIO_SetupRegisters(bool switchToForeground);
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
void RADIO_ConfigureNOAA(void); void RADIO_ConfigureNOAA(void);
#endif #endif
void RADIO_SetTxParameters(void); void RADIO_SetTxParameters(void);
void RADIO_SetupAGC(bool listeningAM, bool disable); void RADIO_SetupAGC(bool listeningAM, bool disable);
void RADIO_SetModulation(ModulationMode_t modulation); void RADIO_SetModulation(ModulationMode_t modulation);
void RADIO_SetVfoState(VfoState_t State); void RADIO_SetVfoState(VfoState_t State);
void RADIO_PrepareTX(void); void RADIO_PrepareTX(void);
void RADIO_SendCssTail(void); void RADIO_SendCssTail(void);
void RADIO_PrepareCssTX(void); void RADIO_PrepareCssTX(void);
void RADIO_SendEndOfTransmission(void); void RADIO_SendEndOfTransmission(void);
#endif #endif

View File

@@ -57,13 +57,14 @@ void SystickHandler(void)
gNextTimeslice_500ms = true; gNextTimeslice_500ms = true;
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
DECREMENT_AND_TRIGGER(gTxTimerCountdownAlert_500ms - ALERT_TOT * 2, gTxTimeoutReachedAlert);
#ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER
DECREMENT(gRxTimerCountdown_500ms); DECREMENT(gRxTimerCountdown_500ms);
#endif #endif
#endif #endif
if (gEeprom.TX_TIMEOUT_TIMER != 0) {
DECREMENT_AND_TRIGGER(gTxTimerCountdown_500ms, gTxTimeoutReached); DECREMENT_AND_TRIGGER(gTxTimerCountdown_500ms, gTxTimeoutReached);
}
DECREMENT(gSerialConfigCountDown_500ms); DECREMENT(gSerialConfigCountDown_500ms);
} }

View File

@@ -17,15 +17,18 @@
#include <string.h> #include <string.h>
#include "app/dtmf.h" #include "app/dtmf.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h" #include "app/fm.h"
#endif #endif
#include "driver/bk1080.h" #include "driver/bk1080.h"
#include "driver/bk4819.h" #include "driver/bk4819.h"
#include "driver/eeprom.h" #include "driver/eeprom.h"
#include "misc.h" #include "misc.h"
#include "settings.h" #include "settings.h"
#include "ui/menu.h" #include "ui/menu.h"
#include "app/messages.h"
#ifdef ENABLE_FEAT_F4HWN_RESET_CHANNEL #ifdef ENABLE_FEAT_F4HWN_RESET_CHANNEL
static const uint32_t gDefaultFrequencyTable[] = static const uint32_t gDefaultFrequencyTable[] =
@@ -38,30 +41,27 @@ static const uint32_t gDefaultFrequencyTable[] =
}; };
#endif #endif
EEPROM_Config_t gEeprom = { 0 }; EEPROM_Config_t gEeprom = {0};
void SETTINGS_InitEEPROM(void) void SETTINGS_InitEEPROM(void) {
{ MESSAGES_GET();
uint8_t Data[16] = {0}; uint8_t Data[16] = {0};
// 0E70..0E77 // 0E70..0E77
EEPROM_ReadBuffer(0x0E70, Data, 8); EEPROM_ReadBuffer(0x0E70, Data, 8);
gEeprom.CHAN_1_CALL = IS_MR_CHANNEL(Data[0]) ? Data[0] : MR_CHANNEL_FIRST; gEeprom.CHAN_1_CALL = IS_MR_CHANNEL(Data[0]) ? Data[0] : MR_CHANNEL_FIRST;
gEeprom.SQUELCH_LEVEL = (Data[1] < 10) ? Data[1] : 1; gEeprom.SQUELCH_LEVEL = (Data[1] < 10) ? Data[1] : 1;
gEeprom.TX_TIMEOUT_TIMER = (Data[2] > 4 && Data[2] < 180) ? Data[2] : 11; gEeprom.TX_TIMEOUT_TIMER = (Data[2] > 4 && Data[2] < 180) ? Data[2] : 11;
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
gEeprom.NOAA_AUTO_SCAN = (Data[3] < 2) ? Data[3] : false; gEeprom.NOAA_AUTO_SCAN = (Data[3] < 2) ? Data[3] : false;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS #ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
gEeprom.KEY_LOCK = (Data[4] & 0x01) != 0;
gEeprom.MENU_LOCK = (Data[4] & 0x02) != 0; gEeprom.MENU_LOCK = (Data[4] & 0x02) != 0;
gEeprom.SET_KEY = ((Data[4] >> 2) & 0x0F) > 4 ? 0 : (Data[4] >> 2) & 0x0F; #endif
#else gEeprom.KEY_LOCK = (Data[4] < 2) != 0 && Data[4];
gEeprom.KEY_LOCK = (Data[4] < 2) ? Data[4] : false; #ifdef ENABLE_VOX
#endif
#ifdef ENABLE_VOX
gEeprom.VOX_SWITCH = (Data[5] < 2) ? Data[5] : false; gEeprom.VOX_SWITCH = (Data[5] < 2) ? Data[5] : false;
gEeprom.VOX_LEVEL = (Data[6] < 10) ? Data[6] : 1; gEeprom.VOX_LEVEL = (Data[6] < 10) ? Data[6] : 1;
#endif #endif
gEeprom.MIC_SENSITIVITY = (Data[7] < 5) ? Data[7] : 4; gEeprom.MIC_SENSITIVITY = (Data[7] < 5) ? Data[7] : 4;
// 0E78..0E7F // 0E78..0E7F
@@ -76,20 +76,16 @@ void SETTINGS_InitEEPROM(void)
gEeprom.BATTERY_SAVE = (Data[3] < 6) ? Data[3] : 4; gEeprom.BATTERY_SAVE = (Data[3] < 6) ? Data[3] : 4;
gEeprom.DUAL_WATCH = (Data[4] < 3) ? Data[4] : DUAL_WATCH_CHAN_A; gEeprom.DUAL_WATCH = (Data[4] < 3) ? Data[4] : DUAL_WATCH_CHAN_A;
gEeprom.BACKLIGHT_TIME = (Data[5] < 62) ? Data[5] : 12; gEeprom.BACKLIGHT_TIME = (Data[5] < 62) ? Data[5] : 12;
#ifdef ENABLE_FEAT_F4HWN_NARROWER
gEeprom.TAIL_TONE_ELIMINATION = Data[6] & 0x01;
gSetting_set_nfm = (Data[6] >> 1) & 0x01;
#else
gEeprom.TAIL_TONE_ELIMINATION = (Data[6] < 2) ? Data[6] : false;
#endif
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE gEeprom.TAIL_TONE_ELIMINATION = (Data[6] < 2) != 0 && Data[6];
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
gEeprom.VFO_OPEN = Data[7] & 0x01; gEeprom.VFO_OPEN = Data[7] & 0x01;
gEeprom.CURRENT_STATE = (Data[7] >> 1) & 0x07; gEeprom.CURRENT_STATE = (Data[7] >> 1) & 0x07;
gEeprom.CURRENT_LIST = (Data[7] >> 4) & 0x07; gEeprom.CURRENT_LIST = (Data[7] >> 4) & 0x07;
#else #else
gEeprom.VFO_OPEN = (Data[7] < 2) ? Data[7] : true; gEeprom.VFO_OPEN = (Data[7] < 2) ? Data[7] : true;
#endif #endif
// 0E80..0E87 // 0E80..0E87
EEPROM_ReadBuffer(0x0E80, Data, 8); EEPROM_ReadBuffer(0x0E80, Data, 8);
@@ -141,39 +137,33 @@ void SETTINGS_InitEEPROM(void)
gEeprom.KEY_2_LONG_PRESS_ACTION = (Data[4] < ACTION_OPT_LEN) ? Data[4] : ACTION_OPT_NONE; gEeprom.KEY_2_LONG_PRESS_ACTION = (Data[4] < ACTION_OPT_LEN) ? Data[4] : ACTION_OPT_NONE;
gEeprom.SCAN_RESUME_MODE = (Data[5] < 105) ? Data[5] : 14; gEeprom.SCAN_RESUME_MODE = (Data[5] < 105) ? Data[5] : 14;
gEeprom.AUTO_KEYPAD_LOCK = (Data[6] < 41) ? Data[6] : 0; gEeprom.AUTO_KEYPAD_LOCK = (Data[6] < 41) ? Data[6] : 0;
#ifdef ENABLE_FEAT_F4HWN gEeprom.FSKMode = Data[7];
gEeprom.POWER_ON_DISPLAY_MODE = (Data[7] < 6) ? Data[7] : POWER_ON_DISPLAY_MODE_VOLTAGE;
#else
gEeprom.POWER_ON_DISPLAY_MODE = (Data[7] < 4) ? Data[7] : POWER_ON_DISPLAY_MODE_VOLTAGE;
#endif
// 0E98..0E9F // 0E98..0E9F
#ifdef ENABLE_PWRON_PASSWORD #ifdef ENABLE_PWRON_PASSWORD
EEPROM_ReadBuffer(0x0E98, Data, 8); EEPROM_ReadBuffer(0x0E98, Data, 8);
memcpy(&gEeprom.POWER_ON_PASSWORD, Data, 4); memcpy(&gEeprom.POWER_ON_PASSWORD, Data, 4);
#endif #endif
// 0EA0..0EA7 // 0EA0..0EA7
EEPROM_ReadBuffer(0x0EA0, Data, 8); EEPROM_ReadBuffer(0x0EA0, Data, 8);
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gEeprom.VOICE_PROMPT = (Data[0] < 3) ? Data[0] : VOICE_PROMPT_ENGLISH; gEeprom.VOICE_PROMPT = (Data[0] < 3) ? Data[0] : VOICE_PROMPT_ENGLISH;
#endif #endif
#ifdef ENABLE_RSSI_BAR #ifdef ENABLE_RSSI_BAR
if((Data[1] < 200 && Data[1] > 90) && (Data[2] < Data[1]-9 && Data[1] < 160 && 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.S0_LEVEL = Data[1];
gEeprom.S9_LEVEL = Data[2]; gEeprom.S9_LEVEL = Data[2];
} } else {
else {
gEeprom.S0_LEVEL = 130; gEeprom.S0_LEVEL = 130;
gEeprom.S9_LEVEL = 76; gEeprom.S9_LEVEL = 76;
} }
#endif #endif
// 0EA8..0EAF // 0EA8..0EAF
EEPROM_ReadBuffer(0x0EA8, Data, 8); EEPROM_ReadBuffer(0x0EA8, Data, 8);
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
gEeprom.ALARM_MODE = (Data[0] < 2) ? Data[0] : true; gEeprom.ALARM_MODE = (Data[0] < 2) ? Data[0] : true;
#endif #endif
gEeprom.ROGER = (Data[1] < 3) ? Data[1] : ROGER_MODE_OFF; gEeprom.ROGER = (Data[1] < 3) ? Data[1] : ROGER_MODE_OFF;
gEeprom.REPEATER_TAIL_TONE_ELIMINATION = (Data[2] < 11) ? Data[2] : 0; gEeprom.REPEATER_TAIL_TONE_ELIMINATION = (Data[2] < 11) ? Data[2] : 0;
gEeprom.TX_VFO = (Data[3] < 2) ? Data[3] : 0; gEeprom.TX_VFO = (Data[3] < 2) ? Data[3] : 0;
@@ -229,7 +219,7 @@ void SETTINGS_InitEEPROM(void)
// 0EF8..0F07 // 0EF8..0F07
EEPROM_ReadBuffer(0x0EF8, Data, sizeof(gEeprom.DTMF_UP_CODE)); EEPROM_ReadBuffer(0x0EF8, Data, sizeof(gEeprom.DTMF_UP_CODE));
if (DTMF_ValidateCodes((char *)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)); memcpy(gEeprom.DTMF_UP_CODE, Data, sizeof(gEeprom.DTMF_UP_CODE));
} else { } else {
strcpy(gEeprom.DTMF_UP_CODE, "12345"); strcpy(gEeprom.DTMF_UP_CODE, "12345");
@@ -237,7 +227,7 @@ void SETTINGS_InitEEPROM(void)
// 0F08..0F17 // 0F08..0F17
EEPROM_ReadBuffer(0x0F08, Data, sizeof(gEeprom.DTMF_DOWN_CODE)); EEPROM_ReadBuffer(0x0F08, Data, sizeof(gEeprom.DTMF_DOWN_CODE));
if (DTMF_ValidateCodes((char *)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)); memcpy(gEeprom.DTMF_DOWN_CODE, Data, sizeof(gEeprom.DTMF_DOWN_CODE));
} else { } else {
strcpy(gEeprom.DTMF_DOWN_CODE, "54321"); strcpy(gEeprom.DTMF_DOWN_CODE, "54321");
@@ -264,62 +254,54 @@ void SETTINGS_InitEEPROM(void)
*/ */
// Fix me probably after Chirp update... // Fix me probably after Chirp update...
for (unsigned int i = 0; i < 3; i++) for (unsigned int i = 0; i < 3; i++) {
{
gEeprom.SCAN_LIST_ENABLED[i] = (Data[1] >> i) & 1; gEeprom.SCAN_LIST_ENABLED[i] = (Data[1] >> i) & 1;
} }
for (unsigned int i = 0; i < 3; i++) for (unsigned int i = 0; i < 3; i++) {
{
const unsigned int j = 1 + (i * 2); const unsigned int j = 1 + (i * 2);
gEeprom.SCANLIST_PRIORITY_CH1[i] = Data[j + 1]; gEeprom.SCANLIST_PRIORITY_CH1[i] = Data[j + 1];
gEeprom.SCANLIST_PRIORITY_CH2[i] = Data[j + 2]; gEeprom.SCANLIST_PRIORITY_CH2[i] = Data[j + 2];
} }
EEPROM_ReadBuffer(0x0F20, Data, 8);
gEeprom.FSKSRCAddress = Data[0];
gEeprom.FSKSRCAddress |= Data[1] << 8;
gEeprom.FSKSRCAddress |= Data[2] << 16;
gEeprom.FSKSRCAddress |= Data[3] << 24;
#ifdef ENABLE_FMRADIO
gEeprom.BK1080_AGC_ENABLED = Data[4] & 0x01;
gEeprom.BK1080_BLEND_CONFIG = (Data[4] >> 1) & 0x03;
gEeprom.BK1080_DEEMPHASIS_CONFIG = (Data[4] >> 3) & 0x03;
#endif
// 0F40..0F47 // 0F40..0F47
EEPROM_ReadBuffer(0x0F40, Data, 8); EEPROM_ReadBuffer(0x0F40, Data, 8);
gSetting_F_LOCK = (Data[0] < F_LOCK_LEN) ? Data[0] : F_LOCK_DEF; gSetting_F_LOCK = (Data[0] < F_LOCK_LEN) ? Data[0] : F_LOCK_DEF;
#ifndef ENABLE_FEAT_F4HWN gSetting_ScrambleEnable = true;
gSetting_350TX = (Data[1] < 2) ? Data[1] : false; // was true
#endif
#ifdef ENABLE_DTMF_CALLING
gSetting_KILLED = (Data[2] < 2) ? Data[2] : false;
#endif
#ifndef ENABLE_FEAT_F4HWN
gSetting_200TX = (Data[3] < 2) ? Data[3] : false;
gSetting_500TX = (Data[4] < 2) ? Data[4] : false;
#endif
gSetting_350EN = (Data[5] < 2) ? Data[5] : true;
#ifdef ENABLE_FEAT_F4HWN
gSetting_ScrambleEnable = false;
#else
gSetting_ScrambleEnable = (Data[6] < 2) ? Data[6] : true;
#endif
//gSetting_TX_EN = (Data[7] & (1u << 0)) ? true : false; //gSetting_TX_EN = (Data[7] & (1u << 0)) ? true : false;
gSetting_live_DTMF_decoder = !!(Data[7] & (1u << 1)); gSetting_live_DTMF_decoder = !!(Data[7] & (1u << 1));
gSetting_battery_text = (((Data[7] >> 2) & 3u) <= 2) ? (Data[7] >> 2) & 3 : 2; gSetting_battery_text = (((Data[7] >> 2) & 3u) <= 2) ? (Data[7] >> 2) & 3 : 2;
#ifdef ENABLE_AUDIO_BAR #ifdef ENABLE_AUDIO_BAR
gSetting_mic_bar = !!(Data[7] & (1u << 4)); gSetting_mic_bar = !!(Data[7] & (1u << 4));
#endif #endif
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
gSetting_AM_fix = !!(Data[7] & (1u << 5)); gSetting_AM_fix = !!(Data[7] & (1u << 5));
#endif #endif
#endif #endif
gSetting_backlight_on_tx_rx = (Data[7] >> 6) & 3u; gSetting_backlight_on_tx_rx = (Data[7] >> 6) & 3u;
if (!gEeprom.VFO_OPEN) if (!gEeprom.VFO_OPEN) {
{
gEeprom.ScreenChannel[0] = gEeprom.MrChannel[0]; gEeprom.ScreenChannel[0] = gEeprom.MrChannel[0];
gEeprom.ScreenChannel[1] = gEeprom.MrChannel[1]; gEeprom.ScreenChannel[1] = gEeprom.MrChannel[1];
} }
// 0D60..0E27 // 0D60..0E27
EEPROM_ReadBuffer(0x0D60, gMR_ChannelAttributes, sizeof(gMR_ChannelAttributes)); EEPROM_ReadBuffer(0x0D60, gMR_ChannelAttributes, sizeof(gMR_ChannelAttributes));
for(uint16_t i = 0; i < sizeof(gMR_ChannelAttributes); i++) { for (uint16_t i = 0; i < sizeof(gMR_ChannelAttributes); i++) {
ChannelAttributes_t *att = &gMR_ChannelAttributes[i]; ChannelAttributes_t *att = &gMR_ChannelAttributes[i];
if(att->__val == 0xff){ if (att->__val == 0xff) {
att->__val = 0; att->__val = 0;
att->band = 0x7; att->band = 0x7;
} }
@@ -329,7 +311,7 @@ void SETTINGS_InitEEPROM(void)
// 0F30..0F3F // 0F30..0F3F
EEPROM_ReadBuffer(0x0F30, gCustomAesKey, sizeof(gCustomAesKey)); EEPROM_ReadBuffer(0x0F30, gCustomAesKey, sizeof(gCustomAesKey));
bHasCustomAesKey = false; bHasCustomAesKey = false;
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
for (unsigned int i = 0; i < ARRAY_SIZE(gCustomAesKey); i++) for (unsigned int i = 0; i < ARRAY_SIZE(gCustomAesKey); i++)
{ {
if (gCustomAesKey[i] != 0xFFFFFFFFu) if (gCustomAesKey[i] != 0xFFFFFFFFu)
@@ -338,25 +320,17 @@ void SETTINGS_InitEEPROM(void)
return; return;
} }
} }
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
// 1FF0..0x1FF7 // 1FF0..0x1FF7
EEPROM_ReadBuffer(0x1FF0, Data, 8); EEPROM_ReadBuffer(0x1FF0, Data, 8);
gSetting_set_pwr = (((Data[7] & 0xF0) >> 4) < 7) ? ((Data[7] & 0xF0) >> 4) : 0;
gSetting_set_ptt = (((Data[7] & 0x0F)) < 2) ? ((Data[7] & 0x0F)) : 0; gSetting_set_ptt = (((Data[7] & 0x0F)) < 2) ? ((Data[7] & 0x0F)) : 0;
gSetting_set_tot = (((Data[6] & 0xF0) >> 4) < 4) ? ((Data[6] & 0xF0) >> 4) : 0;
gSetting_set_eot = (((Data[6] & 0x0F)) < 4) ? ((Data[6] & 0x0F)) : 0;
/* /*
int tmp = ((Data[5] & 0xF0) >> 4); int tmp = ((Data[5] & 0xF0) >> 4);
gSetting_set_inv = (((tmp >> 0) & 0x01) < 2) ? ((tmp >> 0) & 0x01): 0; gSetting_set_inv = (((tmp >> 0) & 0x01) < 2) ? ((tmp >> 0) & 0x01): 0;
gSetting_set_lck = (((tmp >> 1) & 0x01) < 2) ? ((tmp >> 1) & 0x01): 0;
gSetting_set_met = (((tmp >> 2) & 0x01) < 2) ? ((tmp >> 2) & 0x01): 0;
gSetting_set_gui = (((tmp >> 3) & 0x01) < 2) ? ((tmp >> 3) & 0x01): 0;
gSetting_set_ctr = (((Data[5] & 0x0F)) > 00 && ((Data[5] & 0x0F)) < 16) ? ((Data[5] & 0x0F)) : 10;
gSetting_set_tmr = ((Data[4] & 1) < 2) ? (Data[4] & 1): 0; gSetting_set_tmr = ((Data[4] & 1) < 2) ? (Data[4] & 1): 0;
*/ */
@@ -368,16 +342,6 @@ void SETTINGS_InitEEPROM(void)
#else #else
gSetting_set_inv = 0; gSetting_set_inv = 0;
#endif #endif
gSetting_set_lck = (tmp >> 1) & 0x01;
gSetting_set_met = (tmp >> 2) & 0x01;
gSetting_set_gui = (tmp >> 3) & 0x01;
#ifdef ENABLE_FEAT_F4HWN_CTR
int ctr_value = Data[5] & 0x0F;
gSetting_set_ctr = (ctr_value > 0 && ctr_value < 16) ? ctr_value : 10;
#else
gSetting_set_ctr = 10;
#endif
gSetting_set_tmr = Data[4] & 0x01; gSetting_set_tmr = Data[4] & 0x01;
#ifdef ENABLE_FEAT_F4HWN_SLEEP #ifdef ENABLE_FEAT_F4HWN_SLEEP
@@ -390,12 +354,10 @@ void SETTINGS_InitEEPROM(void)
// And set special session settings for actions // And set special session settings for actions
gSetting_set_ptt_session = gSetting_set_ptt; gSetting_set_ptt_session = gSetting_set_ptt;
gEeprom.KEY_LOCK_PTT = gSetting_set_lck; #endif
#endif
} }
void SETTINGS_LoadCalibration(void) void SETTINGS_LoadCalibration(void) {
{
// uint8_t Mic; // uint8_t Mic;
EEPROM_ReadBuffer(0x1EC0, gEEPROM_RSSI_CALIB[3], 8); EEPROM_ReadBuffer(0x1EC0, gEEPROM_RSSI_CALIB[3], 8);
@@ -408,25 +370,23 @@ void SETTINGS_LoadCalibration(void)
memcpy(gEEPROM_RSSI_CALIB[2], gEEPROM_RSSI_CALIB[0], 8); memcpy(gEEPROM_RSSI_CALIB[2], gEEPROM_RSSI_CALIB[0], 8);
EEPROM_ReadBuffer(0x1F40, gBatteryCalibration, 12); EEPROM_ReadBuffer(0x1F40, gBatteryCalibration, 12);
if (gBatteryCalibration[0] >= 5000) if (gBatteryCalibration[0] >= 5000) {
{
gBatteryCalibration[0] = 1900; gBatteryCalibration[0] = 1900;
gBatteryCalibration[1] = 2000; gBatteryCalibration[1] = 2000;
} }
gBatteryCalibration[5] = 2300; gBatteryCalibration[5] = 2300;
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
EEPROM_ReadBuffer(0x1F50 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX1_THRESHOLD, 2); EEPROM_ReadBuffer(0x1F50 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX1_THRESHOLD, 2);
EEPROM_ReadBuffer(0x1F68 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX0_THRESHOLD, 2); EEPROM_ReadBuffer(0x1F68 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX0_THRESHOLD, 2);
#endif #endif
//EEPROM_ReadBuffer(0x1F80 + gEeprom.MIC_SENSITIVITY, &Mic, 1); //EEPROM_ReadBuffer(0x1F80 + gEeprom.MIC_SENSITIVITY, &Mic, 1);
//gEeprom.MIC_SENSITIVITY_TUNING = (Mic < 32) ? Mic : 15; //gEeprom.MIC_SENSITIVITY_TUNING = (Mic < 32) ? Mic : 15;
gEeprom.MIC_SENSITIVITY_TUNING = gMicGain_dB2[gEeprom.MIC_SENSITIVITY]; gEeprom.MIC_SENSITIVITY_TUNING = gMicGain_dB2[gEeprom.MIC_SENSITIVITY];
{ {
struct struct {
{
int16_t BK4819_XtalFreqLow; int16_t BK4819_XtalFreqLow;
uint16_t EEPROM_1F8A; uint16_t EEPROM_1F8A;
uint16_t EEPROM_1F8C; uint16_t EEPROM_1F8C;
@@ -438,36 +398,34 @@ void SETTINGS_LoadCalibration(void)
// radio 2 .. 05 00 46 00 50 00 2C 0E // radio 2 .. 05 00 46 00 50 00 2C 0E
EEPROM_ReadBuffer(0x1F88, &Misc, 8); EEPROM_ReadBuffer(0x1F88, &Misc, 8);
gEeprom.BK4819_XTAL_FREQ_LOW = (Misc.BK4819_XtalFreqLow >= -1000 && Misc.BK4819_XtalFreqLow <= 1000) ? Misc.BK4819_XtalFreqLow : 0; gEeprom.BK4819_XTAL_FREQ_LOW = (Misc.BK4819_XtalFreqLow >= -1000 && Misc.BK4819_XtalFreqLow <= 1000)
? Misc.BK4819_XtalFreqLow : 0;
gEEPROM_1F8A = Misc.EEPROM_1F8A & 0x01FF; gEEPROM_1F8A = Misc.EEPROM_1F8A & 0x01FF;
gEEPROM_1F8C = Misc.EEPROM_1F8C & 0x01FF; gEEPROM_1F8C = Misc.EEPROM_1F8C & 0x01FF;
gEeprom.VOLUME_GAIN = (Misc.VOLUME_GAIN < 64) ? Misc.VOLUME_GAIN : 58; gEeprom.VOLUME_GAIN = (Misc.VOLUME_GAIN < 64) ? Misc.VOLUME_GAIN : 58;
gEeprom.DAC_GAIN = (Misc.DAC_GAIN < 16) ? Misc.DAC_GAIN : 8; gEeprom.DAC_GAIN = (Misc.DAC_GAIN < 16) ? Misc.DAC_GAIN : 8;
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
gEeprom.VOLUME_GAIN_BACKUP = gEeprom.VOLUME_GAIN; gEeprom.VOLUME_GAIN_BACKUP = gEeprom.VOLUME_GAIN;
#endif #endif
BK4819_WriteRegister(BK4819_REG_3B, 22656 + gEeprom.BK4819_XTAL_FREQ_LOW); BK4819_WriteRegister(BK4819_REG_3B, 22656 + gEeprom.BK4819_XTAL_FREQ_LOW);
// BK4819_WriteRegister(BK4819_REG_3C, gEeprom.BK4819_XTAL_FREQ_HIGH); // BK4819_WriteRegister(BK4819_REG_3C, gEeprom.BK4819_XTAL_FREQ_HIGH);
} }
} }
uint32_t SETTINGS_FetchChannelFrequency(const int channel) uint32_t SETTINGS_FetchChannelFrequency(const int channel) {
{ struct {
struct
{
uint32_t frequency; uint32_t frequency;
uint32_t offset; uint32_t offset;
} __attribute__((packed)) info; } __attribute__((packed)) info;
EEPROM_ReadBuffer(channel * 16, &info, sizeof(info)); EEPROM_ReadBuffer(channel * 20, &info, sizeof(info));
return info.frequency; return info.frequency;
} }
void SETTINGS_FetchChannelName(char *s, const int channel) void SETTINGS_FetchChannelName(char *s, const int channel) {
{
if (s == NULL) if (s == NULL)
return; return;
@@ -479,7 +437,7 @@ void SETTINGS_FetchChannelName(char *s, const int channel)
if (!RADIO_CheckValidChannel(channel, false, 0)) if (!RADIO_CheckValidChannel(channel, false, 0))
return; return;
EEPROM_ReadBuffer(0x0F50 + (channel * 16), s, 10); EEPROM_ReadBuffer(0x0F50 + (channel * 20), s, 10);
int i; int i;
for (i = 0; i < 10; i++) for (i = 0; i < 10; i++)
@@ -492,16 +450,14 @@ void SETTINGS_FetchChannelName(char *s, const int channel)
s[i--] = 0; // null term s[i--] = 0; // null term
} }
void SETTINGS_FactoryReset(bool bIsAll) void SETTINGS_FactoryReset(bool bIsAll) {
{
uint16_t i; uint16_t i;
uint8_t Template[8]; uint8_t Template[8];
memset(Template, 0xFF, sizeof(Template)); memset(Template, 0xFF, sizeof(Template));
//for (i = 0x0C80; i < 0x1E00; i += 8) //for (i = 0x0C80; i < 0x1E00; i += 8)
for (i = 0x0000; i < 0x1E00; i += 8) for (i = 0x0000; i < 0x1E00; i += 8) {
{
if ( if (
!(i >= 0x0EE0 && i < 0x0F18) && // ANI ID + DTMF codes !(i >= 0x0EE0 && i < 0x0F18) && // ANI ID + DTMF codes
!(i >= 0x0F30 && i < 0x0F50) && // AES KEY + F LOCK + Scramble Enable !(i >= 0x0F30 && i < 0x0F50) && // AES KEY + F LOCK + Scramble Enable
@@ -516,17 +472,15 @@ void SETTINGS_FactoryReset(bool bIsAll)
!(i >= 0x0E40 && i < 0x0E70) && // FM Channels !(i >= 0x0E40 && i < 0x0E70) && // FM Channels
!(i >= 0x0E88 && i < 0x0E90) // FM settings !(i >= 0x0E88 && i < 0x0E90) // FM settings
)) ))
) ) {
{
EEPROM_WriteBuffer(i, Template); EEPROM_WriteBuffer(i, Template);
} }
} }
if (bIsAll) if (bIsAll) {
{
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_FIRST + BAND6_400MHz, 43350000); RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_FIRST + BAND6_400MHz, 43350000);
#ifdef ENABLE_FEAT_F4HWN_RESET_CHANNEL #ifdef ENABLE_FEAT_F4HWN_RESET_CHANNEL
// set the first few memory channels // set the first few memory channels
for (i = 0; i < ARRAY_SIZE(gDefaultFrequencyTable); i++) for (i = 0; i < ARRAY_SIZE(gDefaultFrequencyTable); i++)
{ {
@@ -536,11 +490,11 @@ void SETTINGS_FactoryReset(bool bIsAll)
gRxVfo->Band = FREQUENCY_GetBand(Frequency); gRxVfo->Band = FREQUENCY_GetBand(Frequency);
SETTINGS_SaveChannel(MR_CHANNEL_FIRST + i, 0, gRxVfo, 2); SETTINGS_SaveChannel(MR_CHANNEL_FIRST + i, 0, gRxVfo, 2);
} }
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
EEPROM_WriteBuffer(0x1FF0, Template); EEPROM_WriteBuffer(0x1FF0, Template);
#endif #endif
} }
} }
@@ -571,13 +525,12 @@ void SETTINGS_SaveFM(void)
} }
#endif #endif
void SETTINGS_SaveVfoIndices(void) void SETTINGS_SaveVfoIndices(void) {
{
uint8_t State[8]; uint8_t State[8];
#ifndef ENABLE_NOAA #ifndef ENABLE_NOAA
EEPROM_ReadBuffer(0x0E80, State, sizeof(State)); EEPROM_ReadBuffer(0x0E80, State, sizeof(State));
#endif #endif
State[0] = gEeprom.ScreenChannel[0]; State[0] = gEeprom.ScreenChannel[0];
State[1] = gEeprom.MrChannel[0]; State[1] = gEeprom.MrChannel[0];
@@ -585,45 +538,39 @@ void SETTINGS_SaveVfoIndices(void)
State[3] = gEeprom.ScreenChannel[1]; State[3] = gEeprom.ScreenChannel[1];
State[4] = gEeprom.MrChannel[1]; State[4] = gEeprom.MrChannel[1];
State[5] = gEeprom.FreqChannel[1]; State[5] = gEeprom.FreqChannel[1];
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
State[6] = gEeprom.NoaaChannel[0]; State[6] = gEeprom.NoaaChannel[0];
State[7] = gEeprom.NoaaChannel[1]; State[7] = gEeprom.NoaaChannel[1];
#endif #endif
EEPROM_WriteBuffer(0x0E80, State); EEPROM_WriteBuffer(0x0E80, State);
} }
void SETTINGS_SaveSettings(void) void SETTINGS_SaveSettings(void) {
{
uint8_t State[8]; uint8_t State[8];
uint8_t tmp = 0; uint8_t tmp = 0;
#ifdef ENABLE_PWRON_PASSWORD #ifdef ENABLE_PWRON_PASSWORD
uint32_t Password[2]; uint32_t Password[2];
#endif #endif
State[0] = gEeprom.CHAN_1_CALL; State[0] = gEeprom.CHAN_1_CALL;
State[1] = gEeprom.SQUELCH_LEVEL; State[1] = gEeprom.SQUELCH_LEVEL;
State[2] = gEeprom.TX_TIMEOUT_TIMER; State[2] = gEeprom.TX_TIMEOUT_TIMER;
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
State[3] = gEeprom.NOAA_AUTO_SCAN; State[3] = gEeprom.NOAA_AUTO_SCAN;
#else #else
State[3] = false; State[3] = false;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS State[4] = (gEeprom.KEY_LOCK ? 0x01 : 0);
State[4] = (gEeprom.KEY_LOCK ? 0x01 : 0) | (gEeprom.MENU_LOCK ? 0x02 :0) | ((gEeprom.SET_KEY & 0x0F) << 2); #ifdef ENABLE_VOX
#else
State[4] = gEeprom.KEY_LOCK;
#endif
#ifdef ENABLE_VOX
State[5] = gEeprom.VOX_SWITCH; State[5] = gEeprom.VOX_SWITCH;
State[6] = gEeprom.VOX_LEVEL; State[6] = gEeprom.VOX_LEVEL;
#else #else
State[5] = false; State[5] = false;
State[6] = 0; State[6] = 0;
#endif #endif
State[7] = gEeprom.MIC_SENSITIVITY; State[7] = gEeprom.MIC_SENSITIVITY;
EEPROM_WriteBuffer(0x0E70, State); EEPROM_WriteBuffer(0x0E70, State);
@@ -633,35 +580,28 @@ void SETTINGS_SaveSettings(void)
State[3] = gEeprom.BATTERY_SAVE; State[3] = gEeprom.BATTERY_SAVE;
State[4] = gEeprom.DUAL_WATCH; State[4] = gEeprom.DUAL_WATCH;
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
if(!gSaveRxMode) if (!gSaveRxMode) {
{
State[2] = gCB; State[2] = gCB;
State[4] = gDW; State[4] = gDW;
} }
if(gBackLight) if (gBackLight) {
{
State[5] = gBacklightTimeOriginal; State[5] = gBacklightTimeOriginal;
} } else {
else
{
State[5] = gEeprom.BACKLIGHT_TIME; State[5] = gEeprom.BACKLIGHT_TIME;
} }
#else #else
State[5] = gEeprom.BACKLIGHT_TIME; State[5] = gEeprom.BACKLIGHT_TIME;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_NARROWER State[6] = gEeprom.TAIL_TONE_ELIMINATION & 0x01;
State[6] = (gEeprom.TAIL_TONE_ELIMINATION & 0x01) | ((gSetting_set_nfm & 0x03) << 1);
#else
State[6] = gEeprom.TAIL_TONE_ELIMINATION;
#endif
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE #ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
State[7] = (gEeprom.VFO_OPEN & 0x01) | ((gEeprom.CURRENT_STATE & 0x07) << 1) | ((gEeprom.SCAN_LIST_DEFAULT & 0x07) << 4); State[7] = (gEeprom.VFO_OPEN & 0x01) | ((gEeprom.CURRENT_STATE & 0x07) << 1) |
#else ((gEeprom.SCAN_LIST_DEFAULT & 0x07) << 4);
#else
State[7] = gEeprom.VFO_OPEN; State[7] = gEeprom.VFO_OPEN;
#endif #endif
EEPROM_WriteBuffer(0x0E78, State); EEPROM_WriteBuffer(0x0E78, State);
State[0] = gEeprom.BEEP_CONTROL; State[0] = gEeprom.BEEP_CONTROL;
@@ -672,14 +612,14 @@ void SETTINGS_SaveSettings(void)
State[4] = gEeprom.KEY_2_LONG_PRESS_ACTION; State[4] = gEeprom.KEY_2_LONG_PRESS_ACTION;
State[5] = gEeprom.SCAN_RESUME_MODE; State[5] = gEeprom.SCAN_RESUME_MODE;
State[6] = gEeprom.AUTO_KEYPAD_LOCK; State[6] = gEeprom.AUTO_KEYPAD_LOCK;
State[7] = gEeprom.POWER_ON_DISPLAY_MODE; State[7] = gEeprom.FSKMode;
EEPROM_WriteBuffer(0x0E90, State); EEPROM_WriteBuffer(0x0E90, State);
#ifdef ENABLE_PWRON_PASSWORD #ifdef ENABLE_PWRON_PASSWORD
memset(Password, 0xFF, sizeof(Password)); memset(Password, 0xFF, sizeof(Password));
Password[0] = gEeprom.POWER_ON_PASSWORD; Password[0] = gEeprom.POWER_ON_PASSWORD;
EEPROM_WriteBuffer(0x0E98, Password); EEPROM_WriteBuffer(0x0E98, Password);
#endif #endif
memset(State, 0xFF, sizeof(State)); memset(State, 0xFF, sizeof(State));
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
@@ -692,11 +632,11 @@ void SETTINGS_SaveSettings(void)
EEPROM_WriteBuffer(0x0EA0, State); EEPROM_WriteBuffer(0x0EA0, State);
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
State[0] = gEeprom.ALARM_MODE; State[0] = gEeprom.ALARM_MODE;
#else #else
State[0] = false; State[0] = false;
#endif #endif
State[1] = gEeprom.ROGER; State[1] = gEeprom.ROGER;
State[2] = gEeprom.REPEATER_TAIL_TONE_ELIMINATION; State[2] = gEeprom.REPEATER_TAIL_TONE_ELIMINATION;
State[3] = gEeprom.TX_VFO; State[3] = gEeprom.TX_VFO;
@@ -743,36 +683,40 @@ void SETTINGS_SaveSettings(void)
State[7] = gEeprom.SCANLIST_PRIORITY_CH2[2]; State[7] = gEeprom.SCANLIST_PRIORITY_CH2[2];
EEPROM_WriteBuffer(0x0F18, State); EEPROM_WriteBuffer(0x0F18, State);
State[0] = gEeprom.FSKSRCAddress & 0xFF;
State[1] = (gEeprom.FSKSRCAddress >> 8) & 0xFF;
State[2] = (gEeprom.FSKSRCAddress >> 16) & 0xFF;
State[3] = (gEeprom.FSKSRCAddress >> 24) & 0xFF;
#ifdef ENABLE_FMRADIO
State[4] = ((gEeprom.BK1080_AGC_ENABLED & 0x01) |
((gEeprom.BK1080_BLEND_CONFIG & 0x03) << 1) |
((gEeprom.BK1080_DEEMPHASIS_CONFIG & 0x03) << 3));
#endif
EEPROM_WriteBuffer(0x0F20, State);
memset(State, 0xFF, sizeof(State)); memset(State, 0xFF, sizeof(State));
State[0] = gSetting_F_LOCK; State[0] = gSetting_F_LOCK;
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
State[1] = gSetting_350TX; State[1] = gSetting_350TX;
#endif #endif
#ifdef ENABLE_DTMF_CALLING
State[2] = gSetting_KILLED;
#endif
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
State[3] = gSetting_200TX; State[3] = gSetting_200TX;
State[4] = gSetting_500TX; State[4] = gSetting_500TX;
#endif #endif
State[5] = gSetting_350EN;
#ifdef ENABLE_FEAT_F4HWN
State[6] = false;
#else
State[6] = gSetting_ScrambleEnable; State[6] = gSetting_ScrambleEnable;
#endif
//if (!gSetting_TX_EN) State[7] &= ~(1u << 0); //if (!gSetting_TX_EN) State[7] &= ~(1u << 0);
if (!gSetting_live_DTMF_decoder) State[7] &= ~(1u << 1); if (!gSetting_live_DTMF_decoder) State[7] &= ~(1u << 1);
State[7] = (State[7] & ~(3u << 2)) | ((gSetting_battery_text & 3u) << 2); State[7] = (State[7] & ~(3u << 2)) | ((gSetting_battery_text & 3u) << 2);
#ifdef ENABLE_AUDIO_BAR #ifdef ENABLE_AUDIO_BAR
if (!gSetting_mic_bar) State[7] &= ~(1u << 4); if (!gSetting_mic_bar) State[7] &= ~(1u << 4);
#endif #endif
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
if (!gSetting_AM_fix) State[7] &= ~(1u << 5); if (!gSetting_AM_fix) State[7] &= ~(1u << 5);
#endif #endif
#endif #endif
State[7] = (State[7] & ~(3u << 6)) | ((gSetting_backlight_on_tx_rx & 3u) << 6); State[7] = (State[7] & ~(3u << 6)) | ((gSetting_backlight_on_tx_rx & 3u) << 6);
EEPROM_WriteBuffer(0x0F40, State); EEPROM_WriteBuffer(0x0F40, State);
@@ -794,12 +738,6 @@ void SETTINGS_SaveSettings(void)
if(gSetting_set_inv == 1) if(gSetting_set_inv == 1)
tmp = tmp | (1 << 0); tmp = tmp | (1 << 0);
if (gSetting_set_lck == 1)
tmp = tmp | (1 << 1);
if (gSetting_set_met == 1)
tmp = tmp | (1 << 2);
if (gSetting_set_gui == 1)
tmp = tmp | (1 << 3);
*/ */
#ifdef ENABLE_FEAT_F4HWN_SLEEP #ifdef ENABLE_FEAT_F4HWN_SLEEP
@@ -808,16 +746,10 @@ void SETTINGS_SaveSettings(void)
State[4] = gSetting_set_tmr ? (1 << 0) : 0; State[4] = gSetting_set_tmr ? (1 << 0) : 0;
#endif #endif
tmp = (gSetting_set_inv << 0) | tmp = (gSetting_set_inv << 0);
(gSetting_set_lck << 1) |
(gSetting_set_met << 2) |
(gSetting_set_gui << 3);
State[5] = ((tmp << 4) | (gSetting_set_ctr & 0x0F)); State[5] = (tmp << 4);
State[6] = ((gSetting_set_tot << 4) | (gSetting_set_eot & 0x0F)); State[7] = gSetting_set_ptt & 0x0F;
State[7] = ((gSetting_set_pwr << 4) | (gSetting_set_ptt & 0x0F));
gEeprom.KEY_LOCK_PTT = gSetting_set_lck;
EEPROM_WriteBuffer(0x1FF0, State); EEPROM_WriteBuffer(0x1FF0, State);
#endif #endif
@@ -827,17 +759,16 @@ void SETTINGS_SaveSettings(void)
#endif #endif
} }
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode) void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode) {
{
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(Channel)) if (IS_NOAA_CHANNEL(Channel))
return; return;
#endif #endif
uint16_t OffsetVFO = Channel * 16; uint16_t OffsetVFO = Channel * 24;
if (IS_FREQ_CHANNEL(Channel)) { // it's a VFO, not a channel if (IS_FREQ_CHANNEL(Channel)) { // it's a VFO, not a channel
OffsetVFO = (VFO == 0) ? 0x0C80 : 0x0C90; OffsetVFO = (VFO == 0) ? 0x0C80 : 0x0C98;
OffsetVFO += (Channel - FREQ_CHANNEL_FIRST) * 32; OffsetVFO += (Channel - FREQ_CHANNEL_FIRST) * 32;
} }
@@ -845,6 +776,7 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
union { union {
uint8_t _8[8]; uint8_t _8[8];
uint32_t _32[2]; uint32_t _32[2];
uint16_t _16[4];
} State; } State;
State._32[0] = pVFO->freq_config_RX.Frequency; State._32[0] = pVFO->freq_config_RX.Frequency;
@@ -856,9 +788,8 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
State._8[2] = (pVFO->freq_config_TX.CodeType << 4) | pVFO->freq_config_RX.CodeType; State._8[2] = (pVFO->freq_config_TX.CodeType << 4) | pVFO->freq_config_RX.CodeType;
State._8[3] = (pVFO->Modulation << 4) | pVFO->TX_OFFSET_FREQUENCY_DIRECTION; State._8[3] = (pVFO->Modulation << 4) | pVFO->TX_OFFSET_FREQUENCY_DIRECTION;
State._8[4] = 0 State._8[4] = 0
| (pVFO->TX_LOCK << 6) | (pVFO->BUSY_CHANNEL_LOCK << 6)
| (pVFO->BUSY_CHANNEL_LOCK << 5) | (pVFO->OUTPUT_POWER << 3)
| (pVFO->OUTPUT_POWER << 2)
| (pVFO->CHANNEL_BANDWIDTH << 1) | (pVFO->CHANNEL_BANDWIDTH << 1)
| (pVFO->FrequencyReverse << 0); | (pVFO->FrequencyReverse << 0);
State._8[5] = ((pVFO->DTMF_PTT_ID_TX_MODE & 7u) << 1) State._8[5] = ((pVFO->DTMF_PTT_ID_TX_MODE & 7u) << 1)
@@ -867,12 +798,11 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
#endif #endif
; ;
State._8[6] = pVFO->STEP_SETTING; State._8[6] = pVFO->STEP_SETTING;
#ifdef ENABLE_FEAT_F4HWN EEPROM_WriteBuffer(OffsetVFO + sizeof (State._32), State._8);
State._8[7] = 0;
#else State._16[0] = pVFO->SCRAMBLING_TYPE;
State._8[7] = pVFO->SCRAMBLING_TYPE; EEPROM_WriteBuffer(OffsetVFO + sizeof (State._32) + sizeof (State._8), State._16);
#endif
EEPROM_WriteBuffer(OffsetVFO + 8, State._8);
SETTINGS_UpdateChannel(Channel, pVFO, true, true, true); SETTINGS_UpdateChannel(Channel, pVFO, true, true, true);
@@ -890,27 +820,24 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
} }
void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration) void SETTINGS_SaveBatteryCalibration(const uint16_t *batteryCalibration) {
{
uint16_t buf[4]; uint16_t buf[4];
EEPROM_WriteBuffer(0x1F40, batteryCalibration); EEPROM_WriteBuffer(0x1F40, batteryCalibration);
EEPROM_ReadBuffer( 0x1F48, buf, sizeof(buf)); EEPROM_ReadBuffer(0x1F48, buf, sizeof(buf));
buf[0] = batteryCalibration[4]; buf[0] = batteryCalibration[4];
buf[1] = batteryCalibration[5]; buf[1] = batteryCalibration[5];
EEPROM_WriteBuffer(0x1F48, buf); EEPROM_WriteBuffer(0x1F48, buf);
} }
void SETTINGS_SaveChannelName(uint8_t channel, const char * name) void SETTINGS_SaveChannelName(uint8_t channel, const char *name) {
{ uint16_t offset = channel * 24;
uint16_t offset = channel * 16;
uint8_t buf[16] = {0}; uint8_t buf[16] = {0};
memcpy(buf, name, MIN(strlen(name), 10u)); memcpy(buf, name, MIN(strlen(name), 10u));
EEPROM_WriteBuffer(0x0F50 + offset, buf); EEPROM_WriteBuffer(0x0F50 + offset, buf);
EEPROM_WriteBuffer(0x0F58 + offset, buf + 8); EEPROM_WriteBuffer(0x0F58 + offset, buf + 8);
} }
void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep, bool check, bool save) void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep, bool check, bool save) {
{
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(channel)) if (!IS_NOAA_CHANNEL(channel))
#endif #endif
@@ -940,8 +867,7 @@ void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep,
state[channel & 7u] = att.__val; state[channel & 7u] = att.__val;
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
if(save) if (save) {
{
EEPROM_WriteBuffer(offset, state); EEPROM_WriteBuffer(offset, state);
} }
#else #else
@@ -959,31 +885,30 @@ void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep,
} }
} }
void SETTINGS_WriteBuildOptions(void) void SETTINGS_WriteBuildOptions(void) {
{
uint8_t State[8]; uint8_t State[8];
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
EEPROM_ReadBuffer(0x1FF0, State, sizeof(State)); EEPROM_ReadBuffer(0x1FF0, State, sizeof(State));
#endif #endif
State[0] = 0 State[0] = 0
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
| (1 << 0) | (1 << 0)
#endif #endif
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
| (1 << 1) | (1 << 1)
#endif #endif
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
| (1 << 2) | (1 << 2)
#endif #endif
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
| (1 << 3) | (1 << 3)
#endif #endif
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
| (1 << 4) | (1 << 4)
#endif #endif
#ifdef ENABLE_TX1750 #ifdef ENABLE_TX1750
| (1 << 5) | (1 << 5)
#endif #endif
#ifdef ENABLE_PWRON_PASSWORD #ifdef ENABLE_PWRON_PASSWORD
@@ -992,65 +917,65 @@ State[0] = 0
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
| (1 << 7) | (1 << 7)
#endif #endif
; ;
State[1] = 0 State[1] = 0
#ifdef ENABLE_FLASHLIGHT #ifdef ENABLE_FLASHLIGHT
| (1 << 0) | (1 << 0)
#endif #endif
#ifdef ENABLE_WIDE_RX #ifdef ENABLE_WIDE_RX
| (1 << 1) | (1 << 1)
#endif #endif
#ifdef ENABLE_BYP_RAW_DEMODULATORS #ifdef ENABLE_BYP_RAW_DEMODULATORS
| (1 << 2) | (1 << 2)
#endif #endif
#ifdef ENABLE_BLMIN_TMP_OFF #ifdef ENABLE_BLMIN_TMP_OFF
| (1 << 3) | (1 << 3)
#endif #endif
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
| (1 << 4) | (1 << 4)
#endif #endif
#ifdef ENABLE_SPECTRUM #ifdef ENABLE_SPECTRUM
| (1 << 5) | (1 << 5)
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS | (1 << 6);
| (1 << 6)
#endif
;
EEPROM_WriteBuffer(0x1FF0, State); EEPROM_WriteBuffer(0x1FF0, State);
} }
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE #ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
void SETTINGS_WriteCurrentState(void)
{ void SETTINGS_WriteCurrentState(void) {
uint8_t State[8]; uint8_t State[8];
EEPROM_ReadBuffer(0x0E78, State, sizeof(State)); EEPROM_ReadBuffer(0x0E78, State, sizeof(State));
//State[3] = (gEeprom.CURRENT_STATE << 4) | (gEeprom.BATTERY_SAVE & 0x0F); //State[3] = (gEeprom.CURRENT_STATE << 4) | (gEeprom.BATTERY_SAVE & 0x0F);
State[7] = (gEeprom.VFO_OPEN & 0x01) | ((gEeprom.CURRENT_STATE & 0x07) << 1) | ((gEeprom.SCAN_LIST_DEFAULT & 0x07) << 4); State[7] = (gEeprom.VFO_OPEN & 0x01) | ((gEeprom.CURRENT_STATE & 0x07) << 1) |
((gEeprom.SCAN_LIST_DEFAULT & 0x07) << 4);
EEPROM_WriteBuffer(0x0E78, State); EEPROM_WriteBuffer(0x0E78, State);
} }
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_VOL #ifdef ENABLE_FEAT_F4HWN_VOL
void SETTINGS_WriteCurrentVol(void)
{ void SETTINGS_WriteCurrentVol(void) {
uint8_t State[8]; uint8_t State[8];
EEPROM_ReadBuffer(0x1F88, State, sizeof(State)); EEPROM_ReadBuffer(0x1F88, State, sizeof(State));
State[6] = gEeprom.VOLUME_GAIN; State[6] = gEeprom.VOLUME_GAIN;
EEPROM_WriteBuffer(0x1F88, State); EEPROM_WriteBuffer(0x1F88, State);
} }
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
void SETTINGS_ResetTxLock(void)
{ void SETTINGS_ResetTxLock(void) {
uint8_t State[8]; uint8_t State[8];
for(uint8_t channel = 0; channel < 200; channel++) for (uint8_t channel = 0; channel < 200; channel++) {
{ uint16_t OffsetVFO = channel * 24;
uint16_t OffsetVFO = channel * 16;
EEPROM_ReadBuffer(OffsetVFO + 8, State, sizeof(State)); EEPROM_ReadBuffer(OffsetVFO + 8, State, sizeof(State));
State[4] |= (1 << 6); State[4] |= (1 << 6);
EEPROM_WriteBuffer(OffsetVFO + 8, State); EEPROM_WriteBuffer(OffsetVFO + 8, State);
} }
} }
#endif #endif

View File

@@ -23,8 +23,20 @@
#include "frequencies.h" #include "frequencies.h"
#include <helper/battery.h> #include <helper/battery.h>
#include "radio.h" #include "radio.h"
#include "functions.h"
#include "app/fskmodem.h"
#include <driver/backlight.h> #include <driver/backlight.h>
// Modem Modulation
typedef enum ModemModulation {
MOD_FSK_450, // for bad conditions
MOD_FSK_700, // for medium conditions
MOD_AFSK_1200, // for good conditions
MOD_AFSK_2400,
MOD_FSK_1200_2400,
MOD_NOAA_SAME
} ModemModulation;
enum POWER_OnDisplayMode_t { enum POWER_OnDisplayMode_t {
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
POWER_ON_DISPLAY_MODE_ALL, POWER_ON_DISPLAY_MODE_ALL,
@@ -40,14 +52,14 @@ typedef enum POWER_OnDisplayMode_t POWER_OnDisplayMode_t;
enum TxLockModes_t { enum TxLockModes_t {
F_LOCK_DEF, //all default frequencies + configurable F_LOCK_DEF, //all default frequencies + configurable
F_LOCK_FCC,
#ifdef ENABLE_FEAT_F4HWN_CA #ifdef ENABLE_FEAT_F4HWN_CA
F_LOCK_FCC,
F_LOCK_CA, F_LOCK_CA,
#endif
F_LOCK_CE, F_LOCK_CE,
F_LOCK_GB, F_LOCK_GB,
F_LOCK_430, F_LOCK_430,
F_LOCK_438, F_LOCK_438,
#endif
#ifdef ENABLE_FEAT_F4HWN_PMR #ifdef ENABLE_FEAT_F4HWN_PMR
F_LOCK_PMR, F_LOCK_PMR,
#endif #endif
@@ -86,8 +98,7 @@ enum {
}; };
enum { enum {
OUTPUT_POWER_USER = 0, OUTPUT_POWER_LOW1 = 0,
OUTPUT_POWER_LOW1,
OUTPUT_POWER_LOW2, OUTPUT_POWER_LOW2,
OUTPUT_POWER_LOW3, OUTPUT_POWER_LOW3,
OUTPUT_POWER_LOW4, OUTPUT_POWER_LOW4,
@@ -113,15 +124,10 @@ enum ACTION_OPT_t {
ACTION_OPT_BLMIN_TMP_OFF, //BackLight Minimum Temporay OFF ACTION_OPT_BLMIN_TMP_OFF, //BackLight Minimum Temporay OFF
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
ACTION_OPT_RXMODE, ACTION_OPT_RXMODE,
ACTION_OPT_MAINONLY,
ACTION_OPT_PTT, ACTION_OPT_PTT,
ACTION_OPT_WN, ACTION_OPT_WN,
ACTION_OPT_BACKLIGHT, ACTION_OPT_BACKLIGHT,
ACTION_OPT_MUTE, ACTION_OPT_MUTE,
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
ACTION_OPT_POWER_HIGH,
ACTION_OPT_REMOVE_OFFSET,
#endif
#endif #endif
#ifdef ENABLE_REGA #ifdef ENABLE_REGA
ACTION_OPT_REGA_ALARM, ACTION_OPT_REGA_ALARM,
@@ -131,13 +137,13 @@ enum ACTION_OPT_t {
}; };
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
enum VOICE_Prompt_t enum VOICE_Prompt_t
{ {
VOICE_PROMPT_OFF = 0, VOICE_PROMPT_OFF = 0,
VOICE_PROMPT_CHINESE, VOICE_PROMPT_CHINESE,
VOICE_PROMPT_ENGLISH VOICE_PROMPT_ENGLISH
}; };
typedef enum VOICE_Prompt_t VOICE_Prompt_t; typedef enum VOICE_Prompt_t VOICE_Prompt_t;
#endif #endif
enum ALARM_Mode_t { enum ALARM_Mode_t {
@@ -161,6 +167,19 @@ enum CHANNEL_DisplayMode_t {
}; };
typedef enum CHANNEL_DisplayMode_t CHANNEL_DisplayMode_t; typedef enum CHANNEL_DisplayMode_t CHANNEL_DisplayMode_t;
enum BK1080_DEEMPHASIS {
DEEMPHASIS_OFF = 0,
DEEMPHASIS_USA = 1,
DEEMPHASIS_EUR = 2
};
enum BK1080_BLEND {
BLEND_DEF = 0,
BLEND_POS6 = 1,
BLEND_NEG12 = 2,
BLEND_NEG6 = 3
};
typedef struct { typedef struct {
uint8_t ScreenChannel[2]; // current channels set in the radio (memory or frequency channels) uint8_t ScreenChannel[2]; // current channels set in the radio (memory or frequency channels)
uint8_t FreqChannel[2]; // last frequency channels used uint8_t FreqChannel[2]; // last frequency channels used
@@ -186,6 +205,9 @@ typedef struct {
bool FM_IsMrMode; bool FM_IsMrMode;
uint16_t FM_FrequencyPlaying; uint16_t FM_FrequencyPlaying;
uint8_t FM_Band : 2; uint8_t FM_Band : 2;
enum BK1080_DEEMPHASIS BK1080_DEEMPHASIS_CONFIG: 2;
enum BK1080_BLEND BK1080_BLEND_CONFIG : 2;
bool BK1080_AGC_ENABLED;
//uint8_t FM_Space : 2; //uint8_t FM_Space : 2;
#endif #endif
@@ -195,10 +217,7 @@ typedef struct {
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
bool KEY_LOCK_PTT; bool KEY_LOCK_PTT;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
bool MENU_LOCK; bool MENU_LOCK;
uint8_t SET_KEY;
#endif
bool VOX_SWITCH; bool VOX_SWITCH;
uint8_t VOX_LEVEL; uint8_t VOX_LEVEL;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
@@ -277,9 +296,9 @@ typedef struct {
bool NOAA_AUTO_SCAN; bool NOAA_AUTO_SCAN;
#endif #endif
uint8_t VOLUME_GAIN; uint8_t VOLUME_GAIN;
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
uint8_t VOLUME_GAIN_BACKUP; uint8_t VOLUME_GAIN_BACKUP;
#endif #endif
uint8_t DAC_GAIN; uint8_t DAC_GAIN;
VFO_Info_t VfoInfo[2]; VFO_Info_t VfoInfo[2];
@@ -302,32 +321,54 @@ typedef struct {
uint8_t S0_LEVEL; uint8_t S0_LEVEL;
uint8_t S9_LEVEL; uint8_t S9_LEVEL;
#endif #endif
ModemModulation FSKMode;
uint32_t FSKSRCAddress;
} EEPROM_Config_t; } EEPROM_Config_t;
extern EEPROM_Config_t gEeprom; extern EEPROM_Config_t gEeprom;
void SETTINGS_InitEEPROM(void); void SETTINGS_InitEEPROM(void);
void SETTINGS_LoadCalibration(void); void SETTINGS_LoadCalibration(void);
uint32_t SETTINGS_FetchChannelFrequency(const int channel); uint32_t SETTINGS_FetchChannelFrequency(const int channel);
void SETTINGS_FetchChannelName(char *s, const int channel); void SETTINGS_FetchChannelName(char *s, const int channel);
void SETTINGS_FactoryReset(bool bIsAll); void SETTINGS_FactoryReset(bool bIsAll);
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
void SETTINGS_SaveFM(void); void SETTINGS_SaveFM(void);
#endif #endif
void SETTINGS_SaveVfoIndices(void); void SETTINGS_SaveVfoIndices(void);
void SETTINGS_SaveSettings(void); void SETTINGS_SaveSettings(void);
void SETTINGS_SaveChannelName(uint8_t channel, const char * name);
void SETTINGS_SaveChannelName(uint8_t channel, const char *name);
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode); void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode);
void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration);
void SETTINGS_SaveBatteryCalibration(const uint16_t *batteryCalibration);
void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep, bool check, bool save); void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep, bool check, bool save);
void SETTINGS_WriteBuildOptions(void); void SETTINGS_WriteBuildOptions(void);
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE #ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
void SETTINGS_WriteCurrentState(void);
void SETTINGS_WriteCurrentState(void);
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_VOL #ifdef ENABLE_FEAT_F4HWN_VOL
void SETTINGS_WriteCurrentVol(void);
void SETTINGS_WriteCurrentVol(void);
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
void SETTINGS_ResetTxLock(void);
void SETTINGS_ResetTxLock(void);
#endif #endif
#endif #endif

View File

@@ -52,7 +52,7 @@ void UI_DisplayAircopy(void)
gAircopyState = AIRCOPY_READY; gAircopyState = AIRCOPY_READY;
} }
UI_PrintString(pPrintStr, 2, 127, 0, 8); UI_PrintString(pPrintStr, 2, 127, 0 /*, 8 */);
if (gInputBoxIndex == 0) { if (gInputBoxIndex == 0) {
uint32_t frequency = gRxVfo->freq_config_RX.Frequency; uint32_t frequency = gRxVfo->freq_config_RX.Frequency;
@@ -61,11 +61,13 @@ void UI_DisplayAircopy(void)
UI_PrintStringSmallNormal(String + 7, 97, 0, 3); UI_PrintStringSmallNormal(String + 7, 97, 0, 3);
String[7] = 0; String[7] = 0;
// show the main large frequency digits // show the main large frequency digits
UI_DisplayFrequency(String, 16, 2, false); //UI_DisplayFrequency(String, 16, 2, false);
UI_PrintStringSmallNormal(String, 0, 20, 2);
} else { } else {
const char *ascii = INPUTBOX_GetAscii(); const char *ascii = INPUTBOX_GetAscii();
sprintf(String, "%.3s.%.3s", ascii, ascii + 3); sprintf(String, "%.3s.%.3s", ascii, ascii + 3);
UI_DisplayFrequency(String, 16, 2, false); //UI_DisplayFrequency(String, 16, 2, false);
UI_PrintStringSmallNormal(String, 0, 20, 2);
} }
memset(String, 0, sizeof(String)); memset(String, 0, sizeof(String));
@@ -81,7 +83,7 @@ void UI_DisplayAircopy(void)
// Draw gauge // Draw gauge
if(gAircopyStep != 0) if(gAircopyStep != 0)
{ {
UI_PrintString(String, 2, 127, 5, 8); UI_PrintString(String, 2, 127, 5 /*, 8 */);
gFrameBuffer[4][1] = 0x3c; gFrameBuffer[4][1] = 0x3c;
gFrameBuffer[4][2] = 0x42; gFrameBuffer[4][2] = 0x42;

View File

@@ -29,13 +29,61 @@
#include "ui/inputbox.h" #include "ui/inputbox.h"
#include "ui/ui.h" #include "ui/ui.h"
const char gBlendStrings[][4] = {
"DEF",
"+6 ",
"-12",
"-6 "
};
const char gDeemphasisStrings[][3] = {
"NO",
"US",
"EU"
};
bool wasStereo;
uint8_t oldRssi;
void UI_UpdateFMThings(bool force) {
force = force;
char String[16] = {0};
const uint16_t Status = BK1080_ReadRegister(BK1080_REG_10_RSSI_STATUS);
bool isStereo = Status & (1 << 9);
uint8_t rssi = Status & 0xFF;
if (!force && isStereo == wasStereo && rssi == oldRssi) {
return;
}
oldRssi = rssi;
wasStereo = isStereo;
sprintf(String, "%s RSSI%d/255",
isStereo ? "STER" : "MONO", rssi);
UI_PrintStringSmallNormal(String, 1, 0, 4);
ST7565_BlitLine(4);
}
void UI_DisplayFM(void) void UI_DisplayFM(void)
{ {
char String[16] = {0}; char String[16] = {0};
char *pPrintStr = String; char *pPrintStr = String;
UI_DisplayClear(); UI_DisplayClear();
UI_PrintString("FM", 2, 0, 0, 8); UI_UpdateFMThings(true);
UI_PrintString("FM", 2, 0, 0 /*, 8 */);
sprintf(String, "%s D%s B%s",
gEeprom.BK1080_AGC_ENABLED ? " AGC" : "NAGC",
gDeemphasisStrings[gEeprom.BK1080_DEEMPHASIS_CONFIG],
gBlendStrings[gEeprom.BK1080_BLEND_CONFIG]);
UI_PrintStringSmallNormal(String, 1, 0, 5);
sprintf(String, "%d%s-%dM", sprintf(String, "%d%s-%dM",
BK1080_GetFreqLoLimit(gEeprom.FM_Band)/10, BK1080_GetFreqLoLimit(gEeprom.FM_Band)/10,
@@ -50,51 +98,51 @@ void UI_DisplayFM(void)
//UI_PrintStringSmallNormal(String, 127 - 4*7, 0, 6); //UI_PrintStringSmallNormal(String, 127 - 4*7, 0, 6);
if (gAskToSave) { if (gAskToSave) {
pPrintStr = "SAVE?"; pPrintStr = "SAV?";
} else if (gAskToDelete) { } else if (gAskToDelete) {
pPrintStr = "DEL?"; pPrintStr = "DEL?";
} else if (gFM_ScanState == FM_SCAN_OFF) { } else if (gFM_ScanState == FM_SCAN_OFF) {
if (gEeprom.FM_IsMrMode) { if (gEeprom.FM_IsMrMode) {
sprintf(String, "MR(CH%02u)", gEeprom.FM_SelectedChannel + 1); sprintf(String, "CH%02u", gEeprom.FM_SelectedChannel + 1);
pPrintStr = String; pPrintStr = String;
} else { } else {
pPrintStr = "VFO"; pPrintStr = "VFO";
for (unsigned int i = 0; i < 20; i++) { for (unsigned int i = 0; i < 20; i++) {
if (gEeprom.FM_FrequencyPlaying == gFM_Channels[i]) { if (gEeprom.FM_FrequencyPlaying == gFM_Channels[i]) {
sprintf(String, "VFO(CH%02u)", i + 1); sprintf(String, "C%02u MHz", i + 1);
pPrintStr = String; pPrintStr = String;
break; break;
} }
} }
} }
} else if (gFM_AutoScan) { } else if (gFM_AutoScan) {
sprintf(String, "A-SCAN(%u)", gFM_ChannelPosition + 1); sprintf(String, "A-SCN(%u)", gFM_ChannelPosition + 1);
pPrintStr = String; pPrintStr = String;
} else { } else {
pPrintStr = "M-SCAN"; pPrintStr = "M-SCN";
} }
UI_PrintString(pPrintStr, 0, 127, 3, 10); // memory, vfo, scan UI_PrintString(pPrintStr, 0, 127, 3 /*, 12 */); // memory, vfo, scan
memset(String, 0, sizeof(String)); memset(String, 0, sizeof(String));
if (gAskToSave || (gEeprom.FM_IsMrMode && gInputBoxIndex > 0)) { if (gAskToSave || (gEeprom.FM_IsMrMode && gInputBoxIndex > 0)) {
UI_GenerateChannelString(String, gFM_ChannelPosition); UI_GenerateChannelString(String, gFM_ChannelPosition);
} else if (gAskToDelete) { } else if (gAskToDelete) {
sprintf(String, "CH-%02u", gEeprom.FM_SelectedChannel + 1); sprintf(String, "C-%02u", gEeprom.FM_SelectedChannel + 1);
} else { } else {
if (gInputBoxIndex == 0) { if (gInputBoxIndex == 0) {
sprintf(String, "%3d.%d", gEeprom.FM_FrequencyPlaying / 10, gEeprom.FM_FrequencyPlaying % 10); sprintf(String, " %3d.%d", gEeprom.FM_FrequencyPlaying / 10, gEeprom.FM_FrequencyPlaying % 10);
} else { } else {
const char * ascii = INPUTBOX_GetAscii(); const char * ascii = INPUTBOX_GetAscii();
sprintf(String, "%.3s.%.1s",ascii, ascii + 3); sprintf(String, "%.3s.%.1s",ascii, ascii + 3);
} }
UI_DisplayFrequency(String, 36, 1, gInputBoxIndex == 0); // frequency UI_PrintString(String, 0, 20, 1 /*, 10 */); // frequency
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
return; return;
} }
UI_PrintString(String, 0, 127, 1, 10); UI_PrintString(String, 0, 127, 1 /*, 10 */);
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
} }

View File

@@ -19,6 +19,7 @@
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
void UI_DisplayFM(void); void UI_DisplayFM(void);
void UI_UpdateFMThings(bool force);
#endif #endif
#endif #endif

View File

@@ -24,15 +24,13 @@
#include "misc.h" #include "misc.h"
#ifndef ARRAY_SIZE #ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0])) #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]))
#endif #endif
void UI_GenerateChannelString(char *pString, const uint8_t Channel) void UI_GenerateChannelString(char *pString, const uint8_t Channel) {
{
unsigned int i; unsigned int i;
if (gInputBoxIndex == 0) if (gInputBoxIndex == 0) {
{
sprintf(pString, "CH-%02u", Channel + 1); sprintf(pString, "CH-%02u", Channel + 1);
return; return;
} }
@@ -44,8 +42,7 @@ void UI_GenerateChannelString(char *pString, const uint8_t Channel)
pString[i + 3] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0'; pString[i + 3] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0';
} }
void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uint8_t ChannelNumber) void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uint8_t ChannelNumber) {
{
if (gInputBoxIndex > 0) { if (gInputBoxIndex > 0) {
for (unsigned int i = 0; i < 3; i++) { for (unsigned int i = 0; i < 3; i++) {
pString[i] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0'; pString[i] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0';
@@ -65,41 +62,44 @@ void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uin
} }
} }
void UI_PrintStringBuffer(const char *pString, uint8_t * buffer, uint32_t char_width, const uint8_t *font) void *memcpy_inv(void *dst, const void *src, size_t n) {
{ if (!dst || !src) return dst;
uint8_t *d = (uint8_t *) dst;
const uint8_t *s = (const uint8_t *) src;
while (n--) {
*d++ = ~(*s++);
}
return dst;
}
void UI_PrintStringBuffer(const char *pString, uint8_t *buffer, uint32_t char_width, const uint8_t *font, bool inv) {
const size_t Length = strlen(pString); const size_t Length = strlen(pString);
const unsigned int char_spacing = char_width + 1; const unsigned int char_spacing = char_width + 1;
const uint32_t total_width = Length * char_spacing; // Total width of the text
if (inv) {
// Draw background rectangle from 1 px before the first char to 1 px after the last char
memset(buffer, 0xFF, total_width + 2);
}
for (size_t i = 0; i < Length; i++) { for (size_t i = 0; i < Length; i++) {
const unsigned int index = pString[i] - ' ' - 1; const unsigned int index = pString[i] - ' ' - 1;
if (pString[i] > ' ' && pString[i] < 127) { if (pString[i] > ' ' && pString[i] < 127) {
const uint32_t offset = i * char_spacing + 1; const uint32_t offset = i * char_spacing + 1;
if (inv) {
memcpy_inv(buffer + offset, font + index * char_width, char_width);
} else {
memcpy(buffer + offset, font + index * char_width, char_width); 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)
{
size_t i;
size_t Length = strlen(pString);
if (End > Start)
Start += (((End - Start) - (Length * Width)) + 1) / 2;
for (i = 0; i < Length; i++)
{
const unsigned int ofs = (unsigned int)Start + (i * Width);
if (pString[i] > ' ' && pString[i] < 127)
{
const unsigned int index = pString[i] - ' ' - 1;
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, uint8_t char_width, const uint8_t *font) void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_t Line, uint8_t char_width,
{ const uint8_t *font, bool inv) {
const size_t Length = strlen(pString); const size_t Length = strlen(pString);
const unsigned int char_spacing = char_width + 1; const unsigned int char_spacing = char_width + 1;
@@ -107,79 +107,123 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_
Start += (((End - Start) - Length * char_spacing) + 1) / 2; Start += (((End - Start) - Length * char_spacing) + 1) / 2;
} }
UI_PrintStringBuffer(pString, gFrameBuffer[Line] + Start, char_width, font); UI_PrintStringBuffer(pString, gFrameBuffer[Line] + Start, char_width, font, inv);
}
void itoa(unsigned long num, char *str) {
char buf[20]; // Enough to store any 32-bit or 64-bit unsigned number
int i = 0;
// Handle 0 explicitly
if (num == 0) {
str[i++] = '0';
str[i] = '\0';
return;
}
// Convert number to string in reverse order
while (num > 0) {
buf[i++] = (num % 10) + '0'; // Get last digit and convert to ASCII
num /= 10;
}
// Reverse the string
int j = 0;
while (i > 0) {
str[j++] = buf[--i];
}
str[j] = '\0'; // Null-terminate the string
} }
void UI_PrintStringSmallNormal(const char *pString, uint8_t Start, uint8_t End, uint8_t Line) 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, false);
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) //void UI_PrintString(const char *pString, uint8_t Start, uint8_t End, uint8_t Line /*, uint8_t Width */) {
{ // UI_PrintStringSmallNormal(pString, Start, End, Line);
//// size_t i;
//// size_t Length = strlen(pString);
////
//// if (End > Start)
//// Start += (((End - Start) - (Length * Width)) + 1) / 2;
////
//// for (i = 0; i < Length; i++)
//// {
//// const unsigned int ofs = (unsigned int)Start + (i * Width);
//// if (pString[i] > ' ' && pString[i] < 127)
//// {
//// const unsigned int index = pString[i] - ' ' - 1;
//// memcpy(gFrameBuffer[Line + 0] + ofs, &gFontSmall[index + '0'][0], 7);
//// memcpy(gFrameBuffer[Line + 1] + ofs, &gFontSmall[index + '0'][7], 7);
//// }
//// }
//}
void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line) {
//#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_PrintStringSmall(pString, Start, End, Line, char_width, font);
UI_PrintStringSmall(pString, Start, End, Line, ARRAY_SIZE(gFontSmall[0]), (const uint8_t *) gFontSmall, true);
}
void UI_PrintStringSmallBufferNormal(const char *pString, uint8_t *buffer) {
UI_PrintStringBuffer(pString, buffer, ARRAY_SIZE(gFontSmall[0]), (uint8_t *) gFontSmall, false);
}
void UI_PrintStringSmallBufferBold(const char *pString, uint8_t *buffer) {
#ifdef ENABLE_SMALL_BOLD #ifdef ENABLE_SMALL_BOLD
const uint8_t *font = (uint8_t *)gFontSmallBold; const uint8_t *font = (uint8_t *) gFontSmallBold;
const uint8_t char_width = ARRAY_SIZE(gFontSmallBold[0]); const uint8_t char_width = ARRAY_SIZE(gFontSmallBold[0]);
#else #else
const uint8_t *font = (uint8_t *)gFontSmall; const uint8_t *font = (uint8_t *) gFontSmall;
const uint8_t char_width = ARRAY_SIZE(gFontSmall[0]); const uint8_t char_width = ARRAY_SIZE(gFontSmall[0]);
#endif #endif
UI_PrintStringBuffer(pString, buffer, char_width, font, false);
UI_PrintStringSmall(pString, Start, End, Line, char_width, font);
} }
void UI_PrintStringSmallBufferNormal(const char *pString, uint8_t * buffer) //void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center) {
{ // const unsigned int char_width = 13;
UI_PrintStringBuffer(pString, buffer, ARRAY_SIZE(gFontSmall[0]), (uint8_t *)gFontSmall); // uint8_t *pFb0 = gFrameBuffer[Y] + X;
} // uint8_t *pFb1 = pFb0 + 128;
// bool bCanDisplay = false;
void UI_PrintStringSmallBufferBold(const char *pString, uint8_t * buffer) //
{ // uint8_t len = strlen(string);
#ifdef ENABLE_SMALL_BOLD // for (int i = 0; i < len; i++) {
const uint8_t *font = (uint8_t *)gFontSmallBold; // char c = string[i];
const uint8_t char_width = ARRAY_SIZE(gFontSmallBold[0]); // if (c == '-') c = '9' + 1;
#else // if (bCanDisplay || c != ' ') {
const uint8_t *font = (uint8_t *)gFontSmall; // bCanDisplay = true;
const uint8_t char_width = ARRAY_SIZE(gFontSmall[0]); // if (c >= '0' && c <= '9' + 1) {
#endif // memcpy(pFb0 + 2, gFontSmall[(unsigned char) c], char_width - 3);
UI_PrintStringBuffer(pString, buffer, char_width, font); // memcpy(pFb1 + 2, gFontSmall[(unsigned char) c] + char_width - 3, char_width - 3);
} // } else if (c == '.') {
// *pFb1 = 0x60;
void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center) // pFb0++;
{ // pFb1++;
const unsigned int char_width = 13; // *pFb1 = 0x60;
uint8_t *pFb0 = gFrameBuffer[Y] + X; // pFb0++;
uint8_t *pFb1 = pFb0 + 128; // pFb1++;
bool bCanDisplay = false; // *pFb1 = 0x60;
// pFb0++;
uint8_t len = strlen(string); // pFb1++;
for(int i = 0; i < len; i++) { // continue;
char c = string[i]; // }
if(c=='-') c = '9' + 1; //
if (bCanDisplay || c != ' ') // } else if (center) {
{ // pFb0 -= 6;
bCanDisplay = true; // pFb1 -= 6;
if(c>='0' && c<='9' + 1) { // }
memcpy(pFb0 + 2, gFontBigDigits[c-'0'], char_width - 3); // pFb0 += char_width;
memcpy(pFb1 + 2, gFontBigDigits[c-'0'] + char_width - 3, char_width - 3); // pFb1 += char_width;
} // }
else if(c=='.') { //}
*pFb1 = 0x60; pFb0++; pFb1++;
*pFb1 = 0x60; pFb0++; pFb1++;
*pFb1 = 0x60; pFb0++; pFb1++;
continue;
}
}
else if (center) {
pFb0 -= 6;
pFb1 -= 6;
}
pFb0 += char_width;
pFb1 += char_width;
}
}
/* /*
void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center) void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center)
@@ -221,18 +265,16 @@ 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); const uint8_t pattern = 1 << (y % 8);
if(black) if (black)
buffer[y/8][x] |= pattern; buffer[y / 8][x] |= pattern;
else else
buffer[y/8][x] &= ~pattern; buffer[y / 8][x] &= ~pattern;
} }
static void sort(int16_t *a, int16_t *b) static void sort(int16_t *a, int16_t *b) {
{ if (*a > *b) {
if(*a > *b) {
int16_t t = *a; int16_t t = *a;
*a = *b; *a = *b;
*b = t; *b = t;
@@ -240,9 +282,10 @@ static void sort(int16_t *a, int16_t *b)
} }
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
/*
void UI_DrawLineDottedBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black) /*
{ void UI_DrawLineDottedBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black)
{
if(x2==x1) { if(x2==x1) {
sort(&y1, &y2); sort(&y1, &y2);
for(int16_t i = y1; i <= y2; i+=2) { for(int16_t i = y1; i <= y2; i+=2) {
@@ -259,28 +302,53 @@ static void sort(int16_t *a, int16_t *b)
UI_DrawPixelBuffer(buffer, i, i*a/multipl +b, black); UI_DrawPixelBuffer(buffer, i, i*a/multipl +b, black);
} }
} }
} }
*/ */
void PutPixel(uint8_t x, uint8_t y, bool fill) { void PutPixel(uint8_t x, uint8_t y, bool fill) {
UI_DrawPixelBuffer(gFrameBuffer, x, y, fill); UI_DrawPixelBuffer(gFrameBuffer, x, y, fill);
} }
void PutPixelStatus(uint8_t x, uint8_t y, bool fill) { void PutPixelStatus(uint8_t x, uint8_t y, bool fill) {
UI_DrawPixelBuffer(&gStatusLine, x, y, fill); UI_DrawPixelBuffer(&gStatusLine, x, y, fill);
} }
void GUI_DisplaySmallest(const char *pString, uint8_t x, uint8_t y, //void GUI_DisplaySmallest(const char *pString, uint8_t x, uint8_t y,
// bool statusbar, bool fill) {
// uint8_t c;
// uint8_t pixels;
// const uint8_t *p = (const uint8_t *) pString;
//
// while ((c = *p++) && c != '\0') {
// c -= 0x20;
// for (int i = 0; i < 3; ++i) {
// pixels = gFont3x5[c][i];
// for (int j = 0; j < 6; ++j) {
// if (pixels & 1) {
// if (statusbar)
// PutPixelStatus(x + i, y + j, fill);
// else
// PutPixel(x + i, y + j, fill);
// }
// pixels >>= 1;
// }
// }
// x += 4;
// }
//}
void GUI_DisplaySmallest(const char *pString, uint8_t x, uint8_t y,
bool statusbar, bool fill) { bool statusbar, bool fill) {
uint8_t c; uint8_t c;
uint8_t pixels; uint8_t pixels;
const uint8_t *p = (const uint8_t *)pString; const uint8_t *p = (const uint8_t *) pString;
while ((c = *p++) && c != '\0') { while ((c = *p++) && c != '\0') {
c -= 0x20; c -= 0x20;
for (int i = 0; i < 3; ++i) { for (int i = 0; i < (int) ARRAY_SIZE(gFontSmall[0]); ++i) {
pixels = gFont3x5[c][i]; if (c) {
for (int j = 0; j < 6; ++j) { pixels = gFontSmall[c - 1][i];
for (int j = 0; j < 8; ++j) {
if (pixels & 1) { if (pixels & 1) {
if (statusbar) if (statusbar)
PutPixelStatus(x + i, y + j, fill); PutPixelStatus(x + i, y + j, fill);
@@ -290,42 +358,41 @@ static void sort(int16_t *a, int16_t *b)
pixels >>= 1; pixels >>= 1;
} }
} }
x += 4;
} }
x += ARRAY_SIZE(gFontSmall[0]) + 1;
} }
}
#endif #endif
void UI_DrawLineBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black) void UI_DrawLineBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black) {
{ if (x2 == x1) {
if(x2==x1) {
sort(&y1, &y2); sort(&y1, &y2);
for(int16_t i = y1; i <= y2; i++) { for (int16_t i = y1; i <= y2; i++) {
UI_DrawPixelBuffer(buffer, x1, i, black); UI_DrawPixelBuffer(buffer, x1, i, black);
} }
} else { } else {
const int multipl = 1000; const int multipl = 1000;
int a = (y2-y1)*multipl / (x2-x1); int a = (y2 - y1) * multipl / (x2 - x1);
int b = y1 - a * x1 / multipl; int b = y1 - a * x1 / multipl;
sort(&x1, &x2); sort(&x1, &x2);
for(int i = x1; i<= x2; i++) for (int i = x1; i <= x2; i++) {
{ UI_DrawPixelBuffer(buffer, i, i * a / multipl + b, black);
UI_DrawPixelBuffer(buffer, i, i*a/multipl +b, black);
} }
} }
} }
void UI_DrawRectangleBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black) void UI_DrawRectangleBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black) {
{ UI_DrawLineBuffer(buffer, x1, y1, x1, y2, black);
UI_DrawLineBuffer(buffer, x1,y1, x1,y2, black); UI_DrawLineBuffer(buffer, x1, y1, x2, y1, black);
UI_DrawLineBuffer(buffer, x1,y1, x2,y1, black); UI_DrawLineBuffer(buffer, x2, y1, x2, y2, black);
UI_DrawLineBuffer(buffer, x2,y1, x2,y2, black); UI_DrawLineBuffer(buffer, x1, y2, x2, y2, black);
UI_DrawLineBuffer(buffer, x1,y2, x2,y2, black);
} }
void UI_DisplayPopup(const char *string) void UI_DisplayPopup(const char *string) {
{
UI_DisplayClear(); UI_DisplayClear();
// for(uint8_t i = 1; i < 5; i++) { // for(uint8_t i = 1; i < 5; i++) {
@@ -342,11 +409,17 @@ void UI_DisplayPopup(const char *string)
// UI_DrawPixelBuffer(117, y, true); // UI_DrawPixelBuffer(117, y, true);
// } // }
// DrawRectangle(9,9, 118,38, true); // DrawRectangle(9,9, 118,38, true);
UI_PrintString(string, 9, 118, 2, 8); UI_PrintString(string, 9, 118, 2 /*, 8 */);
UI_PrintStringSmallNormal("Press EXIT", 9, 118, 6); UI_PrintStringSmallNormal("Press EXIT", 9, 118, 6);
} }
void UI_DisplayClear() void UI_ClearLine(uint8_t Line) {
{ if (Line < 8) { // ST7565 has 8 pages (rows of 8 pixels)
memset(gFrameBuffer[Line], 0x00, 128); // Clear all pixels on the line
}
}
void UI_DisplayClear() {
memset(gFrameBuffer, 0, sizeof(gFrameBuffer)); memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
} }

View File

@@ -22,13 +22,14 @@
void UI_GenerateChannelString(char *pString, const uint8_t Channel); void UI_GenerateChannelString(char *pString, const uint8_t Channel);
void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uint8_t ChannelNumber); 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_PrintString(const char *pString, uint8_t Start, uint8_t End, uint8_t Line /*, uint8_t Width */);
#define UI_PrintString UI_PrintStringSmallNormal
void UI_PrintStringSmallNormal(const char *pString, uint8_t Start, uint8_t End, uint8_t Line); 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_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line);
void UI_PrintStringSmallBufferNormal(const char *pString, uint8_t *buffer); void UI_PrintStringSmallBufferNormal(const char *pString, uint8_t *buffer);
void UI_PrintStringSmallBufferBold(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); //void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center);
void UI_ClearLine(uint8_t Line);
void UI_DisplayPopup(const char *string); void UI_DisplayPopup(const char *string);
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);
@@ -40,7 +41,7 @@ void UI_DrawPixelBuffer(uint8_t (*buffer)[128], uint8_t x, uint8_t y, bool black
#endif #endif
void UI_DrawLineBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, 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_DrawRectangleBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black);
void itoa(unsigned long num, char *str);
void UI_DisplayClear(); void UI_DisplayClear();
#endif #endif

View File

@@ -37,11 +37,11 @@ static void Render(void)
memset(gStatusLine, 0, sizeof(gStatusLine)); memset(gStatusLine, 0, sizeof(gStatusLine));
UI_DisplayClear(); UI_DisplayClear();
UI_PrintString("PASSWORD", 0, 127, 1, 10); UI_PrintString("PASSWORD", 0, 127, 1 /*, 10 */);
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
String[i] = (gInputBox[i] == 10) ? '-' : 'x'; String[i] = (gInputBox[i] == 10) ? '-' : 'x';
String[6] = 0; String[6] = 0;
UI_PrintString(String, 0, 127, 3, 12); UI_PrintString(String, 0, 127, 3 /*, 12 */);
ST7565_BlitStatusLine(); ST7565_BlitStatusLine();
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();

804
ui/main.c

File diff suppressed because it is too large Load Diff

View File

@@ -41,6 +41,7 @@ extern const int8_t dBmCorrTable[7];
void UI_DisplayAudioBar(void); void UI_DisplayAudioBar(void);
void UI_MAIN_TimeSlice500ms(void); void UI_MAIN_TimeSlice500ms(void);
void UI_DisplayMain(void); void UI_DisplayMain(void);
bool isMainOnly();
#ifdef ENABLE_AGC_SHOW_DATA #ifdef ENABLE_AGC_SHOW_DATA
void UI_MAIN_PrintAGC(bool force); void UI_MAIN_PrintAGC(bool force);

982
ui/menu.c

File diff suppressed because it is too large Load Diff

View File

@@ -28,8 +28,7 @@ typedef struct {
uint8_t menu_id; uint8_t menu_id;
} t_menu_item; } t_menu_item;
enum enum {
{
MENU_SQL = 0, MENU_SQL = 0,
MENU_STEP, MENU_STEP,
MENU_TXP, MENU_TXP,
@@ -41,13 +40,8 @@ enum
MENU_OFFSET, MENU_OFFSET,
MENU_TOT, MENU_TOT,
MENU_W_N, MENU_W_N,
#ifndef ENABLE_FEAT_F4HWN
MENU_SCR, MENU_SCR,
#endif
MENU_BCL, MENU_BCL,
#ifdef ENABLE_FEAT_F4HWN
MENU_TX_LOCK,
#endif
MENU_MEM_CH, MENU_MEM_CH,
MENU_DEL_CH, MENU_DEL_CH,
MENU_MEM_NAME, MENU_MEM_NAME,
@@ -98,30 +92,21 @@ enum
MENU_D_LIST, MENU_D_LIST,
#endif #endif
MENU_D_LIVE_DEC, MENU_D_LIVE_DEC,
MENU_PONMSG, MENU_FSKSRC,
MENU_FSKMOD,
MENU_ROGER, MENU_ROGER,
MENU_VOL,
MENU_BAT_TXT, MENU_BAT_TXT,
MENU_AM, MENU_AM,
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
MENU_AM_FIX, MENU_AM_FIX,
#endif #endif
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
MENU_NOAA_S, MENU_NOAA_S,
#endif #endif
#endif #endif
MENU_RESET, MENU_RESET,
MENU_F_LOCK, MENU_F_LOCK,
#ifndef ENABLE_FEAT_F4HWN
MENU_200TX,
MENU_350TX,
MENU_500TX,
#endif
MENU_350EN,
#ifndef ENABLE_FEAT_F4HWN
MENU_SCREN,
#endif
#ifdef ENABLE_F_CAL_MENU #ifdef ENABLE_F_CAL_MENU
MENU_F_CALI, // reference xtal calibration MENU_F_CALI, // reference xtal calibration
#endif #endif
@@ -129,28 +114,15 @@ enum
MENU_SET_OFF, MENU_SET_OFF,
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
MENU_SET_PWR,
MENU_SET_PTT, MENU_SET_PTT,
MENU_SET_TOT,
MENU_SET_EOT,
MENU_SET_CTR,
MENU_SET_INV, MENU_SET_INV,
MENU_SET_LCK,
MENU_SET_MET,
MENU_SET_GUI,
MENU_SET_TMR, MENU_SET_TMR,
#ifdef ENABLE_FEAT_F4HWN_NARROWER #ifdef ENABLE_FEAT_F4HWN_VOL
MENU_SET_NFM,
#endif
#ifdef ENABLE_FEAT_F4HWN_VOL
MENU_SET_VOL, MENU_SET_VOL,
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS #ifdef ENABLE_NOAA
MENU_SET_KEY,
#endif
#ifdef ENABLE_NOAA
MENU_NOAA_S, MENU_NOAA_S,
#endif #endif
#endif #endif
MENU_BATCAL, // battery voltage calibration MENU_BATCAL, // battery voltage calibration
MENU_F1SHRT, MENU_F1SHRT,
@@ -161,60 +133,43 @@ enum
MENU_BATTYP MENU_BATTYP
}; };
extern const uint8_t FIRST_HIDDEN_MENU_ITEM;
extern const t_menu_item MenuList[]; extern const t_menu_item MenuList[];
extern const char gSubMenu_TXP[8][6]; extern const char gSubMenu_TXP[7][5];
extern const char gSubMenu_SFT_D[3][4]; extern const char gSubMenu_SFT_D[3][4];
extern const char gSubMenu_W_N[2][7]; extern const char gSubMenu_W_N[3][5];
extern const char gSubMenu_OFF_ON[2][4]; extern const char gSubMenu_OFF_ON[2][4];
extern const char gSubMenu_NA[4]; extern const char gSubMenu_NA[4];
extern const char gSubMenu_TOT[11][7]; extern const char *const gSubMenu_RXMode[4];
extern const char* const gSubMenu_RXMode[4];
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
extern const char gSubMenu_VOICE[3][4]; extern const char gSubMenu_VOICE[3][4];
#endif #endif
extern const char* const gSubMenu_MDF[4]; extern const char *const gSubMenu_MDF[4];
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
extern const char gSubMenu_AL_MOD[2][5]; extern const char gSubMenu_AL_MOD[2][5];
#endif #endif
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
extern const char gSubMenu_D_RSP[4][11]; extern const char gSubMenu_D_RSP[4][11];
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
extern const char gSubMenu_SET_PWR[7][6]; extern const char gSubMenu_SET_PTT[2][4];
extern const char gSubMenu_SET_PTT[2][8];
extern const char gSubMenu_SET_TOT[4][7];
extern const char gSubMenu_SET_LCK[2][9];
extern const char gSubMenu_SET_MET[2][8];
#ifdef ENABLE_FEAT_F4HWN_NARROWER
extern const char gSubMenu_SET_NFM[2][9];
#endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
extern const char gSubMenu_SET_KEY[][9];
#endif
#endif #endif
extern const char* const gSubMenu_PTT_ID[5]; extern const char *const gSubMenu_PTT_ID[5];
#ifdef ENABLE_FEAT_F4HWN extern const char gSubMenu_FSKMod[6][8];
extern const char gSubMenu_PONMSG[5][8];
#else
extern const char gSubMenu_PONMSG[4][8];
#endif
extern const char gSubMenu_ROGER[3][6]; extern const char gSubMenu_ROGER[3][6];
extern const char gSubMenu_RESET[2][4]; extern const char gSubMenu_RESET[2][4];
extern const char* const gSubMenu_F_LOCK[F_LOCK_LEN]; extern const char *const gSubMenu_F_LOCK[F_LOCK_LEN];
extern const char gSubMenu_RX_TX[4][6]; extern const char gSubMenu_RX_TX[4][6];
extern const char gSubMenu_BAT_TXT[3][8]; extern const char gSubMenu_BAT_TXT[3][5];
extern const char gSubMenu_BATTYP[3][9]; extern const char gSubMenu_BATTYP[3][3];
#ifndef ENABLE_FEAT_F4HWN typedef struct {
extern const char gSubMenu_SCRAMBLER[11][7]; char *name;
#endif uint8_t id;
} t_sidefunction;
typedef struct {char* name; uint8_t id;} t_sidefunction;
extern const uint8_t gSubMenu_SIDEFUNCTIONS_size; extern const uint8_t gSubMenu_SIDEFUNCTIONS_size;
extern const t_sidefunction gSubMenu_SIDEFUNCTIONS[]; extern const t_sidefunction gSubMenu_SIDEFUNCTIONS[];
@@ -229,7 +184,9 @@ extern char edit[17];
extern int edit_index; extern int edit_index;
void UI_DisplayMenu(void); void UI_DisplayMenu(void);
int UI_MENU_GetCurrentMenuId(); int UI_MENU_GetCurrentMenuId();
uint8_t UI_MENU_GetMenuIdx(uint8_t id); uint8_t UI_MENU_GetMenuIdx(uint8_t id);
#endif #endif

121
ui/messages.c Normal file
View File

@@ -0,0 +1,121 @@
//
// Created by bruno on 3/30/25.
//
#include "messages.h"
// Convert a 32-bit number to a string (10 digits, zero-padded)
void u32_to_str(uint32_t num, char *str) {
for (int i = 9; i >= 0; i--) {
str[i] = '0' + (num % 10);
num /= 10;
}
str[10] = '\0';
}
// Convert an 8-bit number to a 2-digit string (zero-padded)
void u8_to_str(uint8_t num, char *str) {
str[0] = '0' + (num / 100); // Hundreds place
str[1] = '0' + ((num / 10) % 10); // Tens place
str[2] = '0' + (num % 10); // Ones place
str[3] = '\0';
}
void UI_DisplayMessages(void) {
char String[19];
UI_DisplayClear();
if (gEnteringSMS != SMS_NOT_ENTERING) {
if (gEnteringSMS == SMS_ENTERING_DEST) {
UI_PrintString("SMS dest", 0, 0, 0 /*, 8 */);
u32_to_str(dataPacket.dest, String);
UI_PrintStringSmallNormal(String, 0, 0, 2);
} else if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
UI_PrintString("SMS data", 0, 0, 0 /*, 8 */);
UI_PrintStringSmallNormal((const char *) dataPacket.data, 1, 0, 1);
memset(gFrameBuffer[1] + 2 + (7 * strlen((const char *) dataPacket.data)), gKeyTimeout == 0 ? 0xFF : 0x80,
6);
}
} else {
String[0] = 'M';
String[1] = 'S';
String[2] = 'G';
String[3] = ' ';
for (size_t i = 8; i < 14; i++) {
String[i] = ' ';
}
String[4] = 'F';
String[5] = 'l';
String[6] = 'g';
String[7] = 's';
String[8] = ':';
String[9] = ' ';
u8_to_str(loadedPacket.flags, &String[10]); // Write at offset 7
String[13] = ' ';
if (gActiveMessage == MESSAGES_COUNT) {
String[14] = 'T';
} else {
String[14] = '0' + gActiveMessage;
}
String[15] = '/';
String[16] = '0' + MESSAGES_COUNT;
String[17] = 0;
UI_PrintString(String, 2, 0, 0 /*, 8 */);
String[5] = ' ';
if (gActiveMessage == MESSAGES_COUNT) {
String[0] = 'T';
String[1] = 'o';
String[2] = ':';
String[3] = ' ';
String[4] = ' ';
} else {
String[0] = 'F';
String[1] = 'r';
String[2] = 'o';
String[3] = 'm';
String[4] = ':';
}
u32_to_str(gActiveMessage == MESSAGES_COUNT ? dataPacket.dest : loadedPacket.src,
&String[6]); // Write at offset 6
UI_PrintString(String, 2, 0, 1 /*, 8 */);
String[0] = 'S';
String[1] = 'E';
String[2] = 'Q';
String[3] = ':';
String[4] = ' ';
u8_to_str(loadedPacket.seq, &String[5]); // Write at offset 5
String[8] = ' ';
String[9] = 'T';
String[10] = 'T';
String[11] = 'L';
String[12] = ':';
String[13] = ' ';
String[14] = 0;
u8_to_str(loadedPacket.ttl, &String[14]); // Write at new offset
UI_PrintString(String, 2, 0, 2 /*, 8 */);
char String2[13] = "Data: ";
if (gGotACK) {
String2[6] = 'G';
String2[7] = 'o';
String2[8] = 't';
String2[9] = 'A';
String2[10] = 'C';
String2[11] = 'K';
}
String2[12] = 0;
UI_PrintString(String2, 0, 0, 3 /*, 8 */);
UI_PrintString((const char *) loadedPacket.data, 2, 0, 4 /*, 8 */);
}
ST7565_BlitFullScreen();
}

18
ui/messages.h Normal file
View File

@@ -0,0 +1,18 @@
//
// Created by bruno on 3/30/25.
//
#ifndef BRNQUANFW_MESSAGES_H
#define BRNQUANFW_MESSAGES_H
#include "stdio.h"
#include "helper.h"
#include "../driver/st7565.h"
#include "string.h"
#include "../app/messages.h"
#include "../app/fskmodem.h"
void UI_DisplayMessages(void);
void u8_to_str(uint8_t num, char *str);
void u32_to_str(uint32_t num, char *str);
#endif //BRNQUANFW_MESSAGES_H

View File

@@ -40,7 +40,7 @@ void UI_DisplayScanner(void)
pPrintStr = "FREQ:**.*****"; pPrintStr = "FREQ:**.*****";
} }
UI_PrintString(pPrintStr, 2, 0, 1, 8); UI_PrintString(pPrintStr, 2, 0, 1 /*, 8 */);
if (gScanCssState < SCAN_CSS_STATE_FOUND || !gScanUseCssResult) { if (gScanCssState < SCAN_CSS_STATE_FOUND || !gScanUseCssResult) {
pPrintStr = "CTC:******"; pPrintStr = "CTC:******";
@@ -52,10 +52,10 @@ void UI_DisplayScanner(void)
pPrintStr = String; pPrintStr = String;
} }
UI_PrintString(pPrintStr, 2, 0, 3, 8); UI_PrintString(pPrintStr, 2, 0, 3 /*, 8 */);
memset(String, 0, sizeof(String)); memset(String, 0, sizeof(String));
if (gScannerSaveState == SCAN_SAVE_CHANNEL) { if (gScannerSaveState == SCAN_SAVE_CHANNEL) {
pPrintStr = "SAVE?"; pPrintStr = "SAV?";
Start = 0; Start = 0;
bCentered = 1; bCentered = 1;
} else { } else {
@@ -63,21 +63,21 @@ void UI_DisplayScanner(void)
bCentered = 0; bCentered = 0;
if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) { if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
strcpy(String, "SAVE:"); strcpy(String, "SAV:");
UI_GenerateChannelStringEx(String + 5, gShowChPrefix, gScanChannel); UI_GenerateChannelStringEx(String + 5, gShowChPrefix, gScanChannel);
pPrintStr = String; pPrintStr = String;
} else if (gScanCssState < SCAN_CSS_STATE_FOUND) { } else if (gScanCssState < SCAN_CSS_STATE_FOUND) {
strcpy(String, "SCAN"); strcpy(String, "SCN");
memset(String + 4, '.', (gScanProgressIndicator & 7) + 1); memset(String + 4, '.', (gScanProgressIndicator & 7) + 1);
pPrintStr = String; pPrintStr = String;
} else if (gScanCssState == SCAN_CSS_STATE_FOUND) { } else if (gScanCssState == SCAN_CSS_STATE_FOUND) {
pPrintStr = "SCAN CMP."; pPrintStr = "SCN CMP.";
} else { } else {
pPrintStr = "SCAN FAIL."; pPrintStr = "SCN FAIL.";
} }
} }
UI_PrintString(pPrintStr, Start, bCentered ? 127 : 0, 5, 8); UI_PrintString(pPrintStr, Start, bCentered ? 127 : 0, 5 /*, 8 */);
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
} }

View File

@@ -54,6 +54,17 @@ static void convertTime(uint8_t *line, uint8_t type)
#endif #endif
#endif #endif
//static const char* const FunctionStrings[] = {
// [FUNCTION_FOREGROUND] = "FG",
// [FUNCTION_TRANSMIT] = "TX",
// [FUNCTION_MONITOR] = "MON",
// [FUNCTION_INCOMING] = "INC",
// [FUNCTION_RECEIVE] = "RX",
// [FUNCTION_POWER_SAVE] = "PWS",
// [FUNCTION_BAND_SCOPE] = "BS",
// [FUNCTION_N_ELEM] = "NE"
//};
void UI_DisplayStatus() void UI_DisplayStatus()
{ {
char str[8] = ""; char str[8] = "";
@@ -84,13 +95,6 @@ void UI_DisplayStatus()
unsigned int x1 = x; unsigned int x1 = x;
#ifdef ENABLE_DTMF_CALLING
if (gSetting_KILLED) {
memset(line + x, 0xFF, 10);
x1 = x + 10;
}
else
#endif
{ // SCAN indicator { // SCAN indicator
if (gScanStateDir != SCAN_OFF || SCANNER_IsScanning()) { if (gScanStateDir != SCAN_OFF || SCANNER_IsScanning()) {
if (IS_MR_CHANNEL(gNextMrChannel) && !SCANNER_IsScanning()) { // channel mode if (IS_MR_CHANNEL(gNextMrChannel) && !SCANNER_IsScanning()) { // channel mode
@@ -234,10 +238,6 @@ void UI_DisplayStatus()
size = sizeof(gFontMute); size = sizeof(gFontMute);
} }
#endif #endif
else if (gBackLight) {
src = gFontLight;
size = sizeof(gFontLight);
}
#ifdef ENABLE_FEAT_F4HWN_CHARGING_C #ifdef ENABLE_FEAT_F4HWN_CHARGING_C
else if (gChargingWithTypeC) { else if (gChargingWithTypeC) {
src = BITMAP_USB_C; src = BITMAP_USB_C;
@@ -246,9 +246,7 @@ void UI_DisplayStatus()
#endif #endif
// Perform the memcpy if a source was selected // Perform the memcpy if a source was selected
if (src) {
memcpy(line + x + 1, src, size); memcpy(line + x + 1, src, size);
}
// Battery // Battery
unsigned int x2 = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - 0; unsigned int x2 = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - 0;
@@ -289,5 +287,8 @@ void UI_DisplayStatus()
// ************** // **************
// x2 -= (7 * strlen(str));
// UI_PrintStringSmallBufferNormal(FunctionStrings[gCurrentFunction], line + x2 - 20);
ST7565_BlitStatusLine(); ST7565_BlitStatusLine();
} }

View File

@@ -39,6 +39,7 @@
#include "ui/scanner.h" #include "ui/scanner.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "../misc.h" #include "../misc.h"
#include "messages.h"
GUI_DisplayType_t gScreenToDisplay; GUI_DisplayType_t gScreenToDisplay;
GUI_DisplayType_t gRequestDisplayScreen = DISPLAY_INVALID; GUI_DisplayType_t gRequestDisplayScreen = DISPLAY_INVALID;
@@ -52,6 +53,7 @@ void (*UI_DisplayFunctions[])(void) = {
[DISPLAY_MAIN] = &UI_DisplayMain, [DISPLAY_MAIN] = &UI_DisplayMain,
[DISPLAY_MENU] = &UI_DisplayMenu, [DISPLAY_MENU] = &UI_DisplayMenu,
[DISPLAY_SCANNER] = &UI_DisplayScanner, [DISPLAY_SCANNER] = &UI_DisplayScanner,
[DISPLAY_MESSAGES] = &UI_DisplayMessages,
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
[DISPLAY_FM] = &UI_DisplayFM, [DISPLAY_FM] = &UI_DisplayFM,

View File

@@ -25,6 +25,7 @@ enum GUI_DisplayType_t
DISPLAY_MAIN = 0, DISPLAY_MAIN = 0,
DISPLAY_MENU, DISPLAY_MENU,
DISPLAY_SCANNER, DISPLAY_SCANNER,
DISPLAY_MESSAGES,
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
DISPLAY_FM, DISPLAY_FM,

View File

@@ -28,27 +28,20 @@
#include "version.h" #include "version.h"
#include "bitmaps.h" #include "bitmaps.h"
void UI_DisplayReleaseKeys(void) void UI_DisplayReleaseKeys(void) {
{
memset(gStatusLine, 0, sizeof(gStatusLine)); memset(gStatusLine, 0, sizeof(gStatusLine));
#if defined(ENABLE_FEAT_F4HWN_CTR) || defined(ENABLE_FEAT_F4HWN_INV) #if defined(ENABLE_FEAT_F4HWN_CTR) || defined(ENABLE_FEAT_F4HWN_INV)
ST7565_ContrastAndInv(); ST7565_ContrastAndInv();
#endif #endif
UI_DisplayClear(); UI_DisplayClear();
UI_PrintString("RELEASE", 0, 127, 1, 10); UI_PrintString("RELEASE KEYS", 0, 127, 1 /*, 10 */);
UI_PrintString("ALL KEYS", 0, 127, 3, 10);
ST7565_BlitStatusLine(); // blank status line ST7565_BlitStatusLine(); // blank status line
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
} }
void UI_DisplayWelcome(void) void UI_DisplayWelcome(void) {
{
char WelcomeString0[16];
char WelcomeString1[16];
char WelcomeString2[16];
char WelcomeString3[20];
memset(gStatusLine, 0, sizeof(gStatusLine)); memset(gStatusLine, 0, sizeof(gStatusLine));
@@ -56,147 +49,16 @@ void UI_DisplayWelcome(void)
ST7565_ContrastAndInv(); ST7565_ContrastAndInv();
#endif #endif
UI_DisplayClear(); UI_DisplayClear();
#ifdef ENABLE_FEAT_F4HWN
ST7565_BlitStatusLine(); ST7565_BlitStatusLine();
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_NONE || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_SOUND) {
ST7565_FillScreen(0x00);
#else
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);
#endif
} else {
memset(WelcomeString0, 0, sizeof(WelcomeString0));
memset(WelcomeString1, 0, sizeof(WelcomeString1));
EEPROM_ReadBuffer(0x0EB0, WelcomeString0, 16);
EEPROM_ReadBuffer(0x0EC0, WelcomeString1, 16);
sprintf(WelcomeString2, "%u.%02uV %u%%",
gBatteryVoltageAverage / 100,
gBatteryVoltageAverage % 100,
BATTERY_VoltsToPercent(gBatteryVoltageAverage));
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_VOLTAGE)
{
strcpy(WelcomeString0, "VOLTAGE");
strcpy(WelcomeString1, WelcomeString2);
}
else if(gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_ALL)
{
if(strlen(WelcomeString0) == 0 && strlen(WelcomeString1) == 0)
{
strcpy(WelcomeString0, "WELCOME");
strcpy(WelcomeString1, WelcomeString2);
}
else if(strlen(WelcomeString0) == 0 || strlen(WelcomeString1) == 0)
{
if(strlen(WelcomeString0) == 0)
{
strcpy(WelcomeString0, WelcomeString1);
}
strcpy(WelcomeString1, WelcomeString2);
}
}
else if(gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_MESSAGE)
{
if(strlen(WelcomeString0) == 0)
{
strcpy(WelcomeString0, "WELCOME");
}
if(strlen(WelcomeString1) == 0)
{
strcpy(WelcomeString1, "BIENVENUE");
}
}
UI_PrintString(WelcomeString0, 0, 127, 0, 10);
UI_PrintString(WelcomeString1, 0, 127, 2, 10);
#ifdef ENABLE_FEAT_F4HWN
UI_PrintStringSmallNormal(Version, 0, 128, 4);
UI_DrawLineBuffer(gFrameBuffer, 0, 31, 127, 31, 1); // Be ware, status zone = 8 lines, the rest = 56 ->total 64 UI_DrawLineBuffer(gFrameBuffer, 0, 31, 127, 31, 1); // Be ware, status zone = 8 lines, the rest = 56 ->total 64
for (uint8_t i = 18; i < 110; i++) for (uint8_t i = 18; i < 110; i++) {
{
gFrameBuffer[4][i] ^= 0xFF; gFrameBuffer[4][i] ^= 0xFF;
} }
sprintf(WelcomeString3, "%s Edition", Edition);
UI_PrintStringSmallNormal(WelcomeString3, 0, 127, 6);
/*
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
#if ENABLE_FEAT_F4HWN_RESCUE_OPS > 1
UI_PrintStringSmallNormal(Edition, 18, 0, 6);
if(gEeprom.MENU_LOCK == true) {
memcpy(gFrameBuffer[6] + 103, BITMAP_Ready, sizeof(BITMAP_Ready));
}
else
{
memcpy(gFrameBuffer[6] + 103, BITMAP_NotReady, sizeof(BITMAP_NotReady));
}
#else
UI_PrintStringSmallNormal(Edition, 18, 0, 5);
memcpy(gFrameBuffer[5] + 103, BITMAP_Ready, sizeof(BITMAP_Ready));
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
UI_PrintStringSmallNormal("RescueOps", 18, 0, 6);
if(gEeprom.MENU_LOCK == true) {
memcpy(gFrameBuffer[6] + 103, BITMAP_Ready, sizeof(BITMAP_Ready));
}
else
{
memcpy(gFrameBuffer[6] + 103, BITMAP_NotReady, sizeof(BITMAP_NotReady));
}
#endif
#endif
#else
UI_PrintStringSmallNormal(Edition, 18, 0, 6);
memcpy(gFrameBuffer[6] + 103, BITMAP_Ready, sizeof(BITMAP_Ready));
#endif
*/
/*
#ifdef ENABLE_SPECTRUM
#ifdef ENABLE_FMRADIO
UI_PrintStringSmallNormal(Based, 0, 127, 5);
UI_PrintStringSmallNormal(Credits, 0, 127, 6);
#else
UI_PrintStringSmallNormal("Bandscope ", 0, 127, 5);
memcpy(gFrameBuffer[5] + 95, BITMAP_Ready, sizeof(BITMAP_Ready));
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
UI_PrintStringSmallNormal("RescueOps ", 0, 127, 6);
if(gEeprom.MENU_LOCK == true) {
memcpy(gFrameBuffer[6] + 95, BITMAP_Ready, sizeof(BITMAP_Ready));
}
#else
UI_PrintStringSmallNormal("Broadcast ", 0, 127, 6);
#endif
#endif
#else
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
UI_PrintStringSmallNormal("RescueOps ", 0, 127, 5);
if(gEeprom.MENU_LOCK == true) {
memcpy(gFrameBuffer[5] + 95, BITMAP_Ready, sizeof(BITMAP_Ready));
}
#else
UI_PrintStringSmallNormal("Bandscope ", 0, 127, 5);
#endif
UI_PrintStringSmallNormal("Broadcast ", 0, 127, 6);
memcpy(gFrameBuffer[6] + 95, BITMAP_Ready, sizeof(BITMAP_Ready));
#endif
*/
#else
UI_PrintStringSmallNormal(Version, 0, 127, 6);
#endif
//ST7565_BlitStatusLine(); // blank status line : I think it's useless //ST7565_BlitStatusLine(); // blank status line : I think it's useless
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
}
} }

View File

@@ -7,7 +7,6 @@
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
const char Version[] = AUTHOR_STRING_2 " " VERSION_STRING_2; const char Version[] = AUTHOR_STRING_2 " " VERSION_STRING_2;
const char Edition[] = EDITION_STRING;
#else #else
const char Version[] = AUTHOR_STRING VER; const char Version[] = AUTHOR_STRING VER;
#endif #endif

View File

@@ -21,7 +21,3 @@ extern const char Version[];
extern const char UART_Version[]; extern const char UART_Version[];
#endif #endif
#ifdef ENABLE_FEAT_F4HWN
extern const char Edition[];
#endif