Merge remote-tracking branch 'remotes/OneOfEleven/main'

This commit is contained in:
Krzysiek Egzmont
2023-10-05 15:01:31 +02:00
20 changed files with 960 additions and 785 deletions

View File

@@ -3,6 +3,7 @@
# 0 = disable
# 1 = enable
#
ENABLE_CLANG := 0
ENABLE_SWD := 0
ENABLE_OVERLAY := 0
ENABLE_LTO := 1
@@ -21,27 +22,31 @@ ENABLE_WIDE_RX := 1
ENABLE_TX_WHEN_AM := 0
ENABLE_F_CAL_MENU := 0
ENABLE_CTCSS_TAIL_PHASE_SHIFT := 1
ENABLE_MAIN_KEY_HOLD := 1
ENABLE_BOOT_BEEPS := 0
ENABLE_SHOW_CHARGE_LEVEL := 1
ENABLE_REVERSE_BAT_SYMBOL := 1
ENABLE_CODE_SCAN_TIMEOUT := 0
ENABLE_AM_FIX := 1
ENABLE_AM_FIX_SHOW_DATA := 0
ENABLE_SQUELCH_LOWER := 0
ENABLE_FASTER_CHANNEL_SCAN := 1
ENABLE_SQUELCH_MORE_SENSITIVE := 1
#ENABLE_FASTER_CHANNEL_SCAN := 0
ENABLE_RSSI_BAR := 1
ENABLE_AUDIO_BAR := 1
ENABLE_COPY_CHAN_TO_VFO := 1
#ENABLE_SINGLE_VFO_CHAN := 1
ENABLE_SPECTRUM := 1
#ENABLE_SINGLE_VFO_CHAN := 1
#ENABLE_BAND_SCOPE := 1
#############################################################
TARGET = firmware
ifeq ($(ENABLE_LTO), 1)
ifeq ($(ENABLE_CLANG),1)
# GCC's linker, ld, doesn't understand LLVM's generated bytecode
ENABLE_LTO := 0
endif
ifeq ($(ENABLE_LTO),1)
# can't have LTO and OVERLAY enabled at same time
ENABLE_OVERLAY := 0
endif
@@ -149,8 +154,20 @@ else
endif
AS = arm-none-eabi-gcc
CC = arm-none-eabi-gcc
CC =
LD = arm-none-eabi-gcc
ifeq ($(ENABLE_CLANG),0)
CC += arm-none-eabi-gcc
# Use GCC's linker to avoid undefined symbol errors
# LD += arm-none-eabi-gcc
else
# May need to adjust this to match your system
CC += clang --sysroot=/usr/arm-none-eabi --target=arm-none-eabi
# Bloats binaries to 512MB
# LD = ld.lld
endif
OBJCOPY = arm-none-eabi-objcopy
SIZE = arm-none-eabi-size
@@ -166,13 +183,18 @@ ifeq ($(ENABLE_OVERLAY),1)
ASFLAGS += -DENABLE_OVERLAY
endif
CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD
#CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c99 -MMD
#CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=gnu99 -MMD
#CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=gnu11 -MMD
CFLAGS =
ifeq ($(ENABLE_CLANG),0)
CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD
# CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c99 -MMD
# CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=gnu99 -MMD
# CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=gnu11 -MMD
else
# Oz needed to make it fit on flash
CFLAGS += -Oz -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD
endif
ifeq ($(ENABLE_LTO), 1)
# CFLAGS += -flto
ifeq ($(ENABLE_LTO),1)
CFLAGS += -flto=2
else
# We get most of the space savings if LTO creates problems
@@ -239,9 +261,6 @@ endif
ifeq ($(ENABLE_CTCSS_TAIL_PHASE_SHIFT),1)
CFLAGS += -DENABLE_CTCSS_TAIL_PHASE_SHIFT
endif
ifeq ($(ENABLE_MAIN_KEY_HOLD),1)
CFLAGS += -DENABLE_MAIN_KEY_HOLD
endif
ifeq ($(ENABLE_BOOT_BEEPS),1)
CFLAGS += -DENABLE_BOOT_BEEPS
endif
@@ -288,12 +307,18 @@ ifeq ($(ENABLE_BAND_SCOPE),1)
CFLAGS += -DENABLE_BAND_SCOPE
endif
LDFLAGS = -mcpu=cortex-m0 -nostartfiles -Wl,-T,firmware.ld
LDFLAGS =
ifeq ($(ENABLE_CLANG),0)
LDFLAGS += -mcpu=cortex-m0 -nostartfiles -Wl,-T,firmware.ld
else
# Fix warning about implied executable stack
LDFLAGS += -z noexecstack -mcpu=cortex-m0 -nostartfiles -Wl,-T,firmware.ld
endif
# Use newlib-nano instead of newlib
LDFLAGS += --specs=nano.specs
ifeq ($(ENABLE_LTO), 0)
ifeq ($(ENABLE_LTO),0)
# Throw away unneeded func/data sections like LTO does
LDFLAGS += -Wl,--gc-sections
endif

View File

@@ -50,6 +50,7 @@ You can customize the firmware by enabling/disabling various compile options.
You'll find the options at the top of "Makefile" ('0' = disable, '1' = enable) ..
```
ENABLE_CLANG := 0 experimental, builds with clang instead of gcc (LTO will be disabled if you enable this)
ENABLE_SWD := 0 only needed if using CPU's SWD port (debugging/programming)
ENABLE_OVERLAY := 0 cpu FLASH stuff, not needed
ENABLE_LTO := 0 **experimental, reduces size of compiled firmware but might break EEPROM reads (overlay will be disabled if you enable this)
@@ -68,7 +69,6 @@ ENABLE_WIDE_RX := 1 full 18MHz to 1300MHz RX (though front-
ENABLE_TX_WHEN_AM := 0 allow TX (always FM) when RX is set to AM
ENABLE_F_CAL_MENU := 0 enable/disable the radios hidden frequency calibration menu
ENABLE_CTCSS_TAIL_PHASE_SHIFT := 1 standard CTCSS tail phase shift rather than QS's own 55Hz tone method
ENABLE_MAIN_KEY_HOLD := 1 initial F-key press not needed, instead just hold down keys 0-9 to access the secondary butt functions
ENABLE_BOOT_BEEPS := 0 gives user audio feedback on volume knob position at boot-up
ENABLE_SHOW_CHARGE_LEVEL := 0 show the charge level when the radio is on charge
ENABLE_REVERSE_BAT_SYMBOL := 1 mirror the battery symbol on the status bar (+ pole on the right)
@@ -76,7 +76,7 @@ ENABLE_CODE_SCAN_TIMEOUT := 0 enable/disable 32-sec CTCSS/DCS scan ti
ENABLE_AM_FIX := 1 dynamically adjust the front end gains when in AM mode to helo prevent AM demodulator saturation, ignore the on-screen RSSI level (for now)
ENABLE_AM_FIX_SHOW_DATA := 1 show debug data for the AM fix (still tweaking it)
ENABLE_SQUELCH_MORE_SENSITIVE := 0 make squelch levels a little bit more sensitive - I plan to let user adjust the values themselves
ENABLE_FASTER_CHANNEL_SCAN := 0 increases the channel scan speed, but the squelch is also made more twitchy
#ENABLE_FASTER_CHANNEL_SCAN := 0 don't use (for now) .. increases the channel scan speed, but the squelch is also made more twitchy
ENABLE_RSSI_BAR := 1 enable a dBm/Sn RSSI bar graph level inplace of the little antenna symbols
ENABLE_AUDIO_BAR := 0 experimental, display an audo bar level when TX'ing
ENABLE_COPY_CHAN_TO_VFO := 1 copy current channel into the other VFO. Long press Menu key ('M')
@@ -86,9 +86,13 @@ ENABLE_COPY_CHAN_TO_VFO := 1 copy current channel into the other VFO
# New/modified function keys
* Long-press 'M' = Copy selected channel into the same VFO, then switches to frequency mode
* Long-press '5' = Toggle a selected channels scanlist setting .. if NOAA is disable in Makefile
* Long-press '*' = Toggles the scanlist number 1, 2 or ALL channels .. if in channel scan mode
* Long-press 'M' .. Copy selected channel into same VFO, then switch VFO to frequency mode
*
* Long-press '7' .. Toggle selected channel scanlist setting .. if VOX is disabled in Makefile
* or
* Long-press '5' .. Toggle selected channel scanlist setting .. if NOAA is disabled in Makefile
*
* Long-press '*' .. Start scanning, then toggles scanlist scan 1, 2 or ALL channel scanning
# Some changes made from the Quansheng firmware
@@ -109,6 +113,9 @@ arm-none-eabi GCC version 10.3.1 is recommended, which is the current version on
Other versions may generate a flash file that is too big.
You can get an appropriate version from: https://developer.arm.com/downloads/-/gnu-rm
clang may be used but isn't fully supported. Resulting binaries may also be bigger.
You can get it from: https://releases.llvm.org/download.html
# Building
To build the firmware, you need to fetch the submodules and then run make:
@@ -123,10 +130,10 @@ To compile directly in windows without the need of a linux virtual machine:
1. Download and install "gcc-arm-none-eabi-10.3-2021.10-win32.exe" from https://developer.arm.com/downloads/-/gnu-rm
2. Download and install "gnu_make-3.81.exe" from https://gnuwin32.sourceforge.net/packages/make.htm
3. You may (or not) need to manualy add gcc path to you OS environment PATH.
3. You may need to (I didn't) manualy add gcc path to your OS environment PATH.
ie add C:\Program Files (x86)\GNU Arm Embedded Toolchain\10 2021.10\bin
4. You may (or not) need to reboot your PC after installing the above
4. You may need to reboot your PC after installing the above
```
Then you can run 'win_make.bat' from the directory you saved this source code too.

View File

@@ -206,7 +206,7 @@ void ACTION_Scan(bool bRestart)
#endif
// clear the other vfo's rssi level (to hide the antenna symbol)
gVFO_RSSI_bar_level[(gEeprom.RX_CHANNEL + 1) & 1u] = 0;
gVFO_RSSI_bar_level[(gEeprom.RX_VFO + 1) & 1u] = 0;
// let the user see DW is not active
gDualWatchActive = false;

View File

@@ -122,7 +122,7 @@ static void APP_CheckForIncoming(void)
FUNCTION_Select(FUNCTION_INCOMING);
//gUpdateDisplay = true;
updateRSSI(gEeprom.RX_CHANNEL);
updateRSSI(gEeprom.RX_VFO);
gUpdateRSSI = true;
}
@@ -138,7 +138,7 @@ static void APP_CheckForIncoming(void)
FUNCTION_Select(FUNCTION_INCOMING);
//gUpdateDisplay = true;
updateRSSI(gEeprom.RX_CHANNEL);
updateRSSI(gEeprom.RX_VFO);
gUpdateRSSI = true;
}
return;
@@ -152,7 +152,7 @@ static void APP_CheckForIncoming(void)
gUpdateStatus = true;
}
else
{
{ // RF scanning
if (gRxReceptionMode != RX_MODE_NONE)
{
if (gCurrentFunction != FUNCTION_INCOMING)
@@ -160,10 +160,9 @@ static void APP_CheckForIncoming(void)
FUNCTION_Select(FUNCTION_INCOMING);
//gUpdateDisplay = true;
updateRSSI(gEeprom.RX_CHANNEL);
updateRSSI(gEeprom.RX_VFO);
gUpdateRSSI = true;
}
return;
}
@@ -178,7 +177,7 @@ static void APP_CheckForIncoming(void)
FUNCTION_Select(FUNCTION_INCOMING);
//gUpdateDisplay = true;
updateRSSI(gEeprom.RX_CHANNEL);
updateRSSI(gEeprom.RX_VFO);
gUpdateRSSI = true;
}
}
@@ -468,7 +467,7 @@ static void APP_HandleFunction(void)
void APP_StartListening(FUNCTION_Type_t Function, const bool reset_am_fix)
{
const unsigned int chan = gEeprom.RX_CHANNEL;
const unsigned int chan = gEeprom.RX_VFO;
// const unsigned int chan = gRxVfo->CHANNEL_SAVE;
if (gSetting_KILLED)
@@ -639,12 +638,12 @@ static void FREQ_NextChannel(void)
static void MR_NextChannel(void)
{
static int prev_mr_chan = 0;
const bool enabled = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCAN_LIST_ENABLED[gEeprom.SCAN_LIST_DEFAULT] : true;
const int chan1 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH1[gEeprom.SCAN_LIST_DEFAULT] : -1;
const int chan2 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH2[gEeprom.SCAN_LIST_DEFAULT] : -1;
const int prev_chan = gNextMrChannel;
int chan = 0;
static unsigned int prev_mr_chan = 0;
const bool enabled = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCAN_LIST_ENABLED[gEeprom.SCAN_LIST_DEFAULT] : true;
const int chan1 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH1[gEeprom.SCAN_LIST_DEFAULT] : -1;
const int chan2 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH2[gEeprom.SCAN_LIST_DEFAULT] : -1;
const unsigned int prev_chan = gNextMrChannel;
unsigned int chan = 0;
if (enabled)
{
@@ -657,7 +656,7 @@ static void MR_NextChannel(void)
{
if (RADIO_CheckValidChannel(chan1, false, 0))
{
//gCurrentScanList = SCAN_NEXT_CHAN_SCANLIST1;
gCurrentScanList = SCAN_NEXT_CHAN_SCANLIST1;
gNextMrChannel = chan1;
break;
}
@@ -674,31 +673,31 @@ static void MR_NextChannel(void)
}
}
// this bit doesn't work at all - yet :(
// this bit doesn't yet work if the other VFO is a frequency
case SCAN_NEXT_CHAN_DUAL_WATCH:
// dual watch is enabled - include the other VFO in the scan
// if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
{
// chan = (gEeprom.RX_CHANNEL + 1) & 1u;
// {
// chan = (gEeprom.RX_VFO + 1) & 1u;
// chan = gEeprom.ScreenChannel[chan];
// chan = 14;
// if (RADIO_CheckValidChannel(chan, false, 0))
// if (IS_MR_CHANNEL(chan))
// {
// gCurrentScanList = SCAN_NEXT_CHAN_DUAL_WATCH;
// gNextMrChannel = chan;
// break;
// }
}
// }
default:
case SCAN_NEXT_CHAN_MR:
gCurrentScanList = SCAN_NEXT_CHAN_MR;
gNextMrChannel = prev_mr_chan;
chan = 0xffffffff;
chan = 0xff;
break;
}
}
if (!enabled || chan == 0xffffffff)
if (!enabled || chan == 0xff)
{
chan = RADIO_FindNextChannel(gNextMrChannel + gScanState, gScanState, (gEeprom.SCAN_LIST_DEFAULT < 2) ? true : false, gEeprom.SCAN_LIST_DEFAULT);
if (chan == 0xFF)
@@ -711,12 +710,12 @@ static void MR_NextChannel(void)
gNextMrChannel = chan;
}
if (prev_chan != gNextMrChannel)
if (gNextMrChannel != prev_chan)
{
gEeprom.MrChannel[gEeprom.RX_CHANNEL] = gNextMrChannel;
gEeprom.ScreenChannel[gEeprom.RX_CHANNEL] = gNextMrChannel;
gEeprom.MrChannel[ gEeprom.RX_VFO] = gNextMrChannel;
gEeprom.ScreenChannel[gEeprom.RX_VFO] = gNextMrChannel;
RADIO_ConfigureChannel(gEeprom.RX_CHANNEL, VFO_CONFIGURE_RELOAD);
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
RADIO_SetupRegisters(true);
gUpdateDisplay = true;
@@ -749,11 +748,11 @@ static void DUALWATCH_Alternate(void)
if (gIsNoaaMode)
{
if (IS_NOT_NOAA_CHANNEL(gEeprom.ScreenChannel[0]) || IS_NOT_NOAA_CHANNEL(gEeprom.ScreenChannel[1]))
gEeprom.RX_CHANNEL = (gEeprom.RX_CHANNEL + 1) & 1;
gEeprom.RX_VFO = (gEeprom.RX_VFO + 1) & 1;
else
gEeprom.RX_CHANNEL = 0;
gEeprom.RX_VFO = 0;
gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_CHANNEL];
gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO];
if (gEeprom.VfoInfo[0].CHANNEL_SAVE >= NOAA_CHANNEL_FIRST)
NOAA_IncreaseChannel();
@@ -761,8 +760,8 @@ static void DUALWATCH_Alternate(void)
else
#endif
{ // toggle between VFO's
gEeprom.RX_CHANNEL = (gEeprom.RX_CHANNEL + 1) & 1;
gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_CHANNEL];
gEeprom.RX_VFO = (gEeprom.RX_VFO + 1) & 1;
gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO];
if (!gDualWatchActive)
{ // let the user see DW is active
@@ -1068,7 +1067,8 @@ void APP_Update(void)
#else
if (gScreenToDisplay != DISPLAY_SCANNER && gScanState != SCAN_OFF && gScheduleScanListen && !gPttIsPressed)
#endif
{
{ // scanning
if (IS_FREQ_CHANNEL(gNextMrChannel))
{
if (gCurrentFunction == FUNCTION_INCOMING)
@@ -1250,7 +1250,7 @@ void APP_Update(void)
if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF || gScanState != SCAN_OFF || gCssScanMode != CSS_SCAN_MODE_OFF || gUpdateRSSI)
{ // dual watch mode, go back to sleep
updateRSSI(gEeprom.RX_CHANNEL);
updateRSSI(gEeprom.RX_VFO);
// go back to sleep
@@ -1370,11 +1370,8 @@ void APP_CheckKeys(void)
Key == KEY_UP ||
Key == KEY_DOWN ||
Key == KEY_EXIT ||
Key == KEY_MENU
#ifdef ENABLE_MAIN_KEY_HOLD
|| Key <= KEY_9 // keys 0-9 can be held down to bypass pressing the F-Key
#endif
)
Key == KEY_MENU ||
Key <= KEY_9) // keys 0-9 can be held down to bypass pressing the F-Key
{
gKeyBeingHeld = true;
APP_ProcessKey(Key, true, true);
@@ -1410,9 +1407,9 @@ void APP_TimeSlice10ms(void)
#endif
#ifdef ENABLE_AM_FIX
// if (gEeprom.VfoInfo[gEeprom.RX_CHANNEL].AM_mode && gSetting_AM_fix)
// if (gEeprom.VfoInfo[gEeprom.RX_VFO].AM_mode && gSetting_AM_fix)
if (gRxVfo->AM_mode && gSetting_AM_fix)
AM_fix_10ms(gEeprom.RX_CHANNEL);
AM_fix_10ms(gEeprom.RX_VFO);
#endif
if (UART_IsCommandAvailable())
@@ -1800,7 +1797,7 @@ void APP_TimeSlice500ms(void)
if (gCurrentFunction != FUNCTION_TRANSMIT)
{
if (gCurrentFunction != FUNCTION_POWER_SAVE)
updateRSSI(gEeprom.RX_CHANNEL);
updateRSSI(gEeprom.RX_VFO);
#ifdef ENABLE_FMRADIO
if ((gFM_ScanState == FM_SCAN_OFF || gAskToSave) && gCssScanMode == CSS_SCAN_MODE_OFF)
@@ -2110,10 +2107,10 @@ static void APP_ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
if (gFlagSaveChannel)
{
SETTINGS_SaveChannel(gTxVfo->CHANNEL_SAVE, gEeprom.TX_CHANNEL, gTxVfo, gFlagSaveChannel);
SETTINGS_SaveChannel(gTxVfo->CHANNEL_SAVE, gEeprom.TX_VFO, gTxVfo, gFlagSaveChannel);
gFlagSaveChannel = false;
RADIO_ConfigureChannel(gEeprom.TX_CHANNEL, VFO_CONFIGURE);
RADIO_ConfigureChannel(gEeprom.TX_VFO, VFO_CONFIGURE);
RADIO_SetupRegisters(true);
GUI_SelectNextDisplay(DISPLAY_MAIN);
@@ -2163,8 +2160,7 @@ static void APP_ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
return;
if (!bKeyHeld)
{
// keypad is locked, tell the user
{ // keypad is locked, tell the user
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL);
gKeypadLocked = 4; // 2 seconds
gUpdateDisplay = true;
@@ -2327,9 +2323,7 @@ static void APP_ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
case DISPLAY_MAIN:
MAIN_ProcessKeys(Key, bKeyPressed, bKeyHeld);
#ifdef ENABLE_MAIN_KEY_HOLD
bKeyHeld = false; // allow the channel setting to be saved
#endif
bKeyHeld = false; // allow the channel setting to be saved
break;
@@ -2435,7 +2429,7 @@ Skip:
{
if (!bKeyHeld)
{
SETTINGS_SaveChannel(gTxVfo->CHANNEL_SAVE, gEeprom.TX_CHANNEL, gTxVfo, gRequestSaveChannel);
SETTINGS_SaveChannel(gTxVfo->CHANNEL_SAVE, gEeprom.TX_VFO, gTxVfo, gRequestSaveChannel);
if (gScreenToDisplay != DISPLAY_SCANNER)
if (gVfoConfigureMode == VFO_CONFIGURE_NONE) // 'if' is so as we don't wipe out previously setting this variable elsewhere
@@ -2460,7 +2454,7 @@ Skip:
RADIO_ConfigureChannel(1, gVfoConfigureMode);
}
else
RADIO_ConfigureChannel(gEeprom.TX_CHANNEL, gVfoConfigureMode);
RADIO_ConfigureChannel(gEeprom.TX_VFO, gVfoConfigureMode);
if (gRequestDisplayScreen == DISPLAY_INVALID)
gRequestDisplayScreen = DISPLAY_MAIN;

View File

@@ -52,12 +52,22 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
if (!bKeyPressed)
return;
#ifdef ENABLE_VOICE
gAnotherVoiceID = gEeprom.KEY_LOCK ? VOICE_ID_UNLOCK : VOICE_ID_LOCK;
#endif
gEeprom.KEY_LOCK = !gEeprom.KEY_LOCK;
gRequestSaveSettings = true;
if (gScreenToDisplay != DISPLAY_MENU &&
gScreenToDisplay != DISPLAY_FM &&
#ifdef ENABLE_FMRADIO
!gFmRadioMode &&
#endif
gCurrentFunction != FUNCTION_TRANSMIT)
{ // toggle the keyboad lock
#ifdef ENABLE_VOICE
gAnotherVoiceID = gEeprom.KEY_LOCK ? VOICE_ID_UNLOCK : VOICE_ID_LOCK;
#endif
gEeprom.KEY_LOCK = !gEeprom.KEY_LOCK;
gRequestSaveSettings = true;
}
}
else
{

View File

@@ -38,11 +38,41 @@
#include "ui/inputbox.h"
#include "ui/ui.h"
void toggle_chan_scanlist(void)
{ // toggle the selected channels scanlist setting
if (gScreenToDisplay == DISPLAY_SCANNER || !IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
return;
if (gTxVfo->SCANLIST1_PARTICIPATION)
{
if (gTxVfo->SCANLIST2_PARTICIPATION)
gTxVfo->SCANLIST1_PARTICIPATION = 0;
else
gTxVfo->SCANLIST2_PARTICIPATION = 1;
}
else
{
if (gTxVfo->SCANLIST2_PARTICIPATION)
gTxVfo->SCANLIST2_PARTICIPATION = 0;
else
gTxVfo->SCANLIST1_PARTICIPATION = 1;
}
SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true);
gVfoConfigureMode = VFO_CONFIGURE;
gFlagResetVfos = true;
}
static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
{
uint8_t Band;
uint8_t Vfo = gEeprom.TX_CHANNEL;
uint8_t Vfo = gEeprom.TX_VFO;
if (gScreenToDisplay == DISPLAY_MENU)
return;
switch (Key)
{
case KEY_0:
@@ -102,7 +132,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B)
gEeprom.DUAL_WATCH = DUAL_WATCH_CHAN_A;
else
gEeprom.TX_CHANNEL = (Vfo + 1) & 1u;
gEeprom.TX_VFO = (Vfo + 1) & 1u;
gRequestSaveSettings = 1;
gFlagReconfigureVfos = true;
@@ -125,7 +155,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // swap to frequency mode
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_CHANNEL];
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_VFO];
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif
@@ -134,7 +164,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break;
}
Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_CHANNEL], 1, false, 0);
Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 0);
if (Channel != 0xFF)
{ // swap to channel mode
gEeprom.ScreenChannel[Vfo] = Channel;
@@ -170,52 +200,31 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
case KEY_5:
if(beep) {
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_CHANNEL];
gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_VFO];
}
else
{
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_CHANNEL];
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_VFO];
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif
}
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
#elif defined(ENABLE_SPECTRUM)
#elif defined(ENABLE_SPECTRUM)
APP_RunSpectrum();
gRequestDisplayScreen = DISPLAY_MAIN;
#endif
#endif
}
else {
// toggle the selected channels scanlist setting
if (gScreenToDisplay != DISPLAY_SCANNER)
{
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
if (gTxVfo->SCANLIST1_PARTICIPATION)
{
if (gTxVfo->SCANLIST2_PARTICIPATION)
gTxVfo->SCANLIST1_PARTICIPATION = 0;
else
gTxVfo->SCANLIST2_PARTICIPATION = 1;
}
else
{
if (gTxVfo->SCANLIST2_PARTICIPATION)
gTxVfo->SCANLIST2_PARTICIPATION = 0;
else
gTxVfo->SCANLIST1_PARTICIPATION = 1;
}
SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true);
gVfoConfigureMode = VFO_CONFIGURE;
gFlagResetVfos = true;
}
}
#ifdef ENABLE_VOX
toggle_chan_scanlist();
#endif
}
break;
case KEY_6:
@@ -226,11 +235,7 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
#ifdef ENABLE_VOX
ACTION_Vox();
#else
// TODO: make use of this function key
toggle_chan_scanlist();
#endif
break;
@@ -273,45 +278,36 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
if (bKeyHeld)
{ // key held down
#ifdef ENABLE_MAIN_KEY_HOLD
if (bKeyPressed)
if (bKeyPressed)
{
if (gScreenToDisplay == DISPLAY_MAIN)
{
if (gScreenToDisplay == DISPLAY_MAIN)
{
if (gInputBoxIndex > 0)
{ // delete any inputted chars
gInputBoxIndex = 0;
gRequestDisplayScreen = DISPLAY_MAIN;
}
gWasFKeyPressed = false;
gUpdateStatus = true;
processFKeyFunction(Key, false);
if (gInputBoxIndex > 0)
{ // delete any inputted chars
gInputBoxIndex = 0;
gRequestDisplayScreen = DISPLAY_MAIN;
}
gWasFKeyPressed = false;
gUpdateStatus = true;
processFKeyFunction(Key, false);
}
#endif
}
return;
}
#ifdef ENABLE_MAIN_KEY_HOLD
if (bKeyPressed)
{ // key is pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; // beep when key is pressed
return; // don't use the key till it's released
}
#else
if (!bKeyPressed)
return;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
#endif
if (bKeyPressed)
{ // key is pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; // beep when key is pressed
return; // don't use the key till it's released
}
if (!gWasFKeyPressed)
{ // F-key wasn't pressed
const uint8_t Vfo = gEeprom.TX_CHANNEL;
const uint8_t Vfo = gEeprom.TX_VFO;
gKeyInputCountdown = key_input_timeout_500ms;
@@ -560,71 +556,50 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
gUpdateStatus = true;
#ifdef ENABLE_COPY_CHAN_TO_VFO
if (gEeprom.VFO_OPEN &&
gEeprom.DUAL_WATCH == DUAL_WATCH_OFF &&
gScanState == SCAN_OFF &&
gCssScanMode == CSS_SCAN_MODE_OFF)
{ // copy channel to VFO
int channel = -1;
int vfo = -1;
if (gEeprom.VFO_OPEN && gCssScanMode == CSS_SCAN_MODE_OFF)
{
#if 0
// copy channel to opposite VFO
if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[0]) &&
IS_MR_CHANNEL(gEeprom.ScreenChannel[1]))
if (gScanState != SCAN_OFF)
{
channel = gEeprom.ScreenChannel[1];
vfo = 0;
if (gCurrentFunction != FUNCTION_INCOMING ||
gRxReceptionMode == RX_MODE_NONE ||
ScanPauseDelayIn_10ms == 0)
{ // scan is running (not paused)
return;
}
}
else
if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[1]) &&
IS_MR_CHANNEL(gEeprom.ScreenChannel[0]))
{
channel = gEeprom.ScreenChannel[0];
vfo = 1;
const unsigned int vfo = get_rx_VFO();
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo]))
{ // copy channel to VFO, then swap to the VFO
const unsigned int channel = FREQ_CHANNEL_FIRST + gEeprom.VfoInfo[vfo].Band;
gEeprom.ScreenChannel[vfo] = channel;
gEeprom.VfoInfo[vfo].CHANNEL_SAVE = channel;
gEeprom.TX_VFO = vfo;
RADIO_SelectVfos();
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
RADIO_SetupRegisters(true);
//SETTINGS_SaveChannel(channel, gEeprom.RX_VFO, gRxVfo, 1);
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gUpdateStatus = true;
gUpdateDisplay = true;
}
#else
// copy channel to same VFO
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[gEeprom.RX_CHANNEL]))
{
channel = gEeprom.ScreenChannel[gEeprom.RX_CHANNEL];
vfo = gEeprom.RX_CHANNEL;
}
#endif
if (channel >= 0 && vfo >= 0)
{ // copy the channel into the VFO
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gEeprom.MrChannel[vfo] = channel;
gEeprom.ScreenChannel[vfo] = channel;
RADIO_ConfigureChannel(vfo, VFO_CONFIGURE_RELOAD);
channel = FREQ_CHANNEL_FIRST + gEeprom.VfoInfo[vfo].Band;
gEeprom.MrChannel[vfo] = channel;
gEeprom.ScreenChannel[vfo] = channel;
gEeprom.VfoInfo[vfo].CHANNEL_SAVE = channel;
// swap to the VFO
gEeprom.TX_CHANNEL = vfo;
gEeprom.RX_CHANNEL = vfo;
RADIO_SelectVfos();
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
RADIO_SetupRegisters(true);
// SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_CHANNEL, gRxVfo, 1);
gUpdateStatus = true;
gUpdateDisplay = true;
}
}
#endif
else
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
#endif
}
}
@@ -731,7 +706,7 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
{
uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_CHANNEL];
uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO];
if (bKeyHeld || !bKeyPressed)
{
@@ -796,8 +771,8 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
if (Channel == Next)
return;
gEeprom.MrChannel[gEeprom.TX_CHANNEL] = Next;
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Next;
gEeprom.MrChannel[gEeprom.TX_VFO] = Next;
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Next;
if (!bKeyHeld)
{
@@ -810,9 +785,9 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
#ifdef ENABLE_NOAA
else
{
Channel = NOAA_CHANNEL_FIRST + NUMBER_AddWithWraparound(gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] - NOAA_CHANNEL_FIRST, Direction, 0, 9);
gEeprom.NoaaChannel[gEeprom.TX_CHANNEL] = Channel;
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Channel;
Channel = NOAA_CHANNEL_FIRST + NUMBER_AddWithWraparound(gEeprom.ScreenChannel[gEeprom.TX_VFO] - NOAA_CHANNEL_FIRST, Direction, 0, 9);
gEeprom.NoaaChannel[gEeprom.TX_VFO] = Channel;
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel;
}
#endif

View File

@@ -472,7 +472,7 @@ void MENU_AcceptSetting(void)
#if 0
gEeprom.MrChannel[0] = gSubMenuSelection;
#else
gEeprom.MrChannel[gEeprom.TX_CHANNEL] = gSubMenuSelection;
gEeprom.MrChannel[gEeprom.TX_VFO] = gSubMenuSelection;
#endif
gRequestSaveChannel = 2;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
@@ -492,7 +492,7 @@ void MENU_AcceptSetting(void)
// save the channel name
memset(gTxVfo->Name, 0, sizeof(gTxVfo->Name));
memmove(gTxVfo->Name, edit, 10);
SETTINGS_SaveChannel(gSubMenuSelection, gEeprom.TX_CHANNEL, gTxVfo, 3);
SETTINGS_SaveChannel(gSubMenuSelection, gEeprom.TX_VFO, gTxVfo, 3);
gFlagReconfigureVfos = true;
return;
@@ -921,12 +921,12 @@ void MENU_ShowCurrentSetting(void)
#if 0
gSubMenuSelection = gEeprom.MrChannel[0];
#else
gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_CHANNEL];
gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_VFO];
#endif
break;
case MENU_MEM_NAME:
gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_CHANNEL];
gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_VFO];
break;
case MENU_SAVE:
@@ -1106,7 +1106,7 @@ void MENU_ShowCurrentSetting(void)
#if 0
gSubMenuSelection = RADIO_FindNextChannel(gEeprom.MrChannel[0], 1, false, 1);
#else
gSubMenuSelection = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_CHANNEL], 1, false, 1);
gSubMenuSelection = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 1);
#endif
break;

View File

@@ -250,16 +250,16 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
Channel = gScanChannel;
gEeprom.MrChannel[gEeprom.TX_CHANNEL] = Channel;
gEeprom.MrChannel[gEeprom.TX_VFO] = Channel;
}
else
{
Channel = gTxVfo->Band + FREQ_CHANNEL_FIRST;
gEeprom.FreqChannel[gEeprom.TX_CHANNEL] = Channel;
gEeprom.FreqChannel[gEeprom.TX_VFO] = Channel;
}
gTxVfo->CHANNEL_SAVE = Channel;
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Channel;
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CONFIRM;
#endif
@@ -430,10 +430,10 @@ void SCANNER_Stop(void)
{
if (IS_MR_CHANNEL(gNextMrChannel))
{
gEeprom.MrChannel[gEeprom.RX_CHANNEL] = gRestoreMrChannel;
gEeprom.ScreenChannel[gEeprom.RX_CHANNEL] = Previous;
gEeprom.MrChannel[gEeprom.RX_VFO] = gRestoreMrChannel;
gEeprom.ScreenChannel[gEeprom.RX_VFO] = Previous;
RADIO_ConfigureChannel(gEeprom.RX_CHANNEL, VFO_CONFIGURE_RELOAD);
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
}
else
{
@@ -450,7 +450,7 @@ void SCANNER_Stop(void)
{
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_CHANNEL, gRxVfo, 1);
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_VFO, gRxVfo, 1);
return;
}

View File

@@ -385,7 +385,7 @@ static void CMD_052F(const uint8_t *pBuffer)
gEeprom.DUAL_WATCH = DUAL_WATCH_OFF;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gEeprom.RX_CHANNEL = 0;
gEeprom.RX_VFO = 0;
gEeprom.DTMF_SIDE_TONE = false;
gEeprom.VfoInfo[0].FrequencyReverse = false;
gEeprom.VfoInfo[0].pRX = &gEeprom.VfoInfo[0].freq_config_RX;

View File

@@ -509,7 +509,7 @@ void BOARD_Init(void)
BOARD_PORTCON_Init();
BOARD_GPIO_Init();
BOARD_ADC_Init();
ST7565_Init();
ST7565_Init(true);
#ifdef ENABLE_FMRADIO
BK1080_Init(0, false);
#endif
@@ -616,7 +616,7 @@ void BOARD_EEPROM_Init(void)
#endif
gEeprom.ROGER = (Data[1] < 3) ? Data[1] : ROGER_MODE_OFF;
gEeprom.REPEATER_TAIL_TONE_ELIMINATION = (Data[2] < 11) ? Data[2] : 0;
gEeprom.TX_CHANNEL = (Data[3] < 2) ? Data[3] : 0;
gEeprom.TX_VFO = (Data[3] < 2) ? Data[3] : 0;
// 0ED0..0ED7
EEPROM_ReadBuffer(0x0ED0, Data, 8);

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -30,7 +30,7 @@ void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const u
void ST7565_BlitFullScreen(void);
void ST7565_BlitStatusLine(void);
void ST7565_FillScreen(uint8_t Value);
void ST7565_Init(void);
void ST7565_Init(const bool full);
void ST7565_Configure_GPIO_B11(void);
void ST7565_SelectColumnAndLine(uint8_t Column, uint8_t Line);
void ST7565_WriteByte(uint8_t Value);

2
main.c
View File

@@ -193,7 +193,7 @@ void Main(void)
AUDIO_SetVoiceID(0, VOICE_ID_WELCOME);
Channel = gEeprom.ScreenChannel[gEeprom.TX_CHANNEL];
Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO];
if (IS_MR_CHANNEL(Channel))
{
AUDIO_SetVoiceID(1, VOICE_ID_CHANNEL_MODE);

35
misc.c
View File

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

3
misc.h
View File

@@ -322,6 +322,9 @@ extern int16_t gCurrentRSSI[2]; // now one per VFO
extern uint8_t gIsLocked;
extern volatile uint8_t boot_counter_10ms;
unsigned int get_tx_VFO(void);
unsigned int get_rx_VFO(void);
void NUMBER_Get(char *pDigits, uint32_t *pInteger);
void NUMBER_ToDigits(uint32_t Value, char *pDigits);
int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit);

43
radio.c
View File

@@ -517,30 +517,16 @@ void RADIO_ApplyOffset(VFO_Info_t *pInfo)
static void RADIO_SelectCurrentVfo(void)
{
gCurrentVfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gRxVfo : &gEeprom.VfoInfo[gEeprom.TX_CHANNEL];
gCurrentVfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gRxVfo : &gEeprom.VfoInfo[gEeprom.TX_VFO];
}
void RADIO_SelectVfos(void)
{
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_B)
gEeprom.TX_CHANNEL = 1;
else
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_A)
gEeprom.TX_CHANNEL = 0;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B)
gEeprom.TX_CHANNEL = 1;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A)
gEeprom.TX_CHANNEL = 0;
gEeprom.TX_VFO = get_tx_VFO();
gEeprom.RX_VFO = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.TX_VFO : (gEeprom.TX_VFO + 1) & 1u;
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF)
gEeprom.RX_CHANNEL = gEeprom.TX_CHANNEL;
else
gEeprom.RX_CHANNEL = (gEeprom.TX_CHANNEL == 0) ? 1 : 0;
gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_CHANNEL];
gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_CHANNEL];
gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_VFO];
gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO];
RADIO_SelectCurrentVfo();
}
@@ -877,10 +863,9 @@ void RADIO_SetVfoState(VfoState_t State)
VfoState[1] = VFO_STATE_TX_DISABLE;
}
else
{
unsigned int chan = (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF && gRxVfoIsActive) ? (gEeprom.RX_CHANNEL + 1) & 1 : gEeprom.RX_CHANNEL; // 1of11
chan = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.TX_CHANNEL : chan;
VfoState[chan] = State;
{ // 1of11
const unsigned int vfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
VfoState[vfo] = State;
}
#ifdef ENABLE_FMRADIO
@@ -901,11 +886,11 @@ void RADIO_PrepareTX(void)
gDualWatchCountdown_10ms = dual_watch_count_after_tx_10ms;
gScheduleDualWatch = false;
if (!gRxVfoIsActive)
if (gRxVfoIsActive)
{ // use the TX vfo
gEeprom.RX_CHANNEL = gEeprom.TX_CHANNEL;
gRxVfo = &gEeprom.VfoInfo[gEeprom.TX_CHANNEL];
gRxVfoIsActive = true;
gEeprom.RX_VFO = gEeprom.TX_VFO;
gRxVfo = &gEeprom.VfoInfo[gEeprom.TX_VFO];
// gRxVfoIsActive = true;
}
// let the user see that DW is not active
@@ -939,7 +924,6 @@ void RADIO_PrepareTX(void)
State = VFO_STATE_TX_DISABLE;
}
else
//if (TX_freq_check(gCurrentVfo->pTX->Frequency) == 0 || gCurrentVfo->CHANNEL_SAVE <= FREQ_CHANNEL_LAST)
if (TX_freq_check(gCurrentVfo->pTX->Frequency) == 0)
{ // TX frequency is allowed
if (gCurrentVfo->BUSY_CHANNEL_LOCK && gCurrentFunction == FUNCTION_RECEIVE)
@@ -958,10 +942,13 @@ void RADIO_PrepareTX(void)
if (State != VFO_STATE_NORMAL)
{ // TX not allowed
RADIO_SetVfoState(State);
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
gAlarmState = ALARM_STATE_OFF;
#endif
gDTMF_ReplyState = DTMF_REPLY_NONE;
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL);
return;
}

View File

@@ -133,7 +133,7 @@ void SETTINGS_SaveSettings(void)
#endif
State[1] = gEeprom.ROGER;
State[2] = gEeprom.REPEATER_TAIL_TONE_ELIMINATION;
State[3] = gEeprom.TX_CHANNEL;
State[3] = gEeprom.TX_VFO;
EEPROM_WriteBuffer(0x0EA8, State);
State[0] = gEeprom.DTMF_SIDE_TONE;

View File

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

126
ui/main.c
View File

@@ -85,59 +85,60 @@ void UI_drawBars(uint8_t *p, const unsigned int level)
const unsigned int bar_width = LCD_WIDTH - 2 - bar_x;
unsigned int i;
if (gScreenToDisplay != DISPLAY_MAIN)
return;
#if 1
// TX audio level
if (gCurrentFunction != FUNCTION_TRANSMIT ||
gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE)
gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE)
{
return; // screen is in use
}
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
if (gAlarmState != ALARM_STATE_OFF)
return;
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
if (gAlarmState != ALARM_STATE_OFF)
return;
#endif
{
#if 1
// TX audio level
const unsigned int voice_amp = BK4819_GetVoiceAmplitudeOut(); // 15:0
// const unsigned int max = 65535;
// const unsigned int level = ((voice_amp * bar_width) + (max / 2)) / max; // with rounding
// const unsigned int len = (level <= bar_width) ? level : bar_width;
// make non-linear to make more sensitive at low values
const unsigned int level = voice_amp * 8;
const unsigned int sqrt_level = sqrt16((level < 65535) ? level : 65535);
const unsigned int len = (sqrt_level <= bar_width) ? sqrt_level : bar_width;
#else
// TX/RX AF input level (dB)
const uint8_t af_tx_rx = BK4819_GetAfTxRx(); // 6:0
const unsigned int max = 63;
const unsigned int level = (((uint16_t)af_tx_rx * bar_width) + (max / 2)) / max; // with rounding
const unsigned int len = (level <= bar_width) ? level : bar_width;
#endif
const unsigned int voice_amp = BK4819_GetVoiceAmplitudeOut(); // 15:0
// const unsigned int max = 65535;
// const unsigned int level = ((voice_amp * bar_width) + (max / 2)) / max; // with rounding
// const unsigned int len = (level <= bar_width) ? level : bar_width;
// make non-linear to make more sensitive at low values
const unsigned int level = voice_amp * 8;
const unsigned int sqrt_level = sqrt16((level < 65535) ? level : 65535);
const unsigned int len = (sqrt_level <= bar_width) ? sqrt_level : bar_width;
#else
// TX/RX AF input level (dB)
const uint8_t af_tx_rx = BK4819_GetAfTxRx(); // 6:0
const unsigned int max = 63;
const unsigned int level = (((uint16_t)af_tx_rx * bar_width) + (max / 2)) / max; // with rounding
const unsigned int len = (level <= bar_width) ? level : bar_width;
#endif
uint8_t *p_line = gFrameBuffer[line];
memset(p_line, 0, LCD_WIDTH);
#if 1
// solid bar
for (i = 0; i < bar_width; i++)
p_line[bar_x + i] = (i > len) ? ((i & 1) == 0) ? 0x41 : 0x00 : ((i & 1) == 0) ? 0x7f : 0x3e;
#else
// knuled bar
for (i = 0; i < bar_width; i += 2)
p_line[bar_x + i] = (i <= len) ? 0x7f : 0x41;
#endif
if (gCurrentFunction == FUNCTION_TRANSMIT)
ST7565_BlitFullScreen();
uint8_t *p_line = gFrameBuffer[line];
memset(p_line, 0, LCD_WIDTH);
#if 1
// solid bar
for (i = 0; i < bar_width; i++)
p_line[bar_x + i] = (i > len) ? ((i & 1) == 0) ? 0x41 : 0x00 : ((i & 1) == 0) ? 0x7f : 0x3e;
#else
// knuled bar
for (i = 0; i < bar_width; i += 2)
p_line[bar_x + i] = (i <= len) ? 0x7f : 0x41;
#endif
if (gCurrentFunction == FUNCTION_TRANSMIT)
ST7565_BlitFullScreen();
}
}
}
#endif
@@ -172,6 +173,7 @@ void UI_drawBars(uint8_t *p, const unsigned int level)
if (gEeprom.KEY_LOCK && gKeypadLocked > 0)
return; // display is in use
if (gCurrentFunction == FUNCTION_TRANSMIT ||
gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE)
@@ -331,8 +333,8 @@ void UI_DisplayMain(void)
for (vfo_num = 0; vfo_num < 2; vfo_num++)
{
const unsigned int line = (vfo_num == 0) ? line0 : line1;
uint8_t channel = gEeprom.TX_CHANNEL;
// uint8_t tx_channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_CHANNEL : gEeprom.TX_CHANNEL;
uint8_t channel = gEeprom.TX_VFO;
// uint8_t tx_channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
const bool same_vfo = (channel == vfo_num) ? true : false;
uint8_t *p_line0 = gFrameBuffer[line + 0];
uint8_t *p_line1 = gFrameBuffer[line + 1];
@@ -349,7 +351,7 @@ void UI_DisplayMain(void)
}
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF && gRxVfoIsActive)
channel = gEeprom.RX_CHANNEL; // we're currently monitoring the other VFO
channel = gEeprom.RX_VFO; // we're currently monitoring the other VFO
if (channel != vfo_num)
{
@@ -427,7 +429,7 @@ void UI_DisplayMain(void)
else
#endif
{
channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_CHANNEL : gEeprom.TX_CHANNEL;
channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
if (channel == vfo_num)
{ // show the TX symbol
mode = 1;
@@ -445,7 +447,7 @@ void UI_DisplayMain(void)
if ((gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING) &&
gEeprom.RX_CHANNEL == vfo_num)
gEeprom.RX_VFO == vfo_num)
{
#ifdef ENABLE_SMALL_BOLD
UI_PrintStringSmallBold("RX", 14, 0, line);
@@ -458,7 +460,7 @@ void UI_DisplayMain(void)
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num]))
{ // channel mode
const unsigned int x = 2;
const bool inputting = (gInputBoxIndex == 0 || gEeprom.TX_CHANNEL != vfo_num) ? false : true;
const bool inputting = (gInputBoxIndex == 0 || gEeprom.TX_VFO != vfo_num) ? false : true;
if (!inputting)
NUMBER_ToDigits(gEeprom.ScreenChannel[vfo_num] + 1, String); // show the memory channel number
else
@@ -478,7 +480,7 @@ void UI_DisplayMain(void)
#ifdef ENABLE_NOAA
else
{
if (gInputBoxIndex == 0 || gEeprom.TX_CHANNEL != vfo_num)
if (gInputBoxIndex == 0 || gEeprom.TX_VFO != vfo_num)
{ // channel number
sprintf(String, "N%u", 1 + gEeprom.ScreenChannel[vfo_num] - NOAA_CHANNEL_FIRST);
}
@@ -497,7 +499,7 @@ void UI_DisplayMain(void)
#ifdef ENABLE_ALARM
if (gCurrentFunction == FUNCTION_TRANSMIT && gAlarmState == ALARM_STATE_ALARM)
{
channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_CHANNEL : gEeprom.TX_CHANNEL;
channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
if (channel == vfo_num)
state = VFO_STATE_ALARM;
}
@@ -510,7 +512,7 @@ void UI_DisplayMain(void)
UI_PrintString(state_list[state], 31, 0, line, 8);
}
else
if (gInputBoxIndex > 0 && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]) && gEeprom.TX_CHANNEL == vfo_num)
if (gInputBoxIndex > 0 && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]) && gEeprom.TX_VFO == vfo_num)
{ // user entering a frequency
UI_DisplayFrequency(gInputBox, 32, line, true, false);
@@ -521,7 +523,7 @@ void UI_DisplayMain(void)
uint32_t frequency = gEeprom.VfoInfo[vfo_num].pRX->Frequency;
if (gCurrentFunction == FUNCTION_TRANSMIT)
{ // transmitting
channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_CHANNEL : gEeprom.TX_CHANNEL;
channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
if (channel == vfo_num)
frequency = gEeprom.VfoInfo[vfo_num].pTX->Frequency;
}
@@ -721,14 +723,14 @@ void UI_DisplayMain(void)
#endif
#if defined(ENABLE_AM_FIX) && defined(ENABLE_AM_FIX_SHOW_DATA)
if (rx && gEeprom.VfoInfo[gEeprom.RX_CHANNEL].AM_mode && gSetting_AM_fix)
if (rx && gEeprom.VfoInfo[gEeprom.RX_VFO].AM_mode && gSetting_AM_fix)
{
if (gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE)
return;
center_line = CENTER_LINE_AM_FIX_DATA;
AM_fix_print_data(gEeprom.RX_CHANNEL, String);
AM_fix_print_data(gEeprom.RX_VFO, String);
UI_PrintStringSmall(String, 2, 0, 3);
}
else
@@ -738,7 +740,7 @@ void UI_DisplayMain(void)
if (rx)
{
center_line = CENTER_LINE_RSSI;
UI_DisplayRSSIBar(gCurrentRSSI[gEeprom.RX_CHANNEL], false);
UI_DisplayRSSIBar(gCurrentRSSI[gEeprom.RX_VFO], false);
}
else
#endif