From dbc520cf8d7e5abe467df0dbff74d445fef3fd35 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Sat, 23 May 2026 02:40:19 +0200 Subject: [PATCH] WIP: display detected CSS code during scan range --- App/app/app.c | 4 ++++ App/app/chFrScanner.c | 54 +++++++++++++++++++++++++++++++++++++++++++ App/app/chFrScanner.h | 3 +++ App/ui/main.c | 34 +++++++++++++++++++++++++++ 4 files changed, 95 insertions(+) diff --git a/App/app/app.c b/App/app/app.c index 869742b7..21d4a58d 100644 --- a/App/app/app.c +++ b/App/app/app.c @@ -1762,6 +1762,10 @@ void APP_TimeSlice10ms(void) SCANNER_TimeSlice10ms(); +#ifdef ENABLE_SCAN_RANGES + CHFRSCANNER_UpdateCssDetection(); +#endif + #ifdef ENABLE_AIRCOPY if (gScreenToDisplay == DISPLAY_AIRCOPY && gAircopyState == AIRCOPY_TRANSFER && gAirCopyIsSendMode == 1) { if (!AIRCOPY_SendMessage()) { diff --git a/App/app/chFrScanner.c b/App/app/chFrScanner.c index 7206ee7e..5a26a4ca 100644 --- a/App/app/chFrScanner.c +++ b/App/app/chFrScanner.c @@ -20,6 +20,10 @@ bool gScanPauseMode; #ifdef ENABLE_SCAN_RANGES uint32_t gScanRangeStart; uint32_t gScanRangeStop; +DCS_CodeType_t gScanRangeCssType = CODE_TYPE_OFF; +uint8_t gScanRangeCssCode = 0xFF; +static uint8_t scanRangeCssCandidate = 0xFF; +static uint8_t scanRangeCssHitCount = 0; #define SCAN_RANGE_SKIP_MAX 32 #if (SCAN_RANGE_SKIP_MAX & (SCAN_RANGE_SKIP_MAX - 1)) != 0 @@ -182,6 +186,56 @@ bool CHFRSCANNER_HasScanRangeExcludedOrdinal(uint32_t first_ordinal, uint32_t la return false; } + +void CHFRSCANNER_UpdateCssDetection(void) +{ + if (!gScanRangeStart || !FUNCTION_IsRx()) + { + gScanRangeCssType = CODE_TYPE_OFF; + gScanRangeCssCode = 0xFF; + scanRangeCssCandidate = 0xFF; + scanRangeCssHitCount = 0; + return; + } + + uint32_t cdcssFreq; + uint16_t ctcssFreq; + const BK4819_CssScanResult_t result = BK4819_GetCxCSSScanResult(&cdcssFreq, &ctcssFreq); + + if (result == BK4819_CSS_RESULT_CDCSS) + { + const uint8_t Code = DCS_GetCdcssCode(cdcssFreq); + if (Code != 0xFF && Code != gScanRangeCssCode) + { + gScanRangeCssType = CODE_TYPE_DIGITAL; + gScanRangeCssCode = Code; + scanRangeCssCandidate = 0xFF; + scanRangeCssHitCount = 0; + gUpdateDisplay = true; + } + } + else if (result == BK4819_CSS_RESULT_CTCSS) + { + const uint8_t Code = DCS_GetCtcssCode(ctcssFreq); + if (Code != 0xFF) + { + if (Code == scanRangeCssCandidate) + { + if (++scanRangeCssHitCount >= 2 && Code != gScanRangeCssCode) + { + gScanRangeCssType = CODE_TYPE_CONTINUOUS_TONE; + gScanRangeCssCode = Code; + gUpdateDisplay = true; + } + } + else + { + scanRangeCssCandidate = Code; + scanRangeCssHitCount = 1; + } + } + } +} #endif static void CHFRSCANNER_AbortActiveReception(void) diff --git a/App/app/chFrScanner.h b/App/app/chFrScanner.h index 264ccc73..e8400322 100644 --- a/App/app/chFrScanner.h +++ b/App/app/chFrScanner.h @@ -15,8 +15,11 @@ extern bool gScanPauseMode; #ifdef ENABLE_SCAN_RANGES extern uint32_t gScanRangeStart; extern uint32_t gScanRangeStop; +extern DCS_CodeType_t gScanRangeCssType; +extern uint8_t gScanRangeCssCode; bool CHFRSCANNER_ExcludeCurrentScanRange(void); bool CHFRSCANNER_HasScanRangeExcludedOrdinal(uint32_t first_ordinal, uint32_t last_ordinal); +void CHFRSCANNER_UpdateCssDetection(void); #endif void CHFRSCANNER_Found(void); diff --git a/App/ui/main.c b/App/ui/main.c index 24a67db1..d40c3bd2 100644 --- a/App/ui/main.c +++ b/App/ui/main.c @@ -1267,6 +1267,16 @@ void UI_DisplayMain(void) UI_FormatFrequency(gScanRangeStop, String); UI_PrintStringSmallNormal(String, 56, 0, line + shift + 1); + if (!isMainOnly() && gScanRangeCssCode != 0xFF) + { + if (gScanRangeCssType == CODE_TYPE_CONTINUOUS_TONE) + sprintf(String, "CTCSS %u.%uHz", CTCSS_Options[gScanRangeCssCode] / 10, CTCSS_Options[gScanRangeCssCode] % 10); + else + sprintf(String, "DCS D%03o%c", DCS_Options[gScanRangeCssCode], + gScanRangeCssType == CODE_TYPE_REVERSE_DIGITAL ? 'I' : 'N'); + UI_PrintStringSmallNormal(String, 6, 0, line + 2); + } + if (!isMainOnly()) continue; } @@ -1280,6 +1290,17 @@ void UI_DisplayMain(void) UI_PrintStringSmallNormal(String, 56, 0, line); UI_FormatFrequency(gScanRangeStop, String); UI_PrintStringSmallNormal(String, 56, 0, line + 1); + + if (gScanRangeCssCode != 0xFF) + { + if (gScanRangeCssType == CODE_TYPE_CONTINUOUS_TONE) + sprintf(String, "CTCSS:%u.%uHz", CTCSS_Options[gScanRangeCssCode] / 10, CTCSS_Options[gScanRangeCssCode] % 10); + else + sprintf(String, "DCS:D%03o%c", DCS_Options[gScanRangeCssCode], + gScanRangeCssType == CODE_TYPE_REVERSE_DIGITAL ? 'I' : 'N'); + UI_PrintStringSmallNormal(String, 2, 0, line + 2); + } + continue; #endif } @@ -2099,6 +2120,18 @@ void UI_DisplayMain(void) UI_MAIN_PrintAGC(false); #endif +#if defined(ENABLE_SCAN_RANGES) && defined(ENABLE_FEAT_F4HWN) + if (isMainOnly() && gScanRangeStart && gScanRangeCssCode != 0xFF) + { + if (gScanRangeCssType == CODE_TYPE_CONTINUOUS_TONE) + sprintf(String, "CTCSS %u.%uHz", CTCSS_Options[gScanRangeCssCode] / 10, CTCSS_Options[gScanRangeCssCode] % 10); + else + sprintf(String, "DCS D%03o%c", DCS_Options[gScanRangeCssCode], + gScanRangeCssType == CODE_TYPE_REVERSE_DIGITAL ? 'I' : 'N'); + UI_PrintStringSmallNormal(String, 2, 0, 6); + } +#endif + if (center_line == CENTER_LINE_NONE) { // we're free to use the middle line @@ -2152,6 +2185,7 @@ void UI_DisplayMain(void) else #endif + #ifdef ENABLE_RSSI_BAR if (rx) { center_line = CENTER_LINE_RSSI;