Refactoring of cxcss and channel/frequency scanner code

This commit is contained in:
Krzysiek Egzmont 2023-11-03 19:28:34 +01:00
parent 5987e03141
commit 1238bf090c
18 changed files with 566 additions and 624 deletions

View File

@ -99,12 +99,13 @@ ifeq ($(ENABLE_AIRCOPY),1)
OBJS += app/aircopy.o
endif
OBJS += app/app.o
OBJS += app/chFrScanner.o
OBJS += app/common.o
OBJS += app/dtmf.o
ifeq ($(ENABLE_FMRADIO),1)
OBJS += app/fm.o
endif
OBJS += app/generic.o
OBJS += app/common.o
OBJS += app/main.o
OBJS += app/menu.o
ifeq ($(ENABLE_SPECTRUM), 1)

View File

@ -18,12 +18,12 @@
#include "app/action.h"
#include "app/app.h"
#include "app/chFrScanner.h"
#include "app/common.h"
#include "app/dtmf.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif
#include "app/scanner.h"
#include "audio.h"
#include "bsp/dp32g030/gpio.h"
#ifdef ENABLE_FMRADIO
@ -192,7 +192,7 @@ void ACTION_Scan(bool bRestart)
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3;
// jump to the next channel
SCANNER_ScanChannels(false, gScanStateDir);
CHFRSCANNER_Start(false, gScanStateDir);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;
@ -201,7 +201,7 @@ void ACTION_Scan(bool bRestart)
else
{ // stop scanning
SCANNER_Stop();
CHFRSCANNER_Stop();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
@ -211,7 +211,7 @@ void ACTION_Scan(bool bRestart)
else
{ // start scanning
SCANNER_ScanChannels(true, SCAN_FWD);
CHFRSCANNER_Start(true, SCAN_FWD);
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN);
@ -227,31 +227,6 @@ void ACTION_Scan(bool bRestart)
}
}
}
else
// if (!bRestart)
if (!bRestart && IS_MR_CHANNEL(gNextMrChannel))
{ // channel mode, keep scanning but toggle between scan lists
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3;
// jump to the next channel
SCANNER_ScanChannels(false, gScanStateDir);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;
gUpdateStatus = true;
}
else
{ // stop scanning
gMonitor = false;
SCANNER_Stop();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
gRequestDisplayScreen = DISPLAY_MAIN;
}
}
#ifdef ENABLE_VOX

202
app/app.c
View File

@ -21,6 +21,7 @@
#include "app/aircopy.h"
#endif
#include "app/app.h"
#include "app/chFrScanner.h"
#include "app/dtmf.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
@ -407,7 +408,7 @@ Skip:
break;
case SCAN_RESUME_SE:
SCANNER_Stop();
CHFRSCANNER_Stop();
break;
}
}
@ -483,7 +484,7 @@ void APP_StartListening(FUNCTION_Type_t Function, const bool reset_am_fix)
BACKLIGHT_TurnOn();
if (gScanStateDir != SCAN_OFF)
SCANNER_Found();
CHFRSCANNER_Found();
#ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gIsNoaaMode) {
@ -901,7 +902,7 @@ void APP_Update(void)
if (gScreenToDisplay != DISPLAY_SCANNER && gScanStateDir != SCAN_OFF && gScheduleScanListen && !gPttIsPressed)
#endif
{ // scanning
SCANNER_ContinueScanning();
CHFRSCANNER_ContinueScanning();
}
#ifdef ENABLE_VOICE
@ -1330,153 +1331,33 @@ void APP_TimeSlice10ms(void)
}
}
#ifdef ENABLE_FMRADIO
if (gFmRadioMode && gFM_RestoreCountdown_10ms > 0)
{
if (--gFM_RestoreCountdown_10ms == 0)
{ // switch back to FM radio mode
FM_Start();
GUI_SelectNextDisplay(DISPLAY_FM);
}
}
#endif
if (gScreenToDisplay == DISPLAY_SCANNER)
#ifdef ENABLE_FMRADIO
if (gFmRadioMode && gFM_RestoreCountdown_10ms > 0)
{
uint32_t Result;
int32_t Delta;
BK4819_CssScanResult_t ScanResult;
uint16_t CtcssFreq;
if (gScanDelay_10ms > 0)
{
if (--gScanDelay_10ms > 0)
{
CheckKeys();
return;
}
}
if (gScannerEditState != 0)
{
CheckKeys();
return;
}
switch (gScanCssState)
{
case SCAN_CSS_STATE_OFF:
// must be RF frequency scanning if we're here ?
if (!BK4819_GetFrequencyScanResult(&Result))
break;
Delta = Result - gScanFrequency;
gScanFrequency = Result;
if (Delta < 0)
Delta = -Delta;
if (Delta < 100)
gScanHitCount++;
else
gScanHitCount = 0;
BK4819_DisableFrequencyScan();
if (gScanHitCount < 3)
{
BK4819_EnableFrequencyScan();
}
else
{
BK4819_SetScanFrequency(gScanFrequency);
gScanCssResultCode = 0xFF;
gScanCssResultType = 0xFF;
gScanHitCount = 0;
gScanUseCssResult = false;
gScanProgressIndicator = 0;
gScanCssState = SCAN_CSS_STATE_SCANNING;
GUI_SelectNextDisplay(DISPLAY_SCANNER);
gUpdateStatus = true;
}
gScanDelay_10ms = scan_delay_10ms;
//gScanDelay_10ms = 1; // 10ms
break;
case SCAN_CSS_STATE_SCANNING:
ScanResult = BK4819_GetCxCSSScanResult(&Result, &CtcssFreq);
if (ScanResult == BK4819_CSS_RESULT_NOT_FOUND)
break;
BK4819_Disable();
if (ScanResult == BK4819_CSS_RESULT_CDCSS)
{
const uint8_t Code = DCS_GetCdcssCode(Result);
if (Code != 0xFF)
{
gScanCssResultCode = Code;
gScanCssResultType = CODE_TYPE_DIGITAL;
gScanCssState = SCAN_CSS_STATE_FOUND;
gScanUseCssResult = true;
gUpdateStatus = true;
}
}
else
if (ScanResult == BK4819_CSS_RESULT_CTCSS)
{
const uint8_t Code = DCS_GetCtcssCode(CtcssFreq);
if (Code != 0xFF)
{
if (Code == gScanCssResultCode && gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE)
{
if (++gScanHitCount >= 2)
{
gScanCssState = SCAN_CSS_STATE_FOUND;
gScanUseCssResult = true;
gUpdateStatus = true;
}
}
else
gScanHitCount = 0;
gScanCssResultType = CODE_TYPE_CONTINUOUS_TONE;
gScanCssResultCode = Code;
}
}
if (gScanCssState < SCAN_CSS_STATE_FOUND)
{
BK4819_SetScanFrequency(gScanFrequency);
gScanDelay_10ms = scan_delay_10ms;
break;
}
GUI_SelectNextDisplay(DISPLAY_SCANNER);
break;
default:
break;
if (--gFM_RestoreCountdown_10ms == 0)
{ // switch back to FM radio mode
FM_Start();
GUI_SelectNextDisplay(DISPLAY_FM);
}
}
#endif
#ifdef ENABLE_AIRCOPY
if (gScreenToDisplay == DISPLAY_AIRCOPY && gAircopyState == AIRCOPY_TRANSFER && gAirCopyIsSendMode == 1)
SCANNER_TimeSlice10ms();
#ifdef ENABLE_AIRCOPY
if (gScreenToDisplay == DISPLAY_AIRCOPY && gAircopyState == AIRCOPY_TRANSFER && gAirCopyIsSendMode == 1)
{
if (gAircopySendCountdown > 0)
{
if (gAircopySendCountdown > 0)
if (--gAircopySendCountdown == 0)
{
if (--gAircopySendCountdown == 0)
{
AIRCOPY_SendMessage();
GUI_DisplayScreen();
}
AIRCOPY_SendMessage();
GUI_DisplayScreen();
}
}
#endif
}
#endif
CheckKeys();
}
@ -1723,27 +1604,8 @@ void APP_TimeSlice500ms(void)
}
}
BATTERY_TimeSlice500ms();
if (gScreenToDisplay == DISPLAY_SCANNER && gScannerEditState == 0 && gScanCssState < SCAN_CSS_STATE_FOUND)
{
gScanProgressIndicator++;
#ifdef ENABLE_CODE_SCAN_TIMEOUT
if (gScanProgressIndicator > 32)
{
if (gScanCssState == SCAN_CSS_STATE_SCANNING && !gScanSingleFrequency)
gScanCssState = SCAN_CSS_STATE_FOUND;
else
gScanCssState = SCAN_CSS_STATE_FAILED;
gUpdateStatus = true;
}
#endif
gUpdateDisplay = true;
}
SCANNER_TimeSlice500ms();
if (gCurrentFunction != FUNCTION_TRANSMIT)
{
@ -2245,22 +2107,6 @@ Skip:
MENU_ShowCurrentSetting();
}
if (gFlagStartScan)
{
gFlagStartScan = false;
gMonitor = false;
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN);
AUDIO_PlaySingleVoice(true);
#endif
SCANNER_Start();
gRequestDisplayScreen = DISPLAY_SCANNER;
}
if (gFlagPrepareTX)
{
RADIO_PrepareTX();

262
app/chFrScanner.c Normal file
View File

@ -0,0 +1,262 @@
#include "app/app.h"
#include "app/chFrScanner.h"
#include "functions.h"
#include "misc.h"
#include "settings.h"
int8_t gScanStateDir;
bool gScanKeepResult;
bool gScanPauseMode;
typedef enum {
SCAN_NEXT_CHAN_SCANLIST1 = 0,
SCAN_NEXT_CHAN_SCANLIST2,
SCAN_NEXT_CHAN_DUAL_WATCH,
SCAN_NEXT_CHAN_MR,
SCAN_NEXT_NUM
} scan_next_chan_t;
scan_next_chan_t currentScanList;
uint32_t initialFrqOrChan;
uint8_t initialCROSS_BAND_RX_TX;
uint32_t lastFoundFrqOrChan;
static void NextFreqChannel(void);
static void NextMemChannel(void);
void CHFRSCANNER_Start(const bool storeBackupSettings, const int8_t scan_direction)
{
if (storeBackupSettings) {
initialCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gScanKeepResult = false;
}
RADIO_SelectVfos();
gNextMrChannel = gRxVfo->CHANNEL_SAVE;
currentScanList = SCAN_NEXT_CHAN_SCANLIST1;
gScanStateDir = scan_direction;
if (IS_MR_CHANNEL(gNextMrChannel))
{ // channel mode
if (storeBackupSettings) {
initialFrqOrChan = gRxVfo->CHANNEL_SAVE;
lastFoundFrqOrChan = initialFrqOrChan;
}
NextMemChannel();
}
else
{ // frequency mode
if (storeBackupSettings) {
initialFrqOrChan = gRxVfo->freq_config_RX.Frequency;
lastFoundFrqOrChan = initialFrqOrChan;
}
NextFreqChannel();
}
gScanPauseDelayIn_10ms = scan_pause_delay_in_2_10ms;
gScheduleScanListen = false;
gRxReceptionMode = RX_MODE_NONE;
gScanPauseMode = false;
}
void CHFRSCANNER_ContinueScanning(void)
{
if (IS_FREQ_CHANNEL(gNextMrChannel))
{
if (gCurrentFunction == FUNCTION_INCOMING)
APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE, true);
else
NextFreqChannel(); // switch to next frequency
}
else
{
if (gCurrentCodeType == CODE_TYPE_OFF && gCurrentFunction == FUNCTION_INCOMING)
APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE, true);
else
NextMemChannel(); // switch to next channel
}
gScanPauseMode = false;
gRxReceptionMode = RX_MODE_NONE;
gScheduleScanListen = false;
}
void CHFRSCANNER_Found(void)
{
switch (gEeprom.SCAN_RESUME_MODE)
{
case SCAN_RESUME_TO:
if (!gScanPauseMode)
{
gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms;
gScheduleScanListen = false;
gScanPauseMode = true;
}
break;
case SCAN_RESUME_CO:
case SCAN_RESUME_SE:
gScanPauseDelayIn_10ms = 0;
gScheduleScanListen = false;
break;
}
if (IS_MR_CHANNEL(gRxVfo->CHANNEL_SAVE)) { //memory scan
lastFoundFrqOrChan = gRxVfo->CHANNEL_SAVE;
}
else { // frequency scan
lastFoundFrqOrChan = gRxVfo->freq_config_RX.Frequency;
}
gScanKeepResult = true;
}
void CHFRSCANNER_Stop(void)
{
if(initialCROSS_BAND_RX_TX != CROSS_BAND_OFF) {
gEeprom.CROSS_BAND_RX_TX = initialCROSS_BAND_RX_TX;
initialCROSS_BAND_RX_TX = CROSS_BAND_OFF;
}
gScanStateDir = SCAN_OFF;
const uint32_t chFr = gScanKeepResult ? lastFoundFrqOrChan : initialFrqOrChan;
const bool channelChanged = chFr != initialFrqOrChan;
if (IS_MR_CHANNEL(gNextMrChannel)) {
gEeprom.MrChannel[gEeprom.RX_VFO] = chFr;
gEeprom.ScreenChannel[gEeprom.RX_VFO] = chFr;
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
if(channelChanged) {
SETTINGS_SaveVfoIndices();
gUpdateStatus = true;
}
}
else {
gRxVfo->freq_config_RX.Frequency = chFr;
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
if(channelChanged) {
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_VFO, gRxVfo, 1);
}
}
RADIO_SetupRegisters(true);
gUpdateDisplay = true;
}
static void NextFreqChannel(void)
{
gRxVfo->freq_config_RX.Frequency = APP_SetFrequencyByStep(gRxVfo, gScanStateDir);
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
RADIO_SetupRegisters(true);
#ifdef ENABLE_FASTER_CHANNEL_SCAN
gScanPauseDelayIn_10ms = 9; // 90ms
#else
gScanPauseDelayIn_10ms = scan_pause_delay_in_6_10ms;
#endif
gUpdateDisplay = true;
}
static void NextMemChannel(void)
{
static unsigned int prev_mr_chan = 0;
const bool enabled = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCAN_LIST_ENABLED[gEeprom.SCAN_LIST_DEFAULT] : true;
const int chan1 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH1[gEeprom.SCAN_LIST_DEFAULT] : -1;
const int chan2 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH2[gEeprom.SCAN_LIST_DEFAULT] : -1;
const unsigned int prev_chan = gNextMrChannel;
unsigned int chan = 0;
if (enabled)
{
switch (currentScanList)
{
case SCAN_NEXT_CHAN_SCANLIST1:
prev_mr_chan = gNextMrChannel;
if (chan1 >= 0)
{
if (RADIO_CheckValidChannel(chan1, false, 0))
{
currentScanList = SCAN_NEXT_CHAN_SCANLIST1;
gNextMrChannel = chan1;
break;
}
}
[[fallthrough]];
case SCAN_NEXT_CHAN_SCANLIST2:
if (chan2 >= 0)
{
if (RADIO_CheckValidChannel(chan2, false, 0))
{
currentScanList = SCAN_NEXT_CHAN_SCANLIST2;
gNextMrChannel = chan2;
break;
}
}
[[fallthrough]];
// this bit doesn't yet work if the other VFO is a frequency
case SCAN_NEXT_CHAN_DUAL_WATCH:
// dual watch is enabled - include the other VFO in the scan
// if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
// {
// chan = (gEeprom.RX_VFO + 1) & 1u;
// chan = gEeprom.ScreenChannel[chan];
// if (IS_MR_CHANNEL(chan))
// {
// currentScanList = SCAN_NEXT_CHAN_DUAL_WATCH;
// gNextMrChannel = chan;
// break;
// }
// }
default:
case SCAN_NEXT_CHAN_MR:
currentScanList = SCAN_NEXT_CHAN_MR;
gNextMrChannel = prev_mr_chan;
chan = 0xff;
break;
}
}
if (!enabled || chan == 0xff)
{
chan = RADIO_FindNextChannel(gNextMrChannel + gScanStateDir, gScanStateDir, (gEeprom.SCAN_LIST_DEFAULT < 2) ? true : false, gEeprom.SCAN_LIST_DEFAULT);
if (chan == 0xFF)
{ // no valid channel found
chan = MR_CHANNEL_FIRST;
}
gNextMrChannel = chan;
}
if (gNextMrChannel != prev_chan)
{
gEeprom.MrChannel[ gEeprom.RX_VFO] = gNextMrChannel;
gEeprom.ScreenChannel[gEeprom.RX_VFO] = gNextMrChannel;
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
RADIO_SetupRegisters(true);
gUpdateDisplay = true;
}
#ifdef ENABLE_FASTER_CHANNEL_SCAN
gScanPauseDelayIn_10ms = 9; // 90ms .. <= ~60ms it misses signals (squelch response and/or PLL lock time) ?
#else
gScanPauseDelayIn_10ms = scan_pause_delay_in_3_10ms;
#endif
if (enabled)
if (++currentScanList >= SCAN_NEXT_NUM)
currentScanList = SCAN_NEXT_CHAN_SCANLIST1; // back round we go
}

18
app/chFrScanner.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef APP_CHFRSCANNER_H
#define APP_CHFRSCANNER_H
#include <stdbool.h>
#include <stdint.h>
// scan direction, if not equal SCAN_OFF indicates
// that we are in a process of scanning channels/frequencies
extern int8_t gScanStateDir;
extern bool gScanKeepResult;
extern bool gScanPauseMode;
void CHFRSCANNER_Found(void);
void CHFRSCANNER_Stop(void);
void CHFRSCANNER_Start(const bool storeBackupSettings, const int8_t scan_direction);
void CHFRSCANNER_ContinueScanning(void);
#endif

View File

@ -17,6 +17,7 @@
#include <string.h>
#include <stdio.h> // NULL
#include "app/chFrScanner.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif

View File

@ -17,6 +17,7 @@
#include <string.h>
#include "app/app.h"
#include "app/chFrScanner.h"
#include "app/common.h"
#ifdef ENABLE_FMRADIO
@ -157,7 +158,7 @@ void GENERIC_Key_PTT(bool bKeyPressed)
else
if (gScanStateDir != SCAN_OFF)
{ // frequency/channel scanning . .stop
SCANNER_Stop();
CHFRSCANNER_Stop();
}
else
if (gCssScanMode != CSS_SCAN_MODE_OFF)

View File

@ -18,6 +18,7 @@
#include "app/action.h"
#include "app/app.h"
#include "app/chFrScanner.h"
#include "app/common.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
@ -192,15 +193,15 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
case KEY_4:
gWasFKeyPressed = false;
gFlagStartScan = true;
gScanSingleFrequency = false;
gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gUpdateStatus = true;
gUpdateStatus = true;
if (beep)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
SCANNER_Start(false);
gRequestDisplayScreen = DISPLAY_SCANNER;
break;
case KEY_5:
@ -506,7 +507,7 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
else
{
gScanKeepResult = false;
SCANNER_Stop();
CHFRSCANNER_Stop();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
@ -579,7 +580,7 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
if (bFlag)
{
if (gScanStateDir != SCAN_OFF) {
SCANNER_Stop();
CHFRSCANNER_Stop();
return;
}
@ -651,19 +652,19 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
{ // with the F-key
gWasFKeyPressed = false;
#ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
#endif
#ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
#endif
// scan the CTCSS/DCS code
gFlagStartScan = true;
gScanSingleFrequency = true;
gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
SCANNER_Start(true);
gRequestDisplayScreen = DISPLAY_SCANNER;
}
gPttWasReleased = true;
@ -764,7 +765,7 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
}
// jump to the next channel
SCANNER_ScanChannels(false, Direction);
CHFRSCANNER_Start(false, Direction);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;

View File

@ -29,68 +29,46 @@
DCS_CodeType_t gScanCssResultType;
uint8_t gScanCssResultCode;
bool gFlagStartScan;
bool gFlagStopScan;
bool gScanSingleFrequency;
uint8_t gScannerEditState;
bool gScanSingleFrequency; // scan CTCSS/DCS codes for current frequency
SCAN_SaveState_t gScannerSaveState;
uint8_t gScanChannel;
uint32_t gScanFrequency;
bool gScanPauseMode;
SCAN_CssState_t gScanCssState;
volatile bool gScheduleScanListen = true;
volatile uint16_t gScanPauseDelayIn_10ms;
uint8_t gScanProgressIndicator;
uint8_t gScanHitCount;
bool gScanUseCssResult;
int8_t gScanStateDir;
bool gScanKeepResult;
typedef enum {
SCAN_NEXT_CHAN_SCANLIST1 = 0,
SCAN_NEXT_CHAN_SCANLIST2,
SCAN_NEXT_CHAN_DUAL_WATCH,
SCAN_NEXT_CHAN_MR,
SCAN_NEXT_NUM
} scan_next_chan_t;
STEP_Setting_t stepSetting;
uint8_t scanHitCount;
scan_next_chan_t currentScanList;
uint32_t initialFrqOrChan;
uint8_t initialCROSS_BAND_RX_TX;
uint32_t lastFoundFrqOrChan;
static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
if (gScannerEditState == 1)
{
uint16_t Channel;
if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
INPUTBOX_Append(Key);
gRequestDisplayScreen = DISPLAY_SCANNER;
if (gInputBoxIndex < 3)
{
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
if (gInputBoxIndex < 3) {
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
return;
}
gInputBoxIndex = 0;
Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
if (IS_MR_CHANNEL(Channel))
{
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gShowChPrefix = RADIO_CheckValidChannel(Channel, false, 0);
gScanChannel = (uint8_t)Channel;
uint16_t chan = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
if (IS_MR_CHANNEL(chan)) {
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gShowChPrefix = RADIO_CheckValidChannel(chan, false, 0);
gScanChannel = (uint8_t)chan;
return;
}
}
@ -101,13 +79,11 @@ static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
if (!bKeyHeld && bKeyPressed) { // short pressed
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
switch (gScannerEditState)
{
case 0:
switch (gScannerSaveState) {
case SCAN_SAVE_NO_PROMPT:
gRequestDisplayScreen = DISPLAY_MAIN;
gEeprom.CROSS_BAND_RX_TX = gBackup_CROSS_BAND_RX_TX;
@ -115,14 +91,13 @@ static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
gFlagStopScan = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
gFlagResetVfos = true;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
break;
case 1:
if (gInputBoxIndex > 0)
{
case SCAN_SAVE_CHAN_SEL:
if (gInputBoxIndex > 0) {
gInputBox[--gInputBoxIndex] = 10;
gRequestDisplayScreen = DISPLAY_SCANNER;
break;
@ -130,11 +105,11 @@ static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
// Fallthrough
case 2:
gScannerEditState = 0;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
case SCAN_SAVE_CHANNEL:
gScannerSaveState = SCAN_SAVE_NO_PROMPT;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
gRequestDisplayScreen = DISPLAY_SCANNER;
break;
}
@ -143,40 +118,28 @@ static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
{
uint8_t Channel;
if (bKeyHeld)
if (bKeyHeld || !bKeyPressed) // ignore long press or release button events
return;
if (!bKeyPressed)
return;
if (gScanCssState == SCAN_CSS_STATE_OFF && !gScanSingleFrequency)
{
if (gScanCssState == SCAN_CSS_STATE_OFF && !gScanSingleFrequency) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gScanCssState == SCAN_CSS_STATE_SCANNING)
{
if (gScanSingleFrequency)
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gScanCssState == SCAN_CSS_STATE_SCANNING && gScanSingleFrequency) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gScanCssState == SCAN_CSS_STATE_FAILED)
{
if (gScanCssState == SCAN_CSS_STATE_FAILED) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
switch (gScannerEditState)
{
case 0:
switch (gScannerSaveState) {
case SCAN_SAVE_NO_PROMPT:
if (!gScanSingleFrequency)
{
uint32_t freq250 = FREQUENCY_RoundToStep(gScanFrequency, 250);
@ -186,60 +149,54 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
uint32_t diff625 = gScanFrequency > freq625 ? gScanFrequency - freq625 : freq625 - gScanFrequency;
if(diff250 > diff625) {
gStepSetting = STEP_6_25kHz;
stepSetting = STEP_6_25kHz;
gScanFrequency = freq625;
}
else {
gStepSetting = STEP_2_5kHz;
stepSetting = STEP_2_5kHz;
gScanFrequency = freq250;
}
}
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gScannerEditState = 1;
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
gScannerSaveState = SCAN_SAVE_CHAN_SEL;
gScanChannel = gTxVfo->CHANNEL_SAVE;
gShowChPrefix = RADIO_CheckValidChannel(gTxVfo->CHANNEL_SAVE, false, 0);
}
else
{
gScannerEditState = 2;
else {
gScannerSaveState = SCAN_SAVE_CHANNEL;
}
gScanCssState = SCAN_CSS_STATE_FOUND;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_MEMORY_CHANNEL;
#endif
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_MEMORY_CHANNEL;
#endif
gRequestDisplayScreen = DISPLAY_SCANNER;
gUpdateStatus = true;
break;
case 1:
if (gInputBoxIndex == 0)
{
case SCAN_SAVE_CHAN_SEL:
if (gInputBoxIndex == 0) {
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gRequestDisplayScreen = DISPLAY_SCANNER;
gScannerEditState = 2;
gScannerSaveState = SCAN_SAVE_CHANNEL;
}
break;
case 2:
if (!gScanSingleFrequency)
{
case SCAN_SAVE_CHANNEL:
if (!gScanSingleFrequency) {
RADIO_InitInfo(gTxVfo, gTxVfo->CHANNEL_SAVE, gScanFrequency);
if (gScanUseCssResult)
{
if (gScanUseCssResult) {
gTxVfo->freq_config_RX.CodeType = gScanCssResultType;
gTxVfo->freq_config_RX.Code = gScanCssResultCode;
}
gTxVfo->freq_config_TX = gTxVfo->freq_config_RX;
gTxVfo->STEP_SETTING = gStepSetting;
gTxVfo->STEP_SETTING = stepSetting;
}
else
{
else {
RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD);
RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD);
@ -249,25 +206,24 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
gTxVfo->freq_config_TX.Code = gScanCssResultCode;
}
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
Channel = gScanChannel;
gEeprom.MrChannel[gEeprom.TX_VFO] = Channel;
uint8_t chan;
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
chan = gScanChannel;
gEeprom.MrChannel[gEeprom.TX_VFO] = chan;
}
else
{
Channel = gTxVfo->Band + FREQ_CHANNEL_FIRST;
gEeprom.FreqChannel[gEeprom.TX_VFO] = Channel;
else {
chan = gTxVfo->Band + FREQ_CHANNEL_FIRST;
gEeprom.FreqChannel[gEeprom.TX_VFO] = chan;
}
gTxVfo->CHANNEL_SAVE = Channel;
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CONFIRM;
#endif
gRequestDisplayScreen = DISPLAY_SCANNER;
gRequestSaveChannel = 2;
gScannerEditState = 0;
gTxVfo->CHANNEL_SAVE = chan;
gEeprom.ScreenChannel[gEeprom.TX_VFO] = chan;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CONFIRM;
#endif
gRequestDisplayScreen = DISPLAY_SCANNER;
gRequestSaveChannel = 2;
gScannerSaveState = SCAN_SAVE_NO_PROMPT;
break;
default:
@ -278,23 +234,20 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
static void SCANNER_Key_STAR(bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
if (!bKeyHeld && bKeyPressed) {
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gFlagStartScan = true;
SCANNER_Start(gScanSingleFrequency);
}
return;
}
static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Direction)
{
if (pKeyHeld)
{
if (pKeyHeld) {
if (!bKeyPressed)
return;
}
else
{
else {
if (!bKeyPressed)
return;
@ -302,8 +255,7 @@ static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Directio
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
}
if (gScannerEditState == 1)
{
if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
gScanChannel = NUMBER_AddWithWraparound(gScanChannel, Direction, 0, MR_CHANNEL_LAST);
gShowChPrefix = RADIO_CheckValidChannel(gScanChannel, false, 0);
gRequestDisplayScreen = DISPLAY_SCANNER;
@ -314,8 +266,7 @@ static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Directio
void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
switch (Key)
{
switch (Key) {
case KEY_0:
case KEY_1:
case KEY_2:
@ -353,13 +304,16 @@ void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
}
}
void SCANNER_Start(void)
void SCANNER_Start(bool singleFreq)
{
uint8_t BackupStep;
uint16_t BackupFrequency;
gScanSingleFrequency = singleFreq;
gMonitor = false;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;
#endif
BK4819_StopScan();
RADIO_SelectVfos();
#ifdef ENABLE_NOAA
@ -367,13 +321,13 @@ void SCANNER_Start(void)
gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + BAND6_400MHz;
#endif
BackupStep = gRxVfo->STEP_SETTING;
BackupFrequency = gRxVfo->StepFrequency;
uint8_t backupStep = gRxVfo->STEP_SETTING;
uint16_t backupFrequency = gRxVfo->StepFrequency;
RADIO_InitInfo(gRxVfo, gRxVfo->CHANNEL_SAVE, gRxVfo->pRX->Frequency);
gRxVfo->STEP_SETTING = BackupStep;
gRxVfo->StepFrequency = BackupFrequency;
gRxVfo->STEP_SETTING = backupStep;
gRxVfo->StepFrequency = backupFrequency;
RADIO_SetupRegisters(true);
@ -381,23 +335,21 @@ void SCANNER_Start(void)
gIsNoaaMode = false;
#endif
if (gScanSingleFrequency)
{
if (gScanSingleFrequency) {
gScanCssState = SCAN_CSS_STATE_SCANNING;
gScanFrequency = gRxVfo->pRX->Frequency;
gStepSetting = gRxVfo->STEP_SETTING;
stepSetting = gRxVfo->STEP_SETTING;
BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency);
BK4819_SetScanFrequency(gScanFrequency);
gUpdateStatus = true;
}
else
{
else {
gScanCssState = SCAN_CSS_STATE_OFF;
gScanFrequency = 0xFFFFFFFF;
BK4819_PickRXFilterPathBasedOnFrequency(0xFFFFFFFF);
BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency);
BK4819_EnableFrequencyScan();
gUpdateStatus = true;
@ -408,7 +360,7 @@ void SCANNER_Start(void)
gScanDelay_10ms = scan_delay_10ms;
gScanCssResultCode = 0xFF;
gScanCssResultType = 0xFF;
gScanHitCount = 0;
scanHitCount = 0;
gScanUseCssResult = false;
g_CxCSS_TAIL_Found = false;
g_CDCSS_Lost = false;
@ -418,242 +370,130 @@ void SCANNER_Start(void)
g_VOX_Lost = false;
#endif
g_SquelchLost = false;
gScannerEditState = 0;
gScannerSaveState = SCAN_SAVE_NO_PROMPT;
gScanProgressIndicator = 0;
}
void SCANNER_Found()
void SCANNER_TimeSlice10ms(void)
{
switch (gEeprom.SCAN_RESUME_MODE)
{
case SCAN_RESUME_TO:
if (!gScanPauseMode)
{
gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms;
gScheduleScanListen = false;
gScanPauseMode = true;
if (gScreenToDisplay != DISPLAY_SCANNER)
return;
if (gScanDelay_10ms > 0) {
gScanDelay_10ms--;
return;
}
if (gScannerSaveState != SCAN_SAVE_NO_PROMPT) {
return;
}
switch (gScanCssState) {
case SCAN_CSS_STATE_OFF: {
// must be RF frequency scanning if we're here ?
uint32_t result;
if (!BK4819_GetFrequencyScanResult(&result))
break;
int32_t delta = result - gScanFrequency;
gScanFrequency = result;
if (delta < 0)
delta = -delta;
if (delta < 100)
scanHitCount++;
else
scanHitCount = 0;
BK4819_DisableFrequencyScan();
if (scanHitCount < 3) {
BK4819_EnableFrequencyScan();
}
break;
else {
BK4819_SetScanFrequency(gScanFrequency);
gScanCssResultCode = 0xFF;
gScanCssResultType = 0xFF;
scanHitCount = 0;
gScanUseCssResult = false;
gScanProgressIndicator = 0;
gScanCssState = SCAN_CSS_STATE_SCANNING;
case SCAN_RESUME_CO:
case SCAN_RESUME_SE:
gScanPauseDelayIn_10ms = 0;
gScheduleScanListen = false;
GUI_SelectNextDisplay(DISPLAY_SCANNER);
gUpdateStatus = true;
}
gScanDelay_10ms = scan_delay_10ms;
//gScanDelay_10ms = 1; // 10ms
break;
}
case SCAN_CSS_STATE_SCANNING: {
uint32_t cdcssFreq;
uint16_t ctcssFreq;
BK4819_CssScanResult_t scanResult = BK4819_GetCxCSSScanResult(&cdcssFreq, &ctcssFreq);
if (scanResult == BK4819_CSS_RESULT_NOT_FOUND)
break;
BK4819_Disable();
if (scanResult == BK4819_CSS_RESULT_CDCSS) {
const uint8_t Code = DCS_GetCdcssCode(cdcssFreq);
if (Code != 0xFF)
{
gScanCssResultCode = Code;
gScanCssResultType = CODE_TYPE_DIGITAL;
gScanCssState = SCAN_CSS_STATE_FOUND;
gScanUseCssResult = true;
gUpdateStatus = true;
}
}
else if (scanResult == BK4819_CSS_RESULT_CTCSS) {
const uint8_t Code = DCS_GetCtcssCode(ctcssFreq);
if (Code != 0xFF) {
if (Code == gScanCssResultCode && gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) {
if (++scanHitCount >= 2) {
gScanCssState = SCAN_CSS_STATE_FOUND;
gScanUseCssResult = true;
gUpdateStatus = true;
}
}
else
scanHitCount = 0;
gScanCssResultType = CODE_TYPE_CONTINUOUS_TONE;
gScanCssResultCode = Code;
}
}
if (gScanCssState < SCAN_CSS_STATE_FOUND) {
BK4819_SetScanFrequency(gScanFrequency);
gScanDelay_10ms = scan_delay_10ms;
break;
}
GUI_SelectNextDisplay(DISPLAY_SCANNER);
break;
}
default:
break;
}
if (IS_MR_CHANNEL(gRxVfo->CHANNEL_SAVE)) { //memory scan
lastFoundFrqOrChan = gRxVfo->CHANNEL_SAVE;
}
else { // frequency scan
lastFoundFrqOrChan = gRxVfo->freq_config_RX.Frequency;
}
gScanKeepResult = true;
}
void SCANNER_Stop(void)
void SCANNER_TimeSlice500ms(void)
{
if(initialCROSS_BAND_RX_TX != CROSS_BAND_OFF) {
gEeprom.CROSS_BAND_RX_TX = initialCROSS_BAND_RX_TX;
initialCROSS_BAND_RX_TX = CROSS_BAND_OFF;
}
gScanStateDir = SCAN_OFF;
if (gScreenToDisplay == DISPLAY_SCANNER && gScannerSaveState == SCAN_SAVE_NO_PROMPT && gScanCssState < SCAN_CSS_STATE_FOUND) {
gScanProgressIndicator++;
#ifdef ENABLE_CODE_SCAN_TIMEOUT
if (gScanProgressIndicator > 32) {
if (gScanCssState == SCAN_CSS_STATE_SCANNING && !gScanSingleFrequency)
gScanCssState = SCAN_CSS_STATE_FOUND;
else
gScanCssState = SCAN_CSS_STATE_FAILED;
const uint32_t chFr = gScanKeepResult ? lastFoundFrqOrChan : initialFrqOrChan;
const bool channelChanged = chFr != initialFrqOrChan;
if (IS_MR_CHANNEL(gNextMrChannel)) {
gEeprom.MrChannel[gEeprom.RX_VFO] = chFr;
gEeprom.ScreenChannel[gEeprom.RX_VFO] = chFr;
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
if(channelChanged) {
SETTINGS_SaveVfoIndices();
gUpdateStatus = true;
}
}
else {
gRxVfo->freq_config_RX.Frequency = chFr;
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
if(channelChanged) {
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_VFO, gRxVfo, 1);
}
}
RADIO_SetupRegisters(true);
gUpdateDisplay = true;
}
static void NextFreqChannel(void)
{
gRxVfo->freq_config_RX.Frequency = APP_SetFrequencyByStep(gRxVfo, gScanStateDir);
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
RADIO_SetupRegisters(true);
#ifdef ENABLE_FASTER_CHANNEL_SCAN
gScanPauseDelayIn_10ms = 9; // 90ms
#else
gScanPauseDelayIn_10ms = scan_pause_delay_in_6_10ms;
#endif
gUpdateDisplay = true;
}
static void NextMemChannel(void)
{
static unsigned int prev_mr_chan = 0;
const bool enabled = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCAN_LIST_ENABLED[gEeprom.SCAN_LIST_DEFAULT] : true;
const int chan1 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH1[gEeprom.SCAN_LIST_DEFAULT] : -1;
const int chan2 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH2[gEeprom.SCAN_LIST_DEFAULT] : -1;
const unsigned int prev_chan = gNextMrChannel;
unsigned int chan = 0;
if (enabled)
{
switch (currentScanList)
{
case SCAN_NEXT_CHAN_SCANLIST1:
prev_mr_chan = gNextMrChannel;
if (chan1 >= 0)
{
if (RADIO_CheckValidChannel(chan1, false, 0))
{
currentScanList = SCAN_NEXT_CHAN_SCANLIST1;
gNextMrChannel = chan1;
break;
}
}
[[fallthrough]];
case SCAN_NEXT_CHAN_SCANLIST2:
if (chan2 >= 0)
{
if (RADIO_CheckValidChannel(chan2, false, 0))
{
currentScanList = SCAN_NEXT_CHAN_SCANLIST2;
gNextMrChannel = chan2;
break;
}
}
[[fallthrough]];
// this bit doesn't yet work if the other VFO is a frequency
case SCAN_NEXT_CHAN_DUAL_WATCH:
// dual watch is enabled - include the other VFO in the scan
// if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
// {
// chan = (gEeprom.RX_VFO + 1) & 1u;
// chan = gEeprom.ScreenChannel[chan];
// if (IS_MR_CHANNEL(chan))
// {
// currentScanList = SCAN_NEXT_CHAN_DUAL_WATCH;
// gNextMrChannel = chan;
// break;
// }
// }
default:
case SCAN_NEXT_CHAN_MR:
currentScanList = SCAN_NEXT_CHAN_MR;
gNextMrChannel = prev_mr_chan;
chan = 0xff;
break;
}
}
if (!enabled || chan == 0xff)
{
chan = RADIO_FindNextChannel(gNextMrChannel + gScanStateDir, gScanStateDir, (gEeprom.SCAN_LIST_DEFAULT < 2) ? true : false, gEeprom.SCAN_LIST_DEFAULT);
if (chan == 0xFF)
{ // no valid channel found
chan = MR_CHANNEL_FIRST;
}
gNextMrChannel = chan;
}
if (gNextMrChannel != prev_chan)
{
gEeprom.MrChannel[ gEeprom.RX_VFO] = gNextMrChannel;
gEeprom.ScreenChannel[gEeprom.RX_VFO] = gNextMrChannel;
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
RADIO_SetupRegisters(true);
gUpdateDisplay = true;
}
#ifdef ENABLE_FASTER_CHANNEL_SCAN
gScanPauseDelayIn_10ms = 9; // 90ms .. <= ~60ms it misses signals (squelch response and/or PLL lock time) ?
#else
gScanPauseDelayIn_10ms = scan_pause_delay_in_3_10ms;
#endif
if (enabled)
if (++currentScanList >= SCAN_NEXT_NUM)
currentScanList = SCAN_NEXT_CHAN_SCANLIST1; // back round we go
}
void SCANNER_ScanChannels(const bool storeBackupSettings, const int8_t scan_direction)
{
if (storeBackupSettings) {
initialCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gScanKeepResult = false;
}
RADIO_SelectVfos();
gNextMrChannel = gRxVfo->CHANNEL_SAVE;
currentScanList = SCAN_NEXT_CHAN_SCANLIST1;
gScanStateDir = scan_direction;
if (IS_MR_CHANNEL(gNextMrChannel))
{ // channel mode
if (storeBackupSettings) {
initialFrqOrChan = gRxVfo->CHANNEL_SAVE;
lastFoundFrqOrChan = initialFrqOrChan;
}
NextMemChannel();
}
else
{ // frequency mode
if (storeBackupSettings) {
initialFrqOrChan = gRxVfo->freq_config_RX.Frequency;
lastFoundFrqOrChan = initialFrqOrChan;
}
NextFreqChannel();
}
gScanPauseDelayIn_10ms = scan_pause_delay_in_2_10ms;
gScheduleScanListen = false;
gRxReceptionMode = RX_MODE_NONE;
gScanPauseMode = false;
}
void SCANNER_ContinueScanning()
{
if (IS_FREQ_CHANNEL(gNextMrChannel))
{
if (gCurrentFunction == FUNCTION_INCOMING)
APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE, true);
else
NextFreqChannel(); // switch to next frequency
}
else
{
if (gCurrentCodeType == CODE_TYPE_OFF && gCurrentFunction == FUNCTION_INCOMING)
APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE, true);
else
NextMemChannel(); // switch to next channel
}
gScanPauseMode = false;
gRxReceptionMode = RX_MODE_NONE;
gScheduleScanListen = false;
}

View File

@ -20,50 +20,37 @@
#include "dcs.h"
#include "driver/keyboard.h"
enum SCAN_CssState_t
typedef enum
{
SCAN_CSS_STATE_OFF = 0,
SCAN_CSS_STATE_OFF,
SCAN_CSS_STATE_SCANNING,
SCAN_CSS_STATE_FOUND,
SCAN_CSS_STATE_FAILED
};
} SCAN_CssState_t;
typedef enum SCAN_CssState_t SCAN_CssState_t;
enum
typedef enum
{
SCAN_REV = -1,
SCAN_OFF = 0,
SCAN_FWD = +1
};
SCAN_SAVE_NO_PROMPT, // saving process not initiated
SCAN_SAVE_CHAN_SEL, // "SAVE: ", channel select prompt, actives only in channel mode
SCAN_SAVE_CHANNEL, // "SAVE?" prompt, waits for confirmation to save settings to channel, or current VFO
} SCAN_SaveState_t;
extern DCS_CodeType_t gScanCssResultType;
extern uint8_t gScanCssResultCode;
extern bool gFlagStartScan;
extern bool gFlagStopScan;
extern bool gScanSingleFrequency;
extern uint8_t gScannerEditState;
extern SCAN_SaveState_t gScannerSaveState;
extern uint8_t gScanChannel;
extern uint32_t gScanFrequency;
extern bool gScanPauseMode;
extern SCAN_CssState_t gScanCssState;
extern volatile bool gScheduleScanListen;
extern volatile uint16_t gScanPauseDelayIn_10ms;
extern uint8_t gScanProgressIndicator;
extern uint8_t gScanHitCount;
extern bool gScanUseCssResult;
// scan direction, if not equal SCAN_OFF indicates
// that we are in a process of scanning channels/frequencies
extern int8_t gScanStateDir;
extern bool gScanKeepResult;
void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
void SCANNER_Start(void);
void SCANNER_Found();
void SCANNER_Stop(void);
void SCANNER_ScanChannels(const bool storeBackupSettings, const int8_t scan_direction);
void SCANNER_ContinueScanning();
void SCANNER_Start(bool singleFreq);
void SCANNER_TimeSlice10ms(void);
void SCANNER_TimeSlice500ms(void);
#endif

4
misc.c
View File

@ -155,6 +155,10 @@ uint8_t gVFO_RSSI_bar_level[2];
uint8_t gReducedService;
uint8_t gBatteryVoltageIndex;
CssScanMode_t gCssScanMode;
volatile bool gScheduleScanListen = true;
volatile uint16_t gScanPauseDelayIn_10ms;
bool gUpdateRSSI;
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
AlarmState_t gAlarmState;

12
misc.h
View File

@ -232,6 +232,18 @@ extern uint8_t gBatteryVoltageIndex;
// if not equal CSS_SCAN_MODE_OFF we are scanning CTCSS/DCS
// this is a scanning inside RX ctcss/dcs menu
extern CssScanMode_t gCssScanMode;
enum
{
SCAN_REV = -1,
SCAN_OFF = 0,
SCAN_FWD = +1
};
extern volatile bool gScheduleScanListen;
extern volatile uint16_t gScanPauseDelayIn_10ms;
extern bool gUpdateRSSI;
extern AlarmState_t gAlarmState;
extern uint16_t gMenuCountdown;

View File

@ -41,7 +41,6 @@ VFO_Info_t *gCurrentVfo;
DCS_CodeType_t gSelectedCodeType;
DCS_CodeType_t gCurrentCodeType;
uint8_t gSelectedCode;
STEP_Setting_t gStepSetting;
VfoState_t VfoState[2];
const char gModulationStr[][4] =

View File

@ -153,8 +153,6 @@ extern DCS_CodeType_t gSelectedCodeType;
extern DCS_CodeType_t gCurrentCodeType;
extern uint8_t gSelectedCode;
extern STEP_Setting_t gStepSetting;
extern VfoState_t VfoState[2];
bool RADIO_CheckValidChannel(uint16_t ChNum, bool bCheckScanList, uint8_t RadioNum);

View File

@ -14,6 +14,7 @@
* limitations under the License.
*/
#include "app/chFrScanner.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif

View File

@ -50,7 +50,7 @@ void UI_DisplayScanner(void)
UI_PrintString(String, 2, 0, 3, 8);
memset(String, 0, sizeof(String));
if (gScannerEditState == 2)
if (gScannerSaveState == SCAN_SAVE_CHANNEL)
{
strcpy(String, "SAVE?");
@ -59,19 +59,15 @@ void UI_DisplayScanner(void)
}
else
{
if (gScannerEditState == 1)
{
if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
strcpy(String, "SAVE:");
UI_GenerateChannelStringEx(String + 5, gShowChPrefix, gScanChannel);
}
else
if (gScanCssState < SCAN_CSS_STATE_FOUND)
{
else if (gScanCssState < SCAN_CSS_STATE_FOUND) {
strcpy(String, "SCAN");
memset(String + 4, '.', (gScanProgressIndicator & 7) + 1);
}
else
if (gScanCssState == SCAN_CSS_STATE_FOUND)
else if (gScanCssState == SCAN_CSS_STATE_FOUND)
strcpy(String, "SCAN CMP.");
else
strcpy(String, "SCAN FAIL.");

View File

@ -16,7 +16,7 @@
#include <string.h>
#include "app/scanner.h"
#include "app/chFrScanner.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif

View File

@ -16,11 +16,11 @@
#include <string.h>
#include "app/chFrScanner.h"
#include "app/dtmf.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif
#include "app/scanner.h"
#include "driver/keyboard.h"
#include "misc.h"
#ifdef ENABLE_AIRCOPY