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 OBJS += app/aircopy.o
endif endif
OBJS += app/app.o OBJS += app/app.o
OBJS += app/chFrScanner.o
OBJS += app/common.o
OBJS += app/dtmf.o OBJS += app/dtmf.o
ifeq ($(ENABLE_FMRADIO),1) ifeq ($(ENABLE_FMRADIO),1)
OBJS += app/fm.o OBJS += app/fm.o
endif endif
OBJS += app/generic.o OBJS += app/generic.o
OBJS += app/common.o
OBJS += app/main.o OBJS += app/main.o
OBJS += app/menu.o OBJS += app/menu.o
ifeq ($(ENABLE_SPECTRUM), 1) ifeq ($(ENABLE_SPECTRUM), 1)

View File

@@ -18,12 +18,12 @@
#include "app/action.h" #include "app/action.h"
#include "app/app.h" #include "app/app.h"
#include "app/chFrScanner.h"
#include "app/common.h" #include "app/common.h"
#include "app/dtmf.h" #include "app/dtmf.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h" #include "app/fm.h"
#endif #endif
#include "app/scanner.h"
#include "audio.h" #include "audio.h"
#include "bsp/dp32g030/gpio.h" #include "bsp/dp32g030/gpio.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
@@ -192,7 +192,7 @@ void ACTION_Scan(bool bRestart)
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3; gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3;
// jump to the next channel // jump to the next channel
SCANNER_ScanChannels(false, gScanStateDir); CHFRSCANNER_Start(false, gScanStateDir);
gScanPauseDelayIn_10ms = 1; gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false; gScheduleScanListen = false;
@@ -201,7 +201,7 @@ void ACTION_Scan(bool bRestart)
else else
{ // stop scanning { // stop scanning
SCANNER_Stop(); CHFRSCANNER_Stop();
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP; gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
@@ -211,7 +211,7 @@ void ACTION_Scan(bool bRestart)
else else
{ // start scanning { // start scanning
SCANNER_ScanChannels(true, SCAN_FWD); CHFRSCANNER_Start(true, SCAN_FWD);
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN); 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 #ifdef ENABLE_VOX

174
app/app.c
View File

@@ -21,6 +21,7 @@
#include "app/aircopy.h" #include "app/aircopy.h"
#endif #endif
#include "app/app.h" #include "app/app.h"
#include "app/chFrScanner.h"
#include "app/dtmf.h" #include "app/dtmf.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h" #include "app/fm.h"
@@ -407,7 +408,7 @@ Skip:
break; break;
case SCAN_RESUME_SE: case SCAN_RESUME_SE:
SCANNER_Stop(); CHFRSCANNER_Stop();
break; break;
} }
} }
@@ -483,7 +484,7 @@ void APP_StartListening(FUNCTION_Type_t Function, const bool reset_am_fix)
BACKLIGHT_TurnOn(); BACKLIGHT_TurnOn();
if (gScanStateDir != SCAN_OFF) if (gScanStateDir != SCAN_OFF)
SCANNER_Found(); CHFRSCANNER_Found();
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gIsNoaaMode) { 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) if (gScreenToDisplay != DISPLAY_SCANNER && gScanStateDir != SCAN_OFF && gScheduleScanListen && !gPttIsPressed)
#endif #endif
{ // scanning { // scanning
SCANNER_ContinueScanning(); CHFRSCANNER_ContinueScanning();
} }
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
@@ -1330,7 +1331,7 @@ void APP_TimeSlice10ms(void)
} }
} }
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (gFmRadioMode && gFM_RestoreCountdown_10ms > 0) if (gFmRadioMode && gFM_RestoreCountdown_10ms > 0)
{ {
if (--gFM_RestoreCountdown_10ms == 0) if (--gFM_RestoreCountdown_10ms == 0)
@@ -1339,132 +1340,12 @@ void APP_TimeSlice10ms(void)
GUI_SelectNextDisplay(DISPLAY_FM); GUI_SelectNextDisplay(DISPLAY_FM);
} }
} }
#endif #endif
if (gScreenToDisplay == DISPLAY_SCANNER)
{
uint32_t Result;
int32_t Delta;
BK4819_CssScanResult_t ScanResult;
uint16_t CtcssFreq;
if (gScanDelay_10ms > 0) SCANNER_TimeSlice10ms();
{
if (--gScanDelay_10ms > 0)
{
CheckKeys();
return;
}
}
if (gScannerEditState != 0) #ifdef ENABLE_AIRCOPY
{
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;
}
}
#ifdef ENABLE_AIRCOPY
if (gScreenToDisplay == DISPLAY_AIRCOPY && gAircopyState == AIRCOPY_TRANSFER && gAirCopyIsSendMode == 1) if (gScreenToDisplay == DISPLAY_AIRCOPY && gAircopyState == AIRCOPY_TRANSFER && gAirCopyIsSendMode == 1)
{ {
if (gAircopySendCountdown > 0) if (gAircopySendCountdown > 0)
@@ -1476,7 +1357,7 @@ void APP_TimeSlice10ms(void)
} }
} }
} }
#endif #endif
CheckKeys(); CheckKeys();
} }
@@ -1723,27 +1604,8 @@ void APP_TimeSlice500ms(void)
} }
} }
BATTERY_TimeSlice500ms(); BATTERY_TimeSlice500ms();
SCANNER_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;
}
if (gCurrentFunction != FUNCTION_TRANSMIT) if (gCurrentFunction != FUNCTION_TRANSMIT)
{ {
@@ -2245,22 +2107,6 @@ Skip:
MENU_ShowCurrentSetting(); 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) if (gFlagPrepareTX)
{ {
RADIO_PrepareTX(); 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 <string.h>
#include <stdio.h> // NULL #include <stdio.h> // NULL
#include "app/chFrScanner.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h" #include "app/fm.h"
#endif #endif

View File

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

View File

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

View File

@@ -29,68 +29,46 @@
DCS_CodeType_t gScanCssResultType; DCS_CodeType_t gScanCssResultType;
uint8_t gScanCssResultCode; uint8_t gScanCssResultCode;
bool gFlagStartScan;
bool gFlagStopScan; bool gFlagStopScan;
bool gScanSingleFrequency; bool gScanSingleFrequency; // scan CTCSS/DCS codes for current frequency
uint8_t gScannerEditState; SCAN_SaveState_t gScannerSaveState;
uint8_t gScanChannel; uint8_t gScanChannel;
uint32_t gScanFrequency; uint32_t gScanFrequency;
bool gScanPauseMode;
SCAN_CssState_t gScanCssState; SCAN_CssState_t gScanCssState;
volatile bool gScheduleScanListen = true;
volatile uint16_t gScanPauseDelayIn_10ms;
uint8_t gScanProgressIndicator; uint8_t gScanProgressIndicator;
uint8_t gScanHitCount;
bool gScanUseCssResult; bool gScanUseCssResult;
int8_t gScanStateDir;
bool gScanKeepResult;
typedef enum { STEP_Setting_t stepSetting;
SCAN_NEXT_CHAN_SCANLIST1 = 0, uint8_t scanHitCount;
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 SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{ {
if (!bKeyHeld && bKeyPressed) if (!bKeyHeld && bKeyPressed)
{ {
if (gScannerEditState == 1) if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
{
uint16_t Channel;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
INPUTBOX_Append(Key); INPUTBOX_Append(Key);
gRequestDisplayScreen = DISPLAY_SCANNER; gRequestDisplayScreen = DISPLAY_SCANNER;
if (gInputBoxIndex < 3) if (gInputBoxIndex < 3) {
{ #ifdef ENABLE_VOICE
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
#endif #endif
return; return;
} }
gInputBoxIndex = 0; gInputBoxIndex = 0;
Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1; uint16_t chan = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
if (IS_MR_CHANNEL(Channel)) if (IS_MR_CHANNEL(chan)) {
{ #ifdef ENABLE_VOICE
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key; gAnotherVoiceID = (VOICE_ID_t)Key;
#endif #endif
gShowChPrefix = RADIO_CheckValidChannel(Channel, false, 0); gShowChPrefix = RADIO_CheckValidChannel(chan, false, 0);
gScanChannel = (uint8_t)Channel; gScanChannel = (uint8_t)chan;
return; 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) static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
{ {
if (!bKeyHeld && bKeyPressed) if (!bKeyHeld && bKeyPressed) { // short pressed
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
switch (gScannerEditState) switch (gScannerSaveState) {
{ case SCAN_SAVE_NO_PROMPT:
case 0:
gRequestDisplayScreen = DISPLAY_MAIN; gRequestDisplayScreen = DISPLAY_MAIN;
gEeprom.CROSS_BAND_RX_TX = gBackup_CROSS_BAND_RX_TX; 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; gFlagStopScan = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD; gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
gFlagResetVfos = true; gFlagResetVfos = true;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL; gAnotherVoiceID = VOICE_ID_CANCEL;
#endif #endif
break; break;
case 1: case SCAN_SAVE_CHAN_SEL:
if (gInputBoxIndex > 0) if (gInputBoxIndex > 0) {
{
gInputBox[--gInputBoxIndex] = 10; gInputBox[--gInputBoxIndex] = 10;
gRequestDisplayScreen = DISPLAY_SCANNER; gRequestDisplayScreen = DISPLAY_SCANNER;
break; break;
@@ -130,11 +105,11 @@ static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
// Fallthrough // Fallthrough
case 2: case SCAN_SAVE_CHANNEL:
gScannerEditState = 0; gScannerSaveState = SCAN_SAVE_NO_PROMPT;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL; gAnotherVoiceID = VOICE_ID_CANCEL;
#endif #endif
gRequestDisplayScreen = DISPLAY_SCANNER; gRequestDisplayScreen = DISPLAY_SCANNER;
break; break;
} }
@@ -143,40 +118,28 @@ static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld) static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
{ {
uint8_t Channel; if (bKeyHeld || !bKeyPressed) // ignore long press or release button events
if (bKeyHeld)
return; return;
if (!bKeyPressed) if (gScanCssState == SCAN_CSS_STATE_OFF && !gScanSingleFrequency) {
return;
if (gScanCssState == SCAN_CSS_STATE_OFF && !gScanSingleFrequency)
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return; return;
} }
if (gScanCssState == SCAN_CSS_STATE_SCANNING) if (gScanCssState == SCAN_CSS_STATE_SCANNING && gScanSingleFrequency) {
{
if (gScanSingleFrequency)
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return; return;
} }
}
if (gScanCssState == SCAN_CSS_STATE_FAILED) if (gScanCssState == SCAN_CSS_STATE_FAILED) {
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return; return;
} }
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
switch (gScannerEditState) switch (gScannerSaveState) {
{ case SCAN_SAVE_NO_PROMPT:
case 0:
if (!gScanSingleFrequency) if (!gScanSingleFrequency)
{ {
uint32_t freq250 = FREQUENCY_RoundToStep(gScanFrequency, 250); 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; uint32_t diff625 = gScanFrequency > freq625 ? gScanFrequency - freq625 : freq625 - gScanFrequency;
if(diff250 > diff625) { if(diff250 > diff625) {
gStepSetting = STEP_6_25kHz; stepSetting = STEP_6_25kHz;
gScanFrequency = freq625; gScanFrequency = freq625;
} }
else { else {
gStepSetting = STEP_2_5kHz; stepSetting = STEP_2_5kHz;
gScanFrequency = freq250; gScanFrequency = freq250;
} }
} }
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
{ gScannerSaveState = SCAN_SAVE_CHAN_SEL;
gScannerEditState = 1;
gScanChannel = gTxVfo->CHANNEL_SAVE; gScanChannel = gTxVfo->CHANNEL_SAVE;
gShowChPrefix = RADIO_CheckValidChannel(gTxVfo->CHANNEL_SAVE, false, 0); gShowChPrefix = RADIO_CheckValidChannel(gTxVfo->CHANNEL_SAVE, false, 0);
} }
else else {
{ gScannerSaveState = SCAN_SAVE_CHANNEL;
gScannerEditState = 2;
} }
gScanCssState = SCAN_CSS_STATE_FOUND; gScanCssState = SCAN_CSS_STATE_FOUND;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_MEMORY_CHANNEL; gAnotherVoiceID = VOICE_ID_MEMORY_CHANNEL;
#endif #endif
gRequestDisplayScreen = DISPLAY_SCANNER; gRequestDisplayScreen = DISPLAY_SCANNER;
gUpdateStatus = true; gUpdateStatus = true;
break; break;
case 1: case SCAN_SAVE_CHAN_SEL:
if (gInputBoxIndex == 0) if (gInputBoxIndex == 0) {
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gRequestDisplayScreen = DISPLAY_SCANNER; gRequestDisplayScreen = DISPLAY_SCANNER;
gScannerEditState = 2; gScannerSaveState = SCAN_SAVE_CHANNEL;
} }
break; break;
case 2: case SCAN_SAVE_CHANNEL:
if (!gScanSingleFrequency) if (!gScanSingleFrequency) {
{
RADIO_InitInfo(gTxVfo, gTxVfo->CHANNEL_SAVE, gScanFrequency); RADIO_InitInfo(gTxVfo, gTxVfo->CHANNEL_SAVE, gScanFrequency);
if (gScanUseCssResult) if (gScanUseCssResult) {
{
gTxVfo->freq_config_RX.CodeType = gScanCssResultType; gTxVfo->freq_config_RX.CodeType = gScanCssResultType;
gTxVfo->freq_config_RX.Code = gScanCssResultCode; gTxVfo->freq_config_RX.Code = gScanCssResultCode;
} }
gTxVfo->freq_config_TX = gTxVfo->freq_config_RX; 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(0, VFO_CONFIGURE_RELOAD);
RADIO_ConfigureChannel(1, 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; gTxVfo->freq_config_TX.Code = gScanCssResultCode;
} }
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) uint8_t chan;
{ if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
Channel = gScanChannel; chan = gScanChannel;
gEeprom.MrChannel[gEeprom.TX_VFO] = Channel; gEeprom.MrChannel[gEeprom.TX_VFO] = chan;
} }
else else {
{ chan = gTxVfo->Band + FREQ_CHANNEL_FIRST;
Channel = gTxVfo->Band + FREQ_CHANNEL_FIRST; gEeprom.FreqChannel[gEeprom.TX_VFO] = chan;
gEeprom.FreqChannel[gEeprom.TX_VFO] = Channel;
} }
gTxVfo->CHANNEL_SAVE = Channel; gTxVfo->CHANNEL_SAVE = chan;
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel; gEeprom.ScreenChannel[gEeprom.TX_VFO] = chan;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CONFIRM; gAnotherVoiceID = VOICE_ID_CONFIRM;
#endif #endif
gRequestDisplayScreen = DISPLAY_SCANNER; gRequestDisplayScreen = DISPLAY_SCANNER;
gRequestSaveChannel = 2; gRequestSaveChannel = 2;
gScannerEditState = 0; gScannerSaveState = SCAN_SAVE_NO_PROMPT;
break; break;
default: default:
@@ -278,23 +234,20 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
static void SCANNER_Key_STAR(bool bKeyPressed, bool bKeyHeld) static void SCANNER_Key_STAR(bool bKeyPressed, bool bKeyHeld)
{ {
if (!bKeyHeld && bKeyPressed) if (!bKeyHeld && bKeyPressed) {
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gFlagStartScan = true; SCANNER_Start(gScanSingleFrequency);
} }
return; return;
} }
static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Direction) static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Direction)
{ {
if (pKeyHeld) if (pKeyHeld) {
{
if (!bKeyPressed) if (!bKeyPressed)
return; return;
} }
else else {
{
if (!bKeyPressed) if (!bKeyPressed)
return; return;
@@ -302,8 +255,7 @@ static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Directio
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
} }
if (gScannerEditState == 1) if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
{
gScanChannel = NUMBER_AddWithWraparound(gScanChannel, Direction, 0, MR_CHANNEL_LAST); gScanChannel = NUMBER_AddWithWraparound(gScanChannel, Direction, 0, MR_CHANNEL_LAST);
gShowChPrefix = RADIO_CheckValidChannel(gScanChannel, false, 0); gShowChPrefix = RADIO_CheckValidChannel(gScanChannel, false, 0);
gRequestDisplayScreen = DISPLAY_SCANNER; 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) void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{ {
switch (Key) switch (Key) {
{
case KEY_0: case KEY_0:
case KEY_1: case KEY_1:
case KEY_2: 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; gScanSingleFrequency = singleFreq;
uint16_t BackupFrequency; gMonitor = false;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;
#endif
BK4819_StopScan(); BK4819_StopScan();
RADIO_SelectVfos(); RADIO_SelectVfos();
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
@@ -367,13 +321,13 @@ void SCANNER_Start(void)
gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + BAND6_400MHz; gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + BAND6_400MHz;
#endif #endif
BackupStep = gRxVfo->STEP_SETTING; uint8_t backupStep = gRxVfo->STEP_SETTING;
BackupFrequency = gRxVfo->StepFrequency; uint16_t backupFrequency = gRxVfo->StepFrequency;
RADIO_InitInfo(gRxVfo, gRxVfo->CHANNEL_SAVE, gRxVfo->pRX->Frequency); RADIO_InitInfo(gRxVfo, gRxVfo->CHANNEL_SAVE, gRxVfo->pRX->Frequency);
gRxVfo->STEP_SETTING = BackupStep; gRxVfo->STEP_SETTING = backupStep;
gRxVfo->StepFrequency = BackupFrequency; gRxVfo->StepFrequency = backupFrequency;
RADIO_SetupRegisters(true); RADIO_SetupRegisters(true);
@@ -381,23 +335,21 @@ void SCANNER_Start(void)
gIsNoaaMode = false; gIsNoaaMode = false;
#endif #endif
if (gScanSingleFrequency) if (gScanSingleFrequency) {
{
gScanCssState = SCAN_CSS_STATE_SCANNING; gScanCssState = SCAN_CSS_STATE_SCANNING;
gScanFrequency = gRxVfo->pRX->Frequency; gScanFrequency = gRxVfo->pRX->Frequency;
gStepSetting = gRxVfo->STEP_SETTING; stepSetting = gRxVfo->STEP_SETTING;
BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency); BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency);
BK4819_SetScanFrequency(gScanFrequency); BK4819_SetScanFrequency(gScanFrequency);
gUpdateStatus = true; gUpdateStatus = true;
} }
else else {
{
gScanCssState = SCAN_CSS_STATE_OFF; gScanCssState = SCAN_CSS_STATE_OFF;
gScanFrequency = 0xFFFFFFFF; gScanFrequency = 0xFFFFFFFF;
BK4819_PickRXFilterPathBasedOnFrequency(0xFFFFFFFF); BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency);
BK4819_EnableFrequencyScan(); BK4819_EnableFrequencyScan();
gUpdateStatus = true; gUpdateStatus = true;
@@ -408,7 +360,7 @@ void SCANNER_Start(void)
gScanDelay_10ms = scan_delay_10ms; gScanDelay_10ms = scan_delay_10ms;
gScanCssResultCode = 0xFF; gScanCssResultCode = 0xFF;
gScanCssResultType = 0xFF; gScanCssResultType = 0xFF;
gScanHitCount = 0; scanHitCount = 0;
gScanUseCssResult = false; gScanUseCssResult = false;
g_CxCSS_TAIL_Found = false; g_CxCSS_TAIL_Found = false;
g_CDCSS_Lost = false; g_CDCSS_Lost = false;
@@ -418,242 +370,130 @@ void SCANNER_Start(void)
g_VOX_Lost = false; g_VOX_Lost = false;
#endif #endif
g_SquelchLost = false; g_SquelchLost = false;
gScannerEditState = 0; gScannerSaveState = SCAN_SAVE_NO_PROMPT;
gScanProgressIndicator = 0; gScanProgressIndicator = 0;
} }
void SCANNER_Found() void SCANNER_TimeSlice10ms(void)
{ {
switch (gEeprom.SCAN_RESUME_MODE) if (gScreenToDisplay != DISPLAY_SCANNER)
{ return;
case SCAN_RESUME_TO:
if (!gScanPauseMode) if (gScanDelay_10ms > 0) {
{ gScanDelay_10ms--;
gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms; return;
gScheduleScanListen = false;
gScanPauseMode = true;
} }
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; break;
case SCAN_RESUME_CO: int32_t delta = result - gScanFrequency;
case SCAN_RESUME_SE: gScanFrequency = result;
gScanPauseDelayIn_10ms = 0;
gScheduleScanListen = false; if (delta < 0)
delta = -delta;
if (delta < 100)
scanHitCount++;
else
scanHitCount = 0;
BK4819_DisableFrequencyScan();
if (scanHitCount < 3) {
BK4819_EnableFrequencyScan();
}
else {
BK4819_SetScanFrequency(gScanFrequency);
gScanCssResultCode = 0xFF;
gScanCssResultType = 0xFF;
scanHitCount = 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; 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;
if (IS_MR_CHANNEL(gRxVfo->CHANNEL_SAVE)) { //memory scan BK4819_Disable();
lastFoundFrqOrChan = gRxVfo->CHANNEL_SAVE;
}
else { // frequency scan
lastFoundFrqOrChan = gRxVfo->freq_config_RX.Frequency;
}
if (scanResult == BK4819_CSS_RESULT_CDCSS) {
gScanKeepResult = true; const uint8_t Code = DCS_GetCdcssCode(cdcssFreq);
} if (Code != 0xFF)
{
void SCANNER_Stop(void) gScanCssResultCode = Code;
{ gScanCssResultType = CODE_TYPE_DIGITAL;
if(initialCROSS_BAND_RX_TX != CROSS_BAND_OFF) { gScanCssState = SCAN_CSS_STATE_FOUND;
gEeprom.CROSS_BAND_RX_TX = initialCROSS_BAND_RX_TX; gScanUseCssResult = true;
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; gUpdateStatus = true;
} }
} }
else { else if (scanResult == BK4819_CSS_RESULT_CTCSS) {
gRxVfo->freq_config_RX.Frequency = chFr; const uint8_t Code = DCS_GetCtcssCode(ctcssFreq);
RADIO_ApplyOffset(gRxVfo); if (Code != 0xFF) {
RADIO_ConfigureSquelchAndOutputPower(gRxVfo); if (Code == gScanCssResultCode && gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) {
if(channelChanged) { if (++scanHitCount >= 2) {
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_VFO, gRxVfo, 1); gScanCssState = SCAN_CSS_STATE_FOUND;
gScanUseCssResult = true;
gUpdateStatus = true;
}
}
else
scanHitCount = 0;
gScanCssResultType = CODE_TYPE_CONTINUOUS_TONE;
gScanCssResultCode = Code;
} }
} }
RADIO_SetupRegisters(true); if (gScanCssState < SCAN_CSS_STATE_FOUND) {
gUpdateDisplay = true; BK4819_SetScanFrequency(gScanFrequency);
} gScanDelay_10ms = scan_delay_10ms;
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; break;
} }
}
[[fallthrough]]; GUI_SelectNextDisplay(DISPLAY_SCANNER);
case SCAN_NEXT_CHAN_SCANLIST2:
if (chan2 >= 0)
{
if (RADIO_CheckValidChannel(chan2, false, 0))
{
currentScanList = SCAN_NEXT_CHAN_SCANLIST2;
gNextMrChannel = chan2;
break; 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: default:
case SCAN_NEXT_CHAN_MR:
currentScanList = SCAN_NEXT_CHAN_MR;
gNextMrChannel = prev_mr_chan;
chan = 0xff;
break; break;
} }
}
void SCANNER_TimeSlice500ms(void)
{
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;
gUpdateStatus = true;
} }
#endif
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; 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 "dcs.h"
#include "driver/keyboard.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_SCANNING,
SCAN_CSS_STATE_FOUND, SCAN_CSS_STATE_FOUND,
SCAN_CSS_STATE_FAILED SCAN_CSS_STATE_FAILED
}; } SCAN_CssState_t;
typedef enum SCAN_CssState_t SCAN_CssState_t; typedef enum
enum
{ {
SCAN_REV = -1, SCAN_SAVE_NO_PROMPT, // saving process not initiated
SCAN_OFF = 0, SCAN_SAVE_CHAN_SEL, // "SAVE: ", channel select prompt, actives only in channel mode
SCAN_FWD = +1 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 DCS_CodeType_t gScanCssResultType;
extern uint8_t gScanCssResultCode; extern uint8_t gScanCssResultCode;
extern bool gFlagStartScan;
extern bool gFlagStopScan; extern bool gFlagStopScan;
extern bool gScanSingleFrequency; extern bool gScanSingleFrequency;
extern uint8_t gScannerEditState; extern SCAN_SaveState_t gScannerSaveState;
extern uint8_t gScanChannel; extern uint8_t gScanChannel;
extern uint32_t gScanFrequency; extern uint32_t gScanFrequency;
extern bool gScanPauseMode;
extern SCAN_CssState_t gScanCssState; extern SCAN_CssState_t gScanCssState;
extern volatile bool gScheduleScanListen;
extern volatile uint16_t gScanPauseDelayIn_10ms;
extern uint8_t gScanProgressIndicator; extern uint8_t gScanProgressIndicator;
extern uint8_t gScanHitCount;
extern bool gScanUseCssResult; 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_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
void SCANNER_Start(void); void SCANNER_Start(bool singleFreq);
void SCANNER_Found(); void SCANNER_TimeSlice10ms(void);
void SCANNER_Stop(void); void SCANNER_TimeSlice500ms(void);
void SCANNER_ScanChannels(const bool storeBackupSettings, const int8_t scan_direction);
void SCANNER_ContinueScanning();
#endif #endif

4
misc.c
View File

@@ -155,6 +155,10 @@ uint8_t gVFO_RSSI_bar_level[2];
uint8_t gReducedService; uint8_t gReducedService;
uint8_t gBatteryVoltageIndex; uint8_t gBatteryVoltageIndex;
CssScanMode_t gCssScanMode; CssScanMode_t gCssScanMode;
volatile bool gScheduleScanListen = true;
volatile uint16_t gScanPauseDelayIn_10ms;
bool gUpdateRSSI; bool gUpdateRSSI;
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
AlarmState_t gAlarmState; 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 // if not equal CSS_SCAN_MODE_OFF we are scanning CTCSS/DCS
// this is a scanning inside RX ctcss/dcs menu // this is a scanning inside RX ctcss/dcs menu
extern CssScanMode_t gCssScanMode; 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 bool gUpdateRSSI;
extern AlarmState_t gAlarmState; extern AlarmState_t gAlarmState;
extern uint16_t gMenuCountdown; extern uint16_t gMenuCountdown;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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