23 Commits
0.23 ... main

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
64 changed files with 2895 additions and 2923 deletions

View File

@@ -9,16 +9,22 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
- 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: Upload firmware artifact - name: Debug files
uses: actions/upload-artifact@v4 run: ls -lah
with:
name: firmware-artifact - name: Debug compiled firmware
path: compiled-firmware/f4hwn.packed.bin run: ls -lah compiled-firmware
- name: Upload firmware artifact
uses: actions/upload-artifact@v4
with:
name: firmware-artifact
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

@@ -11,7 +11,7 @@ ENABLE_NOAA ?= 0
ENABLE_VOICE ?= 0 ENABLE_VOICE ?= 0
ENABLE_VOX ?= 0 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
@@ -38,7 +38,7 @@ ENABLE_AUDIO_BAR ?= 1
ENABLE_COPY_CHAN_TO_VFO ?= 1 ENABLE_COPY_CHAN_TO_VFO ?= 1
ENABLE_REDUCE_LOW_MID_TX_POWER ?= 1 ENABLE_REDUCE_LOW_MID_TX_POWER ?= 1
ENABLE_BYP_RAW_DEMODULATORS ?= 1 ENABLE_BYP_RAW_DEMODULATORS ?= 1
ENABLE_BLMIN_TMP_OFF ?= 1 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
@@ -47,9 +47,8 @@ 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 ?= 0 ENABLE_FEAT_F4HWN_CTR ?= 0
ENABLE_FEAT_F4HWN_CTR ?= 1
ENABLE_FEAT_F4HWN_RESCUE_OPS ?= 0 ENABLE_FEAT_F4HWN_RESCUE_OPS ?= 0
ENABLE_FEAT_F4HWN_VOL ?= 1 ENABLE_FEAT_F4HWN_VOL ?= 1
ENABLE_FEAT_F4HWN_RESET_CHANNEL ?= 0 ENABLE_FEAT_F4HWN_RESET_CHANNEL ?= 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
############################################################# #############################################################
@@ -139,6 +138,7 @@ 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/fskmodem.o
OBJS += app/messages.o
ifeq ($(ENABLE_REGA),1) ifeq ($(ENABLE_REGA),1)
OBJS += app/rega.o OBJS += app/rega.o
endif endif
@@ -177,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
@@ -449,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

@@ -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);

134
app/app.c
View File

@@ -29,6 +29,7 @@
#include "app/chFrScanner.h" #include "app/chFrScanner.h"
#include "app/dtmf.h" #include "app/dtmf.h"
#include "../ui/fmradio.h"
#ifdef ENABLE_FLASHLIGHT #ifdef ENABLE_FLASHLIGHT
#include "app/flashlight.h" #include "app/flashlight.h"
@@ -90,6 +91,7 @@
#include "ui/menu.h" #include "ui/menu.h"
#include "ui/status.h" #include "ui/status.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "messages.h"
static bool flagSaveVfo; static bool flagSaveVfo;
static bool flagSaveSettings; static bool flagSaveSettings;
@@ -102,6 +104,7 @@ void (*ProcessKeysFunctions[])(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
[DISPLAY_MAIN] = &MAIN_ProcessKeys, [DISPLAY_MAIN] = &MAIN_ProcessKeys,
[DISPLAY_MENU] = &MENU_ProcessKeys, [DISPLAY_MENU] = &MENU_ProcessKeys,
[DISPLAY_SCANNER] = &SCANNER_ProcessKeys, [DISPLAY_SCANNER] = &SCANNER_ProcessKeys,
[DISPLAY_MESSAGES] = &MESSAGES_ProcessKeys,
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
[DISPLAY_FM] = &FM_ProcessKeys, [DISPLAY_FM] = &FM_ProcessKeys,
@@ -552,7 +555,7 @@ uint32_t APP_SetFreqByStepAndLimits(VFO_Info_t *pInfo, int8_t direction, uint32_
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
if (Frequency > upper) if (Frequency > upper)
#else #else
if (Frequency >= upper) if (Frequency >= upper)
#endif #endif
Frequency = lower; Frequency = lower;
@@ -758,6 +761,7 @@ static void CheckRadioInterrupts(void) {
} }
#endif #endif
} }
FSK_HANDLE_IRQ(interrupts.__raw);
} }
} }
@@ -849,43 +853,6 @@ void APP_Update(void) {
} }
#endif #endif
#ifdef ENABLE_FEAT_F4HWN
if (gCurrentFunction == FUNCTION_TRANSMIT && (gTxTimeoutReachedAlert || SerialConfigInProgress())) {
if (gSetting_set_tot >= 2) {
if (gEeprom.BACKLIGHT_TIME == 0) {
if (gBlinkCounter == 0 || gBlinkCounter == 250) {
GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
}
} else {
if (gBlinkCounter == 0) {
//BACKLIGHT_TurnOn();
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX);
} else if (gBlinkCounter == 15000) {
//BACKLIGHT_TurnOff();
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MIN);
}
}
}
gBlinkCounter++;
if (
(gSetting_set_tot == 3 && gEeprom.BACKLIGHT_TIME != 0 && gBlinkCounter > 74000) ||
(gSetting_set_tot == 3 && gEeprom.BACKLIGHT_TIME == 0 && gBlinkCounter > 79000) ||
(gSetting_set_tot != 3 && gBlinkCounter > 76000)
) // try to calibrate 10 times
{
gBlinkCounter = 0;
if (gSetting_set_tot == 1 || gSetting_set_tot == 3) {
BK4819_DisableScramble();
BK4819_PlaySingleTone(gTxTimeoutToneAlert, 30, 1, true);
gTxTimeoutToneAlert += 100;
}
}
}
#endif
if (gCurrentFunction == FUNCTION_TRANSMIT && if (gCurrentFunction == FUNCTION_TRANSMIT &&
(gTxTimeoutReached || SerialConfigInProgress())) { // transmitter timed out or must de-key (gTxTimeoutReached || SerialConfigInProgress())) { // transmitter timed out or must de-key
gTxTimeoutReached = false; gTxTimeoutReached = false;
@@ -969,13 +936,13 @@ void APP_Update(void) {
&& gScanStateDir == SCAN_OFF && gScanStateDir == SCAN_OFF
&& !gPttIsPressed && !gPttIsPressed
&& gCurrentFunction != FUNCTION_POWER_SAVE && gCurrentFunction != FUNCTION_POWER_SAVE
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
&& gVoiceWriteIndex == 0 && gVoiceWriteIndex == 0
#endif #endif
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
&& !gFmRadioMode && !gFmRadioMode
#endif #endif
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
&& gDTMF_CallState == DTMF_CALL_STATE_NONE && gDTMF_CallState == DTMF_CALL_STATE_NONE
#endif #endif
) { ) {
@@ -1011,10 +978,10 @@ void APP_Update(void) {
|| gScanStateDir != SCAN_OFF || gScanStateDir != SCAN_OFF
|| gCssBackgroundScan || gCssBackgroundScan
|| gScreenToDisplay != DISPLAY_MAIN || gScreenToDisplay != DISPLAY_MAIN
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
|| gFmRadioMode || gFmRadioMode
#endif #endif
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
|| gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_CallState != DTMF_CALL_STATE_NONE
#endif #endif
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
@@ -1168,10 +1135,9 @@ static void CheckKeys(void) {
gPttDebounceCounter = 0; gPttDebounceCounter = 0;
} }
#else #else
if (gPttIsPressed) if (gPttIsPressed) {
{ if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) ||
if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || SerialConfigInProgress()) SerialConfigInProgress()) { // PTT released or serial comms config in progress
{ // PTT released or serial comms config in progress
if (++gPttDebounceCounter >= 3 || SerialConfigInProgress()) // 30ms if (++gPttDebounceCounter >= 3 || SerialConfigInProgress()) // 30ms
{ // stop transmitting { // stop transmitting
ProcessKey(KEY_PTT, false, false); ProcessKey(KEY_PTT, false, false);
@@ -1179,21 +1145,17 @@ static void CheckKeys(void) {
if (gKeyReading1 != KEY_INVALID) if (gKeyReading1 != KEY_INVALID)
gPttWasReleased = true; gPttWasReleased = true;
} }
} } else
else
gPttDebounceCounter = 0; gPttDebounceCounter = 0;
} } else if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && !SerialConfigInProgress()) { // PTT pressed
else if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && !SerialConfigInProgress())
{ // PTT pressed
if (++gPttDebounceCounter >= 3) // 30ms if (++gPttDebounceCounter >= 3) // 30ms
{ // start transmitting { // start transmitting
boot_counter_10ms = 0; boot_counter_10ms = 0;
gPttDebounceCounter = 0; gPttDebounceCounter = 0;
gPttIsPressed = true; gPttIsPressed = true;
ProcessKey(KEY_PTT, true, false); ProcessKey(KEY_PTT, true, false);
} }
} } else
else
gPttDebounceCounter = 0; gPttDebounceCounter = 0;
#endif #endif
@@ -1309,11 +1271,9 @@ void APP_TimeSlice10ms(void) {
return; return;
#endif #endif
#if !defined(ENABLE_FEAT_F4HWN) || defined(ENABLE_FEAT_F4HWN_RESCUE_OPS)
#ifdef ENABLE_FLASHLIGHT #ifdef ENABLE_FLASHLIGHT
FlashlightTimeSlice(); FlashlightTimeSlice();
#endif #endif
#endif
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
if (gVoxResumeCountdown > 0) if (gVoxResumeCountdown > 0)
@@ -1394,6 +1354,10 @@ void APP_TimeSlice10ms(void) {
SCANNER_TimeSlice10ms(); SCANNER_TimeSlice10ms();
// if (gEnteringSMS == SMS_NOT_ENTERING) {
// MSG_FSKReceiveData();
// }
#ifdef ENABLE_AIRCOPY #ifdef ENABLE_AIRCOPY
if (gScreenToDisplay == DISPLAY_AIRCOPY && gAircopyState == AIRCOPY_TRANSFER && gAirCopyIsSendMode == 1) { if (gScreenToDisplay == DISPLAY_AIRCOPY && gAircopyState == AIRCOPY_TRANSFER && gAirCopyIsSendMode == 1) {
if (!AIRCOPY_SendMessage()) { if (!AIRCOPY_SendMessage()) {
@@ -1485,6 +1449,9 @@ void APP_TimeSlice500ms(void) {
if (gFmRadioMode) // 1of11 if (gFmRadioMode) // 1of11
return; return;
} }
if (gScreenToDisplay == DISPLAY_FM) {
UI_UpdateFMThings(false);
}
#endif #endif
if (gBacklightCountdown_500ms > 0 && !gAskToSave && !gCssBackgroundScan if (gBacklightCountdown_500ms > 0 && !gAskToSave && !gCssBackgroundScan
@@ -1628,7 +1595,7 @@ void APP_TimeSlice500ms(void) {
#endif #endif
if (disp == DISPLAY_INVALID if (disp == DISPLAY_INVALID
#ifdef ENABLE_NO_CODE_SCAN_TIMEOUT #ifdef ENABLE_NO_CODE_SCAN_TIMEOUT
&& !SCANNER_IsScanning() && !SCANNER_IsScanning()
#endif #endif
) { ) {
@@ -1654,6 +1621,8 @@ void APP_TimeSlice500ms(void) {
BATTERY_TimeSlice500ms(); BATTERY_TimeSlice500ms();
SCANNER_TimeSlice500ms(); SCANNER_TimeSlice500ms();
MESSAGES_TimeSlice500ms();
FSKModem_TimeSlice500ms();
UI_MAIN_TimeSlice500ms(); UI_MAIN_TimeSlice500ms();
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
@@ -1814,19 +1783,8 @@ static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
bool lowBatPopup = gLowBattery && !gLowBatteryConfirmed && gScreenToDisplay == DISPLAY_MAIN; bool lowBatPopup = gLowBattery && !gLowBatteryConfirmed && gScreenToDisplay == DISPLAY_MAIN;
#ifdef ENABLE_FEAT_F4HWN // Disable PTT if KEY_LOCK if ((gEeprom.KEY_LOCK || lowBatPopup) &&
bool lck_condition = false; gCurrentFunction != FUNCTION_TRANSMIT) { // keyboard is locked or low battery popup
if (gSetting_set_lck)
lck_condition = (gEeprom.KEY_LOCK || lowBatPopup) && gCurrentFunction != FUNCTION_TRANSMIT;
else
lck_condition = (gEeprom.KEY_LOCK || lowBatPopup) && gCurrentFunction != FUNCTION_TRANSMIT && Key != KEY_PTT;
if (lck_condition)
#else
if ((gEeprom.KEY_LOCK || lowBatPopup) && gCurrentFunction != FUNCTION_TRANSMIT && Key != KEY_PTT)
#endif
{ // keyboard is locked or low battery popup
// close low battery popup // close low battery popup
if (Key == KEY_EXIT && bKeyPressed && lowBatPopup) { if (Key == KEY_EXIT && bKeyPressed && lowBatPopup) {
@@ -1850,8 +1808,7 @@ static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
// KEY_MENU has a special treatment here, because we want to pass hold event to ACTION_Handle // KEY_MENU has a special treatment here, because we want to pass hold event to ACTION_Handle
// but we don't want it to complain when initial press happens // but we don't want it to complain when initial press happens
// we want to react on realese instead // we want to react on realese instead
else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && // pass side buttons else if (!(Key == KEY_MENU && bKeyHeld)) // pass KEY_MENU held
!(Key == KEY_MENU && bKeyHeld)) // pass KEY_MENU held
{ {
if ((!bKeyPressed || bKeyHeld || (Key == KEY_MENU && bKeyPressed)) && if ((!bKeyPressed || bKeyHeld || (Key == KEY_MENU && bKeyPressed)) &&
// prevent released or held, prevent KEY_MENU pressed // prevent released or held, prevent KEY_MENU pressed
@@ -1896,7 +1853,7 @@ static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
#ifdef ENABLE_FEAT_F4HWN // For F + SIDE1 or F + SIDE2 #ifdef ENABLE_FEAT_F4HWN // For F + SIDE1 or F + SIDE2
if (gWasFKeyPressed && (Key == KEY_PTT || Key == KEY_EXIT)) { if (gWasFKeyPressed && (Key == KEY_PTT || Key == KEY_EXIT)) {
#else #else
if (gWasFKeyPressed && (Key == KEY_PTT || Key == KEY_EXIT || Key == KEY_SIDE1 || Key == KEY_SIDE2)) { if (gWasFKeyPressed && (Key == KEY_PTT || Key == KEY_EXIT || Key == KEY_SIDE1 || Key == KEY_SIDE2)) {
#endif #endif
// cancel the F-key // cancel the F-key
gWasFKeyPressed = false; gWasFKeyPressed = false;
@@ -1936,10 +1893,7 @@ static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
BK4819_ExitDTMF_TX(false); BK4819_ExitDTMF_TX(false);
if (gCurrentVfo->SCRAMBLING_TYPE == 0) BK4819_SetScramble(gCurrentVfo->SCRAMBLING_TYPE);
BK4819_DisableScramble();
else
BK4819_EnableScramble(gCurrentVfo->SCRAMBLING_TYPE - 1);
} }
} else { } else {
@@ -1948,7 +1902,7 @@ static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
gEnableSpeaker = true; gEnableSpeaker = true;
} }
BK4819_DisableScramble(); BK4819_SetScramble(0);
if (Code == 0xFE) if (Code == 0xFE)
BK4819_TransmitTone(gEeprom.DTMF_SIDE_TONE, 1750); BK4819_TransmitTone(gEeprom.DTMF_SIDE_TONE, 1750);
@@ -1973,15 +1927,15 @@ static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
#endif #endif
} }
#ifdef ENABLE_FEAT_F4HWN // For F + SIDE1 or F + SIDE2 #ifdef ENABLE_FEAT_F4HWN // For F + SIDE1 or F + SIDE2
else if (gWasFKeyPressed && (Key == KEY_SIDE1 || Key == KEY_SIDE2)) { else if (gWasFKeyPressed && (Key == KEY_SIDE1 || Key == KEY_SIDE2)) {
ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld); ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld);
} else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && gScreenToDisplay != DISPLAY_INVALID) { } else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && gScreenToDisplay != DISPLAY_INVALID) {
ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld);
}
#else
else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && gScreenToDisplay != DISPLAY_INVALID) {
ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld); ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld);
} }
#else
else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && gScreenToDisplay != DISPLAY_INVALID) {
ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld);
}
#endif #endif
else if (!SCANNER_IsScanning() else if (!SCANNER_IsScanning()
#ifdef ENABLE_AIRCOPY #ifdef ENABLE_AIRCOPY

View File

@@ -5,79 +5,60 @@
#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;
}
if (gFlashLightState == FLASHLIGHT_SOS) {
const uint16_t u = 15;
static uint8_t c;
static uint16_t next;
if (gFlashLightBlinkCounter - next > 7 * u) {
c = 0;
next = gFlashLightBlinkCounter + 1;
return; return;
} }
if (gFlashLightState == FLASHLIGHT_SOS) { if (gFlashLightBlinkCounter == next) {
const uint16_t u = 15; if (c == 0) {
static uint8_t c;
static uint16_t next;
if (gFlashLightBlinkCounter - next > 7 * u) {
c = 0;
next = gFlashLightBlinkCounter + 1;
return;
}
if (gFlashLightBlinkCounter == next) {
if (c==0) {
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
} else {
GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
}
if (c >= 18) {
next = gFlashLightBlinkCounter + 7 * u;
c = 0;
} else if(c==7 || c==9 || c==11) {
next = gFlashLightBlinkCounter + 3 * u;
} else {
next = gFlashLightBlinkCounter + u;
}
c++;
}
}
}
void ACTION_FlashLight(void)
{
switch (gFlashLightState) {
case FLASHLIGHT_OFF:
gFlashLightState++;
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
break;
case FLASHLIGHT_ON:
case FLASHLIGHT_BLINK:
gFlashLightState++;
break;
case FLASHLIGHT_SOS:
default:
gFlashLightState = 0;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
} else {
GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
}
if (c >= 18) {
next = gFlashLightBlinkCounter + 7 * u;
c = 0;
} else if (c == 7 || c == 9 || c == 11) {
next = gFlashLightBlinkCounter + 3 * u;
} else {
next = gFlashLightBlinkCounter + u;
}
c++;
} }
} }
#else }
void ACTION_FlashLight(void)
{
static bool gFlashLightState = false;
if(gFlashLightState) void ACTION_FlashLight(void) {
{ switch (gFlashLightState) {
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); case FLASHLIGHT_OFF:
} gFlashLightState++;
else
{
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
} break;
case FLASHLIGHT_ON:
gFlashLightState = (gFlashLightState) ? false : true; case FLASHLIGHT_BLINK:
gFlashLightState++;
break;
case FLASHLIGHT_SOS:
default:
gFlashLightState = 0;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
} }
#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

263
app/fm.c
View File

@@ -31,22 +31,22 @@
#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];
bool gFmRadioMode; bool gFmRadioMode;
uint8_t gFmRadioCountdown_500ms; uint8_t gFmRadioCountdown_500ms;
volatile uint16_t gFmPlayCountdown_10ms; volatile uint16_t gFmPlayCountdown_10ms;
volatile int8_t gFM_ScanState; volatile int8_t gFM_ScanState;
bool gFM_AutoScan; bool gFM_AutoScan;
uint8_t gFM_ChannelPosition; uint8_t gFM_ChannelPosition;
bool gFM_FoundFrequency; bool gFM_FoundFrequency;
bool gFM_AutoScan; 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;
@@ -54,21 +54,19 @@ const uint8_t BUTTON_STATE_HELD = 1 << 1;
const uint8_t BUTTON_EVENT_PRESSED = BUTTON_STATE_PRESSED; const uint8_t BUTTON_EVENT_PRESSED = BUTTON_STATE_PRESSED;
const uint8_t BUTTON_EVENT_HELD = BUTTON_STATE_PRESSED | BUTTON_STATE_HELD; const uint8_t BUTTON_EVENT_HELD = BUTTON_STATE_PRESSED | BUTTON_STATE_HELD;
const uint8_t BUTTON_EVENT_SHORT = 0; const uint8_t BUTTON_EVENT_SHORT = 0;
const uint8_t BUTTON_EVENT_LONG = BUTTON_STATE_HELD; 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) {
@@ -92,17 +89,16 @@ int FM_ConfigureChannelState(void)
gEeprom.FM_IsMrMode = false; gEeprom.FM_IsMrMode = false;
return -1; return -1;
} }
gEeprom.FM_SelectedChannel = Channel; gEeprom.FM_SelectedChannel = Channel;
gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel]; gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel];
} }
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;
AUDIO_AudioPathOff(); AUDIO_AudioPathOff();
@@ -110,17 +106,16 @@ void FM_TurnOff(void)
BK1080_Init0(); BK1080_Init0();
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));
for (unsigned i = 0; i < 5; i++) for (unsigned i = 0; i < 5; i++)
@@ -129,18 +124,18 @@ 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;
gAskToSave = false; gAskToSave = false;
gAskToDelete = false; gAskToDelete = false;
gEeprom.FM_FrequencyPlaying = Frequency; gEeprom.FM_FrequencyPlaying = Frequency;
if (!bFlag) { if (!bFlag) {
@@ -158,12 +153,11 @@ 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) {
gEeprom.FM_IsMrMode = true; gEeprom.FM_IsMrMode = true;
gEeprom.FM_SelectedChannel = 0; gEeprom.FM_SelectedChannel = 0;
} }
@@ -172,35 +166,34 @@ void FM_PlayAndUpdate(void)
SETTINGS_SaveFM(); SETTINGS_SaveFM();
gFmPlayCountdown_10ms = 0; gFmPlayCountdown_10ms = 0;
gScheduleFM = false; gScheduleFM = false;
gAskToSave = false; gAskToSave = false;
AUDIO_AudioPathOn(); AUDIO_AudioPathOn();
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);
if (BK1080_REG_07_GET_SNR(Test2) <= 2) { if (BK1080_REG_07_GET_SNR(Test2) <= 2) {
BK1080_FrequencyDeviation = Deviation; BK1080_FrequencyDeviation = Deviation;
BK1080_BaseFrequency = Frequency; BK1080_BaseFrequency = Frequency;
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;
BK1080_BaseFrequency = Frequency; BK1080_BaseFrequency = Frequency;
return ret; return ret;
} }
@@ -208,17 +201,16 @@ int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit)
//if (Deviation > -281 && Deviation < 280) //if (Deviation > -281 && Deviation < 280)
if (Deviation >= 280 && Deviation <= 3815) { if (Deviation >= 280 && Deviation <= 3815) {
BK1080_FrequencyDeviation = Deviation; BK1080_FrequencyDeviation = Deviation;
BK1080_BaseFrequency = Frequency; BK1080_BaseFrequency = Frequency;
return ret; return ret;
} }
// 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;
return ret; return ret;
} }
@@ -227,10 +219,9 @@ 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;
return ret; return ret;
} }
@@ -238,14 +229,15 @@ int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit)
ret = 0; ret = 0;
BK1080_FrequencyDeviation = Deviation; BK1080_FrequencyDeviation = Deviation;
BK1080_BaseFrequency = Frequency; BK1080_BaseFrequency = Frequency;
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) ||
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; BK1080_GetFreqHiLimit(gEeprom.FM_Band) < Frequency) {
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,19 +325,17 @@ 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);
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gWasFKeyPressed = false; gWasFKeyPressed = false;
gUpdateStatus = true; gUpdateStatus = true;
gRequestDisplayScreen = DISPLAY_FM; gRequestDisplayScreen = DISPLAY_FM;
switch (Key) { switch (Key) {
@@ -361,10 +348,10 @@ static void Key_FUNC(KEY_Code_t Key, uint8_t state)
gRequestSaveFM = true; gRequestSaveFM = true;
break; break;
// case KEY_2: // case KEY_2:
// gEeprom.FM_Space = (gEeprom.FM_Space + 1) % 3; // gEeprom.FM_Space = (gEeprom.FM_Space + 1) % 3;
// gRequestSaveFM = true; // gRequestSaveFM = true;
// break; // break;
case KEY_3: case KEY_3:
gEeprom.FM_IsMrMode = !gEeprom.FM_IsMrMode; gEeprom.FM_IsMrMode = !gEeprom.FM_IsMrMode;
@@ -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,24 +394,23 @@ 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();
return; return;
} }
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,14 +440,13 @@ 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;
gRequestDisplayScreen = DISPLAY_FM; gRequestDisplayScreen = DISPLAY_FM;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gFM_ScanState == FM_SCAN_OFF) { if (gFM_ScanState == FM_SCAN_OFF) {
if (!gEeprom.FM_IsMrMode) { if (!gEeprom.FM_IsMrMode) {
@@ -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,10 +466,9 @@ 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;
return; return;
} }
@@ -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,13 +489,13 @@ 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;
} }
if (gAskToSave) { if (gAskToSave) {
gRequestDisplayScreen = DISPLAY_FM; gRequestDisplayScreen = DISPLAY_FM;
gFM_ChannelPosition = NUMBER_AddWithWraparound(gFM_ChannelPosition, Step, 0, 19); gFM_ChannelPosition = NUMBER_AddWithWraparound(gFM_ChannelPosition, Step, 0, 19);
return; return;
} }
@@ -515,10 +515,9 @@ static void Key_UP_DOWN(uint8_t state, int8_t Step)
if (Channel == 0xFF || gEeprom.FM_SelectedChannel == Channel) if (Channel == 0xFF || gEeprom.FM_SelectedChannel == Channel)
goto Bail; goto Bail;
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))
@@ -526,20 +525,19 @@ static void Key_UP_DOWN(uint8_t state, int8_t Step)
else if (Frequency > BK1080_GetFreqHiLimit(gEeprom.FM_Band)) else if (Frequency > BK1080_GetFreqHiLimit(gEeprom.FM_Band))
Frequency = BK1080_GetFreqLoLimit(gEeprom.FM_Band); Frequency = BK1080_GetFreqLoLimit(gEeprom.FM_Band);
gEeprom.FM_FrequencyPlaying = Frequency; gEeprom.FM_FrequencyPlaying = Frequency;
gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying; gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying;
} }
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,14 +570,14 @@ 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;
gFM_FoundFrequency = true; gFM_FoundFrequency = true;
if (!gEeprom.FM_IsMrMode) if (!gEeprom.FM_IsMrMode)
gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying; gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying;
@@ -609,24 +607,23 @@ 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;
gFM_RestoreCountdown_10ms = 0; gFM_RestoreCountdown_10ms = 0;
BK1080_Init(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); BK1080_Init(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/);
AUDIO_AudioPathOn(); AUDIO_AudioPathOn();
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

@@ -49,21 +49,6 @@
#include "ui/ui.h" #include "ui/ui.h"
#include <stdlib.h> #include <stdlib.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'}
};
static void toggle_chan_scanlist(void) { // toggle the selected channels scanlist setting static void toggle_chan_scanlist(void) { // toggle the selected channels scanlist setting
if (SCANNER_IsScanning()) if (SCANNER_IsScanning())
@@ -180,7 +165,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep) {
#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) {
@@ -270,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;
@@ -360,10 +345,8 @@ void channelMove(uint16_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);
@@ -660,7 +643,7 @@ static void MAIN_Key_MENU(bool bKeyPressed, bool bKeyHeld) {
#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()) { if (FUNCTION_IsRx() || gScanPauseDelayIn_10ms > 9) {
gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] = true; gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] = true;
gVfoConfigureMode = VFO_CONFIGURE; gVfoConfigureMode = VFO_CONFIGURE;
@@ -693,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;
@@ -825,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];
@@ -910,11 +896,6 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
gPttWasReleased = true; gPttWasReleased = true;
} }
void updatePrevChar(KEY_Code_t Key) {
if (Key != prevKey) {
prevKey = Key;
}
}
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
@@ -943,104 +924,6 @@ void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
// Key = KEY_SIDE2; // what's this doing ??? // Key = KEY_SIDE2; // what's this doing ???
// } // }
if (Key == KEY_9 && bKeyHeld) {
if (bKeyPressed) {
if (gEnteringSMS == SMS_NOT_ENTERING) {
gEnteringSMS = SMS_ENTERING_DEST;
updatePrevChar(Key);
return;
}
}
}
if (Key == KEY_MENU) {
if (gEnteringSMS == SMS_ENTERING_DEST) {
if (bKeyPressed) {
memset(dataPacket.data, 0, DataPacketDataSize);
prepareDataPacket();
dataPacket.flags = 126;
gEnteringSMS = SMS_ENTERING_MESSAGE;
}
return;
}
if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
if (bKeyPressed) {
if (strlen((char *) dataPacket.data)) {
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true);
AUDIO_AudioPathOff();
gEnableSpeaker = false;
RADIO_PrepareTX();
if (gCurrentVfo->SCRAMBLING_TYPE > 0)
BK4819_EnableScramble(gCurrentVfo->SCRAMBLING_TYPE - 1);
else
BK4819_DisableScramble();
MSG_FSKSendData();
AUDIO_AudioPathOn();
gEnableSpeaker = true;
BK4819_ExitTxMute();
MSG_EnableRX(true);
gVfoConfigureMode = VFO_CONFIGURE;
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false);
dataPTR = dataPacket.data;
memset(dataPacket.data, 0, DataPacketDataSize);
gEnteringSMS = SMS_NOT_ENTERING;
}
}
return;
}
}
if (Key == KEY_EXIT && 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;
}
}
}
updatePrevChar(Key);
return;
}
if (gEnteringSMS != SMS_NOT_ENTERING && !bKeyHeld) {
if (!dataPTR) {
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) { switch (Key) {
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
case KEY_SIDE1: case KEY_SIDE1:

View File

@@ -121,6 +121,11 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax) {
*pMax = 9; *pMax = 9;
break; break;
case MENU_TOT:
*pMin = 0;
*pMax = 179;
break;
case MENU_STEP: case MENU_STEP:
//*pMin = 0; //*pMin = 0;
*pMax = STEP_N_ELEM - 1; *pMax = STEP_N_ELEM - 1;
@@ -246,12 +251,6 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax) {
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
case MENU_NOAA_S: case MENU_NOAA_S:
#endif #endif
#ifndef ENABLE_FEAT_F4HWN
case MENU_350TX:
case MENU_200TX:
case MENU_500TX:
#endif
case MENU_350EN:
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
case MENU_SET_TMR: case MENU_SET_TMR:
#endif #endif
@@ -265,7 +264,7 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax) {
case MENU_SCR: case MENU_SCR:
//*pMin = 0; //*pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1; *pMax = 65535;
break; break;
case MENU_AUTOLK: case MENU_AUTOLK:
@@ -277,11 +276,6 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax) {
*pMin = 0; *pMin = 0;
break; break;
case MENU_TOT:
//*pMin = 0;
*pMin = 5;
*pMax = 179;
break;
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
case MENU_VOX: case MENU_VOX:
@@ -387,45 +381,15 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax) {
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
case MENU_SET_PWR:
*pMax = ARRAY_SIZE(gSubMenu_SET_PWR) - 1;
break;
case MENU_SET_PTT: case MENU_SET_PTT:
//*pMin = 0; //*pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_SET_PTT) - 1; *pMax = ARRAY_SIZE(gSubMenu_SET_PTT) - 1;
break; break;
case MENU_SET_TOT:
case MENU_SET_EOT:
//*pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_SET_TOT) - 1;
break;
#ifdef ENABLE_FEAT_F4HWN_CTR
case MENU_SET_CTR:
*pMin = 1;
*pMax = 15;
break;
#endif
case MENU_TX_LOCK:
#ifdef ENABLE_FEAT_F4HWN_INV #ifdef ENABLE_FEAT_F4HWN_INV
case MENU_SET_INV: case MENU_SET_INV:
//*pMin = 0; //*pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_OFF_ON) - 1; *pMax = ARRAY_SIZE(gSubMenu_OFF_ON) - 1;
break; break;
#endif
case MENU_SET_LCK:
//*pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_SET_LCK) - 1;
break;
case MENU_SET_MET:
case MENU_SET_GUI:
//*pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_SET_MET) - 1;
break;
#ifdef ENABLE_FEAT_F4HWN_NARROWER
case MENU_SET_NFM:
//*pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_SET_NFM) - 1;
break;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_VOL #ifdef ENABLE_FEAT_F4HWN_VOL
case MENU_SET_VOL: case MENU_SET_VOL:
@@ -433,12 +397,6 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax) {
*pMax = 63; *pMax = 63;
break; break;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
case MENU_SET_KEY:
//*pMin = 0;
*pMax = 4;
break;
#endif
#endif #endif
default: default:
@@ -537,10 +495,7 @@ void MENU_AcceptSetting(void) {
case MENU_SCR: case MENU_SCR:
gTxVfo->SCRAMBLING_TYPE = gSubMenuSelection; gTxVfo->SCRAMBLING_TYPE = gSubMenuSelection;
if (gSubMenuSelection > 0) BK4819_SetScramble(gSubMenuSelection);
BK4819_EnableScramble(gSubMenuSelection - 1);
else
BK4819_DisableScramble();
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
return; return;
@@ -549,6 +504,10 @@ void MENU_AcceptSetting(void) {
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
return; return;
case MENU_TOT:
gEeprom.TX_TIMEOUT_TIMER = gSubMenuSelection;
break;
case MENU_MEM_CH: case MENU_MEM_CH:
gTxVfo->CHANNEL_SAVE = gSubMenuSelection; gTxVfo->CHANNEL_SAVE = gSubMenuSelection;
#if 0 #if 0
@@ -625,10 +584,6 @@ void MENU_AcceptSetting(void) {
gEeprom.BEEP_CONTROL = gSubMenuSelection; gEeprom.BEEP_CONTROL = gSubMenuSelection;
break; break;
case MENU_TOT:
gEeprom.TX_TIMEOUT_TIMER = gSubMenuSelection;
break;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
case MENU_VOICE: case MENU_VOICE:
gEeprom.VOICE_PROMPT = gSubMenuSelection; gEeprom.VOICE_PROMPT = gSubMenuSelection;
@@ -812,40 +767,14 @@ void MENU_AcceptSetting(void) {
SETTINGS_FactoryReset(gSubMenuSelection); SETTINGS_FactoryReset(gSubMenuSelection);
return; return;
#ifndef ENABLE_FEAT_F4HWN
case MENU_350TX:
gSetting_350TX = gSubMenuSelection;
break;
#endif
case MENU_F_LOCK: { case MENU_F_LOCK: {
gSetting_F_LOCK = gSubMenuSelection; gSetting_F_LOCK = gSubMenuSelection;
#ifdef ENABLE_FEAT_F4HWN if(gSetting_F_LOCK == F_LOCK_ALL) {
if (gSetting_F_LOCK == F_LOCK_ALL) {
SETTINGS_ResetTxLock(); SETTINGS_ResetTxLock();
} }
#endif
break; break;
} }
#ifndef ENABLE_FEAT_F4HWN
case MENU_200TX:
gSetting_200TX = gSubMenuSelection;
break;
case MENU_500TX:
gSetting_500TX = gSubMenuSelection;
break;
#endif
case MENU_350EN:
gSetting_350EN = gSubMenuSelection;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
gFlagResetVfos = true;
break;
// case MENU_SCREN:
// gSetting_ScrambleEnable = gSubMenuSelection;
// gFlagReconfigureVfos = true;
// break;
#ifdef ENABLE_F_CAL_MENU #ifdef ENABLE_F_CAL_MENU
case MENU_F_CALI: case MENU_F_CALI:
@@ -890,61 +819,21 @@ void MENU_AcceptSetting(void) {
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
case MENU_SET_PWR:
gSetting_set_pwr = gSubMenuSelection;
gRequestSaveChannel = 1;
break;
case MENU_SET_PTT: case MENU_SET_PTT:
gSetting_set_ptt = gSubMenuSelection; gSetting_set_ptt = gSubMenuSelection;
gSetting_set_ptt_session = gSetting_set_ptt; // Special for action gSetting_set_ptt_session = gSetting_set_ptt; // Special for action
break; break;
case MENU_SET_TOT:
gSetting_set_tot = gSubMenuSelection;
break;
case MENU_SET_EOT:
gSetting_set_eot = gSubMenuSelection;
break;
#ifdef ENABLE_FEAT_F4HWN_CTR
case MENU_SET_CTR:
gSetting_set_ctr = gSubMenuSelection;
break;
#endif
case MENU_SET_INV: case MENU_SET_INV:
gSetting_set_inv = gSubMenuSelection; gSetting_set_inv = gSubMenuSelection;
break; break;
case MENU_SET_LCK:
gSetting_set_lck = gSubMenuSelection;
break;
case MENU_SET_MET:
gSetting_set_met = gSubMenuSelection;
break;
case MENU_SET_GUI:
gSetting_set_gui = gSubMenuSelection;
break;
#ifdef ENABLE_FEAT_F4HWN_NARROWER
case MENU_SET_NFM:
gSetting_set_nfm = gSubMenuSelection;
RADIO_SetTxParameters();
RADIO_SetupRegisters(true);
break;
#endif
#ifdef ENABLE_FEAT_F4HWN_VOL #ifdef ENABLE_FEAT_F4HWN_VOL
case MENU_SET_VOL: case MENU_SET_VOL:
gEeprom.VOLUME_GAIN = gSubMenuSelection; gEeprom.VOLUME_GAIN = gSubMenuSelection;
break; break;
#endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
case MENU_SET_KEY:
gEeprom.SET_KEY = gSubMenuSelection;
break;
#endif #endif
case MENU_SET_TMR: case MENU_SET_TMR:
gSetting_set_tmr = gSubMenuSelection; gSetting_set_tmr = gSubMenuSelection;
break; break;
case MENU_TX_LOCK:
gTxVfo->TX_LOCK = gSubMenuSelection;
gRequestSaveChannel = 1;
return;
#endif #endif
} }
@@ -1051,6 +940,10 @@ void MENU_ShowCurrentSetting(void) {
gSubMenuSelection = gTxVfo->BUSY_CHANNEL_LOCK; gSubMenuSelection = gTxVfo->BUSY_CHANNEL_LOCK;
break; break;
case MENU_TOT:
gSubMenuSelection = gEeprom.TX_TIMEOUT_TIMER;
break;
case MENU_MEM_CH: case MENU_MEM_CH:
#if 0 #if 0
gSubMenuSelection = gEeprom.MrChannel[0]; gSubMenuSelection = gEeprom.MrChannel[0];
@@ -1105,11 +998,6 @@ void MENU_ShowCurrentSetting(void) {
case MENU_BEEP: case MENU_BEEP:
gSubMenuSelection = gEeprom.BEEP_CONTROL; gSubMenuSelection = gEeprom.BEEP_CONTROL;
break; break;
case MENU_TOT:
gSubMenuSelection = gEeprom.TX_TIMEOUT_TIMER;
break;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
case MENU_VOICE: case MENU_VOICE:
gSubMenuSelection = gEeprom.VOICE_PROMPT; gSubMenuSelection = gEeprom.VOICE_PROMPT;
@@ -1268,17 +1156,6 @@ void MENU_ShowCurrentSetting(void) {
gSubMenuSelection = gSetting_F_LOCK; gSubMenuSelection = gSetting_F_LOCK;
break; break;
#ifndef ENABLE_FEAT_F4HWN
case MENU_200TX:
gSubMenuSelection = gSetting_200TX;
break;
case MENU_500TX:
gSubMenuSelection = gSetting_500TX;
break;
#endif
#ifdef ENABLE_F_CAL_MENU #ifdef ENABLE_F_CAL_MENU
case MENU_F_CALI: case MENU_F_CALI:
gSubMenuSelection = gEeprom.BK4819_XTAL_FREQ_LOW; gSubMenuSelection = gEeprom.BK4819_XTAL_FREQ_LOW;
@@ -1323,56 +1200,20 @@ void MENU_ShowCurrentSetting(void) {
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
case MENU_SET_PWR:
gSubMenuSelection = gSetting_set_pwr;
break;
case MENU_SET_PTT: case MENU_SET_PTT:
gSubMenuSelection = gSetting_set_ptt_session; gSubMenuSelection = gSetting_set_ptt_session;
break; break;
case MENU_SET_TOT:
gSubMenuSelection = gSetting_set_tot;
break;
case MENU_SET_EOT:
gSubMenuSelection = gSetting_set_eot;
break;
#ifdef ENABLE_FEAT_F4HWN_CTR
case MENU_SET_CTR:
gSubMenuSelection = gSetting_set_ctr;
break;
#endif
case MENU_SET_INV: case MENU_SET_INV:
gSubMenuSelection = gSetting_set_inv; gSubMenuSelection = gSetting_set_inv;
break; break;
case MENU_SET_LCK:
gSubMenuSelection = gSetting_set_lck;
break;
case MENU_SET_MET:
gSubMenuSelection = gSetting_set_met;
break;
case MENU_SET_GUI:
gSubMenuSelection = gSetting_set_gui;
break;
#ifdef ENABLE_FEAT_F4HWN_NARROWER
case MENU_SET_NFM:
gSubMenuSelection = gSetting_set_nfm;
break;
#endif
#ifdef ENABLE_FEAT_F4HWN_VOL #ifdef ENABLE_FEAT_F4HWN_VOL
case MENU_SET_VOL: case MENU_SET_VOL:
gSubMenuSelection = gEeprom.VOLUME_GAIN; gSubMenuSelection = gEeprom.VOLUME_GAIN;
break; break;
#endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
case MENU_SET_KEY:
gSubMenuSelection = gEeprom.SET_KEY;
break;
#endif #endif
case MENU_SET_TMR: case MENU_SET_TMR:
gSubMenuSelection = gSetting_set_tmr; gSubMenuSelection = gSetting_set_tmr;
break; break;
case MENU_TX_LOCK:
gSubMenuSelection = gTxVfo->TX_LOCK;
break;
#endif #endif
default: default:
@@ -1504,7 +1345,15 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
return; return;
} }
Offset = (Max >= 100) ? 3 : (Max >= 10) ? 2 : 1; Offset = (Max >= 1000000000) ? 10 :
(Max >= 100000000) ? 9 :
(Max >= 10000000) ? 8 :
(Max >= 1000000) ? 7 :
(Max >= 100000) ? 6 :
(Max >= 10000) ? 5 :
(Max >= 1000) ? 4 :
(Max >= 100) ? 3 :
(Max >= 10) ? 2 : 1;
/* /*
switch (gInputBoxIndex) switch (gInputBoxIndex)

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

View File

@@ -794,7 +794,7 @@ static void DrawStatus() {
#else #else
sprintf(String, "%d/%d", settings.dbMin, settings.dbMax); sprintf(String, "%d/%d", settings.dbMin, settings.dbMax);
#endif #endif
GUI_DisplaySmallest(String, 0, 1, true, true); GUI_DisplaySmallest(String, 50, 20, true, true);
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryCheckCounter++ % 4], BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryCheckCounter++ % 4],
&gBatteryCurrent); &gBatteryCurrent);
@@ -856,13 +856,13 @@ static void ShowChannelName(uint32_t f) {
#endif #endif
static void DrawF(uint32_t f) { static void DrawF(uint32_t f) {
sprintf(String, "%u.%05u", f / 100000, f % 100000); sprintf(String, "%lu.%05lu", f / 100000, f % 100000);
UI_PrintStringSmallNormal(String, 8, 127, 0); UI_PrintStringSmallNormal(String, 8, 127, 0);
sprintf(String, "%3s", gModulationStr[settings.modulationType]); sprintf(String, "%3s", gModulationStr[settings.modulationType]);
GUI_DisplaySmallest(String, 116, 1, false, true); GUI_DisplaySmallest(String, 95, 1, false, true);
sprintf(String, "%4sk", bwOptions[settings.listenBw]); sprintf(String, "%4sk", bwOptions[settings.listenBw]);
GUI_DisplaySmallest(String, 108, 7, false, true); GUI_DisplaySmallest(String, 90, 10, false, true);
#ifdef ENABLE_FEAT_F4HWN_SPECTRUM #ifdef ENABLE_FEAT_F4HWN_SPECTRUM
ShowChannelName(f); ShowChannelName(f);
@@ -879,19 +879,19 @@ static void DrawNums() {
} }
if (IsCenterMode()) { if (IsCenterMode()) {
sprintf(String, "%u.%05u \x7F%u.%02uk", currentFreq / 100000, sprintf(String, "%lu.%05lu \x7F%lu.%02luk", currentFreq / 100000,
currentFreq % 100000, settings.frequencyChangeStep / 100, currentFreq % 100000, settings.frequencyChangeStep / 100,
settings.frequencyChangeStep % 100); settings.frequencyChangeStep % 100);
GUI_DisplaySmallest(String, 36, 49, false, true); GUI_DisplaySmallest(String, 36, 39, false, true);
} else { } else {
sprintf(String, "%u.%05u", GetFStart() / 100000, GetFStart() % 100000); sprintf(String, "%lu.%05lu", GetFStart() / 100000, GetFStart() % 100000);
GUI_DisplaySmallest(String, 0, 49, false, true); GUI_DisplaySmallest(String, 0, 49, false, true);
sprintf(String, "\x7F%u.%02uk", settings.frequencyChangeStep / 100, sprintf(String, "\x7F%lu.%02luk", settings.frequencyChangeStep / 100,
settings.frequencyChangeStep % 100); settings.frequencyChangeStep % 100);
GUI_DisplaySmallest(String, 48, 49, false, true); GUI_DisplaySmallest(String, 48, 10, false, true);
sprintf(String, "%u.%05u", GetFEnd() / 100000, GetFEnd() % 100000); sprintf(String, "%lu.%05lu", GetFEnd() / 100000, GetFEnd() % 100000);
GUI_DisplaySmallest(String, 93, 49, false, true); GUI_DisplaySmallest(String, 93, 49, false, true);
} }
} }
@@ -1139,7 +1139,7 @@ void OnKeyDownStill(KEY_Code_t key) {
} }
} }
static void RenderFreqInput() { UI_PrintString(freqInputString, 2, 127, 0, 8); } static void RenderFreqInput() { UI_PrintString(freqInputString, 2, 127, 0 /*, 8 */); }
static void RenderStatus() { static void RenderStatus() {
memset(gStatusLine, 0, sizeof(gStatusLine)); memset(gStatusLine, 0, sizeof(gStatusLine));
@@ -1193,8 +1193,8 @@ static void RenderStill() {
gFrameBuffer[2][METER_PAD_LEFT + x] = 0b11111111; gFrameBuffer[2][METER_PAD_LEFT + x] = 0b11111111;
} }
const uint8_t PAD_LEFT = 4; const uint8_t PAD_LEFT = 0;
const uint8_t CELL_WIDTH = 30; const uint8_t CELL_WIDTH = 28;
uint8_t offset = PAD_LEFT; uint8_t offset = PAD_LEFT;
uint8_t row = 4; uint8_t row = 4;

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

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/"
}
basic() {
echo "Basic 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=Basic \
TARGET=f4hwn.basic \
&& cp f4hwn.basic* 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
;;
basic)
basic
;;
rescueops)
rescueops
;;
all)
bandscope
broadcast
rescueops
basic
;;
*)
echo "Usage: $0 {custom|bandscope|broadcast|basic|standard|all}"
exit 1
;;
esac

View File

@@ -66,12 +66,6 @@ void BACKLIGHT_InitHardware()
0; 0;
} }
static void BACKLIGHT_Sound(void)
{
gK5startup = false;
}
void BACKLIGHT_TurnOn(void) void BACKLIGHT_TurnOn(void)
{ {
#ifdef ENABLE_FEAT_F4HWN_SLEEP #ifdef ENABLE_FEAT_F4HWN_SLEEP
@@ -84,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);
#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); BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX);
}
#else
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX);
#endif
switch (gEeprom.BACKLIGHT_TIME) { switch (gEeprom.BACKLIGHT_TIME) {
default: default:

View File

@@ -18,15 +18,43 @@
#define BK1080_REGS_H #define BK1080_REGS_H
enum BK1080_Register_t { enum BK1080_Register_t {
BK1080_REG_00 = 0x00U, BK1080_REG_00 = 0x00U,
BK1080_REG_02_POWER_CONFIGURATION = 0x02U, BK1080_REG_01_CHIP_ID = 0x01U,
BK1080_REG_03_CHANNEL = 0x03U, BK1080_REG_02_POWER_CONFIGURATION = 0x02U,
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_25_INTERNAL = 0x19U, 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_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

@@ -42,12 +42,18 @@ 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){ void BK4819_FskEnableTx(void){
const uint16_t fsk_reg59 = BK4819_ReadRegister(BK4819_REG_59); const uint16_t fsk_reg59 = BK4819_ReadRegister(BK4819_REG_59);
BK4819_WriteRegister(BK4819_REG_59, (1u << 11) | fsk_reg59); BK4819_WriteRegister(BK4819_REG_59, (1u << 11) | fsk_reg59);
@@ -854,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);
@@ -100,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

@@ -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,35 +48,32 @@ 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
| DMA_CH_MOD_MS_SIZE_BITS_8BIT | DMA_CH_MOD_MS_SIZE_BITS_8BIT
| DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS1 | DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS1
// 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
| DMA_INTST_CH1_TC_INTST_BITS_SET | DMA_INTST_CH1_TC_INTST_BITS_SET
| DMA_INTST_CH2_TC_INTST_BITS_SET | DMA_INTST_CH2_TC_INTST_BITS_SET
| DMA_INTST_CH3_TC_INTST_BITS_SET | DMA_INTST_CH3_TC_INTST_BITS_SET
| 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

@@ -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,185 +122,183 @@
// 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;
if (character) { (void) maxlen;
_putchar(character); if (character) {
} _putchar(character);
}
} }
// 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,
const size_t start_idx = idx; unsigned int flags) {
const size_t start_idx = idx;
// pad spaces up to given width // pad spaces up to given width
if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) {
for (size_t i = len; i < width; i++) { for (size_t i = len; i < width; i++) {
out(' ', buffer, idx++, maxlen); out(' ', buffer, idx++, maxlen);
}
} }
}
// reverse string // reverse string
while (len) { while (len) {
out(buf[--len], buffer, idx++, maxlen); out(buf[--len], buffer, idx++, maxlen);
}
// append pad spaces up to given width
if (flags & FLAGS_LEFT) {
while (idx - start_idx < width) {
out(' ', buffer, idx++, maxlen);
} }
}
return idx; // append pad spaces up to given width
if (flags & FLAGS_LEFT) {
while (idx - start_idx < width) {
out(' ', buffer, idx++, maxlen);
}
}
return idx;
} }
// 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,
// pad leading zeros unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) {
if (!(flags & FLAGS_LEFT)) { // pad leading zeros
if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { if (!(flags & FLAGS_LEFT)) {
width--; if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
} }
while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
}
// handle hash // handle hash
if (flags & FLAGS_HASH) { if (flags & FLAGS_HASH) {
if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) { if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) {
len--; len--;
if (len && (base == 16U)) { if (len && (base == 16U)) {
len--; len--;
} }
} }
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)) {
} buf[len++] = 'b';
else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { }
buf[len++] = 'b'; if (len < PRINTF_NTOA_BUFFER_SIZE) {
buf[len++] = '0';
}
} }
if (len < PRINTF_NTOA_BUFFER_SIZE) { if (len < PRINTF_NTOA_BUFFER_SIZE) {
buf[len++] = '0'; if (negative) {
buf[len++] = '-';
} else if (flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists
} else if (flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
} }
}
if (len < PRINTF_NTOA_BUFFER_SIZE) { return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
if (negative) {
buf[len++] = '-';
}
else if (flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists
}
else if (flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
}
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
} }
// 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;
// no hash for 0 values // no hash for 0 values
if (!value) { if (!value) {
flags &= ~FLAGS_HASH; flags &= ~FLAGS_HASH;
} }
// 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,341 +575,353 @@ 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;
if (!buffer) { if (!buffer) {
// use null output function // use null output function
out = _out_null; out = _out_null;
}
while (*format)
{
// format specifier? %[flags][width][.precision][length]
if (*format != '%') {
// no
out(*format, buffer, idx++, maxlen);
format++;
continue;
}
else {
// yes, evaluate it
format++;
} }
// evaluate flags while (*format) {
flags = 0U; // format specifier? %[flags][width][.precision][length]
do { if (*format != '%') {
switch (*format) { // no
case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break; out(*format, buffer, idx++, maxlen);
case '-': flags |= FLAGS_LEFT; format++; n = 1U; break; format++;
case '+': flags |= FLAGS_PLUS; format++; n = 1U; break; continue;
case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break; } else {
case '#': flags |= FLAGS_HASH; format++; n = 1U; break; // yes, evaluate it
default : n = 0U; break; format++;
}
} while (n);
// evaluate width field
width = 0U;
if (_is_digit(*format)) {
width = _atoi(&format);
}
else if (*format == '*') {
const int w = va_arg(va, int);
if (w < 0) {
flags |= FLAGS_LEFT; // reverse padding
width = (unsigned int)-w;
}
else {
width = (unsigned int)w;
}
format++;
}
// evaluate precision field
precision = 0U;
if (*format == '.') {
flags |= FLAGS_PRECISION;
format++;
if (_is_digit(*format)) {
precision = _atoi(&format);
}
else if (*format == '*') {
const int prec = (int)va_arg(va, int);
precision = prec > 0 ? (unsigned int)prec : 0U;
format++;
}
}
// evaluate length field
switch (*format) {
case 'l' :
flags |= FLAGS_LONG;
format++;
if (*format == 'l') {
flags |= FLAGS_LONG_LONG;
format++;
} }
break;
case 'h' : // evaluate flags
flags |= FLAGS_SHORT; flags = 0U;
format++; do {
if (*format == 'h') { switch (*format) {
flags |= FLAGS_CHAR; case '0':
format++; flags |= FLAGS_ZEROPAD;
format++;
n = 1U;
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);
// evaluate width field
width = 0U;
if (_is_digit(*format)) {
width = _atoi(&format);
} else if (*format == '*') {
const int w = va_arg(va, int);
if (w < 0) {
flags |= FLAGS_LEFT; // reverse padding
width = (unsigned int) -w;
} else {
width = (unsigned int) w;
}
format++;
} }
break;
// evaluate precision field
precision = 0U;
if (*format == '.') {
flags |= FLAGS_PRECISION;
format++;
if (_is_digit(*format)) {
precision = _atoi(&format);
} else if (*format == '*') {
const int prec = (int) va_arg(va, int);
precision = prec > 0 ? (unsigned int) prec : 0U;
format++;
}
}
// evaluate length field
switch (*format) {
case 'l' :
flags |= FLAGS_LONG;
format++;
if (*format == 'l') {
flags |= FLAGS_LONG_LONG;
format++;
}
break;
case 'h' :
flags |= FLAGS_SHORT;
format++;
if (*format == 'h') {
flags |= FLAGS_CHAR;
format++;
}
break;
#if defined(PRINTF_SUPPORT_PTRDIFF_T) #if defined(PRINTF_SUPPORT_PTRDIFF_T)
case 't' : case 't' :
flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++; format++;
break; break;
#endif #endif
case 'j' : case 'j' :
flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++; format++;
break; break;
case 'z' : case 'z' :
flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++; format++;
break; break;
default : default :
break; break;
}
// evaluate specifier
switch (*format) {
case 'd' :
case 'i' :
case 'u' :
case 'x' :
case 'X' :
case 'o' :
case 'b' : {
// set the base
unsigned int base;
if (*format == 'x' || *format == 'X') {
base = 16U;
}
else if (*format == 'o') {
base = 8U;
}
else if (*format == 'b') {
base = 2U;
}
else {
base = 10U;
flags &= ~FLAGS_HASH; // no hash for dec format
}
// uppercase
if (*format == 'X') {
flags |= FLAGS_UPPERCASE;
} }
// no plus or space flag for u, x, X, o, b // evaluate specifier
if ((*format != 'i') && (*format != 'd')) { switch (*format) {
flags &= ~(FLAGS_PLUS | FLAGS_SPACE); case 'd' :
} case 'i' :
case 'u' :
case 'x' :
case 'X' :
case 'o' :
case 'b' : {
// set the base
unsigned int base;
if (*format == 'x' || *format == 'X') {
base = 16U;
} else if (*format == 'o') {
base = 8U;
} else if (*format == 'b') {
base = 2U;
} else {
base = 10U;
flags &= ~FLAGS_HASH; // no hash for dec format
}
// uppercase
if (*format == 'X') {
flags |= FLAGS_UPPERCASE;
}
// ignore '0' flag when precision is given // no plus or space flag for u, x, X, o, b
if (flags & FLAGS_PRECISION) { if ((*format != 'i') && (*format != 'd')) {
flags &= ~FLAGS_ZEROPAD; flags &= ~(FLAGS_PLUS | FLAGS_SPACE);
} }
// convert the integer // ignore '0' flag when precision is given
if ((*format == 'i') || (*format == 'd')) { if (flags & FLAGS_PRECISION) {
// signed flags &= ~FLAGS_ZEROPAD;
if (flags & FLAGS_LONG_LONG) { }
// convert the integer
if ((*format == 'i') || (*format == 'd')) {
// signed
if (flags & FLAGS_LONG_LONG) {
#if defined(PRINTF_SUPPORT_LONG_LONG) #if defined(PRINTF_SUPPORT_LONG_LONG)
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),
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); value < 0, base, precision, width, flags);
} } else {
else { const int value = (flags & FLAGS_CHAR) ? (char) va_arg(va, int) : (flags & FLAGS_SHORT)
const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); ? (short 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); : 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 } else {
if (flags & FLAGS_LONG_LONG) { // unsigned
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)
idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); ? (unsigned short int) va_arg(va,
} unsigned int)
} : va_arg(va, unsigned int);
format++; idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags);
break; }
} }
format++;
break;
}
#if defined(PRINTF_SUPPORT_FLOAT) #if defined(PRINTF_SUPPORT_FLOAT)
case 'f' : case 'f' :
case 'F' : case 'F' :
if (*format == 'F') flags |= FLAGS_UPPERCASE; if (*format == 'F') flags |= FLAGS_UPPERCASE;
idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++; format++;
break; break;
#if defined(PRINTF_SUPPORT_EXPONENTIAL) #if defined(PRINTF_SUPPORT_EXPONENTIAL)
case 'e': case 'e':
case 'E': case 'E':
case 'g': case 'g':
case 'G': case 'G':
if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP; if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP;
if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE; if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE;
idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++; format++;
break; break;
#endif // PRINTF_SUPPORT_EXPONENTIAL #endif // PRINTF_SUPPORT_EXPONENTIAL
#endif // PRINTF_SUPPORT_FLOAT #endif // PRINTF_SUPPORT_FLOAT
case 'c' : { case 'c' : {
unsigned int l = 1U; unsigned int l = 1U;
// pre padding // pre padding
if (!(flags & FLAGS_LEFT)) { if (!(flags & FLAGS_LEFT)) {
while (l++ < width) { while (l++ < width) {
out(' ', buffer, idx++, maxlen); out(' ', buffer, idx++, maxlen);
} }
} }
// 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) {
out(' ', buffer, idx++, maxlen); out(' ', buffer, idx++, maxlen);
} }
} }
format++; format++;
break; break;
} }
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);
} }
if (!(flags & FLAGS_LEFT)) { if (!(flags & FLAGS_LEFT)) {
while (l++ < width) { while (l++ < width) {
out(' ', buffer, idx++, maxlen); out(' ', buffer, idx++, maxlen);
} }
} }
// string output // string output
while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) {
out(*(p++), buffer, idx++, maxlen); out(*(p++), buffer, idx++, maxlen);
} }
// post padding // post padding
if (flags & FLAGS_LEFT) { if (flags & FLAGS_LEFT) {
while (l++ < width) { while (l++ < width) {
out(' ', buffer, idx++, maxlen); out(' ', buffer, idx++, maxlen);
} }
} }
format++; format++;
break; break;
} }
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);
if (is_ll) { if (is_ll) {
idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags);
} }
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
format++; format++;
break; break;
} }
case '%' : case '%' :
out('%', buffer, idx++, maxlen); out('%', buffer, idx++, maxlen);
format++; format++;
break; break;
default : default :
out(*format, buffer, idx++, maxlen); out(*format, buffer, idx++, maxlen);
format++; format++;
break; break;
}
} }
}
// 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); va_end(va);
va_end(va); return ret;
return ret;
} }
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;
} }

View File

@@ -24,90 +24,90 @@
#define BX4819_band1_lower 1800000 #define BX4819_band1_lower 1800000
#define BX4819_band2_upper 130000000 #define BX4819_band2_upper 130000000
const freq_band_table_t BX4819_band1 = {BX4819_band1_lower, 63000000}; 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,
16242500, 16242500,
16245000, 16245000,
16250000, 16250000,
16252500, 16252500,
16152500, 16152500,
16177500, 16177500,
16327500 16327500
}; };
#endif #endif
// this order of steps has to be preserved for backwards compatibility with other/stock firmwares // this order of steps has to be preserved for backwards compatibility with other/stock firmwares
const uint16_t gStepFrequencyTable[] = { const uint16_t gStepFrequencyTable[] = {
// standard steps // standard steps
[STEP_2_5kHz] = 250, [STEP_2_5kHz] = 250,
[STEP_5kHz] = 500, [STEP_5kHz] = 500,
[STEP_6_25kHz] = 625, [STEP_6_25kHz] = 625,
[STEP_10kHz] = 1000, [STEP_10kHz] = 1000,
[STEP_12_5kHz] = 1250, [STEP_12_5kHz] = 1250,
[STEP_25kHz] = 2500, [STEP_25kHz] = 2500,
[STEP_8_33kHz] = 833, [STEP_8_33kHz] = 833,
// custom steps // custom steps
[STEP_0_01kHz] = 1, [STEP_0_01kHz] = 1,
[STEP_0_05kHz] = 5, [STEP_0_05kHz] = 5,
[STEP_0_1kHz] = 10, [STEP_0_1kHz] = 10,
[STEP_0_25kHz] = 25, [STEP_0_25kHz] = 25,
[STEP_0_5kHz] = 50, [STEP_0_5kHz] = 50,
[STEP_1kHz] = 100, [STEP_1kHz] = 100,
[STEP_1_25kHz] = 125, [STEP_1_25kHz] = 125,
[STEP_9kHz] = 900, [STEP_9kHz] = 900,
[STEP_15kHz] = 1500, [STEP_15kHz] = 1500,
[STEP_20kHz] = 2000, [STEP_20kHz] = 2000,
[STEP_30kHz] = 3000, [STEP_30kHz] = 3000,
[STEP_50kHz] = 5000, [STEP_50kHz] = 5000,
[STEP_100kHz] = 10000, [STEP_100kHz] = 10000,
[STEP_125kHz] = 12500, [STEP_125kHz] = 12500,
[STEP_200kHz] = 20000, [STEP_200kHz] = 20000,
[STEP_250kHz] = 25000, [STEP_250kHz] = 25000,
[STEP_500kHz] = 50000 [STEP_500kHz] = 50000
}; };
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_125kHz, STEP_200kHz, STEP_250kHz, STEP_500kHz STEP_8_33kHz, STEP_9kHz, STEP_10kHz, STEP_12_5kHz, STEP_15kHz, STEP_20kHz, STEP_25kHz, STEP_30kHz, STEP_50kHz,
STEP_100kHz,
STEP_125kHz, STEP_200kHz, STEP_250kHz, STEP_500kHz
}; };
STEP_Setting_t FREQUENCY_GetStepIdxFromSortedIdx(uint8_t sortedIdx) 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,30 +167,22 @@ 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) return 0;
#endif if (Frequency >= frequencyBandTable[BAND5_350MHz].lower &&
return 0; Frequency < frequencyBandTable[BAND5_350MHz].upper)
if (Frequency >= frequencyBandTable[BAND5_350MHz].lower && Frequency < frequencyBandTable[BAND5_350MHz].upper) return 0;
#ifndef ENABLE_FEAT_F4HWN if (Frequency >= frequencyBandTable[BAND6_400MHz].lower &&
if (gSetting_350TX && gSetting_350EN) Frequency < frequencyBandTable[BAND6_400MHz].upper)
#else
if (gSetting_350EN)
#endif
return 0;
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 return 0;
if (gSetting_500TX)
#endif
return 0;
break; break;
// case F_LOCK_FCC: // case F_LOCK_FCC:
@@ -231,25 +221,25 @@ int32_t TX_freq_check(const uint32_t Frequency)
// break; // break;
#ifdef ENABLE_FEAT_F4HWN_PMR #ifdef ENABLE_FEAT_F4HWN_PMR
case F_LOCK_PMR: case F_LOCK_PMR:
if (Frequency >= 44600625 && Frequency <= 44619375) if (Frequency >= 44600625 && Frequency <= 44619375)
return 0; return 0;
break; break;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_GMRS_FRS_MURS #ifdef ENABLE_FEAT_F4HWN_GMRS_FRS_MURS
case F_LOCK_GMRS_FRS_MURS: case F_LOCK_GMRS_FRS_MURS:
// https://forums.radioreference.com/threads/the-great-unofficial-radioreference-frs-gmrs-murs-fact-sheet.275370/ // https://forums.radioreference.com/threads/the-great-unofficial-radioreference-frs-gmrs-murs-fact-sheet.275370/
if ((Frequency >= 46255000 && Frequency <= 46272500) || if ((Frequency >= 46255000 && Frequency <= 46272500) ||
(Frequency >= 46755000 && Frequency <= 46772500)) // FRS/GMRS (Frequency >= 46755000 && Frequency <= 46772500)) // FRS/GMRS
return 0; return 0;
if (Frequency == 15182000 || if (Frequency == 15182000 ||
Frequency == 15188000 || Frequency == 15188000 ||
Frequency == 15194000 || Frequency == 15194000 ||
Frequency == 15457000 || Frequency == 15457000 ||
Frequency == 15460000) // MURS Frequency == 15460000) // MURS
return 0; return 0;
break; break;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_CA #ifdef ENABLE_FEAT_F4HWN_CA
@@ -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

@@ -48,6 +48,7 @@
#include "ui/status.h" #include "ui/status.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "app/app.h" #include "app/app.h"
#include "driver/systick.h"
FUNCTION_Type_t gCurrentFunction; FUNCTION_Type_t gCurrentFunction;
@@ -204,6 +205,7 @@ 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);
@@ -211,7 +213,7 @@ void FUNCTION_Transmit() {
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(false, 1750); BK4819_TransmitTone(gEeprom.DTMF_SIDE_TONE, 1750);
gAlarmState = ALARM_STATE_OFF; gAlarmState = ALARM_STATE_OFF;
} }
#endif #endif
@@ -234,10 +236,6 @@ void FUNCTION_Transmit() {
#endif #endif
if (gCurrentVfo->SCRAMBLING_TYPE > 0)
BK4819_EnableScramble(gCurrentVfo->SCRAMBLING_TYPE - 1);
else
BK4819_DisableScramble();
if (gSetting_backlight_on_tx_rx & BACKLIGHT_ON_TR_TX) { if (gSetting_backlight_on_tx_rx & BACKLIGHT_ON_TR_TX) {
BACKLIGHT_TurnOn(); BACKLIGHT_TurnOn();

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,98 +32,77 @@
#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; if (Keys[0] == KEY_SIDE2)
return BOOT_MODE_AIRCOPY;
#ifdef ENABLE_AIRCOPY #endif
if (Keys[0] == KEY_SIDE2)
return BOOT_MODE_AIRCOPY;
#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
if (Mode == BOOT_MODE_AIRCOPY)
{ {
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE gEeprom.DUAL_WATCH = DUAL_WATCH_OFF;
gEeprom.BATTERY_SAVE = 0;
#ifdef ENABLE_VOX
gEeprom.VOX_SWITCH = false;
#endif
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gEeprom.AUTO_KEYPAD_LOCK = false;
gEeprom.KEY_1_SHORT_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_1_LONG_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_2_SHORT_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_2_LONG_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_M_LONG_PRESS_ACTION = ACTION_OPT_NONE;
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_LAST - 1, 43400000); // LPD
gRxVfo->CHANNEL_BANDWIDTH = BANDWIDTH_NARROW;
gRxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW1;
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
gCurrentVfo = gRxVfo;
RADIO_SetupRegisters(true);
BK4819_SetupAircopy();
BK4819_ResetFSK();
gAircopyState = AIRCOPY_READY;
gEeprom.BACKLIGHT_TIME = 61;
gEeprom.KEY_LOCK = 0;
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
gEeprom.CURRENT_STATE = 0; // Don't resume is active... gEeprom.CURRENT_STATE = 0; // Don't resume is active...
#endif #endif
GUI_SelectNextDisplay(DISPLAY_MENU);
} GUI_SelectNextDisplay(DISPLAY_AIRCOPY);
#ifdef ENABLE_AIRCOPY
else
if (Mode == BOOT_MODE_AIRCOPY)
{
gEeprom.DUAL_WATCH = DUAL_WATCH_OFF;
gEeprom.BATTERY_SAVE = 0;
#ifdef ENABLE_VOX
gEeprom.VOX_SWITCH = false;
#endif
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gEeprom.AUTO_KEYPAD_LOCK = false;
gEeprom.KEY_1_SHORT_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_1_LONG_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_2_SHORT_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_2_LONG_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_M_LONG_PRESS_ACTION = ACTION_OPT_NONE;
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_LAST - 1, 43400000); // LPD
gRxVfo->CHANNEL_BANDWIDTH = BANDWIDTH_NARROW;
gRxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW1;
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
gCurrentVfo = gRxVfo;
RADIO_SetupRegisters(true);
BK4819_SetupAircopy();
BK4819_ResetFSK();
gAircopyState = AIRCOPY_READY;
gEeprom.BACKLIGHT_TIME = 61;
gEeprom.KEY_LOCK = 0;
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
gEeprom.CURRENT_STATE = 0; // Don't resume is active...
#endif
GUI_SelectNextDisplay(DISPLAY_AIRCOPY);
}
#endif
else
{
GUI_SelectNextDisplay(DISPLAY_MAIN);
} }
#endif
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

40
main.c
View File

@@ -140,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
@@ -160,48 +161,21 @@ 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) { // keys are pressed #if defined(ENABLE_FEAT_F4HWN_RESCUE_OPS) || defined(ENABLE_AIRCOPY)
|| BootMode != BOOT_MODE_NORMAL
#endif
) { // keys are pressed
UI_DisplayReleaseKeys(); UI_DisplayReleaseKeys();
BACKLIGHT_TurnOn(); BACKLIGHT_TurnOn();
@@ -249,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);

13
misc.c
View File

@@ -95,7 +95,6 @@ const uint8_t gMicGain_dB2[5] = {3, 8, 16, 24, 31};
bool gSetting_200TX; bool gSetting_200TX;
bool gSetting_500TX; bool gSetting_500TX;
#endif #endif
bool gSetting_350EN = true;
uint8_t gSetting_F_LOCK; uint8_t gSetting_F_LOCK;
bool gSetting_ScrambleEnable; bool gSetting_ScrambleEnable;
@@ -111,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
@@ -134,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

13
misc.h
View File

@@ -148,7 +148,6 @@ 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;
@@ -164,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
@@ -187,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

694
radio.c

File diff suppressed because it is too large Load Diff

128
radio.h
View File

@@ -24,7 +24,7 @@
#include "frequencies.h" #include "frequencies.h"
enum { enum {
RADIO_CHANNEL_UP = 0x01u, RADIO_CHANNEL_UP = 0x01u,
RADIO_CHANNEL_DOWN = 0xFFu, RADIO_CHANNEL_DOWN = 0xFFu,
}; };
@@ -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,18 +69,16 @@ 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;
// this is for a purpose of the FrequencyReverse function // this is for a purpose of the FrequencyReverse function
// it points to freq_config_RX normally and to freq_config_TX if reverse function is active // it points to freq_config_RX normally and to freq_config_TX if reverse function is active
@@ -92,82 +89,97 @@ typedef struct VFO_Info_t
// it points to freq_config_TX normally and to freq_config_RX if reverse function is active // it points to freq_config_TX normally and to freq_config_RX if reverse function is active
FREQ_Config_t *pTX; FREQ_Config_t *pTX;
uint32_t TX_OFFSET_FREQUENCY; uint32_t TX_OFFSET_FREQUENCY;
uint16_t StepFrequency; uint16_t StepFrequency;
uint8_t CHANNEL_SAVE; uint8_t CHANNEL_SAVE;
uint8_t TX_OFFSET_FREQUENCY_DIRECTION; uint8_t TX_OFFSET_FREQUENCY_DIRECTION;
uint8_t SquelchOpenRSSIThresh; uint8_t SquelchOpenRSSIThresh;
uint8_t SquelchOpenNoiseThresh; uint8_t SquelchOpenNoiseThresh;
uint8_t SquelchCloseGlitchThresh; uint8_t SquelchCloseGlitchThresh;
uint8_t SquelchCloseRSSIThresh; uint8_t SquelchCloseRSSIThresh;
uint8_t SquelchCloseNoiseThresh; uint8_t SquelchCloseNoiseThresh;
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;
uint8_t SCANLIST2_PARTICIPATION; uint8_t SCANLIST2_PARTICIPATION;
uint8_t SCANLIST3_PARTICIPATION; uint8_t SCANLIST3_PARTICIPATION;
uint8_t Band; uint8_t Band;
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
uint8_t DTMF_DECODING_ENABLE; uint8_t DTMF_DECODING_ENABLE;
#endif #endif
PTT_ID_t DTMF_PTT_ID_TX_MODE; PTT_ID_t DTMF_PTT_ID_TX_MODE;
uint8_t BUSY_CHANNEL_LOCK; uint8_t BUSY_CHANNEL_LOCK;
ModulationMode_t Modulation; ModulationMode_t Modulation;
uint8_t Compander; uint8_t Compander;
char Name[16]; char Name[16];
} VFO_Info_t; } VFO_Info_t;
// Settings of the main VFO that is selected by the user // Settings of the main VFO that is selected by the user
// The pointer follows gEeprom.TX_VFO index // The pointer follows gEeprom.TX_VFO index
extern VFO_Info_t *gTxVfo; extern VFO_Info_t *gTxVfo;
// Settings of the actual VFO that is now used for RX, // Settings of the actual VFO that is now used for RX,
// It is being alternated by dual watch, and flipped by crossband // It is being alternated by dual watch, and flipped by crossband
// The pointer follows gEeprom.RX_VFO // The pointer follows gEeprom.RX_VFO
extern VFO_Info_t *gRxVfo; extern VFO_Info_t *gRxVfo;
// Equal to gTxVfo unless dual watch changes it on incomming transmition (this can only happen when XB off and DW on) // Equal to gTxVfo unless dual watch changes it on incomming transmition (this can only happen when XB off and DW on)
extern VFO_Info_t *gCurrentVfo; extern VFO_Info_t *gCurrentVfo;
extern DCS_CodeType_t gCurrentCodeType; 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);
uint8_t RADIO_FindNextChannel(uint8_t ChNum, int8_t Direction, bool bCheckScanList, uint8_t RadioNum);
void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t Frequency);
void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure);
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo);
void RADIO_ApplyOffset(VFO_Info_t *pInfo);
void RADIO_SelectVfos(void);
void RADIO_SetupRegisters(bool switchToForeground);
bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanList);
uint8_t RADIO_FindNextChannel(uint8_t ChNum, int8_t Direction, bool bCheckScanList, uint8_t RadioNum);
void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t Frequency);
void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure);
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo);
void RADIO_ApplyOffset(VFO_Info_t *pInfo);
void RADIO_SelectVfos(void);
void RADIO_SetupRegisters(bool switchToForeground);
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
void RADIO_ConfigureNOAA(void); void RADIO_ConfigureNOAA(void);
#endif #endif
void RADIO_SetTxParameters(void);
void RADIO_SetupAGC(bool listeningAM, bool disable); void RADIO_SetTxParameters(void);
void RADIO_SetModulation(ModulationMode_t modulation);
void RADIO_SetVfoState(VfoState_t State); void RADIO_SetupAGC(bool listeningAM, bool disable);
void RADIO_PrepareTX(void);
void RADIO_SendCssTail(void); void RADIO_SetModulation(ModulationMode_t modulation);
void RADIO_PrepareCssTX(void);
void RADIO_SendEndOfTransmission(void); void RADIO_SetVfoState(VfoState_t State);
void RADIO_PrepareTX(void);
void RADIO_SendCssTail(void);
void RADIO_PrepareCssTX(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
DECREMENT_AND_TRIGGER(gTxTimerCountdown_500ms, gTxTimeoutReached); if (gEeprom.TX_TIMEOUT_TIMER != 0) {
DECREMENT_AND_TRIGGER(gTxTimerCountdown_500ms, gTxTimeoutReached);
}
DECREMENT(gSerialConfigCountDown_500ms); DECREMENT(gSerialConfigCountDown_500ms);
} }

View File

@@ -28,6 +28,7 @@
#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[] =
@@ -43,6 +44,7 @@ static const uint32_t gDefaultFrequencyTable[] =
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);
@@ -53,12 +55,9 @@ void SETTINGS_InitEEPROM(void) {
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;
#else
gEeprom.KEY_LOCK = (Data[4] < 2) ? Data[4] : false;
#endif #endif
gEeprom.KEY_LOCK = (Data[4] < 2) != 0 && Data[4];
#ifdef ENABLE_VOX #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;
@@ -77,12 +76,8 @@ 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; gEeprom.TAIL_TONE_ELIMINATION = (Data[6] < 2) != 0 && Data[6];
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 #ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
gEeprom.VFO_OPEN = Data[7] & 0x01; gEeprom.VFO_OPEN = Data[7] & 0x01;
@@ -274,21 +269,14 @@ void SETTINGS_InitEEPROM(void) {
gEeprom.FSKSRCAddress |= Data[1] << 8; gEeprom.FSKSRCAddress |= Data[1] << 8;
gEeprom.FSKSRCAddress |= Data[2] << 16; gEeprom.FSKSRCAddress |= Data[2] << 16;
gEeprom.FSKSRCAddress |= Data[3] << 24; 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_350TX = (Data[1] < 2) ? Data[1] : false; // was true
#endif
#ifndef ENABLE_FEAT_F4HWN
gSetting_200TX = (Data[3] < 2) ? Data[3] : false;
gSetting_500TX = (Data[4] < 2) ? Data[4] : false;
gSetting_350EN = (Data[5] < 2) ? Data[5] : true;
#else
gSetting_350EN = true;
#endif
gSetting_ScrambleEnable = true; gSetting_ScrambleEnable = true;
//gSetting_TX_EN = (Data[7] & (1u << 0)) ? true : false; //gSetting_TX_EN = (Data[7] & (1u << 0)) ? true : false;
@@ -337,20 +325,12 @@ void SETTINGS_InitEEPROM(void) {
#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;
*/ */
@@ -362,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
@@ -384,7 +354,6 @@ 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
} }
@@ -451,7 +420,7 @@ uint32_t SETTINGS_FetchChannelFrequency(const int channel) {
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;
} }
@@ -468,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++)
@@ -594,12 +563,7 @@ void SETTINGS_SaveSettings(void) {
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);
#else
State[4] = gEeprom.KEY_LOCK;
#endif
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
State[5] = gEeprom.VOX_SWITCH; State[5] = gEeprom.VOX_SWITCH;
State[6] = gEeprom.VOX_LEVEL; State[6] = gEeprom.VOX_LEVEL;
@@ -630,11 +594,7 @@ void SETTINGS_SaveSettings(void) {
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) | State[7] = (gEeprom.VFO_OPEN & 0x01) | ((gEeprom.CURRENT_STATE & 0x07) << 1) |
@@ -727,6 +687,12 @@ void SETTINGS_SaveSettings(void) {
State[1] = (gEeprom.FSKSRCAddress >> 8) & 0xFF; State[1] = (gEeprom.FSKSRCAddress >> 8) & 0xFF;
State[2] = (gEeprom.FSKSRCAddress >> 16) & 0xFF; State[2] = (gEeprom.FSKSRCAddress >> 16) & 0xFF;
State[3] = (gEeprom.FSKSRCAddress >> 24) & 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); EEPROM_WriteBuffer(0x0F20, State);
memset(State, 0xFF, sizeof(State)); memset(State, 0xFF, sizeof(State));
@@ -738,8 +704,6 @@ void SETTINGS_SaveSettings(void) {
State[3] = gSetting_200TX; State[3] = gSetting_200TX;
State[4] = gSetting_500TX; State[4] = gSetting_500TX;
#endif #endif
State[5] = gSetting_350EN;
State[6] = gSetting_ScrambleEnable; State[6] = gSetting_ScrambleEnable;
//if (!gSetting_TX_EN) State[7] &= ~(1u << 0); //if (!gSetting_TX_EN) State[7] &= ~(1u << 0);
@@ -774,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
@@ -788,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
@@ -813,10 +765,10 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
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;
} }
@@ -824,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;
@@ -835,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)
@@ -846,9 +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;
EEPROM_WriteBuffer(OffsetVFO + sizeof (State._32), State._8);
State._16[0] = pVFO->SCRAMBLING_TYPE;
EEPROM_WriteBuffer(OffsetVFO + sizeof (State._32) + sizeof (State._8), State._16);
State._8[7] = pVFO->SCRAMBLING_TYPE;
EEPROM_WriteBuffer(OffsetVFO + 8, State._8);
SETTINGS_UpdateChannel(Channel, pVFO, true, true, true); SETTINGS_UpdateChannel(Channel, pVFO, true, true, true);
@@ -876,7 +830,7 @@ void SETTINGS_SaveBatteryCalibration(const uint16_t *batteryCalibration) {
} }
void SETTINGS_SaveChannelName(uint8_t channel, const char *name) { void SETTINGS_SaveChannelName(uint8_t channel, const char *name) {
uint16_t offset = channel * 16; uint16_t offset = channel * 24;
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);
@@ -980,14 +934,11 @@ void SETTINGS_WriteBuildOptions(void) {
#endif #endif
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
| (1 << 4) | (1 << 4)
#endif
#ifdef ENABLE_SPECTRUM
| (1 << 5)
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS #ifdef ENABLE_SPECTRUM
| (1 << 6) | (1 << 5)
#endif #endif
; | (1 << 6);
EEPROM_WriteBuffer(0x1FF0, State); EEPROM_WriteBuffer(0x1FF0, State);
} }
@@ -1020,7 +971,7 @@ void SETTINGS_WriteCurrentVol(void) {
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 * 16; uint16_t OffsetVFO = channel * 24;
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);

View File

@@ -98,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,
@@ -125,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,
@@ -173,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
@@ -198,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
@@ -207,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

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;
@@ -83,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,
@@ -55,13 +103,13 @@ void UI_DisplayFM(void)
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, "VF(C%02u)", i + 1); sprintf(String, "C%02u MHz", i + 1);
pPrintStr = String; pPrintStr = String;
break; break;
} }
@@ -74,7 +122,7 @@ void UI_DisplayFM(void)
pPrintStr = "M-SCN"; pPrintStr = "M-SCN";
} }
UI_PrintString(pPrintStr, 0, 127, 3, 12); // 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)) {
@@ -89,12 +137,12 @@ void UI_DisplayFM(void)
sprintf(String, "%.3s.%.1s",ascii, ascii + 3); sprintf(String, "%.3s.%.1s",ascii, ascii + 3);
} }
UI_PrintString(String, 0, 20, 1, 10); // 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

@@ -78,6 +78,13 @@ void *memcpy_inv(void *dst, const void *src, size_t n) {
void UI_PrintStringBuffer(const char *pString, uint8_t *buffer, uint32_t char_width, const uint8_t *font, bool inv) { 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) {
@@ -91,7 +98,6 @@ void UI_PrintStringBuffer(const char *pString, uint8_t *buffer, uint32_t char_wi
} }
} }
void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_t Line, uint8_t char_width, 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 uint8_t *font, bool inv) {
const size_t Length = strlen(pString); const size_t Length = strlen(pString);
@@ -104,31 +110,55 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_
UI_PrintStringBuffer(pString, gFrameBuffer[Line] + Start, char_width, font, inv); 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, false);
} }
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 */) {
Width = Width; // UI_PrintStringSmallNormal(pString, Start, End, Line);
UI_PrintStringSmallNormal(pString, Start, End, Line); //// size_t i;
// size_t i; //// size_t Length = strlen(pString);
// size_t Length = strlen(pString); ////
// //// if (End > Start)
// if (End > Start) //// Start += (((End - Start) - (Length * Width)) + 1) / 2;
// Start += (((End - Start) - (Length * Width)) + 1) / 2; ////
// //// for (i = 0; i < Length; i++)
// for (i = 0; i < Length; i++) //// {
// { //// const unsigned int ofs = (unsigned int)Start + (i * Width);
// const unsigned int ofs = (unsigned int)Start + (i * Width); //// if (pString[i] > ' ' && pString[i] < 127)
// if (pString[i] > ' ' && pString[i] < 127) //// {
// { //// const unsigned int index = pString[i] - ' ' - 1;
// const unsigned int index = pString[i] - ' ' - 1; //// memcpy(gFrameBuffer[Line + 0] + ofs, &gFontSmall[index + '0'][0], 7);
// memcpy(gFrameBuffer[Line + 0] + ofs, &gFontSmall[index + '0'][0], 7); //// memcpy(gFrameBuffer[Line + 1] + ofs, &gFontSmall[index + '0'][7], 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) { void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line) {
//#ifdef ENABLE_SMALL_BOLD //#ifdef ENABLE_SMALL_BOLD
@@ -149,7 +179,7 @@ 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) {
#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;
@@ -283,6 +313,30 @@ 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,
// 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, 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;
@@ -291,22 +345,25 @@ void GUI_DisplaySmallest(const char *pString, uint8_t x, uint8_t y,
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];
if (pixels & 1) { for (int j = 0; j < 8; ++j) {
if (statusbar) if (pixels & 1) {
PutPixelStatus(x + i, y + j, fill); if (statusbar)
else PutPixelStatus(x + i, y + j, fill);
PutPixel(x + i, y + j, fill); else
PutPixel(x + i, y + j, fill);
}
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) {
@@ -352,10 +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_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() { 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();

429
ui/main.c
View File

@@ -45,6 +45,7 @@
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
#include "driver/system.h" #include "driver/system.h"
#include "app/scanner.h"
#endif #endif
@@ -59,7 +60,7 @@ static uint32_t RxOnVfofrequency;
bool isMainOnlyInputDTMF = false; bool isMainOnlyInputDTMF = false;
static bool isMainOnly() { bool isMainOnly() {
return (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF) && (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF); return (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF) && (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF);
} }
@@ -88,6 +89,7 @@ const char *VfoStateStr[] = {
// *************************************************************************** // ***************************************************************************
static void DrawSmallAntennaAndBars(uint8_t *p, unsigned int level) { static void DrawSmallAntennaAndBars(uint8_t *p, unsigned int level) {
level++;
if (level > 6) if (level > 6)
level = 6; level = 6;
@@ -115,51 +117,19 @@ static void DrawLevelBar(uint8_t xpos, uint8_t line, uint8_t level, uint8_t bars
level = MIN(level, bars); level = MIN(level, bars);
for (uint8_t i = 0; i < level; i++) { for (uint8_t i = 0; i < level; i++) {
#ifdef ENABLE_FEAT_F4HWN const char hollowBar[] = {
if (gSetting_set_met) { 0b01111111,
const char hollowBar[] = { 0b01000001,
0b01111111, 0b01000001,
0b01000001, 0b01111111
0b01000001, };
0b01111111
};
if (i < bars - 4) { if (i < bars - 4) {
for (uint8_t j = 0; j < 4; j++) for (uint8_t j = 0; j < 4; j++)
p_line[xpos + i * 5 + j] = (~(0x7F >> (i + 1))) & 0x7F; p_line[xpos + i * 5 + j] = (~(0x7F >> (i + 1))) & 0x7F;
} else {
memcpy(p_line + (xpos + i * 5), &hollowBar, ARRAY_SIZE(hollowBar));
}
} else { } else {
const char hollowBar[] = {
0b00111110,
0b00100010,
0b00100010,
0b00111110
};
const char simpleBar[] = {
0b00111110,
0b00111110,
0b00111110,
0b00111110
};
if (i < bars - 4) {
memcpy(p_line + (xpos + i * 5), &simpleBar, ARRAY_SIZE(simpleBar));
} else {
memcpy(p_line + (xpos + i * 5), &hollowBar, ARRAY_SIZE(hollowBar));
}
}
#else
if(i < bars - 4) {
for(uint8_t j = 0; j < 4; j++)
p_line[xpos + i * 5 + j] = (~(0x7F >> (i+1))) & 0x7F;
}
else {
memcpy(p_line + (xpos + i * 5), &hollowBar, ARRAY_SIZE(hollowBar)); memcpy(p_line + (xpos + i * 5), &hollowBar, ARRAY_SIZE(hollowBar));
} }
#endif
} }
} }
@@ -197,7 +167,7 @@ void UI_DisplayAudioBar(void) {
if (gCurrentFunction != FUNCTION_TRANSMIT || if (gCurrentFunction != FUNCTION_TRANSMIT ||
gScreenToDisplay != DISPLAY_MAIN gScreenToDisplay != DISPLAY_MAIN
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
|| gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_CallState != DTMF_CALL_STATE_NONE
#endif #endif
) { ) {
@@ -237,7 +207,7 @@ void UI_DisplayAudioBar(void) {
void DisplayRSSIBar(const bool now) { void DisplayRSSIBar(const bool now) {
#if defined(ENABLE_RSSI_BAR) #if defined(ENABLE_RSSI_BAR)
const unsigned int txt_width = 7 * 8; // 8 text chars const unsigned int txt_width = 7 * 10; // 8 text chars
const unsigned int bar_x = 2 + txt_width + 4; // X coord of bar graph const unsigned int bar_x = 2 + txt_width + 4; // X coord of bar graph
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
@@ -266,7 +236,7 @@ void DisplayRSSIBar(const bool now) {
if (RxLine >= 0 && center_line != CENTER_LINE_IN_USE) { if (RxLine >= 0 && center_line != CENTER_LINE_IN_USE) {
if (RxBlink == 0 || RxBlink == 1) { if (RxBlink == 0 || RxBlink == 1) {
UI_PrintStringSmallBold("RX", 8, 0, RxLine); UI_PrintStringSmallBold("RX", 24, 0, RxLine);
if (RxBlink == 1) RxBlink = 2; if (RxBlink == 1) RxBlink = 2;
} else { } else {
for (uint8_t i = 8; i < 24; i++) { for (uint8_t i = 8; i < 24; i++) {
@@ -299,7 +269,7 @@ void DisplayRSSIBar(const bool now) {
if (gCurrentFunction == FUNCTION_TRANSMIT || if (gCurrentFunction == FUNCTION_TRANSMIT ||
gScreenToDisplay != DISPLAY_MAIN gScreenToDisplay != DISPLAY_MAIN
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
|| gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_CallState != DTMF_CALL_STATE_NONE
#endif #endif
) )
@@ -348,36 +318,31 @@ void DisplayRSSIBar(const bool now) {
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
if (gSetting_set_gui) { char tempStr[4];
sprintf(str, "%3d", -rssi_dBm);
UI_PrintStringSmallNormal(str, LCD_WIDTH + 8, 0, line - 1);
} else {
sprintf(str, "% 4d %s", -rssi_dBm, "dBm");
if (isMainOnly())
GUI_DisplaySmallest(str, 2, 41, false, true);
else
GUI_DisplaySmallest(str, 2, 25, false, true);
}
if (overS9Bars == 0) { if (overS9Bars == 0) {
sprintf(str, "S%d", s_level); sprintf(tempStr, "S%d", s_level);
} else { } else {
sprintf(str, "+%02d", overS9dBm); sprintf(tempStr, "+%02d", overS9dBm);
} }
UI_PrintStringSmallNormal(str, LCD_WIDTH + 38, 0, line - 1); sprintf(str, "%4ddBm%3s", -rssi_dBm, tempStr);
if (isMainOnly())
UI_PrintStringSmallNormal(str, 2, 0, 4);
else
UI_PrintStringSmallNormal(str, 2, 0, 3);
#else #else
if(overS9Bars == 0) { if(overS9Bars == 0) {
sprintf(str, "% 4d S%d", -rssi_dBm, s_level); sprintf(str, "% 4d S%d", -rssi_dBm, s_level);
} }
else { else {
sprintf(str, "% 4d %2d", -rssi_dBm, overS9dBm); sprintf(str, "% 4d %2ld", -rssi_dBm, overS9dBm);
memcpy(p_line + 2 + 7*5, &plus, ARRAY_SIZE(plus)); memcpy(p_line + 2 + 7*5, &plus, ARRAY_SIZE(plus));
} }
UI_PrintStringSmallNormal(str, 2, 0, line); UI_PrintStringSmallNormal(str, 2, 0, line);
#endif #endif
DrawLevelBar(bar_x, line, s_level + overS9Bars, 13); DrawLevelBar(bar_x, line, s_level + overS9Bars, 10);
if (now) if (now)
ST7565_BlitLine(line); ST7565_BlitLine(line);
#else #else
@@ -438,7 +403,7 @@ void UI_MAIN_PrintAGC(bool now)
int8_t pgaTab[] = {-33, -27, -21, -15, -9, -6, -3, 0}; int8_t pgaTab[] = {-33, -27, -21, -15, -9, -6, -3, 0};
int16_t agcGain = lnaShortTab[agcGainReg.lnaS] + lnaTab[agcGainReg.lna] + mixerTab[agcGainReg.mixer] + pgaTab[agcGainReg.pga]; int16_t agcGain = lnaShortTab[agcGainReg.lnaS] + lnaTab[agcGainReg.lna] + mixerTab[agcGainReg.mixer] + pgaTab[agcGainReg.pga];
sprintf(buf, "%d%2d %2d %2d %3d", reg7e.agcEnab, reg7e.gainIdx, -agcGain, reg7e.agcSigStrength, BK4819_GetRSSI()); sprintf(buf, "%d%2ld %2ld %2ld %3ld", reg7e.agcEnab, reg7e.gainIdx, -agcGain, reg7e.agcSigStrength, BK4819_GetRSSI());
UI_PrintStringSmallNormal(buf, 2, 0, 3); UI_PrintStringSmallNormal(buf, 2, 0, 3);
if(now) if(now)
ST7565_BlitLine(3); ST7565_BlitLine(3);
@@ -455,44 +420,6 @@ void UI_MAIN_TimeSlice500ms(void) {
if (FUNCTION_IsRx()) { if (FUNCTION_IsRx()) {
DisplayRSSIBar(true); DisplayRSSIBar(true);
} }
#ifdef ENABLE_FEAT_F4HWN // Blink Green Led for white...
else if (gSetting_set_eot > 0 && RxBlinkLed == 2) {
if (RxBlinkLedCounter <= 8) {
if (RxBlinkLedCounter % 2 == 0) {
if (gSetting_set_eot > 1) {
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
}
} else {
if (gSetting_set_eot > 1) {
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, true);
}
if (gSetting_set_eot == 1 || gSetting_set_eot == 3) {
switch (RxBlinkLedCounter) {
case 1:
AUDIO_PlayBeep(BEEP_400HZ_30MS);
break;
case 3:
AUDIO_PlayBeep(BEEP_400HZ_30MS);
break;
case 5:
AUDIO_PlayBeep(BEEP_500HZ_30MS);
break;
case 7:
AUDIO_PlayBeep(BEEP_600HZ_30MS);
break;
}
}
}
RxBlinkLedCounter += 1;
} else {
RxBlinkLed = 0;
}
}
#endif
} }
} }
@@ -507,7 +434,7 @@ void UI_DisplayMain(void) {
UI_DisplayClear(); UI_DisplayClear();
if (gLowBattery && !gLowBatteryConfirmed) { if (gLowBattery && !gLowBatteryConfirmed) {
UI_DisplayPopup("LOW BATTERY"); UI_DisplayPopup("LOW BAT");
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
return; return;
} }
@@ -515,8 +442,8 @@ void UI_DisplayMain(void) {
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
if (gEeprom.KEY_LOCK && gKeypadLocked > 0) if (gEeprom.KEY_LOCK && gKeypadLocked > 0)
{ // tell user how to unlock the keyboard { // tell user how to unlock the keyboard
UI_PrintString("Long press #", 0, LCD_WIDTH, 1, 8); UI_PrintString("Long press #", 0, LCD_WIDTH, 1 /*, 8 */);
UI_PrintString("to unlock", 0, LCD_WIDTH, 3, 8); UI_PrintString("to unlock", 0, LCD_WIDTH, 3 /*, 8 */);
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
return; return;
} }
@@ -535,7 +462,7 @@ void UI_DisplayMain(void) {
shift = 5; shift = 5;
} }
//memcpy(gFrameBuffer[shift] + 2, gFontKeyLock, sizeof(gFontKeyLock)); //memcpy(gFrameBuffer[shift] + 2, gFontKeyLock, sizeof(gFontKeyLock));
UI_PrintStringSmallBold("UNLOCK KEYBOARD", 12, 0, shift); UI_PrintStringSmallBold("KEYLOCK", 12, 0, shift);
//memcpy(gFrameBuffer[shift] + 120, gFontKeyLock, sizeof(gFontKeyLock)); //memcpy(gFrameBuffer[shift] + 120, gFontKeyLock, sizeof(gFontKeyLock));
/* /*
@@ -600,10 +527,10 @@ void UI_DisplayMain(void) {
shift = 3; shift = 3;
} }
UI_PrintString("ScnRng", 5, 0, line + shift, 8); UI_PrintString("ScnRng", 5, 0, line + shift /*, 8 */);
sprintf(String, "%3u.%05u", gScanRangeStart / 100000, gScanRangeStart % 100000); sprintf(String, "%3lu.%05lu", gScanRangeStart / 100000, gScanRangeStart % 100000);
UI_PrintStringSmallNormal(String, 56, 0, line + shift); UI_PrintStringSmallNormal(String, 56, 0, line + shift);
sprintf(String, "%3u.%05u", gScanRangeStop / 100000, gScanRangeStop % 100000); sprintf(String, "%3lu.%05lu", gScanRangeStop / 100000, gScanRangeStop % 100000);
UI_PrintStringSmallNormal(String, 56, 0, line + shift + 1); UI_PrintStringSmallNormal(String, 56, 0, line + shift + 1);
if (!isMainOnly()) if (!isMainOnly())
@@ -612,33 +539,18 @@ void UI_DisplayMain(void) {
gScanRangeStart = 0; gScanRangeStart = 0;
} }
#else #else
UI_PrintString("ScnRng", 5, 0, line, 8); UI_PrintString("ScnRng", 5, 0, line /*, 8 */);
sprintf(String, "%3u.%05u", gScanRangeStart / 100000, gScanRangeStart % 100000); sprintf(String, "%3lu.%05lu", gScanRangeStart / 100000, gScanRangeStart % 100000);
UI_PrintStringSmallNormal(String, 56, 0, line); UI_PrintStringSmallNormal(String, 56, 0, line);
sprintf(String, "%3u.%05u", gScanRangeStop / 100000, gScanRangeStop % 100000); sprintf(String, "%3lu.%05lu", gScanRangeStop / 100000, gScanRangeStop % 100000);
UI_PrintStringSmallNormal(String, 56, 0, line + 1); UI_PrintStringSmallNormal(String, 56, 0, line + 1);
continue; continue;
#endif #endif
} }
#endif #endif
if (gEnteringSMS == SMS_ENTERING_DEST) {
UI_PrintString("SMS Dst", 0, 0, line - 1, 8);
sprintf(String, "%d", dataPacket.dest);
UI_PrintStringSmallNormal(String, 0, 0, line);
continue;
}
if (gEnteringSMS == SMS_ENTERING_MESSAGE) {
UI_PrintString("SMS Dat", 0, 0, line - 1, 8);
sprintf(String, "%s", dataPacket.data);
UI_PrintStringSmallNormal(String, 0, 0, line);
continue;
}
if (gDTMF_InputMode if (gDTMF_InputMode
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
|| gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_IsTx || gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_IsTx
#endif #endif
) { ) {
@@ -657,7 +569,7 @@ void UI_DisplayMain(void) {
} }
} }
UI_PrintString(pPrintStr, 2, 0, 2 + (vfo_num * 3), 8); UI_PrintString(pPrintStr, 2, 0, 2 + (vfo_num * 3) /*, 8 */);
pPrintStr = ""; pPrintStr = "";
if (!gDTMF_InputMode) { if (!gDTMF_InputMode) {
@@ -680,17 +592,17 @@ void UI_DisplayMain(void) {
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
if (isMainOnly()) { if (isMainOnly()) {
UI_PrintString(pPrintStr, 2, 0, 5, 8); UI_PrintString(pPrintStr, 2, 0, 5 /*, 8 */);
isMainOnlyInputDTMF = true; isMainOnlyInputDTMF = true;
center_line = CENTER_LINE_IN_USE; center_line = CENTER_LINE_IN_USE;
} else { } else {
UI_PrintString(pPrintStr, 2, 0, 0 + (vfo_num * 3), 8); UI_PrintString(pPrintStr, 2, 0, 0 + (vfo_num * 3) /*, 8 */);
isMainOnlyInputDTMF = false; isMainOnlyInputDTMF = false;
center_line = CENTER_LINE_IN_USE; center_line = CENTER_LINE_IN_USE;
continue; continue;
} }
#else #else
UI_PrintString(pPrintStr, 2, 0, 0 + (vfo_num * 3), 8); UI_PrintString(pPrintStr, 2, 0, 0 + (vfo_num * 3) /*, 8 */);
center_line = CENTER_LINE_IN_USE; center_line = CENTER_LINE_IN_USE;
continue; continue;
#endif #endif
@@ -709,11 +621,11 @@ void UI_DisplayMain(void) {
uint32_t frequency = gEeprom.VfoInfo[vfo_num].pRX->Frequency; uint32_t frequency = gEeprom.VfoInfo[vfo_num].pRX->Frequency;
if (TX_freq_check(frequency) != 0 && gEeprom.VfoInfo[vfo_num].TX_LOCK == true) { if (TX_freq_check(frequency) != 0) {
if (isMainOnly()) if (isMainOnly())
memcpy(p_line0 + 14, BITMAP_VFO_Lock, sizeof(BITMAP_VFO_Lock)); memcpy(p_line0 + 5, gFontKeyLock, sizeof(gFontKeyLock));
else else
memcpy(p_line0 + 24, BITMAP_VFO_Lock, sizeof(BITMAP_VFO_Lock)); memcpy(p_line0 + 10, gFontKeyLock, sizeof(gFontKeyLock));
} }
if (gCurrentFunction == FUNCTION_TRANSMIT) { // transmitting if (gCurrentFunction == FUNCTION_TRANSMIT) { // transmitting
@@ -750,7 +662,7 @@ void UI_DisplayMain(void) {
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
else { else {
if (RxOnVfofrequency == frequency && !isMainOnly()) { if (RxOnVfofrequency == frequency && !isMainOnly()) {
UI_PrintStringSmallNormal(">>", 8, 0, line); UI_PrintStringSmallNormal(">>", 24, 0, line);
//memcpy(p_line0 + 14, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default)); //memcpy(p_line0 + 14, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default));
} }
@@ -761,7 +673,7 @@ void UI_DisplayMain(void) {
} }
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num])) { // channel mode if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num])) { // channel mode
const unsigned int x = 2; const unsigned int x = 20;
const bool inputting = gInputBoxIndex != 0 && gEeprom.TX_VFO == vfo_num; const bool inputting = gInputBoxIndex != 0 && gEeprom.TX_VFO == vfo_num;
if (!inputting) if (!inputting)
sprintf(String, "M%u", gEeprom.ScreenChannel[vfo_num] + 1); sprintf(String, "M%u", gEeprom.ScreenChannel[vfo_num] + 1);
@@ -770,7 +682,7 @@ void UI_DisplayMain(void) {
UI_PrintStringSmallNormal(String, x, 0, line + 1); UI_PrintStringSmallNormal(String, x, 0, line + 1);
} else if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num])) { // frequency mode } else if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num])) { // frequency mode
// show the frequency band number // show the frequency band number
const unsigned int x = 2; const unsigned int x = 0;
char *buf = gEeprom.VfoInfo[vfo_num].pRX->Frequency < _1GHz_in_KHz ? "" : "+"; char *buf = gEeprom.VfoInfo[vfo_num].pRX->Frequency < _1GHz_in_KHz ? "" : "+";
sprintf(String, "F%u%s", 1 + gEeprom.ScreenChannel[vfo_num] - FREQ_CHANNEL_FIRST, buf); sprintf(String, "F%u%s", 1 + gEeprom.ScreenChannel[vfo_num] - FREQ_CHANNEL_FIRST, buf);
UI_PrintStringSmallNormal(String, x, 0, line + 1); UI_PrintStringSmallNormal(String, x, 0, line + 1);
@@ -802,24 +714,15 @@ void UI_DisplayMain(void) {
#endif #endif
if (state != VFO_STATE_NORMAL) { if (state != VFO_STATE_NORMAL) {
if (state < ARRAY_SIZE(VfoStateStr)) if (state < ARRAY_SIZE(VfoStateStr))
UI_PrintString(VfoStateStr[state], 31, 0, line, 8); UI_PrintString(VfoStateStr[state], 31, 0, line /*, 8 */);
} else if (gInputBoxIndex > 0 && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]) && } else if (gInputBoxIndex > 0 && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]) &&
gEeprom.TX_VFO == vfo_num) { // user entering a frequency gEeprom.TX_VFO == vfo_num) { // user entering a frequency
const char *ascii = INPUTBOX_GetAscii(); const char *ascii = INPUTBOX_GetAscii();
bool isGigaF = frequency >= _1GHz_in_KHz; bool isGigaF = frequency >= _1GHz_in_KHz;
sprintf(String, "%.*s.%.3s", 3 + isGigaF, ascii, ascii + 3 + isGigaF); sprintf(String, "%.*s.%.3s", 3 + isGigaF, ascii, ascii + 3 + isGigaF);
#ifdef ENABLE_BIG_FREQ
if (!isGigaF) {
// show the remaining 2 small frequency digits
UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1);
String[7] = 0;
// show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false);
} else
#endif
{ {
// show the frequency in the main font // show the frequency in the main font
UI_PrintString(String, 32, 0, line, 8); UI_PrintString(String, 45, 0, line /*, 8 */);
} }
continue; continue;
@@ -872,35 +775,33 @@ void UI_DisplayMain(void) {
// compander symbol // compander symbol
#ifndef ENABLE_BIG_FREQ #ifndef ENABLE_BIG_FREQ
const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; //const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
if (att.compander)
memcpy(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
#else #else
// TODO: // find somewhere else to put the symbol // TODO: // find somewhere else to put the symbol
#endif #endif
switch (gEeprom.CHANNEL_DISPLAY_MODE) { switch (gEeprom.CHANNEL_DISPLAY_MODE) {
case MDF_FREQUENCY: // show the channel frequency case MDF_FREQUENCY: // show the channel frequency
sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000); sprintf(String, "%3lu.%05lu", frequency / 100000, frequency % 100000);
#ifdef ENABLE_BIG_FREQ #ifdef ENABLE_BIG_FREQ
if (frequency < _1GHz_in_KHz) { if (frequency < _1GHz_in_KHz) {
// show the remaining 2 small frequency digits // show the remaining 2 small frequency digits
UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1); UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1);
String[7] = 0; String[7] = 0;
// show the main large frequency digits // show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false); UI_DisplayFrequency(String, 20, line, false);
} else } else
#endif #endif
{ {
// show the frequency in the main font // show the frequency in the main font
UI_PrintString(String, 32, 0, line, 8); UI_PrintStringSmallBold(String, 40, 0, line /*, 8 */);
} }
break; break;
case MDF_CHANNEL: // show the channel number case MDF_CHANNEL: // show the channel number
sprintf(String, "CH-%03u", gEeprom.ScreenChannel[vfo_num] + 1); sprintf(String, "CH-%03u", gEeprom.ScreenChannel[vfo_num] + 1);
UI_PrintString(String, 32, 0, line, 8); UI_PrintStringSmallBold(String, 40, 0, line /*, 8 */);
break; break;
case MDF_NAME: // show the channel name case MDF_NAME: // show the channel name
@@ -912,50 +813,50 @@ void UI_DisplayMain(void) {
} }
if (gEeprom.CHANNEL_DISPLAY_MODE == MDF_NAME) { if (gEeprom.CHANNEL_DISPLAY_MODE == MDF_NAME) {
UI_PrintString(String, 32, 0, line, 8); UI_PrintStringSmallBold(String, 40, 0, line /*, 8 */);
} else { } else {
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
if (isMainOnly()) { if (isMainOnly()) {
UI_PrintString(String, 32, 0, line, 8); UI_PrintStringSmallBold(String, 40, 0, line /*, 8 */);
} else { } else {
if (activeTxVFO == vfo_num) { if (activeTxVFO == vfo_num) {
UI_PrintStringSmallBold(String, 32 + 4, 0, line); UI_PrintStringSmallBold(String, 40 + 4, 0, line);
} else { } else {
UI_PrintStringSmallNormal(String, 32 + 4, 0, line); UI_PrintStringSmallNormal(String, 40 + 4, 0, line);
} }
} }
#else #else
UI_PrintStringSmallBold(String, 32 + 4, 0, line); UI_PrintStringSmallBold(String, 20 + 4, 0, line);
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
if (isMainOnly()) { if (isMainOnly()) {
sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000); sprintf(String, "%3lu.%05lu", frequency / 100000, frequency % 100000);
if (frequency < _1GHz_in_KHz) { if (frequency < _1GHz_in_KHz) {
// show the remaining 2 small frequency digits // show the remaining 2 small frequency digits
UI_PrintStringSmallNormal(String + 7, 113, 0, line + 4); UI_PrintStringSmallNormal(String + 7, 113, 0, line + 4);
String[7] = 0; String[7] = 0;
// show the main large frequency digits // show the main large frequency digits
//UI_DisplayFrequency(String, 32, line + 3, false); //UI_DisplayFrequency(String, 20, line + 3, false);
UI_PrintStringSmallNormal(String, 0, 20, line + 3); UI_PrintStringSmallBold(String, 20, 20, line + 3);
} else { } else {
// show the frequency in the main font // show the frequency in the main font
UI_PrintString(String, 32, 0, line + 3, 8); UI_PrintString(String, 40, 0, line + 3 /*, 8 */);
} }
} else { } else {
sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000); sprintf(String, "%03lu.%05lu", frequency / 100000, frequency % 100000);
UI_PrintStringSmallNormal(String, 32 + 4, 0, line + 1); UI_PrintStringSmallBold(String, 40 + 4, 0, line + 1);
} }
#else // show the channel frequency below the channel number/name #else // show the channel frequency below the channel number/name
sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000); sprintf(String, "%03u.%05lu", frequency / 100000, frequency % 100000);
UI_PrintStringSmallNormal(String, 32 + 4, 0, line + 1); UI_PrintStringSmallNormal(String, 20 + 4, 0, line + 1);
#endif #endif
} }
break; break;
} }
} else { // frequency mode } else { // frequency mode
sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000); sprintf(String, "%3lu.%05lu", frequency / 100000, frequency % 100000);
#ifdef ENABLE_BIG_FREQ #ifdef ENABLE_BIG_FREQ
if (frequency < _1GHz_in_KHz) { if (frequency < _1GHz_in_KHz) {
@@ -963,22 +864,16 @@ void UI_DisplayMain(void) {
UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1); UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1);
String[7] = 0; String[7] = 0;
// show the main large frequency digits // show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false); UI_DisplayFrequency(String, 20, line, false);
} else } else
#endif #endif
{ {
// show the frequency in the main font // show the frequency in the main font
UI_PrintString(String, 32, 0, line, 8); UI_PrintStringSmallBold(String, 40, 0, line /*, 8 */);
} }
// show the channel symbols // show the channel symbols
const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; //const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
if (att.compander)
#ifdef ENABLE_BIG_FREQ
memcpy(p_line0 + 120, BITMAP_compand, sizeof(BITMAP_compand));
#else
memcpy(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
#endif
} }
} }
@@ -1008,7 +903,7 @@ void UI_DisplayMain(void) {
Level = 2; Level = 2;
} }
*/ */
Level = gRxVfo->OUTPUT_POWER - 1; Level = gRxVfo->OUTPUT_POWER;
} else if (mode == VFO_MODE_RX) { // RX signal level } else if (mode == VFO_MODE_RX) { // RX signal level
#ifndef ENABLE_RSSI_BAR #ifndef ENABLE_RSSI_BAR
// bar graph // bar graph
@@ -1056,7 +951,6 @@ void UI_DisplayMain(void) {
#if ENABLE_FEAT_F4HWN #if ENABLE_FEAT_F4HWN
const FREQ_Config_t *pConfig = (mode == VFO_MODE_TX) ? vfoInfo->pTX : vfoInfo->pRX; const FREQ_Config_t *pConfig = (mode == VFO_MODE_TX) ? vfoInfo->pTX : vfoInfo->pRX;
int8_t shift = 0; int8_t shift = 0;
switch ((int) pConfig->CodeType) { switch ((int) pConfig->CodeType) {
case 1: case 1:
sprintf(String, "%u.%u", CTCSS_Options[pConfig->Code] / 10, CTCSS_Options[pConfig->Code] % 10); sprintf(String, "%u.%u", CTCSS_Options[pConfig->Code] / 10, CTCSS_Options[pConfig->Code] % 10);
@@ -1075,103 +969,43 @@ void UI_DisplayMain(void) {
shift = -10; shift = -10;
} }
if (gSetting_set_gui) {
UI_PrintStringSmallNormal(s, LCD_WIDTH + 22, 0, line + 1);
UI_PrintStringSmallNormal(t, LCD_WIDTH + 2, 0, line + 1);
if (isMainOnly() && !gDTMF_InputMode) {
if (shift == 0) {
UI_PrintStringSmallNormal(String, 2, 0, 6);
}
if ((vfoInfo->StepFrequency / 100) < 100) { UI_PrintStringSmallNormal(s, 50, 0, line + 2);
sprintf(String, "%d.%02uK", vfoInfo->StepFrequency / 100, vfoInfo->StepFrequency % 100); UI_PrintStringSmallNormal(t, 2, 0, line + 2);
} else {
sprintf(String, "%dK", vfoInfo->StepFrequency / 100);
}
UI_PrintStringSmallNormal(String, 46, 0, 6);
}
} else {
if ((s != NULL) && (s[0] != '\0')) {
GUI_DisplaySmallest(s, 58, line == 0 ? 17 : 49, false, true);
}
if ((t != NULL) && (t[0] != '\0')) { if (shift == 0) {
GUI_DisplaySmallest(t, 3, line == 0 ? 17 : 49, false, true); UI_PrintStringSmallNormal(String, 65, 0, line + 2);
}
GUI_DisplaySmallest(String, 68 + shift, line == 0 ? 17 : 49, false, true);
//sprintf(String, "%d.%02u", vfoInfo->StepFrequency / 100, vfoInfo->StepFrequency % 100);
//GUI_DisplaySmallest(String, 91, line == 0 ? 2 : 34, false, true);
} }
if ((vfoInfo->StepFrequency / 100) < 100) {
sprintf(String, "%d.%02uK", vfoInfo->StepFrequency / 100, vfoInfo->StepFrequency % 100);
} else {
sprintf(String, "%dK", vfoInfo->StepFrequency / 100);
}
UI_PrintStringSmallNormal(String, 55, 0, line + 1);
#else #else
UI_PrintStringSmallNormal(s, LCD_WIDTH + 24, 0, line + 1); UI_PrintStringSmallNormal(s, LCD_WIDTH + 24, 0, line + 1);
#endif #endif
if (state == VFO_STATE_NORMAL || state == VFO_STATE_ALARM) { // show the TX power if (state == VFO_STATE_NORMAL || state == VFO_STATE_ALARM) { // show the TX power
uint8_t currentPower = vfoInfo->OUTPUT_POWER % 8; const char pwr_short[][3] = {"L1", "L2", "L3", "L4", "L5", "ME",
uint8_t arrowPos = 19; "HI"};
bool userPower = false; UI_PrintStringSmallNormal(pwr_short[vfoInfo->OUTPUT_POWER], LCD_WIDTH + 25, 0, line + 1);
if (currentPower == OUTPUT_POWER_USER) {
currentPower = gSetting_set_pwr;
userPower = true;
} else {
currentPower--;
userPower = false;
}
if (gSetting_set_gui) {
const char pwr_short[][3] = {"L1", "L2", "L3", "L4", "L5", "M", "H"};
//sprintf(String, "%s", pwr_short[currentPower]);
//UI_PrintStringSmallNormal(String, LCD_WIDTH + 42, 0, line + 1);
UI_PrintStringSmallNormal(pwr_short[currentPower], LCD_WIDTH + 42, 0, line + 1);
arrowPos = 38;
} else {
const char pwr_long[][5] = {"LOW1", "LOW2", "LOW3", "LOW4", "LOW5", "MID", "HIGH"};
//sprintf(String, "%s", pwr_long[currentPower]);
//GUI_DisplaySmallest(String, 24, line == 0 ? 17 : 49, false, true);
GUI_DisplaySmallest(pwr_long[currentPower], 24, line == 0 ? 17 : 49, false, true);
}
if (userPower == true) {
memcpy(p_line0 + 256 + arrowPos, BITMAP_PowerUser, sizeof(BITMAP_PowerUser));
}
} }
if (vfoInfo->freq_config_RX.Frequency != vfoInfo->freq_config_TX.Frequency) { // show the TX offset symbol if (vfoInfo->freq_config_RX.Frequency != vfoInfo->freq_config_TX.Frequency) { // show the TX offset symbol
int i = vfoInfo->TX_OFFSET_FREQUENCY_DIRECTION % 3; int i = vfoInfo->TX_OFFSET_FREQUENCY_DIRECTION % 3;
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
const char dir_list[][2] = {"", "+", "-", "D"}; const char dir_list[][2] = {"", "+", "-", "D"};
if(gTxVfo->TX_OFFSET_FREQUENCY_DIRECTION != 0 && gTxVfo->pTX == &gTxVfo->freq_config_RX && !vfoInfo->FrequencyReverse) if(gTxVfo->TX_OFFSET_FREQUENCY_DIRECTION != 0 && gTxVfo->pTX == &gTxVfo->freq_config_RX && !vfoInfo->FrequencyReverse)
{ {
i = 3; i = 3;
} }
#else
const char dir_list[][2] = {"", "+", "-"};
#endif
#if ENABLE_FEAT_F4HWN #if ENABLE_FEAT_F4HWN
if (gSetting_set_gui) { UI_PrintStringSmallNormal(dir_list[i], LCD_WIDTH + 60, 0, line + 1);
UI_PrintStringSmallNormal(dir_list[i], LCD_WIDTH + 60, 0, line + 1);
} else {
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
if(i == 3)
{
GUI_DisplaySmallest(dir_list[i], 43, line == 0 ? 17 : 49, false, true);
}
else
{
#endif
UI_PrintStringSmallNormal(dir_list[i], LCD_WIDTH + 41, 0, line + 1);
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
}
#endif
}
#else #else
UI_PrintStringSmallNormal(dir_list[i], LCD_WIDTH + 54, 0, line + 1); UI_PrintStringSmallNormal(dir_list[i], LCD_WIDTH + 54, 0, line + 1);
#endif #endif
@@ -1181,45 +1015,18 @@ void UI_DisplayMain(void) {
if (vfoInfo->FrequencyReverse) if (vfoInfo->FrequencyReverse)
#if ENABLE_FEAT_F4HWN #if ENABLE_FEAT_F4HWN
{ {
if (gSetting_set_gui) { UI_PrintStringSmallNormal("R", LCD_WIDTH + 110, 0, line + 1);
UI_PrintStringSmallNormal("R", LCD_WIDTH + 68, 0, line + 1);
} else {
GUI_DisplaySmallest("R", 51, line == 0 ? 17 : 49, false, true);
}
} }
#else #else
UI_PrintStringSmallNormal("R", LCD_WIDTH + 62, 0, line + 1); UI_PrintStringSmallNormal("R", LCD_WIDTH + 110, 0, line + 1);
#endif #endif
#if ENABLE_FEAT_F4HWN #if ENABLE_FEAT_F4HWN
#ifdef ENABLE_FEAT_F4HWN_NARROWER
bool narrower = 0;
if (vfoInfo->CHANNEL_BANDWIDTH == BANDWIDTH_NARROW && gSetting_set_nfm == 1) { const char *bandWidthNames[] = {"WID", "NAR", "NR+"};
narrower = 1; UI_PrintStringSmallNormal(bandWidthNames[vfoInfo->CHANNEL_BANDWIDTH], LCD_WIDTH + 30, 0,
} line);
if (gSetting_set_gui) {
const char *bandWidthNames[] = {"W", "N", "N+"};
UI_PrintStringSmallNormal(bandWidthNames[vfoInfo->CHANNEL_BANDWIDTH + narrower], LCD_WIDTH + 80, 0,
line + 1);
} else {
const char *bandWidthNames[] = {"WIDE", "NAR", "NAR+"};
GUI_DisplaySmallest(bandWidthNames[vfoInfo->CHANNEL_BANDWIDTH + narrower], 91, line == 0 ? 17 : 49, false,
true);
}
#else
if (gSetting_set_gui)
{
const char *bandWidthNames[] = {"W", "N"};
UI_PrintStringSmallNormal(bandWidthNames[vfoInfo->CHANNEL_BANDWIDTH], LCD_WIDTH + 80, 0, line + 1);
}
else
{
const char *bandWidthNames[] = {"WIDE", "NAR"};
GUI_DisplaySmallest(bandWidthNames[vfoInfo->CHANNEL_BANDWIDTH], 91, line == 0 ? 17 : 49, false, true);
}
#endif
#else #else
if (vfoInfo->CHANNEL_BANDWIDTH == BANDWIDTH_NARROW) if (vfoInfo->CHANNEL_BANDWIDTH == BANDWIDTH_NARROW)
UI_PrintStringSmallNormal("N", LCD_WIDTH + 70, 0, line + 1); UI_PrintStringSmallNormal("N", LCD_WIDTH + 70, 0, line + 1);
@@ -1232,49 +1039,21 @@ void UI_DisplayMain(void) {
#endif #endif
// show the audio scramble symbol // show the audio scramble symbol
if (vfoInfo->SCRAMBLING_TYPE > 0) if (vfoInfo->SCRAMBLING_TYPE > 0) {
UI_PrintStringSmallNormal("S", LCD_WIDTH + 106, 0, line); sprintf(String, "S%d", inverse_scale_freq(vfoInfo->SCRAMBLING_TYPE));
UI_PrintStringSmallNormal(String, 90, 0, line + 2);
}
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
/* if (isMainVFO && gMonitor) {
if(isMainVFO) strcpy(String, "MONI");
{
if(gMonitor)
{
sprintf(String, "%s", "MONI");
}
if (gSetting_set_gui) } else {
{ sprintf(String, "SQL%d", gEeprom.SQUELCH_LEVEL);
if(!gMonitor)
{
sprintf(String, "SQL%d", gEeprom.SQUELCH_LEVEL);
}
UI_PrintStringSmallNormal(String, LCD_WIDTH + 98, 0, line + 1);
}
else
{
if(!gMonitor)
{
sprintf(String, "SQL%d", gEeprom.SQUELCH_LEVEL);
}
GUI_DisplaySmallest(String, 110, line == 0 ? 17 : 49, false, true);
}
} }
*/
if (isMainVFO) {
if (gMonitor) {
strcpy(String, "MONI");
} else {
sprintf(String, "SQL%d", gEeprom.SQUELCH_LEVEL);
}
if (gSetting_set_gui) { UI_PrintStringSmallNormal(String, LCD_WIDTH + 98, 0, line);
UI_PrintStringSmallNormal(String, LCD_WIDTH + 98, 0, line + 1);
} else {
GUI_DisplaySmallest(String, 110, line == 0 ? 17 : 49, false, true);
}
}
#endif #endif
} }
@@ -1324,7 +1103,7 @@ void UI_DisplayMain(void) {
const unsigned int idx = (len > (17 - 5)) ? len - (17 - 5) : 0; // limit to last 'n' chars const unsigned int idx = (len > (17 - 5)) ? len - (17 - 5) : 0; // limit to last 'n' chars
if (gScreenToDisplay != DISPLAY_MAIN if (gScreenToDisplay != DISPLAY_MAIN
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
|| gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_CallState != DTMF_CALL_STATE_NONE
#endif #endif
) )

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);

410
ui/menu.c
View File

@@ -48,13 +48,12 @@ const t_menu_item MenuList[] =
{"TCTCS", MENU_T_CTCS}, // was "T_CTCS" {"TCTCS", MENU_T_CTCS}, // was "T_CTCS"
{"TxODir", MENU_SFT_D}, // was "SFT_D" {"TxODir", MENU_SFT_D}, // was "SFT_D"
{"TxOffs", MENU_OFFSET}, // was "OFFSET" {"TxOffs", MENU_OFFSET}, // was "OFFSET"
{"W/N", MENU_W_N}, {"WID", MENU_W_N},
{"SCR", MENU_SCR}, // was "SCR" {"SCR", MENU_SCR}, // was "SCR"
{"BusyL", MENU_BCL}, // was "BCL" {"BusyL", MENU_BCL}, // was "BCL"
{"COMP", MENU_COMPAND}, {"COMP", MENU_COMPAND},
{"Mod", MENU_AM}, // was "AM" {"Mod", MENU_AM}, // was "AM"
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
{"TXLck", MENU_TX_LOCK},
#endif #endif
{"ScAdd1", MENU_S_ADD1}, {"ScAdd1", MENU_S_ADD1},
{"ScAdd2", MENU_S_ADD2}, {"ScAdd2", MENU_S_ADD2},
@@ -80,7 +79,7 @@ const t_menu_item MenuList[] =
{"ML", MENU_MLONG}, {"ML", MENU_MLONG},
{"KeyLck", MENU_AUTOLK}, // was "AUTOLk" {"KeyLck", MENU_AUTOLK}, // was "AUTOLk"
{"TxTOut", MENU_TOT}, // was "TOT" {"TXTime", MENU_TOT},
{"BatSav", MENU_SAVE}, // was "SAVE" {"BatSav", MENU_SAVE}, // was "SAVE"
{"BatTxt", MENU_BAT_TXT}, {"BatTxt", MENU_BAT_TXT},
{"Mic", MENU_MIC}, {"Mic", MENU_MIC},
@@ -131,28 +130,15 @@ const t_menu_item MenuList[] =
{"RxMode", MENU_TDR}, {"RxMode", MENU_TDR},
{"Sql", MENU_SQL}, {"Sql", MENU_SQL},
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
{"SPwr", MENU_SET_PWR},
{"SPTT", MENU_SET_PTT}, {"SPTT", MENU_SET_PTT},
{"STOT", MENU_SET_TOT},
{"SEOT", MENU_SET_EOT},
{"SCtr", MENU_SET_CTR},
{"SInv", MENU_SET_INV}, {"SInv", MENU_SET_INV},
{"SLck", MENU_SET_LCK},
//{"SMet", MENU_SET_MET},
//{"SGUI", MENU_SET_GUI},
{"STmr", MENU_SET_TMR}, {"STmr", MENU_SET_TMR},
#ifdef ENABLE_FEAT_F4HWN_SLEEP #ifdef ENABLE_FEAT_F4HWN_SLEEP
{"SOff", MENU_SET_OFF}, {"SOff", MENU_SET_OFF},
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_NARROWER
{"SNFM", MENU_SET_NFM},
#endif
#ifdef ENABLE_FEAT_F4HWN_VOL #ifdef ENABLE_FEAT_F4HWN_VOL
{"SVol", MENU_SET_VOL}, {"SVol", MENU_SET_VOL},
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
{"SKey", MENU_SET_KEY },
#endif
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
{"SNWR", MENU_NOAA_S }, {"SNWR", MENU_NOAA_S },
#endif #endif
@@ -160,13 +146,6 @@ const t_menu_item MenuList[] =
// hidden menu items from here on // hidden menu items from here on
// enabled if pressing both the PTT and upper side button at power-on // enabled if pressing both the PTT and upper side button at power-on
{"F Lock", MENU_F_LOCK}, {"F Lock", MENU_F_LOCK},
#ifndef ENABLE_FEAT_F4HWN
{"Tx 200", MENU_200TX }, // was "200TX"
{"Tx 350", MENU_350TX }, // was "350TX"
{"Tx 500", MENU_500TX }, // was "500TX"
{"350 En", MENU_350EN }, // was "350EN"
#endif
//{"ScraEn", MENU_SCREN }, // was "SCREN"
#ifdef ENABLE_F_CAL_MENU #ifdef ENABLE_F_CAL_MENU
{"FrCali", MENU_F_CALI}, // reference xtal calibration {"FrCali", MENU_F_CALI}, // reference xtal calibration
#endif #endif
@@ -177,18 +156,15 @@ const t_menu_item MenuList[] =
{"", 0xff} // end of list - DO NOT delete or move this this {"", 0xff} // end of list - DO NOT delete or move this this
}; };
const uint8_t FIRST_HIDDEN_MENU_ITEM = MENU_F_LOCK; const char gSubMenu_TXP[][5] =
const char gSubMenu_TXP[][6] =
{ {
"USR", "<.02",
"L1", ".125",
"L2", ".25",
"L3", ".5",
"L4", "1",
"L5", "2",
"M", "5"
"H"
}; };
const char gSubMenu_SFT_D[][4] = const char gSubMenu_SFT_D[][4] =
@@ -198,10 +174,11 @@ const char gSubMenu_SFT_D[][4] =
"-" "-"
}; };
const char gSubMenu_W_N[][7] = const char gSubMenu_W_N[][5] =
{ {
"WIDE", "WIDE",
"NARR" "NARR",
"NAR+"
}; };
const char gSubMenu_OFF_ON[][4] = const char gSubMenu_OFF_ON[][4] =
@@ -219,8 +196,8 @@ const char *const gSubMenu_RXMode[] =
{ {
"MAIN", // TX and RX on main only "MAIN", // TX and RX on main only
"RESP", // Watch both and respond "RESP", // Watch both and respond
"XBAND ONLY", // TX on main, RX on secondary "XBAND", // TX on main, RX on secondary
"DUALMON" // always TX on main, but RX on both "DMON" // always TX on main, but RX on both
}; };
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
@@ -235,7 +212,7 @@ const char gSubMenu_VOICE[][4] =
const char *const gSubMenu_MDF[] = const char *const gSubMenu_MDF[] =
{ {
"FREQ", "FREQ",
"CHNUMB", "CHNUM",
"NAME", "NAME",
"NAME\n+\nFREQ" "NAME\n+\nFREQ"
}; };
@@ -319,85 +296,27 @@ const char gSubMenu_RX_TX[][6] =
"TX/RX" "TX/RX"
}; };
const char gSubMenu_BAT_TXT[][8] = const char gSubMenu_BAT_TXT[][5] =
{ {
"NONE", "NONE",
"VLT", "VLT",
"PRC" "PRC"
}; };
const char gSubMenu_BATTYP[][9] = const char gSubMenu_BATTYP[][3] =
{ {
"16", "16",
"22", "22",
"35" "35"
}; };
const char gSubMenu_SCRAMBLER[][7] =
{
"OFF",
"26K",
"27K",
"28K",
"29K",
"30K",
"31K",
"32K",
"33K",
"34K",
"35K"
};
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
const char gSubMenu_SET_PWR[][6] =
{
"<.02",
".125",
".25",
".5",
"1",
"2",
"5"
};
const char gSubMenu_SET_PTT[][8] = const char gSubMenu_SET_PTT[][4] =
{ {
"HOLD", "HOL",
"TAP" "TOG",
}; };
const char gSubMenu_SET_TOT[][7] = // Use by SET_EOT too
{
"OFF",
"SND",
"VIS",
"ALL"
};
const char gSubMenu_SET_LCK[][9] =
{
"KEY",
"KEY+PTT"
};
#ifdef ENABLE_FEAT_F4HWN_NARROWER
const char gSubMenu_SET_NFM[][9] =
{
"NRW",
"NRWER"
};
#endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
const char gSubMenu_SET_KEY[][9] =
{
"KEY_MENU",
"KEY_UP",
"KEY_DOWN",
"KEY_EXIT",
"KEY_STAR"
};
#endif
#endif #endif
const t_sidefunction gSubMenu_SIDEFUNCTIONS[] = const t_sidefunction gSubMenu_SIDEFUNCTIONS[] =
@@ -434,16 +353,11 @@ const t_sidefunction gSubMenu_SIDEFUNCTIONS[] =
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
{"RX MOD", ACTION_OPT_RXMODE}, {"RX MOD", ACTION_OPT_RXMODE},
{"MAIN ONLY", ACTION_OPT_MAINONLY},
{"PTT", ACTION_OPT_PTT}, {"PTT", ACTION_OPT_PTT},
{"WIDE\nNAR", ACTION_OPT_WN}, {"WIDE\nNAR", ACTION_OPT_WN},
#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO) #if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO)
{"MUTE", ACTION_OPT_MUTE}, {"MUTE", ACTION_OPT_MUTE},
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
{"POWER\nHIGH", ACTION_OPT_POWER_HIGH},
{"REMOVE\nOFFSET", ACTION_OPT_REMOVE_OFFSET},
#endif
#endif #endif
}; };
@@ -500,7 +414,7 @@ void UI_DisplayMenu(void) {
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
if (gMenuCursor > 0 || i > 0) if (gMenuCursor > 0 || i > 0)
if ((gMenuListCount - 1) != gMenuCursor || i != 2) if ((gMenuListCount - 1) != gMenuCursor || i != 2)
UI_PrintString(MenuList[gMenuCursor + i - 1].name, 0, 0, i * 2, 8); UI_PrintString(MenuList[gMenuCursor + i - 1].name, 0, 0, i * 2 /*, 8 */);
// invert the current menu list item pixels // invert the current menu list item pixels
for (i = 0; i < (8 * menu_list_width); i++) for (i = 0; i < (8 * menu_list_width); i++)
@@ -525,14 +439,17 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
#else #else
{ // new menu layout .. experimental & unfinished { // new menu layout .. experimental & unfinished
const int menu_index = gMenuCursor; // current selected menu item const int menu_index = gMenuCursor; // current selected menu item
i = 1; i = 0;
if (!gIsInSubMenu) { if (!gIsInSubMenu) {
while (i < 2) { // leading menu items - small text while (i < 2) { // leading menu items - small text
const int k = menu_index + i - 2; const int k = menu_index + i - 2;
if (k < 0) if (k < 0)
UI_PrintStringSmallNormal(MenuList[gMenuListCount + k].name, 0, 0, i); // wrap-a-round UI_PrintStringSmallNormal(MenuList[(gMenuListCount + k) % gMenuListCount].name, 0, 0,
else if (k >= 0 && k < (int) gMenuListCount) i); // wrap-around
else if (k >= (int) gMenuListCount)
UI_PrintStringSmallNormal(MenuList[k % gMenuListCount].name, 0, 0, i); // wrap-around
else
UI_PrintStringSmallNormal(MenuList[k].name, 0, 0, i); UI_PrintStringSmallNormal(MenuList[k].name, 0, 0, i);
i++; i++;
} }
@@ -546,10 +463,13 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
while (i < 5) { // trailing menu item - small text while (i < 5) { // trailing menu item - small text
const int k = menu_index + i - 2; const int k = menu_index + i - 2;
if (k >= 0 && k < (int) gMenuListCount) if (k < 0)
UI_PrintStringSmallNormal(MenuList[k].name, 0, 0, i); UI_PrintStringSmallNormal(MenuList[(gMenuListCount + k) % gMenuListCount].name, 0, 0,
i); // wrap-around
else if (k >= (int) gMenuListCount) else if (k >= (int) gMenuListCount)
UI_PrintStringSmallNormal(MenuList[gMenuListCount - k].name, 0, 0, i); // wrap-a-round UI_PrintStringSmallNormal(MenuList[k % gMenuListCount].name, 0, 0, i); // wrap-around
else
UI_PrintStringSmallNormal(MenuList[k].name, 0, 0, i);
i++; i++;
} }
@@ -560,7 +480,7 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
#endif #endif
} else if (menu_index >= 0 && menu_index < (int) gMenuListCount) { // current menu item } else if (menu_index >= 0 && menu_index < (int) gMenuListCount) { // current menu item
// strcat(String, ":"); // strcat(String, ":");
UI_PrintString(MenuList[menu_index].name, 0, 0, 0, 8); UI_PrintString(MenuList[menu_index].name, 0, 0, 0 /*, 8 */);
// UI_PrintStringSmallNormal(String, 0, 0, 0); // UI_PrintStringSmallNormal(String, 0, 0, 0);
} }
@@ -583,15 +503,9 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
BACKLIGHT_TurnOn(); BACKLIGHT_TurnOn();
#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO)
uint8_t gaugeLine = 0;
uint8_t gaugeMin = 0;
uint8_t gaugeMax = 0;
#endif
switch (UI_MENU_GetCurrentMenuId()) { switch (UI_MENU_GetCurrentMenuId()) {
case MENU_SQL: case MENU_SQL:
sprintf(String, "%d", gSubMenuSelection); sprintf(String, "%ld", gSubMenuSelection);
break; break;
case MENU_MIC: { // display the mic gain in actual dB rather than just an index number case MENU_MIC: { // display the mic gain in actual dB rather than just an index number
@@ -615,11 +529,7 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
} }
case MENU_TXP: case MENU_TXP:
if (gSubMenuSelection == 0) { sprintf(String, "%sW", gSubMenu_TXP[gSubMenuSelection]);
strcpy(String, gSubMenu_TXP[gSubMenuSelection]);
} else {
sprintf(String, "%s\n%sW", gSubMenu_TXP[gSubMenuSelection], gSubMenu_SET_PWR[gSubMenuSelection - 1]);
}
break; break;
case MENU_R_DCS: case MENU_R_DCS:
@@ -648,15 +558,15 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
case MENU_OFFSET: case MENU_OFFSET:
if (!gIsInSubMenu || gInputBoxIndex == 0) { if (!gIsInSubMenu || gInputBoxIndex == 0) {
sprintf(String, "%3d.%05u", gSubMenuSelection / 100000, abs(gSubMenuSelection) % 100000); sprintf(String, "%3ld.%05u", gSubMenuSelection / 100000, abs(gSubMenuSelection) % 100000);
UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8); UI_PrintString(String, menu_item_x1, menu_item_x2, 1 /*, 8 */);
} else { } else {
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_PrintString(String, menu_item_x1, menu_item_x2, 1, 8); UI_PrintString(String, menu_item_x1, menu_item_x2, 1 /*, 8 */);
} }
UI_PrintString("MHz", menu_item_x1, menu_item_x2, 3, 8); UI_PrintString("MHz", menu_item_x1, menu_item_x2, 3 /*, 8 */);
already_printed = true; already_printed = true;
break; break;
@@ -666,16 +576,17 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
break; break;
case MENU_SCR: case MENU_SCR:
strcpy(String, gSubMenu_SCRAMBLER[gSubMenuSelection]); if (gSubMenuSelection > 0) {
if (gSubMenuSelection > 0) sprintf(String, "%huHz\n%ld", inverse_scale_freq(gSubMenuSelection), gSubMenuSelection);
BK4819_EnableScramble(gSubMenuSelection - 1); } else {
else strcpy(String, "OFF");
BK4819_DisableScramble(); }
BK4819_SetScramble(gSubMenuSelection);
break; break;
case MENU_VOX: case MENU_VOX:
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
sprintf(String, gSubMenuSelection == 0 ? gSubMenu_OFF_ON[0] : "%u", gSubMenuSelection); sprintf(String, gSubMenuSelection == 0 ? gSubMenu_OFF_ON[0] : "%lu", gSubMenuSelection);
#else #else
strcpy(String, gSubMenu_NA); strcpy(String, gSubMenu_NA);
#endif #endif
@@ -685,13 +596,7 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
if (gSubMenuSelection == 0) { if (gSubMenuSelection == 0) {
strcpy(String, gSubMenu_OFF_ON[0]); strcpy(String, gSubMenu_OFF_ON[0]);
} else if (gSubMenuSelection < 61) { } else if (gSubMenuSelection < 61) {
sprintf(String, "%02dm:%02ds", (((gSubMenuSelection) * 5) / 60), (((gSubMenuSelection) * 5) % 60)); sprintf(String, "%02ldm:%02lds", (((gSubMenuSelection) * 5) / 60), (((gSubMenuSelection) * 5) % 60));
#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO)
//ST7565_Gauge(4, 1, 60, gSubMenuSelection);
gaugeLine = 4;
gaugeMin = 1;
gaugeMax = 60;
#endif
} else { } else {
strcpy(String, "ON"); strcpy(String, "ON");
} }
@@ -703,7 +608,7 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
case MENU_ABR_MIN: case MENU_ABR_MIN:
case MENU_ABR_MAX: case MENU_ABR_MAX:
sprintf(String, "%d", gSubMenuSelection); sprintf(String, "%ld", gSubMenuSelection);
if (gIsInSubMenu) if (gIsInSubMenu)
BACKLIGHT_SetBrightness(gSubMenuSelection); BACKLIGHT_SetBrightness(gSubMenuSelection);
// Obsolete ??? // Obsolete ???
@@ -715,22 +620,24 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
strcpy(String, gModulationStr[gSubMenuSelection]); strcpy(String, gModulationStr[gSubMenuSelection]);
break; break;
case MENU_TOT:
if (gSubMenuSelection == 0) {
strcpy(String, "OFF");
} else {
sprintf(String, "%02ldm:%02lds", (((gSubMenuSelection + 1) * 5) / 60), (((gSubMenuSelection + 1) * 5) % 60));
}
break;
case MENU_AUTOLK: case MENU_AUTOLK:
if (gSubMenuSelection == 0) if (gSubMenuSelection == 0)
strcpy(String, gSubMenu_OFF_ON[0]); strcpy(String, gSubMenu_OFF_ON[0]);
else { else {
sprintf(String, "%02dm:%02ds", ((gSubMenuSelection * 15) / 60), ((gSubMenuSelection * 15) % 60)); sprintf(String, "%02ldm:%02lds", ((gSubMenuSelection * 15) / 60), ((gSubMenuSelection * 15) % 60));
#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO)
//ST7565_Gauge(4, 1, 40, gSubMenuSelection);
gaugeLine = 4;
gaugeMin = 1;
gaugeMax = 40;
#endif
} }
break; break;
case MENU_FSKSRC: case MENU_FSKSRC:
sprintf(String, "%d", gSubMenuSelection); sprintf(String, "%ld", gSubMenuSelection);
break; break;
case MENU_COMPAND: case MENU_COMPAND:
@@ -757,13 +664,6 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
case MENU_NOAA_S: case MENU_NOAA_S:
#endif #endif
#ifndef ENABLE_FEAT_F4HWN
case MENU_350TX:
case MENU_200TX:
case MENU_500TX:
#endif
case MENU_350EN:
//case MENU_SCREN:
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
case MENU_SET_TMR: case MENU_SET_TMR:
#endif #endif
@@ -776,16 +676,16 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 0); const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 0);
UI_GenerateChannelStringEx(String, valid, gSubMenuSelection); UI_GenerateChannelStringEx(String, valid, gSubMenuSelection);
UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8); UI_PrintString(String, menu_item_x1, menu_item_x2, 0 /*, 8 */);
if (valid && !gAskForConfirmation) { // show the frequency so that the user knows the channels frequency if (valid && !gAskForConfirmation) { // show the frequency so that the user knows the channels frequency
const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection); const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection);
sprintf(String, "%u.%05u", frequency / 100000, frequency % 100000); sprintf(String, "%lu.%05lu", frequency / 100000, frequency % 100000);
UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8); UI_PrintString(String, menu_item_x1, menu_item_x2, 4 /*, 8 */);
} }
SETTINGS_FetchChannelName(String, gSubMenuSelection); SETTINGS_FetchChannelName(String, gSubMenuSelection);
UI_PrintString(String[0] ? String : "--", menu_item_x1, menu_item_x2, 2, 8); UI_PrintString(String[0] ? String : "--", menu_item_x1, menu_item_x2, 2 /*, 8 */);
already_printed = true; already_printed = true;
break; break;
} }
@@ -794,7 +694,7 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 0); const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 0);
UI_GenerateChannelStringEx(String, valid, gSubMenuSelection); UI_GenerateChannelStringEx(String, valid, gSubMenuSelection);
UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8); UI_PrintString(String, menu_item_x1, menu_item_x2, 0 /*, 8 */);
if (valid) { if (valid) {
const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection); const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection);
@@ -805,18 +705,18 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
if (edit_index < 0) { // show the channel name if (edit_index < 0) { // show the channel name
SETTINGS_FetchChannelName(String, gSubMenuSelection); SETTINGS_FetchChannelName(String, gSubMenuSelection);
char *pPrintStr = String[0] ? String : "--"; char *pPrintStr = String[0] ? String : "--";
UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 2, 8); UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 2 /*, 8 */);
} else { // show the channel name being edited } else { // show the channel name being edited
//UI_PrintString(edit, menu_item_x1, 0, 2, 8); //UI_PrintString(edit, menu_item_x1, 0, 2 /*, 8 */);
UI_PrintString(edit, menu_item_x1, menu_item_x2, 2, 8); UI_PrintString(edit, menu_item_x1, menu_item_x2, 2 /*, 8 */);
if (edit_index < 10) if (edit_index < 10)
//UI_PrintString("^", menu_item_x1 + (8 * edit_index), 0, 4, 8); // show the cursor //UI_PrintString("^", menu_item_x1 + (8 * edit_index), 0, 4 /*, 8 */); // show the cursor
UI_PrintString("^", menu_item_x1 - 1 + (8 * edit_index), 0, 4, 8); // show the cursor UI_PrintString("^", menu_item_x1 - 1 + (8 * edit_index), 0, 4 /*, 8 */); // show the cursor
} }
if (!gAskForConfirmation) { // show the frequency so that the user knows the channels frequency if (!gAskForConfirmation) { // show the frequency so that the user knows the channels frequency
sprintf(String, "%u.%05u", frequency / 100000, frequency % 100000); sprintf(String, "%lu.%05lu", frequency / 100000, frequency % 100000);
UI_PrintString(String, menu_item_x1, menu_item_x2, 4 + (gIsInSubMenu && edit_index >= 0), 8); UI_PrintString(String, menu_item_x1, menu_item_x2, 4 + (gIsInSubMenu && edit_index >= 0) /*, 8 */);
} }
} }
@@ -825,23 +725,13 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
} }
case MENU_SAVE: case MENU_SAVE:
sprintf(String, gSubMenuSelection == 0 ? gSubMenu_OFF_ON[0] : "1:%u", gSubMenuSelection); sprintf(String, gSubMenuSelection == 0 ? gSubMenu_OFF_ON[0] : "1:%ld", gSubMenuSelection);
break; break;
case MENU_TDR: case MENU_TDR:
strcpy(String, gSubMenu_RXMode[gSubMenuSelection]); strcpy(String, gSubMenu_RXMode[gSubMenuSelection]);
break; break;
case MENU_TOT:
sprintf(String, "%02dm:%02ds", (((gSubMenuSelection + 1) * 5) / 60), (((gSubMenuSelection + 1) * 5) % 60));
#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO)
//ST7565_Gauge(4, 5, 179, gSubMenuSelection);
gaugeLine = 4;
gaugeMin = 5;
gaugeMax = 179;
#endif
break;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
case MENU_VOICE: case MENU_VOICE:
strcpy(String, gSubMenu_VOICE[gSubMenuSelection]); strcpy(String, gSubMenu_VOICE[gSubMenuSelection]);
@@ -852,22 +742,16 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
if (gSubMenuSelection == 0) { if (gSubMenuSelection == 0) {
strcpy(String, "STOP"); strcpy(String, "STOP");
} else if (gSubMenuSelection < 81) { } else if (gSubMenuSelection < 81) {
sprintf(String, "CARRIER\n%02ds:%03dms", ((gSubMenuSelection * 250) / 1000), sprintf(String, "CARRIER\n%02lds:%03ldms", ((gSubMenuSelection * 250) / 1000),
((gSubMenuSelection * 250) % 1000)); ((gSubMenuSelection * 250) % 1000));
#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO) #if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO)
//ST7565_Gauge(5, 1, 80, gSubMenuSelection); //ST7565_Gauge(5, 1, 80, gSubMenuSelection);
gaugeLine = 5;
gaugeMin = 1;
gaugeMax = 80;
#endif #endif
} else { } else {
sprintf(String, "TIMEOUT\n%02dm:%02ds", (((gSubMenuSelection - 80) * 5) / 60), sprintf(String, "TIMEOUT\n%02ldm:%02lds", (((gSubMenuSelection - 80) * 5) / 60),
(((gSubMenuSelection - 80) * 5) % 60)); (((gSubMenuSelection - 80) * 5) % 60));
#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO) #if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO)
//ST7565_Gauge(5, 80, 104, gSubMenuSelection); //ST7565_Gauge(5, 80, 104, gSubMenuSelection);
gaugeLine = 5;
gaugeMin = 80;
gaugeMax = 104;
#endif #endif
} }
break; break;
@@ -877,14 +761,14 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
break; break;
case MENU_RP_STE: case MENU_RP_STE:
sprintf(String, gSubMenuSelection == 0 ? gSubMenu_OFF_ON[0] : "%u*100ms", gSubMenuSelection); sprintf(String, gSubMenuSelection == 0 ? gSubMenu_OFF_ON[0] : "%lu*100ms", gSubMenuSelection);
break; break;
case MENU_S_LIST: case MENU_S_LIST:
if (gSubMenuSelection == 0) if (gSubMenuSelection == 0)
strcpy(String, "LIST [0]\nNO LIST"); strcpy(String, "LIST [0]\nNO LIST");
else if (gSubMenuSelection < 4) else if (gSubMenuSelection < 4)
sprintf(String, "LIST [%u]", gSubMenuSelection); sprintf(String, "LIST [%lu]", gSubMenuSelection);
else if (gSubMenuSelection == 4) else if (gSubMenuSelection == 4)
strcpy(String, "LISTS\n[1, 2, 3]"); strcpy(String, "LISTS\n[1, 2, 3]");
else if (gSubMenuSelection == 5) else if (gSubMenuSelection == 5)
@@ -916,11 +800,11 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
break; break;
case MENU_D_HOLD: case MENU_D_HOLD:
sprintf(String, "%ds", gSubMenuSelection); sprintf(String, "%lds", gSubMenuSelection);
break; break;
#endif #endif
case MENU_D_PRE: case MENU_D_PRE:
sprintf(String, "%d*10ms", gSubMenuSelection); sprintf(String, "%ld*10ms", gSubMenuSelection);
break; break;
case MENU_PTT_ID: case MENU_PTT_ID:
@@ -958,22 +842,22 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
break; break;
#ifdef ENABLE_F_CAL_MENU #ifdef ENABLE_F_CAL_MENU
case MENU_F_CALI: { case MENU_F_CALI: {
const uint32_t value = 22656 + gSubMenuSelection; const uint32_t value = 22656 + gSubMenuSelection;
const uint32_t xtal_Hz = (0x4f0000u + value) * 5; const uint32_t xtal_Hz = (0x4f0000u + value) * 5;
writeXtalFreqCal(gSubMenuSelection, false); writeXtalFreqCal(gSubMenuSelection, false);
sprintf(String, "%d\n%u.%06u\nMHz", sprintf(String, "%ld\n%lu.%06lu\nMHz",
gSubMenuSelection, gSubMenuSelection,
xtal_Hz / 1000000, xtal_Hz % 1000000); xtal_Hz / 1000000, xtal_Hz % 1000000);
} }
break; break;
#endif #endif
case MENU_BATCAL: { case MENU_BATCAL: {
const uint16_t vol = (uint32_t) gBatteryVoltageAverage * gBatteryCalibration[3] / gSubMenuSelection; const uint16_t vol = (uint32_t) gBatteryVoltageAverage * gBatteryCalibration[3] / gSubMenuSelection;
sprintf(String, "%u.%02uV\n%u", vol / 100, vol % 100, gSubMenuSelection); sprintf(String, "%u.%02dV\n%lu", vol / 100, vol % 100, gSubMenuSelection);
break; break;
} }
@@ -994,41 +878,16 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
if (gSubMenuSelection == 0) { if (gSubMenuSelection == 0) {
strcpy(String, gSubMenu_OFF_ON[0]); strcpy(String, gSubMenu_OFF_ON[0]);
} else if (gSubMenuSelection < 121) { } else if (gSubMenuSelection < 121) {
sprintf(String, "%dh:%02dm", (gSubMenuSelection / 60), (gSubMenuSelection % 60)); sprintf(String, "%ldh:%02ldm", (gSubMenuSelection / 60), (gSubMenuSelection % 60));
#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO)
//ST7565_Gauge(4, 1, 120, gSubMenuSelection);
gaugeLine = 4;
gaugeMin = 1;
gaugeMax = 120;
#endif
} }
break; break;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
case MENU_SET_PWR:
sprintf(String, "%s\n%sW", gSubMenu_TXP[gSubMenuSelection + 1], gSubMenu_SET_PWR[gSubMenuSelection]);
break;
case MENU_SET_PTT: case MENU_SET_PTT:
strcpy(String, gSubMenu_SET_PTT[gSubMenuSelection]); strcpy(String, gSubMenu_SET_PTT[gSubMenuSelection]);
break; break;
case MENU_SET_TOT:
case MENU_SET_EOT:
strcpy(String, gSubMenu_SET_TOT[gSubMenuSelection]); // Same as SET_TOT
break;
case MENU_SET_CTR:
#ifdef ENABLE_FEAT_F4HWN_CTR
sprintf(String, "%d", gSubMenuSelection);
gSetting_set_ctr = gSubMenuSelection;
ST7565_ContrastAndInv();
#else
strcpy(String, gSubMenu_NA);
#endif
break;
case MENU_SET_INV: case MENU_SET_INV:
#ifdef ENABLE_FEAT_F4HWN_INV #ifdef ENABLE_FEAT_F4HWN_INV
strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]); strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]);
@@ -1038,65 +897,32 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
#endif #endif
break; break;
case MENU_TX_LOCK:
if (TX_freq_check(gEeprom.VfoInfo[gEeprom.TX_VFO].pRX->Frequency) == 0) {
strcpy(String, "Inside\nF Lock\nPlan");
} else {
strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]);
}
break;
case MENU_SET_LCK:
strcpy(String, gSubMenu_SET_LCK[gSubMenuSelection]);
break;
//case MENU_SET_MET:
//case MENU_SET_GUI:
strcpy(String, gSubMenu_SET_MET[gSubMenuSelection]); // Same as SET_MET
break;
#ifdef ENABLE_FEAT_F4HWN_NARROWER
case MENU_SET_NFM:
strcpy(String, gSubMenu_SET_NFM[gSubMenuSelection]);
break;
#endif
#ifdef ENABLE_FEAT_F4HWN_VOL #ifdef ENABLE_FEAT_F4HWN_VOL
case MENU_SET_VOL: case MENU_SET_VOL:
if (gSubMenuSelection == 0) { if (gSubMenuSelection == 0) {
strcpy(String, gSubMenu_OFF_ON[0]); strcpy(String, gSubMenu_OFF_ON[0]);
} else if (gSubMenuSelection < 64) { } else if (gSubMenuSelection < 64) {
sprintf(String, "%02u", gSubMenuSelection); sprintf(String, "%02lu", gSubMenuSelection);
#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO) #if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO)
//ST7565_Gauge(4, 1, 63, gSubMenuSelection);
gaugeLine = 4;
gaugeMin = 1;
gaugeMax = 63;
#endif #endif
} }
gEeprom.VOLUME_GAIN = gSubMenuSelection; gEeprom.VOLUME_GAIN = gSubMenuSelection;
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)
break;
#endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
case MENU_SET_KEY:
strcpy(String, gSubMenu_SET_KEY[gSubMenuSelection]);
break; break;
#endif #endif
#endif #endif
} }
#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO) //#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO)
if (gaugeLine != 0) { // if (gaugeLine != 0) {
ST7565_Gauge(gaugeLine, gaugeMin, gaugeMax, gSubMenuSelection); // ST7565_Gauge(gaugeLine, gaugeMin, gaugeMax, gSubMenuSelection);
} // }
#endif //#endif
if (!already_printed) { // we now do multi-line text in a single string if (!already_printed) { // we now do multi-line text in a single string
@@ -1135,7 +961,7 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
if (small) if (small)
UI_PrintStringSmallNormal(String + i, menu_item_x1, menu_item_x2, y); UI_PrintStringSmallNormal(String + i, menu_item_x1, menu_item_x2, y);
else else
UI_PrintString(String + i, menu_item_x1, menu_item_x2, y, 8); UI_PrintString(String + i, menu_item_x1, menu_item_x2, y /*, 8 */);
// look for start of next line // look for start of next line
while (i < len && String[i] >= 32) while (i < len && String[i] >= 32)
@@ -1164,25 +990,25 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
} }
// channel number // channel number
UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 0, 8); UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 0 /*, 8 */);
SETTINGS_FetchChannelName(String, gSubMenuSelection); SETTINGS_FetchChannelName(String, gSubMenuSelection);
pPrintStr = String[0] ? String : "--"; pPrintStr = String[0] ? String : "--";
// channel name and scan-list // channel name and scan-list
if (gSubMenuSelection < 0 || !gEeprom.SCAN_LIST_ENABLED[i]) { if (gSubMenuSelection < 0 || !gEeprom.SCAN_LIST_ENABLED[i]) {
UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 2, 8); UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 2 /*, 8 */);
} else { } else {
/* /*
UI_PrintStringSmallNormal(pPrintStr, menu_item_x1, menu_item_x2, 2); UI_PrintStringSmallNormal(pPrintStr, menu_item_x1, menu_item_x2, 2);
if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH1[i])) { if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH1[i])) {
sprintf(String, "PRI%d:%u", 1, gEeprom.SCANLIST_PRIORITY_CH1[i] + 1); sprintf(String, "PRI%ld:%u", 1, gEeprom.SCANLIST_PRIORITY_CH1[i] + 1);
UI_PrintString(String, menu_item_x1, menu_item_x2, 3, 8); UI_PrintString(String, menu_item_x1, menu_item_x2, 3 , 8);
} }
if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH2[i])) { if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH2[i])) {
sprintf(String, "PRI%d:%u", 2, gEeprom.SCANLIST_PRIORITY_CH2[i] + 1); sprintf(String, "PRI%ld:%u", 2, gEeprom.SCANLIST_PRIORITY_CH2[i] + 1);
UI_PrintString(String, menu_item_x1, menu_item_x2, 5, 8); UI_PrintString(String, menu_item_x1, menu_item_x2, 5, 8);
} }
*/ */
@@ -1194,7 +1020,7 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
if (IS_MR_CHANNEL(channel)) { if (IS_MR_CHANNEL(channel)) {
sprintf(String, "PRI%d:%u", pri, channel + 1); sprintf(String, "PRI%d:%u", pri, channel + 1);
UI_PrintString(String, menu_item_x1, menu_item_x2, pri * 2 + 1, 8); UI_PrintString(String, menu_item_x1, menu_item_x2, pri * 2 + 1 /*, 8 */);
} }
} }
@@ -1202,14 +1028,14 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
} }
if ((UI_MENU_GetCurrentMenuId() == MENU_R_CTCS || UI_MENU_GetCurrentMenuId() == MENU_R_DCS) && gCssBackgroundScan) if ((UI_MENU_GetCurrentMenuId() == MENU_R_CTCS || UI_MENU_GetCurrentMenuId() == MENU_R_DCS) && gCssBackgroundScan)
UI_PrintString("SCAN", menu_item_x1, menu_item_x2, 4, 8); UI_PrintString("SCAN", menu_item_x1, menu_item_x2, 4 /*, 8 */);
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
if (UI_MENU_GetCurrentMenuId() == MENU_D_LIST && gIsDtmfContactValid) { if (UI_MENU_GetCurrentMenuId() == MENU_D_LIST && gIsDtmfContactValid) {
Contact[11] = 0; Contact[11] = 0;
memcpy(&gDTMF_ID, Contact + 8, 4); memcpy(&gDTMF_ID, Contact + 8, 4);
sprintf(String, "ID:%4s", gDTMF_ID); sprintf(String, "ID:%4s", gDTMF_ID);
UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8); UI_PrintString(String, menu_item_x1, menu_item_x2, 4 /*, 8 */);
} }
#endif #endif
@@ -1221,7 +1047,7 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
|| UI_MENU_GetCurrentMenuId() == MENU_D_LIST || UI_MENU_GetCurrentMenuId() == MENU_D_LIST
#endif #endif
) { ) {
sprintf(String, "%2d", gSubMenuSelection); sprintf(String, "%2ld", gSubMenuSelection);
UI_PrintStringSmallNormal(String, 105, 0, 0); UI_PrintStringSmallNormal(String, 105, 0, 0);
} }
@@ -1230,7 +1056,7 @@ UI_PrintStringSmallNormal(String, 2, 0, 6);
UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME || UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME ||
UI_MENU_GetCurrentMenuId() == MENU_DEL_CH) && gAskForConfirmation) { // display confirmation UI_MENU_GetCurrentMenuId() == MENU_DEL_CH) && gAskForConfirmation) { // display confirmation
char *pPrintStr = (gAskForConfirmation == 1) ? "SURE?" : "WAIT!"; char *pPrintStr = (gAskForConfirmation == 1) ? "SURE?" : "WAIT!";
UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 5, 8); UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 5 /*, 8 */);
} }
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();

View File

@@ -42,9 +42,6 @@ enum {
MENU_W_N, MENU_W_N,
MENU_SCR, MENU_SCR,
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,
@@ -110,13 +107,6 @@ enum {
#endif #endif
MENU_RESET, MENU_RESET,
MENU_F_LOCK, MENU_F_LOCK,
#ifndef ENABLE_FEAT_F4HWN
MENU_200TX,
MENU_350TX,
MENU_500TX,
MENU_SCREN,
#endif
MENU_350EN,
#ifdef ENABLE_F_CAL_MENU #ifdef ENABLE_F_CAL_MENU
MENU_F_CALI, // reference xtal calibration MENU_F_CALI, // reference xtal calibration
#endif #endif
@@ -124,25 +114,12 @@ 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
MENU_SET_NFM,
#endif
#ifdef ENABLE_FEAT_F4HWN_VOL #ifdef ENABLE_FEAT_F4HWN_VOL
MENU_SET_VOL, MENU_SET_VOL,
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
MENU_SET_KEY,
#endif
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
MENU_NOAA_S, MENU_NOAA_S,
#endif #endif
@@ -156,15 +133,13 @@ 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
@@ -179,17 +154,7 @@ 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];
@@ -198,10 +163,8 @@ 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];
extern const char gSubMenu_SCRAMBLER[11][7];
typedef struct { typedef struct {
char *name; char *name;

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] = "";
@@ -227,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;
@@ -239,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;
@@ -282,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

@@ -35,8 +35,7 @@ void UI_DisplayReleaseKeys(void) {
#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();