From d2a132f966b6420998d229c2f76caab6ac2a2408 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Fri, 9 Aug 2024 00:04:26 +0200 Subject: [PATCH 01/30] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 54cdc40..47c3355 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ Special thanks to Jean-Cyrille F6IWW, Fabrice 14RC123, David F4BPP, Olivier 14RC * add SetMet menu to set s-meter style (Classic or Tiny), * add SetLck menu to set what is locked (Keys or Keys + PTT), * add SetGui menu to set font size on the VFO baseline (Classic or Tiny), - * add TXLock menu to open TX on channel + * add TXLock menu to open TX on channel, * rename BatVol menu (52/63) to SysInf, which displays the firmware version in addition to the battery status, * improve PonMsg menu, * improve BackLt menu, From f42de8f7c34c9a8ff323deeb345fb0e1afb3d2da Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Sat, 10 Aug 2024 15:40:44 +0200 Subject: [PATCH 02/30] Let's go to v3.3 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c797710..7f856ad 100644 --- a/Makefile +++ b/Makefile @@ -217,7 +217,7 @@ ifeq ($(ENABLE_FEAT_F4HWN),1) VERSION_STRING_1 ?= v0.22 AUTHOR_STRING_2 ?= F4HWN - VERSION_STRING_2 ?= v3.2 + VERSION_STRING_2 ?= v3.3 AUTHOR_STRING ?= $(AUTHOR_STRING_1)+$(AUTHOR_STRING_2) VERSION_STRING ?= $(VERSION_STRING_2) From bf85a444d09054c47113207d5c071fc4a046adbd Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Sun, 11 Aug 2024 07:06:33 +0200 Subject: [PATCH 03/30] Air Copy UI refactoring --- Makefile | 2 +- helper/boot.c | 2 ++ ui/aircopy.c | 40 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 7f856ad..cf77eb5 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # ---- STOCK QUANSHENG FERATURES ---- ENABLE_FMRADIO ?= 0 ENABLE_UART ?= 1 -ENABLE_AIRCOPY ?= 0 +ENABLE_AIRCOPY ?= 1 ENABLE_NOAA ?= 0 ENABLE_VOICE ?= 0 ENABLE_VOX ?= 1 diff --git a/helper/boot.c b/helper/boot.c index ad56631..4ac9d5c 100644 --- a/helper/boot.c +++ b/helper/boot.c @@ -101,6 +101,8 @@ void BOOT_ProcessMode(BOOT_Mode_t Mode) gAircopyState = AIRCOPY_READY; + gEeprom.BACKLIGHT_TIME = 61; + GUI_SelectNextDisplay(DISPLAY_AIRCOPY); } #endif diff --git a/ui/aircopy.c b/ui/aircopy.c index 37b278d..f2020bd 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -27,10 +27,16 @@ #include "ui/helper.h" #include "ui/inputbox.h" +static int8_t map(int8_t x, int8_t in_min, int8_t in_max, int8_t out_min, int8_t out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + void UI_DisplayAircopy(void) { char String[16] = { 0 }; char *pPrintStr = { 0 }; + static bool crc[120] = { 0 }; + static uint8_t lErrorsDuringAirCopy = 0; UI_DisplayClear(); @@ -60,11 +66,39 @@ void UI_DisplayAircopy(void) memset(String, 0, sizeof(String)); if (gAirCopyIsSendMode == 0) { - sprintf(String, "RCV:%u E:%u", gAirCopyBlockNumber, gErrorsDuringAirCopy); + sprintf(String, "RCV:%02d%% E:%02d", map(gAirCopyBlockNumber + gErrorsDuringAirCopy, 0, 120, 0, 100), gErrorsDuringAirCopy); } else if (gAirCopyIsSendMode == 1) { - sprintf(String, "SND:%u", gAirCopyBlockNumber); + sprintf(String, "SND:%02d%%", map(gAirCopyBlockNumber + gErrorsDuringAirCopy, 0, 120, 0, 100)); } - UI_PrintString(String, 2, 127, 4, 8); + UI_PrintString(String, 2, 127, 5, 8); + + // Draw gauge + gFrameBuffer[4][2] = 0xff; + + for(uint8_t i = 1; i <= 122; i++) + { + gFrameBuffer[4][2 + i] = 0x81; + } + + if(gAirCopyBlockNumber + gErrorsDuringAirCopy != 0) + { + // Check CRC + if(gErrorsDuringAirCopy != lErrorsDuringAirCopy) + { + crc[gAirCopyBlockNumber + gErrorsDuringAirCopy - 1] = 1; + lErrorsDuringAirCopy = gErrorsDuringAirCopy; + } + + for(uint8_t i = 0; i < (gAirCopyBlockNumber + gErrorsDuringAirCopy); i++) + { + if(crc[i] == 0) + { + gFrameBuffer[4][i + 4] = 0xbd; + } + } + } + + gFrameBuffer[4][125] = 0xff; ST7565_BlitFullScreen(); } From 1bd71fce2f6687b3e7c08a9a9a27de6c2179e60e Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Sun, 11 Aug 2024 15:39:27 +0200 Subject: [PATCH 04/30] Fix approximative percent --- ui/aircopy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/aircopy.c b/ui/aircopy.c index f2020bd..9ea7df3 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -66,9 +66,9 @@ void UI_DisplayAircopy(void) memset(String, 0, sizeof(String)); if (gAirCopyIsSendMode == 0) { - sprintf(String, "RCV:%02d%% E:%02d", map(gAirCopyBlockNumber + gErrorsDuringAirCopy, 0, 120, 0, 100), gErrorsDuringAirCopy); + sprintf(String, "RCV:%02d%% E:%02d", map(gAirCopyBlockNumber, 0, 120, 0, 100), gErrorsDuringAirCopy); } else if (gAirCopyIsSendMode == 1) { - sprintf(String, "SND:%02d%%", map(gAirCopyBlockNumber + gErrorsDuringAirCopy, 0, 120, 0, 100)); + sprintf(String, "SND:%02d%%", map(gAirCopyBlockNumber, 0, 120, 0, 100)); } UI_PrintString(String, 2, 127, 5, 8); From f0aefd8e8fcdb1a436aae3f2aa699f2590bfebf0 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Sun, 11 Aug 2024 18:09:21 +0200 Subject: [PATCH 05/30] Improve percent --- ui/aircopy.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ui/aircopy.c b/ui/aircopy.c index 9ea7df3..5aaf42c 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -27,7 +27,7 @@ #include "ui/helper.h" #include "ui/inputbox.h" -static int8_t map(int8_t x, int8_t in_min, int8_t in_max, int8_t out_min, int8_t out_max) { +static int16_t map(int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } @@ -37,6 +37,7 @@ void UI_DisplayAircopy(void) char *pPrintStr = { 0 }; static bool crc[120] = { 0 }; static uint8_t lErrorsDuringAirCopy = 0; + uint16_t percent; UI_DisplayClear(); @@ -65,10 +66,13 @@ void UI_DisplayAircopy(void) } memset(String, 0, sizeof(String)); + + percent = map(gAirCopyBlockNumber * 100, 0, 120 * 100, 0, 100 * 100); + if (gAirCopyIsSendMode == 0) { - sprintf(String, "RCV:%02d%% E:%02d", map(gAirCopyBlockNumber, 0, 120, 0, 100), gErrorsDuringAirCopy); + sprintf(String, "RCV:%02u.%02u%% E:%d", percent / 100, percent % 100, gErrorsDuringAirCopy); } else if (gAirCopyIsSendMode == 1) { - sprintf(String, "SND:%02d%%", map(gAirCopyBlockNumber, 0, 120, 0, 100)); + sprintf(String, "SND:%02d%%", percent / 100); } UI_PrintString(String, 2, 127, 5, 8); From 99fbf9d3844c9f0fb1f72f977b44afa05e9a4a2a Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Sun, 11 Aug 2024 18:49:14 +0200 Subject: [PATCH 06/30] Improve percent --- ui/aircopy.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ui/aircopy.c b/ui/aircopy.c index 5aaf42c..66bf38d 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -27,10 +27,6 @@ #include "ui/helper.h" #include "ui/inputbox.h" -static int16_t map(int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max) { - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; -} - void UI_DisplayAircopy(void) { char String[16] = { 0 }; @@ -67,12 +63,12 @@ void UI_DisplayAircopy(void) memset(String, 0, sizeof(String)); - percent = map(gAirCopyBlockNumber * 100, 0, 120 * 100, 0, 100 * 100); + percent = (gAirCopyBlockNumber * 10000) / 120; if (gAirCopyIsSendMode == 0) { sprintf(String, "RCV:%02u.%02u%% E:%d", percent / 100, percent % 100, gErrorsDuringAirCopy); } else if (gAirCopyIsSendMode == 1) { - sprintf(String, "SND:%02d%%", percent / 100); + sprintf(String, "SND:%02u.%02u%%", percent / 100, percent % 100); } UI_PrintString(String, 2, 127, 5, 8); From d696720b74b569a2e57a7c676955c72238cc0f78 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Mon, 12 Aug 2024 01:15:54 +0200 Subject: [PATCH 07/30] Save 48 bytes --- ui/aircopy.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ui/aircopy.c b/ui/aircopy.c index 66bf38d..6697a6e 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -27,11 +27,19 @@ #include "ui/helper.h" #include "ui/inputbox.h" +static void set_bit(uint8_t* array, int bit_index) { + array[bit_index / 8] |= (1 << (bit_index % 8)); +} + +int get_bit(uint8_t* array, int bit_index) { + return (array[bit_index / 8] >> (bit_index % 8)) & 1; +} + void UI_DisplayAircopy(void) { char String[16] = { 0 }; char *pPrintStr = { 0 }; - static bool crc[120] = { 0 }; + static uint8_t crc[15] = { 0 }; static uint8_t lErrorsDuringAirCopy = 0; uint16_t percent; @@ -85,13 +93,13 @@ void UI_DisplayAircopy(void) // Check CRC if(gErrorsDuringAirCopy != lErrorsDuringAirCopy) { - crc[gAirCopyBlockNumber + gErrorsDuringAirCopy - 1] = 1; + set_bit(crc, gAirCopyBlockNumber + gErrorsDuringAirCopy); lErrorsDuringAirCopy = gErrorsDuringAirCopy; } for(uint8_t i = 0; i < (gAirCopyBlockNumber + gErrorsDuringAirCopy); i++) { - if(crc[i] == 0) + if(get_bit(crc, i) == 0) { gFrameBuffer[4][i + 4] = 0xbd; } From f98480175e29a5f6d42e984945fb7f73e7864ac9 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Mon, 12 Aug 2024 02:15:51 +0200 Subject: [PATCH 08/30] Refactoring --- app/aircopy.c | 5 +++++ ui/aircopy.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/aircopy.c b/app/aircopy.c index 57134b1..9e5532f 100644 --- a/app/aircopy.c +++ b/app/aircopy.c @@ -16,6 +16,10 @@ #ifdef ENABLE_AIRCOPY +//#if !defined(ENABLE_OVERLAY) +// #include "ARMCM0.h" +//#endif + #include "app/aircopy.h" #include "audio.h" #include "driver/bk4819.h" @@ -61,6 +65,7 @@ bool AIRCOPY_SendMessage(void) if (++gAirCopyBlockNumber >= 0x78) { gAircopyState = AIRCOPY_COMPLETE; + //NVIC_SystemReset(); } RADIO_SetTxParameters(); diff --git a/ui/aircopy.c b/ui/aircopy.c index 6697a6e..26e4dc0 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -31,7 +31,7 @@ static void set_bit(uint8_t* array, int bit_index) { array[bit_index / 8] |= (1 << (bit_index % 8)); } -int get_bit(uint8_t* array, int bit_index) { +static int get_bit(uint8_t* array, int bit_index) { return (array[bit_index / 8] >> (bit_index % 8)) & 1; } @@ -88,6 +88,8 @@ void UI_DisplayAircopy(void) gFrameBuffer[4][2 + i] = 0x81; } + gFrameBuffer[4][125] = 0xff; + if(gAirCopyBlockNumber + gErrorsDuringAirCopy != 0) { // Check CRC @@ -106,8 +108,6 @@ void UI_DisplayAircopy(void) } } - gFrameBuffer[4][125] = 0xff; - ST7565_BlitFullScreen(); } From bf90961944291d332b81f29496ccb23bdd7c57c9 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Mon, 12 Aug 2024 19:43:12 +0200 Subject: [PATCH 09/30] Save 88 bytes --- app/spectrum.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/app/spectrum.c b/app/spectrum.c index 2066c99..0896c76 100644 --- a/app/spectrum.c +++ b/app/spectrum.c @@ -789,32 +789,19 @@ static void DrawStatus() { #ifdef ENABLE_FEAT_F4HWN_SPECTRUM static void ShowChannelName(uint32_t f) { unsigned int i; - char s[12]; memset(String, 0, sizeof(String)); if ( isListening ) { for (i = 0; IS_MR_CHANNEL(i); i++) { - if (RADIO_CheckValidChannel(i, false, 0)) { - if (SETTINGS_FetchChannelFrequency(i) == f) { - memset(s, 0, sizeof(s)); - SETTINGS_FetchChannelName(s, i); - if (s[0] != 0) { - if ( strlen(String) != 0 ) - strcat(String, "/"); // Add a space to result - strcat(String, s); - } - break; - } + if (RADIO_CheckValidChannel(i, false, 0)) { + if (SETTINGS_FetchChannelFrequency(i) == f) { + SETTINGS_FetchChannelName(String, i); + UI_PrintStringSmallBold(String[0] ? String : "--", 8, 127, 1); + break; } + } } } - - if (String[0] != 0) { - if ( strlen(String) > 19 ) { - String[19] = 0; - } - UI_PrintStringSmallBold(String, 8, 127, 1); - } } #endif From 9c0df1355c020904c042195c3688556bae8bd3ce Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Tue, 13 Aug 2024 02:38:13 +0200 Subject: [PATCH 10/30] Save 8 bytes --- ui/status.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/ui/status.c b/ui/status.c index 24f1721..528aa0a 100644 --- a/ui/status.c +++ b/ui/status.c @@ -37,26 +37,16 @@ #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER static void convertTime(uint8_t *line, uint8_t type) { - char str[8] = ""; + uint16_t t = (type == 0) ? (gTxTimerCountdown_500ms / 2) : (3600 - gRxTimerCountdown_500ms / 2); - uint8_t m, s; // Declare variables for seconds, hours, minutes, and seconds - uint16_t t; + uint8_t m = t / 60; + uint8_t s = t % 60; // Utilisation de l'opérateur modulo pour simplifier le calcul des secondes - if(type == 0) // Tx timer - t = (gTxTimerCountdown_500ms / 2); - //t = ((gEeprom.TX_TIMEOUT_TIMER + 1) * 5) - (gTxTimerCountdown_500ms / 2); - else // Rx timer - t = 3600 - (gRxTimerCountdown_500ms / 2); - - m = t / 60; - s = t - (m * 60); - - gStatusLine[0] = 0x00; // Quick fix on display (on scanning I, II, etc.) - gStatusLine[7] = 0x00; // Quick fix on display (on scanning I, II, etc.) - gStatusLine[14] = 0x00; // Quick fix on display (on scanning I, II, etc.) + gStatusLine[0] = gStatusLine[7] = gStatusLine[14] = 0x00; // Quick fix on display (on scanning I, II, etc.) + char str[8]; sprintf(str, "%02d:%02d", m, s); - UI_PrintStringSmallBufferNormal(str, line + 0); + UI_PrintStringSmallBufferNormal(str, line); gUpdateStatus = true; } From efdea646b7290cc125cb37efba204a27e6d02929 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Tue, 13 Aug 2024 04:37:44 +0200 Subject: [PATCH 11/30] Save 16 bytes --- app/dtmf.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/app/dtmf.c b/app/dtmf.c index c7635c0..7376b96 100644 --- a/app/dtmf.c +++ b/app/dtmf.c @@ -171,18 +171,11 @@ bool DTMF_FindContact(const char *pContact, char *pResult) char DTMF_GetCharacter(const unsigned int code) { + if (code <= KEY_9) + return '0' + code; + switch (code) { - case KEY_0: return '0'; - case KEY_1: return '1'; - case KEY_2: return '2'; - case KEY_3: return '3'; - case KEY_4: return '4'; - case KEY_5: return '5'; - case KEY_6: return '6'; - case KEY_7: return '7'; - case KEY_8: return '8'; - case KEY_9: return '9'; case KEY_MENU: return 'A'; case KEY_UP: return 'B'; case KEY_DOWN: return 'C'; From 4a3b2770811f4024a2e20b91ff404c7c806e95fc Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Tue, 13 Aug 2024 04:49:41 +0200 Subject: [PATCH 12/30] Save 40 bytes --- app/main.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/app/main.c b/app/main.c index 554ccb8..231ec5f 100644 --- a/app/main.c +++ b/app/main.c @@ -405,23 +405,8 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) if (gScanStateDir != SCAN_OFF){ switch(Key) { - case KEY_0: - gEeprom.SCAN_LIST_DEFAULT = 0; - break; - case KEY_1: - gEeprom.SCAN_LIST_DEFAULT = 1; - break; - case KEY_2: - gEeprom.SCAN_LIST_DEFAULT = 2; - break; - case KEY_3: - gEeprom.SCAN_LIST_DEFAULT = 3; - break; - case KEY_4: - gEeprom.SCAN_LIST_DEFAULT = 4; - break; - case KEY_5: - gEeprom.SCAN_LIST_DEFAULT = 5; + case KEY_0...KEY_5: + gEeprom.SCAN_LIST_DEFAULT = Key; break; default: break; From b78115f8bfc680c88e64595dd80664d0580b6b4e Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Tue, 13 Aug 2024 18:50:32 +0200 Subject: [PATCH 13/30] UI gauge refactoring --- ui/aircopy.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/aircopy.c b/ui/aircopy.c index 26e4dc0..cb0f771 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -81,14 +81,16 @@ void UI_DisplayAircopy(void) UI_PrintString(String, 2, 127, 5, 8); // Draw gauge - gFrameBuffer[4][2] = 0xff; + gFrameBuffer[4][1] = 0x3c; + gFrameBuffer[4][2] = 0x42; for(uint8_t i = 1; i <= 122; i++) { gFrameBuffer[4][2 + i] = 0x81; } - gFrameBuffer[4][125] = 0xff; + gFrameBuffer[4][125] = 0x42; + gFrameBuffer[4][126] = 0x3c; if(gAirCopyBlockNumber + gErrorsDuringAirCopy != 0) { From d2235c0bdb4d01349bc927cfc47866ece6f63279 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Tue, 13 Aug 2024 20:15:45 +0200 Subject: [PATCH 14/30] Improve Air Copy and enable restart --- app/aircopy.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/aircopy.c b/app/aircopy.c index 9e5532f..8e5ee52 100644 --- a/app/aircopy.c +++ b/app/aircopy.c @@ -64,7 +64,8 @@ bool AIRCOPY_SendMessage(void) } if (++gAirCopyBlockNumber >= 0x78) { - gAircopyState = AIRCOPY_COMPLETE; + gAircopyState = AIRCOPY_READY; + //gAircopyState = AIRCOPY_COMPLETE; //NVIC_SystemReset(); } @@ -122,7 +123,8 @@ void AIRCOPY_StorePacket(void) } if (Offset == 0x1E00) { - gAircopyState = AIRCOPY_COMPLETE; + gAircopyState = AIRCOPY_READY; + //gAircopyState = AIRCOPY_COMPLETE; } gAirCopyBlockNumber++; From 69362495b390b1f344b3b1908d272a48ff9a5f33 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Tue, 13 Aug 2024 20:30:00 +0200 Subject: [PATCH 15/30] Improve Air Copy and enable restart --- ui/aircopy.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ui/aircopy.c b/ui/aircopy.c index cb0f771..7a218dd 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -47,6 +47,10 @@ void UI_DisplayAircopy(void) if (gAircopyState == AIRCOPY_READY) { pPrintStr = "AIR COPY(RDY)"; + for(uint8_t i = 0; i < 15; i++) + { + crc[i] = 0; + } } else if (gAircopyState == AIRCOPY_TRANSFER) { pPrintStr = "AIR COPY"; } else { From 7340e6cdc5a89e11183995614129be2019a67f93 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Tue, 13 Aug 2024 20:36:23 +0200 Subject: [PATCH 16/30] Improve Air Copy and enable restart --- ui/aircopy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/aircopy.c b/ui/aircopy.c index 7a218dd..c0e1b84 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -47,6 +47,7 @@ void UI_DisplayAircopy(void) if (gAircopyState == AIRCOPY_READY) { pPrintStr = "AIR COPY(RDY)"; + lErrorsDuringAirCopy = 0; for(uint8_t i = 0; i < 15; i++) { crc[i] = 0; From cb4b622a2a63732e555f46050ce87ed73ef0407f Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Wed, 14 Aug 2024 00:05:22 +0200 Subject: [PATCH 17/30] Revert last 3 commit --- app/aircopy.c | 6 ++---- ui/aircopy.c | 5 ----- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/app/aircopy.c b/app/aircopy.c index 8e5ee52..9e5532f 100644 --- a/app/aircopy.c +++ b/app/aircopy.c @@ -64,8 +64,7 @@ bool AIRCOPY_SendMessage(void) } if (++gAirCopyBlockNumber >= 0x78) { - gAircopyState = AIRCOPY_READY; - //gAircopyState = AIRCOPY_COMPLETE; + gAircopyState = AIRCOPY_COMPLETE; //NVIC_SystemReset(); } @@ -123,8 +122,7 @@ void AIRCOPY_StorePacket(void) } if (Offset == 0x1E00) { - gAircopyState = AIRCOPY_READY; - //gAircopyState = AIRCOPY_COMPLETE; + gAircopyState = AIRCOPY_COMPLETE; } gAirCopyBlockNumber++; diff --git a/ui/aircopy.c b/ui/aircopy.c index c0e1b84..cb0f771 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -47,11 +47,6 @@ void UI_DisplayAircopy(void) if (gAircopyState == AIRCOPY_READY) { pPrintStr = "AIR COPY(RDY)"; - lErrorsDuringAirCopy = 0; - for(uint8_t i = 0; i < 15; i++) - { - crc[i] = 0; - } } else if (gAircopyState == AIRCOPY_TRANSFER) { pPrintStr = "AIR COPY"; } else { From 19c0c05aaee88f7ee43b79d70697fd94e4422db0 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Wed, 14 Aug 2024 04:16:58 +0200 Subject: [PATCH 18/30] Air Copy UI refactoring --- misc.c | 2 ++ misc.h | 2 ++ ui/aircopy.c | 24 +++++++++++++----------- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/misc.c b/misc.c index 75d401c..6c99d51 100644 --- a/misc.c +++ b/misc.c @@ -119,6 +119,8 @@ enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx; uint8_t gDW = 0; uint8_t gCB = 0; bool gSaveRxMode = false; + uint8_t crc[15] = { 0 }; + uint8_t lErrorsDuringAirCopy = 0; #endif #ifdef ENABLE_AUDIO_BAR diff --git a/misc.h b/misc.h index fb5b4e6..9fcc6d5 100644 --- a/misc.h +++ b/misc.h @@ -171,6 +171,8 @@ extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx; extern uint8_t gDW; extern uint8_t gCB; extern bool gSaveRxMode; + extern uint8_t crc[15]; + extern uint8_t lErrorsDuringAirCopy; #endif #ifdef ENABLE_AUDIO_BAR diff --git a/ui/aircopy.c b/ui/aircopy.c index cb0f771..88e7af0 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -39,8 +39,6 @@ void UI_DisplayAircopy(void) { char String[16] = { 0 }; char *pPrintStr = { 0 }; - static uint8_t crc[15] = { 0 }; - static uint8_t lErrorsDuringAirCopy = 0; uint16_t percent; UI_DisplayClear(); @@ -78,19 +76,23 @@ void UI_DisplayAircopy(void) } else if (gAirCopyIsSendMode == 1) { sprintf(String, "SND:%02u.%02u%%", percent / 100, percent % 100); } - UI_PrintString(String, 2, 127, 5, 8); // Draw gauge - gFrameBuffer[4][1] = 0x3c; - gFrameBuffer[4][2] = 0x42; - - for(uint8_t i = 1; i <= 122; i++) + if(gAircopyState != AIRCOPY_READY) { - gFrameBuffer[4][2 + i] = 0x81; - } + UI_PrintString(String, 2, 127, 5, 8); - gFrameBuffer[4][125] = 0x42; - gFrameBuffer[4][126] = 0x3c; + gFrameBuffer[4][1] = 0x3c; + gFrameBuffer[4][2] = 0x42; + + for(uint8_t i = 1; i <= 122; i++) + { + gFrameBuffer[4][2 + i] = 0x81; + } + + gFrameBuffer[4][125] = 0x42; + gFrameBuffer[4][126] = 0x3c; + } if(gAirCopyBlockNumber + gErrorsDuringAirCopy != 0) { From 75480cac100252894c8205f077ed9db911d6fe4b Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Thu, 15 Aug 2024 01:43:26 +0200 Subject: [PATCH 19/30] Improve Air Copy and enable restart --- app/aircopy.c | 16 +++++++++++++++- misc.c | 1 + misc.h | 1 + ui/aircopy.c | 3 ++- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/app/aircopy.c b/app/aircopy.c index 9e5532f..cda195c 100644 --- a/app/aircopy.c +++ b/app/aircopy.c @@ -41,6 +41,14 @@ uint8_t gAirCopyIsSendMode; uint16_t g_FSK_Buffer[36]; +static void AIRCOPY_clear() +{ + for (uint8_t i = 0; i < 15; i++) + { + crc[i] = 0; + } +} + bool AIRCOPY_SendMessage(void) { static uint8_t gAircopySendCountdown = 1; @@ -183,12 +191,15 @@ static void AIRCOPY_Key_EXIT(bool bKeyPressed, bool bKeyHeld) } if (gInputBoxIndex == 0) { + gAircopyStep = 1; gFSKWriteIndex = 0; gAirCopyBlockNumber = 0; gInputBoxIndex = 0; - gErrorsDuringAirCopy = 0; + gErrorsDuringAirCopy = lErrorsDuringAirCopy = 0; gAirCopyIsSendMode = 0; + AIRCOPY_clear(); + BK4819_PrepareFSKReceive(); gAircopyState = AIRCOPY_TRANSFER; @@ -205,6 +216,7 @@ static void AIRCOPY_Key_MENU(bool bKeyPressed, bool bKeyHeld) return; } + gAircopyStep = 1; gFSKWriteIndex = 0; gAirCopyBlockNumber = 0; gInputBoxIndex = 0; @@ -213,6 +225,8 @@ static void AIRCOPY_Key_MENU(bool bKeyPressed, bool bKeyHeld) g_FSK_Buffer[1] = 0; g_FSK_Buffer[35] = 0xDCBA; + AIRCOPY_clear(); + GUI_DisplayScreen(); gAircopyState = AIRCOPY_TRANSFER; diff --git a/misc.c b/misc.c index 6c99d51..d8e3a89 100644 --- a/misc.c +++ b/misc.c @@ -121,6 +121,7 @@ enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx; bool gSaveRxMode = false; uint8_t crc[15] = { 0 }; uint8_t lErrorsDuringAirCopy = 0; + uint8_t gAircopyStep = 0; #endif #ifdef ENABLE_AUDIO_BAR diff --git a/misc.h b/misc.h index 9fcc6d5..bf28f1e 100644 --- a/misc.h +++ b/misc.h @@ -173,6 +173,7 @@ extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx; extern bool gSaveRxMode; extern uint8_t crc[15]; extern uint8_t lErrorsDuringAirCopy; + extern uint8_t gAircopyStep; #endif #ifdef ENABLE_AUDIO_BAR diff --git a/ui/aircopy.c b/ui/aircopy.c index 88e7af0..0c3da4c 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -49,6 +49,7 @@ void UI_DisplayAircopy(void) pPrintStr = "AIR COPY"; } else { pPrintStr = "AIR COPY(CMP)"; + gAircopyState = AIRCOPY_READY; } UI_PrintString(pPrintStr, 2, 127, 0, 8); @@ -78,7 +79,7 @@ void UI_DisplayAircopy(void) } // Draw gauge - if(gAircopyState != AIRCOPY_READY) + if(gAircopyStep != 0) { UI_PrintString(String, 2, 127, 5, 8); From e0083131706ef57f22783e49f359ec4142997274 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Thu, 15 Aug 2024 04:34:00 +0200 Subject: [PATCH 20/30] Add SetTmr --- app/menu.c | 11 ++++++++++- main.c | 4 ++-- misc.c | 1 + misc.h | 1 + settings.c | 32 ++++++++++++++++++++++++++++++++ ui/menu.c | 4 ++++ ui/menu.h | 1 + ui/status.c | 4 ++-- 8 files changed, 53 insertions(+), 5 deletions(-) diff --git a/app/menu.c b/app/menu.c index 1f7ca9b..bc07c38 100644 --- a/app/menu.c +++ b/app/menu.c @@ -254,6 +254,9 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax) case MENU_350EN: #ifndef ENABLE_FEAT_F4HWN case MENU_SCREN: +#endif +#ifdef ENABLE_FEAT_F4HWN + case MENU_SET_TMR: #endif //*pMin = 0; *pMax = ARRAY_SIZE(gSubMenu_OFF_ON) - 1; @@ -895,10 +898,13 @@ void MENU_AcceptSetting(void) case MENU_SET_GUI: gSetting_set_gui = gSubMenuSelection; break; + case MENU_SET_TMR: + gSetting_set_tmr = gSubMenuSelection; + break; case MENU_TX_LOCK: gTxVfo->TX_LOCK = gSubMenuSelection; gRequestSaveChannel = 1; - return; + return; #endif } @@ -1316,6 +1322,9 @@ void MENU_ShowCurrentSetting(void) case MENU_SET_GUI: gSubMenuSelection = gSetting_set_gui; break; + case MENU_SET_TMR: + gSubMenuSelection = gSetting_set_tmr; + break; case MENU_TX_LOCK: gSubMenuSelection = gTxVfo->TX_LOCK; break; diff --git a/main.c b/main.c index e6fedb6..7359658 100644 --- a/main.c +++ b/main.c @@ -129,9 +129,9 @@ void Main(void) gEeprom.KEY_LOCK = 0; SETTINGS_SaveSettings(); #ifndef ENABLE_VOX - gMenuCursor = 63; // move to hidden section, fix me if change... !!! Remove VOX and Mic Bar + gMenuCursor = 64; // move to hidden section, fix me if change... !!! Remove VOX and Mic Bar #else - gMenuCursor = 65; // move to hidden section, fix me if change... !!! + gMenuCursor = 66; // move to hidden section, fix me if change... !!! #endif gSubMenuSelection = gSetting_F_LOCK; #endif diff --git a/misc.c b/misc.c index d8e3a89..811d1eb 100644 --- a/misc.c +++ b/misc.c @@ -114,6 +114,7 @@ enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx; bool gSetting_set_lck = false; bool gSetting_set_met = 0; bool gSetting_set_gui = 0; + bool gSetting_set_tmr = 0; bool gSetting_set_ptt_session; uint8_t gDebug; uint8_t gDW = 0; diff --git a/misc.h b/misc.h index bf28f1e..4fb8cb0 100644 --- a/misc.h +++ b/misc.h @@ -166,6 +166,7 @@ extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx; extern bool gSetting_set_lck; extern bool gSetting_set_met; extern bool gSetting_set_gui; + extern bool gSetting_set_tmr; extern bool gSetting_set_ptt_session; extern uint8_t gDebug; extern uint8_t gDW; diff --git a/settings.c b/settings.c index d4acb46..298ae4d 100644 --- a/settings.c +++ b/settings.c @@ -324,6 +324,7 @@ void SETTINGS_InitEEPROM(void) gSetting_set_tot = (((Data[6] & 0xF0) >> 4) < 4) ? ((Data[6] & 0xF0) >> 4) : 0; gSetting_set_eot = (((Data[6] & 0x0F)) < 4) ? ((Data[6] & 0x0F)) : 0; + /* int tmp = ((Data[5] & 0xF0) >> 4); gSetting_set_inv = (((tmp >> 0) & 0x01) < 2) ? ((tmp >> 0) & 0x01): 0; @@ -332,6 +333,21 @@ void SETTINGS_InitEEPROM(void) gSetting_set_gui = (((tmp >> 3) & 0x01) < 2) ? ((tmp >> 3) & 0x01): 0; gSetting_set_ctr = (((Data[5] & 0x0F)) > 00 && ((Data[5] & 0x0F)) < 16) ? ((Data[5] & 0x0F)) : 10; + gSetting_set_tmr = ((Data[4] & 1) < 2) ? (Data[4] & 1): 0; + */ + + int tmp = (Data[5] & 0xF0) >> 4; + + gSetting_set_inv = (tmp >> 0) & 0x01; + gSetting_set_lck = (tmp >> 1) & 0x01; + gSetting_set_met = (tmp >> 2) & 0x01; + gSetting_set_gui = (tmp >> 3) & 0x01; + + int ctr_value = Data[5] & 0x0F; + gSetting_set_ctr = (ctr_value > 0 && ctr_value < 16) ? ctr_value : 10; + + gSetting_set_tmr = Data[4] & 1; + // And set special session settings for actions gSetting_set_ptt_session = gSetting_set_ptt; gEeprom.KEY_LOCK_PTT = gSetting_set_lck; @@ -700,6 +716,14 @@ void SETTINGS_SaveSettings(void) #ifdef ENABLE_FEAT_F4HWN memset(State, 0xFF, sizeof(State)); + /* + tmp = 0; + + if(gSetting_set_tmr == 1) + tmp = tmp | (1 << 0); + + State[4] = tmp; + tmp = 0; if(gSetting_set_inv == 1) @@ -710,6 +734,14 @@ void SETTINGS_SaveSettings(void) tmp = tmp | (1 << 2); if (gSetting_set_gui == 1) tmp = tmp | (1 << 3); + */ + + State[4] = gSetting_set_tmr ? (1 << 0) : 0; + + tmp = (gSetting_set_inv << 0) | + (gSetting_set_lck << 1) | + (gSetting_set_met << 2) | + (gSetting_set_gui << 3); State[5] = ((tmp << 4) | (gSetting_set_ctr & 0x0F)); State[6] = ((gSetting_set_tot << 4) | (gSetting_set_eot & 0x0F)); diff --git a/ui/menu.c b/ui/menu.c index a6a29da..6be7848 100644 --- a/ui/menu.c +++ b/ui/menu.c @@ -146,6 +146,7 @@ const t_menu_item MenuList[] = {"SetLck", MENU_SET_LCK }, {"SetMet", MENU_SET_MET }, {"SetGui", MENU_SET_GUI }, + {"SetTmr", MENU_SET_TMR }, #endif // hidden menu items from here on // enabled if pressing both the PTT and upper side button at power-on @@ -737,6 +738,9 @@ void UI_DisplayMenu(void) case MENU_350EN: #ifndef ENABLE_FEAT_F4HWN case MENU_SCREN: +#endif +#ifdef ENABLE_FEAT_F4HWN + case MENU_SET_TMR: #endif strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]); break; diff --git a/ui/menu.h b/ui/menu.h index 4f40530..2025cd9 100644 --- a/ui/menu.h +++ b/ui/menu.h @@ -135,6 +135,7 @@ enum MENU_SET_LCK, MENU_SET_MET, MENU_SET_GUI, + MENU_SET_TMR, #endif MENU_BATCAL, // battery voltage calibration MENU_F1SHRT, diff --git a/ui/status.c b/ui/status.c index 528aa0a..32d4e48 100644 --- a/ui/status.c +++ b/ui/status.c @@ -143,11 +143,11 @@ void UI_DisplayStatus() if(!SCANNER_IsScanning()) { #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER - if(gCurrentFunction == FUNCTION_TRANSMIT) + if(gCurrentFunction == FUNCTION_TRANSMIT && gSetting_set_tmr == true) { convertTime(line, 0); } - else if(FUNCTION_IsRx()) + else if(FUNCTION_IsRx() && gSetting_set_tmr == true) { convertTime(line, 1); } From 7c53df8d2b88ef769fac3ea46f16f9d4644402d1 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Thu, 15 Aug 2024 05:07:20 +0200 Subject: [PATCH 21/30] Remove mysterious AES_Encrypt call --- app/uart.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/app/uart.c b/app/uart.c index 8d8feac..a1b1fc5 100644 --- a/app/uart.c +++ b/app/uart.c @@ -42,6 +42,7 @@ #include "sram-overlay.h" #endif +#define UNUSED(x) (void)(x) #define DMA_INDEX(x, y) (((x) + (y)) % sizeof(UART_DMA_Buffer)) @@ -211,20 +212,25 @@ static void SendVersion(void) static bool IsBadChallenge(const uint32_t *pKey, const uint32_t *pIn, const uint32_t *pResponse) { - unsigned int i; - uint32_t IV[4]; + #ifdef ENABLE_FEAT_F4HWN + UNUSED(pKey); + UNUSED(pIn); + UNUSED(pResponse); + #else + unsigned int i; + uint32_t IV[4]; - IV[0] = 0; - IV[1] = 0; - IV[2] = 0; - IV[3] = 0; + IV[0] = 0; + IV[1] = 0; + IV[2] = 0; + IV[3] = 0; - AES_Encrypt(pKey, IV, pIn, IV, true); - - for (i = 0; i < 4; i++) - if (IV[i] != pResponse[i]) - return true; + AES_Encrypt(pKey, IV, pIn, IV, true); + for (i = 0; i < 4; i++) + if (IV[i] != pResponse[i]) + return true; + #endif return false; } From 74862d1ac2af5acec5d135e4b7c3133d64d4d67c Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Fri, 16 Aug 2024 00:11:09 +0200 Subject: [PATCH 22/30] Check tab only... --- am_fix.c | 320 ++--- am_fix.h | 16 +- app/action.c | 614 ++++----- app/action.h | 18 +- app/aircopy.c | 294 ++--- app/aircopy.h | 6 +- app/app.c | 2986 ++++++++++++++++++++--------------------- app/chFrScanner.c | 440 +++---- app/chFrScanner.h | 4 +- app/common.c | 6 +- app/dtmf.c | 578 ++++---- app/dtmf.h | 40 +- app/flashlight.c | 128 +- app/fm.c | 752 +++++------ app/fm.h | 6 +- app/generic.c | 244 ++-- app/menu.c | 3000 +++++++++++++++++++++--------------------- app/menu.h | 2 +- app/scanner.c | 692 +++++----- app/scanner.h | 14 +- app/uart.c | 780 +++++------ audio.c | 608 ++++----- audio.h | 222 ++-- bitmaps.c | 391 +++--- bitmaps.h | 4 +- board.c | 802 +++++------ dcs.c | 130 +- dcs.h | 12 +- debugging.h | 36 +- driver/adc.c | 178 +-- driver/adc.h | 66 +- driver/aes.c | 70 +- driver/backlight.c | 166 +-- driver/bk1080-regs.h | 40 +- driver/bk1080.c | 120 +- driver/bk4819-regs.h | 532 ++++---- driver/bk4819.c | 2586 ++++++++++++++++++------------------ driver/bk4819.h | 58 +- driver/crc.c | 38 +- driver/eeprom.c | 46 +- driver/flash.c | 6 +- driver/flash.h | 24 +- driver/gpio.h | 56 +- driver/i2c.c | 208 +-- driver/i2c.h | 4 +- driver/keyboard.c | 200 +-- driver/keyboard.h | 40 +- driver/spi.c | 124 +- driver/spi.h | 24 +- driver/st7565.c | 314 ++--- driver/st7565.h | 2 +- driver/system.c | 14 +- driver/systick.c | 30 +- driver/uart.c | 122 +- font.c | 1202 ++++++++--------- font.h | 2 +- frequencies.c | 348 ++--- frequencies.h | 78 +- functions.c | 276 ++-- functions.h | 16 +- helper/battery.c | 294 ++--- helper/boot.c | 120 +- helper/boot.h | 10 +- init.c | 18 +- main.c | 274 ++-- misc.c | 150 +-- misc.h | 152 +-- radio.c | 1718 ++++++++++++------------ radio.h | 130 +- scheduler.c | 98 +- screenshot.h | 50 +- settings.c | 1292 +++++++++--------- settings.h | 338 ++--- sram-overlay.c | 144 +- ui/aircopy.c | 126 +- ui/aircopy.h | 2 +- ui/battery.c | 32 +- ui/fmradio.c | 114 +- ui/fmradio.h | 2 +- ui/helper.c | 382 +++--- ui/helper.h | 8 +- ui/inputbox.c | 22 +- ui/lock.c | 192 +-- ui/lock.h | 2 +- ui/main.c | 2174 +++++++++++++++--------------- ui/main.h | 20 +- ui/menu.c | 1600 +++++++++++----------- ui/menu.h | 208 +-- ui/scanner.c | 92 +- ui/status.c | 344 ++--- ui/ui.c | 62 +- ui/ui.h | 14 +- ui/welcome.c | 180 +-- version.c | 12 +- version.h | 4 +- 95 files changed, 15257 insertions(+), 15258 deletions(-) diff --git a/am_fix.c b/am_fix.c index dade239..3c4c9e4 100644 --- a/am_fix.c +++ b/am_fix.c @@ -38,8 +38,8 @@ typedef struct { - uint16_t reg_val; - int8_t gain_dB; + uint16_t reg_val; + int8_t gain_dB; } __attribute__((packed)) t_gain_table; // REG_10 AGC gain table @@ -85,11 +85,11 @@ typedef struct // // these 4 tables need a measuring/calibration update // -//// static const int16_t lna_short_dB[] = { -19, -16, -11, 0}; // was (but wrong) -// static const int16_t lna_short_dB[] = { (-28), (-24), (-19), 0}; // corrected'ish -// static const int16_t lna_dB[] = { (-24), (-19), (-14), ( -9), (-6), (-4), (-2), 0}; -// static const int16_t mixer_dB[] = { ( -8), ( -6), ( -3), 0}; -// static const int16_t pga_dB[] = { (-33), (-27), (-21), (-15), (-9), (-6), (-3), 0}; +//// static const int16_t lna_short_dB[] = { -19, -16, -11, 0}; // was (but wrong) +// static const int16_t lna_short_dB[] = { (-28), (-24), (-19), 0}; // corrected'ish +// static const int16_t lna_dB[] = { (-24), (-19), (-14), ( -9), (-6), (-4), (-2), 0}; +// static const int16_t mixer_dB[] = { ( -8), ( -6), ( -3), 0}; +// static const int16_t pga_dB[] = { (-33), (-27), (-21), (-15), (-9), (-6), (-3), 0}; // lookup table is hugely easier than writing code to do the same // @@ -99,50 +99,50 @@ typedef struct #if LOOKUP_TABLE static const t_gain_table gain_table[] = { - {0x03BE, -7}, // 0 .. 3 5 3 6 .. 0dB -4dB 0dB -3dB .. -7dB original + {0x03BE, -7}, // 0 .. 3 5 3 6 .. 0dB -4dB 0dB -3dB .. -7dB original - {0x0000,-93}, // 1 .. 0 0 0 0 .. -28dB -24dB -8dB -33dB .. -93dB - {0x0008,-91}, // 2 .. 0 0 1 0 .. -28dB -24dB -6dB -33dB .. -91dB - {0x0010,-88}, // 3 .. 0 0 2 0 .. -28dB -24dB -3dB -33dB .. -88dB - {0x0001,-87}, // 4 .. 0 0 0 1 .. -28dB -24dB -8dB -27dB .. -87dB - {0x0009,-85}, // 5 .. 0 0 1 1 .. -28dB -24dB -6dB -27dB .. -85dB - {0x0011,-82}, // 6 .. 0 0 2 1 .. -28dB -24dB -3dB -27dB .. -82dB - {0x0002,-81}, // 7 .. 0 0 0 2 .. -28dB -24dB -8dB -21dB .. -81dB - {0x000A,-79}, // 8 .. 0 0 1 2 .. -28dB -24dB -6dB -21dB .. -79dB - {0x0012,-76}, // 9 .. 0 0 2 2 .. -28dB -24dB -3dB -21dB .. -76dB - {0x0003,-75}, // 10 .. 0 0 0 3 .. -28dB -24dB -8dB -15dB .. -75dB - {0x000B,-73}, // 11 .. 0 0 1 3 .. -28dB -24dB -6dB -15dB .. -73dB - {0x0013,-70}, // 12 .. 0 0 2 3 .. -28dB -24dB -3dB -15dB .. -70dB - {0x0004,-69}, // 13 .. 0 0 0 4 .. -28dB -24dB -8dB -9dB .. -69dB - {0x000C,-67}, // 14 .. 0 0 1 4 .. -28dB -24dB -6dB -9dB .. -67dB - {0x000D,-64}, // 15 .. 0 0 1 5 .. -28dB -24dB -6dB -6dB .. -64dB - {0x001C,-61}, // 16 .. 0 0 3 4 .. -28dB -24dB 0dB - 9dB .. -61dB - {0x001D,-58}, // 17 .. 0 0 3 5 .. -28dB -24dB 0dB -6dB .. -58dB - {0x001E,-55}, // 18 .. 0 0 3 6 .. -28dB -24dB 0dB -3dB .. -55dB - {0x001F,-52}, // 19 .. 0 0 3 7 .. -28dB -24dB 0dB 0dB .. -52dB - {0x003E,-50}, // 20 .. 0 1 3 6 .. -28dB -19dB 0dB -3dB .. -50dB - {0x003F,-47}, // 21 .. 0 1 3 7 .. -28dB -19dB 0dB 0dB .. -47dB - {0x005E,-45}, // 22 .. 0 2 3 6 .. -28dB -14dB 0dB -3dB .. -45dB - {0x005F,-42}, // 23 .. 0 2 3 7 .. -28dB -14dB 0dB 0dB .. -42dB - {0x007E,-40}, // 24 .. 0 3 3 6 .. -28dB -9dB 0dB -3dB .. -40dB - {0x007F,-37}, // 25 .. 0 3 3 7 .. -28dB -9dB 0dB 0dB .. -37dB - {0x009F,-34}, // 26 .. 0 4 3 7 .. -28dB -6dB 0dB 0dB .. -34dB - {0x00BF,-32}, // 27 .. 0 5 3 7 .. -28dB -4dB 0dB 0dB .. -32dB - {0x00DF,-30}, // 28 .. 0 6 3 7 .. -28dB -2dB 0dB 0dB .. -30dB - {0x00FF,-28}, // 29 .. 0 7 3 7 .. -28dB 0dB 0dB 0dB .. -28dB - {0x01DF,-26}, // 30 .. 1 6 3 7 .. -24dB -2dB 0dB 0dB .. -26dB - {0x01FF,-24}, // 31 .. 1 7 3 7 .. -24dB 0dB 0dB 0dB .. -24dB - {0x02BF,-23}, // 32 .. 2 5 3 7 .. -19dB -4dB 0dB 0dB .. -23dB - {0x02DF,-21}, // 33 .. 2 6 3 7 .. -19dB -2dB 0dB -0dB .. -21dB - {0x02FF,-19}, // 34 .. 2 7 3 7 .. -19dB 0dB 0dB 0dB .. -19dB - {0x035E,-17}, // 35 .. 3 2 3 6 .. 0dB -14dB 0dB -3dB .. -17dB - {0x035F,-14}, // 36 .. 3 2 3 7 .. 0dB -14dB 0dB 0dB .. -14dB - {0x037E,-12}, // 37 .. 3 3 3 6 .. 0dB -9dB 0dB -3dB .. -12dB - {0x037F,-9}, // 38 .. 3 3 3 7 .. 0dB -9dB 0dB 0dB .. -9dB - {0x038F,-6}, // 39 .. 3 4 3 7 .. 0dB - 6dB 0dB 0dB .. -6dB - {0x03BF,-4}, // 40 .. 3 5 3 7 .. 0dB -4dB 0dB 0dB .. -4dB - {0x03DF,-2}, // 41 .. 3 6 3 7 .. 0dB - 2dB 0dB 0dB .. -2dB - {0x03FF,0} // 42 .. 3 7 3 7 .. 0dB 0dB 0dB 0dB .. 0dB + {0x0000,-93}, // 1 .. 0 0 0 0 .. -28dB -24dB -8dB -33dB .. -93dB + {0x0008,-91}, // 2 .. 0 0 1 0 .. -28dB -24dB -6dB -33dB .. -91dB + {0x0010,-88}, // 3 .. 0 0 2 0 .. -28dB -24dB -3dB -33dB .. -88dB + {0x0001,-87}, // 4 .. 0 0 0 1 .. -28dB -24dB -8dB -27dB .. -87dB + {0x0009,-85}, // 5 .. 0 0 1 1 .. -28dB -24dB -6dB -27dB .. -85dB + {0x0011,-82}, // 6 .. 0 0 2 1 .. -28dB -24dB -3dB -27dB .. -82dB + {0x0002,-81}, // 7 .. 0 0 0 2 .. -28dB -24dB -8dB -21dB .. -81dB + {0x000A,-79}, // 8 .. 0 0 1 2 .. -28dB -24dB -6dB -21dB .. -79dB + {0x0012,-76}, // 9 .. 0 0 2 2 .. -28dB -24dB -3dB -21dB .. -76dB + {0x0003,-75}, // 10 .. 0 0 0 3 .. -28dB -24dB -8dB -15dB .. -75dB + {0x000B,-73}, // 11 .. 0 0 1 3 .. -28dB -24dB -6dB -15dB .. -73dB + {0x0013,-70}, // 12 .. 0 0 2 3 .. -28dB -24dB -3dB -15dB .. -70dB + {0x0004,-69}, // 13 .. 0 0 0 4 .. -28dB -24dB -8dB -9dB .. -69dB + {0x000C,-67}, // 14 .. 0 0 1 4 .. -28dB -24dB -6dB -9dB .. -67dB + {0x000D,-64}, // 15 .. 0 0 1 5 .. -28dB -24dB -6dB -6dB .. -64dB + {0x001C,-61}, // 16 .. 0 0 3 4 .. -28dB -24dB 0dB - 9dB .. -61dB + {0x001D,-58}, // 17 .. 0 0 3 5 .. -28dB -24dB 0dB -6dB .. -58dB + {0x001E,-55}, // 18 .. 0 0 3 6 .. -28dB -24dB 0dB -3dB .. -55dB + {0x001F,-52}, // 19 .. 0 0 3 7 .. -28dB -24dB 0dB 0dB .. -52dB + {0x003E,-50}, // 20 .. 0 1 3 6 .. -28dB -19dB 0dB -3dB .. -50dB + {0x003F,-47}, // 21 .. 0 1 3 7 .. -28dB -19dB 0dB 0dB .. -47dB + {0x005E,-45}, // 22 .. 0 2 3 6 .. -28dB -14dB 0dB -3dB .. -45dB + {0x005F,-42}, // 23 .. 0 2 3 7 .. -28dB -14dB 0dB 0dB .. -42dB + {0x007E,-40}, // 24 .. 0 3 3 6 .. -28dB -9dB 0dB -3dB .. -40dB + {0x007F,-37}, // 25 .. 0 3 3 7 .. -28dB -9dB 0dB 0dB .. -37dB + {0x009F,-34}, // 26 .. 0 4 3 7 .. -28dB -6dB 0dB 0dB .. -34dB + {0x00BF,-32}, // 27 .. 0 5 3 7 .. -28dB -4dB 0dB 0dB .. -32dB + {0x00DF,-30}, // 28 .. 0 6 3 7 .. -28dB -2dB 0dB 0dB .. -30dB + {0x00FF,-28}, // 29 .. 0 7 3 7 .. -28dB 0dB 0dB 0dB .. -28dB + {0x01DF,-26}, // 30 .. 1 6 3 7 .. -24dB -2dB 0dB 0dB .. -26dB + {0x01FF,-24}, // 31 .. 1 7 3 7 .. -24dB 0dB 0dB 0dB .. -24dB + {0x02BF,-23}, // 32 .. 2 5 3 7 .. -19dB -4dB 0dB 0dB .. -23dB + {0x02DF,-21}, // 33 .. 2 6 3 7 .. -19dB -2dB 0dB -0dB .. -21dB + {0x02FF,-19}, // 34 .. 2 7 3 7 .. -19dB 0dB 0dB 0dB .. -19dB + {0x035E,-17}, // 35 .. 3 2 3 6 .. 0dB -14dB 0dB -3dB .. -17dB + {0x035F,-14}, // 36 .. 3 2 3 7 .. 0dB -14dB 0dB 0dB .. -14dB + {0x037E,-12}, // 37 .. 3 3 3 6 .. 0dB -9dB 0dB -3dB .. -12dB + {0x037F,-9}, // 38 .. 3 3 3 7 .. 0dB -9dB 0dB 0dB .. -9dB + {0x038F,-6}, // 39 .. 3 4 3 7 .. 0dB - 6dB 0dB 0dB .. -6dB + {0x03BF,-4}, // 40 .. 3 5 3 7 .. 0dB -4dB 0dB 0dB .. -4dB + {0x03DF,-2}, // 41 .. 3 6 3 7 .. 0dB - 2dB 0dB 0dB .. -2dB + {0x03FF,0} // 42 .. 3 7 3 7 .. 0dB 0dB 0dB 0dB .. 0dB }; const uint8_t gain_table_size = ARRAY_SIZE(gain_table); @@ -163,12 +163,12 @@ typedef union { uint16_t __raw; } GainData; - static const int8_t lna_short_dB[] = {-28, -24, -19, 0}; // corrected'ish - static const int8_t lna_dB[] = {-24, -19, -14, -9, -6, -4, -2, 0}; - static const int8_t mixer_dB[] = { -8, -6, -3, 0}; - static const int8_t pga_dB[] = {-33, -27, -21, -15, -9, -6, -3, 0}; + static const int8_t lna_short_dB[] = {-28, -24, -19, 0}; // corrected'ish + static const int8_t lna_dB[] = {-24, -19, -14, -9, -6, -4, -2, 0}; + static const int8_t mixer_dB[] = { -8, -6, -3, 0}; + static const int8_t pga_dB[] = {-33, -27, -21, -15, -9, -6, -3, 0}; - unsigned i; + unsigned i; for (uint8_t lnaSIdx = 0; lnaSIdx < ARRAY_SIZE(lna_short_dB); lnaSIdx++) { for (uint8_t lnaIdx = 0; lnaIdx < ARRAY_SIZE(lna_dB); lnaIdx++) { for (uint8_t mixerIdx = 0; mixerIdx < ARRAY_SIZE(mixer_dB); mixerIdx++) { @@ -209,9 +209,9 @@ typedef union { #ifdef ENABLE_AM_FIX_SHOW_DATA - // display update rate - static const unsigned int display_update_rate = 250 / 10; // max 250ms display update rate - unsigned int counter = 0; + // display update rate + static const unsigned int display_update_rate = 250 / 10; // max 250ms display update rate + unsigned int counter = 0; #endif unsigned int gain_table_index[2] = {0, 0}; @@ -228,27 +228,27 @@ int8_t currentGainDiff; bool enabled = true; void AM_fix_init(void) -{ // called at boot-up - for (int i = 0; i < 2; i++) { - gain_table_index[i] = 0; // re-start with original QS setting - } +{ // called at boot-up + for (int i = 0; i < 2; i++) { + gain_table_index[i] = 0; // re-start with original QS setting + } #if !LOOKUP_TABLE - CreateTable(); + CreateTable(); #endif } void AM_fix_reset(const unsigned vfo) -{ // reset the AM fixer upper - if (vfo > 1) - return; +{ // reset the AM fixer upper + if (vfo > 1) + return; - #ifdef ENABLE_AM_FIX_SHOW_DATA - counter = 0; - #endif + #ifdef ENABLE_AM_FIX_SHOW_DATA + counter = 0; + #endif - prev_rssi[vfo] = 0; - hold_counter[vfo] = 0; - gain_table_index_prev[vfo] = 0; + prev_rssi[vfo] = 0; + hold_counter[vfo] = 0; + gain_table_index_prev[vfo] = 0; } // adjust the RX gain to try and prevent the AM demodulator from @@ -260,138 +260,138 @@ void AM_fix_reset(const unsigned vfo) // void AM_fix_10ms(const unsigned vfo) { - if(!gSetting_AM_fix || !enabled || vfo > 1 ) - return; + if(!gSetting_AM_fix || !enabled || vfo > 1 ) + return; - if (gCurrentFunction != FUNCTION_FOREGROUND && !FUNCTION_IsRx()) { + if (gCurrentFunction != FUNCTION_FOREGROUND && !FUNCTION_IsRx()) { #ifdef ENABLE_AM_FIX_SHOW_DATA - counter = display_update_rate; // queue up a display update as soon as we switch to RX mode + counter = display_update_rate; // queue up a display update as soon as we switch to RX mode #endif - return; - } + return; + } #ifdef ENABLE_AM_FIX_SHOW_DATA - if (counter > 0) { - if (++counter >= display_update_rate) { // trigger a display update - counter = 0; - gUpdateDisplay = true; - } - } + if (counter > 0) { + if (++counter >= display_update_rate) { // trigger a display update + counter = 0; + gUpdateDisplay = true; + } + } #endif - static uint32_t lastFreq[2]; - if(gEeprom.VfoInfo[vfo].pRX->Frequency != lastFreq[vfo]) { - lastFreq[vfo] = gEeprom.VfoInfo[vfo].pRX->Frequency; - AM_fix_reset(vfo); - } + static uint32_t lastFreq[2]; + if(gEeprom.VfoInfo[vfo].pRX->Frequency != lastFreq[vfo]) { + lastFreq[vfo] = gEeprom.VfoInfo[vfo].pRX->Frequency; + AM_fix_reset(vfo); + } - int16_t rssi; - { // sample the current RSSI level - // average it with the previous rssi (a bit of noise/spike immunity) - const int16_t new_rssi = BK4819_GetRSSI(); - rssi = (prev_rssi[vfo] > 0) ? (prev_rssi[vfo] + new_rssi) / 2 : new_rssi; - prev_rssi[vfo] = new_rssi; - } + int16_t rssi; + { // sample the current RSSI level + // average it with the previous rssi (a bit of noise/spike immunity) + const int16_t new_rssi = BK4819_GetRSSI(); + rssi = (prev_rssi[vfo] > 0) ? (prev_rssi[vfo] + new_rssi) / 2 : new_rssi; + prev_rssi[vfo] = new_rssi; + } #ifdef ENABLE_AM_FIX_SHOW_DATA - { - static int16_t lastRssi; + { + static int16_t lastRssi; - if (lastRssi != rssi) { // rssi changed - lastRssi = rssi; + if (lastRssi != rssi) { // rssi changed + lastRssi = rssi; - if (counter == 0) { - counter = 1; - gUpdateDisplay = true; // trigger a display update - } - } - } + if (counter == 0) { + counter = 1; + gUpdateDisplay = true; // trigger a display update + } + } + } #endif - // automatically adjust the RF RX gain + // automatically adjust the RF RX gain - // update the gain hold counter - if (hold_counter[vfo] > 0) - hold_counter[vfo]--; + // update the gain hold counter + if (hold_counter[vfo] > 0) + hold_counter[vfo]--; - // dB difference between actual and desired RSSI level - int16_t diff_dB = (rssi - desired_rssi) / 2; + // dB difference between actual and desired RSSI level + int16_t diff_dB = (rssi - desired_rssi) / 2; - if (diff_dB > 0) { // decrease gain - unsigned int index = gain_table_index[vfo]; // current position we're at + if (diff_dB > 0) { // decrease gain + unsigned int index = gain_table_index[vfo]; // current position we're at - if (diff_dB >= 10) { // jump immediately to a new gain setting - // this greatly speeds up initial gain reduction (but reduces noise/spike immunity) + if (diff_dB >= 10) { // jump immediately to a new gain setting + // this greatly speeds up initial gain reduction (but reduces noise/spike immunity) - const int16_t desired_gain_dB = (int16_t)gain_table[index].gain_dB - diff_dB + 8; // get no closer than 8dB (bit of noise/spike immunity) + const int16_t desired_gain_dB = (int16_t)gain_table[index].gain_dB - diff_dB + 8; // get no closer than 8dB (bit of noise/spike immunity) - // scan the table to see what index to jump straight too - while (index > 1) - if (gain_table[--index].gain_dB <= desired_gain_dB) - break; - } - else - { // incrementally reduce the gain .. taking it slow improves noise/spike immunity - if (index > 1) - index--; // slow step-by-step gain reduction - } + // scan the table to see what index to jump straight too + while (index > 1) + if (gain_table[--index].gain_dB <= desired_gain_dB) + break; + } + else + { // incrementally reduce the gain .. taking it slow improves noise/spike immunity + if (index > 1) + index--; // slow step-by-step gain reduction + } - index = MAX(1u, index); + index = MAX(1u, index); - if (gain_table_index[vfo] != index) - { - gain_table_index[vfo] = index; - hold_counter[vfo] = 30; // 300ms hold - } - } + if (gain_table_index[vfo] != index) + { + gain_table_index[vfo] = index; + hold_counter[vfo] = 30; // 300ms hold + } + } - if (diff_dB >= -6) // 6dB hysterisis (help reduce gain hunting) - hold_counter[vfo] = 30; // 300ms hold + if (diff_dB >= -6) // 6dB hysterisis (help reduce gain hunting) + hold_counter[vfo] = 30; // 300ms hold - if (hold_counter[vfo] == 0) - { // hold has been released, we're free to increase gain - const unsigned int index = gain_table_index[vfo] + 1; // move up to next gain index - gain_table_index[vfo] = MIN(index, gain_table_size - 1u); - } + if (hold_counter[vfo] == 0) + { // hold has been released, we're free to increase gain + const unsigned int index = gain_table_index[vfo] + 1; // move up to next gain index + gain_table_index[vfo] = MIN(index, gain_table_size - 1u); + } - { // apply the new settings to the front end registers - const unsigned int index = gain_table_index[vfo]; + { // apply the new settings to the front end registers + const unsigned int index = gain_table_index[vfo]; - // remember the new table index - gain_table_index_prev[vfo] = index; - currentGainDiff = gain_table[0].gain_dB - gain_table[index].gain_dB; - BK4819_WriteRegister(BK4819_REG_13, gain_table[index].reg_val); + // remember the new table index + gain_table_index_prev[vfo] = index; + currentGainDiff = gain_table[0].gain_dB - gain_table[index].gain_dB; + BK4819_WriteRegister(BK4819_REG_13, gain_table[index].reg_val); #ifdef ENABLE_AGC_SHOW_DATA - UI_MAIN_PrintAGC(true); + UI_MAIN_PrintAGC(true); #endif - } + } #ifdef ENABLE_AM_FIX_SHOW_DATA - if (counter == 0) { - counter = 1; - gUpdateDisplay = true; - } + if (counter == 0) { + counter = 1; + gUpdateDisplay = true; + } #endif } #ifdef ENABLE_AM_FIX_SHOW_DATA void AM_fix_print_data(const unsigned vfo, char *s) { - if (s != NULL && vfo < ARRAY_SIZE(gain_table_index)) { - const unsigned int index = gain_table_index[vfo]; - sprintf(s, "%2u %4ddB %3u", index, gain_table[index].gain_dB, prev_rssi[vfo]); - counter = 0; - } + if (s != NULL && vfo < ARRAY_SIZE(gain_table_index)) { + const unsigned int index = gain_table_index[vfo]; + sprintf(s, "%2u %4ddB %3u", index, gain_table[index].gain_dB, prev_rssi[vfo]); + counter = 0; + } } #endif int8_t AM_fix_get_gain_diff() { - return currentGainDiff; + return currentGainDiff; } void AM_fix_enable(bool on) { - enabled = on; + enabled = on; } #endif diff --git a/am_fix.h b/am_fix.h index db8f31e..3667301 100644 --- a/am_fix.h +++ b/am_fix.h @@ -21,14 +21,14 @@ #include #ifdef ENABLE_AM_FIX - void AM_fix_init(void); - void AM_fix_reset(const unsigned vfo); - void AM_fix_10ms(const unsigned vfo); - #ifdef ENABLE_AM_FIX_SHOW_DATA - void AM_fix_print_data(const unsigned vfo, char *s); - #endif - int8_t AM_fix_get_gain_diff(); - void AM_fix_enable(bool on); + void AM_fix_init(void); + void AM_fix_reset(const unsigned vfo); + void AM_fix_10ms(const unsigned vfo); + #ifdef ENABLE_AM_FIX_SHOW_DATA + void AM_fix_print_data(const unsigned vfo, char *s); + #endif + int8_t AM_fix_get_gain_diff(); + void AM_fix_enable(bool on); #endif diff --git a/app/action.c b/app/action.c index 021c72f..73a2f0b 100644 --- a/app/action.c +++ b/app/action.c @@ -23,16 +23,16 @@ #include "app/common.h" #include "app/dtmf.h" #ifdef ENABLE_FLASHLIGHT - #include "app/flashlight.h" + #include "app/flashlight.h" #endif #ifdef ENABLE_FMRADIO - #include "app/fm.h" + #include "app/fm.h" #endif #include "app/scanner.h" #include "audio.h" #include "bsp/dp32g030/gpio.h" #ifdef ENABLE_FMRADIO - #include "driver/bk1080.h" + #include "driver/bk1080.h" #endif #include "driver/bk4819.h" #include "driver/gpio.h" @@ -60,59 +60,59 @@ inline static void ACTION_1750() { ACTION_AlarmOr1750(true); }; inline static void ACTION_ScanRestart() { ACTION_Scan(true); }; void (*action_opt_table[])(void) = { - [ACTION_OPT_NONE] = &FUNCTION_NOP, - [ACTION_OPT_POWER] = &ACTION_Power, - [ACTION_OPT_MONITOR] = &ACTION_Monitor, - [ACTION_OPT_SCAN] = &ACTION_ScanRestart, - [ACTION_OPT_KEYLOCK] = &COMMON_KeypadLockToggle, - [ACTION_OPT_A_B] = &COMMON_SwitchVFOs, - [ACTION_OPT_VFO_MR] = &COMMON_SwitchVFOMode, - [ACTION_OPT_SWITCH_DEMODUL] = &ACTION_SwitchDemodul, + [ACTION_OPT_NONE] = &FUNCTION_NOP, + [ACTION_OPT_POWER] = &ACTION_Power, + [ACTION_OPT_MONITOR] = &ACTION_Monitor, + [ACTION_OPT_SCAN] = &ACTION_ScanRestart, + [ACTION_OPT_KEYLOCK] = &COMMON_KeypadLockToggle, + [ACTION_OPT_A_B] = &COMMON_SwitchVFOs, + [ACTION_OPT_VFO_MR] = &COMMON_SwitchVFOMode, + [ACTION_OPT_SWITCH_DEMODUL] = &ACTION_SwitchDemodul, #ifdef ENABLE_FLASHLIGHT - [ACTION_OPT_FLASHLIGHT] = &ACTION_FlashLight, + [ACTION_OPT_FLASHLIGHT] = &ACTION_FlashLight, #else - [ACTION_OPT_FLASHLIGHT] = &FUNCTION_NOP, + [ACTION_OPT_FLASHLIGHT] = &FUNCTION_NOP, #endif #ifdef ENABLE_VOX - [ACTION_OPT_VOX] = &ACTION_Vox, + [ACTION_OPT_VOX] = &ACTION_Vox, #else - [ACTION_OPT_VOX] = &FUNCTION_NOP, + [ACTION_OPT_VOX] = &FUNCTION_NOP, #endif #ifdef ENABLE_FMRADIO - [ACTION_OPT_FM] = &ACTION_FM, + [ACTION_OPT_FM] = &ACTION_FM, #else - [ACTION_OPT_FM] = &FUNCTION_NOP, + [ACTION_OPT_FM] = &FUNCTION_NOP, #endif #ifdef ENABLE_ALARM - [ACTION_OPT_ALARM] = &ACTION_Alarm, + [ACTION_OPT_ALARM] = &ACTION_Alarm, #else - [ACTION_OPT_ALARM] = &FUNCTION_NOP, + [ACTION_OPT_ALARM] = &FUNCTION_NOP, #endif #ifdef ENABLE_TX1750 - [ACTION_OPT_1750] = &ACTION_1750, + [ACTION_OPT_1750] = &ACTION_1750, #else - [ACTION_OPT_1750] = &FUNCTION_NOP, + [ACTION_OPT_1750] = &FUNCTION_NOP, #endif #ifdef ENABLE_BLMIN_TMP_OFF - [ACTION_OPT_BLMIN_TMP_OFF] = &ACTION_BlminTmpOff, + [ACTION_OPT_BLMIN_TMP_OFF] = &ACTION_BlminTmpOff, #else - [ACTION_OPT_BLMIN_TMP_OFF] = &FUNCTION_NOP, + [ACTION_OPT_BLMIN_TMP_OFF] = &FUNCTION_NOP, #endif #ifdef ENABLE_FEAT_F4HWN - [ACTION_OPT_RXMODE] = &ACTION_RxMode, - [ACTION_OPT_MAINONLY] = &ACTION_MainOnly, - [ACTION_OPT_PTT] = &ACTION_Ptt, - [ACTION_OPT_WN] = &ACTION_Wn, - [ACTION_OPT_BACKLIGHT] = &ACTION_BackLight, + [ACTION_OPT_RXMODE] = &ACTION_RxMode, + [ACTION_OPT_MAINONLY] = &ACTION_MainOnly, + [ACTION_OPT_PTT] = &ACTION_Ptt, + [ACTION_OPT_WN] = &ACTION_Wn, + [ACTION_OPT_BACKLIGHT] = &ACTION_BackLight, #else - [ACTION_OPT_RXMODE] = &FUNCTION_NOP, + [ACTION_OPT_RXMODE] = &FUNCTION_NOP, #endif }; @@ -120,285 +120,285 @@ static_assert(ARRAY_SIZE(action_opt_table) == ACTION_OPT_LEN); void ACTION_Power(void) { - if (++gTxVfo->OUTPUT_POWER > OUTPUT_POWER_HIGH) - gTxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW1; + if (++gTxVfo->OUTPUT_POWER > OUTPUT_POWER_HIGH) + gTxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW1; - gRequestSaveChannel = 1; + gRequestSaveChannel = 1; - gRequestDisplayScreen = gScreenToDisplay; + gRequestDisplayScreen = gScreenToDisplay; #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_POWER; + gAnotherVoiceID = VOICE_ID_POWER; #endif } void ACTION_Monitor(void) { - if (gCurrentFunction != FUNCTION_MONITOR) { // enable the monitor - RADIO_SelectVfos(); + if (gCurrentFunction != FUNCTION_MONITOR) { // enable the monitor + RADIO_SelectVfos(); #ifdef ENABLE_NOAA - if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gIsNoaaMode) - gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST; + if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gIsNoaaMode) + gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST; #endif - RADIO_SetupRegisters(true); - APP_StartListening(FUNCTION_MONITOR); - return; - } + RADIO_SetupRegisters(true); + APP_StartListening(FUNCTION_MONITOR); + return; + } - gMonitor = false; + gMonitor = false; - if (gScanStateDir != SCAN_OFF) { - gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms; - gScheduleScanListen = false; - gScanPauseMode = true; - } + if (gScanStateDir != SCAN_OFF) { + gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms; + gScheduleScanListen = false; + gScanPauseMode = true; + } #ifdef ENABLE_NOAA - if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode) { - gNOAA_Countdown_10ms = NOAA_countdown_10ms; - gScheduleNOAA = false; - } + if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode) { + gNOAA_Countdown_10ms = NOAA_countdown_10ms; + gScheduleNOAA = false; + } #endif - RADIO_SetupRegisters(true); + RADIO_SetupRegisters(true); #ifdef ENABLE_FMRADIO - if (gFmRadioMode) { - FM_Start(); - gRequestDisplayScreen = DISPLAY_FM; - } - else + if (gFmRadioMode) { + FM_Start(); + gRequestDisplayScreen = DISPLAY_FM; + } + else #endif - gRequestDisplayScreen = gScreenToDisplay; + gRequestDisplayScreen = gScreenToDisplay; } void ACTION_Scan(bool bRestart) { - (void)bRestart; + (void)bRestart; #ifdef ENABLE_FMRADIO - if (gFmRadioMode) { - ACTION_Scan_FM(bRestart); - return; - } + if (gFmRadioMode) { + ACTION_Scan_FM(bRestart); + return; + } #endif - if (SCANNER_IsScanning()) { - return; - } + if (SCANNER_IsScanning()) { + return; + } - // not scanning - gMonitor = false; + // not scanning + gMonitor = false; #ifdef ENABLE_DTMF_CALLING - DTMF_clear_RX(); + DTMF_clear_RX(); #endif - gDTMF_RX_live_timeout = 0; - memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); + gDTMF_RX_live_timeout = 0; + memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); - RADIO_SelectVfos(); + RADIO_SelectVfos(); #ifdef ENABLE_NOAA - if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) { - return; - } + if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) { + return; + } #endif - GUI_SelectNextDisplay(DISPLAY_MAIN); + GUI_SelectNextDisplay(DISPLAY_MAIN); - if (gScanStateDir != SCAN_OFF) { - // already scanning + if (gScanStateDir != SCAN_OFF) { + // already scanning - if (!IS_MR_CHANNEL(gNextMrChannel)) { - CHFRSCANNER_Stop(); + if (!IS_MR_CHANNEL(gNextMrChannel)) { + CHFRSCANNER_Stop(); #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_SCANNING_STOP; + gAnotherVoiceID = VOICE_ID_SCANNING_STOP; #endif - return; - } + return; + } - // channel mode. Keep scanning but toggle between scan lists - gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 6; + // channel mode. Keep scanning but toggle between scan lists + gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 6; - // jump to the next channel - CHFRSCANNER_Start(false, gScanStateDir); - gScanPauseDelayIn_10ms = 1; - gScheduleScanListen = false; - } else { - // start scanning - CHFRSCANNER_Start(true, SCAN_FWD); + // jump to the next channel + CHFRSCANNER_Start(false, gScanStateDir); + gScanPauseDelayIn_10ms = 1; + gScheduleScanListen = false; + } else { + // start scanning + CHFRSCANNER_Start(true, SCAN_FWD); #ifdef ENABLE_VOICE - AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN); - AUDIO_PlaySingleVoice(true); + AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN); + AUDIO_PlaySingleVoice(true); #endif - // clear the other vfo's rssi level (to hide the antenna symbol) - gVFO_RSSI_bar_level[(gEeprom.RX_VFO + 1) & 1U] = 0; + // clear the other vfo's rssi level (to hide the antenna symbol) + gVFO_RSSI_bar_level[(gEeprom.RX_VFO + 1) & 1U] = 0; - // let the user see DW is not active - gDualWatchActive = false; - } + // let the user see DW is not active + gDualWatchActive = false; + } - gUpdateStatus = true; + gUpdateStatus = true; } void ACTION_SwitchDemodul(void) { - gRequestSaveChannel = 1; + gRequestSaveChannel = 1; - gTxVfo->Modulation++; + gTxVfo->Modulation++; - if(gTxVfo->Modulation == MODULATION_UKNOWN) - gTxVfo->Modulation = MODULATION_FM; + if(gTxVfo->Modulation == MODULATION_UKNOWN) + gTxVfo->Modulation = MODULATION_FM; } void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { - if (gScreenToDisplay == DISPLAY_MAIN && gDTMF_InputMode){ - // entering DTMF code + if (gScreenToDisplay == DISPLAY_MAIN && gDTMF_InputMode){ + // entering DTMF code - gPttWasReleased = true; + gPttWasReleased = true; - if (Key != KEY_SIDE1 || bKeyHeld || !bKeyPressed){ - return; - } + if (Key != KEY_SIDE1 || bKeyHeld || !bKeyPressed){ + return; + } - // side1 btn pressed + // side1 btn pressed - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - gRequestDisplayScreen = DISPLAY_MAIN; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gRequestDisplayScreen = DISPLAY_MAIN; - if (gDTMF_InputBox_Index <= 0) { - // turn off DTMF input box if no codes left - gDTMF_InputMode = false; - return; - } + if (gDTMF_InputBox_Index <= 0) { + // turn off DTMF input box if no codes left + gDTMF_InputMode = false; + return; + } - // DTMF codes are in the input box - gDTMF_InputBox[--gDTMF_InputBox_Index] = '-'; // delete one code + // DTMF codes are in the input box + gDTMF_InputBox[--gDTMF_InputBox_Index] = '-'; // delete one code #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_CANCEL; + gAnotherVoiceID = VOICE_ID_CANCEL; #endif - return; - } + return; + } - enum ACTION_OPT_t funcShort = ACTION_OPT_NONE; - enum ACTION_OPT_t funcLong = ACTION_OPT_NONE; - switch(Key) { - case KEY_SIDE1: - funcShort = gEeprom.KEY_1_SHORT_PRESS_ACTION; - funcLong = gEeprom.KEY_1_LONG_PRESS_ACTION; - break; - case KEY_SIDE2: - funcShort = gEeprom.KEY_2_SHORT_PRESS_ACTION; - funcLong = gEeprom.KEY_2_LONG_PRESS_ACTION; - break; - case KEY_MENU: - funcLong = gEeprom.KEY_M_LONG_PRESS_ACTION; - break; - default: - break; - } + enum ACTION_OPT_t funcShort = ACTION_OPT_NONE; + enum ACTION_OPT_t funcLong = ACTION_OPT_NONE; + switch(Key) { + case KEY_SIDE1: + funcShort = gEeprom.KEY_1_SHORT_PRESS_ACTION; + funcLong = gEeprom.KEY_1_LONG_PRESS_ACTION; + break; + case KEY_SIDE2: + funcShort = gEeprom.KEY_2_SHORT_PRESS_ACTION; + funcLong = gEeprom.KEY_2_LONG_PRESS_ACTION; + break; + case KEY_MENU: + funcLong = gEeprom.KEY_M_LONG_PRESS_ACTION; + break; + default: + break; + } - if (!bKeyHeld && bKeyPressed) // button pushed - { - return; - } + if (!bKeyHeld && bKeyPressed) // button pushed + { + return; + } - // held or released beyond this point + // held or released beyond this point - if(!(bKeyHeld && !bKeyPressed)) // don't beep on released after hold - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + if(!(bKeyHeld && !bKeyPressed)) // don't beep on released after hold + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - if (bKeyHeld || bKeyPressed) // held - { - funcShort = funcLong; + if (bKeyHeld || bKeyPressed) // held + { + funcShort = funcLong; - // For screenshot - #ifdef ENABLE_FEAT_F4HWN_SCREENSHOT - getScreenShot(); - #endif + // For screenshot + #ifdef ENABLE_FEAT_F4HWN_SCREENSHOT + getScreenShot(); + #endif - if (!bKeyPressed) //ignore release if held - return; - } + if (!bKeyPressed) //ignore release if held + return; + } - // held or released after short press beyond this point + // held or released after short press beyond this point - action_opt_table[funcShort](); + action_opt_table[funcShort](); } #ifdef ENABLE_FMRADIO void ACTION_FM(void) { - if (gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_MONITOR) - { - gInputBoxIndex = 0; + if (gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_MONITOR) + { + gInputBoxIndex = 0; - if (gFmRadioMode) { - FM_TurnOff(); - gFlagReconfigureVfos = true; - gRequestDisplayScreen = DISPLAY_MAIN; + if (gFmRadioMode) { + FM_TurnOff(); + gFlagReconfigureVfos = true; + gRequestDisplayScreen = DISPLAY_MAIN; #ifdef ENABLE_VOX - gVoxResumeCountdown = 80; + gVoxResumeCountdown = 80; #endif - return; - } + return; + } - gMonitor = false; + gMonitor = false; - RADIO_SelectVfos(); - RADIO_SetupRegisters(true); + RADIO_SelectVfos(); + RADIO_SetupRegisters(true); - FM_Start(); + FM_Start(); - gRequestDisplayScreen = DISPLAY_FM; - } + gRequestDisplayScreen = DISPLAY_FM; + } } static void ACTION_Scan_FM(bool bRestart) { - if (FUNCTION_IsRx()) - return; + if (FUNCTION_IsRx()) + return; - GUI_SelectNextDisplay(DISPLAY_FM); + GUI_SelectNextDisplay(DISPLAY_FM); - gMonitor = false; + gMonitor = false; - if (gFM_ScanState != FM_SCAN_OFF) { - FM_PlayAndUpdate(); + if (gFM_ScanState != FM_SCAN_OFF) { + FM_PlayAndUpdate(); #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_SCANNING_STOP; + gAnotherVoiceID = VOICE_ID_SCANNING_STOP; #endif - return; - } + return; + } - uint16_t freq; + uint16_t freq; - if (bRestart) { - gFM_AutoScan = true; - gFM_ChannelPosition = 0; - FM_EraseChannels(); - freq = BK1080_GetFreqLoLimit(gEeprom.FM_Band); - } else { - gFM_AutoScan = false; - gFM_ChannelPosition = 0; - freq = gEeprom.FM_FrequencyPlaying; - } + if (bRestart) { + gFM_AutoScan = true; + gFM_ChannelPosition = 0; + FM_EraseChannels(); + freq = BK1080_GetFreqLoLimit(gEeprom.FM_Band); + } else { + gFM_AutoScan = false; + gFM_ChannelPosition = 0; + freq = gEeprom.FM_FrequencyPlaying; + } - BK1080_GetFrequencyDeviation(freq); - FM_Tune(freq, 1, bRestart); + BK1080_GetFrequencyDeviation(freq); + FM_Tune(freq, 1, bRestart); #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN; + gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN; #endif } @@ -410,29 +410,29 @@ static void ACTION_Scan_FM(bool bRestart) static void ACTION_AlarmOr1750(const bool b1750) { - if(gEeprom.KEY_LOCK && gEeprom.KEY_LOCK_PTT) - return; + if(gEeprom.KEY_LOCK && gEeprom.KEY_LOCK_PTT) + return; - #if defined(ENABLE_ALARM) - const AlarmState_t alarm_mode = (gEeprom.ALARM_MODE == ALARM_MODE_TONE) ? ALARM_STATE_TXALARM : ALARM_STATE_SITE_ALARM; - gAlarmRunningCounter = 0; - #endif + #if defined(ENABLE_ALARM) + const AlarmState_t alarm_mode = (gEeprom.ALARM_MODE == ALARM_MODE_TONE) ? ALARM_STATE_TXALARM : ALARM_STATE_SITE_ALARM; + gAlarmRunningCounter = 0; + #endif - #if defined(ENABLE_ALARM) && defined(ENABLE_TX1750) - gAlarmState = b1750 ? ALARM_STATE_TX1750 : alarm_mode; - #elif defined(ENABLE_ALARM) - gAlarmState = alarm_mode; - #else - gAlarmState = ALARM_STATE_TX1750; - #endif + #if defined(ENABLE_ALARM) && defined(ENABLE_TX1750) + gAlarmState = b1750 ? ALARM_STATE_TX1750 : alarm_mode; + #elif defined(ENABLE_ALARM) + gAlarmState = alarm_mode; + #else + gAlarmState = ALARM_STATE_TX1750; + #endif - (void)b1750; - gInputBoxIndex = 0; + (void)b1750; + gInputBoxIndex = 0; - gFlagPrepareTX = gAlarmState != ALARM_STATE_OFF; + gFlagPrepareTX = gAlarmState != ALARM_STATE_OFF; - if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu - gRequestDisplayScreen = DISPLAY_MAIN; + if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu + gRequestDisplayScreen = DISPLAY_MAIN; } @@ -441,137 +441,137 @@ static void ACTION_AlarmOr1750(const bool b1750) #ifdef ENABLE_VOX void ACTION_Vox(void) { - gEeprom.VOX_SWITCH = !gEeprom.VOX_SWITCH; - gRequestSaveSettings = true; - gFlagReconfigureVfos = true; - gUpdateStatus = true; + gEeprom.VOX_SWITCH = !gEeprom.VOX_SWITCH; + gRequestSaveSettings = true; + gFlagReconfigureVfos = true; + gUpdateStatus = true; - #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_VOX; - #endif + #ifdef ENABLE_VOICE + gAnotherVoiceID = VOICE_ID_VOX; + #endif } #endif #ifdef ENABLE_BLMIN_TMP_OFF void ACTION_BlminTmpOff(void) { - if(++gEeprom.BACKLIGHT_MIN_STAT == BLMIN_STAT_UNKNOWN) { - gEeprom.BACKLIGHT_MIN_STAT = BLMIN_STAT_ON; - BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MIN); - } else { - BACKLIGHT_SetBrightness(0); - } + if(++gEeprom.BACKLIGHT_MIN_STAT == BLMIN_STAT_UNKNOWN) { + gEeprom.BACKLIGHT_MIN_STAT = BLMIN_STAT_ON; + BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MIN); + } else { + BACKLIGHT_SetBrightness(0); + } } #endif #ifdef ENABLE_FEAT_F4HWN void ACTION_Update(void) { - gSaveRxMode = false; - gFlagReconfigureVfos = true; - gUpdateStatus = true; + gSaveRxMode = false; + gFlagReconfigureVfos = true; + gUpdateStatus = true; } void ACTION_RxMode(void) { - static bool cycle = 0; + static bool cycle = 0; - switch(cycle) { - case 0: - gEeprom.DUAL_WATCH = !gEeprom.DUAL_WATCH; - cycle = 1; - break; - case 1: - gEeprom.CROSS_BAND_RX_TX = !gEeprom.CROSS_BAND_RX_TX; - cycle = 0; - break; - } + switch(cycle) { + case 0: + gEeprom.DUAL_WATCH = !gEeprom.DUAL_WATCH; + cycle = 1; + break; + case 1: + gEeprom.CROSS_BAND_RX_TX = !gEeprom.CROSS_BAND_RX_TX; + cycle = 0; + break; + } - ACTION_Update(); + ACTION_Update(); } void ACTION_MainOnly(void) { - static bool cycle = 0; - static uint8_t dw = 0; - static uint8_t cb = 0; + static bool cycle = 0; + static uint8_t dw = 0; + static uint8_t cb = 0; - switch(cycle) { - case 0: - dw = gEeprom.DUAL_WATCH; - cb = gEeprom.CROSS_BAND_RX_TX; + switch(cycle) { + case 0: + dw = gEeprom.DUAL_WATCH; + cb = gEeprom.CROSS_BAND_RX_TX; - gEeprom.DUAL_WATCH = 0; - gEeprom.CROSS_BAND_RX_TX = 0; - cycle = 1; - break; - case 1: - gEeprom.DUAL_WATCH = dw; - gEeprom.CROSS_BAND_RX_TX = cb; - cycle = 0; - break; - } + gEeprom.DUAL_WATCH = 0; + gEeprom.CROSS_BAND_RX_TX = 0; + cycle = 1; + break; + case 1: + gEeprom.DUAL_WATCH = dw; + gEeprom.CROSS_BAND_RX_TX = cb; + cycle = 0; + break; + } - ACTION_Update(); + ACTION_Update(); } void ACTION_Ptt(void) { - gSetting_set_ptt_session = (gSetting_set_ptt_session == 0) ? 1: 0; + gSetting_set_ptt_session = (gSetting_set_ptt_session == 0) ? 1: 0; } void ACTION_Wn(void) { - if (FUNCTION_IsRx()) - { - gRxVfo->CHANNEL_BANDWIDTH = (gRxVfo->CHANNEL_BANDWIDTH == 0) ? 1: 0; - #ifdef ENABLE_AM_FIX - BK4819_SetFilterBandwidth(gRxVfo->CHANNEL_BANDWIDTH, true); - #else - BK4819_SetFilterBandwidth(gRxVfo->CHANNEL_BANDWIDTH, false); - #endif - } - else - { - gTxVfo->CHANNEL_BANDWIDTH = (gTxVfo->CHANNEL_BANDWIDTH == 0) ? 1: 0; - #ifdef ENABLE_AM_FIX - BK4819_SetFilterBandwidth(gTxVfo->CHANNEL_BANDWIDTH, true); - #else - BK4819_SetFilterBandwidth(gTxVfo->CHANNEL_BANDWIDTH, false); - #endif - } + if (FUNCTION_IsRx()) + { + gRxVfo->CHANNEL_BANDWIDTH = (gRxVfo->CHANNEL_BANDWIDTH == 0) ? 1: 0; + #ifdef ENABLE_AM_FIX + BK4819_SetFilterBandwidth(gRxVfo->CHANNEL_BANDWIDTH, true); + #else + BK4819_SetFilterBandwidth(gRxVfo->CHANNEL_BANDWIDTH, false); + #endif + } + else + { + gTxVfo->CHANNEL_BANDWIDTH = (gTxVfo->CHANNEL_BANDWIDTH == 0) ? 1: 0; + #ifdef ENABLE_AM_FIX + BK4819_SetFilterBandwidth(gTxVfo->CHANNEL_BANDWIDTH, true); + #else + BK4819_SetFilterBandwidth(gTxVfo->CHANNEL_BANDWIDTH, false); + #endif + } } void ACTION_BackLight(void) { - if(gBackLight) - { - gEeprom.BACKLIGHT_TIME = gBacklightTimeOriginal; - } - gBackLight = false; - BACKLIGHT_TurnOn(); + if(gBackLight) + { + gEeprom.BACKLIGHT_TIME = gBacklightTimeOriginal; + } + gBackLight = false; + BACKLIGHT_TurnOn(); } void ACTION_BackLightOnDemand(void) { - if(gBackLight == false) - { - gBacklightTimeOriginal = gEeprom.BACKLIGHT_TIME; - gEeprom.BACKLIGHT_TIME = 61; - gBackLight = true; - } - else - { - if(gBacklightBrightnessOld == gEeprom.BACKLIGHT_MAX) - { - gEeprom.BACKLIGHT_TIME = 0; - } - else - { - gEeprom.BACKLIGHT_TIME = 61; - } - } - - BACKLIGHT_TurnOn(); + if(gBackLight == false) + { + gBacklightTimeOriginal = gEeprom.BACKLIGHT_TIME; + gEeprom.BACKLIGHT_TIME = 61; + gBackLight = true; + } + else + { + if(gBacklightBrightnessOld == gEeprom.BACKLIGHT_MAX) + { + gEeprom.BACKLIGHT_TIME = 0; + } + else + { + gEeprom.BACKLIGHT_TIME = 61; + } + } + + BACKLIGHT_TurnOn(); } #endif \ No newline at end of file diff --git a/app/action.h b/app/action.h index 6f92440..311d3b4 100644 --- a/app/action.h +++ b/app/action.h @@ -23,25 +23,25 @@ void ACTION_Power(void); void ACTION_Monitor(void); void ACTION_Scan(bool bRestart); #ifdef ENABLE_VOX - void ACTION_Vox(void); + void ACTION_Vox(void); #endif #ifdef ENABLE_FMRADIO - void ACTION_FM(void); + void ACTION_FM(void); #endif void ACTION_SwitchDemodul(void); #ifdef ENABLE_BLMIN_TMP_OFF - void ACTION_BlminTmpOff(void); + void ACTION_BlminTmpOff(void); #endif #ifdef ENABLE_FEAT_F4HWN - void ACTION_RxMode(void); - void ACTION_MainOnly(void); - void ACTION_Ptt(void); - void ACTION_Wn(void); - void ACTION_BackLightOnDemand(void); - void ACTION_BackLight(void); + void ACTION_RxMode(void); + void ACTION_MainOnly(void); + void ACTION_Ptt(void); + void ACTION_Wn(void); + void ACTION_BackLightOnDemand(void); + void ACTION_BackLight(void); #endif void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); diff --git a/app/aircopy.c b/app/aircopy.c index cda195c..4f06075 100644 --- a/app/aircopy.c +++ b/app/aircopy.c @@ -17,7 +17,7 @@ #ifdef ENABLE_AIRCOPY //#if !defined(ENABLE_OVERLAY) -// #include "ARMCM0.h" +// #include "ARMCM0.h" //#endif #include "app/aircopy.h" @@ -43,219 +43,219 @@ uint16_t g_FSK_Buffer[36]; static void AIRCOPY_clear() { - for (uint8_t i = 0; i < 15; i++) - { - crc[i] = 0; - } + for (uint8_t i = 0; i < 15; i++) + { + crc[i] = 0; + } } bool AIRCOPY_SendMessage(void) { - static uint8_t gAircopySendCountdown = 1; + static uint8_t gAircopySendCountdown = 1; - if (gAircopyState != AIRCOPY_TRANSFER) { - return 1; - } + if (gAircopyState != AIRCOPY_TRANSFER) { + return 1; + } - if (--gAircopySendCountdown) { - return 1; - } + if (--gAircopySendCountdown) { + return 1; + } - g_FSK_Buffer[1] = (gAirCopyBlockNumber & 0x3FF) << 6; + g_FSK_Buffer[1] = (gAirCopyBlockNumber & 0x3FF) << 6; - EEPROM_ReadBuffer(g_FSK_Buffer[1], &g_FSK_Buffer[2], 64); + EEPROM_ReadBuffer(g_FSK_Buffer[1], &g_FSK_Buffer[2], 64); - g_FSK_Buffer[34] = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64); + g_FSK_Buffer[34] = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64); - for (unsigned int i = 0; i < 34; i++) { - g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8]; - } + for (unsigned int i = 0; i < 34; i++) { + g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8]; + } - if (++gAirCopyBlockNumber >= 0x78) { - gAircopyState = AIRCOPY_COMPLETE; - //NVIC_SystemReset(); - } + if (++gAirCopyBlockNumber >= 0x78) { + gAircopyState = AIRCOPY_COMPLETE; + //NVIC_SystemReset(); + } - RADIO_SetTxParameters(); + RADIO_SetTxParameters(); - BK4819_SendFSKData(g_FSK_Buffer); - BK4819_SetupPowerAmplifier(0, 0); - BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false); + BK4819_SendFSKData(g_FSK_Buffer); + BK4819_SetupPowerAmplifier(0, 0); + BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false); - gAircopySendCountdown = 30; + gAircopySendCountdown = 30; - return 0; + return 0; } void AIRCOPY_StorePacket(void) { - if (gFSKWriteIndex < 36) { - return; - } + if (gFSKWriteIndex < 36) { + return; + } - gFSKWriteIndex = 0; - gUpdateDisplay = true; - uint16_t Status = BK4819_ReadRegister(BK4819_REG_0B); - BK4819_PrepareFSKReceive(); + gFSKWriteIndex = 0; + gUpdateDisplay = true; + uint16_t Status = BK4819_ReadRegister(BK4819_REG_0B); + BK4819_PrepareFSKReceive(); - // Doc says bit 4 should be 1 = CRC OK, 0 = CRC FAIL, but original firmware checks for FAIL. + // Doc says bit 4 should be 1 = CRC OK, 0 = CRC FAIL, but original firmware checks for FAIL. - if ((Status & 0x0010U) != 0 || g_FSK_Buffer[0] != 0xABCD || g_FSK_Buffer[35] != 0xDCBA) { - gErrorsDuringAirCopy++; - return; - } + if ((Status & 0x0010U) != 0 || g_FSK_Buffer[0] != 0xABCD || g_FSK_Buffer[35] != 0xDCBA) { + gErrorsDuringAirCopy++; + return; + } - for (unsigned int i = 0; i < 34; i++) { - g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8]; - } + for (unsigned int i = 0; i < 34; i++) { + g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8]; + } - uint16_t CRC = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64); - if (g_FSK_Buffer[34] != CRC) { - gErrorsDuringAirCopy++; - return; - } + uint16_t CRC = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64); + if (g_FSK_Buffer[34] != CRC) { + gErrorsDuringAirCopy++; + return; + } - uint16_t Offset = g_FSK_Buffer[1]; + uint16_t Offset = g_FSK_Buffer[1]; - if (Offset >= 0x1E00) { - gErrorsDuringAirCopy++; - return; - } + if (Offset >= 0x1E00) { + gErrorsDuringAirCopy++; + return; + } - const uint16_t *pData = &g_FSK_Buffer[2]; - for (unsigned int i = 0; i < 8; i++) { - EEPROM_WriteBuffer(Offset, pData); - pData += 4; - Offset += 8; - } + const uint16_t *pData = &g_FSK_Buffer[2]; + for (unsigned int i = 0; i < 8; i++) { + EEPROM_WriteBuffer(Offset, pData); + pData += 4; + Offset += 8; + } - if (Offset == 0x1E00) { - gAircopyState = AIRCOPY_COMPLETE; - } + if (Offset == 0x1E00) { + gAircopyState = AIRCOPY_COMPLETE; + } - gAirCopyBlockNumber++; + gAirCopyBlockNumber++; } static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { - if (bKeyHeld || !bKeyPressed) { - return; - } + if (bKeyHeld || !bKeyPressed) { + return; + } - INPUTBOX_Append(Key); + INPUTBOX_Append(Key); - gRequestDisplayScreen = DISPLAY_AIRCOPY; + gRequestDisplayScreen = DISPLAY_AIRCOPY; - if (gInputBoxIndex < 6) { + if (gInputBoxIndex < 6) { #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; + gAnotherVoiceID = (VOICE_ID_t)Key; #endif - return; - } + return; + } - gInputBoxIndex = 0; - uint32_t Frequency = StrToUL(INPUTBOX_GetAscii()) * 100; + gInputBoxIndex = 0; + uint32_t Frequency = StrToUL(INPUTBOX_GetAscii()) * 100; - for (unsigned int i = 0; i < BAND_N_ELEM; i++) { - if (Frequency < frequencyBandTable[i].lower || Frequency >= frequencyBandTable[i].upper) { - continue; - } + for (unsigned int i = 0; i < BAND_N_ELEM; i++) { + if (Frequency < frequencyBandTable[i].lower || Frequency >= frequencyBandTable[i].upper) { + continue; + } - if (TX_freq_check(Frequency)) { - continue; - } + if (TX_freq_check(Frequency)) { + continue; + } #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; + gAnotherVoiceID = (VOICE_ID_t)Key; #endif - Frequency = FREQUENCY_RoundToStep(Frequency, gRxVfo->StepFrequency); - gRxVfo->Band = i; - gRxVfo->freq_config_RX.Frequency = Frequency; - gRxVfo->freq_config_TX.Frequency = Frequency; - RADIO_ConfigureSquelchAndOutputPower(gRxVfo); - gCurrentVfo = gRxVfo; - RADIO_SetupRegisters(true); - BK4819_SetupAircopy(); - BK4819_ResetFSK(); - return; - } + Frequency = FREQUENCY_RoundToStep(Frequency, gRxVfo->StepFrequency); + gRxVfo->Band = i; + gRxVfo->freq_config_RX.Frequency = Frequency; + gRxVfo->freq_config_TX.Frequency = Frequency; + RADIO_ConfigureSquelchAndOutputPower(gRxVfo); + gCurrentVfo = gRxVfo; + RADIO_SetupRegisters(true); + BK4819_SetupAircopy(); + BK4819_ResetFSK(); + return; + } - gRequestDisplayScreen = DISPLAY_AIRCOPY; + gRequestDisplayScreen = DISPLAY_AIRCOPY; } static void AIRCOPY_Key_EXIT(bool bKeyPressed, bool bKeyHeld) { - if (bKeyHeld || !bKeyPressed) { - return; - } + if (bKeyHeld || !bKeyPressed) { + return; + } - if (gInputBoxIndex == 0) { - gAircopyStep = 1; - gFSKWriteIndex = 0; - gAirCopyBlockNumber = 0; - gInputBoxIndex = 0; - gErrorsDuringAirCopy = lErrorsDuringAirCopy = 0; - gAirCopyIsSendMode = 0; + if (gInputBoxIndex == 0) { + gAircopyStep = 1; + gFSKWriteIndex = 0; + gAirCopyBlockNumber = 0; + gInputBoxIndex = 0; + gErrorsDuringAirCopy = lErrorsDuringAirCopy = 0; + gAirCopyIsSendMode = 0; - AIRCOPY_clear(); + AIRCOPY_clear(); - BK4819_PrepareFSKReceive(); + BK4819_PrepareFSKReceive(); - gAircopyState = AIRCOPY_TRANSFER; - } else { - gInputBox[--gInputBoxIndex] = 10; - } + gAircopyState = AIRCOPY_TRANSFER; + } else { + gInputBox[--gInputBoxIndex] = 10; + } - gRequestDisplayScreen = DISPLAY_AIRCOPY; + gRequestDisplayScreen = DISPLAY_AIRCOPY; } static void AIRCOPY_Key_MENU(bool bKeyPressed, bool bKeyHeld) { - if (bKeyHeld || !bKeyPressed) { - return; - } + if (bKeyHeld || !bKeyPressed) { + return; + } - gAircopyStep = 1; - gFSKWriteIndex = 0; - gAirCopyBlockNumber = 0; - gInputBoxIndex = 0; - gAirCopyIsSendMode = 1; - g_FSK_Buffer[0] = 0xABCD; - g_FSK_Buffer[1] = 0; - g_FSK_Buffer[35] = 0xDCBA; + gAircopyStep = 1; + gFSKWriteIndex = 0; + gAirCopyBlockNumber = 0; + gInputBoxIndex = 0; + gAirCopyIsSendMode = 1; + g_FSK_Buffer[0] = 0xABCD; + g_FSK_Buffer[1] = 0; + g_FSK_Buffer[35] = 0xDCBA; - AIRCOPY_clear(); + AIRCOPY_clear(); - GUI_DisplayScreen(); + GUI_DisplayScreen(); - gAircopyState = AIRCOPY_TRANSFER; + gAircopyState = AIRCOPY_TRANSFER; } void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { - switch (Key) { - case KEY_0: - case KEY_1: - case KEY_2: - case KEY_3: - case KEY_4: - case KEY_5: - case KEY_6: - case KEY_7: - case KEY_8: - case KEY_9: - AIRCOPY_Key_DIGITS(Key, bKeyPressed, bKeyHeld); - break; - case KEY_MENU: - AIRCOPY_Key_MENU(bKeyPressed, bKeyHeld); - break; - case KEY_EXIT: - AIRCOPY_Key_EXIT(bKeyPressed, bKeyHeld); - break; - default: - break; - } + switch (Key) { + case KEY_0: + case KEY_1: + case KEY_2: + case KEY_3: + case KEY_4: + case KEY_5: + case KEY_6: + case KEY_7: + case KEY_8: + case KEY_9: + AIRCOPY_Key_DIGITS(Key, bKeyPressed, bKeyHeld); + break; + case KEY_MENU: + AIRCOPY_Key_MENU(bKeyPressed, bKeyHeld); + break; + case KEY_EXIT: + AIRCOPY_Key_EXIT(bKeyPressed, bKeyHeld); + break; + default: + break; + } } #endif diff --git a/app/aircopy.h b/app/aircopy.h index 4ea18f9..fe64115 100644 --- a/app/aircopy.h +++ b/app/aircopy.h @@ -23,9 +23,9 @@ enum AIRCOPY_State_t { - AIRCOPY_READY = 0, - AIRCOPY_TRANSFER, - AIRCOPY_COMPLETE + AIRCOPY_READY = 0, + AIRCOPY_TRANSFER, + AIRCOPY_COMPLETE }; typedef enum AIRCOPY_State_t AIRCOPY_State_t; diff --git a/app/app.c b/app/app.c index c342925..277b885 100644 --- a/app/app.c +++ b/app/app.c @@ -22,23 +22,23 @@ #include "app/action.h" #ifdef ENABLE_AIRCOPY - #include "app/aircopy.h" + #include "app/aircopy.h" #endif #include "app/app.h" #include "app/chFrScanner.h" #include "app/dtmf.h" #ifdef ENABLE_FLASHLIGHT - #include "app/flashlight.h" + #include "app/flashlight.h" #endif #ifdef ENABLE_FMRADIO - #include "app/fm.h" + #include "app/fm.h" #endif #include "app/generic.h" #include "app/main.h" #include "app/menu.h" #include "app/scanner.h" #ifdef ENABLE_UART - #include "app/uart.h" + #include "app/uart.h" #endif #include "ARMCM0.h" #include "audio.h" @@ -46,7 +46,7 @@ #include "bsp/dp32g030/gpio.h" #include "driver/backlight.h" #ifdef ENABLE_FMRADIO - #include "driver/bk1080.h" + #include "driver/bk1080.h" #endif #include "driver/bk4819.h" #include "driver/gpio.h" @@ -63,7 +63,7 @@ #include "settings.h" #if defined(ENABLE_OVERLAY) - #include "sram-overlay.h" + #include "sram-overlay.h" #endif #include "ui/battery.h" #include "ui/inputbox.h" @@ -80,16 +80,16 @@ static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); void (*ProcessKeysFunctions[])(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) = { - [DISPLAY_MAIN] = &MAIN_ProcessKeys, - [DISPLAY_MENU] = &MENU_ProcessKeys, - [DISPLAY_SCANNER] = &SCANNER_ProcessKeys, + [DISPLAY_MAIN] = &MAIN_ProcessKeys, + [DISPLAY_MENU] = &MENU_ProcessKeys, + [DISPLAY_SCANNER] = &SCANNER_ProcessKeys, #ifdef ENABLE_FMRADIO - [DISPLAY_FM] = &FM_ProcessKeys, + [DISPLAY_FM] = &FM_ProcessKeys, #endif #ifdef ENABLE_AIRCOPY - [DISPLAY_AIRCOPY] = &AIRCOPY_ProcessKeys, + [DISPLAY_AIRCOPY] = &AIRCOPY_ProcessKeys, #endif }; @@ -99,2021 +99,2021 @@ static_assert(ARRAY_SIZE(ProcessKeysFunctions) == DISPLAY_N_ELEM); static void CheckForIncoming(void) { - if (!g_SquelchLost) - return; // squelch is closed + if (!g_SquelchLost) + return; // squelch is closed - // squelch is open + // squelch is open - if (gScanStateDir == SCAN_OFF) - { // not RF scanning - if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF) - { // dual watch is disabled + if (gScanStateDir == SCAN_OFF) + { // not RF scanning + if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF) + { // dual watch is disabled - #ifdef ENABLE_NOAA - if (gIsNoaaMode) - { - gNOAA_Countdown_10ms = NOAA_countdown_3_10ms; - gScheduleNOAA = false; - } - #endif + #ifdef ENABLE_NOAA + if (gIsNoaaMode) + { + gNOAA_Countdown_10ms = NOAA_countdown_3_10ms; + gScheduleNOAA = false; + } + #endif - if (gCurrentFunction != FUNCTION_INCOMING) - { - FUNCTION_Select(FUNCTION_INCOMING); - //gUpdateDisplay = true; - } + if (gCurrentFunction != FUNCTION_INCOMING) + { + FUNCTION_Select(FUNCTION_INCOMING); + //gUpdateDisplay = true; + } - return; - } + return; + } - // dual watch is enabled and we're RX'ing a signal + // dual watch is enabled and we're RX'ing a signal - if (gRxReceptionMode != RX_MODE_NONE) - { - if (gCurrentFunction != FUNCTION_INCOMING) - { - FUNCTION_Select(FUNCTION_INCOMING); - //gUpdateDisplay = true; - } - return; - } + if (gRxReceptionMode != RX_MODE_NONE) + { + if (gCurrentFunction != FUNCTION_INCOMING) + { + FUNCTION_Select(FUNCTION_INCOMING); + //gUpdateDisplay = true; + } + return; + } - gDualWatchCountdown_10ms = dual_watch_count_after_rx_10ms; - gScheduleDualWatch = false; + gDualWatchCountdown_10ms = dual_watch_count_after_rx_10ms; + gScheduleDualWatch = false; - // let the user see DW is not active - gDualWatchActive = false; - gUpdateStatus = true; - } - else - { // RF scanning - if (gRxReceptionMode != RX_MODE_NONE) - { - if (gCurrentFunction != FUNCTION_INCOMING) - { - FUNCTION_Select(FUNCTION_INCOMING); - //gUpdateDisplay = true; - } - return; - } + // let the user see DW is not active + gDualWatchActive = false; + gUpdateStatus = true; + } + else + { // RF scanning + if (gRxReceptionMode != RX_MODE_NONE) + { + if (gCurrentFunction != FUNCTION_INCOMING) + { + FUNCTION_Select(FUNCTION_INCOMING); + //gUpdateDisplay = true; + } + return; + } - gScanPauseDelayIn_10ms = scan_pause_delay_in_3_10ms; - gScheduleScanListen = false; - } + gScanPauseDelayIn_10ms = scan_pause_delay_in_3_10ms; + gScheduleScanListen = false; + } - gRxReceptionMode = RX_MODE_DETECTED; + gRxReceptionMode = RX_MODE_DETECTED; - if (gCurrentFunction != FUNCTION_INCOMING) - { - FUNCTION_Select(FUNCTION_INCOMING); - //gUpdateDisplay = true; - } + if (gCurrentFunction != FUNCTION_INCOMING) + { + FUNCTION_Select(FUNCTION_INCOMING); + //gUpdateDisplay = true; + } } static void HandleIncoming(void) { - if (!g_SquelchLost) { // squelch is closed + if (!g_SquelchLost) { // squelch is closed #ifdef ENABLE_DTMF_CALLING - if (gDTMF_RX_index > 0) - DTMF_clear_RX(); + if (gDTMF_RX_index > 0) + DTMF_clear_RX(); #endif - if (gCurrentFunction != FUNCTION_FOREGROUND) { - FUNCTION_Select(FUNCTION_FOREGROUND); - gUpdateDisplay = true; - } - return; - } + if (gCurrentFunction != FUNCTION_FOREGROUND) { + FUNCTION_Select(FUNCTION_FOREGROUND); + gUpdateDisplay = true; + } + return; + } - bool bFlag = (gScanStateDir == SCAN_OFF && gCurrentCodeType == CODE_TYPE_OFF); + bool bFlag = (gScanStateDir == SCAN_OFF && gCurrentCodeType == CODE_TYPE_OFF); #ifdef ENABLE_NOAA - if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gNOAACountdown_10ms > 0) { - gNOAACountdown_10ms = 0; - bFlag = true; - } + if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gNOAACountdown_10ms > 0) { + gNOAACountdown_10ms = 0; + bFlag = true; + } #endif - if (g_CTCSS_Lost && gCurrentCodeType == CODE_TYPE_CONTINUOUS_TONE) { - bFlag = true; - gFoundCTCSS = false; - } + if (g_CTCSS_Lost && gCurrentCodeType == CODE_TYPE_CONTINUOUS_TONE) { + bFlag = true; + gFoundCTCSS = false; + } - if (g_CDCSS_Lost && gCDCSSCodeType == CDCSS_POSITIVE_CODE - && (gCurrentCodeType == CODE_TYPE_DIGITAL || gCurrentCodeType == CODE_TYPE_REVERSE_DIGITAL)) - { - gFoundCDCSS = false; - } - else if (!bFlag) - return; + if (g_CDCSS_Lost && gCDCSSCodeType == CDCSS_POSITIVE_CODE + && (gCurrentCodeType == CODE_TYPE_DIGITAL || gCurrentCodeType == CODE_TYPE_REVERSE_DIGITAL)) + { + gFoundCDCSS = false; + } + else if (!bFlag) + return; #ifdef ENABLE_DTMF_CALLING - if (gScanStateDir == SCAN_OFF && (gRxVfo->DTMF_DECODING_ENABLE || gSetting_KILLED)) { + if (gScanStateDir == SCAN_OFF && (gRxVfo->DTMF_DECODING_ENABLE || gSetting_KILLED)) { - // DTMF DCD is enabled - DTMF_HandleRequest(); - if (gDTMF_CallState == DTMF_CALL_STATE_NONE) { - if (gRxReceptionMode != RX_MODE_DETECTED) { - return; - } - gDualWatchCountdown_10ms = dual_watch_count_after_1_10ms; - gScheduleDualWatch = false; + // DTMF DCD is enabled + DTMF_HandleRequest(); + if (gDTMF_CallState == DTMF_CALL_STATE_NONE) { + if (gRxReceptionMode != RX_MODE_DETECTED) { + return; + } + gDualWatchCountdown_10ms = dual_watch_count_after_1_10ms; + gScheduleDualWatch = false; - gRxReceptionMode = RX_MODE_LISTENING; + gRxReceptionMode = RX_MODE_LISTENING; - // let the user see DW is not active - gDualWatchActive = false; - gUpdateStatus = true; + // let the user see DW is not active + gDualWatchActive = false; + gUpdateStatus = true; - gUpdateDisplay = true; - return; - } - } + gUpdateDisplay = true; + return; + } + } #endif - APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE); + APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE); } static void HandleReceive(void) { - #define END_OF_RX_MODE_SKIP 0 - #define END_OF_RX_MODE_END 1 - #define END_OF_RX_MODE_TTE 2 + #define END_OF_RX_MODE_SKIP 0 + #define END_OF_RX_MODE_END 1 + #define END_OF_RX_MODE_TTE 2 - uint8_t Mode = END_OF_RX_MODE_SKIP; + uint8_t Mode = END_OF_RX_MODE_SKIP; - if (gFlagTailNoteEliminationComplete) - { - Mode = END_OF_RX_MODE_END; - goto Skip; - } + if (gFlagTailNoteEliminationComplete) + { + Mode = END_OF_RX_MODE_END; + goto Skip; + } - if (gScanStateDir != SCAN_OFF && IS_FREQ_CHANNEL(gNextMrChannel)) - { // we are scanning in the frequency mode - if (g_SquelchLost) - return; + if (gScanStateDir != SCAN_OFF && IS_FREQ_CHANNEL(gNextMrChannel)) + { // we are scanning in the frequency mode + if (g_SquelchLost) + return; - Mode = END_OF_RX_MODE_END; - goto Skip; - } + Mode = END_OF_RX_MODE_END; + goto Skip; + } - switch (gCurrentCodeType) - { - default: - case CODE_TYPE_OFF: - break; + switch (gCurrentCodeType) + { + default: + case CODE_TYPE_OFF: + break; - case CODE_TYPE_CONTINUOUS_TONE: - if (gFoundCTCSS && gFoundCTCSSCountdown_10ms == 0) - { - gFoundCTCSS = false; - gFoundCDCSS = false; - Mode = END_OF_RX_MODE_END; - goto Skip; - } - break; + case CODE_TYPE_CONTINUOUS_TONE: + if (gFoundCTCSS && gFoundCTCSSCountdown_10ms == 0) + { + gFoundCTCSS = false; + gFoundCDCSS = false; + Mode = END_OF_RX_MODE_END; + goto Skip; + } + break; - case CODE_TYPE_DIGITAL: - case CODE_TYPE_REVERSE_DIGITAL: - if (gFoundCDCSS && gFoundCDCSSCountdown_10ms == 0) - { - gFoundCTCSS = false; - gFoundCDCSS = false; - Mode = END_OF_RX_MODE_END; - goto Skip; - } - break; - } + case CODE_TYPE_DIGITAL: + case CODE_TYPE_REVERSE_DIGITAL: + if (gFoundCDCSS && gFoundCDCSSCountdown_10ms == 0) + { + gFoundCTCSS = false; + gFoundCDCSS = false; + Mode = END_OF_RX_MODE_END; + goto Skip; + } + break; + } - if (g_SquelchLost) - { - #ifdef ENABLE_NOAA - if (!gEndOfRxDetectedMaybe && !IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) - #else - if (!gEndOfRxDetectedMaybe) - #endif - { - switch (gCurrentCodeType) - { - case CODE_TYPE_OFF: - if (gEeprom.SQUELCH_LEVEL) - { - if (g_CxCSS_TAIL_Found) - { - Mode = END_OF_RX_MODE_TTE; - g_CxCSS_TAIL_Found = false; - } - } - break; + if (g_SquelchLost) + { + #ifdef ENABLE_NOAA + if (!gEndOfRxDetectedMaybe && !IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) + #else + if (!gEndOfRxDetectedMaybe) + #endif + { + switch (gCurrentCodeType) + { + case CODE_TYPE_OFF: + if (gEeprom.SQUELCH_LEVEL) + { + if (g_CxCSS_TAIL_Found) + { + Mode = END_OF_RX_MODE_TTE; + g_CxCSS_TAIL_Found = false; + } + } + break; - case CODE_TYPE_CONTINUOUS_TONE: - if (g_CTCSS_Lost) - { - gFoundCTCSS = false; - } - else - if (!gFoundCTCSS) - { - gFoundCTCSS = true; - gFoundCTCSSCountdown_10ms = 100; // 1 sec - } + case CODE_TYPE_CONTINUOUS_TONE: + if (g_CTCSS_Lost) + { + gFoundCTCSS = false; + } + else + if (!gFoundCTCSS) + { + gFoundCTCSS = true; + gFoundCTCSSCountdown_10ms = 100; // 1 sec + } - if (g_CxCSS_TAIL_Found) - { - Mode = END_OF_RX_MODE_TTE; - g_CxCSS_TAIL_Found = false; - } - break; + if (g_CxCSS_TAIL_Found) + { + Mode = END_OF_RX_MODE_TTE; + g_CxCSS_TAIL_Found = false; + } + break; - case CODE_TYPE_DIGITAL: - case CODE_TYPE_REVERSE_DIGITAL: - if (g_CDCSS_Lost && gCDCSSCodeType == CDCSS_POSITIVE_CODE) - { - gFoundCDCSS = false; - } - else - if (!gFoundCDCSS) - { - gFoundCDCSS = true; - gFoundCDCSSCountdown_10ms = 100; // 1 sec - } + case CODE_TYPE_DIGITAL: + case CODE_TYPE_REVERSE_DIGITAL: + if (g_CDCSS_Lost && gCDCSSCodeType == CDCSS_POSITIVE_CODE) + { + gFoundCDCSS = false; + } + else + if (!gFoundCDCSS) + { + gFoundCDCSS = true; + gFoundCDCSSCountdown_10ms = 100; // 1 sec + } - if (g_CxCSS_TAIL_Found) - { - if (BK4819_GetCTCType() == 1) - Mode = END_OF_RX_MODE_TTE; + if (g_CxCSS_TAIL_Found) + { + if (BK4819_GetCTCType() == 1) + Mode = END_OF_RX_MODE_TTE; - g_CxCSS_TAIL_Found = false; - } + g_CxCSS_TAIL_Found = false; + } - break; - } - } - } - else - Mode = END_OF_RX_MODE_END; + break; + } + } + } + else + Mode = END_OF_RX_MODE_END; - if (!gEndOfRxDetectedMaybe && - Mode == END_OF_RX_MODE_SKIP && - gNextTimeslice40ms && - gEeprom.TAIL_TONE_ELIMINATION && - (gCurrentCodeType == CODE_TYPE_DIGITAL || gCurrentCodeType == CODE_TYPE_REVERSE_DIGITAL) && - BK4819_GetCTCType() == 1) - Mode = END_OF_RX_MODE_TTE; - else - gNextTimeslice40ms = false; + if (!gEndOfRxDetectedMaybe && + Mode == END_OF_RX_MODE_SKIP && + gNextTimeslice40ms && + gEeprom.TAIL_TONE_ELIMINATION && + (gCurrentCodeType == CODE_TYPE_DIGITAL || gCurrentCodeType == CODE_TYPE_REVERSE_DIGITAL) && + BK4819_GetCTCType() == 1) + Mode = END_OF_RX_MODE_TTE; + else + gNextTimeslice40ms = false; Skip: - switch (Mode) - { - case END_OF_RX_MODE_SKIP: - break; + switch (Mode) + { + case END_OF_RX_MODE_SKIP: + break; - case END_OF_RX_MODE_END: - RADIO_SetupRegisters(true); + case END_OF_RX_MODE_END: + RADIO_SetupRegisters(true); - #ifdef ENABLE_NOAA - if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) - gNOAACountdown_10ms = 300; // 3 sec - #endif + #ifdef ENABLE_NOAA + if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) + gNOAACountdown_10ms = 300; // 3 sec + #endif - gUpdateDisplay = true; + gUpdateDisplay = true; - if (gScanStateDir != SCAN_OFF) - { - switch (gEeprom.SCAN_RESUME_MODE) - { - case SCAN_RESUME_TO: - break; + if (gScanStateDir != SCAN_OFF) + { + switch (gEeprom.SCAN_RESUME_MODE) + { + case SCAN_RESUME_TO: + break; - case SCAN_RESUME_CO: - gScanPauseDelayIn_10ms = scan_pause_delay_in_7_10ms; - gScheduleScanListen = false; - break; + case SCAN_RESUME_CO: + gScanPauseDelayIn_10ms = scan_pause_delay_in_7_10ms; + gScheduleScanListen = false; + break; - case SCAN_RESUME_SE: - CHFRSCANNER_Stop(); - break; - } - } + case SCAN_RESUME_SE: + CHFRSCANNER_Stop(); + break; + } + } - break; + break; - case END_OF_RX_MODE_TTE: - if (gEeprom.TAIL_TONE_ELIMINATION) { - AUDIO_AudioPathOff(); + case END_OF_RX_MODE_TTE: + if (gEeprom.TAIL_TONE_ELIMINATION) { + AUDIO_AudioPathOff(); - gTailNoteEliminationCountdown_10ms = 20; - gFlagTailNoteEliminationComplete = false; - gEndOfRxDetectedMaybe = true; - gEnableSpeaker = false; - } - break; - } + gTailNoteEliminationCountdown_10ms = 20; + gFlagTailNoteEliminationComplete = false; + gEndOfRxDetectedMaybe = true; + gEnableSpeaker = false; + } + break; + } } static void HandlePowerSave() { - if (!gRxIdleMode) { - CheckForIncoming(); - } + if (!gRxIdleMode) { + CheckForIncoming(); + } } static void (*HandleFunction_fn_table[])(void) = { - [FUNCTION_FOREGROUND] = &CheckForIncoming, - [FUNCTION_TRANSMIT] = &FUNCTION_NOP, - [FUNCTION_MONITOR] = &FUNCTION_NOP, - [FUNCTION_INCOMING] = &HandleIncoming, - [FUNCTION_RECEIVE] = &HandleReceive, - [FUNCTION_POWER_SAVE] = &HandlePowerSave, - [FUNCTION_BAND_SCOPE] = &FUNCTION_NOP, + [FUNCTION_FOREGROUND] = &CheckForIncoming, + [FUNCTION_TRANSMIT] = &FUNCTION_NOP, + [FUNCTION_MONITOR] = &FUNCTION_NOP, + [FUNCTION_INCOMING] = &HandleIncoming, + [FUNCTION_RECEIVE] = &HandleReceive, + [FUNCTION_POWER_SAVE] = &HandlePowerSave, + [FUNCTION_BAND_SCOPE] = &FUNCTION_NOP, }; static_assert(ARRAY_SIZE(HandleFunction_fn_table) == FUNCTION_N_ELEM); static void HandleFunction(void) { - HandleFunction_fn_table[gCurrentFunction](); + HandleFunction_fn_table[gCurrentFunction](); } void APP_StartListening(FUNCTION_Type_t function) { - const unsigned int vfo = gEeprom.RX_VFO; + const unsigned int vfo = gEeprom.RX_VFO; #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER gRxTimerCountdown_500ms = 7200; #endif #ifdef ENABLE_DTMF_CALLING - if (gSetting_KILLED) - return; + if (gSetting_KILLED) + return; #endif #ifdef ENABLE_FMRADIO - if (gFmRadioMode) - BK1080_Init0(); + if (gFmRadioMode) + BK1080_Init0(); #endif - // clear the other vfo's rssi level (to hide the antenna symbol) - gVFO_RSSI_bar_level[!vfo] = 0; + // clear the other vfo's rssi level (to hide the antenna symbol) + gVFO_RSSI_bar_level[!vfo] = 0; - AUDIO_AudioPathOn(); - gEnableSpeaker = true; + AUDIO_AudioPathOn(); + gEnableSpeaker = true; - if (gSetting_backlight_on_tx_rx & BACKLIGHT_ON_TR_RX) { - BACKLIGHT_TurnOn(); - } + if (gSetting_backlight_on_tx_rx & BACKLIGHT_ON_TR_RX) { + BACKLIGHT_TurnOn(); + } - if (gScanStateDir != SCAN_OFF) - CHFRSCANNER_Found(); + if (gScanStateDir != SCAN_OFF) + CHFRSCANNER_Found(); #ifdef ENABLE_NOAA - if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gIsNoaaMode) { - gRxVfo->CHANNEL_SAVE = gNoaaChannel + NOAA_CHANNEL_FIRST; - gRxVfo->pRX->Frequency = NoaaFrequencyTable[gNoaaChannel]; - gRxVfo->pTX->Frequency = NoaaFrequencyTable[gNoaaChannel]; - gEeprom.ScreenChannel[vfo] = gRxVfo->CHANNEL_SAVE; + if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gIsNoaaMode) { + gRxVfo->CHANNEL_SAVE = gNoaaChannel + NOAA_CHANNEL_FIRST; + gRxVfo->pRX->Frequency = NoaaFrequencyTable[gNoaaChannel]; + gRxVfo->pTX->Frequency = NoaaFrequencyTable[gNoaaChannel]; + gEeprom.ScreenChannel[vfo] = gRxVfo->CHANNEL_SAVE; - gNOAA_Countdown_10ms = 500; // 5 sec - gScheduleNOAA = false; - } + gNOAA_Countdown_10ms = 500; // 5 sec + gScheduleNOAA = false; + } #endif - if (gScanStateDir == SCAN_OFF && - gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) - { // not scanning, dual watch is enabled + if (gScanStateDir == SCAN_OFF && + gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + { // not scanning, dual watch is enabled - gDualWatchCountdown_10ms = dual_watch_count_after_2_10ms; - gScheduleDualWatch = false; + gDualWatchCountdown_10ms = dual_watch_count_after_2_10ms; + gScheduleDualWatch = false; - // when crossband is active only the main VFO should be used for TX - if(gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) - gRxVfoIsActive = true; + // when crossband is active only the main VFO should be used for TX + if(gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) + gRxVfoIsActive = true; - // let the user see DW is not active - gDualWatchActive = false; - gUpdateStatus = true; - } + // let the user see DW is not active + gDualWatchActive = false; + gUpdateStatus = true; + } - BK4819_WriteRegister(BK4819_REG_48, - (11u << 12) | // ??? .. 0 to 15, doesn't seem to make any difference - ( 0u << 10) | // AF Rx Gain-1 - (gEeprom.VOLUME_GAIN << 4) | // AF Rx Gain-2 - (gEeprom.DAC_GAIN << 0)); // AF DAC Gain (after Gain-1 and Gain-2) + BK4819_WriteRegister(BK4819_REG_48, + (11u << 12) | // ??? .. 0 to 15, doesn't seem to make any difference + ( 0u << 10) | // AF Rx Gain-1 + (gEeprom.VOLUME_GAIN << 4) | // AF Rx Gain-2 + (gEeprom.DAC_GAIN << 0)); // AF DAC Gain (after Gain-1 and Gain-2) #ifdef ENABLE_VOICE - if (gVoiceWriteIndex == 0) // AM/FM RX mode will be set when the voice has finished + if (gVoiceWriteIndex == 0) // AM/FM RX mode will be set when the voice has finished #endif - RADIO_SetModulation(gRxVfo->Modulation); // no need, set it now + RADIO_SetModulation(gRxVfo->Modulation); // no need, set it now - FUNCTION_Select(function); + FUNCTION_Select(function); #ifdef ENABLE_FMRADIO - if (function == FUNCTION_MONITOR || gFmRadioMode) + if (function == FUNCTION_MONITOR || gFmRadioMode) #else - if (function == FUNCTION_MONITOR) + if (function == FUNCTION_MONITOR) #endif - { // squelch is disabled - if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu - GUI_SelectNextDisplay(DISPLAY_MAIN); - } - else - gUpdateDisplay = true; + { // squelch is disabled + if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu + GUI_SelectNextDisplay(DISPLAY_MAIN); + } + else + gUpdateDisplay = true; - gUpdateStatus = true; + gUpdateStatus = true; } uint32_t APP_SetFreqByStepAndLimits(VFO_Info_t *pInfo, int8_t direction, uint32_t lower, uint32_t upper) { - uint32_t Frequency = FREQUENCY_RoundToStep(pInfo->freq_config_RX.Frequency + (direction * pInfo->StepFrequency), pInfo->StepFrequency); + uint32_t Frequency = FREQUENCY_RoundToStep(pInfo->freq_config_RX.Frequency + (direction * pInfo->StepFrequency), pInfo->StepFrequency); #ifdef ENABLE_FEAT_F4HWN - if (Frequency > upper) + if (Frequency > upper) #else - if (Frequency >= upper) + if (Frequency >= upper) #endif - Frequency = lower; + Frequency = lower; - else if (Frequency < lower) - Frequency = FREQUENCY_RoundToStep(upper - pInfo->StepFrequency, pInfo->StepFrequency); + else if (Frequency < lower) + Frequency = FREQUENCY_RoundToStep(upper - pInfo->StepFrequency, pInfo->StepFrequency); - return Frequency; + return Frequency; } uint32_t APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t direction) { - return APP_SetFreqByStepAndLimits(pInfo, direction, frequencyBandTable[pInfo->Band].lower, frequencyBandTable[pInfo->Band].upper); + return APP_SetFreqByStepAndLimits(pInfo, direction, frequencyBandTable[pInfo->Band].lower, frequencyBandTable[pInfo->Band].upper); } #ifdef ENABLE_NOAA - static void NOAA_IncreaseChannel(void) - { - if (++gNoaaChannel > 9) - gNoaaChannel = 0; - } + static void NOAA_IncreaseChannel(void) + { + if (++gNoaaChannel > 9) + gNoaaChannel = 0; + } #endif static void DualwatchAlternate(void) { - #ifdef ENABLE_NOAA - if (gIsNoaaMode) - { - if (!IS_NOAA_CHANNEL(gEeprom.ScreenChannel[0]) || !IS_NOAA_CHANNEL(gEeprom.ScreenChannel[1])) - gEeprom.RX_VFO = (gEeprom.RX_VFO + 1) & 1; - else - gEeprom.RX_VFO = 0; + #ifdef ENABLE_NOAA + if (gIsNoaaMode) + { + if (!IS_NOAA_CHANNEL(gEeprom.ScreenChannel[0]) || !IS_NOAA_CHANNEL(gEeprom.ScreenChannel[1])) + gEeprom.RX_VFO = (gEeprom.RX_VFO + 1) & 1; + else + gEeprom.RX_VFO = 0; - gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO]; + gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO]; - if (IS_NOAA_CHANNEL(gEeprom.VfoInfo[0].CHANNEL_SAVE)) - NOAA_IncreaseChannel(); - } - else - #endif - { // toggle between VFO's - gEeprom.RX_VFO = !gEeprom.RX_VFO; - gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO]; + if (IS_NOAA_CHANNEL(gEeprom.VfoInfo[0].CHANNEL_SAVE)) + NOAA_IncreaseChannel(); + } + else + #endif + { // toggle between VFO's + gEeprom.RX_VFO = !gEeprom.RX_VFO; + gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO]; - if (!gDualWatchActive) - { // let the user see DW is active - gDualWatchActive = true; - gUpdateStatus = true; - } - } + if (!gDualWatchActive) + { // let the user see DW is active + gDualWatchActive = true; + gUpdateStatus = true; + } + } - RADIO_SetupRegisters(false); + RADIO_SetupRegisters(false); - #ifdef ENABLE_NOAA - gDualWatchCountdown_10ms = gIsNoaaMode ? dual_watch_count_noaa_10ms : dual_watch_count_toggle_10ms; - #else - gDualWatchCountdown_10ms = dual_watch_count_toggle_10ms; - #endif + #ifdef ENABLE_NOAA + gDualWatchCountdown_10ms = gIsNoaaMode ? dual_watch_count_noaa_10ms : dual_watch_count_toggle_10ms; + #else + gDualWatchCountdown_10ms = dual_watch_count_toggle_10ms; + #endif } static void CheckRadioInterrupts(void) { - if (SCANNER_IsScanning()) - return; + if (SCANNER_IsScanning()) + return; - while (BK4819_ReadRegister(BK4819_REG_0C) & 1u) { // BK chip interrupt request - // clear interrupts - BK4819_WriteRegister(BK4819_REG_02, 0); - // fetch interrupt status bits + while (BK4819_ReadRegister(BK4819_REG_0C) & 1u) { // BK chip interrupt request + // clear interrupts + BK4819_WriteRegister(BK4819_REG_02, 0); + // fetch interrupt status bits - union { - struct { - uint16_t __UNUSED : 1; - uint16_t fskRxSync : 1; - uint16_t sqlLost : 1; - uint16_t sqlFound : 1; - uint16_t voxLost : 1; - uint16_t voxFound : 1; - uint16_t ctcssLost : 1; - uint16_t ctcssFound : 1; - uint16_t cdcssLost : 1; - uint16_t cdcssFound : 1; - uint16_t cssTailFound : 1; - uint16_t dtmf5ToneFound : 1; - uint16_t fskFifoAlmostFull : 1; - uint16_t fskRxFinied : 1; - uint16_t fskFifoAlmostEmpty : 1; - uint16_t fskTxFinied : 1; - }; - uint16_t __raw; - } interrupts; + union { + struct { + uint16_t __UNUSED : 1; + uint16_t fskRxSync : 1; + uint16_t sqlLost : 1; + uint16_t sqlFound : 1; + uint16_t voxLost : 1; + uint16_t voxFound : 1; + uint16_t ctcssLost : 1; + uint16_t ctcssFound : 1; + uint16_t cdcssLost : 1; + uint16_t cdcssFound : 1; + uint16_t cssTailFound : 1; + uint16_t dtmf5ToneFound : 1; + uint16_t fskFifoAlmostFull : 1; + uint16_t fskRxFinied : 1; + uint16_t fskFifoAlmostEmpty : 1; + uint16_t fskTxFinied : 1; + }; + uint16_t __raw; + } interrupts; - interrupts.__raw = BK4819_ReadRegister(BK4819_REG_02); + interrupts.__raw = BK4819_ReadRegister(BK4819_REG_02); - // 0 = no phase shift - // 1 = 120deg phase shift - // 2 = 180deg phase shift - // 3 = 240deg phase shift -// const uint8_t ctcss_shift = BK4819_GetCTCShift(); -// if (ctcss_shift > 0) -// g_CTCSS_Lost = true; + // 0 = no phase shift + // 1 = 120deg phase shift + // 2 = 180deg phase shift + // 3 = 240deg phase shift +// const uint8_t ctcss_shift = BK4819_GetCTCShift(); +// if (ctcss_shift > 0) +// g_CTCSS_Lost = true; - if (interrupts.dtmf5ToneFound) { - const char c = DTMF_GetCharacter(BK4819_GetDTMF_5TONE_Code()); // save the RX'ed DTMF character - if (c != 0xff) { - if (gCurrentFunction != FUNCTION_TRANSMIT) { - if (gSetting_live_DTMF_decoder) { - size_t len = strlen(gDTMF_RX_live); - if (len >= sizeof(gDTMF_RX_live) - 1) { // make room - memmove(&gDTMF_RX_live[0], &gDTMF_RX_live[1], sizeof(gDTMF_RX_live) - 1); - len--; - } - gDTMF_RX_live[len++] = c; - gDTMF_RX_live[len] = 0; - gDTMF_RX_live_timeout = DTMF_RX_live_timeout_500ms; // time till we delete it - gUpdateDisplay = true; - } + if (interrupts.dtmf5ToneFound) { + const char c = DTMF_GetCharacter(BK4819_GetDTMF_5TONE_Code()); // save the RX'ed DTMF character + if (c != 0xff) { + if (gCurrentFunction != FUNCTION_TRANSMIT) { + if (gSetting_live_DTMF_decoder) { + size_t len = strlen(gDTMF_RX_live); + if (len >= sizeof(gDTMF_RX_live) - 1) { // make room + memmove(&gDTMF_RX_live[0], &gDTMF_RX_live[1], sizeof(gDTMF_RX_live) - 1); + len--; + } + gDTMF_RX_live[len++] = c; + gDTMF_RX_live[len] = 0; + gDTMF_RX_live_timeout = DTMF_RX_live_timeout_500ms; // time till we delete it + gUpdateDisplay = true; + } #ifdef ENABLE_DTMF_CALLING - if (gRxVfo->DTMF_DECODING_ENABLE || gSetting_KILLED) { - if (gDTMF_RX_index >= sizeof(gDTMF_RX) - 1) { // make room - memmove(&gDTMF_RX[0], &gDTMF_RX[1], sizeof(gDTMF_RX) - 1); - gDTMF_RX_index--; - } - gDTMF_RX[gDTMF_RX_index++] = c; - gDTMF_RX[gDTMF_RX_index] = 0; - gDTMF_RX_timeout = DTMF_RX_timeout_500ms; // time till we delete it - gDTMF_RX_pending = true; - - SYSTEM_DelayMs(3);//fix DTMF not reply@Yurisu - DTMF_HandleRequest(); - } + if (gRxVfo->DTMF_DECODING_ENABLE || gSetting_KILLED) { + if (gDTMF_RX_index >= sizeof(gDTMF_RX) - 1) { // make room + memmove(&gDTMF_RX[0], &gDTMF_RX[1], sizeof(gDTMF_RX) - 1); + gDTMF_RX_index--; + } + gDTMF_RX[gDTMF_RX_index++] = c; + gDTMF_RX[gDTMF_RX_index] = 0; + gDTMF_RX_timeout = DTMF_RX_timeout_500ms; // time till we delete it + gDTMF_RX_pending = true; + + SYSTEM_DelayMs(3);//fix DTMF not reply@Yurisu + DTMF_HandleRequest(); + } #endif - } - } - } + } + } + } - if (interrupts.cssTailFound) - g_CxCSS_TAIL_Found = true; + if (interrupts.cssTailFound) + g_CxCSS_TAIL_Found = true; - if (interrupts.cdcssLost) { - g_CDCSS_Lost = true; - gCDCSSCodeType = BK4819_GetCDCSSCodeType(); - } + if (interrupts.cdcssLost) { + g_CDCSS_Lost = true; + gCDCSSCodeType = BK4819_GetCDCSSCodeType(); + } - if (interrupts.cdcssFound) - g_CDCSS_Lost = false; + if (interrupts.cdcssFound) + g_CDCSS_Lost = false; - if (interrupts.ctcssLost) - g_CTCSS_Lost = true; + if (interrupts.ctcssLost) + g_CTCSS_Lost = true; - if (interrupts.ctcssFound) - g_CTCSS_Lost = false; + if (interrupts.ctcssFound) + g_CTCSS_Lost = false; #ifdef ENABLE_VOX - if (interrupts.voxLost) { - g_VOX_Lost = true; - gVoxPauseCountdown = 10; + if (interrupts.voxLost) { + g_VOX_Lost = true; + gVoxPauseCountdown = 10; - if (gEeprom.VOX_SWITCH) { - if (gCurrentFunction == FUNCTION_POWER_SAVE && !gRxIdleMode) { - gPowerSave_10ms = power_save2_10ms; - gPowerSaveCountdownExpired = 0; - } + if (gEeprom.VOX_SWITCH) { + if (gCurrentFunction == FUNCTION_POWER_SAVE && !gRxIdleMode) { + gPowerSave_10ms = power_save2_10ms; + gPowerSaveCountdownExpired = 0; + } - if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF && (gScheduleDualWatch || gDualWatchCountdown_10ms < dual_watch_count_after_vox_10ms)) { - gDualWatchCountdown_10ms = dual_watch_count_after_vox_10ms; - gScheduleDualWatch = false; + if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF && (gScheduleDualWatch || gDualWatchCountdown_10ms < dual_watch_count_after_vox_10ms)) { + gDualWatchCountdown_10ms = dual_watch_count_after_vox_10ms; + gScheduleDualWatch = false; - // let the user see DW is not active - gDualWatchActive = false; - gUpdateStatus = true; - } - } - } + // let the user see DW is not active + gDualWatchActive = false; + gUpdateStatus = true; + } + } + } - if (interrupts.voxFound) { - g_VOX_Lost = false; - gVoxPauseCountdown = 0; - } + if (interrupts.voxFound) { + g_VOX_Lost = false; + gVoxPauseCountdown = 0; + } #endif - if (interrupts.sqlLost) { - g_SquelchLost = true; - BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, true); - #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER - gRxTimerCountdown_500ms = 7200; - #endif - } + if (interrupts.sqlLost) { + g_SquelchLost = true; + BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, true); + #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER + gRxTimerCountdown_500ms = 7200; + #endif + } - if (interrupts.sqlFound) { - g_SquelchLost = false; - BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false); - } + if (interrupts.sqlFound) { + g_SquelchLost = false; + BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false); + } #ifdef ENABLE_AIRCOPY - if (interrupts.fskFifoAlmostFull && - gScreenToDisplay == DISPLAY_AIRCOPY && - gAircopyState == AIRCOPY_TRANSFER && - gAirCopyIsSendMode == 0) - { - for (unsigned int i = 0; i < 4; i++) { - g_FSK_Buffer[gFSKWriteIndex++] = BK4819_ReadRegister(BK4819_REG_5F); - } + if (interrupts.fskFifoAlmostFull && + gScreenToDisplay == DISPLAY_AIRCOPY && + gAircopyState == AIRCOPY_TRANSFER && + gAirCopyIsSendMode == 0) + { + for (unsigned int i = 0; i < 4; i++) { + g_FSK_Buffer[gFSKWriteIndex++] = BK4819_ReadRegister(BK4819_REG_5F); + } - AIRCOPY_StorePacket(); - } + AIRCOPY_StorePacket(); + } #endif - } + } } void APP_EndTransmission(void) { - // back to RX mode - RADIO_SendEndOfTransmission(); + // back to RX mode + RADIO_SendEndOfTransmission(); - gFlagEndTransmission = true; + gFlagEndTransmission = true; - if (gMonitor) { - //turn the monitor back on - gFlagReconfigureVfos = true; - } + if (gMonitor) { + //turn the monitor back on + gFlagReconfigureVfos = true; + } } #ifdef ENABLE_VOX static void HandleVox(void) { #ifdef ENABLE_DTMF_CALLING - if (gSetting_KILLED) - return; + if (gSetting_KILLED) + return; #endif - if (gVoxResumeCountdown == 0) { - if (gVoxPauseCountdown) - return; - } - else { - g_VOX_Lost = false; - gVoxPauseCountdown = 0; - } + if (gVoxResumeCountdown == 0) { + if (gVoxPauseCountdown) + return; + } + else { + g_VOX_Lost = false; + gVoxPauseCountdown = 0; + } #ifdef ENABLE_FMRADIO - if (gFmRadioMode) - return; + if (gFmRadioMode) + return; #endif - if (gCurrentFunction == FUNCTION_RECEIVE || gCurrentFunction == FUNCTION_MONITOR) - return; + if (gCurrentFunction == FUNCTION_RECEIVE || gCurrentFunction == FUNCTION_MONITOR) + return; - if (gScanStateDir != SCAN_OFF) - return; + if (gScanStateDir != SCAN_OFF) + return; - if (gVOX_NoiseDetected) { - if (g_VOX_Lost) - gVoxStopCountdown_10ms = vox_stop_count_down_10ms; - else if (gVoxStopCountdown_10ms == 0) - gVOX_NoiseDetected = false; + if (gVOX_NoiseDetected) { + if (g_VOX_Lost) + gVoxStopCountdown_10ms = vox_stop_count_down_10ms; + else if (gVoxStopCountdown_10ms == 0) + gVOX_NoiseDetected = false; - if (gCurrentFunction == FUNCTION_TRANSMIT && !gPttIsPressed && !gVOX_NoiseDetected) { - if (gFlagEndTransmission) { - //if (gCurrentFunction != FUNCTION_FOREGROUND) - FUNCTION_Select(FUNCTION_FOREGROUND); - } - else { - APP_EndTransmission(); + if (gCurrentFunction == FUNCTION_TRANSMIT && !gPttIsPressed && !gVOX_NoiseDetected) { + if (gFlagEndTransmission) { + //if (gCurrentFunction != FUNCTION_FOREGROUND) + FUNCTION_Select(FUNCTION_FOREGROUND); + } + else { + APP_EndTransmission(); - if (gEeprom.REPEATER_TAIL_TONE_ELIMINATION == 0) { - //if (gCurrentFunction != FUNCTION_FOREGROUND) - FUNCTION_Select(FUNCTION_FOREGROUND); - } - else - gRTTECountdown_10ms = gEeprom.REPEATER_TAIL_TONE_ELIMINATION * 10; - } + if (gEeprom.REPEATER_TAIL_TONE_ELIMINATION == 0) { + //if (gCurrentFunction != FUNCTION_FOREGROUND) + FUNCTION_Select(FUNCTION_FOREGROUND); + } + else + gRTTECountdown_10ms = gEeprom.REPEATER_TAIL_TONE_ELIMINATION * 10; + } - gUpdateStatus = true; - gUpdateDisplay = true; - gFlagEndTransmission = false; - } - return; - } + gUpdateStatus = true; + gUpdateDisplay = true; + gFlagEndTransmission = false; + } + return; + } - if (g_VOX_Lost) { - gVOX_NoiseDetected = true; + if (g_VOX_Lost) { + gVOX_NoiseDetected = true; - if (gCurrentFunction == FUNCTION_POWER_SAVE) - FUNCTION_Select(FUNCTION_FOREGROUND); + if (gCurrentFunction == FUNCTION_POWER_SAVE) + FUNCTION_Select(FUNCTION_FOREGROUND); - if (gCurrentFunction != FUNCTION_TRANSMIT && !SerialConfigInProgress()) { + if (gCurrentFunction != FUNCTION_TRANSMIT && !SerialConfigInProgress()) { #ifdef ENABLE_DTMF_CALLING - gDTMF_ReplyState = DTMF_REPLY_NONE; + gDTMF_ReplyState = DTMF_REPLY_NONE; #endif - RADIO_PrepareTX(); - gUpdateDisplay = true; - } - } + RADIO_PrepareTX(); + gUpdateDisplay = true; + } + } } #endif void APP_Update(void) { #ifdef ENABLE_VOICE - if (gFlagPlayQueuedVoice) { - AUDIO_PlayQueuedVoice(); - gFlagPlayQueuedVoice = false; - } + if (gFlagPlayQueuedVoice) { + AUDIO_PlayQueuedVoice(); + gFlagPlayQueuedVoice = false; + } #endif #ifdef ENABLE_FEAT_F4HWN - if (gCurrentFunction == FUNCTION_TRANSMIT && (gTxTimeoutReachedAlert || SerialConfigInProgress())) - { - if(gSetting_set_tot >= 2) - { - if (gEeprom.BACKLIGHT_TIME == 0) { - if (gBlinkCounter == 0 || gBlinkCounter == 250) - { - GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); - } - } - else - { - if (gBlinkCounter == 0) - { - //BACKLIGHT_TurnOn(); - BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX); - } - else if(gBlinkCounter == 15000) - { - //BACKLIGHT_TurnOff(); - BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MIN); - } - } - } + if (gCurrentFunction == FUNCTION_TRANSMIT && (gTxTimeoutReachedAlert || SerialConfigInProgress())) + { + if(gSetting_set_tot >= 2) + { + if (gEeprom.BACKLIGHT_TIME == 0) { + if (gBlinkCounter == 0 || gBlinkCounter == 250) + { + GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); + } + } + else + { + if (gBlinkCounter == 0) + { + //BACKLIGHT_TurnOn(); + BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX); + } + else if(gBlinkCounter == 15000) + { + //BACKLIGHT_TurnOff(); + BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MIN); + } + } + } - gBlinkCounter++; + gBlinkCounter++; - if( - (gSetting_set_tot == 3 && gEeprom.BACKLIGHT_TIME != 0 && gBlinkCounter > 74000) || - (gSetting_set_tot == 3 && gEeprom.BACKLIGHT_TIME == 0 && gBlinkCounter > 79000) || - (gSetting_set_tot != 3 && gBlinkCounter > 76000) - ) // try to calibrate 10 times - { - gBlinkCounter = 0; + if( + (gSetting_set_tot == 3 && gEeprom.BACKLIGHT_TIME != 0 && gBlinkCounter > 74000) || + (gSetting_set_tot == 3 && gEeprom.BACKLIGHT_TIME == 0 && gBlinkCounter > 79000) || + (gSetting_set_tot != 3 && gBlinkCounter > 76000) + ) // try to calibrate 10 times + { + gBlinkCounter = 0; - if(gSetting_set_tot == 1 || gSetting_set_tot == 3) - { - BK4819_DisableScramble(); - BK4819_PlaySingleTone(gTxTimeoutToneAlert, 30, 1, true); - gTxTimeoutToneAlert += 100; - } - } - } + if(gSetting_set_tot == 1 || gSetting_set_tot == 3) + { + BK4819_DisableScramble(); + BK4819_PlaySingleTone(gTxTimeoutToneAlert, 30, 1, true); + gTxTimeoutToneAlert += 100; + } + } + } #endif - if (gCurrentFunction == FUNCTION_TRANSMIT && (gTxTimeoutReached || SerialConfigInProgress())) - { // transmitter timed out or must de-key - gTxTimeoutReached = false; + if (gCurrentFunction == FUNCTION_TRANSMIT && (gTxTimeoutReached || SerialConfigInProgress())) + { // transmitter timed out or must de-key + gTxTimeoutReached = false; #ifdef ENABLE_FEAT_F4HWN - if(gBacklightCountdown_500ms > 0 || gEeprom.BACKLIGHT_TIME == 61) - { - //BACKLIGHT_TurnOn(); - BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX); - } + if(gBacklightCountdown_500ms > 0 || gEeprom.BACKLIGHT_TIME == 61) + { + //BACKLIGHT_TurnOn(); + BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX); + } - gTxTimeoutReachedAlert = false; - gTxTimeoutToneAlert = 800; + gTxTimeoutReachedAlert = false; + gTxTimeoutToneAlert = 800; - if (gSetting_set_ptt_session) // Improve OnePush if TOT - { - if(gPttOnePushCounter == 1) - { - gPttOnePushCounter = 3; - } - else if(gPttOnePushCounter == 2) - { - ProcessKey(KEY_PTT, false, false); - gPttIsPressed = false; - gPttOnePushCounter = 0; - gPttWasReleased = true; - //if (gKeyReading1 != KEY_INVALID) - // gPttWasReleased = true; - } - ST7565_ContrastAndInv(); - } - /* - if (gSetting_set_ptt_session) // Improve OnePush if TOT - { - ProcessKey(KEY_PTT, false, false); - gPttIsPressed = false; - gPttOnePushCounter = 0; - if (gKeyReading1 != KEY_INVALID) - gPttWasReleased = true; - ST7565_ContrastAndInv(); - } - */ + if (gSetting_set_ptt_session) // Improve OnePush if TOT + { + if(gPttOnePushCounter == 1) + { + gPttOnePushCounter = 3; + } + else if(gPttOnePushCounter == 2) + { + ProcessKey(KEY_PTT, false, false); + gPttIsPressed = false; + gPttOnePushCounter = 0; + gPttWasReleased = true; + //if (gKeyReading1 != KEY_INVALID) + // gPttWasReleased = true; + } + ST7565_ContrastAndInv(); + } + /* + if (gSetting_set_ptt_session) // Improve OnePush if TOT + { + ProcessKey(KEY_PTT, false, false); + gPttIsPressed = false; + gPttOnePushCounter = 0; + if (gKeyReading1 != KEY_INVALID) + gPttWasReleased = true; + ST7565_ContrastAndInv(); + } + */ #endif - APP_EndTransmission(); + APP_EndTransmission(); - AUDIO_PlayBeep(BEEP_880HZ_60MS_DOUBLE_BEEP); + AUDIO_PlayBeep(BEEP_880HZ_60MS_DOUBLE_BEEP); - RADIO_SetVfoState(VFO_STATE_TIMEOUT); + RADIO_SetVfoState(VFO_STATE_TIMEOUT); - GUI_DisplayScreen(); - } + GUI_DisplayScreen(); + } - if (gReducedService) - return; + if (gReducedService) + return; - if (gCurrentFunction != FUNCTION_TRANSMIT) - HandleFunction(); + if (gCurrentFunction != FUNCTION_TRANSMIT) + HandleFunction(); #ifdef ENABLE_FMRADIO -// if (gFmRadioCountdown_500ms > 0) - if (gFmRadioMode && gFmRadioCountdown_500ms > 0) // 1of11 - return; +// if (gFmRadioCountdown_500ms > 0) + if (gFmRadioMode && gFmRadioCountdown_500ms > 0) // 1of11 + return; #endif #ifdef ENABLE_VOICE - if (!SCANNER_IsScanning() && gScanStateDir != SCAN_OFF && gScheduleScanListen && !gPttIsPressed && gVoiceWriteIndex == 0) + if (!SCANNER_IsScanning() && gScanStateDir != SCAN_OFF && gScheduleScanListen && !gPttIsPressed && gVoiceWriteIndex == 0) #else - if (!SCANNER_IsScanning() && gScanStateDir != SCAN_OFF && gScheduleScanListen && !gPttIsPressed) + if (!SCANNER_IsScanning() && gScanStateDir != SCAN_OFF && gScheduleScanListen && !gPttIsPressed) #endif - { // scanning - CHFRSCANNER_ContinueScanning(); - } + { // scanning + CHFRSCANNER_ContinueScanning(); + } #ifdef ENABLE_NOAA #ifdef ENABLE_VOICE - if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode && gScheduleNOAA && gVoiceWriteIndex == 0) + if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode && gScheduleNOAA && gVoiceWriteIndex == 0) #else - if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode && gScheduleNOAA) + if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode && gScheduleNOAA) #endif - { - NOAA_IncreaseChannel(); - RADIO_SetupRegisters(false); + { + NOAA_IncreaseChannel(); + RADIO_SetupRegisters(false); - gNOAA_Countdown_10ms = 7; // 70ms - gScheduleNOAA = false; - } + gNOAA_Countdown_10ms = 7; // 70ms + gScheduleNOAA = false; + } #endif - // toggle between the VFO's if dual watch is enabled - if (!SCANNER_IsScanning() - && gEeprom.DUAL_WATCH != DUAL_WATCH_OFF - && gScheduleDualWatch - && gScanStateDir == SCAN_OFF - && !gPttIsPressed - && gCurrentFunction != FUNCTION_POWER_SAVE + // toggle between the VFO's if dual watch is enabled + if (!SCANNER_IsScanning() + && gEeprom.DUAL_WATCH != DUAL_WATCH_OFF + && gScheduleDualWatch + && gScanStateDir == SCAN_OFF + && !gPttIsPressed + && gCurrentFunction != FUNCTION_POWER_SAVE #ifdef ENABLE_VOICE - && gVoiceWriteIndex == 0 + && gVoiceWriteIndex == 0 #endif #ifdef ENABLE_FMRADIO - && !gFmRadioMode + && !gFmRadioMode #endif #ifdef ENABLE_DTMF_CALLING - && gDTMF_CallState == DTMF_CALL_STATE_NONE + && gDTMF_CallState == DTMF_CALL_STATE_NONE #endif - ) { - DualwatchAlternate(); // toggle between the two VFO's + ) { + DualwatchAlternate(); // toggle between the two VFO's - if (gRxVfoIsActive && gScreenToDisplay == DISPLAY_MAIN) { - GUI_SelectNextDisplay(DISPLAY_MAIN); - } + if (gRxVfoIsActive && gScreenToDisplay == DISPLAY_MAIN) { + GUI_SelectNextDisplay(DISPLAY_MAIN); + } - gRxVfoIsActive = false; - gScanPauseMode = false; - gRxReceptionMode = RX_MODE_NONE; - gScheduleDualWatch = false; - } + gRxVfoIsActive = false; + gScanPauseMode = false; + gRxReceptionMode = RX_MODE_NONE; + gScheduleDualWatch = false; + } #ifdef ENABLE_FMRADIO - if (gScheduleFM && gFM_ScanState != FM_SCAN_OFF && !FUNCTION_IsRx()) { - // switch to FM radio mode - FM_Play(); - gScheduleFM = false; - } + if (gScheduleFM && gFM_ScanState != FM_SCAN_OFF && !FUNCTION_IsRx()) { + // switch to FM radio mode + FM_Play(); + gScheduleFM = false; + } #endif #ifdef ENABLE_VOX - if (gEeprom.VOX_SWITCH) - HandleVox(); + if (gEeprom.VOX_SWITCH) + HandleVox(); #endif - if (gSchedulePowerSave) { - if (gPttIsPressed - || gKeyBeingHeld - || gEeprom.BATTERY_SAVE == 0 - || gScanStateDir != SCAN_OFF - || gCssBackgroundScan - || gScreenToDisplay != DISPLAY_MAIN + if (gSchedulePowerSave) { + if (gPttIsPressed + || gKeyBeingHeld + || gEeprom.BATTERY_SAVE == 0 + || gScanStateDir != SCAN_OFF + || gCssBackgroundScan + || gScreenToDisplay != DISPLAY_MAIN #ifdef ENABLE_FMRADIO - || gFmRadioMode + || gFmRadioMode #endif #ifdef ENABLE_DTMF_CALLING - || gDTMF_CallState != DTMF_CALL_STATE_NONE + || gDTMF_CallState != DTMF_CALL_STATE_NONE #endif #ifdef ENABLE_NOAA - || (gIsNoaaMode && (IS_NOAA_CHANNEL(gEeprom.ScreenChannel[0]) || IS_NOAA_CHANNEL(gEeprom.ScreenChannel[1]))) + || (gIsNoaaMode && (IS_NOAA_CHANNEL(gEeprom.ScreenChannel[0]) || IS_NOAA_CHANNEL(gEeprom.ScreenChannel[1]))) #endif - ) { - gBatterySaveCountdown_10ms = battery_save_count_10ms; - } else { - FUNCTION_Select(FUNCTION_POWER_SAVE); - } + ) { + gBatterySaveCountdown_10ms = battery_save_count_10ms; + } else { + FUNCTION_Select(FUNCTION_POWER_SAVE); + } - gSchedulePowerSave = false; - } + gSchedulePowerSave = false; + } - if (gPowerSaveCountdownExpired && gCurrentFunction == FUNCTION_POWER_SAVE + if (gPowerSaveCountdownExpired && gCurrentFunction == FUNCTION_POWER_SAVE #ifdef ENABLE_VOICE - && gVoiceWriteIndex == 0 + && gVoiceWriteIndex == 0 #endif - ) { - static bool goToSleep; - // wake up, enable RX then go back to sleep - if (gRxIdleMode) - { - BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable(); + ) { + static bool goToSleep; + // wake up, enable RX then go back to sleep + if (gRxIdleMode) + { + BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable(); #ifdef ENABLE_VOX - if (gEeprom.VOX_SWITCH) - BK4819_EnableVox(gEeprom.VOX1_THRESHOLD, gEeprom.VOX0_THRESHOLD); + if (gEeprom.VOX_SWITCH) + BK4819_EnableVox(gEeprom.VOX1_THRESHOLD, gEeprom.VOX0_THRESHOLD); #endif - if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF && - gScanStateDir == SCAN_OFF && - !gCssBackgroundScan) - { // dual watch mode, toggle between the two VFO's - DualwatchAlternate(); - goToSleep = false; - } + if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF && + gScanStateDir == SCAN_OFF && + !gCssBackgroundScan) + { // dual watch mode, toggle between the two VFO's + DualwatchAlternate(); + goToSleep = false; + } - FUNCTION_Init(); + FUNCTION_Init(); - gPowerSave_10ms = power_save1_10ms; // come back here in a bit - gRxIdleMode = false; // RX is awake - } - else if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF || gScanStateDir != SCAN_OFF || gCssBackgroundScan || goToSleep) - { // dual watch mode off or scanning or rssi update request - // go back to sleep + gPowerSave_10ms = power_save1_10ms; // come back here in a bit + gRxIdleMode = false; // RX is awake + } + else if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF || gScanStateDir != SCAN_OFF || gCssBackgroundScan || goToSleep) + { // dual watch mode off or scanning or rssi update request + // go back to sleep - gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10; - gRxIdleMode = true; - goToSleep = false; + gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10; + gRxIdleMode = true; + goToSleep = false; - BK4819_DisableVox(); - BK4819_Sleep(); - BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false); + BK4819_DisableVox(); + BK4819_Sleep(); + BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false); - // Authentic device checked removed + // Authentic device checked removed - } - else { - // toggle between the two VFO's - DualwatchAlternate(); - gPowerSave_10ms = power_save1_10ms; - goToSleep = true; - } + } + else { + // toggle between the two VFO's + DualwatchAlternate(); + gPowerSave_10ms = power_save1_10ms; + goToSleep = true; + } - gPowerSaveCountdownExpired = false; - } + gPowerSaveCountdownExpired = false; + } } // called every 10ms static void CheckKeys(void) { #ifdef ENABLE_DTMF_CALLING - if(gSetting_KILLED){ - return; - } + if(gSetting_KILLED){ + return; + } #endif #ifdef ENABLE_AIRCOPY - if (gScreenToDisplay == DISPLAY_AIRCOPY && gAircopyState != AIRCOPY_READY){ - return; - } + if (gScreenToDisplay == DISPLAY_AIRCOPY && gAircopyState != AIRCOPY_READY){ + return; + } #endif // -------------------- PTT ------------------------ #ifdef ENABLE_FEAT_F4HWN - if (gSetting_set_ptt_session) - { - if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && !SerialConfigInProgress() && gPttOnePushCounter == 0) - { // PTT pressed - if (++gPttDebounceCounter >= 3) // 30ms - { // start transmitting - boot_counter_10ms = 0; - gPttDebounceCounter = 0; - gPttIsPressed = true; - gPttOnePushCounter = 1; - ProcessKey(KEY_PTT, true, false); - } - } - else if ((GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || SerialConfigInProgress()) && gPttOnePushCounter == 1) - { - // PTT released or serial comms config in progress - if (++gPttDebounceCounter >= 3 || SerialConfigInProgress()) // 30ms - { // stop transmitting - gPttOnePushCounter = 2; - } - } - else if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && !SerialConfigInProgress() && gPttOnePushCounter == 2) - { // PTT pressed again - if (++gPttDebounceCounter >= 3 || SerialConfigInProgress()) // 30ms - { // stop transmitting - gPttOnePushCounter = 3; - } - } - else if ((GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || SerialConfigInProgress()) && gPttOnePushCounter == 3) - { // PTT released or serial comms config in progress - if (++gPttDebounceCounter >= 3 || SerialConfigInProgress()) // 30ms - { // stop transmitting - ProcessKey(KEY_PTT, false, false); - gPttIsPressed = false; - if (gKeyReading1 != KEY_INVALID) - gPttWasReleased = true; - gPttOnePushCounter = 0; - ST7565_ContrastAndInv(); - } - } - else - gPttDebounceCounter = 0; + if (gSetting_set_ptt_session) + { + if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && !SerialConfigInProgress() && gPttOnePushCounter == 0) + { // PTT pressed + if (++gPttDebounceCounter >= 3) // 30ms + { // start transmitting + boot_counter_10ms = 0; + gPttDebounceCounter = 0; + gPttIsPressed = true; + gPttOnePushCounter = 1; + ProcessKey(KEY_PTT, true, false); + } + } + else if ((GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || SerialConfigInProgress()) && gPttOnePushCounter == 1) + { + // PTT released or serial comms config in progress + if (++gPttDebounceCounter >= 3 || SerialConfigInProgress()) // 30ms + { // stop transmitting + gPttOnePushCounter = 2; + } + } + else if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && !SerialConfigInProgress() && gPttOnePushCounter == 2) + { // PTT pressed again + if (++gPttDebounceCounter >= 3 || SerialConfigInProgress()) // 30ms + { // stop transmitting + gPttOnePushCounter = 3; + } + } + else if ((GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || SerialConfigInProgress()) && gPttOnePushCounter == 3) + { // PTT released or serial comms config in progress + if (++gPttDebounceCounter >= 3 || SerialConfigInProgress()) // 30ms + { // stop transmitting + ProcessKey(KEY_PTT, false, false); + gPttIsPressed = false; + if (gKeyReading1 != KEY_INVALID) + gPttWasReleased = true; + gPttOnePushCounter = 0; + ST7565_ContrastAndInv(); + } + } + else + gPttDebounceCounter = 0; - //gDebug = gPttOnePushCounter; - } - else - { - if (gPttIsPressed) - { - if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || SerialConfigInProgress()) - { // PTT released or serial comms config in progress - if (++gPttDebounceCounter >= 3 || SerialConfigInProgress()) // 30ms - { // stop transmitting - ProcessKey(KEY_PTT, false, false); - gPttIsPressed = false; - if (gKeyReading1 != KEY_INVALID) - gPttWasReleased = true; - ST7565_ContrastAndInv(); - } - } - else - gPttDebounceCounter = 0; - } - else if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && !SerialConfigInProgress()) - { // PTT pressed - if (++gPttDebounceCounter >= 3) // 30ms - { // start transmitting - boot_counter_10ms = 0; - gPttDebounceCounter = 0; - gPttIsPressed = true; - ProcessKey(KEY_PTT, true, false); - } - } - else - gPttDebounceCounter = 0; - } + //gDebug = gPttOnePushCounter; + } + else + { + if (gPttIsPressed) + { + if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || SerialConfigInProgress()) + { // PTT released or serial comms config in progress + if (++gPttDebounceCounter >= 3 || SerialConfigInProgress()) // 30ms + { // stop transmitting + ProcessKey(KEY_PTT, false, false); + gPttIsPressed = false; + if (gKeyReading1 != KEY_INVALID) + gPttWasReleased = true; + ST7565_ContrastAndInv(); + } + } + else + gPttDebounceCounter = 0; + } + else if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && !SerialConfigInProgress()) + { // PTT pressed + if (++gPttDebounceCounter >= 3) // 30ms + { // start transmitting + boot_counter_10ms = 0; + gPttDebounceCounter = 0; + gPttIsPressed = true; + ProcessKey(KEY_PTT, true, false); + } + } + else + gPttDebounceCounter = 0; + } #else - if (gPttIsPressed) - { - if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || SerialConfigInProgress()) - { // PTT released or serial comms config in progress - if (++gPttDebounceCounter >= 3 || SerialConfigInProgress()) // 30ms - { // stop transmitting - ProcessKey(KEY_PTT, false, false); - gPttIsPressed = false; - if (gKeyReading1 != KEY_INVALID) - gPttWasReleased = true; - } - } - else - gPttDebounceCounter = 0; - } - else if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && !SerialConfigInProgress()) - { // PTT pressed - if (++gPttDebounceCounter >= 3) // 30ms - { // start transmitting - boot_counter_10ms = 0; - gPttDebounceCounter = 0; - gPttIsPressed = true; - ProcessKey(KEY_PTT, true, false); - } - } - else - gPttDebounceCounter = 0; + if (gPttIsPressed) + { + if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || SerialConfigInProgress()) + { // PTT released or serial comms config in progress + if (++gPttDebounceCounter >= 3 || SerialConfigInProgress()) // 30ms + { // stop transmitting + ProcessKey(KEY_PTT, false, false); + gPttIsPressed = false; + if (gKeyReading1 != KEY_INVALID) + gPttWasReleased = true; + } + } + else + gPttDebounceCounter = 0; + } + else if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && !SerialConfigInProgress()) + { // PTT pressed + if (++gPttDebounceCounter >= 3) // 30ms + { // start transmitting + boot_counter_10ms = 0; + gPttDebounceCounter = 0; + gPttIsPressed = true; + ProcessKey(KEY_PTT, true, false); + } + } + else + gPttDebounceCounter = 0; #endif // --------------------- OTHER KEYS ---------------------------- - // scan the hardware keys - KEY_Code_t Key = KEYBOARD_Poll(); + // scan the hardware keys + KEY_Code_t Key = KEYBOARD_Poll(); - if (Key != KEY_INVALID) // any key pressed - boot_counter_10ms = 0; // cancel boot screen/beeps if any key pressed + if (Key != KEY_INVALID) // any key pressed + boot_counter_10ms = 0; // cancel boot screen/beeps if any key pressed - if (gKeyReading0 != Key) // new key pressed - { + if (gKeyReading0 != Key) // new key pressed + { - if (gKeyReading0 != KEY_INVALID && Key != KEY_INVALID) - ProcessKey(gKeyReading1, false, gKeyBeingHeld); // key pressed without releasing previous key + if (gKeyReading0 != KEY_INVALID && Key != KEY_INVALID) + ProcessKey(gKeyReading1, false, gKeyBeingHeld); // key pressed without releasing previous key - gKeyReading0 = Key; - gDebounceCounter = 0; - return; - } + gKeyReading0 = Key; + gDebounceCounter = 0; + return; + } - gDebounceCounter++; + gDebounceCounter++; - if (gDebounceCounter == key_debounce_10ms) // debounced new key pressed - { - if (Key == KEY_INVALID) //all non PTT keys released - { - if (gKeyReading1 != KEY_INVALID) // some button was pressed before - { - ProcessKey(gKeyReading1, false, gKeyBeingHeld); // process last button released event - gKeyReading1 = KEY_INVALID; - } - } - else // process new key pressed - { - gKeyReading1 = Key; - ProcessKey(Key, true, false); - } + if (gDebounceCounter == key_debounce_10ms) // debounced new key pressed + { + if (Key == KEY_INVALID) //all non PTT keys released + { + if (gKeyReading1 != KEY_INVALID) // some button was pressed before + { + ProcessKey(gKeyReading1, false, gKeyBeingHeld); // process last button released event + gKeyReading1 = KEY_INVALID; + } + } + else // process new key pressed + { + gKeyReading1 = Key; + ProcessKey(Key, true, false); + } - gKeyBeingHeld = false; - return; - } + gKeyBeingHeld = false; + return; + } - if (gDebounceCounter < key_repeat_delay_10ms || Key == KEY_INVALID) // the button is not held long enough for repeat yet, or not really pressed - return; + if (gDebounceCounter < key_repeat_delay_10ms || Key == KEY_INVALID) // the button is not held long enough for repeat yet, or not really pressed + return; - if (gDebounceCounter == key_repeat_delay_10ms) //initial key repeat with longer delay - { - if (Key != KEY_PTT) - { - gKeyBeingHeld = true; - ProcessKey(Key, true, true); // key held event - } - } - else //subsequent fast key repeats - { - if (Key == KEY_UP || Key == KEY_DOWN) // fast key repeats for up/down buttons - { - gKeyBeingHeld = true; - if ((gDebounceCounter % key_repeat_10ms) == 0) - ProcessKey(Key, true, true); // key held event - } + if (gDebounceCounter == key_repeat_delay_10ms) //initial key repeat with longer delay + { + if (Key != KEY_PTT) + { + gKeyBeingHeld = true; + ProcessKey(Key, true, true); // key held event + } + } + else //subsequent fast key repeats + { + if (Key == KEY_UP || Key == KEY_DOWN) // fast key repeats for up/down buttons + { + gKeyBeingHeld = true; + if ((gDebounceCounter % key_repeat_10ms) == 0) + ProcessKey(Key, true, true); // key held event + } - if (gDebounceCounter < 0xFFFF) - return; + if (gDebounceCounter < 0xFFFF) + return; - gDebounceCounter = key_repeat_delay_10ms+1; - } + gDebounceCounter = key_repeat_delay_10ms+1; + } } void APP_TimeSlice10ms(void) { - gNextTimeslice = false; - gFlashLightBlinkCounter++; + gNextTimeslice = false; + gFlashLightBlinkCounter++; #ifdef ENABLE_AM_FIX - if (gRxVfo->Modulation == MODULATION_AM) { - AM_fix_10ms(gEeprom.RX_VFO); - } + if (gRxVfo->Modulation == MODULATION_AM) { + AM_fix_10ms(gEeprom.RX_VFO); + } #endif #ifdef ENABLE_UART - if (UART_IsCommandAvailable()) { - __disable_irq(); - UART_HandleCommand(); - __enable_irq(); - } + if (UART_IsCommandAvailable()) { + __disable_irq(); + UART_HandleCommand(); + __enable_irq(); + } #endif - if (gReducedService) - return; + if (gReducedService) + return; - if (gCurrentFunction != FUNCTION_POWER_SAVE || !gRxIdleMode) - CheckRadioInterrupts(); + if (gCurrentFunction != FUNCTION_POWER_SAVE || !gRxIdleMode) + CheckRadioInterrupts(); - if (gCurrentFunction == FUNCTION_TRANSMIT) - { // transmitting + if (gCurrentFunction == FUNCTION_TRANSMIT) + { // transmitting #ifdef ENABLE_AUDIO_BAR - if (gSetting_mic_bar && (gFlashLightBlinkCounter % (150 / 10)) == 0) // once every 150ms - UI_DisplayAudioBar(); + if (gSetting_mic_bar && (gFlashLightBlinkCounter % (150 / 10)) == 0) // once every 150ms + UI_DisplayAudioBar(); #endif - } + } - if (gUpdateDisplay) { - gUpdateDisplay = false; - GUI_DisplayScreen(); - } + if (gUpdateDisplay) { + gUpdateDisplay = false; + GUI_DisplayScreen(); + } - if (gUpdateStatus) - UI_DisplayStatus(); + if (gUpdateStatus) + UI_DisplayStatus(); - // Skipping authentic device checks + // Skipping authentic device checks #ifdef ENABLE_FMRADIO - if (gFmRadioMode && gFmRadioCountdown_500ms > 0) // 1of11 - return; + if (gFmRadioMode && gFmRadioCountdown_500ms > 0) // 1of11 + return; #endif #ifndef ENABLE_FEAT_F4HWN - #ifdef ENABLE_FLASHLIGHT - FlashlightTimeSlice(); - #endif + #ifdef ENABLE_FLASHLIGHT + FlashlightTimeSlice(); + #endif #endif #ifdef ENABLE_VOX - if (gVoxResumeCountdown > 0) - gVoxResumeCountdown--; + if (gVoxResumeCountdown > 0) + gVoxResumeCountdown--; - if (gVoxPauseCountdown > 0) - gVoxPauseCountdown--; + if (gVoxPauseCountdown > 0) + gVoxPauseCountdown--; #endif - if (gCurrentFunction == FUNCTION_TRANSMIT) { + if (gCurrentFunction == FUNCTION_TRANSMIT) { #ifdef ENABLE_ALARM - if (gAlarmState == ALARM_STATE_TXALARM || gAlarmState == ALARM_STATE_SITE_ALARM) { - uint16_t Tone; + if (gAlarmState == ALARM_STATE_TXALARM || gAlarmState == ALARM_STATE_SITE_ALARM) { + uint16_t Tone; - gAlarmRunningCounter++; - gAlarmToneCounter++; + gAlarmRunningCounter++; + gAlarmToneCounter++; - Tone = 500 + (gAlarmToneCounter * 25); - if (Tone > 1500) { - Tone = 500; - gAlarmToneCounter = 0; - } + Tone = 500 + (gAlarmToneCounter * 25); + if (Tone > 1500) { + Tone = 500; + gAlarmToneCounter = 0; + } - BK4819_SetScrambleFrequencyControlWord(Tone); + BK4819_SetScrambleFrequencyControlWord(Tone); - if (gEeprom.ALARM_MODE == ALARM_MODE_TONE && gAlarmRunningCounter == 512) { - gAlarmRunningCounter = 0; + if (gEeprom.ALARM_MODE == ALARM_MODE_TONE && gAlarmRunningCounter == 512) { + gAlarmRunningCounter = 0; - if (gAlarmState == ALARM_STATE_TXALARM) { - gAlarmState = ALARM_STATE_SITE_ALARM; + if (gAlarmState == ALARM_STATE_TXALARM) { + gAlarmState = ALARM_STATE_SITE_ALARM; - if(gEeprom.TAIL_TONE_ELIMINATION) - RADIO_SendCssTail(); - BK4819_SetupPowerAmplifier(0, 0); - BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false); - BK4819_Enable_AfDac_DiscMode_TxDsp(); - BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false); + if(gEeprom.TAIL_TONE_ELIMINATION) + RADIO_SendCssTail(); + BK4819_SetupPowerAmplifier(0, 0); + BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false); + BK4819_Enable_AfDac_DiscMode_TxDsp(); + BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false); - GUI_DisplayScreen(); - } - else { - gAlarmState = ALARM_STATE_TXALARM; + GUI_DisplayScreen(); + } + else { + gAlarmState = ALARM_STATE_TXALARM; - GUI_DisplayScreen(); + GUI_DisplayScreen(); - BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); - RADIO_SetTxParameters(); - BK4819_TransmitTone(true, 500); - SYSTEM_DelayMs(2); - AUDIO_AudioPathOn(); + BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); + RADIO_SetTxParameters(); + BK4819_TransmitTone(true, 500); + SYSTEM_DelayMs(2); + AUDIO_AudioPathOn(); - gEnableSpeaker = true; - gAlarmToneCounter = 0; - } - } - } + gEnableSpeaker = true; + gAlarmToneCounter = 0; + } + } + } #endif - // repeater tail tone elimination - if (gRTTECountdown_10ms > 0) { - if (--gRTTECountdown_10ms == 0) { - //if (gCurrentFunction != FUNCTION_FOREGROUND) - FUNCTION_Select(FUNCTION_FOREGROUND); + // repeater tail tone elimination + if (gRTTECountdown_10ms > 0) { + if (--gRTTECountdown_10ms == 0) { + //if (gCurrentFunction != FUNCTION_FOREGROUND) + FUNCTION_Select(FUNCTION_FOREGROUND); - gUpdateStatus = true; - gUpdateDisplay = true; - } - } - } + gUpdateStatus = true; + gUpdateDisplay = true; + } + } + } #ifdef ENABLE_FMRADIO - if (gFmRadioMode && gFM_RestoreCountdown_10ms > 0) { - if (--gFM_RestoreCountdown_10ms == 0) { - FM_Start(); // switch back to FM radio mode - GUI_SelectNextDisplay(DISPLAY_FM); - } - } + if (gFmRadioMode && gFM_RestoreCountdown_10ms > 0) { + if (--gFM_RestoreCountdown_10ms == 0) { + FM_Start(); // switch back to FM radio mode + GUI_SelectNextDisplay(DISPLAY_FM); + } + } #endif - SCANNER_TimeSlice10ms(); + SCANNER_TimeSlice10ms(); #ifdef ENABLE_AIRCOPY - if (gScreenToDisplay == DISPLAY_AIRCOPY && gAircopyState == AIRCOPY_TRANSFER && gAirCopyIsSendMode == 1) { - if (!AIRCOPY_SendMessage()) { - GUI_DisplayScreen(); - } - } + if (gScreenToDisplay == DISPLAY_AIRCOPY && gAircopyState == AIRCOPY_TRANSFER && gAirCopyIsSendMode == 1) { + if (!AIRCOPY_SendMessage()) { + GUI_DisplayScreen(); + } + } #endif - CheckKeys(); + CheckKeys(); } void cancelUserInputModes(void) { - if (gDTMF_InputMode || gDTMF_InputBox_Index > 0) - { - DTMF_clear_input_box(); - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - gRequestDisplayScreen = DISPLAY_MAIN; - gUpdateDisplay = true; - } + if (gDTMF_InputMode || gDTMF_InputBox_Index > 0) + { + DTMF_clear_input_box(); + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + gRequestDisplayScreen = DISPLAY_MAIN; + gUpdateDisplay = true; + } - if (gWasFKeyPressed || gKeyInputCountdown > 0 || gInputBoxIndex > 0) - { - gWasFKeyPressed = false; - gInputBoxIndex = 0; - gKeyInputCountdown = 0; - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - gUpdateStatus = true; - gUpdateDisplay = true; - } + if (gWasFKeyPressed || gKeyInputCountdown > 0 || gInputBoxIndex > 0) + { + gWasFKeyPressed = false; + gInputBoxIndex = 0; + gKeyInputCountdown = 0; + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + gUpdateStatus = true; + gUpdateDisplay = true; + } } // this is called once every 500ms void APP_TimeSlice500ms(void) { - gNextTimeslice_500ms = false; - bool exit_menu = false; + gNextTimeslice_500ms = false; + bool exit_menu = false; - // Skipped authentic device check + // Skipped authentic device check - if (gKeypadLocked > 0) - if (--gKeypadLocked == 0) - gUpdateDisplay = true; + if (gKeypadLocked > 0) + if (--gKeypadLocked == 0) + gUpdateDisplay = true; - if (gKeyInputCountdown > 0) - { - if (--gKeyInputCountdown == 0) - { + if (gKeyInputCountdown > 0) + { + if (--gKeyInputCountdown == 0) + { - if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE) && (gInputBoxIndex == 1 || gInputBoxIndex == 2)) - { - channelMoveSwitch(); + if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE) && (gInputBoxIndex == 1 || gInputBoxIndex == 2)) + { + channelMoveSwitch(); - if (gBeepToPlay == BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL) { - AUDIO_PlayBeep(gBeepToPlay); - } + if (gBeepToPlay == BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL) { + AUDIO_PlayBeep(gBeepToPlay); + } - SETTINGS_SaveVfoIndices(); - } + SETTINGS_SaveVfoIndices(); + } - cancelUserInputModes(); - } - } + cancelUserInputModes(); + } + } - if (gDTMF_RX_live_timeout > 0) - { - #ifdef ENABLE_RSSI_BAR - if (center_line == CENTER_LINE_DTMF_DEC || - center_line == CENTER_LINE_NONE) // wait till the center line is free for us to use before timing out - #endif - { - if (--gDTMF_RX_live_timeout == 0) - { - if (gDTMF_RX_live[0] != 0) - { - memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); - gUpdateDisplay = true; - } - } - } - } + if (gDTMF_RX_live_timeout > 0) + { + #ifdef ENABLE_RSSI_BAR + if (center_line == CENTER_LINE_DTMF_DEC || + center_line == CENTER_LINE_NONE) // wait till the center line is free for us to use before timing out + #endif + { + if (--gDTMF_RX_live_timeout == 0) + { + if (gDTMF_RX_live[0] != 0) + { + memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); + gUpdateDisplay = true; + } + } + } + } - if (gMenuCountdown > 0) - if (--gMenuCountdown == 0) - exit_menu = (gScreenToDisplay == DISPLAY_MENU); // exit menu mode + if (gMenuCountdown > 0) + if (--gMenuCountdown == 0) + exit_menu = (gScreenToDisplay == DISPLAY_MENU); // exit menu mode #ifdef ENABLE_DTMF_CALLING - if (gDTMF_RX_timeout > 0) - if (--gDTMF_RX_timeout == 0) - DTMF_clear_RX(); + if (gDTMF_RX_timeout > 0) + if (--gDTMF_RX_timeout == 0) + DTMF_clear_RX(); #endif - // Skipped authentic device check + // Skipped authentic device check #ifdef ENABLE_FMRADIO - if (gFmRadioCountdown_500ms > 0) - { - gFmRadioCountdown_500ms--; - if (gFmRadioMode) // 1of11 - return; - } + if (gFmRadioCountdown_500ms > 0) + { + gFmRadioCountdown_500ms--; + if (gFmRadioMode) // 1of11 + return; + } #endif - if (gBacklightCountdown_500ms > 0 && !gAskToSave && !gCssBackgroundScan - // don't turn off backlight if user is in backlight menu option - && !(gScreenToDisplay == DISPLAY_MENU && (UI_MENU_GetCurrentMenuId() == MENU_ABR || UI_MENU_GetCurrentMenuId() == MENU_ABR_MAX)) - && --gBacklightCountdown_500ms == 0 - && gEeprom.BACKLIGHT_TIME < 61 - ) { - BACKLIGHT_TurnOff(); - } + if (gBacklightCountdown_500ms > 0 && !gAskToSave && !gCssBackgroundScan + // don't turn off backlight if user is in backlight menu option + && !(gScreenToDisplay == DISPLAY_MENU && (UI_MENU_GetCurrentMenuId() == MENU_ABR || UI_MENU_GetCurrentMenuId() == MENU_ABR_MAX)) + && --gBacklightCountdown_500ms == 0 + && gEeprom.BACKLIGHT_TIME < 61 + ) { + BACKLIGHT_TurnOff(); + } - if (gReducedService) - { - BOARD_ADC_GetBatteryInfo(&gBatteryCurrentVoltage, &gBatteryCurrent); + if (gReducedService) + { + BOARD_ADC_GetBatteryInfo(&gBatteryCurrentVoltage, &gBatteryCurrent); - if (gBatteryCurrent > 500 || gBatteryCalibration[3] < gBatteryCurrentVoltage) - { - #ifdef ENABLE_OVERLAY - overlay_FLASH_RebootToBootloader(); - #else - NVIC_SystemReset(); - #endif - } + if (gBatteryCurrent > 500 || gBatteryCalibration[3] < gBatteryCurrentVoltage) + { + #ifdef ENABLE_OVERLAY + overlay_FLASH_RebootToBootloader(); + #else + NVIC_SystemReset(); + #endif + } - return; - } + return; + } - gBatteryCheckCounter++; + gBatteryCheckCounter++; - // Skipped authentic device check + // Skipped authentic device check - if (gCurrentFunction != FUNCTION_TRANSMIT) - { + if (gCurrentFunction != FUNCTION_TRANSMIT) + { - if ((gBatteryCheckCounter & 1) == 0) - { - BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryVoltageIndex++], &gBatteryCurrent); - if (gBatteryVoltageIndex > 3) - gBatteryVoltageIndex = 0; - BATTERY_GetReadings(true); - } - } + if ((gBatteryCheckCounter & 1) == 0) + { + BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryVoltageIndex++], &gBatteryCurrent); + if (gBatteryVoltageIndex > 3) + gBatteryVoltageIndex = 0; + BATTERY_GetReadings(true); + } + } - // regular display updates (once every 2 sec) - if need be - if ((gBatteryCheckCounter & 3) == 0) - { - if (gChargingWithTypeC || gSetting_battery_text > 0) - gUpdateStatus = true; - #ifdef ENABLE_SHOW_CHARGE_LEVEL - if (gChargingWithTypeC) - gUpdateDisplay = true; - #endif - } + // regular display updates (once every 2 sec) - if need be + if ((gBatteryCheckCounter & 3) == 0) + { + if (gChargingWithTypeC || gSetting_battery_text > 0) + gUpdateStatus = true; + #ifdef ENABLE_SHOW_CHARGE_LEVEL + if (gChargingWithTypeC) + gUpdateDisplay = true; + #endif + } - if (!gCssBackgroundScan && gScanStateDir == SCAN_OFF && !SCANNER_IsScanning() + if (!gCssBackgroundScan && gScanStateDir == SCAN_OFF && !SCANNER_IsScanning() #ifdef ENABLE_FMRADIO - && (gFM_ScanState == FM_SCAN_OFF || gAskToSave) + && (gFM_ScanState == FM_SCAN_OFF || gAskToSave) #endif #ifdef ENABLE_AIRCOPY - && gScreenToDisplay != DISPLAY_AIRCOPY + && gScreenToDisplay != DISPLAY_AIRCOPY #endif - ) { - if (gEeprom.AUTO_KEYPAD_LOCK && gKeyLockCountdown > 0 && !gDTMF_InputMode - && gScreenToDisplay != DISPLAY_MENU && --gKeyLockCountdown == 0) - { - gEeprom.KEY_LOCK = true; // lock the keyboard - gUpdateStatus = true; // lock symbol needs showing - } + ) { + if (gEeprom.AUTO_KEYPAD_LOCK && gKeyLockCountdown > 0 && !gDTMF_InputMode + && gScreenToDisplay != DISPLAY_MENU && --gKeyLockCountdown == 0) + { + gEeprom.KEY_LOCK = true; // lock the keyboard + gUpdateStatus = true; // lock symbol needs showing + } - if (exit_menu) { - gMenuCountdown = 0; + if (exit_menu) { + gMenuCountdown = 0; - if (gEeprom.BACKLIGHT_TIME == 0) { - BACKLIGHT_TurnOff(); - } + if (gEeprom.BACKLIGHT_TIME == 0) { + BACKLIGHT_TurnOff(); + } - if (gInputBoxIndex > 0 || gDTMF_InputMode) { - AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL); - } + if (gInputBoxIndex > 0 || gDTMF_InputMode) { + AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL); + } /* - if (SCANNER_IsScanning()) { - BK4819_StopScan(); + if (SCANNER_IsScanning()) { + BK4819_StopScan(); - RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD); - RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD); + RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD); + RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD); - RADIO_SetupRegisters(true); - } + RADIO_SetupRegisters(true); + } */ - DTMF_clear_input_box(); + DTMF_clear_input_box(); - gWasFKeyPressed = false; - gInputBoxIndex = 0; + gWasFKeyPressed = false; + gInputBoxIndex = 0; - gAskToSave = false; - gAskToDelete = false; + gAskToSave = false; + gAskToDelete = false; - gUpdateStatus = true; - gUpdateDisplay = true; + gUpdateStatus = true; + gUpdateDisplay = true; - GUI_DisplayType_t disp = DISPLAY_INVALID; + GUI_DisplayType_t disp = DISPLAY_INVALID; #ifdef ENABLE_FMRADIO - if (gFmRadioMode && ! FUNCTION_IsRx()) { - disp = DISPLAY_FM; - } + if (gFmRadioMode && ! FUNCTION_IsRx()) { + disp = DISPLAY_FM; + } #endif - if (disp == DISPLAY_INVALID + if (disp == DISPLAY_INVALID #ifdef ENABLE_NO_CODE_SCAN_TIMEOUT - && !SCANNER_IsScanning() + && !SCANNER_IsScanning() #endif - ) { - disp = DISPLAY_MAIN; - } + ) { + disp = DISPLAY_MAIN; + } - if (disp != DISPLAY_INVALID) { - GUI_SelectNextDisplay(disp); - } - } - } + if (disp != DISPLAY_INVALID) { + GUI_SelectNextDisplay(disp); + } + } + } - if (!gPttIsPressed && gVFOStateResumeCountdown_500ms > 0 && --gVFOStateResumeCountdown_500ms == 0) { - RADIO_SetVfoState(VFO_STATE_NORMAL); + if (!gPttIsPressed && gVFOStateResumeCountdown_500ms > 0 && --gVFOStateResumeCountdown_500ms == 0) { + RADIO_SetVfoState(VFO_STATE_NORMAL); #ifdef ENABLE_FMRADIO - if (gFmRadioMode && !FUNCTION_IsRx()) { - // switch back to FM radio mode - FM_Start(); - GUI_SelectNextDisplay(DISPLAY_FM); - } + if (gFmRadioMode && !FUNCTION_IsRx()) { + // switch back to FM radio mode + FM_Start(); + GUI_SelectNextDisplay(DISPLAY_FM); + } #endif - } + } - BATTERY_TimeSlice500ms(); - SCANNER_TimeSlice500ms(); - UI_MAIN_TimeSlice500ms(); + BATTERY_TimeSlice500ms(); + SCANNER_TimeSlice500ms(); + UI_MAIN_TimeSlice500ms(); #ifdef ENABLE_DTMF_CALLING - if (gCurrentFunction != FUNCTION_TRANSMIT) { - if (gDTMF_DecodeRingCountdown_500ms > 0) { - // make "ring-ring" sound - gDTMF_DecodeRingCountdown_500ms--; - AUDIO_PlayBeep(BEEP_880HZ_200MS); - } - } else { - gDTMF_DecodeRingCountdown_500ms = 0; - } + if (gCurrentFunction != FUNCTION_TRANSMIT) { + if (gDTMF_DecodeRingCountdown_500ms > 0) { + // make "ring-ring" sound + gDTMF_DecodeRingCountdown_500ms--; + AUDIO_PlayBeep(BEEP_880HZ_200MS); + } + } else { + gDTMF_DecodeRingCountdown_500ms = 0; + } - if (gDTMF_CallState != DTMF_CALL_STATE_NONE && gCurrentFunction != FUNCTION_TRANSMIT - && gCurrentFunction != FUNCTION_RECEIVE && gDTMF_auto_reset_time_500ms > 0 - && --gDTMF_auto_reset_time_500ms == 0) - { - gUpdateDisplay = true; - if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED && gEeprom.DTMF_auto_reset_time >= DTMF_HOLD_MAX) { - gDTMF_CallState = DTMF_CALL_STATE_RECEIVED_STAY; // keep message on-screen till a key is pressed - } else { - gDTMF_CallState = DTMF_CALL_STATE_NONE; - } - } + if (gDTMF_CallState != DTMF_CALL_STATE_NONE && gCurrentFunction != FUNCTION_TRANSMIT + && gCurrentFunction != FUNCTION_RECEIVE && gDTMF_auto_reset_time_500ms > 0 + && --gDTMF_auto_reset_time_500ms == 0) + { + gUpdateDisplay = true; + if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED && gEeprom.DTMF_auto_reset_time >= DTMF_HOLD_MAX) { + gDTMF_CallState = DTMF_CALL_STATE_RECEIVED_STAY; // keep message on-screen till a key is pressed + } else { + gDTMF_CallState = DTMF_CALL_STATE_NONE; + } + } - if (gDTMF_IsTx && gDTMF_TxStopCountdown_500ms > 0 && --gDTMF_TxStopCountdown_500ms == 0) { - gDTMF_IsTx = false; - gUpdateDisplay = true; - } + if (gDTMF_IsTx && gDTMF_TxStopCountdown_500ms > 0 && --gDTMF_TxStopCountdown_500ms == 0) { + gDTMF_IsTx = false; + gUpdateDisplay = true; + } #endif } #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) static void ALARM_Off(void) { - AUDIO_AudioPathOff(); - gEnableSpeaker = false; + AUDIO_AudioPathOff(); + gEnableSpeaker = false; - if (gAlarmState == ALARM_STATE_TXALARM || gAlarmState == ALARM_STATE_TX1750) { - RADIO_SendEndOfTransmission(); - } + if (gAlarmState == ALARM_STATE_TXALARM || gAlarmState == ALARM_STATE_TX1750) { + RADIO_SendEndOfTransmission(); + } - gAlarmState = ALARM_STATE_OFF; + gAlarmState = ALARM_STATE_OFF; #ifdef ENABLE_VOX - gVoxResumeCountdown = 80; + gVoxResumeCountdown = 80; #endif - SYSTEM_DelayMs(5); + SYSTEM_DelayMs(5); - RADIO_SetupRegisters(true); + RADIO_SetupRegisters(true); - if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu - gRequestDisplayScreen = DISPLAY_MAIN; + if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu + gRequestDisplayScreen = DISPLAY_MAIN; } #endif static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { - if (Key == KEY_EXIT && !BACKLIGHT_IsOn() && gEeprom.BACKLIGHT_TIME > 0) - { // just turn the light on for now so the user can see what's what - BACKLIGHT_TurnOn(); - gBeepToPlay = BEEP_NONE; - return; - } + if (Key == KEY_EXIT && !BACKLIGHT_IsOn() && gEeprom.BACKLIGHT_TIME > 0) + { // just turn the light on for now so the user can see what's what + BACKLIGHT_TurnOn(); + gBeepToPlay = BEEP_NONE; + return; + } - if (gCurrentFunction == FUNCTION_POWER_SAVE) - FUNCTION_Select(FUNCTION_FOREGROUND); + if (gCurrentFunction == FUNCTION_POWER_SAVE) + FUNCTION_Select(FUNCTION_FOREGROUND); - gBatterySaveCountdown_10ms = battery_save_count_10ms; + gBatterySaveCountdown_10ms = battery_save_count_10ms; - if (gEeprom.AUTO_KEYPAD_LOCK) - gKeyLockCountdown = 30; // 15 seconds + if (gEeprom.AUTO_KEYPAD_LOCK) + gKeyLockCountdown = 30; // 15 seconds - if (!bKeyPressed) { // key released - if (flagSaveVfo) { - SETTINGS_SaveVfoIndices(); - flagSaveVfo = false; - } + if (!bKeyPressed) { // key released + if (flagSaveVfo) { + SETTINGS_SaveVfoIndices(); + flagSaveVfo = false; + } - if (flagSaveSettings) { - SETTINGS_SaveSettings(); - flagSaveSettings = false; - } + if (flagSaveSettings) { + SETTINGS_SaveSettings(); + flagSaveSettings = false; + } #ifdef ENABLE_FMRADIO - if (gFlagSaveFM) { - SETTINGS_SaveFM(); - gFlagSaveFM = false; - } + if (gFlagSaveFM) { + SETTINGS_SaveFM(); + gFlagSaveFM = false; + } #endif - if (flagSaveChannel) { - SETTINGS_SaveChannel(gTxVfo->CHANNEL_SAVE, gEeprom.TX_VFO, gTxVfo, flagSaveChannel); - flagSaveChannel = false; + if (flagSaveChannel) { + SETTINGS_SaveChannel(gTxVfo->CHANNEL_SAVE, gEeprom.TX_VFO, gTxVfo, flagSaveChannel); + flagSaveChannel = false; - if (!SCANNER_IsScanning() && gVfoConfigureMode == VFO_CONFIGURE_NONE) - // gVfoConfigureMode is so as we don't wipe out previously setting this variable elsewhere - gVfoConfigureMode = VFO_CONFIGURE; - } - } - else { // key pressed or held - const int m = UI_MENU_GetCurrentMenuId(); - if ( //not when PTT and the backlight shouldn't turn on on TX - !(Key == KEY_PTT && !(gSetting_backlight_on_tx_rx & BACKLIGHT_ON_TR_TX)) - // not in the backlight menu - && !(gScreenToDisplay == DISPLAY_MENU && ( m == MENU_ABR || m == MENU_ABR_MAX || m == MENU_ABR_MIN)) - ) - { - BACKLIGHT_TurnOn(); - } + if (!SCANNER_IsScanning() && gVfoConfigureMode == VFO_CONFIGURE_NONE) + // gVfoConfigureMode is so as we don't wipe out previously setting this variable elsewhere + gVfoConfigureMode = VFO_CONFIGURE; + } + } + else { // key pressed or held + const int m = UI_MENU_GetCurrentMenuId(); + if ( //not when PTT and the backlight shouldn't turn on on TX + !(Key == KEY_PTT && !(gSetting_backlight_on_tx_rx & BACKLIGHT_ON_TR_TX)) + // not in the backlight menu + && !(gScreenToDisplay == DISPLAY_MENU && ( m == MENU_ABR || m == MENU_ABR_MAX || m == MENU_ABR_MIN)) + ) + { + BACKLIGHT_TurnOn(); + } - if (Key == KEY_EXIT && bKeyHeld) { // exit key held pressed - // clear the live DTMF decoder - if (gDTMF_RX_live[0] != 0) { - memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); - gDTMF_RX_live_timeout = 0; - gUpdateDisplay = true; - } + if (Key == KEY_EXIT && bKeyHeld) { // exit key held pressed + // clear the live DTMF decoder + if (gDTMF_RX_live[0] != 0) { + memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); + gDTMF_RX_live_timeout = 0; + gUpdateDisplay = true; + } - // cancel user input - cancelUserInputModes(); + // cancel user input + cancelUserInputModes(); - if (gMonitor) - ACTION_Monitor(); //turn off the monitor + if (gMonitor) + ACTION_Monitor(); //turn off the monitor #ifdef ENABLE_SCAN_RANGES - gScanRangeStart = 0; + gScanRangeStart = 0; #endif - } + } - if (gScreenToDisplay == DISPLAY_MENU) // 1of11 - gMenuCountdown = menu_timeout_500ms; + if (gScreenToDisplay == DISPLAY_MENU) // 1of11 + gMenuCountdown = menu_timeout_500ms; #ifdef ENABLE_DTMF_CALLING - if (gDTMF_DecodeRingCountdown_500ms > 0) { // cancel the ringing - gDTMF_DecodeRingCountdown_500ms = 0; + if (gDTMF_DecodeRingCountdown_500ms > 0) { // cancel the ringing + gDTMF_DecodeRingCountdown_500ms = 0; - AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL); + AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL); - if (Key != KEY_PTT) { - gPttWasReleased = true; - return; - } - } + if (Key != KEY_PTT) { + gPttWasReleased = true; + return; + } + } #endif - } + } - bool lowBatPopup = gLowBattery && !gLowBatteryConfirmed && gScreenToDisplay == DISPLAY_MAIN; + bool lowBatPopup = gLowBattery && !gLowBatteryConfirmed && gScreenToDisplay == DISPLAY_MAIN; #ifdef ENABLE_FEAT_F4HWN // Disable PTT if KEY_LOCK - bool lck_condition = false; + bool lck_condition = false; - if(gSetting_set_lck) - lck_condition = (gEeprom.KEY_LOCK || lowBatPopup) && gCurrentFunction != FUNCTION_TRANSMIT; - else - lck_condition = (gEeprom.KEY_LOCK || lowBatPopup) && gCurrentFunction != FUNCTION_TRANSMIT && Key != KEY_PTT; + if(gSetting_set_lck) + lck_condition = (gEeprom.KEY_LOCK || lowBatPopup) && gCurrentFunction != FUNCTION_TRANSMIT; + else + lck_condition = (gEeprom.KEY_LOCK || lowBatPopup) && gCurrentFunction != FUNCTION_TRANSMIT && Key != KEY_PTT; - if (lck_condition) + if (lck_condition) #else - if ((gEeprom.KEY_LOCK || lowBatPopup) && gCurrentFunction != FUNCTION_TRANSMIT && Key != KEY_PTT) + if ((gEeprom.KEY_LOCK || lowBatPopup) && gCurrentFunction != FUNCTION_TRANSMIT && Key != KEY_PTT) #endif - { // keyboard is locked or low battery popup + { // keyboard is locked or low battery popup - // close low battery popup - if(Key == KEY_EXIT && bKeyPressed && lowBatPopup) { - gLowBatteryConfirmed = true; - gUpdateDisplay = true; - AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL); - return; - } + // close low battery popup + if(Key == KEY_EXIT && bKeyPressed && lowBatPopup) { + gLowBatteryConfirmed = true; + gUpdateDisplay = true; + AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL); + return; + } - if (Key == KEY_F) { // function/key-lock key - if (!bKeyPressed) - return; + if (Key == KEY_F) { // function/key-lock key + if (!bKeyPressed) + return; - if (!bKeyHeld) { // keypad is locked, tell the user - AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL); - gKeypadLocked = 4; // 2 seconds - gUpdateDisplay = true; - return; - } - } - // KEY_MENU has a special treatment here, because we want to pass hold event to ACTION_Handle - // but we don't want it to complain when initial press happens - // we want to react on realese instead - else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && // pass side buttons - !(Key == KEY_MENU && bKeyHeld)) // pass KEY_MENU held - { - if ((!bKeyPressed || bKeyHeld || (Key == KEY_MENU && bKeyPressed)) && // prevent released or held, prevent KEY_MENU pressed - !(Key == KEY_MENU && !bKeyPressed)) // pass KEY_MENU released - return; + if (!bKeyHeld) { // keypad is locked, tell the user + AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL); + gKeypadLocked = 4; // 2 seconds + gUpdateDisplay = true; + return; + } + } + // KEY_MENU has a special treatment here, because we want to pass hold event to ACTION_Handle + // but we don't want it to complain when initial press happens + // we want to react on realese instead + else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && // pass side buttons + !(Key == KEY_MENU && bKeyHeld)) // pass KEY_MENU held + { + if ((!bKeyPressed || bKeyHeld || (Key == KEY_MENU && bKeyPressed)) && // prevent released or held, prevent KEY_MENU pressed + !(Key == KEY_MENU && !bKeyPressed)) // pass KEY_MENU released + return; - // keypad is locked, tell the user - AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL); - gKeypadLocked = 4; // 2 seconds - gUpdateDisplay = true; - return; - } - } + // keypad is locked, tell the user + AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL); + gKeypadLocked = 4; // 2 seconds + gUpdateDisplay = true; + return; + } + } - if (Key <= KEY_9 || Key == KEY_F) { - //if (gScanStateDir != SCAN_OFF || gCssBackgroundScan) { // FREQ/CTCSS/DCS scanning - if (gCssBackgroundScan) { // FREQ/CTCSS/DCS scanning - if (bKeyPressed && !bKeyHeld) - AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL); - return; - } - } + if (Key <= KEY_9 || Key == KEY_F) { + //if (gScanStateDir != SCAN_OFF || gCssBackgroundScan) { // FREQ/CTCSS/DCS scanning + if (gCssBackgroundScan) { // FREQ/CTCSS/DCS scanning + if (bKeyPressed && !bKeyHeld) + AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL); + return; + } + } - bool bFlag = false; - if (Key == KEY_PTT) { - if (gPttWasPressed) { - bFlag = bKeyHeld; - if (!bKeyPressed) { - bFlag = true; - gPttWasPressed = false; - } - } - } - else if (gPttWasReleased) { - if (bKeyHeld) - bFlag = true; - if (!bKeyPressed) { - bFlag = true; - gPttWasReleased = false; - } - } + bool bFlag = false; + if (Key == KEY_PTT) { + if (gPttWasPressed) { + bFlag = bKeyHeld; + if (!bKeyPressed) { + bFlag = true; + gPttWasPressed = false; + } + } + } + else if (gPttWasReleased) { + if (bKeyHeld) + bFlag = true; + if (!bKeyPressed) { + bFlag = true; + gPttWasReleased = false; + } + } #ifdef ENABLE_FEAT_F4HWN // For F + SIDE1 or F + SIDE2 - if (gWasFKeyPressed && (Key == KEY_PTT || Key == KEY_EXIT)) { + if (gWasFKeyPressed && (Key == KEY_PTT || Key == KEY_EXIT)) { #else - if (gWasFKeyPressed && (Key == KEY_PTT || Key == KEY_EXIT || Key == KEY_SIDE1 || Key == KEY_SIDE2)) { + if (gWasFKeyPressed && (Key == KEY_PTT || Key == KEY_EXIT || Key == KEY_SIDE1 || Key == KEY_SIDE2)) { #endif - // cancel the F-key - gWasFKeyPressed = false; - gUpdateStatus = true; - } + // cancel the F-key + gWasFKeyPressed = false; + gUpdateStatus = true; + } - if (bFlag) { - goto Skip; - } + if (bFlag) { + goto Skip; + } - if (gCurrentFunction == FUNCTION_TRANSMIT) { + if (gCurrentFunction == FUNCTION_TRANSMIT) { #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) - if (gAlarmState == ALARM_STATE_OFF) + if (gAlarmState == ALARM_STATE_OFF) #endif - { - char Code; + { + char Code; - if (Key == KEY_PTT) { - GENERIC_Key_PTT(bKeyPressed); - goto Skip; - } + if (Key == KEY_PTT) { + GENERIC_Key_PTT(bKeyPressed); + goto Skip; + } - if (Key == KEY_SIDE2) { // transmit 1750Hz tone - Code = 0xFE; - } - else { - Code = DTMF_GetCharacter(Key - KEY_0); - if (Code == 0xFF) - goto Skip; - // transmit DTMF keys - } + if (Key == KEY_SIDE2) { // transmit 1750Hz tone + Code = 0xFE; + } + else { + Code = DTMF_GetCharacter(Key - KEY_0); + if (Code == 0xFF) + goto Skip; + // transmit DTMF keys + } - if (!bKeyPressed || bKeyHeld) { - if (!bKeyPressed) { - AUDIO_AudioPathOff(); + if (!bKeyPressed || bKeyHeld) { + if (!bKeyPressed) { + AUDIO_AudioPathOff(); - gEnableSpeaker = false; + gEnableSpeaker = false; - BK4819_ExitDTMF_TX(false); + BK4819_ExitDTMF_TX(false); #ifndef ENABLE_FEAT_F4HWN - if (gCurrentVfo->SCRAMBLING_TYPE == 0 || !gSetting_ScrambleEnable) - BK4819_DisableScramble(); - else - BK4819_EnableScramble(gCurrentVfo->SCRAMBLING_TYPE - 1); + if (gCurrentVfo->SCRAMBLING_TYPE == 0 || !gSetting_ScrambleEnable) + BK4819_DisableScramble(); + else + BK4819_EnableScramble(gCurrentVfo->SCRAMBLING_TYPE - 1); #else - BK4819_DisableScramble(); + BK4819_DisableScramble(); #endif - } - } - else { - if (gEeprom.DTMF_SIDE_TONE) { // user will here the DTMF tones in speaker - AUDIO_AudioPathOn(); - gEnableSpeaker = true; - } + } + } + else { + if (gEeprom.DTMF_SIDE_TONE) { // user will here the DTMF tones in speaker + AUDIO_AudioPathOn(); + gEnableSpeaker = true; + } - BK4819_DisableScramble(); + BK4819_DisableScramble(); - if (Code == 0xFE) - BK4819_TransmitTone(gEeprom.DTMF_SIDE_TONE, 1750); - else - BK4819_PlayDTMFEx(gEeprom.DTMF_SIDE_TONE, Code); - } - } + if (Code == 0xFE) + BK4819_TransmitTone(gEeprom.DTMF_SIDE_TONE, 1750); + else + BK4819_PlayDTMFEx(gEeprom.DTMF_SIDE_TONE, Code); + } + } #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) - else if ((!bKeyHeld && bKeyPressed) || (gAlarmState == ALARM_STATE_TX1750 && bKeyHeld && !bKeyPressed)) { - ALARM_Off(); + else if ((!bKeyHeld && bKeyPressed) || (gAlarmState == ALARM_STATE_TX1750 && bKeyHeld && !bKeyPressed)) { + ALARM_Off(); - if (gEeprom.REPEATER_TAIL_TONE_ELIMINATION == 0) - FUNCTION_Select(FUNCTION_FOREGROUND); - else - gRTTECountdown_10ms = gEeprom.REPEATER_TAIL_TONE_ELIMINATION * 10; + if (gEeprom.REPEATER_TAIL_TONE_ELIMINATION == 0) + FUNCTION_Select(FUNCTION_FOREGROUND); + else + gRTTECountdown_10ms = gEeprom.REPEATER_TAIL_TONE_ELIMINATION * 10; - if (Key == KEY_PTT) - gPttWasPressed = true; - else if (!bKeyHeld) - gPttWasReleased = true; - } + if (Key == KEY_PTT) + gPttWasPressed = true; + else if (!bKeyHeld) + gPttWasReleased = true; + } #endif - } + } #ifdef ENABLE_FEAT_F4HWN // For F + SIDE1 or F + SIDE2 - else if (gWasFKeyPressed && (Key == KEY_SIDE1 || Key == KEY_SIDE2)) { - ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld); - } - else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && gScreenToDisplay != DISPLAY_INVALID) { - ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld); - } + else if (gWasFKeyPressed && (Key == KEY_SIDE1 || Key == KEY_SIDE2)) { + ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld); + } + else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && gScreenToDisplay != DISPLAY_INVALID) { + ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld); + } #else - else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && gScreenToDisplay != DISPLAY_INVALID) { - ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld); - } + else if (Key != KEY_SIDE1 && Key != KEY_SIDE2 && gScreenToDisplay != DISPLAY_INVALID) { + ProcessKeysFunctions[gScreenToDisplay](Key, bKeyPressed, bKeyHeld); + } #endif - else if (!SCANNER_IsScanning() + else if (!SCANNER_IsScanning() #ifdef ENABLE_AIRCOPY - && gScreenToDisplay != DISPLAY_AIRCOPY + && gScreenToDisplay != DISPLAY_AIRCOPY #endif - ) { - ACTION_Handle(Key, bKeyPressed, bKeyHeld); - } - else if (!bKeyHeld && bKeyPressed) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - } + ) { + ACTION_Handle(Key, bKeyPressed, bKeyHeld); + } + else if (!bKeyHeld && bKeyPressed) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + } Skip: - if (gBeepToPlay != BEEP_NONE) { - AUDIO_PlayBeep(gBeepToPlay); - gBeepToPlay = BEEP_NONE; - } + if (gBeepToPlay != BEEP_NONE) { + AUDIO_PlayBeep(gBeepToPlay); + gBeepToPlay = BEEP_NONE; + } - if (gFlagAcceptSetting) { - gMenuCountdown = menu_timeout_500ms; + if (gFlagAcceptSetting) { + gMenuCountdown = menu_timeout_500ms; - MENU_AcceptSetting(); + MENU_AcceptSetting(); - gFlagRefreshSetting = true; - gFlagAcceptSetting = false; - } + gFlagRefreshSetting = true; + gFlagAcceptSetting = false; + } - if (gRequestSaveSettings) { - if (!bKeyHeld) - SETTINGS_SaveSettings(); - else - flagSaveSettings = 1; - gRequestSaveSettings = false; - gUpdateStatus = true; - } + if (gRequestSaveSettings) { + if (!bKeyHeld) + SETTINGS_SaveSettings(); + else + flagSaveSettings = 1; + gRequestSaveSettings = false; + gUpdateStatus = true; + } #ifdef ENABLE_FMRADIO - if (gRequestSaveFM) { - gRequestSaveFM = false; - if (!bKeyHeld) - SETTINGS_SaveFM(); - else - gFlagSaveFM = true; - } + if (gRequestSaveFM) { + gRequestSaveFM = false; + if (!bKeyHeld) + SETTINGS_SaveFM(); + else + gFlagSaveFM = true; + } #endif - if (gRequestSaveVFO) { - gRequestSaveVFO = false; - if (!bKeyHeld) - SETTINGS_SaveVfoIndices(); - else - flagSaveVfo = true; - } + if (gRequestSaveVFO) { + gRequestSaveVFO = false; + if (!bKeyHeld) + SETTINGS_SaveVfoIndices(); + else + flagSaveVfo = true; + } - if (gRequestSaveChannel > 0) { // TODO: remove the gRequestSaveChannel, why use global variable for that?? - if ((!bKeyHeld && !bKeyPressed) || UI_MENU_GetCurrentMenuId()) - { - SETTINGS_SaveChannel(gTxVfo->CHANNEL_SAVE, gEeprom.TX_VFO, gTxVfo, gRequestSaveChannel); + if (gRequestSaveChannel > 0) { // TODO: remove the gRequestSaveChannel, why use global variable for that?? + if ((!bKeyHeld && !bKeyPressed) || UI_MENU_GetCurrentMenuId()) + { + SETTINGS_SaveChannel(gTxVfo->CHANNEL_SAVE, gEeprom.TX_VFO, gTxVfo, gRequestSaveChannel); - if (!SCANNER_IsScanning() && gVfoConfigureMode == VFO_CONFIGURE_NONE) - // gVfoConfigureMode is so as we don't wipe out previously setting this variable elsewhere - gVfoConfigureMode = VFO_CONFIGURE; - } - else { // this is probably so settings are not saved when up/down button is held and save is postponed to btn release - flagSaveChannel = gRequestSaveChannel; + if (!SCANNER_IsScanning() && gVfoConfigureMode == VFO_CONFIGURE_NONE) + // gVfoConfigureMode is so as we don't wipe out previously setting this variable elsewhere + gVfoConfigureMode = VFO_CONFIGURE; + } + else { // this is probably so settings are not saved when up/down button is held and save is postponed to btn release + flagSaveChannel = gRequestSaveChannel; - if (gRequestDisplayScreen == DISPLAY_INVALID) - gRequestDisplayScreen = DISPLAY_MAIN; - } + if (gRequestDisplayScreen == DISPLAY_INVALID) + gRequestDisplayScreen = DISPLAY_MAIN; + } - gRequestSaveChannel = 0; - } + gRequestSaveChannel = 0; + } - if (gVfoConfigureMode != VFO_CONFIGURE_NONE) { - if (gFlagResetVfos) { - RADIO_ConfigureChannel(0, gVfoConfigureMode); - RADIO_ConfigureChannel(1, gVfoConfigureMode); - } - else - RADIO_ConfigureChannel(gEeprom.TX_VFO, gVfoConfigureMode); + if (gVfoConfigureMode != VFO_CONFIGURE_NONE) { + if (gFlagResetVfos) { + RADIO_ConfigureChannel(0, gVfoConfigureMode); + RADIO_ConfigureChannel(1, gVfoConfigureMode); + } + else + RADIO_ConfigureChannel(gEeprom.TX_VFO, gVfoConfigureMode); - if (gRequestDisplayScreen == DISPLAY_INVALID) - gRequestDisplayScreen = DISPLAY_MAIN; + if (gRequestDisplayScreen == DISPLAY_INVALID) + gRequestDisplayScreen = DISPLAY_MAIN; - gFlagReconfigureVfos = true; - gVfoConfigureMode = VFO_CONFIGURE_NONE; - gFlagResetVfos = false; - } + gFlagReconfigureVfos = true; + gVfoConfigureMode = VFO_CONFIGURE_NONE; + gFlagResetVfos = false; + } - if (gFlagReconfigureVfos) { - RADIO_SelectVfos(); + if (gFlagReconfigureVfos) { + RADIO_SelectVfos(); #ifdef ENABLE_NOAA - RADIO_ConfigureNOAA(); + RADIO_ConfigureNOAA(); #endif - RADIO_SetupRegisters(true); + RADIO_SetupRegisters(true); #ifdef ENABLE_DTMF_CALLING - gDTMF_auto_reset_time_500ms = 0; - gDTMF_CallState = DTMF_CALL_STATE_NONE; - gDTMF_TxStopCountdown_500ms = 0; - gDTMF_IsTx = false; + gDTMF_auto_reset_time_500ms = 0; + gDTMF_CallState = DTMF_CALL_STATE_NONE; + gDTMF_TxStopCountdown_500ms = 0; + gDTMF_IsTx = false; #endif - gVFO_RSSI_bar_level[0] = 0; - gVFO_RSSI_bar_level[1] = 0; + gVFO_RSSI_bar_level[0] = 0; + gVFO_RSSI_bar_level[1] = 0; - gFlagReconfigureVfos = false; + gFlagReconfigureVfos = false; - if (gMonitor) - ACTION_Monitor(); // 1of11 - } + if (gMonitor) + ACTION_Monitor(); // 1of11 + } - if (gFlagRefreshSetting) { - gFlagRefreshSetting = false; - gMenuCountdown = menu_timeout_500ms; + if (gFlagRefreshSetting) { + gFlagRefreshSetting = false; + gMenuCountdown = menu_timeout_500ms; - MENU_ShowCurrentSetting(); - } + MENU_ShowCurrentSetting(); + } - if (gFlagPrepareTX) { - RADIO_PrepareTX(); - gFlagPrepareTX = false; - } + if (gFlagPrepareTX) { + RADIO_PrepareTX(); + gFlagPrepareTX = false; + } #ifdef ENABLE_VOICE - if (gAnotherVoiceID != VOICE_ID_INVALID) { - if (gAnotherVoiceID < 76) - AUDIO_SetVoiceID(0, gAnotherVoiceID); - AUDIO_PlaySingleVoice(false); - gAnotherVoiceID = VOICE_ID_INVALID; - } + if (gAnotherVoiceID != VOICE_ID_INVALID) { + if (gAnotherVoiceID < 76) + AUDIO_SetVoiceID(0, gAnotherVoiceID); + AUDIO_PlaySingleVoice(false); + gAnotherVoiceID = VOICE_ID_INVALID; + } #endif - GUI_SelectNextDisplay(gRequestDisplayScreen); - gRequestDisplayScreen = DISPLAY_INVALID; + GUI_SelectNextDisplay(gRequestDisplayScreen); + gRequestDisplayScreen = DISPLAY_INVALID; - gUpdateDisplay = true; + gUpdateDisplay = true; } diff --git a/app/chFrScanner.c b/app/chFrScanner.c index 5b5ae7e..bc00c1f 100644 --- a/app/chFrScanner.c +++ b/app/chFrScanner.c @@ -16,22 +16,22 @@ uint32_t gScanRangeStop; #endif 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_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; +scan_next_chan_t currentScanList; uint32_t initialFrqOrChan; -uint8_t initialCROSS_BAND_RX_TX; +uint8_t initialCROSS_BAND_RX_TX; #ifndef ENABLE_FEAT_F4HWN - uint32_t lastFoundFrqOrChan; + uint32_t lastFoundFrqOrChan; #else - uint32_t lastFoundFrqOrChan; - uint32_t lastFoundFrqOrChanOld; + uint32_t lastFoundFrqOrChan; + uint32_t lastFoundFrqOrChanOld; #endif static void NextFreqChannel(void); @@ -39,276 +39,276 @@ 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(); + 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; + 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(); - } + 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(); + } #ifdef ENABLE_FEAT_F4HWN - lastFoundFrqOrChanOld = lastFoundFrqOrChan; + lastFoundFrqOrChanOld = lastFoundFrqOrChan; #endif - gScanPauseDelayIn_10ms = scan_pause_delay_in_2_10ms; - gScheduleScanListen = false; - gRxReceptionMode = RX_MODE_NONE; - gScanPauseMode = false; + 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); - else - NextFreqChannel(); // switch to next frequency - } - else - { - if (gCurrentCodeType == CODE_TYPE_OFF && gCurrentFunction == FUNCTION_INCOMING) - APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE); - else - NextMemChannel(); // switch to next channel - } - - gScanPauseMode = false; - gRxReceptionMode = RX_MODE_NONE; - gScheduleScanListen = false; + if (IS_FREQ_CHANNEL(gNextMrChannel)) + { + if (gCurrentFunction == FUNCTION_INCOMING) + APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE); + else + NextFreqChannel(); // switch to next frequency + } + else + { + if (gCurrentCodeType == CODE_TYPE_OFF && gCurrentFunction == FUNCTION_INCOMING) + APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE); + 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; + 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; - } + case SCAN_RESUME_CO: + case SCAN_RESUME_SE: + gScanPauseDelayIn_10ms = 0; + gScheduleScanListen = false; + break; + } #ifdef ENABLE_FEAT_F4HWN - lastFoundFrqOrChanOld = lastFoundFrqOrChan; + lastFoundFrqOrChanOld = lastFoundFrqOrChan; #endif - if (IS_MR_CHANNEL(gRxVfo->CHANNEL_SAVE)) { //memory scan - lastFoundFrqOrChan = gRxVfo->CHANNEL_SAVE; - } - else { // frequency scan - lastFoundFrqOrChan = gRxVfo->freq_config_RX.Frequency; - } + if (IS_MR_CHANNEL(gRxVfo->CHANNEL_SAVE)) { //memory scan + lastFoundFrqOrChan = gRxVfo->CHANNEL_SAVE; + } + else { // frequency scan + lastFoundFrqOrChan = gRxVfo->freq_config_RX.Frequency; + } - gScanKeepResult = true; + 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; + 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); + 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); - } - } + 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; + RADIO_SetupRegisters(true); + gUpdateDisplay = true; } static void NextFreqChannel(void) { #ifdef ENABLE_SCAN_RANGES - if(gScanRangeStart) { - gRxVfo->freq_config_RX.Frequency = APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, gScanRangeStart, gScanRangeStop); - } - else + if(gScanRangeStart) { + gRxVfo->freq_config_RX.Frequency = APP_SetFreqByStepAndLimits(gRxVfo, gScanStateDir, gScanRangeStart, gScanRangeStop); + } + else #endif - gRxVfo->freq_config_RX.Frequency = APP_SetFrequencyByStep(gRxVfo, gScanStateDir); + gRxVfo->freq_config_RX.Frequency = APP_SetFrequencyByStep(gRxVfo, gScanStateDir); - RADIO_ApplyOffset(gRxVfo); - RADIO_ConfigureSquelchAndOutputPower(gRxVfo); - RADIO_SetupRegisters(true); + RADIO_ApplyOffset(gRxVfo); + RADIO_ConfigureSquelchAndOutputPower(gRxVfo); + RADIO_SetupRegisters(true); #ifdef ENABLE_FASTER_CHANNEL_SCAN - gScanPauseDelayIn_10ms = 9; // 90ms + gScanPauseDelayIn_10ms = 9; // 90ms #else - gScanPauseDelayIn_10ms = scan_pause_delay_in_6_10ms; + gScanPauseDelayIn_10ms = scan_pause_delay_in_6_10ms; #endif - gUpdateDisplay = true; + gUpdateDisplay = true; } static void NextMemChannel(void) { - static unsigned int prev_mr_chan = 0; - const bool enabled = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT < 4) ? gEeprom.SCAN_LIST_ENABLED[gEeprom.SCAN_LIST_DEFAULT - 1] : true; - const int chan1 = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT < 4) ? gEeprom.SCANLIST_PRIORITY_CH1[gEeprom.SCAN_LIST_DEFAULT - 1] : -1; - const int chan2 = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT < 4) ? gEeprom.SCANLIST_PRIORITY_CH2[gEeprom.SCAN_LIST_DEFAULT - 1] : -1; - const unsigned int prev_chan = gNextMrChannel; - unsigned int chan = 0; + static unsigned int prev_mr_chan = 0; + const bool enabled = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT < 4) ? gEeprom.SCAN_LIST_ENABLED[gEeprom.SCAN_LIST_DEFAULT - 1] : true; + const int chan1 = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT < 4) ? gEeprom.SCANLIST_PRIORITY_CH1[gEeprom.SCAN_LIST_DEFAULT - 1] : -1; + const int chan2 = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT < 4) ? gEeprom.SCANLIST_PRIORITY_CH2[gEeprom.SCAN_LIST_DEFAULT - 1] : -1; + const unsigned int prev_chan = gNextMrChannel; + unsigned int chan = 0; - //char str[64] = ""; + //char str[64] = ""; - if (enabled) - { - switch (currentScanList) - { - case SCAN_NEXT_CHAN_SCANLIST1: - prev_mr_chan = gNextMrChannel; - - //sprintf(str, "-> Chan1 %d\n", chan1 + 1); - //LogUart(str); + if (enabled) + { + switch (currentScanList) + { + case SCAN_NEXT_CHAN_SCANLIST1: + prev_mr_chan = gNextMrChannel; + + //sprintf(str, "-> Chan1 %d\n", chan1 + 1); + //LogUart(str); - if (chan1 >= 0) - { - if (RADIO_CheckValidChannel(chan1, false, gEeprom.SCAN_LIST_DEFAULT)) - { - currentScanList = SCAN_NEXT_CHAN_SCANLIST1; - gNextMrChannel = chan1; - break; - } - } + if (chan1 >= 0) + { + if (RADIO_CheckValidChannel(chan1, false, gEeprom.SCAN_LIST_DEFAULT)) + { + currentScanList = SCAN_NEXT_CHAN_SCANLIST1; + gNextMrChannel = chan1; + break; + } + } - [[fallthrough]]; - case SCAN_NEXT_CHAN_SCANLIST2: + [[fallthrough]]; + case SCAN_NEXT_CHAN_SCANLIST2: - //sprintf(str, "-> Chan2 %d\n", chan2 + 1); - //LogUart(str); + //sprintf(str, "-> Chan2 %d\n", chan2 + 1); + //LogUart(str); - if (chan2 >= 0) - { - if (RADIO_CheckValidChannel(chan2, false, gEeprom.SCAN_LIST_DEFAULT)) - { - currentScanList = SCAN_NEXT_CHAN_SCANLIST2; - gNextMrChannel = chan2; - break; - } - } + if (chan2 >= 0) + { + if (RADIO_CheckValidChannel(chan2, false, gEeprom.SCAN_LIST_DEFAULT)) + { + currentScanList = SCAN_NEXT_CHAN_SCANLIST2; + gNextMrChannel = chan2; + break; + } + } - [[fallthrough]]; - /* - case SCAN_NEXT_CHAN_SCANLIST3: - if (chan3 >= 0) - { - if (RADIO_CheckValidChannel(chan3, false, 0)) - { - currentScanList = SCAN_NEXT_CHAN_SCANLIST3; - gNextMrChannel = chan3; - 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; -// } -// } + [[fallthrough]]; + /* + case SCAN_NEXT_CHAN_SCANLIST3: + if (chan3 >= 0) + { + if (RADIO_CheckValidChannel(chan3, false, 0)) + { + currentScanList = SCAN_NEXT_CHAN_SCANLIST3; + gNextMrChannel = chan3; + 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; - } - } + 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, true, gEeprom.SCAN_LIST_DEFAULT); - if (chan == 0xFF) - { // no valid channel found - chan = MR_CHANNEL_FIRST; - } - - gNextMrChannel = chan; + if (!enabled || chan == 0xff) + { + chan = RADIO_FindNextChannel(gNextMrChannel + gScanStateDir, gScanStateDir, true, gEeprom.SCAN_LIST_DEFAULT); + if (chan == 0xFF) + { // no valid channel found + chan = MR_CHANNEL_FIRST; + } + + gNextMrChannel = chan; - //sprintf(str, "----> Chan %d\n", chan + 1); - //LogUart(str); - } + //sprintf(str, "----> Chan %d\n", chan + 1); + //LogUart(str); + } - if (gNextMrChannel != prev_chan) - { - gEeprom.MrChannel[ gEeprom.RX_VFO] = gNextMrChannel; - gEeprom.ScreenChannel[gEeprom.RX_VFO] = gNextMrChannel; + 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); + 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) ? + gScanPauseDelayIn_10ms = 9; // 90ms .. <= ~60ms it misses signals (squelch response and/or PLL lock time) ? #else - gScanPauseDelayIn_10ms = scan_pause_delay_in_3_10ms; + 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 + if (enabled) + if (++currentScanList >= SCAN_NEXT_NUM) + currentScanList = SCAN_NEXT_CHAN_SCANLIST1; // back round we go } diff --git a/app/chFrScanner.h b/app/chFrScanner.h index 484b726..1b42562 100644 --- a/app/chFrScanner.h +++ b/app/chFrScanner.h @@ -21,8 +21,8 @@ void CHFRSCANNER_Start(const bool storeBackupSettings, const int8_t scan_directi void CHFRSCANNER_ContinueScanning(void); #ifdef ENABLE_FEAT_F4HWN - extern uint32_t lastFoundFrqOrChan; - extern uint32_t lastFoundFrqOrChanOld; + extern uint32_t lastFoundFrqOrChan; + extern uint32_t lastFoundFrqOrChanOld; #endif #endif \ No newline at end of file diff --git a/app/common.c b/app/common.c index 4265dfa..8bc2168 100644 --- a/app/common.c +++ b/app/common.c @@ -10,7 +10,7 @@ void COMMON_KeypadLockToggle() if (gScreenToDisplay != DISPLAY_MENU && gCurrentFunction != FUNCTION_TRANSMIT) - { // toggle the keyboad lock + { // toggle the keyboad lock #ifdef ENABLE_VOICE gAnotherVoiceID = gEeprom.KEY_LOCK ? VOICE_ID_UNLOCK : VOICE_ID_LOCK; @@ -50,7 +50,7 @@ void COMMON_SwitchVFOMode() #endif { if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) - { // swap to frequency mode + { // swap to frequency mode gEeprom.ScreenChannel[gEeprom.TX_VFO] = gEeprom.FreqChannel[gEeprom.TX_VFO]; #ifdef ENABLE_VOICE gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE; @@ -62,7 +62,7 @@ void COMMON_SwitchVFOMode() uint8_t Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 0); if (Channel != 0xFF) - { // swap to channel mode + { // swap to channel mode gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel; #ifdef ENABLE_VOICE AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE); diff --git a/app/dtmf.c b/app/dtmf.c index 7376b96..91b5868 100644 --- a/app/dtmf.c +++ b/app/dtmf.c @@ -19,7 +19,7 @@ #include "app/chFrScanner.h" #ifdef ENABLE_FMRADIO - #include "app/fm.h" + #include "app/fm.h" #endif #include "app/scanner.h" #include "bsp/dp32g030/gpio.h" @@ -71,429 +71,429 @@ DTMF_ReplyState_t gDTMF_ReplyState; #ifdef ENABLE_DTMF_CALLING void DTMF_clear_RX(void) { - gDTMF_RX_timeout = 0; - gDTMF_RX_index = 0; - gDTMF_RX_pending = false; - memset(gDTMF_RX, 0, sizeof(gDTMF_RX)); + gDTMF_RX_timeout = 0; + gDTMF_RX_index = 0; + gDTMF_RX_pending = false; + memset(gDTMF_RX, 0, sizeof(gDTMF_RX)); } #endif void DTMF_SendEndOfTransmission(void) { - if (gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO) { - BK4819_PlaySingleTone(2475, 250, 28, gEeprom.DTMF_SIDE_TONE); - } + if (gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO) { + BK4819_PlaySingleTone(2475, 250, 28, gEeprom.DTMF_SIDE_TONE); + } - if ((gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_TX_DOWN || gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_BOTH) + if ((gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_TX_DOWN || gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_BOTH) #ifdef ENABLE_DTMF_CALLING - && gDTMF_CallState == DTMF_CALL_STATE_NONE + && gDTMF_CallState == DTMF_CALL_STATE_NONE #endif - ) { // end-of-tx - if (gEeprom.DTMF_SIDE_TONE) { - AUDIO_AudioPathOn(); - gEnableSpeaker = true; - SYSTEM_DelayMs(60); - } + ) { // end-of-tx + if (gEeprom.DTMF_SIDE_TONE) { + AUDIO_AudioPathOn(); + gEnableSpeaker = true; + SYSTEM_DelayMs(60); + } - BK4819_EnterDTMF_TX(gEeprom.DTMF_SIDE_TONE); + BK4819_EnterDTMF_TX(gEeprom.DTMF_SIDE_TONE); - BK4819_PlayDTMFString( - gEeprom.DTMF_DOWN_CODE, - 0, - gEeprom.DTMF_FIRST_CODE_PERSIST_TIME, - gEeprom.DTMF_HASH_CODE_PERSIST_TIME, - gEeprom.DTMF_CODE_PERSIST_TIME, - gEeprom.DTMF_CODE_INTERVAL_TIME); + BK4819_PlayDTMFString( + gEeprom.DTMF_DOWN_CODE, + 0, + gEeprom.DTMF_FIRST_CODE_PERSIST_TIME, + gEeprom.DTMF_HASH_CODE_PERSIST_TIME, + gEeprom.DTMF_CODE_PERSIST_TIME, + gEeprom.DTMF_CODE_INTERVAL_TIME); - AUDIO_AudioPathOff(); - gEnableSpeaker = false; - } + AUDIO_AudioPathOff(); + gEnableSpeaker = false; + } - BK4819_ExitDTMF_TX(true); + BK4819_ExitDTMF_TX(true); } bool DTMF_ValidateCodes(char *pCode, const unsigned int size) { - unsigned int i; + unsigned int i; - if (pCode[0] == 0xFF || pCode[0] == 0) - return false; + if (pCode[0] == 0xFF || pCode[0] == 0) + return false; - for (i = 0; i < size; i++) - { - if (pCode[i] == 0xFF || pCode[i] == 0) - { - pCode[i] = 0; - break; - } + for (i = 0; i < size; i++) + { + if (pCode[i] == 0xFF || pCode[i] == 0) + { + pCode[i] = 0; + break; + } - if ((pCode[i] < '0' || pCode[i] > '9') && (pCode[i] < 'A' || pCode[i] > 'D') && pCode[i] != '*' && pCode[i] != '#') - return false; - } + if ((pCode[i] < '0' || pCode[i] > '9') && (pCode[i] < 'A' || pCode[i] > 'D') && pCode[i] != '*' && pCode[i] != '#') + return false; + } - return true; + return true; } #ifdef ENABLE_DTMF_CALLING bool DTMF_GetContact(const int Index, char *pContact) { - if (Index < 0 || Index >= MAX_DTMF_CONTACTS || pContact == NULL) { - return false; - } + if (Index < 0 || Index >= MAX_DTMF_CONTACTS || pContact == NULL) { + return false; + } - EEPROM_ReadBuffer(0x1C00 + (Index * 16), pContact, 16); + EEPROM_ReadBuffer(0x1C00 + (Index * 16), pContact, 16); - // check whether the first character is printable or not - return (pContact[0] >= ' ' && pContact[0] < 127); + // check whether the first character is printable or not + return (pContact[0] >= ' ' && pContact[0] < 127); } bool DTMF_FindContact(const char *pContact, char *pResult) { - pResult[0] = 0; + pResult[0] = 0; - for (unsigned int i = 0; i < MAX_DTMF_CONTACTS; i++) { - char Contact[16]; - if (!DTMF_GetContact(i, Contact)) { - return false; - } + for (unsigned int i = 0; i < MAX_DTMF_CONTACTS; i++) { + char Contact[16]; + if (!DTMF_GetContact(i, Contact)) { + return false; + } - if (memcmp(pContact, Contact + 8, 3) == 0) { - memcpy(pResult, Contact, 8); - pResult[8] = 0; - return true; - } - } + if (memcmp(pContact, Contact + 8, 3) == 0) { + memcpy(pResult, Contact, 8); + pResult[8] = 0; + return true; + } + } - return false; + return false; } #endif char DTMF_GetCharacter(const unsigned int code) { - if (code <= KEY_9) - return '0' + code; + if (code <= KEY_9) + return '0' + code; - switch (code) - { - case KEY_MENU: return 'A'; - case KEY_UP: return 'B'; - case KEY_DOWN: return 'C'; - case KEY_EXIT: return 'D'; - case KEY_STAR: return '*'; - case KEY_F: return '#'; - default: return 0xff; - } + switch (code) + { + case KEY_MENU: return 'A'; + case KEY_UP: return 'B'; + case KEY_DOWN: return 'C'; + case KEY_EXIT: return 'D'; + case KEY_STAR: return '*'; + case KEY_F: return '#'; + default: return 0xff; + } } #ifdef ENABLE_DTMF_CALLING static bool CompareMessage(const char *pMsg, const char *pTemplate, const unsigned int size, const bool bCheckGroup) { - unsigned int i; - for (i = 0; i < size; i++) - { - if (pMsg[i] != pTemplate[i]) - { - if (!bCheckGroup || pMsg[i] != gEeprom.DTMF_GROUP_CALL_CODE) - return false; - gDTMF_IsGroupCall = true; - } - } + unsigned int i; + for (i = 0; i < size; i++) + { + if (pMsg[i] != pTemplate[i]) + { + if (!bCheckGroup || pMsg[i] != gEeprom.DTMF_GROUP_CALL_CODE) + return false; + gDTMF_IsGroupCall = true; + } + } - return true; + return true; } DTMF_CallMode_t DTMF_CheckGroupCall(const char *pMsg, const unsigned int size) { - for (unsigned int i = 0; i < size; i++) - if (pMsg[i] == gEeprom.DTMF_GROUP_CALL_CODE) { - return DTMF_CALL_MODE_GROUP; - } + for (unsigned int i = 0; i < size; i++) + if (pMsg[i] == gEeprom.DTMF_GROUP_CALL_CODE) { + return DTMF_CALL_MODE_GROUP; + } - return DTMF_CALL_MODE_NOT_GROUP; + return DTMF_CALL_MODE_NOT_GROUP; } #endif void DTMF_clear_input_box(void) { - memset(gDTMF_InputBox, 0, sizeof(gDTMF_InputBox)); - gDTMF_InputBox_Index = 0; - gDTMF_InputMode = false; + memset(gDTMF_InputBox, 0, sizeof(gDTMF_InputBox)); + gDTMF_InputBox_Index = 0; + gDTMF_InputMode = false; } void DTMF_Append(const char code) { - if (gDTMF_InputBox_Index == 0) - { - memset(gDTMF_InputBox, '-', sizeof(gDTMF_InputBox) - 1); - gDTMF_InputBox[sizeof(gDTMF_InputBox) - 1] = 0; - } + if (gDTMF_InputBox_Index == 0) + { + memset(gDTMF_InputBox, '-', sizeof(gDTMF_InputBox) - 1); + gDTMF_InputBox[sizeof(gDTMF_InputBox) - 1] = 0; + } - if (gDTMF_InputBox_Index < (sizeof(gDTMF_InputBox) - 1)) - gDTMF_InputBox[gDTMF_InputBox_Index++] = code; + if (gDTMF_InputBox_Index < (sizeof(gDTMF_InputBox) - 1)) + gDTMF_InputBox[gDTMF_InputBox_Index++] = code; } #ifdef ENABLE_DTMF_CALLING void DTMF_HandleRequest(void) -{ // proccess the RX'ed DTMF characters +{ // proccess the RX'ed DTMF characters - char String[21]; - unsigned int Offset; + char String[21]; + unsigned int Offset; - if (!gDTMF_RX_pending) - return; // nothing new received + if (!gDTMF_RX_pending) + return; // nothing new received - if (gScanStateDir != SCAN_OFF || gCssBackgroundScan) - { // we're busy scanning - DTMF_clear_RX(); - return; - } + if (gScanStateDir != SCAN_OFF || gCssBackgroundScan) + { // we're busy scanning + DTMF_clear_RX(); + return; + } - if (!gRxVfo->DTMF_DECODING_ENABLE && !gSetting_KILLED) - { // D-DCD is disabled or we're alive - DTMF_clear_RX(); - return; - } + if (!gRxVfo->DTMF_DECODING_ENABLE && !gSetting_KILLED) + { // D-DCD is disabled or we're alive + DTMF_clear_RX(); + return; + } - gDTMF_RX_pending = false; + gDTMF_RX_pending = false; - if (gDTMF_RX_index >= 9) - { // look for the KILL code + if (gDTMF_RX_index >= 9) + { // look for the KILL code - sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, gEeprom.KILL_CODE); + sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, gEeprom.KILL_CODE); - Offset = gDTMF_RX_index - strlen(String); + Offset = gDTMF_RX_index - strlen(String); - if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true)) - { // bugger + if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true)) + { // bugger - if (gEeprom.PERMIT_REMOTE_KILL) - { - gSetting_KILLED = true; // oooerr ! + if (gEeprom.PERMIT_REMOTE_KILL) + { + gSetting_KILLED = true; // oooerr ! - DTMF_clear_RX(); + DTMF_clear_RX(); - SETTINGS_SaveSettings(); + SETTINGS_SaveSettings(); - gDTMF_ReplyState = DTMF_REPLY_AB; + gDTMF_ReplyState = DTMF_REPLY_AB; - #ifdef ENABLE_FMRADIO - if (gFmRadioMode) - { - FM_TurnOff(); - GUI_SelectNextDisplay(DISPLAY_MAIN); - } - #endif - } - else - { - gDTMF_ReplyState = DTMF_REPLY_NONE; - } + #ifdef ENABLE_FMRADIO + if (gFmRadioMode) + { + FM_TurnOff(); + GUI_SelectNextDisplay(DISPLAY_MAIN); + } + #endif + } + else + { + gDTMF_ReplyState = DTMF_REPLY_NONE; + } - gDTMF_CallState = DTMF_CALL_STATE_NONE; + gDTMF_CallState = DTMF_CALL_STATE_NONE; - gUpdateDisplay = true; - gUpdateStatus = true; - return; - } - } + gUpdateDisplay = true; + gUpdateStatus = true; + return; + } + } - if (gDTMF_RX_index >= 9) - { // look for the REVIVE code + if (gDTMF_RX_index >= 9) + { // look for the REVIVE code - sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, gEeprom.REVIVE_CODE); + sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, gEeprom.REVIVE_CODE); - Offset = gDTMF_RX_index - strlen(String); + Offset = gDTMF_RX_index - strlen(String); - if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true)) - { // shit, we're back ! + if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true)) + { // shit, we're back ! - gSetting_KILLED = false; + gSetting_KILLED = false; - DTMF_clear_RX(); + DTMF_clear_RX(); - SETTINGS_SaveSettings(); + SETTINGS_SaveSettings(); - gDTMF_ReplyState = DTMF_REPLY_AB; - gDTMF_CallState = DTMF_CALL_STATE_NONE; + gDTMF_ReplyState = DTMF_REPLY_AB; + gDTMF_CallState = DTMF_CALL_STATE_NONE; - gUpdateDisplay = true; - gUpdateStatus = true; - return; - } - } + gUpdateDisplay = true; + gUpdateStatus = true; + return; + } + } - if (gDTMF_RX_index >= 2) - { // look for ACK reply - char *pPrintStr = "AB"; + if (gDTMF_RX_index >= 2) + { // look for ACK reply + char *pPrintStr = "AB"; - Offset = gDTMF_RX_index - strlen(pPrintStr); + Offset = gDTMF_RX_index - strlen(pPrintStr); - if (CompareMessage(gDTMF_RX + Offset, pPrintStr, strlen(pPrintStr), true)) { - // ends with "AB" + if (CompareMessage(gDTMF_RX + Offset, pPrintStr, strlen(pPrintStr), true)) { + // ends with "AB" - if (gDTMF_ReplyState != DTMF_REPLY_NONE) // 1of11 -// if (gDTMF_CallState != DTMF_CALL_STATE_NONE) // 1of11 -// if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT) // 1of11 - { - gDTMF_State = DTMF_STATE_TX_SUCC; - DTMF_clear_RX(); - gUpdateDisplay = true; - return; - } - } - } + if (gDTMF_ReplyState != DTMF_REPLY_NONE) // 1of11 +// if (gDTMF_CallState != DTMF_CALL_STATE_NONE) // 1of11 +// if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT) // 1of11 + { + gDTMF_State = DTMF_STATE_TX_SUCC; + DTMF_clear_RX(); + gUpdateDisplay = true; + return; + } + } + } - if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT && - gDTMF_CallMode == DTMF_CALL_MODE_NOT_GROUP && - gDTMF_RX_index >= 9) - { // waiting for a reply + if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT && + gDTMF_CallMode == DTMF_CALL_MODE_NOT_GROUP && + gDTMF_RX_index >= 9) + { // waiting for a reply - sprintf(String, "%s%c%s", gDTMF_String, gEeprom.DTMF_SEPARATE_CODE, "AAAAA"); + sprintf(String, "%s%c%s", gDTMF_String, gEeprom.DTMF_SEPARATE_CODE, "AAAAA"); - Offset = gDTMF_RX_index - strlen(String); + Offset = gDTMF_RX_index - strlen(String); - if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), false)) - { // we got a response - gDTMF_State = DTMF_STATE_CALL_OUT_RSP; - DTMF_clear_RX(); - gUpdateDisplay = true; - } - } + if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), false)) + { // we got a response + gDTMF_State = DTMF_STATE_CALL_OUT_RSP; + DTMF_clear_RX(); + gUpdateDisplay = true; + } + } - if (gSetting_KILLED || gDTMF_CallState != DTMF_CALL_STATE_NONE) - { // we've been killed or expecting a reply - return; - } + if (gSetting_KILLED || gDTMF_CallState != DTMF_CALL_STATE_NONE) + { // we've been killed or expecting a reply + return; + } - if (gDTMF_RX_index >= 7) - { // see if we're being called + if (gDTMF_RX_index >= 7) + { // see if we're being called - gDTMF_IsGroupCall = false; + gDTMF_IsGroupCall = false; - sprintf(String, "%s%c", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE); + sprintf(String, "%s%c", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE); - Offset = gDTMF_RX_index - strlen(String) - 3; + Offset = gDTMF_RX_index - strlen(String) - 3; - if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true)) - { // it's for us ! + if (CompareMessage(gDTMF_RX + Offset, String, strlen(String), true)) + { // it's for us ! - gDTMF_CallState = DTMF_CALL_STATE_RECEIVED; + gDTMF_CallState = DTMF_CALL_STATE_RECEIVED; - memset(gDTMF_Callee, 0, sizeof(gDTMF_Callee)); - memset(gDTMF_Caller, 0, sizeof(gDTMF_Caller)); - memcpy(gDTMF_Callee, gDTMF_RX + Offset + 0, 3); - memcpy(gDTMF_Caller, gDTMF_RX + Offset + 4, 3); + memset(gDTMF_Callee, 0, sizeof(gDTMF_Callee)); + memset(gDTMF_Caller, 0, sizeof(gDTMF_Caller)); + memcpy(gDTMF_Callee, gDTMF_RX + Offset + 0, 3); + memcpy(gDTMF_Caller, gDTMF_RX + Offset + 4, 3); - DTMF_clear_RX(); + DTMF_clear_RX(); - gUpdateDisplay = true; + gUpdateDisplay = true; - switch (gEeprom.DTMF_DECODE_RESPONSE) - { - case DTMF_DEC_RESPONSE_BOTH: - gDTMF_DecodeRingCountdown_500ms = DTMF_decode_ring_countdown_500ms; - [[fallthrough]]; - case DTMF_DEC_RESPONSE_REPLY: - gDTMF_ReplyState = DTMF_REPLY_AAAAA; - break; - case DTMF_DEC_RESPONSE_RING: - gDTMF_DecodeRingCountdown_500ms = DTMF_decode_ring_countdown_500ms; - break; - default: - case DTMF_DEC_RESPONSE_NONE: - gDTMF_DecodeRingCountdown_500ms = 0; - gDTMF_ReplyState = DTMF_REPLY_NONE; - break; - } + switch (gEeprom.DTMF_DECODE_RESPONSE) + { + case DTMF_DEC_RESPONSE_BOTH: + gDTMF_DecodeRingCountdown_500ms = DTMF_decode_ring_countdown_500ms; + [[fallthrough]]; + case DTMF_DEC_RESPONSE_REPLY: + gDTMF_ReplyState = DTMF_REPLY_AAAAA; + break; + case DTMF_DEC_RESPONSE_RING: + gDTMF_DecodeRingCountdown_500ms = DTMF_decode_ring_countdown_500ms; + break; + default: + case DTMF_DEC_RESPONSE_NONE: + gDTMF_DecodeRingCountdown_500ms = 0; + gDTMF_ReplyState = DTMF_REPLY_NONE; + break; + } - if (gDTMF_IsGroupCall) - gDTMF_ReplyState = DTMF_REPLY_NONE; - } - } + if (gDTMF_IsGroupCall) + gDTMF_ReplyState = DTMF_REPLY_NONE; + } + } } #endif void DTMF_Reply(void) { - uint16_t Delay; + uint16_t Delay; #ifdef ENABLE_DTMF_CALLING - char String[23]; + char String[23]; #endif - const char *pString = NULL; + const char *pString = NULL; - switch (gDTMF_ReplyState) - { - case DTMF_REPLY_ANI: + switch (gDTMF_ReplyState) + { + case DTMF_REPLY_ANI: #ifdef ENABLE_DTMF_CALLING - if (gDTMF_CallMode != DTMF_CALL_MODE_DTMF) - { // append our ID code onto the end of the DTMF code to send - sprintf(String, "%s%c%s", gDTMF_String, gEeprom.DTMF_SEPARATE_CODE, gEeprom.ANI_DTMF_ID); - pString = String; - } - else + if (gDTMF_CallMode != DTMF_CALL_MODE_DTMF) + { // append our ID code onto the end of the DTMF code to send + sprintf(String, "%s%c%s", gDTMF_String, gEeprom.DTMF_SEPARATE_CODE, gEeprom.ANI_DTMF_ID); + pString = String; + } + else #endif - { - pString = gDTMF_String; - } + { + pString = gDTMF_String; + } - break; + break; #ifdef ENABLE_DTMF_CALLING - case DTMF_REPLY_AB: - pString = "AB"; - break; + case DTMF_REPLY_AB: + pString = "AB"; + break; - case DTMF_REPLY_AAAAA: - sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, "AAAAA"); - pString = String; - break; + case DTMF_REPLY_AAAAA: + sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, "AAAAA"); + pString = String; + break; #endif - default: - case DTMF_REPLY_NONE: - if ( + default: + case DTMF_REPLY_NONE: + if ( #ifdef ENABLE_DTMF_CALLING - gDTMF_CallState != DTMF_CALL_STATE_NONE || + gDTMF_CallState != DTMF_CALL_STATE_NONE || #endif - gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO || - gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_OFF || - gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_TX_DOWN) - { - gDTMF_ReplyState = DTMF_REPLY_NONE; - return; - } + gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO || + gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_OFF || + gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_TX_DOWN) + { + gDTMF_ReplyState = DTMF_REPLY_NONE; + return; + } - // send TX-UP DTMF - pString = gEeprom.DTMF_UP_CODE; - break; - } + // send TX-UP DTMF + pString = gEeprom.DTMF_UP_CODE; + break; + } - gDTMF_ReplyState = DTMF_REPLY_NONE; + gDTMF_ReplyState = DTMF_REPLY_NONE; - if (pString == NULL) - return; + if (pString == NULL) + return; - Delay = (gEeprom.DTMF_PRELOAD_TIME < 200) ? 200 : gEeprom.DTMF_PRELOAD_TIME; + Delay = (gEeprom.DTMF_PRELOAD_TIME < 200) ? 200 : gEeprom.DTMF_PRELOAD_TIME; - if (gEeprom.DTMF_SIDE_TONE) - { // the user will also hear the transmitted tones - AUDIO_AudioPathOn(); - gEnableSpeaker = true; - } + if (gEeprom.DTMF_SIDE_TONE) + { // the user will also hear the transmitted tones + AUDIO_AudioPathOn(); + gEnableSpeaker = true; + } - SYSTEM_DelayMs(Delay); + SYSTEM_DelayMs(Delay); - BK4819_EnterDTMF_TX(gEeprom.DTMF_SIDE_TONE); + BK4819_EnterDTMF_TX(gEeprom.DTMF_SIDE_TONE); - BK4819_PlayDTMFString( - pString, - 1, - gEeprom.DTMF_FIRST_CODE_PERSIST_TIME, - gEeprom.DTMF_HASH_CODE_PERSIST_TIME, - gEeprom.DTMF_CODE_PERSIST_TIME, - gEeprom.DTMF_CODE_INTERVAL_TIME); + BK4819_PlayDTMFString( + pString, + 1, + gEeprom.DTMF_FIRST_CODE_PERSIST_TIME, + gEeprom.DTMF_HASH_CODE_PERSIST_TIME, + gEeprom.DTMF_CODE_PERSIST_TIME, + gEeprom.DTMF_CODE_INTERVAL_TIME); - AUDIO_AudioPathOff(); + AUDIO_AudioPathOff(); - gEnableSpeaker = false; + gEnableSpeaker = false; - BK4819_ExitDTMF_TX(false); + BK4819_ExitDTMF_TX(false); } diff --git a/app/dtmf.h b/app/dtmf.h index 8e112b3..0e51383 100644 --- a/app/dtmf.h +++ b/app/dtmf.h @@ -23,47 +23,47 @@ #define MAX_DTMF_CONTACTS 16 enum DTMF_State_t { - DTMF_STATE_0 = 0, - DTMF_STATE_TX_SUCC, - DTMF_STATE_CALL_OUT_RSP + DTMF_STATE_0 = 0, + DTMF_STATE_TX_SUCC, + DTMF_STATE_CALL_OUT_RSP }; typedef enum DTMF_State_t DTMF_State_t; enum DTMF_CallState_t { - DTMF_CALL_STATE_NONE = 0, - DTMF_CALL_STATE_CALL_OUT, - DTMF_CALL_STATE_RECEIVED, - DTMF_CALL_STATE_RECEIVED_STAY + DTMF_CALL_STATE_NONE = 0, + DTMF_CALL_STATE_CALL_OUT, + DTMF_CALL_STATE_RECEIVED, + DTMF_CALL_STATE_RECEIVED_STAY }; enum DTMF_DecodeResponse_t { - DTMF_DEC_RESPONSE_NONE = 0, - DTMF_DEC_RESPONSE_RING, - DTMF_DEC_RESPONSE_REPLY, - DTMF_DEC_RESPONSE_BOTH + DTMF_DEC_RESPONSE_NONE = 0, + DTMF_DEC_RESPONSE_RING, + DTMF_DEC_RESPONSE_REPLY, + DTMF_DEC_RESPONSE_BOTH }; typedef enum DTMF_CallState_t DTMF_CallState_t; enum DTMF_ReplyState_t { - DTMF_REPLY_NONE = 0, - DTMF_REPLY_ANI, - DTMF_REPLY_AB, - DTMF_REPLY_AAAAA + DTMF_REPLY_NONE = 0, + DTMF_REPLY_ANI, + DTMF_REPLY_AB, + DTMF_REPLY_AAAAA }; typedef enum DTMF_ReplyState_t DTMF_ReplyState_t; enum DTMF_CallMode_t { - DTMF_CALL_MODE_NOT_GROUP = 0, - DTMF_CALL_MODE_GROUP, - DTMF_CALL_MODE_DTMF + DTMF_CALL_MODE_NOT_GROUP = 0, + DTMF_CALL_MODE_GROUP, + DTMF_CALL_MODE_DTMF }; enum { // seconds - DTMF_HOLD_MIN = 5, - DTMF_HOLD_MAX = 60 + DTMF_HOLD_MIN = 5, + DTMF_HOLD_MAX = 60 }; typedef enum DTMF_CallMode_t DTMF_CallMode_t; diff --git a/app/flashlight.c b/app/flashlight.c index 9cb94b9..28a48b9 100644 --- a/app/flashlight.c +++ b/app/flashlight.c @@ -6,78 +6,78 @@ #include "flashlight.h" #ifndef ENABLE_FEAT_F4HWN - enum FlashlightMode_t gFlashLightState; + enum FlashlightMode_t gFlashLightState; - void FlashlightTimeSlice() - { - if (gFlashLightState == FLASHLIGHT_BLINK && (gFlashLightBlinkCounter & 15u) == 0) { - GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); - return; - } + void FlashlightTimeSlice() + { + if (gFlashLightState == FLASHLIGHT_BLINK && (gFlashLightBlinkCounter & 15u) == 0) { + GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); + return; + } - if (gFlashLightState == FLASHLIGHT_SOS) { - const uint16_t u = 15; - static uint8_t c; - static uint16_t next; + if (gFlashLightState == FLASHLIGHT_SOS) { + const uint16_t u = 15; + static uint8_t c; + static uint16_t next; - if (gFlashLightBlinkCounter - next > 7 * u) { - c = 0; - next = gFlashLightBlinkCounter + 1; - return; - } + if (gFlashLightBlinkCounter - next > 7 * u) { + c = 0; + next = gFlashLightBlinkCounter + 1; + return; + } - if (gFlashLightBlinkCounter == next) { - if (c==0) { - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); - } else { - GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); - } + if (gFlashLightBlinkCounter == next) { + if (c==0) { + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); + } else { + GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); + } - if (c >= 18) { - next = gFlashLightBlinkCounter + 7 * u; - c = 0; - } else if(c==7 || c==9 || c==11) { - next = gFlashLightBlinkCounter + 3 * u; - } else { - next = gFlashLightBlinkCounter + u; - } - c++; - } - } - } + if (c >= 18) { + next = gFlashLightBlinkCounter + 7 * u; + c = 0; + } else if(c==7 || c==9 || c==11) { + next = gFlashLightBlinkCounter + 3 * u; + } else { + next = gFlashLightBlinkCounter + u; + } + c++; + } + } + } - void ACTION_FlashLight(void) - { - switch (gFlashLightState) { - case FLASHLIGHT_OFF: - gFlashLightState++; - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); - break; - case FLASHLIGHT_ON: - case FLASHLIGHT_BLINK: - gFlashLightState++; - break; - case FLASHLIGHT_SOS: - default: - gFlashLightState = 0; - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); - } - } + void ACTION_FlashLight(void) + { + switch (gFlashLightState) { + case FLASHLIGHT_OFF: + gFlashLightState++; + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); + break; + case FLASHLIGHT_ON: + case FLASHLIGHT_BLINK: + gFlashLightState++; + break; + case FLASHLIGHT_SOS: + default: + gFlashLightState = 0; + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); + } + } #else - void ACTION_FlashLight(void) - { - static bool gFlashLightState = false; + void ACTION_FlashLight(void) + { + static bool gFlashLightState = false; - if(gFlashLightState) - { - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); - } - else - { - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); - } + if(gFlashLightState) + { + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); + } + else + { + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); + } - gFlashLightState = (gFlashLightState) ? false : true; - } + gFlashLightState = (gFlashLightState) ? false : true; + } #endif #endif diff --git a/app/fm.c b/app/fm.c index d53a731..248ad2c 100644 --- a/app/fm.c +++ b/app/fm.c @@ -33,7 +33,7 @@ #include "ui/ui.h" #ifndef ARRAY_SIZE - #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif uint16_t gFM_Channels[20]; @@ -62,544 +62,544 @@ static void Key_FUNC(KEY_Code_t Key, uint8_t state); bool FM_CheckValidChannel(uint8_t Channel) { - return Channel < ARRAY_SIZE(gFM_Channels) && - gFM_Channels[Channel] >= BK1080_GetFreqLoLimit(gEeprom.FM_Band) && - gFM_Channels[Channel] < BK1080_GetFreqHiLimit(gEeprom.FM_Band); + return Channel < ARRAY_SIZE(gFM_Channels) && + gFM_Channels[Channel] >= BK1080_GetFreqLoLimit(gEeprom.FM_Band) && + gFM_Channels[Channel] < BK1080_GetFreqHiLimit(gEeprom.FM_Band); } uint8_t FM_FindNextChannel(uint8_t Channel, uint8_t Direction) { - for (unsigned i = 0; i < ARRAY_SIZE(gFM_Channels); i++) { - if (Channel == 0xFF) - Channel = ARRAY_SIZE(gFM_Channels) - 1; - else if (Channel >= ARRAY_SIZE(gFM_Channels)) - Channel = 0; - if (FM_CheckValidChannel(Channel)) - return Channel; - Channel += Direction; - } + for (unsigned i = 0; i < ARRAY_SIZE(gFM_Channels); i++) { + if (Channel == 0xFF) + Channel = ARRAY_SIZE(gFM_Channels) - 1; + else if (Channel >= ARRAY_SIZE(gFM_Channels)) + Channel = 0; + if (FM_CheckValidChannel(Channel)) + return Channel; + Channel += Direction; + } - return 0xFF; + return 0xFF; } int FM_ConfigureChannelState(void) { - gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency; + gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency; - if (gEeprom.FM_IsMrMode) { - const uint8_t Channel = FM_FindNextChannel(gEeprom.FM_SelectedChannel, FM_CHANNEL_UP); - if (Channel == 0xFF) { - gEeprom.FM_IsMrMode = false; - return -1; - } - gEeprom.FM_SelectedChannel = Channel; - gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel]; - } + if (gEeprom.FM_IsMrMode) { + const uint8_t Channel = FM_FindNextChannel(gEeprom.FM_SelectedChannel, FM_CHANNEL_UP); + if (Channel == 0xFF) { + gEeprom.FM_IsMrMode = false; + return -1; + } + gEeprom.FM_SelectedChannel = Channel; + gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel]; + } - return 0; + return 0; } void FM_TurnOff(void) { - gFmRadioMode = false; - gFM_ScanState = FM_SCAN_OFF; - gFM_RestoreCountdown_10ms = 0; + gFmRadioMode = false; + gFM_ScanState = FM_SCAN_OFF; + gFM_RestoreCountdown_10ms = 0; - AUDIO_AudioPathOff(); - gEnableSpeaker = false; + AUDIO_AudioPathOff(); + gEnableSpeaker = false; - BK1080_Init0(); + BK1080_Init0(); - gUpdateStatus = true; + gUpdateStatus = true; } void FM_EraseChannels(void) { - uint8_t Template[8]; - memset(Template, 0xFF, sizeof(Template)); + uint8_t Template[8]; + memset(Template, 0xFF, sizeof(Template)); - for (unsigned i = 0; i < 5; i++) - EEPROM_WriteBuffer(0x0E40 + (i * 8), Template); + for (unsigned i = 0; i < 5; i++) + EEPROM_WriteBuffer(0x0E40 + (i * 8), Template); - memset(gFM_Channels, 0xFF, sizeof(gFM_Channels)); + memset(gFM_Channels, 0xFF, sizeof(gFM_Channels)); } void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag) { - AUDIO_AudioPathOff(); + AUDIO_AudioPathOff(); - gEnableSpeaker = false; + gEnableSpeaker = false; - gFmPlayCountdown_10ms = (gFM_ScanState == FM_SCAN_OFF) ? fm_play_countdown_noscan_10ms : fm_play_countdown_scan_10ms; + gFmPlayCountdown_10ms = (gFM_ScanState == FM_SCAN_OFF) ? fm_play_countdown_noscan_10ms : fm_play_countdown_scan_10ms; - gScheduleFM = false; - gFM_FoundFrequency = false; - gAskToSave = false; - gAskToDelete = false; - gEeprom.FM_FrequencyPlaying = Frequency; + gScheduleFM = false; + gFM_FoundFrequency = false; + gAskToSave = false; + gAskToDelete = false; + gEeprom.FM_FrequencyPlaying = Frequency; - if (!bFlag) { - Frequency += Step; - if (Frequency < BK1080_GetFreqLoLimit(gEeprom.FM_Band)) - Frequency = BK1080_GetFreqHiLimit(gEeprom.FM_Band); - else if (Frequency > BK1080_GetFreqHiLimit(gEeprom.FM_Band)) - Frequency = BK1080_GetFreqLoLimit(gEeprom.FM_Band); + if (!bFlag) { + Frequency += Step; + if (Frequency < BK1080_GetFreqLoLimit(gEeprom.FM_Band)) + Frequency = BK1080_GetFreqHiLimit(gEeprom.FM_Band); + else if (Frequency > BK1080_GetFreqHiLimit(gEeprom.FM_Band)) + Frequency = BK1080_GetFreqLoLimit(gEeprom.FM_Band); - gEeprom.FM_FrequencyPlaying = Frequency; - } + gEeprom.FM_FrequencyPlaying = Frequency; + } - gFM_ScanState = Step; + gFM_ScanState = Step; - BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); + BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); } void FM_PlayAndUpdate(void) { - gFM_ScanState = FM_SCAN_OFF; + gFM_ScanState = FM_SCAN_OFF; - if (gFM_AutoScan) { - gEeprom.FM_IsMrMode = true; - gEeprom.FM_SelectedChannel = 0; - } + if (gFM_AutoScan) { + gEeprom.FM_IsMrMode = true; + gEeprom.FM_SelectedChannel = 0; + } - FM_ConfigureChannelState(); - BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); - SETTINGS_SaveFM(); + FM_ConfigureChannelState(); + BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); + SETTINGS_SaveFM(); - gFmPlayCountdown_10ms = 0; - gScheduleFM = false; - gAskToSave = false; + gFmPlayCountdown_10ms = 0; + gScheduleFM = false; + gAskToSave = false; - AUDIO_AudioPathOn(); + AUDIO_AudioPathOn(); - gEnableSpeaker = true; + gEnableSpeaker = true; } int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit) { - int ret = -1; + int ret = -1; - const uint16_t Test2 = BK1080_ReadRegister(BK1080_REG_07); + const uint16_t Test2 = BK1080_ReadRegister(BK1080_REG_07); - // This is supposed to be a signed value, but above function is unsigned - const uint16_t Deviation = BK1080_REG_07_GET_FREQD(Test2); + // This is supposed to be a signed value, but above function is unsigned + const uint16_t Deviation = BK1080_REG_07_GET_FREQD(Test2); - if (BK1080_REG_07_GET_SNR(Test2) <= 2) { - goto Bail; - } + if (BK1080_REG_07_GET_SNR(Test2) <= 2) { + goto Bail; + } - const uint16_t Status = BK1080_ReadRegister(BK1080_REG_10); + const uint16_t Status = BK1080_ReadRegister(BK1080_REG_10); - if ((Status & BK1080_REG_10_MASK_AFCRL) != BK1080_REG_10_AFCRL_NOT_RAILED || BK1080_REG_10_GET_RSSI(Status) < 10) { - goto Bail; - } + if ((Status & BK1080_REG_10_MASK_AFCRL) != BK1080_REG_10_AFCRL_NOT_RAILED || BK1080_REG_10_GET_RSSI(Status) < 10) { + goto Bail; + } - //if (Deviation > -281 && Deviation < 280) - if (Deviation >= 280 && Deviation <= 3815) { - goto Bail; - } + //if (Deviation > -281 && Deviation < 280) + if (Deviation >= 280 && Deviation <= 3815) { + goto Bail; + } - // not BLE(less than or equal) - if (Frequency > LowerLimit && (Frequency - BK1080_BaseFrequency) == 1) { - if (BK1080_FrequencyDeviation & 0x800 || (BK1080_FrequencyDeviation < 20)) - goto Bail; - } + // not BLE(less than or equal) + if (Frequency > LowerLimit && (Frequency - BK1080_BaseFrequency) == 1) { + if (BK1080_FrequencyDeviation & 0x800 || (BK1080_FrequencyDeviation < 20)) + goto Bail; + } - // not BLT(less than) + // not BLT(less than) - if (Frequency >= LowerLimit && (BK1080_BaseFrequency - Frequency) == 1) { - if ((BK1080_FrequencyDeviation & 0x800) == 0 || (BK1080_FrequencyDeviation > 4075)) - goto Bail; - } + if (Frequency >= LowerLimit && (BK1080_BaseFrequency - Frequency) == 1) { + if ((BK1080_FrequencyDeviation & 0x800) == 0 || (BK1080_FrequencyDeviation > 4075)) + goto Bail; + } - ret = 0; + ret = 0; Bail: - BK1080_FrequencyDeviation = Deviation; - BK1080_BaseFrequency = Frequency; + BK1080_FrequencyDeviation = Deviation; + BK1080_BaseFrequency = Frequency; - return ret; + return ret; } static void Key_DIGITS(KEY_Code_t Key, uint8_t state) { - enum { STATE_FREQ_MODE, STATE_MR_MODE, STATE_SAVE }; + enum { STATE_FREQ_MODE, STATE_MR_MODE, STATE_SAVE }; - if (state == BUTTON_EVENT_SHORT && !gWasFKeyPressed) { - uint8_t State; + if (state == BUTTON_EVENT_SHORT && !gWasFKeyPressed) { + uint8_t State; - if (gAskToDelete) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + if (gAskToDelete) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } - if (gAskToSave) { - State = STATE_SAVE; - } - else { - if (gFM_ScanState != FM_SCAN_OFF) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + if (gAskToSave) { + State = STATE_SAVE; + } + else { + if (gFM_ScanState != FM_SCAN_OFF) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } - State = gEeprom.FM_IsMrMode ? STATE_MR_MODE : STATE_FREQ_MODE; - } + State = gEeprom.FM_IsMrMode ? STATE_MR_MODE : STATE_FREQ_MODE; + } - INPUTBOX_Append(Key); + INPUTBOX_Append(Key); - gRequestDisplayScreen = DISPLAY_FM; + gRequestDisplayScreen = DISPLAY_FM; - if (State == STATE_FREQ_MODE) { - if (gInputBoxIndex == 1) { - if (gInputBox[0] > 1) { - gInputBox[1] = gInputBox[0]; - gInputBox[0] = 0; - gInputBoxIndex = 2; - } - } - else if (gInputBoxIndex > 3) { - uint32_t Frequency; + if (State == STATE_FREQ_MODE) { + if (gInputBoxIndex == 1) { + if (gInputBox[0] > 1) { + gInputBox[1] = gInputBox[0]; + gInputBox[0] = 0; + gInputBoxIndex = 2; + } + } + else if (gInputBoxIndex > 3) { + uint32_t Frequency; - gInputBoxIndex = 0; - Frequency = StrToUL(INPUTBOX_GetAscii()); + gInputBoxIndex = 0; + Frequency = StrToUL(INPUTBOX_GetAscii()); - if (Frequency < BK1080_GetFreqLoLimit(gEeprom.FM_Band) || BK1080_GetFreqHiLimit(gEeprom.FM_Band) < Frequency) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - gRequestDisplayScreen = DISPLAY_FM; - return; - } + if (Frequency < BK1080_GetFreqLoLimit(gEeprom.FM_Band) || BK1080_GetFreqHiLimit(gEeprom.FM_Band) < Frequency) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + gRequestDisplayScreen = DISPLAY_FM; + return; + } - gEeprom.FM_SelectedFrequency = (uint16_t)Frequency; + gEeprom.FM_SelectedFrequency = (uint16_t)Frequency; #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; + gAnotherVoiceID = (VOICE_ID_t)Key; #endif - gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency; - BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); - gRequestSaveFM = true; - return; - } - } - else if (gInputBoxIndex == 2) { - uint8_t Channel; + gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency; + BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); + gRequestSaveFM = true; + return; + } + } + else if (gInputBoxIndex == 2) { + uint8_t Channel; - gInputBoxIndex = 0; - Channel = ((gInputBox[0] * 10) + gInputBox[1]) - 1; + gInputBoxIndex = 0; + Channel = ((gInputBox[0] * 10) + gInputBox[1]) - 1; - if (State == STATE_MR_MODE) { - if (FM_CheckValidChannel(Channel)) { + if (State == STATE_MR_MODE) { + if (FM_CheckValidChannel(Channel)) { #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; + gAnotherVoiceID = (VOICE_ID_t)Key; #endif - gEeprom.FM_SelectedChannel = Channel; - gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel]; - BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); - gRequestSaveFM = true; - return; - } - } - else if (Channel < 20) { + gEeprom.FM_SelectedChannel = Channel; + gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel]; + BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); + gRequestSaveFM = true; + return; + } + } + else if (Channel < 20) { #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; + gAnotherVoiceID = (VOICE_ID_t)Key; #endif - gRequestDisplayScreen = DISPLAY_FM; - gInputBoxIndex = 0; - gFM_ChannelPosition = Channel; - return; - } + gRequestDisplayScreen = DISPLAY_FM; + gInputBoxIndex = 0; + gFM_ChannelPosition = Channel; + return; + } - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; + gAnotherVoiceID = (VOICE_ID_t)Key; #endif - } - else - Key_FUNC(Key, state); + } + else + Key_FUNC(Key, state); } static void Key_FUNC(KEY_Code_t Key, uint8_t state) { - if (state == BUTTON_EVENT_SHORT || state == BUTTON_EVENT_HELD) { - bool autoScan = gWasFKeyPressed || (state == BUTTON_EVENT_HELD); + if (state == BUTTON_EVENT_SHORT || state == BUTTON_EVENT_HELD) { + bool autoScan = gWasFKeyPressed || (state == BUTTON_EVENT_HELD); - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - gWasFKeyPressed = false; - gUpdateStatus = true; - gRequestDisplayScreen = DISPLAY_FM; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gWasFKeyPressed = false; + gUpdateStatus = true; + gRequestDisplayScreen = DISPLAY_FM; - switch (Key) { - case KEY_0: - ACTION_FM(); - break; + switch (Key) { + case KEY_0: + ACTION_FM(); + break; - case KEY_1: - gEeprom.FM_Band++; - gRequestSaveFM = true; - break; + case KEY_1: + gEeprom.FM_Band++; + gRequestSaveFM = true; + break; - // case KEY_2: - // gEeprom.FM_Space = (gEeprom.FM_Space + 1) % 3; - // gRequestSaveFM = true; - // break; + // case KEY_2: + // gEeprom.FM_Space = (gEeprom.FM_Space + 1) % 3; + // gRequestSaveFM = true; + // break; - case KEY_3: - gEeprom.FM_IsMrMode = !gEeprom.FM_IsMrMode; + case KEY_3: + gEeprom.FM_IsMrMode = !gEeprom.FM_IsMrMode; - if (!FM_ConfigureChannelState()) { - BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); - gRequestSaveFM = true; - } - else - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - break; + if (!FM_ConfigureChannelState()) { + BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); + gRequestSaveFM = true; + } + else + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + break; - case KEY_STAR: - ACTION_Scan(autoScan); - break; + case KEY_STAR: + ACTION_Scan(autoScan); + break; - default: - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - break; - } - } + default: + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + break; + } + } } static void Key_EXIT(uint8_t state) { - if (state != BUTTON_EVENT_SHORT) - return; + if (state != BUTTON_EVENT_SHORT) + return; - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - if (gFM_ScanState == FM_SCAN_OFF) { - if (gInputBoxIndex == 0) { - if (!gAskToSave && !gAskToDelete) { - ACTION_FM(); - return; - } + if (gFM_ScanState == FM_SCAN_OFF) { + if (gInputBoxIndex == 0) { + if (!gAskToSave && !gAskToDelete) { + ACTION_FM(); + return; + } - gAskToSave = false; - gAskToDelete = false; - } - else { - gInputBox[--gInputBoxIndex] = 10; + gAskToSave = false; + gAskToDelete = false; + } + else { + gInputBox[--gInputBoxIndex] = 10; - if (gInputBoxIndex) { - if (gInputBoxIndex != 1) { - gRequestDisplayScreen = DISPLAY_FM; - return; - } + if (gInputBoxIndex) { + if (gInputBoxIndex != 1) { + gRequestDisplayScreen = DISPLAY_FM; + return; + } - if (gInputBox[0] != 0) { - gRequestDisplayScreen = DISPLAY_FM; - return; - } - } - gInputBoxIndex = 0; - } + if (gInputBox[0] != 0) { + gRequestDisplayScreen = DISPLAY_FM; + return; + } + } + gInputBoxIndex = 0; + } #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_CANCEL; + gAnotherVoiceID = VOICE_ID_CANCEL; #endif - } - else { - FM_PlayAndUpdate(); + } + else { + FM_PlayAndUpdate(); #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_SCANNING_STOP; + gAnotherVoiceID = VOICE_ID_SCANNING_STOP; #endif - } + } - gRequestDisplayScreen = DISPLAY_FM; + gRequestDisplayScreen = DISPLAY_FM; } static void Key_MENU(uint8_t state) { - if (state != BUTTON_EVENT_SHORT) - return; + if (state != BUTTON_EVENT_SHORT) + return; - gRequestDisplayScreen = DISPLAY_FM; - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gRequestDisplayScreen = DISPLAY_FM; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - if (gFM_ScanState == FM_SCAN_OFF) { - if (!gEeprom.FM_IsMrMode) { - if (gAskToSave) { - gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying; - gRequestSaveFM = true; - } - gAskToSave = !gAskToSave; - } - else { - if (gAskToDelete) { - gFM_Channels[gEeprom.FM_SelectedChannel] = 0xFFFF; + if (gFM_ScanState == FM_SCAN_OFF) { + if (!gEeprom.FM_IsMrMode) { + if (gAskToSave) { + gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying; + gRequestSaveFM = true; + } + gAskToSave = !gAskToSave; + } + else { + if (gAskToDelete) { + gFM_Channels[gEeprom.FM_SelectedChannel] = 0xFFFF; - FM_ConfigureChannelState(); - BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); + FM_ConfigureChannelState(); + BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); - gRequestSaveFM = true; - } - gAskToDelete = !gAskToDelete; - } - } - else { - if (gFM_AutoScan || !gFM_FoundFrequency) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - gInputBoxIndex = 0; - return; - } + gRequestSaveFM = true; + } + gAskToDelete = !gAskToDelete; + } + } + else { + if (gFM_AutoScan || !gFM_FoundFrequency) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + gInputBoxIndex = 0; + return; + } - if (gAskToSave) { - gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying; - gRequestSaveFM = true; - } - gAskToSave = !gAskToSave; - } + if (gAskToSave) { + gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying; + gRequestSaveFM = true; + } + gAskToSave = !gAskToSave; + } } static void Key_UP_DOWN(uint8_t state, int8_t Step) { - if (state == BUTTON_EVENT_PRESSED) { - if (gInputBoxIndex) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + if (state == BUTTON_EVENT_PRESSED) { + if (gInputBoxIndex) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - } else if (gInputBoxIndex || state!=BUTTON_EVENT_HELD) { - return; - } + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + } else if (gInputBoxIndex || state!=BUTTON_EVENT_HELD) { + return; + } - if (gAskToSave) { - gRequestDisplayScreen = DISPLAY_FM; - gFM_ChannelPosition = NUMBER_AddWithWraparound(gFM_ChannelPosition, Step, 0, 19); - return; - } + if (gAskToSave) { + gRequestDisplayScreen = DISPLAY_FM; + gFM_ChannelPosition = NUMBER_AddWithWraparound(gFM_ChannelPosition, Step, 0, 19); + return; + } - if (gFM_ScanState != FM_SCAN_OFF) { - if (gFM_AutoScan) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + if (gFM_ScanState != FM_SCAN_OFF) { + if (gFM_AutoScan) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } - FM_Tune(gEeprom.FM_FrequencyPlaying, Step, false); - gRequestDisplayScreen = DISPLAY_FM; - return; - } + FM_Tune(gEeprom.FM_FrequencyPlaying, Step, false); + gRequestDisplayScreen = DISPLAY_FM; + return; + } - if (gEeprom.FM_IsMrMode) { - const uint8_t Channel = FM_FindNextChannel(gEeprom.FM_SelectedChannel + Step, Step); - if (Channel == 0xFF || gEeprom.FM_SelectedChannel == Channel) - goto Bail; + if (gEeprom.FM_IsMrMode) { + const uint8_t Channel = FM_FindNextChannel(gEeprom.FM_SelectedChannel + Step, Step); + if (Channel == 0xFF || gEeprom.FM_SelectedChannel == Channel) + goto Bail; - gEeprom.FM_SelectedChannel = Channel; - gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel]; - } - else { - uint16_t Frequency = gEeprom.FM_SelectedFrequency + Step; + gEeprom.FM_SelectedChannel = Channel; + gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel]; + } + else { + uint16_t Frequency = gEeprom.FM_SelectedFrequency + Step; - if (Frequency < BK1080_GetFreqLoLimit(gEeprom.FM_Band)) - Frequency = BK1080_GetFreqHiLimit(gEeprom.FM_Band); - else if (Frequency > BK1080_GetFreqHiLimit(gEeprom.FM_Band)) - Frequency = BK1080_GetFreqLoLimit(gEeprom.FM_Band); + if (Frequency < BK1080_GetFreqLoLimit(gEeprom.FM_Band)) + Frequency = BK1080_GetFreqHiLimit(gEeprom.FM_Band); + else if (Frequency > BK1080_GetFreqHiLimit(gEeprom.FM_Band)) + Frequency = BK1080_GetFreqLoLimit(gEeprom.FM_Band); - gEeprom.FM_FrequencyPlaying = Frequency; - gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying; - } + gEeprom.FM_FrequencyPlaying = Frequency; + gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying; + } - gRequestSaveFM = true; + gRequestSaveFM = true; Bail: - BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); + BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); - gRequestDisplayScreen = DISPLAY_FM; + gRequestDisplayScreen = DISPLAY_FM; } void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { - uint8_t state = bKeyPressed + 2 * bKeyHeld; + uint8_t state = bKeyPressed + 2 * bKeyHeld; - switch (Key) { - case KEY_0...KEY_9: - Key_DIGITS(Key, state); - break; - case KEY_STAR: - Key_FUNC(Key, state); - break; - case KEY_MENU: - Key_MENU(state); - break; - case KEY_UP: - Key_UP_DOWN(state, 1); - break; - case KEY_DOWN: - Key_UP_DOWN(state, -1); - break;; - case KEY_EXIT: - Key_EXIT(state); - break; - case KEY_F: - GENERIC_Key_F(bKeyPressed, bKeyHeld); - break; - case KEY_PTT: - GENERIC_Key_PTT(bKeyPressed); - break; - default: - if (!bKeyHeld && bKeyPressed) - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - break; - } + switch (Key) { + case KEY_0...KEY_9: + Key_DIGITS(Key, state); + break; + case KEY_STAR: + Key_FUNC(Key, state); + break; + case KEY_MENU: + Key_MENU(state); + break; + case KEY_UP: + Key_UP_DOWN(state, 1); + break; + case KEY_DOWN: + Key_UP_DOWN(state, -1); + break;; + case KEY_EXIT: + Key_EXIT(state); + break; + case KEY_F: + GENERIC_Key_F(bKeyPressed, bKeyHeld); + break; + case KEY_PTT: + GENERIC_Key_PTT(bKeyPressed); + break; + default: + if (!bKeyHeld && bKeyPressed) + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + break; + } } void FM_Play(void) { - if (!FM_CheckFrequencyLock(gEeprom.FM_FrequencyPlaying, BK1080_GetFreqLoLimit(gEeprom.FM_Band))) { - if (!gFM_AutoScan) { - gFmPlayCountdown_10ms = 0; - gFM_FoundFrequency = true; + if (!FM_CheckFrequencyLock(gEeprom.FM_FrequencyPlaying, BK1080_GetFreqLoLimit(gEeprom.FM_Band))) { + if (!gFM_AutoScan) { + gFmPlayCountdown_10ms = 0; + gFM_FoundFrequency = true; - if (!gEeprom.FM_IsMrMode) - gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying; + if (!gEeprom.FM_IsMrMode) + gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying; - AUDIO_AudioPathOn(); - gEnableSpeaker = true; + AUDIO_AudioPathOn(); + gEnableSpeaker = true; - GUI_SelectNextDisplay(DISPLAY_FM); - return; - } + GUI_SelectNextDisplay(DISPLAY_FM); + return; + } - if (gFM_ChannelPosition < 20) - gFM_Channels[gFM_ChannelPosition++] = gEeprom.FM_FrequencyPlaying; + if (gFM_ChannelPosition < 20) + gFM_Channels[gFM_ChannelPosition++] = gEeprom.FM_FrequencyPlaying; - if (gFM_ChannelPosition >= 20) { - FM_PlayAndUpdate(); - GUI_SelectNextDisplay(DISPLAY_FM); - return; - } - } + if (gFM_ChannelPosition >= 20) { + FM_PlayAndUpdate(); + GUI_SelectNextDisplay(DISPLAY_FM); + return; + } + } - if (gFM_AutoScan && gEeprom.FM_FrequencyPlaying >= BK1080_GetFreqHiLimit(1)) - FM_PlayAndUpdate(); - else - FM_Tune(gEeprom.FM_FrequencyPlaying, gFM_ScanState, false); + if (gFM_AutoScan && gEeprom.FM_FrequencyPlaying >= BK1080_GetFreqHiLimit(1)) + FM_PlayAndUpdate(); + else + FM_Tune(gEeprom.FM_FrequencyPlaying, gFM_ScanState, false); - GUI_SelectNextDisplay(DISPLAY_FM); + GUI_SelectNextDisplay(DISPLAY_FM); } void FM_Start(void) { - gDualWatchActive = false; - gFmRadioMode = true; - gFM_ScanState = FM_SCAN_OFF; - gFM_RestoreCountdown_10ms = 0; + gDualWatchActive = false; + gFmRadioMode = true; + gFM_ScanState = FM_SCAN_OFF; + gFM_RestoreCountdown_10ms = 0; - BK1080_Init(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); + BK1080_Init(gEeprom.FM_FrequencyPlaying, gEeprom.FM_Band/*, gEeprom.FM_Space*/); - AUDIO_AudioPathOn(); + AUDIO_AudioPathOn(); - gEnableSpeaker = true; - gUpdateStatus = true; + gEnableSpeaker = true; + gUpdateStatus = true; } #endif diff --git a/app/fm.h b/app/fm.h index 51bac66..346cd90 100644 --- a/app/fm.h +++ b/app/fm.h @@ -21,11 +21,11 @@ #include "driver/keyboard.h" -#define FM_CHANNEL_UP 0x01 -#define FM_CHANNEL_DOWN 0xFF +#define FM_CHANNEL_UP 0x01 +#define FM_CHANNEL_DOWN 0xFF enum { - FM_SCAN_OFF = 0U, + FM_SCAN_OFF = 0U, }; extern uint16_t gFM_Channels[20]; diff --git a/app/generic.c b/app/generic.c index 00f9205..542e660 100644 --- a/app/generic.c +++ b/app/generic.c @@ -21,7 +21,7 @@ #include "app/common.h" #ifdef ENABLE_FMRADIO - #include "app/fm.h" + #include "app/fm.h" #endif #include "app/generic.h" @@ -39,187 +39,187 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld) { - if (gInputBoxIndex > 0) { - if (!bKeyHeld && bKeyPressed) // short pressed - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + if (gInputBoxIndex > 0) { + if (!bKeyHeld && bKeyPressed) // short pressed + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } - if (bKeyHeld || !bKeyPressed) { // held or released - if (bKeyHeld || bKeyPressed) { // held or pressed (cannot be held and not pressed I guess, so it checks only if HELD?) - if (!bKeyHeld) // won't ever pass - return; + if (bKeyHeld || !bKeyPressed) { // held or released + if (bKeyHeld || bKeyPressed) { // held or pressed (cannot be held and not pressed I guess, so it checks only if HELD?) + if (!bKeyHeld) // won't ever pass + return; - if (!bKeyPressed) // won't ever pass - return; + if (!bKeyPressed) // won't ever pass + return; - COMMON_KeypadLockToggle(); - } - else { // released + COMMON_KeypadLockToggle(); + } + else { // released #ifdef ENABLE_FMRADIO - if ((gFmRadioMode || gScreenToDisplay != DISPLAY_MAIN) && gScreenToDisplay != DISPLAY_FM) - return; + if ((gFmRadioMode || gScreenToDisplay != DISPLAY_MAIN) && gScreenToDisplay != DISPLAY_FM) + return; #else - if (gScreenToDisplay != DISPLAY_MAIN) - return; + if (gScreenToDisplay != DISPLAY_MAIN) + return; #endif - gWasFKeyPressed = !gWasFKeyPressed; // toggle F function + gWasFKeyPressed = !gWasFKeyPressed; // toggle F function - if (gWasFKeyPressed) - gKeyInputCountdown = key_input_timeout_500ms; + if (gWasFKeyPressed) + gKeyInputCountdown = key_input_timeout_500ms; #ifdef ENABLE_VOICE - if (!gWasFKeyPressed) - gAnotherVoiceID = VOICE_ID_CANCEL; + if (!gWasFKeyPressed) + gAnotherVoiceID = VOICE_ID_CANCEL; #endif - gUpdateStatus = true; - } - } - else { // short pressed + gUpdateStatus = true; + } + } + else { // short pressed #ifdef ENABLE_FMRADIO - if (gScreenToDisplay != DISPLAY_FM) + if (gScreenToDisplay != DISPLAY_FM) #endif - { - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - return; - } + { + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + return; + } #ifdef ENABLE_FMRADIO - if (gFM_ScanState == FM_SCAN_OFF) { // not scanning - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - return; - } + if (gFM_ScanState == FM_SCAN_OFF) { // not scanning + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + return; + } #endif - gBeepToPlay = BEEP_440HZ_500MS; - gPttWasReleased = true; - } + gBeepToPlay = BEEP_440HZ_500MS; + gPttWasReleased = true; + } } void GENERIC_Key_PTT(bool bKeyPressed) { - gInputBoxIndex = 0; + gInputBoxIndex = 0; - if (!bKeyPressed || SerialConfigInProgress()) - { // PTT released - if (gCurrentFunction == FUNCTION_TRANSMIT) { - // we are transmitting .. stop - if (gFlagEndTransmission) { - FUNCTION_Select(FUNCTION_FOREGROUND); - } - else { - APP_EndTransmission(); + if (!bKeyPressed || SerialConfigInProgress()) + { // PTT released + if (gCurrentFunction == FUNCTION_TRANSMIT) { + // we are transmitting .. stop + if (gFlagEndTransmission) { + FUNCTION_Select(FUNCTION_FOREGROUND); + } + else { + APP_EndTransmission(); - if (gEeprom.REPEATER_TAIL_TONE_ELIMINATION == 0) - FUNCTION_Select(FUNCTION_FOREGROUND); - else - gRTTECountdown_10ms = gEeprom.REPEATER_TAIL_TONE_ELIMINATION * 10; - } + if (gEeprom.REPEATER_TAIL_TONE_ELIMINATION == 0) + FUNCTION_Select(FUNCTION_FOREGROUND); + else + gRTTECountdown_10ms = gEeprom.REPEATER_TAIL_TONE_ELIMINATION * 10; + } - gFlagEndTransmission = false; + gFlagEndTransmission = false; #ifdef ENABLE_VOX - gVOX_NoiseDetected = false; + gVOX_NoiseDetected = false; #endif - RADIO_SetVfoState(VFO_STATE_NORMAL); + RADIO_SetVfoState(VFO_STATE_NORMAL); - if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu - gRequestDisplayScreen = DISPLAY_MAIN; - } + if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu + gRequestDisplayScreen = DISPLAY_MAIN; + } - return; - } + return; + } - // PTT pressed + // PTT pressed - if (SCANNER_IsScanning()) { - SCANNER_Stop(); // CTCSS/CDCSS scanning .. stop - goto cancel_tx; - } + if (SCANNER_IsScanning()) { + SCANNER_Stop(); // CTCSS/CDCSS scanning .. stop + goto cancel_tx; + } - if (gScanStateDir != SCAN_OFF) { - CHFRSCANNER_Stop(); // frequency/channel scanning . .stop - goto cancel_tx; - } + if (gScanStateDir != SCAN_OFF) { + CHFRSCANNER_Stop(); // frequency/channel scanning . .stop + goto cancel_tx; + } #ifdef ENABLE_FMRADIO - if (gFM_ScanState != FM_SCAN_OFF) { // FM radio is scanning .. stop - FM_PlayAndUpdate(); + if (gFM_ScanState != FM_SCAN_OFF) { // FM radio is scanning .. stop + FM_PlayAndUpdate(); #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_SCANNING_STOP; + gAnotherVoiceID = VOICE_ID_SCANNING_STOP; #endif - gRequestDisplayScreen = DISPLAY_FM; - goto cancel_tx; - } + gRequestDisplayScreen = DISPLAY_FM; + goto cancel_tx; + } #endif #ifdef ENABLE_FMRADIO - if (gScreenToDisplay == DISPLAY_FM) - goto start_tx; // listening to the FM radio .. start TX'ing + if (gScreenToDisplay == DISPLAY_FM) + goto start_tx; // listening to the FM radio .. start TX'ing #endif - if (gCurrentFunction == FUNCTION_TRANSMIT && gRTTECountdown_10ms == 0) {// already transmitting - gInputBoxIndex = 0; - return; - } + if (gCurrentFunction == FUNCTION_TRANSMIT && gRTTECountdown_10ms == 0) {// already transmitting + gInputBoxIndex = 0; + return; + } - if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu - gRequestDisplayScreen = DISPLAY_MAIN; + if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu + gRequestDisplayScreen = DISPLAY_MAIN; - if (!gDTMF_InputMode && gDTMF_InputBox_Index == 0) - goto start_tx; // wasn't entering a DTMF code .. start TX'ing (maybe) + if (!gDTMF_InputMode && gDTMF_InputBox_Index == 0) + goto start_tx; // wasn't entering a DTMF code .. start TX'ing (maybe) - // was entering a DTMF string + // was entering a DTMF string - if (gDTMF_InputBox_Index > 0 || gDTMF_PreviousIndex > 0) { // going to transmit a DTMF string - if (gDTMF_InputBox_Index == 0 && gDTMF_PreviousIndex > 0) - gDTMF_InputBox_Index = gDTMF_PreviousIndex; // use the previous DTMF string + if (gDTMF_InputBox_Index > 0 || gDTMF_PreviousIndex > 0) { // going to transmit a DTMF string + if (gDTMF_InputBox_Index == 0 && gDTMF_PreviousIndex > 0) + gDTMF_InputBox_Index = gDTMF_PreviousIndex; // use the previous DTMF string - if (gDTMF_InputBox_Index < sizeof(gDTMF_InputBox)) - gDTMF_InputBox[gDTMF_InputBox_Index] = 0; // NULL term the string + if (gDTMF_InputBox_Index < sizeof(gDTMF_InputBox)) + gDTMF_InputBox[gDTMF_InputBox_Index] = 0; // NULL term the string #ifdef ENABLE_DTMF_CALLING - // append our DTMF ID to the inputted DTMF code - - // IF the user inputted code is exactly 3 digits long and D-DCD is enabled - if (gDTMF_InputBox_Index == 3 && gTxVfo->DTMF_DECODING_ENABLE > 0) - gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3); - else - gDTMF_CallMode = DTMF_CALL_MODE_DTMF; + // append our DTMF ID to the inputted DTMF code - + // IF the user inputted code is exactly 3 digits long and D-DCD is enabled + if (gDTMF_InputBox_Index == 3 && gTxVfo->DTMF_DECODING_ENABLE > 0) + gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3); + else + gDTMF_CallMode = DTMF_CALL_MODE_DTMF; - gDTMF_State = DTMF_STATE_0; + gDTMF_State = DTMF_STATE_0; #endif - // remember the DTMF string - gDTMF_PreviousIndex = gDTMF_InputBox_Index; - strcpy(gDTMF_String, gDTMF_InputBox); - gDTMF_ReplyState = DTMF_REPLY_ANI; - } + // remember the DTMF string + gDTMF_PreviousIndex = gDTMF_InputBox_Index; + strcpy(gDTMF_String, gDTMF_InputBox); + gDTMF_ReplyState = DTMF_REPLY_ANI; + } - DTMF_clear_input_box(); + DTMF_clear_input_box(); start_tx: - // request start TX - gFlagPrepareTX = true; - goto done; + // request start TX + gFlagPrepareTX = true; + goto done; cancel_tx: - if (gPttIsPressed) { - gPttWasPressed = true; - } + if (gPttIsPressed) { + gPttWasPressed = true; + } done: - gPttDebounceCounter = 0; - if (gScreenToDisplay != DISPLAY_MENU + gPttDebounceCounter = 0; + if (gScreenToDisplay != DISPLAY_MENU #ifdef ENABLE_FMRADIO - && gRequestDisplayScreen != DISPLAY_FM + && gRequestDisplayScreen != DISPLAY_FM #endif - ) { - // 1of11 .. don't close the menu - gRequestDisplayScreen = DISPLAY_MAIN; - } + ) { + // 1of11 .. don't close the menu + gRequestDisplayScreen = DISPLAY_MAIN; + } - gUpdateStatus = true; - gUpdateDisplay = true; + gUpdateStatus = true; + gUpdateDisplay = true; } diff --git a/app/menu.c b/app/menu.c index bc07c38..52987c9 100644 --- a/app/menu.c +++ b/app/menu.c @@ -17,7 +17,7 @@ #include #if !defined(ENABLE_OVERLAY) - #include "ARMCM0.h" + #include "ARMCM0.h" #endif #include "app/dtmf.h" #include "app/generic.h" @@ -36,1908 +36,1908 @@ #include "misc.h" #include "settings.h" #if defined(ENABLE_OVERLAY) - #include "sram-overlay.h" + #include "sram-overlay.h" #endif #include "ui/inputbox.h" #include "ui/menu.h" #include "ui/ui.h" #ifndef ARRAY_SIZE - #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif uint8_t gUnlockAllTxConfCnt; #ifdef ENABLE_F_CAL_MENU - void writeXtalFreqCal(const int32_t value, const bool update_eeprom) - { - BK4819_WriteRegister(BK4819_REG_3B, 22656 + value); + void writeXtalFreqCal(const int32_t value, const bool update_eeprom) + { + BK4819_WriteRegister(BK4819_REG_3B, 22656 + value); - if (update_eeprom) - { - struct - { - int16_t BK4819_XtalFreqLow; - uint16_t EEPROM_1F8A; - uint16_t EEPROM_1F8C; - uint8_t VOLUME_GAIN; - uint8_t DAC_GAIN; - } __attribute__((packed)) misc; + if (update_eeprom) + { + struct + { + int16_t BK4819_XtalFreqLow; + uint16_t EEPROM_1F8A; + uint16_t EEPROM_1F8C; + uint8_t VOLUME_GAIN; + uint8_t DAC_GAIN; + } __attribute__((packed)) misc; - gEeprom.BK4819_XTAL_FREQ_LOW = value; + gEeprom.BK4819_XTAL_FREQ_LOW = value; - // radio 1 .. 04 00 46 00 50 00 2C 0E - // radio 2 .. 05 00 46 00 50 00 2C 0E - // - EEPROM_ReadBuffer(0x1F88, &misc, 8); - misc.BK4819_XtalFreqLow = value; - EEPROM_WriteBuffer(0x1F88, &misc); - } - } + // radio 1 .. 04 00 46 00 50 00 2C 0E + // radio 2 .. 05 00 46 00 50 00 2C 0E + // + EEPROM_ReadBuffer(0x1F88, &misc, 8); + misc.BK4819_XtalFreqLow = value; + EEPROM_WriteBuffer(0x1F88, &misc); + } + } #endif void MENU_StartCssScan(void) { - SCANNER_Start(true); - gUpdateStatus = true; - gCssBackgroundScan = true; + SCANNER_Start(true); + gUpdateStatus = true; + gCssBackgroundScan = true; - gRequestDisplayScreen = DISPLAY_MENU; + gRequestDisplayScreen = DISPLAY_MENU; } void MENU_CssScanFound(void) { - if(gScanCssResultType == CODE_TYPE_DIGITAL || gScanCssResultType == CODE_TYPE_REVERSE_DIGITAL) { - gMenuCursor = UI_MENU_GetMenuIdx(MENU_R_DCS); - } - else if(gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) { - gMenuCursor = UI_MENU_GetMenuIdx(MENU_R_CTCS); - } + if(gScanCssResultType == CODE_TYPE_DIGITAL || gScanCssResultType == CODE_TYPE_REVERSE_DIGITAL) { + gMenuCursor = UI_MENU_GetMenuIdx(MENU_R_DCS); + } + else if(gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) { + gMenuCursor = UI_MENU_GetMenuIdx(MENU_R_CTCS); + } - MENU_ShowCurrentSetting(); + MENU_ShowCurrentSetting(); - gUpdateStatus = true; - gUpdateDisplay = true; + gUpdateStatus = true; + gUpdateDisplay = true; } void MENU_StopCssScan(void) { - gCssBackgroundScan = false; + gCssBackgroundScan = false; #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_SCANNING_STOP; + gAnotherVoiceID = VOICE_ID_SCANNING_STOP; #endif - gUpdateDisplay = true; - gUpdateStatus = true; + gUpdateDisplay = true; + gUpdateStatus = true; } int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax) { - *pMin = 0; + *pMin = 0; - switch (menu_id) - { - case MENU_SQL: - //*pMin = 0; - *pMax = 9; - break; + switch (menu_id) + { + case MENU_SQL: + //*pMin = 0; + *pMax = 9; + break; - case MENU_STEP: - //*pMin = 0; - *pMax = STEP_N_ELEM - 1; - break; + case MENU_STEP: + //*pMin = 0; + *pMax = STEP_N_ELEM - 1; + break; - case MENU_ABR: - //*pMin = 0; - *pMax = 61; - break; + case MENU_ABR: + //*pMin = 0; + *pMax = 61; + break; - case MENU_ABR_MIN: - //*pMin = 0; - *pMax = 9; - break; + case MENU_ABR_MIN: + //*pMin = 0; + *pMax = 9; + break; - case MENU_ABR_MAX: - *pMin = 1; - *pMax = 10; - break; + case MENU_ABR_MAX: + *pMin = 1; + *pMax = 10; + break; - case MENU_F_LOCK: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_F_LOCK) - 1; - break; + case MENU_F_LOCK: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_F_LOCK) - 1; + break; - case MENU_MDF: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_MDF) - 1; - break; + case MENU_MDF: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_MDF) - 1; + break; - case MENU_TXP: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_TXP) - 1; - break; + case MENU_TXP: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_TXP) - 1; + break; - case MENU_SFT_D: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_SFT_D) - 1; - break; + case MENU_SFT_D: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_SFT_D) - 1; + break; - case MENU_TDR: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_RXMode) - 1; - break; + case MENU_TDR: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_RXMode) - 1; + break; - #ifdef ENABLE_VOICE - case MENU_VOICE: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_VOICE) - 1; - break; - #endif + #ifdef ENABLE_VOICE + case MENU_VOICE: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_VOICE) - 1; + break; + #endif - case MENU_SC_REV: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_SC_REV) - 1; - break; + case MENU_SC_REV: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_SC_REV) - 1; + break; - case MENU_ROGER: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_ROGER) - 1; - break; + case MENU_ROGER: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_ROGER) - 1; + break; - case MENU_PONMSG: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_PONMSG) - 1; - break; + case MENU_PONMSG: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_PONMSG) - 1; + break; - case MENU_R_DCS: - case MENU_T_DCS: - //*pMin = 0; - *pMax = 208; - //*pMax = (ARRAY_SIZE(DCS_Options) * 2); - break; + case MENU_R_DCS: + case MENU_T_DCS: + //*pMin = 0; + *pMax = 208; + //*pMax = (ARRAY_SIZE(DCS_Options) * 2); + break; - case MENU_R_CTCS: - case MENU_T_CTCS: - //*pMin = 0; - *pMax = ARRAY_SIZE(CTCSS_Options); - break; + case MENU_R_CTCS: + case MENU_T_CTCS: + //*pMin = 0; + *pMax = ARRAY_SIZE(CTCSS_Options); + break; - case MENU_W_N: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_W_N) - 1; - break; + case MENU_W_N: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_W_N) - 1; + break; - #ifdef ENABLE_ALARM - case MENU_AL_MOD: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_AL_MOD) - 1; - break; - #endif + #ifdef ENABLE_ALARM + case MENU_AL_MOD: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_AL_MOD) - 1; + break; + #endif - case MENU_RESET: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_RESET) - 1; - break; + case MENU_RESET: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_RESET) - 1; + break; - case MENU_COMPAND: - case MENU_ABR_ON_TX_RX: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_RX_TX) - 1; - break; + case MENU_COMPAND: + case MENU_ABR_ON_TX_RX: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_RX_TX) - 1; + break; - #ifndef ENABLE_FEAT_F4HWN - #ifdef ENABLE_AM_FIX - case MENU_AM_FIX: - #endif - #endif - #ifdef ENABLE_AUDIO_BAR - case MENU_MIC_BAR: - #endif - case MENU_BCL: - case MENU_BEEP: - case MENU_AUTOLK: - case MENU_S_ADD1: - case MENU_S_ADD2: - case MENU_S_ADD3: - case MENU_STE: - case MENU_D_ST: + #ifndef ENABLE_FEAT_F4HWN + #ifdef ENABLE_AM_FIX + case MENU_AM_FIX: + #endif + #endif + #ifdef ENABLE_AUDIO_BAR + case MENU_MIC_BAR: + #endif + case MENU_BCL: + case MENU_BEEP: + case MENU_AUTOLK: + case MENU_S_ADD1: + case MENU_S_ADD2: + case MENU_S_ADD3: + case MENU_STE: + case MENU_D_ST: #ifdef ENABLE_DTMF_CALLING - case MENU_D_DCD: + case MENU_D_DCD: #endif - case MENU_D_LIVE_DEC: - #ifdef ENABLE_NOAA - case MENU_NOAA_S: - #endif - case MENU_350TX: - case MENU_200TX: - case MENU_500TX: - case MENU_350EN: + case MENU_D_LIVE_DEC: + #ifdef ENABLE_NOAA + case MENU_NOAA_S: + #endif + case MENU_350TX: + case MENU_200TX: + case MENU_500TX: + case MENU_350EN: #ifndef ENABLE_FEAT_F4HWN - case MENU_SCREN: + case MENU_SCREN: #endif #ifdef ENABLE_FEAT_F4HWN - case MENU_SET_TMR: + case MENU_SET_TMR: #endif - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_OFF_ON) - 1; - break; - case MENU_AM: - //*pMin = 0; - *pMax = ARRAY_SIZE(gModulationStr) - 1; - break; + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_OFF_ON) - 1; + break; + case MENU_AM: + //*pMin = 0; + *pMax = ARRAY_SIZE(gModulationStr) - 1; + break; #ifndef ENABLE_FEAT_F4HWN - case MENU_SCR: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1; - break; + case MENU_SCR: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1; + break; #endif - case MENU_TOT: - //*pMin = 0; - *pMin = 5; - *pMax = 179; - break; + case MENU_TOT: + //*pMin = 0; + *pMin = 5; + *pMax = 179; + break; - #ifdef ENABLE_VOX - case MENU_VOX: - #endif - case MENU_RP_STE: - //*pMin = 0; - *pMax = 10; - break; + #ifdef ENABLE_VOX + case MENU_VOX: + #endif + case MENU_RP_STE: + //*pMin = 0; + *pMax = 10; + break; - case MENU_MEM_CH: - case MENU_1_CALL: - case MENU_DEL_CH: - case MENU_MEM_NAME: - //*pMin = 0; - *pMax = MR_CHANNEL_LAST; - break; + case MENU_MEM_CH: + case MENU_1_CALL: + case MENU_DEL_CH: + case MENU_MEM_NAME: + //*pMin = 0; + *pMax = MR_CHANNEL_LAST; + break; - case MENU_SLIST1: - case MENU_SLIST2: - case MENU_SLIST3: - *pMin = -1; - *pMax = MR_CHANNEL_LAST; - break; + case MENU_SLIST1: + case MENU_SLIST2: + case MENU_SLIST3: + *pMin = -1; + *pMax = MR_CHANNEL_LAST; + break; - case MENU_SAVE: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_SAVE) - 1; - break; + case MENU_SAVE: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_SAVE) - 1; + break; - case MENU_MIC: - //*pMin = 0; - *pMax = 4; - break; + case MENU_MIC: + //*pMin = 0; + *pMax = 4; + break; - case MENU_S_LIST: - //*pMin = 0; - *pMax = 5; - break; + case MENU_S_LIST: + //*pMin = 0; + *pMax = 5; + break; #ifdef ENABLE_DTMF_CALLING - case MENU_D_RSP: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_D_RSP) - 1; - break; + case MENU_D_RSP: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_D_RSP) - 1; + break; #endif - case MENU_PTT_ID: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_PTT_ID) - 1; - break; + case MENU_PTT_ID: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_PTT_ID) - 1; + break; - case MENU_BAT_TXT: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_BAT_TXT) - 1; - break; + case MENU_BAT_TXT: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_BAT_TXT) - 1; + break; #ifdef ENABLE_DTMF_CALLING - case MENU_D_HOLD: - *pMin = 5; - *pMax = 60; - break; + case MENU_D_HOLD: + *pMin = 5; + *pMax = 60; + break; #endif - case MENU_D_PRE: - *pMin = 3; - *pMax = 99; - break; + case MENU_D_PRE: + *pMin = 3; + *pMax = 99; + break; #ifdef ENABLE_DTMF_CALLING - case MENU_D_LIST: - *pMin = 1; - *pMax = 16; - break; + case MENU_D_LIST: + *pMin = 1; + *pMax = 16; + break; #endif - #ifdef ENABLE_F_CAL_MENU - case MENU_F_CALI: - *pMin = -50; - *pMax = +50; - break; - #endif + #ifdef ENABLE_F_CAL_MENU + case MENU_F_CALI: + *pMin = -50; + *pMax = +50; + break; + #endif - case MENU_BATCAL: - *pMin = 1600; - *pMax = 2200; - break; + case MENU_BATCAL: + *pMin = 1600; + *pMax = 2200; + break; - case MENU_BATTYP: - //*pMin = 0; - *pMax = 2; - break; + case MENU_BATTYP: + //*pMin = 0; + *pMax = 2; + break; - case MENU_F1SHRT: - case MENU_F1LONG: - case MENU_F2SHRT: - case MENU_F2LONG: - case MENU_MLONG: - //*pMin = 0; - *pMax = gSubMenu_SIDEFUNCTIONS_size-1; - break; + case MENU_F1SHRT: + case MENU_F1LONG: + case MENU_F2SHRT: + case MENU_F2LONG: + case MENU_MLONG: + //*pMin = 0; + *pMax = gSubMenu_SIDEFUNCTIONS_size-1; + break; #ifdef ENABLE_FEAT_F4HWN - case MENU_SET_PWR: - *pMax = ARRAY_SIZE(gSubMenu_SET_PWR) - 1; - break; - case MENU_SET_PTT: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_SET_PTT) - 1; - break; - case MENU_SET_TOT: - case MENU_SET_EOT: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_SET_TOT) - 1; - break; - case MENU_SET_CTR: - *pMin = 1; - *pMax = 15; - break; - case MENU_TX_LOCK: + case MENU_SET_PWR: + *pMax = ARRAY_SIZE(gSubMenu_SET_PWR) - 1; + break; + case MENU_SET_PTT: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_SET_PTT) - 1; + break; + case MENU_SET_TOT: + case MENU_SET_EOT: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_SET_TOT) - 1; + break; + case MENU_SET_CTR: + *pMin = 1; + *pMax = 15; + break; + case MENU_TX_LOCK: case MENU_SET_INV: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_OFF_ON) - 1; - break; - case MENU_SET_LCK: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_SET_LCK) - 1; - break; - case MENU_SET_MET: - case MENU_SET_GUI: - //*pMin = 0; - *pMax = ARRAY_SIZE(gSubMenu_SET_MET) - 1; - break; + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_OFF_ON) - 1; + break; + case MENU_SET_LCK: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_SET_LCK) - 1; + break; + case MENU_SET_MET: + case MENU_SET_GUI: + //*pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_SET_MET) - 1; + break; #endif - default: - return -1; - } + default: + return -1; + } - return 0; + return 0; } void MENU_AcceptSetting(void) { - int32_t Min; - int32_t Max; - FREQ_Config_t *pConfig = &gTxVfo->freq_config_RX; + int32_t Min; + int32_t Max; + FREQ_Config_t *pConfig = &gTxVfo->freq_config_RX; - if (!MENU_GetLimits(UI_MENU_GetCurrentMenuId(), &Min, &Max)) - { - if (gSubMenuSelection < Min) gSubMenuSelection = Min; - else - if (gSubMenuSelection > Max) gSubMenuSelection = Max; - } + if (!MENU_GetLimits(UI_MENU_GetCurrentMenuId(), &Min, &Max)) + { + if (gSubMenuSelection < Min) gSubMenuSelection = Min; + else + if (gSubMenuSelection > Max) gSubMenuSelection = Max; + } - switch (UI_MENU_GetCurrentMenuId()) - { - default: - return; + switch (UI_MENU_GetCurrentMenuId()) + { + default: + return; - case MENU_SQL: - gEeprom.SQUELCH_LEVEL = gSubMenuSelection; - gVfoConfigureMode = VFO_CONFIGURE; - break; + case MENU_SQL: + gEeprom.SQUELCH_LEVEL = gSubMenuSelection; + gVfoConfigureMode = VFO_CONFIGURE; + break; - case MENU_STEP: - gTxVfo->STEP_SETTING = FREQUENCY_GetStepIdxFromSortedIdx(gSubMenuSelection); - if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) - { - gRequestSaveChannel = 1; - } - return; + case MENU_STEP: + gTxVfo->STEP_SETTING = FREQUENCY_GetStepIdxFromSortedIdx(gSubMenuSelection); + if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) + { + gRequestSaveChannel = 1; + } + return; - case MENU_TXP: - gTxVfo->OUTPUT_POWER = gSubMenuSelection; - gRequestSaveChannel = 1; - return; + case MENU_TXP: + gTxVfo->OUTPUT_POWER = gSubMenuSelection; + gRequestSaveChannel = 1; + return; - case MENU_T_DCS: - pConfig = &gTxVfo->freq_config_TX; + case MENU_T_DCS: + pConfig = &gTxVfo->freq_config_TX; - // Fallthrough + // Fallthrough - case MENU_R_DCS: { - if (gSubMenuSelection == 0) { - if (pConfig->CodeType == CODE_TYPE_CONTINUOUS_TONE) { - return; - } - pConfig->Code = 0; - pConfig->CodeType = CODE_TYPE_OFF; - } - else if (gSubMenuSelection < 105) { - pConfig->CodeType = CODE_TYPE_DIGITAL; - pConfig->Code = gSubMenuSelection - 1; - } - else { - pConfig->CodeType = CODE_TYPE_REVERSE_DIGITAL; - pConfig->Code = gSubMenuSelection - 105; - } + case MENU_R_DCS: { + if (gSubMenuSelection == 0) { + if (pConfig->CodeType == CODE_TYPE_CONTINUOUS_TONE) { + return; + } + pConfig->Code = 0; + pConfig->CodeType = CODE_TYPE_OFF; + } + else if (gSubMenuSelection < 105) { + pConfig->CodeType = CODE_TYPE_DIGITAL; + pConfig->Code = gSubMenuSelection - 1; + } + else { + pConfig->CodeType = CODE_TYPE_REVERSE_DIGITAL; + pConfig->Code = gSubMenuSelection - 105; + } - gRequestSaveChannel = 1; - return; - } - case MENU_T_CTCS: - pConfig = &gTxVfo->freq_config_TX; - [[fallthrough]]; - case MENU_R_CTCS: { - if (gSubMenuSelection == 0) { - if (pConfig->CodeType != CODE_TYPE_CONTINUOUS_TONE) { - return; - } - pConfig->Code = 0; - pConfig->CodeType = CODE_TYPE_OFF; - } - else { - pConfig->Code = gSubMenuSelection - 1; - pConfig->CodeType = CODE_TYPE_CONTINUOUS_TONE; - } + gRequestSaveChannel = 1; + return; + } + case MENU_T_CTCS: + pConfig = &gTxVfo->freq_config_TX; + [[fallthrough]]; + case MENU_R_CTCS: { + if (gSubMenuSelection == 0) { + if (pConfig->CodeType != CODE_TYPE_CONTINUOUS_TONE) { + return; + } + pConfig->Code = 0; + pConfig->CodeType = CODE_TYPE_OFF; + } + else { + pConfig->Code = gSubMenuSelection - 1; + pConfig->CodeType = CODE_TYPE_CONTINUOUS_TONE; + } - gRequestSaveChannel = 1; - return; - } - case MENU_SFT_D: - gTxVfo->TX_OFFSET_FREQUENCY_DIRECTION = gSubMenuSelection; - gRequestSaveChannel = 1; - return; + gRequestSaveChannel = 1; + return; + } + case MENU_SFT_D: + gTxVfo->TX_OFFSET_FREQUENCY_DIRECTION = gSubMenuSelection; + gRequestSaveChannel = 1; + return; - case MENU_OFFSET: - gTxVfo->TX_OFFSET_FREQUENCY = gSubMenuSelection; - gRequestSaveChannel = 1; - return; + case MENU_OFFSET: + gTxVfo->TX_OFFSET_FREQUENCY = gSubMenuSelection; + gRequestSaveChannel = 1; + return; - case MENU_W_N: - gTxVfo->CHANNEL_BANDWIDTH = gSubMenuSelection; - gRequestSaveChannel = 1; - return; + case MENU_W_N: + gTxVfo->CHANNEL_BANDWIDTH = gSubMenuSelection; + gRequestSaveChannel = 1; + return; #ifndef ENABLE_FEAT_F4HWN - case MENU_SCR: - gTxVfo->SCRAMBLING_TYPE = gSubMenuSelection; - #if 0 - if (gSubMenuSelection > 0 && gSetting_ScrambleEnable) - BK4819_EnableScramble(gSubMenuSelection - 1); - else - BK4819_DisableScramble(); - #endif - gRequestSaveChannel = 1; - return; + case MENU_SCR: + gTxVfo->SCRAMBLING_TYPE = gSubMenuSelection; + #if 0 + if (gSubMenuSelection > 0 && gSetting_ScrambleEnable) + BK4819_EnableScramble(gSubMenuSelection - 1); + else + BK4819_DisableScramble(); + #endif + gRequestSaveChannel = 1; + return; #endif - case MENU_BCL: - gTxVfo->BUSY_CHANNEL_LOCK = gSubMenuSelection; - gRequestSaveChannel = 1; - return; + case MENU_BCL: + gTxVfo->BUSY_CHANNEL_LOCK = gSubMenuSelection; + gRequestSaveChannel = 1; + return; - case MENU_MEM_CH: - gTxVfo->CHANNEL_SAVE = gSubMenuSelection; - #if 0 - gEeprom.MrChannel[0] = gSubMenuSelection; - #else - gEeprom.MrChannel[gEeprom.TX_VFO] = gSubMenuSelection; - #endif - gRequestSaveChannel = 2; - gVfoConfigureMode = VFO_CONFIGURE_RELOAD; - gFlagResetVfos = true; - return; + case MENU_MEM_CH: + gTxVfo->CHANNEL_SAVE = gSubMenuSelection; + #if 0 + gEeprom.MrChannel[0] = gSubMenuSelection; + #else + gEeprom.MrChannel[gEeprom.TX_VFO] = gSubMenuSelection; + #endif + gRequestSaveChannel = 2; + gVfoConfigureMode = VFO_CONFIGURE_RELOAD; + gFlagResetVfos = true; + return; - case MENU_MEM_NAME: - for (int i = 9; i >= 0; i--) { - if (edit[i] != ' ' && edit[i] != '_' && edit[i] != 0x00 && edit[i] != 0xff) - break; - edit[i] = ' '; - } + case MENU_MEM_NAME: + for (int i = 9; i >= 0; i--) { + if (edit[i] != ' ' && edit[i] != '_' && edit[i] != 0x00 && edit[i] != 0xff) + break; + edit[i] = ' '; + } - SETTINGS_SaveChannelName(gSubMenuSelection, edit); - return; + SETTINGS_SaveChannelName(gSubMenuSelection, edit); + return; - case MENU_SAVE: - gEeprom.BATTERY_SAVE = gSubMenuSelection; - break; + case MENU_SAVE: + gEeprom.BATTERY_SAVE = gSubMenuSelection; + break; - #ifdef ENABLE_VOX - case MENU_VOX: - gEeprom.VOX_SWITCH = gSubMenuSelection != 0; - if (gEeprom.VOX_SWITCH) - gEeprom.VOX_LEVEL = gSubMenuSelection - 1; - SETTINGS_LoadCalibration(); - gFlagReconfigureVfos = true; - gUpdateStatus = true; - break; - #endif + #ifdef ENABLE_VOX + case MENU_VOX: + gEeprom.VOX_SWITCH = gSubMenuSelection != 0; + if (gEeprom.VOX_SWITCH) + gEeprom.VOX_LEVEL = gSubMenuSelection - 1; + SETTINGS_LoadCalibration(); + gFlagReconfigureVfos = true; + gUpdateStatus = true; + break; + #endif - case MENU_ABR: - gEeprom.BACKLIGHT_TIME = gSubMenuSelection; - #ifdef ENABLE_FEAT_F4HWN - gBackLight = false; - #endif - break; + case MENU_ABR: + gEeprom.BACKLIGHT_TIME = gSubMenuSelection; + #ifdef ENABLE_FEAT_F4HWN + gBackLight = false; + #endif + break; - case MENU_ABR_MIN: - gEeprom.BACKLIGHT_MIN = gSubMenuSelection; - gEeprom.BACKLIGHT_MAX = MAX(gSubMenuSelection + 1 , gEeprom.BACKLIGHT_MAX); - break; + case MENU_ABR_MIN: + gEeprom.BACKLIGHT_MIN = gSubMenuSelection; + gEeprom.BACKLIGHT_MAX = MAX(gSubMenuSelection + 1 , gEeprom.BACKLIGHT_MAX); + break; - case MENU_ABR_MAX: - gEeprom.BACKLIGHT_MAX = gSubMenuSelection; - gEeprom.BACKLIGHT_MIN = MIN(gSubMenuSelection - 1, gEeprom.BACKLIGHT_MIN); - break; + case MENU_ABR_MAX: + gEeprom.BACKLIGHT_MAX = gSubMenuSelection; + gEeprom.BACKLIGHT_MIN = MIN(gSubMenuSelection - 1, gEeprom.BACKLIGHT_MIN); + break; - case MENU_ABR_ON_TX_RX: - gSetting_backlight_on_tx_rx = gSubMenuSelection; - break; + case MENU_ABR_ON_TX_RX: + gSetting_backlight_on_tx_rx = gSubMenuSelection; + break; - case MENU_TDR: - gEeprom.DUAL_WATCH = (gEeprom.TX_VFO + 1) * (gSubMenuSelection & 1); - gEeprom.CROSS_BAND_RX_TX = (gEeprom.TX_VFO + 1) * ((gSubMenuSelection & 2) > 0); + case MENU_TDR: + gEeprom.DUAL_WATCH = (gEeprom.TX_VFO + 1) * (gSubMenuSelection & 1); + gEeprom.CROSS_BAND_RX_TX = (gEeprom.TX_VFO + 1) * ((gSubMenuSelection & 2) > 0); - #ifdef ENABLE_FEAT_F4HWN - gDW = gEeprom.DUAL_WATCH; - gCB = gEeprom.CROSS_BAND_RX_TX; - gSaveRxMode = true; - #endif + #ifdef ENABLE_FEAT_F4HWN + gDW = gEeprom.DUAL_WATCH; + gCB = gEeprom.CROSS_BAND_RX_TX; + gSaveRxMode = true; + #endif - gFlagReconfigureVfos = true; - gUpdateStatus = true; - break; + gFlagReconfigureVfos = true; + gUpdateStatus = true; + break; - case MENU_BEEP: - gEeprom.BEEP_CONTROL = gSubMenuSelection; - break; + case MENU_BEEP: + gEeprom.BEEP_CONTROL = gSubMenuSelection; + break; - case MENU_TOT: - gEeprom.TX_TIMEOUT_TIMER = gSubMenuSelection; - break; + case MENU_TOT: + gEeprom.TX_TIMEOUT_TIMER = gSubMenuSelection; + break; - #ifdef ENABLE_VOICE - case MENU_VOICE: - gEeprom.VOICE_PROMPT = gSubMenuSelection; - gUpdateStatus = true; - break; - #endif + #ifdef ENABLE_VOICE + case MENU_VOICE: + gEeprom.VOICE_PROMPT = gSubMenuSelection; + gUpdateStatus = true; + break; + #endif - case MENU_SC_REV: - gEeprom.SCAN_RESUME_MODE = gSubMenuSelection; - break; + case MENU_SC_REV: + gEeprom.SCAN_RESUME_MODE = gSubMenuSelection; + break; - case MENU_MDF: - gEeprom.CHANNEL_DISPLAY_MODE = gSubMenuSelection; - break; + case MENU_MDF: + gEeprom.CHANNEL_DISPLAY_MODE = gSubMenuSelection; + break; - case MENU_AUTOLK: - gEeprom.AUTO_KEYPAD_LOCK = gSubMenuSelection; - gKeyLockCountdown = 30; - break; + case MENU_AUTOLK: + gEeprom.AUTO_KEYPAD_LOCK = gSubMenuSelection; + gKeyLockCountdown = 30; + break; - case MENU_S_ADD1: - gTxVfo->SCANLIST1_PARTICIPATION = gSubMenuSelection; - SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, false, true); - gVfoConfigureMode = VFO_CONFIGURE; - gFlagResetVfos = true; - return; + case MENU_S_ADD1: + gTxVfo->SCANLIST1_PARTICIPATION = gSubMenuSelection; + SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, false, true); + gVfoConfigureMode = VFO_CONFIGURE; + gFlagResetVfos = true; + return; - case MENU_S_ADD2: - gTxVfo->SCANLIST2_PARTICIPATION = gSubMenuSelection; - SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, false, true); - gVfoConfigureMode = VFO_CONFIGURE; - gFlagResetVfos = true; - return; + case MENU_S_ADD2: + gTxVfo->SCANLIST2_PARTICIPATION = gSubMenuSelection; + SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, false, true); + gVfoConfigureMode = VFO_CONFIGURE; + gFlagResetVfos = true; + return; - case MENU_S_ADD3: - gTxVfo->SCANLIST3_PARTICIPATION = gSubMenuSelection; - SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, false, true); - gVfoConfigureMode = VFO_CONFIGURE; - gFlagResetVfos = true; - return; + case MENU_S_ADD3: + gTxVfo->SCANLIST3_PARTICIPATION = gSubMenuSelection; + SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, false, true); + gVfoConfigureMode = VFO_CONFIGURE; + gFlagResetVfos = true; + return; - case MENU_STE: - gEeprom.TAIL_TONE_ELIMINATION = gSubMenuSelection; - break; + case MENU_STE: + gEeprom.TAIL_TONE_ELIMINATION = gSubMenuSelection; + break; - case MENU_RP_STE: - gEeprom.REPEATER_TAIL_TONE_ELIMINATION = gSubMenuSelection; - break; + case MENU_RP_STE: + gEeprom.REPEATER_TAIL_TONE_ELIMINATION = gSubMenuSelection; + break; - case MENU_MIC: - gEeprom.MIC_SENSITIVITY = gSubMenuSelection; - SETTINGS_LoadCalibration(); - gFlagReconfigureVfos = true; - break; + case MENU_MIC: + gEeprom.MIC_SENSITIVITY = gSubMenuSelection; + SETTINGS_LoadCalibration(); + gFlagReconfigureVfos = true; + break; - #ifdef ENABLE_AUDIO_BAR - case MENU_MIC_BAR: - gSetting_mic_bar = gSubMenuSelection; - break; - #endif + #ifdef ENABLE_AUDIO_BAR + case MENU_MIC_BAR: + gSetting_mic_bar = gSubMenuSelection; + break; + #endif - case MENU_COMPAND: - gTxVfo->Compander = gSubMenuSelection; - SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, false, true); - gVfoConfigureMode = VFO_CONFIGURE; - gFlagResetVfos = true; -// gRequestSaveChannel = 1; - return; + case MENU_COMPAND: + gTxVfo->Compander = gSubMenuSelection; + SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, false, true); + gVfoConfigureMode = VFO_CONFIGURE; + gFlagResetVfos = true; +// gRequestSaveChannel = 1; + return; - case MENU_1_CALL: - gEeprom.CHAN_1_CALL = gSubMenuSelection; - break; + case MENU_1_CALL: + gEeprom.CHAN_1_CALL = gSubMenuSelection; + break; - case MENU_S_LIST: - gEeprom.SCAN_LIST_DEFAULT = gSubMenuSelection; - break; + case MENU_S_LIST: + gEeprom.SCAN_LIST_DEFAULT = gSubMenuSelection; + break; - #ifdef ENABLE_ALARM - case MENU_AL_MOD: - gEeprom.ALARM_MODE = gSubMenuSelection; - break; - #endif + #ifdef ENABLE_ALARM + case MENU_AL_MOD: + gEeprom.ALARM_MODE = gSubMenuSelection; + break; + #endif - case MENU_D_ST: - gEeprom.DTMF_SIDE_TONE = gSubMenuSelection; - break; + case MENU_D_ST: + gEeprom.DTMF_SIDE_TONE = gSubMenuSelection; + break; #ifdef ENABLE_DTMF_CALLING - case MENU_D_RSP: - gEeprom.DTMF_DECODE_RESPONSE = gSubMenuSelection; - break; + case MENU_D_RSP: + gEeprom.DTMF_DECODE_RESPONSE = gSubMenuSelection; + break; - case MENU_D_HOLD: - gEeprom.DTMF_auto_reset_time = gSubMenuSelection; - break; + case MENU_D_HOLD: + gEeprom.DTMF_auto_reset_time = gSubMenuSelection; + break; #endif - case MENU_D_PRE: - gEeprom.DTMF_PRELOAD_TIME = gSubMenuSelection * 10; - break; + case MENU_D_PRE: + gEeprom.DTMF_PRELOAD_TIME = gSubMenuSelection * 10; + break; - case MENU_PTT_ID: - gTxVfo->DTMF_PTT_ID_TX_MODE = gSubMenuSelection; - gRequestSaveChannel = 1; - return; + case MENU_PTT_ID: + gTxVfo->DTMF_PTT_ID_TX_MODE = gSubMenuSelection; + gRequestSaveChannel = 1; + return; - case MENU_BAT_TXT: - gSetting_battery_text = gSubMenuSelection; - break; + case MENU_BAT_TXT: + gSetting_battery_text = gSubMenuSelection; + break; #ifdef ENABLE_DTMF_CALLING - case MENU_D_DCD: - gTxVfo->DTMF_DECODING_ENABLE = gSubMenuSelection; - DTMF_clear_RX(); - gRequestSaveChannel = 1; - return; + case MENU_D_DCD: + gTxVfo->DTMF_DECODING_ENABLE = gSubMenuSelection; + DTMF_clear_RX(); + gRequestSaveChannel = 1; + return; #endif - case MENU_D_LIVE_DEC: - gSetting_live_DTMF_decoder = gSubMenuSelection; - gDTMF_RX_live_timeout = 0; - memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); - if (!gSetting_live_DTMF_decoder) - BK4819_DisableDTMF(); - gFlagReconfigureVfos = true; - gUpdateStatus = true; - break; + case MENU_D_LIVE_DEC: + gSetting_live_DTMF_decoder = gSubMenuSelection; + gDTMF_RX_live_timeout = 0; + memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); + if (!gSetting_live_DTMF_decoder) + BK4819_DisableDTMF(); + gFlagReconfigureVfos = true; + gUpdateStatus = true; + break; #ifdef ENABLE_DTMF_CALLING - case MENU_D_LIST: - gDTMF_chosen_contact = gSubMenuSelection - 1; - if (gIsDtmfContactValid) - { - GUI_SelectNextDisplay(DISPLAY_MAIN); - gDTMF_InputMode = true; - gDTMF_InputBox_Index = 3; - memcpy(gDTMF_InputBox, gDTMF_ID, 4); - gRequestDisplayScreen = DISPLAY_INVALID; - } - return; + case MENU_D_LIST: + gDTMF_chosen_contact = gSubMenuSelection - 1; + if (gIsDtmfContactValid) + { + GUI_SelectNextDisplay(DISPLAY_MAIN); + gDTMF_InputMode = true; + gDTMF_InputBox_Index = 3; + memcpy(gDTMF_InputBox, gDTMF_ID, 4); + gRequestDisplayScreen = DISPLAY_INVALID; + } + return; #endif - case MENU_PONMSG: - gEeprom.POWER_ON_DISPLAY_MODE = gSubMenuSelection; - break; + case MENU_PONMSG: + gEeprom.POWER_ON_DISPLAY_MODE = gSubMenuSelection; + break; - case MENU_ROGER: - gEeprom.ROGER = gSubMenuSelection; - break; + case MENU_ROGER: + gEeprom.ROGER = gSubMenuSelection; + break; - case MENU_AM: - gTxVfo->Modulation = gSubMenuSelection; - gRequestSaveChannel = 1; - return; + case MENU_AM: + gTxVfo->Modulation = gSubMenuSelection; + gRequestSaveChannel = 1; + return; - #ifndef ENABLE_FEAT_F4HWN - #ifdef ENABLE_AM_FIX - case MENU_AM_FIX: - gSetting_AM_fix = gSubMenuSelection; - gVfoConfigureMode = VFO_CONFIGURE_RELOAD; - gFlagResetVfos = true; - break; - #endif - #endif + #ifndef ENABLE_FEAT_F4HWN + #ifdef ENABLE_AM_FIX + case MENU_AM_FIX: + gSetting_AM_fix = gSubMenuSelection; + gVfoConfigureMode = VFO_CONFIGURE_RELOAD; + gFlagResetVfos = true; + break; + #endif + #endif - #ifdef ENABLE_NOAA - case MENU_NOAA_S: - gEeprom.NOAA_AUTO_SCAN = gSubMenuSelection; - gFlagReconfigureVfos = true; - break; - #endif + #ifdef ENABLE_NOAA + case MENU_NOAA_S: + gEeprom.NOAA_AUTO_SCAN = gSubMenuSelection; + gFlagReconfigureVfos = true; + break; + #endif - case MENU_DEL_CH: - SETTINGS_UpdateChannel(gSubMenuSelection, NULL, false, false, true); - gVfoConfigureMode = VFO_CONFIGURE_RELOAD; - gFlagResetVfos = true; - return; + case MENU_DEL_CH: + SETTINGS_UpdateChannel(gSubMenuSelection, NULL, false, false, true); + gVfoConfigureMode = VFO_CONFIGURE_RELOAD; + gFlagResetVfos = true; + return; - case MENU_RESET: - SETTINGS_FactoryReset(gSubMenuSelection); - return; + case MENU_RESET: + SETTINGS_FactoryReset(gSubMenuSelection); + return; - case MENU_350TX: - gSetting_350TX = gSubMenuSelection; - break; + case MENU_350TX: + gSetting_350TX = gSubMenuSelection; + break; - case MENU_F_LOCK: { - if(gSubMenuSelection == F_LOCK_NONE) { // select 10 times to enable - gUnlockAllTxConfCnt++; + case MENU_F_LOCK: { + if(gSubMenuSelection == F_LOCK_NONE) { // select 10 times to enable + gUnlockAllTxConfCnt++; #ifdef ENABLE_FEAT_F4HWN - if(gUnlockAllTxConfCnt < 3) + if(gUnlockAllTxConfCnt < 3) #else - if(gUnlockAllTxConfCnt < 10) + if(gUnlockAllTxConfCnt < 10) #endif - return; - } - else - gUnlockAllTxConfCnt = 0; + return; + } + else + gUnlockAllTxConfCnt = 0; - gSetting_F_LOCK = gSubMenuSelection; - break; - } - case MENU_200TX: - gSetting_200TX = gSubMenuSelection; - break; + gSetting_F_LOCK = gSubMenuSelection; + break; + } + case MENU_200TX: + gSetting_200TX = gSubMenuSelection; + break; - case MENU_500TX: - gSetting_500TX = gSubMenuSelection; - break; + case MENU_500TX: + gSetting_500TX = gSubMenuSelection; + break; - case MENU_350EN: - gSetting_350EN = gSubMenuSelection; - gVfoConfigureMode = VFO_CONFIGURE_RELOAD; - gFlagResetVfos = true; - break; + case MENU_350EN: + gSetting_350EN = gSubMenuSelection; + gVfoConfigureMode = VFO_CONFIGURE_RELOAD; + gFlagResetVfos = true; + break; #ifndef ENABLE_FEAT_F4HWN - case MENU_SCREN: - gSetting_ScrambleEnable = gSubMenuSelection; - gFlagReconfigureVfos = true; - break; + case MENU_SCREN: + gSetting_ScrambleEnable = gSubMenuSelection; + gFlagReconfigureVfos = true; + break; #endif - #ifdef ENABLE_F_CAL_MENU - case MENU_F_CALI: - writeXtalFreqCal(gSubMenuSelection, true); - return; - #endif + #ifdef ENABLE_F_CAL_MENU + case MENU_F_CALI: + writeXtalFreqCal(gSubMenuSelection, true); + return; + #endif - case MENU_BATCAL: - { // voltages are averages between discharge curves of 1600 and 2200 mAh - // gBatteryCalibration[0] = (520ul * gSubMenuSelection) / 760; // 5.20V empty, blinking above this value, reduced functionality below - // gBatteryCalibration[1] = (689ul * gSubMenuSelection) / 760; // 6.89V, ~5%, 1 bars above this value - // gBatteryCalibration[2] = (724ul * gSubMenuSelection) / 760; // 7.24V, ~17%, 2 bars above this value - gBatteryCalibration[3] = gSubMenuSelection; // 7.6V, ~29%, 3 bars above this value - // gBatteryCalibration[4] = (771ul * gSubMenuSelection) / 760; // 7.71V, ~65%, 4 bars above this value - // gBatteryCalibration[5] = 2300; - SETTINGS_SaveBatteryCalibration(gBatteryCalibration); - return; - } + case MENU_BATCAL: + { // voltages are averages between discharge curves of 1600 and 2200 mAh + // gBatteryCalibration[0] = (520ul * gSubMenuSelection) / 760; // 5.20V empty, blinking above this value, reduced functionality below + // gBatteryCalibration[1] = (689ul * gSubMenuSelection) / 760; // 6.89V, ~5%, 1 bars above this value + // gBatteryCalibration[2] = (724ul * gSubMenuSelection) / 760; // 7.24V, ~17%, 2 bars above this value + gBatteryCalibration[3] = gSubMenuSelection; // 7.6V, ~29%, 3 bars above this value + // gBatteryCalibration[4] = (771ul * gSubMenuSelection) / 760; // 7.71V, ~65%, 4 bars above this value + // gBatteryCalibration[5] = 2300; + SETTINGS_SaveBatteryCalibration(gBatteryCalibration); + return; + } - case MENU_BATTYP: - gEeprom.BATTERY_TYPE = gSubMenuSelection; - break; + case MENU_BATTYP: + gEeprom.BATTERY_TYPE = gSubMenuSelection; + break; - case MENU_F1SHRT: - case MENU_F1LONG: - case MENU_F2SHRT: - case MENU_F2LONG: - case MENU_MLONG: - { - uint8_t * fun[]= { - &gEeprom.KEY_1_SHORT_PRESS_ACTION, - &gEeprom.KEY_1_LONG_PRESS_ACTION, - &gEeprom.KEY_2_SHORT_PRESS_ACTION, - &gEeprom.KEY_2_LONG_PRESS_ACTION, - &gEeprom.KEY_M_LONG_PRESS_ACTION}; - *fun[UI_MENU_GetCurrentMenuId()-MENU_F1SHRT] = gSubMenu_SIDEFUNCTIONS[gSubMenuSelection].id; - } - break; + case MENU_F1SHRT: + case MENU_F1LONG: + case MENU_F2SHRT: + case MENU_F2LONG: + case MENU_MLONG: + { + uint8_t * fun[]= { + &gEeprom.KEY_1_SHORT_PRESS_ACTION, + &gEeprom.KEY_1_LONG_PRESS_ACTION, + &gEeprom.KEY_2_SHORT_PRESS_ACTION, + &gEeprom.KEY_2_LONG_PRESS_ACTION, + &gEeprom.KEY_M_LONG_PRESS_ACTION}; + *fun[UI_MENU_GetCurrentMenuId()-MENU_F1SHRT] = gSubMenu_SIDEFUNCTIONS[gSubMenuSelection].id; + } + break; #ifdef ENABLE_FEAT_F4HWN - case MENU_SET_PWR: - gSetting_set_pwr = gSubMenuSelection; - gRequestSaveChannel = 1; - break; - case MENU_SET_PTT: - gSetting_set_ptt = gSubMenuSelection; - gSetting_set_ptt_session = gSetting_set_ptt; // Special for action - break; - case MENU_SET_TOT: - gSetting_set_tot = gSubMenuSelection; - break; - case MENU_SET_EOT: - gSetting_set_eot = gSubMenuSelection; - break; - case MENU_SET_CTR: - gSetting_set_ctr = gSubMenuSelection; - break; - case MENU_SET_INV: - gSetting_set_inv = gSubMenuSelection; - break; - case MENU_SET_LCK: - gSetting_set_lck = gSubMenuSelection; - break; - case MENU_SET_MET: - gSetting_set_met = gSubMenuSelection; - break; - case MENU_SET_GUI: - gSetting_set_gui = gSubMenuSelection; - break; - case MENU_SET_TMR: - gSetting_set_tmr = gSubMenuSelection; - break; - case MENU_TX_LOCK: - gTxVfo->TX_LOCK = gSubMenuSelection; - gRequestSaveChannel = 1; - return; + case MENU_SET_PWR: + gSetting_set_pwr = gSubMenuSelection; + gRequestSaveChannel = 1; + break; + case MENU_SET_PTT: + gSetting_set_ptt = gSubMenuSelection; + gSetting_set_ptt_session = gSetting_set_ptt; // Special for action + break; + case MENU_SET_TOT: + gSetting_set_tot = gSubMenuSelection; + break; + case MENU_SET_EOT: + gSetting_set_eot = gSubMenuSelection; + break; + case MENU_SET_CTR: + gSetting_set_ctr = gSubMenuSelection; + break; + case MENU_SET_INV: + gSetting_set_inv = gSubMenuSelection; + break; + case MENU_SET_LCK: + gSetting_set_lck = gSubMenuSelection; + break; + case MENU_SET_MET: + gSetting_set_met = gSubMenuSelection; + break; + case MENU_SET_GUI: + gSetting_set_gui = gSubMenuSelection; + break; + case MENU_SET_TMR: + gSetting_set_tmr = gSubMenuSelection; + break; + case MENU_TX_LOCK: + gTxVfo->TX_LOCK = gSubMenuSelection; + gRequestSaveChannel = 1; + return; #endif - } + } - gRequestSaveSettings = true; + gRequestSaveSettings = true; } static void MENU_ClampSelection(int8_t Direction) { - int32_t Min; - int32_t Max; + int32_t Min; + int32_t Max; - if (!MENU_GetLimits(UI_MENU_GetCurrentMenuId(), &Min, &Max)) - { - int32_t Selection = gSubMenuSelection; - if (Selection < Min) Selection = Min; - else - if (Selection > Max) Selection = Max; - gSubMenuSelection = NUMBER_AddWithWraparound(Selection, Direction, Min, Max); - } + if (!MENU_GetLimits(UI_MENU_GetCurrentMenuId(), &Min, &Max)) + { + int32_t Selection = gSubMenuSelection; + if (Selection < Min) Selection = Min; + else + if (Selection > Max) Selection = Max; + gSubMenuSelection = NUMBER_AddWithWraparound(Selection, Direction, Min, Max); + } } void MENU_ShowCurrentSetting(void) { - switch (UI_MENU_GetCurrentMenuId()) - { - case MENU_SQL: - gSubMenuSelection = gEeprom.SQUELCH_LEVEL; - break; + switch (UI_MENU_GetCurrentMenuId()) + { + case MENU_SQL: + gSubMenuSelection = gEeprom.SQUELCH_LEVEL; + break; - case MENU_STEP: - gSubMenuSelection = FREQUENCY_GetSortedIdxFromStepIdx(gTxVfo->STEP_SETTING); - break; + case MENU_STEP: + gSubMenuSelection = FREQUENCY_GetSortedIdxFromStepIdx(gTxVfo->STEP_SETTING); + break; - case MENU_TXP: - gSubMenuSelection = gTxVfo->OUTPUT_POWER; - break; + case MENU_TXP: + gSubMenuSelection = gTxVfo->OUTPUT_POWER; + break; - case MENU_RESET: - gSubMenuSelection = 0; - break; + case MENU_RESET: + gSubMenuSelection = 0; + break; - case MENU_R_DCS: - case MENU_R_CTCS: - { - DCS_CodeType_t type = gTxVfo->freq_config_RX.CodeType; - uint8_t code = gTxVfo->freq_config_RX.Code; - int menuid = UI_MENU_GetCurrentMenuId(); + case MENU_R_DCS: + case MENU_R_CTCS: + { + DCS_CodeType_t type = gTxVfo->freq_config_RX.CodeType; + uint8_t code = gTxVfo->freq_config_RX.Code; + int menuid = UI_MENU_GetCurrentMenuId(); - if(gScanUseCssResult) { - gScanUseCssResult = false; - type = gScanCssResultType; - code = gScanCssResultCode; - } - if((menuid==MENU_R_CTCS) ^ (type==CODE_TYPE_CONTINUOUS_TONE)) { //not the same type - gSubMenuSelection = 0; - break; - } + if(gScanUseCssResult) { + gScanUseCssResult = false; + type = gScanCssResultType; + code = gScanCssResultCode; + } + if((menuid==MENU_R_CTCS) ^ (type==CODE_TYPE_CONTINUOUS_TONE)) { //not the same type + gSubMenuSelection = 0; + break; + } - switch (type) { - case CODE_TYPE_CONTINUOUS_TONE: - case CODE_TYPE_DIGITAL: - gSubMenuSelection = code + 1; - break; - case CODE_TYPE_REVERSE_DIGITAL: - gSubMenuSelection = code + 105; - break; - default: - gSubMenuSelection = 0; - break; - } - break; - } + switch (type) { + case CODE_TYPE_CONTINUOUS_TONE: + case CODE_TYPE_DIGITAL: + gSubMenuSelection = code + 1; + break; + case CODE_TYPE_REVERSE_DIGITAL: + gSubMenuSelection = code + 105; + break; + default: + gSubMenuSelection = 0; + break; + } + break; + } - case MENU_T_DCS: - switch (gTxVfo->freq_config_TX.CodeType) - { - case CODE_TYPE_DIGITAL: - gSubMenuSelection = gTxVfo->freq_config_TX.Code + 1; - break; - case CODE_TYPE_REVERSE_DIGITAL: - gSubMenuSelection = gTxVfo->freq_config_TX.Code + 105; - break; - default: - gSubMenuSelection = 0; - break; - } - break; + case MENU_T_DCS: + switch (gTxVfo->freq_config_TX.CodeType) + { + case CODE_TYPE_DIGITAL: + gSubMenuSelection = gTxVfo->freq_config_TX.Code + 1; + break; + case CODE_TYPE_REVERSE_DIGITAL: + gSubMenuSelection = gTxVfo->freq_config_TX.Code + 105; + break; + default: + gSubMenuSelection = 0; + break; + } + break; - case MENU_T_CTCS: - gSubMenuSelection = (gTxVfo->freq_config_TX.CodeType == CODE_TYPE_CONTINUOUS_TONE) ? gTxVfo->freq_config_TX.Code + 1 : 0; - break; + case MENU_T_CTCS: + gSubMenuSelection = (gTxVfo->freq_config_TX.CodeType == CODE_TYPE_CONTINUOUS_TONE) ? gTxVfo->freq_config_TX.Code + 1 : 0; + break; - case MENU_SFT_D: - gSubMenuSelection = gTxVfo->TX_OFFSET_FREQUENCY_DIRECTION; - break; + case MENU_SFT_D: + gSubMenuSelection = gTxVfo->TX_OFFSET_FREQUENCY_DIRECTION; + break; - case MENU_OFFSET: - gSubMenuSelection = gTxVfo->TX_OFFSET_FREQUENCY; - break; + case MENU_OFFSET: + gSubMenuSelection = gTxVfo->TX_OFFSET_FREQUENCY; + break; - case MENU_W_N: - gSubMenuSelection = gTxVfo->CHANNEL_BANDWIDTH; - break; + case MENU_W_N: + gSubMenuSelection = gTxVfo->CHANNEL_BANDWIDTH; + break; #ifndef ENABLE_FEAT_F4HWN - case MENU_SCR: - gSubMenuSelection = gTxVfo->SCRAMBLING_TYPE; - break; + case MENU_SCR: + gSubMenuSelection = gTxVfo->SCRAMBLING_TYPE; + break; #endif - case MENU_BCL: - gSubMenuSelection = gTxVfo->BUSY_CHANNEL_LOCK; - break; + case MENU_BCL: + gSubMenuSelection = gTxVfo->BUSY_CHANNEL_LOCK; + break; - case MENU_MEM_CH: - #if 0 - gSubMenuSelection = gEeprom.MrChannel[0]; - #else - gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_VFO]; - #endif - break; + case MENU_MEM_CH: + #if 0 + gSubMenuSelection = gEeprom.MrChannel[0]; + #else + gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_VFO]; + #endif + break; - case MENU_MEM_NAME: - gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_VFO]; - break; + case MENU_MEM_NAME: + gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_VFO]; + break; - case MENU_SAVE: - gSubMenuSelection = gEeprom.BATTERY_SAVE; - break; + case MENU_SAVE: + gSubMenuSelection = gEeprom.BATTERY_SAVE; + break; #ifdef ENABLE_VOX - case MENU_VOX: - gSubMenuSelection = gEeprom.VOX_SWITCH ? gEeprom.VOX_LEVEL + 1 : 0; - break; + case MENU_VOX: + gSubMenuSelection = gEeprom.VOX_SWITCH ? gEeprom.VOX_LEVEL + 1 : 0; + break; #endif - case MENU_ABR: - #ifdef ENABLE_FEAT_F4HWN - if(gBackLight) - { - gSubMenuSelection = gBacklightTimeOriginal; - } - else - { - gSubMenuSelection = gEeprom.BACKLIGHT_TIME; - } - #else - gSubMenuSelection = gEeprom.BACKLIGHT_TIME; - #endif - break; + case MENU_ABR: + #ifdef ENABLE_FEAT_F4HWN + if(gBackLight) + { + gSubMenuSelection = gBacklightTimeOriginal; + } + else + { + gSubMenuSelection = gEeprom.BACKLIGHT_TIME; + } + #else + gSubMenuSelection = gEeprom.BACKLIGHT_TIME; + #endif + break; - case MENU_ABR_MIN: - gSubMenuSelection = gEeprom.BACKLIGHT_MIN; - break; + case MENU_ABR_MIN: + gSubMenuSelection = gEeprom.BACKLIGHT_MIN; + break; - case MENU_ABR_MAX: - gSubMenuSelection = gEeprom.BACKLIGHT_MAX; - break; + case MENU_ABR_MAX: + gSubMenuSelection = gEeprom.BACKLIGHT_MAX; + break; - case MENU_ABR_ON_TX_RX: - gSubMenuSelection = gSetting_backlight_on_tx_rx; - break; + case MENU_ABR_ON_TX_RX: + gSubMenuSelection = gSetting_backlight_on_tx_rx; + break; - case MENU_TDR: - gSubMenuSelection = (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2; - break; + case MENU_TDR: + gSubMenuSelection = (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2; + break; - case MENU_BEEP: - gSubMenuSelection = gEeprom.BEEP_CONTROL; - break; + case MENU_BEEP: + gSubMenuSelection = gEeprom.BEEP_CONTROL; + break; - case MENU_TOT: - gSubMenuSelection = gEeprom.TX_TIMEOUT_TIMER; - break; + case MENU_TOT: + gSubMenuSelection = gEeprom.TX_TIMEOUT_TIMER; + break; #ifdef ENABLE_VOICE - case MENU_VOICE: - gSubMenuSelection = gEeprom.VOICE_PROMPT; - break; + case MENU_VOICE: + gSubMenuSelection = gEeprom.VOICE_PROMPT; + break; #endif - case MENU_SC_REV: - gSubMenuSelection = gEeprom.SCAN_RESUME_MODE; - break; + case MENU_SC_REV: + gSubMenuSelection = gEeprom.SCAN_RESUME_MODE; + break; - case MENU_MDF: - gSubMenuSelection = gEeprom.CHANNEL_DISPLAY_MODE; - break; + case MENU_MDF: + gSubMenuSelection = gEeprom.CHANNEL_DISPLAY_MODE; + break; - case MENU_AUTOLK: - gSubMenuSelection = gEeprom.AUTO_KEYPAD_LOCK; - break; + case MENU_AUTOLK: + gSubMenuSelection = gEeprom.AUTO_KEYPAD_LOCK; + break; - case MENU_S_ADD1: - gSubMenuSelection = gTxVfo->SCANLIST1_PARTICIPATION; - break; + case MENU_S_ADD1: + gSubMenuSelection = gTxVfo->SCANLIST1_PARTICIPATION; + break; - case MENU_S_ADD2: - gSubMenuSelection = gTxVfo->SCANLIST2_PARTICIPATION; - break; + case MENU_S_ADD2: + gSubMenuSelection = gTxVfo->SCANLIST2_PARTICIPATION; + break; - case MENU_S_ADD3: - gSubMenuSelection = gTxVfo->SCANLIST3_PARTICIPATION; - break; + case MENU_S_ADD3: + gSubMenuSelection = gTxVfo->SCANLIST3_PARTICIPATION; + break; - case MENU_STE: - gSubMenuSelection = gEeprom.TAIL_TONE_ELIMINATION; - break; + case MENU_STE: + gSubMenuSelection = gEeprom.TAIL_TONE_ELIMINATION; + break; - case MENU_RP_STE: - gSubMenuSelection = gEeprom.REPEATER_TAIL_TONE_ELIMINATION; - break; + case MENU_RP_STE: + gSubMenuSelection = gEeprom.REPEATER_TAIL_TONE_ELIMINATION; + break; - case MENU_MIC: - gSubMenuSelection = gEeprom.MIC_SENSITIVITY; - break; + case MENU_MIC: + gSubMenuSelection = gEeprom.MIC_SENSITIVITY; + break; #ifdef ENABLE_AUDIO_BAR - case MENU_MIC_BAR: - gSubMenuSelection = gSetting_mic_bar; - break; + case MENU_MIC_BAR: + gSubMenuSelection = gSetting_mic_bar; + break; #endif - case MENU_COMPAND: - gSubMenuSelection = gTxVfo->Compander; - return; + case MENU_COMPAND: + gSubMenuSelection = gTxVfo->Compander; + return; - case MENU_1_CALL: - gSubMenuSelection = gEeprom.CHAN_1_CALL; - break; + case MENU_1_CALL: + gSubMenuSelection = gEeprom.CHAN_1_CALL; + break; - case MENU_S_LIST: - gSubMenuSelection = gEeprom.SCAN_LIST_DEFAULT; - break; + case MENU_S_LIST: + gSubMenuSelection = gEeprom.SCAN_LIST_DEFAULT; + break; - case MENU_SLIST1: - gSubMenuSelection = RADIO_FindNextChannel(0, 1, true, 1); - break; + case MENU_SLIST1: + gSubMenuSelection = RADIO_FindNextChannel(0, 1, true, 1); + break; - case MENU_SLIST2: - gSubMenuSelection = RADIO_FindNextChannel(0, 1, true, 2); - break; + case MENU_SLIST2: + gSubMenuSelection = RADIO_FindNextChannel(0, 1, true, 2); + break; - case MENU_SLIST3: - gSubMenuSelection = RADIO_FindNextChannel(0, 1, true, 3); - break; + case MENU_SLIST3: + gSubMenuSelection = RADIO_FindNextChannel(0, 1, true, 3); + break; - #ifdef ENABLE_ALARM - case MENU_AL_MOD: - gSubMenuSelection = gEeprom.ALARM_MODE; - break; - #endif + #ifdef ENABLE_ALARM + case MENU_AL_MOD: + gSubMenuSelection = gEeprom.ALARM_MODE; + break; + #endif - case MENU_D_ST: - gSubMenuSelection = gEeprom.DTMF_SIDE_TONE; - break; + case MENU_D_ST: + gSubMenuSelection = gEeprom.DTMF_SIDE_TONE; + break; #ifdef ENABLE_DTMF_CALLING - case MENU_D_RSP: - gSubMenuSelection = gEeprom.DTMF_DECODE_RESPONSE; - break; + case MENU_D_RSP: + gSubMenuSelection = gEeprom.DTMF_DECODE_RESPONSE; + break; - case MENU_D_HOLD: - gSubMenuSelection = gEeprom.DTMF_auto_reset_time; - break; + case MENU_D_HOLD: + gSubMenuSelection = gEeprom.DTMF_auto_reset_time; + break; #endif - case MENU_D_PRE: - gSubMenuSelection = gEeprom.DTMF_PRELOAD_TIME / 10; - break; + case MENU_D_PRE: + gSubMenuSelection = gEeprom.DTMF_PRELOAD_TIME / 10; + break; - case MENU_PTT_ID: - gSubMenuSelection = gTxVfo->DTMF_PTT_ID_TX_MODE; - break; + case MENU_PTT_ID: + gSubMenuSelection = gTxVfo->DTMF_PTT_ID_TX_MODE; + break; - case MENU_BAT_TXT: - gSubMenuSelection = gSetting_battery_text; - return; + case MENU_BAT_TXT: + gSubMenuSelection = gSetting_battery_text; + return; #ifdef ENABLE_DTMF_CALLING - case MENU_D_DCD: - gSubMenuSelection = gTxVfo->DTMF_DECODING_ENABLE; - break; + case MENU_D_DCD: + gSubMenuSelection = gTxVfo->DTMF_DECODING_ENABLE; + break; - case MENU_D_LIST: - gSubMenuSelection = gDTMF_chosen_contact + 1; - break; + case MENU_D_LIST: + gSubMenuSelection = gDTMF_chosen_contact + 1; + break; #endif - case MENU_D_LIVE_DEC: - gSubMenuSelection = gSetting_live_DTMF_decoder; - break; + case MENU_D_LIVE_DEC: + gSubMenuSelection = gSetting_live_DTMF_decoder; + break; - case MENU_PONMSG: - gSubMenuSelection = gEeprom.POWER_ON_DISPLAY_MODE; - break; + case MENU_PONMSG: + gSubMenuSelection = gEeprom.POWER_ON_DISPLAY_MODE; + break; - case MENU_ROGER: - gSubMenuSelection = gEeprom.ROGER; - break; + case MENU_ROGER: + gSubMenuSelection = gEeprom.ROGER; + break; - case MENU_AM: - gSubMenuSelection = gTxVfo->Modulation; - break; + case MENU_AM: + gSubMenuSelection = gTxVfo->Modulation; + break; #ifndef ENABLE_FEAT_F4HWN - #ifdef ENABLE_AM_FIX - case MENU_AM_FIX: - gSubMenuSelection = gSetting_AM_fix; - break; - #endif + #ifdef ENABLE_AM_FIX + case MENU_AM_FIX: + gSubMenuSelection = gSetting_AM_fix; + break; + #endif #endif - - #ifdef ENABLE_NOAA - case MENU_NOAA_S: - gSubMenuSelection = gEeprom.NOAA_AUTO_SCAN; - break; - #endif + + #ifdef ENABLE_NOAA + case MENU_NOAA_S: + gSubMenuSelection = gEeprom.NOAA_AUTO_SCAN; + break; + #endif - case MENU_DEL_CH: - #if 0 - gSubMenuSelection = RADIO_FindNextChannel(gEeprom.MrChannel[0], 1, false, 1); - #else - gSubMenuSelection = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 1); - #endif - break; + case MENU_DEL_CH: + #if 0 + gSubMenuSelection = RADIO_FindNextChannel(gEeprom.MrChannel[0], 1, false, 1); + #else + gSubMenuSelection = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 1); + #endif + break; - case MENU_350TX: - gSubMenuSelection = gSetting_350TX; - break; + case MENU_350TX: + gSubMenuSelection = gSetting_350TX; + break; - case MENU_F_LOCK: - gSubMenuSelection = gSetting_F_LOCK; - break; + case MENU_F_LOCK: + gSubMenuSelection = gSetting_F_LOCK; + break; - case MENU_200TX: - gSubMenuSelection = gSetting_200TX; - break; + case MENU_200TX: + gSubMenuSelection = gSetting_200TX; + break; - case MENU_500TX: - gSubMenuSelection = gSetting_500TX; - break; + case MENU_500TX: + gSubMenuSelection = gSetting_500TX; + break; - case MENU_350EN: - gSubMenuSelection = gSetting_350EN; - break; + case MENU_350EN: + gSubMenuSelection = gSetting_350EN; + break; #ifndef ENABLE_FEAT_F4HWN - case MENU_SCREN: - gSubMenuSelection = gSetting_ScrambleEnable; - break; + case MENU_SCREN: + gSubMenuSelection = gSetting_ScrambleEnable; + break; #endif - #ifdef ENABLE_F_CAL_MENU - case MENU_F_CALI: - gSubMenuSelection = gEeprom.BK4819_XTAL_FREQ_LOW; - break; - #endif + #ifdef ENABLE_F_CAL_MENU + case MENU_F_CALI: + gSubMenuSelection = gEeprom.BK4819_XTAL_FREQ_LOW; + break; + #endif - case MENU_BATCAL: - gSubMenuSelection = gBatteryCalibration[3]; - break; + case MENU_BATCAL: + gSubMenuSelection = gBatteryCalibration[3]; + break; - case MENU_BATTYP: - gSubMenuSelection = gEeprom.BATTERY_TYPE; - break; + case MENU_BATTYP: + gSubMenuSelection = gEeprom.BATTERY_TYPE; + break; - case MENU_F1SHRT: - case MENU_F1LONG: - case MENU_F2SHRT: - case MENU_F2LONG: - case MENU_MLONG: - { - uint8_t * fun[]= { - &gEeprom.KEY_1_SHORT_PRESS_ACTION, - &gEeprom.KEY_1_LONG_PRESS_ACTION, - &gEeprom.KEY_2_SHORT_PRESS_ACTION, - &gEeprom.KEY_2_LONG_PRESS_ACTION, - &gEeprom.KEY_M_LONG_PRESS_ACTION}; - uint8_t id = *fun[UI_MENU_GetCurrentMenuId()-MENU_F1SHRT]; + case MENU_F1SHRT: + case MENU_F1LONG: + case MENU_F2SHRT: + case MENU_F2LONG: + case MENU_MLONG: + { + uint8_t * fun[]= { + &gEeprom.KEY_1_SHORT_PRESS_ACTION, + &gEeprom.KEY_1_LONG_PRESS_ACTION, + &gEeprom.KEY_2_SHORT_PRESS_ACTION, + &gEeprom.KEY_2_LONG_PRESS_ACTION, + &gEeprom.KEY_M_LONG_PRESS_ACTION}; + uint8_t id = *fun[UI_MENU_GetCurrentMenuId()-MENU_F1SHRT]; - for(int i = 0; i < gSubMenu_SIDEFUNCTIONS_size; i++) { - if(gSubMenu_SIDEFUNCTIONS[i].id==id) { - gSubMenuSelection = i; - break; - } + for(int i = 0; i < gSubMenu_SIDEFUNCTIONS_size; i++) { + if(gSubMenu_SIDEFUNCTIONS[i].id==id) { + gSubMenuSelection = i; + break; + } - } - break; - } + } + break; + } #ifdef ENABLE_FEAT_F4HWN - case MENU_SET_PWR: - gSubMenuSelection = gSetting_set_pwr; - break; - case MENU_SET_PTT: - gSubMenuSelection = gSetting_set_ptt_session; - break; - case MENU_SET_TOT: - gSubMenuSelection = gSetting_set_tot; - break; + case MENU_SET_PWR: + gSubMenuSelection = gSetting_set_pwr; + break; + case MENU_SET_PTT: + gSubMenuSelection = gSetting_set_ptt_session; + break; + case MENU_SET_TOT: + gSubMenuSelection = gSetting_set_tot; + break; case MENU_SET_EOT: - gSubMenuSelection = gSetting_set_eot; - break; - case MENU_SET_CTR: - gSubMenuSelection = gSetting_set_ctr; - break; + gSubMenuSelection = gSetting_set_eot; + break; + case MENU_SET_CTR: + gSubMenuSelection = gSetting_set_ctr; + break; case MENU_SET_INV: - gSubMenuSelection = gSetting_set_inv; - break; + gSubMenuSelection = gSetting_set_inv; + break; case MENU_SET_LCK: - gSubMenuSelection = gSetting_set_lck; - break; - case MENU_SET_MET: - gSubMenuSelection = gSetting_set_met; - break; - case MENU_SET_GUI: - gSubMenuSelection = gSetting_set_gui; - break; - case MENU_SET_TMR: - gSubMenuSelection = gSetting_set_tmr; - break; - case MENU_TX_LOCK: - gSubMenuSelection = gTxVfo->TX_LOCK; - break; + gSubMenuSelection = gSetting_set_lck; + break; + case MENU_SET_MET: + gSubMenuSelection = gSetting_set_met; + break; + case MENU_SET_GUI: + gSubMenuSelection = gSetting_set_gui; + break; + case MENU_SET_TMR: + gSubMenuSelection = gSetting_set_tmr; + break; + case MENU_TX_LOCK: + gSubMenuSelection = gTxVfo->TX_LOCK; + break; #endif - default: - return; - } + default: + return; + } } static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { - uint8_t Offset; - int32_t Min; - int32_t Max; - uint16_t Value = 0; + uint8_t Offset; + int32_t Min; + int32_t Max; + uint16_t Value = 0; - if (bKeyHeld || !bKeyPressed) - return; + if (bKeyHeld || !bKeyPressed) + return; - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0) - { // currently editing the channel name + if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0) + { // currently editing the channel name - if (edit_index < 10) - { - if (Key <= KEY_9) - { - edit[edit_index] = '0' + Key - KEY_0; + if (edit_index < 10) + { + if (Key <= KEY_9) + { + edit[edit_index] = '0' + Key - KEY_0; - if (++edit_index >= 10) - { // exit edit - gFlagAcceptSetting = false; - gAskForConfirmation = 1; - } + if (++edit_index >= 10) + { // exit edit + gFlagAcceptSetting = false; + gAskForConfirmation = 1; + } - gRequestDisplayScreen = DISPLAY_MENU; - } - } + gRequestDisplayScreen = DISPLAY_MENU; + } + } - return; - } + return; + } - INPUTBOX_Append(Key); + INPUTBOX_Append(Key); - gRequestDisplayScreen = DISPLAY_MENU; + gRequestDisplayScreen = DISPLAY_MENU; - if (!gIsInSubMenu) - { - switch (gInputBoxIndex) - { - case 2: - gInputBoxIndex = 0; + if (!gIsInSubMenu) + { + switch (gInputBoxIndex) + { + case 2: + gInputBoxIndex = 0; - Value = (gInputBox[0] * 10) + gInputBox[1]; + Value = (gInputBox[0] * 10) + gInputBox[1]; - if (Value > 0 && Value <= gMenuListCount) - { - gMenuCursor = Value - 1; - gFlagRefreshSetting = true; - return; - } + if (Value > 0 && Value <= gMenuListCount) + { + gMenuCursor = Value - 1; + gFlagRefreshSetting = true; + return; + } - if (Value <= gMenuListCount) - break; + if (Value <= gMenuListCount) + break; - gInputBox[0] = gInputBox[1]; - gInputBoxIndex = 1; - [[fallthrough]]; - case 1: - Value = gInputBox[0]; - if (Value > 0 && Value <= gMenuListCount) - { - gMenuCursor = Value - 1; - gFlagRefreshSetting = true; - return; - } - break; - } + gInputBox[0] = gInputBox[1]; + gInputBoxIndex = 1; + [[fallthrough]]; + case 1: + Value = gInputBox[0]; + if (Value > 0 && Value <= gMenuListCount) + { + gMenuCursor = Value - 1; + gFlagRefreshSetting = true; + return; + } + break; + } - gInputBoxIndex = 0; + gInputBoxIndex = 0; - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } - if (UI_MENU_GetCurrentMenuId() == MENU_OFFSET) - { - uint32_t Frequency; + if (UI_MENU_GetCurrentMenuId() == MENU_OFFSET) + { + uint32_t Frequency; - if (gInputBoxIndex < 6) - { // invalid frequency - #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; - #endif - return; - } + if (gInputBoxIndex < 6) + { // invalid frequency + #ifdef ENABLE_VOICE + gAnotherVoiceID = (VOICE_ID_t)Key; + #endif + return; + } - #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; - #endif + #ifdef ENABLE_VOICE + gAnotherVoiceID = (VOICE_ID_t)Key; + #endif - Frequency = StrToUL(INPUTBOX_GetAscii())*100; - gSubMenuSelection = FREQUENCY_RoundToStep(Frequency, gTxVfo->StepFrequency); + Frequency = StrToUL(INPUTBOX_GetAscii())*100; + gSubMenuSelection = FREQUENCY_RoundToStep(Frequency, gTxVfo->StepFrequency); - gInputBoxIndex = 0; - return; - } + gInputBoxIndex = 0; + return; + } - if (UI_MENU_GetCurrentMenuId() == MENU_MEM_CH || - UI_MENU_GetCurrentMenuId() == MENU_DEL_CH || - UI_MENU_GetCurrentMenuId() == MENU_1_CALL || - UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME) - { // enter 3-digit channel number + if (UI_MENU_GetCurrentMenuId() == MENU_MEM_CH || + UI_MENU_GetCurrentMenuId() == MENU_DEL_CH || + UI_MENU_GetCurrentMenuId() == MENU_1_CALL || + UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME) + { // enter 3-digit channel number - if (gInputBoxIndex < 3) - { - #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; - #endif - gRequestDisplayScreen = DISPLAY_MENU; - return; - } + if (gInputBoxIndex < 3) + { + #ifdef ENABLE_VOICE + gAnotherVoiceID = (VOICE_ID_t)Key; + #endif + gRequestDisplayScreen = DISPLAY_MENU; + return; + } - gInputBoxIndex = 0; + gInputBoxIndex = 0; - Value = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1; + Value = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1; - if (IS_MR_CHANNEL(Value)) - { - #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; - #endif - gSubMenuSelection = Value; - return; - } + if (IS_MR_CHANNEL(Value)) + { + #ifdef ENABLE_VOICE + gAnotherVoiceID = (VOICE_ID_t)Key; + #endif + gSubMenuSelection = Value; + return; + } - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } - if (MENU_GetLimits(UI_MENU_GetCurrentMenuId(), &Min, &Max)) - { - gInputBoxIndex = 0; - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + if (MENU_GetLimits(UI_MENU_GetCurrentMenuId(), &Min, &Max)) + { + gInputBoxIndex = 0; + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } - Offset = (Max >= 100) ? 3 : (Max >= 10) ? 2 : 1; + Offset = (Max >= 100) ? 3 : (Max >= 10) ? 2 : 1; - switch (gInputBoxIndex) - { - case 1: - Value = gInputBox[0]; - break; - case 2: - Value = (gInputBox[0] * 10) + gInputBox[1]; - break; - case 3: - Value = (gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]; - break; - } + switch (gInputBoxIndex) + { + case 1: + Value = gInputBox[0]; + break; + case 2: + Value = (gInputBox[0] * 10) + gInputBox[1]; + break; + case 3: + Value = (gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]; + break; + } - if (Offset == gInputBoxIndex) - gInputBoxIndex = 0; + if (Offset == gInputBoxIndex) + gInputBoxIndex = 0; - if (Value <= Max) - { - gSubMenuSelection = Value; - return; - } + if (Value <= Max) + { + gSubMenuSelection = Value; + return; + } - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; } static void MENU_Key_EXIT(bool bKeyPressed, bool bKeyHeld) { - if (bKeyHeld || !bKeyPressed) - return; + if (bKeyHeld || !bKeyPressed) + return; - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - if (!gCssBackgroundScan) - { - /* Backlight related menus set full brightness. Set it back to the configured value, - just in case we are exiting from one of them. */ - BACKLIGHT_TurnOn(); + if (!gCssBackgroundScan) + { + /* Backlight related menus set full brightness. Set it back to the configured value, + just in case we are exiting from one of them. */ + BACKLIGHT_TurnOn(); - if (gIsInSubMenu) - { - if (gInputBoxIndex == 0 || UI_MENU_GetCurrentMenuId() != MENU_OFFSET) - { - gAskForConfirmation = 0; - gIsInSubMenu = false; - gInputBoxIndex = 0; - gFlagRefreshSetting = true; + if (gIsInSubMenu) + { + if (gInputBoxIndex == 0 || UI_MENU_GetCurrentMenuId() != MENU_OFFSET) + { + gAskForConfirmation = 0; + gIsInSubMenu = false; + gInputBoxIndex = 0; + gFlagRefreshSetting = true; - #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_CANCEL; - #endif - } - else - gInputBox[--gInputBoxIndex] = 10; + #ifdef ENABLE_VOICE + gAnotherVoiceID = VOICE_ID_CANCEL; + #endif + } + else + gInputBox[--gInputBoxIndex] = 10; - // *********************** + // *********************** - gRequestDisplayScreen = DISPLAY_MENU; - return; - } + gRequestDisplayScreen = DISPLAY_MENU; + return; + } - #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_CANCEL; - #endif + #ifdef ENABLE_VOICE + gAnotherVoiceID = VOICE_ID_CANCEL; + #endif - gRequestDisplayScreen = DISPLAY_MAIN; + gRequestDisplayScreen = DISPLAY_MAIN; - if (gEeprom.BACKLIGHT_TIME == 0) // backlight set to always off - { - BACKLIGHT_TurnOff(); // turn the backlight OFF - } - } - else - { - MENU_StopCssScan(); + if (gEeprom.BACKLIGHT_TIME == 0) // backlight set to always off + { + BACKLIGHT_TurnOff(); // turn the backlight OFF + } + } + else + { + MENU_StopCssScan(); - #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_SCANNING_STOP; - #endif + #ifdef ENABLE_VOICE + gAnotherVoiceID = VOICE_ID_SCANNING_STOP; + #endif - gRequestDisplayScreen = DISPLAY_MENU; - } + gRequestDisplayScreen = DISPLAY_MENU; + } - gPttWasReleased = true; + gPttWasReleased = true; } static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld) { - if (bKeyHeld || !bKeyPressed) - return; + if (bKeyHeld || !bKeyPressed) + return; - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - gRequestDisplayScreen = DISPLAY_MENU; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gRequestDisplayScreen = DISPLAY_MENU; - if (!gIsInSubMenu) - { - #ifdef ENABLE_VOICE - if (UI_MENU_GetCurrentMenuId() != MENU_SCR) - gAnotherVoiceID = MenuList[gMenuCursor].voice_id; - #endif + if (!gIsInSubMenu) + { + #ifdef ENABLE_VOICE + if (UI_MENU_GetCurrentMenuId() != MENU_SCR) + gAnotherVoiceID = MenuList[gMenuCursor].voice_id; + #endif if (UI_MENU_GetCurrentMenuId() == MENU_UPCODE - || UI_MENU_GetCurrentMenuId() == MENU_DWCODE + || UI_MENU_GetCurrentMenuId() == MENU_DWCODE #ifdef ENABLE_DTMF_CALLING - || UI_MENU_GetCurrentMenuId() == MENU_ANI_ID + || UI_MENU_GetCurrentMenuId() == MENU_ANI_ID #endif - ) + ) return; - #if 1 - if (UI_MENU_GetCurrentMenuId() == MENU_DEL_CH || UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME) - if (!RADIO_CheckValidChannel(gSubMenuSelection, false, 0)) - return; // invalid channel - #endif + #if 1 + if (UI_MENU_GetCurrentMenuId() == MENU_DEL_CH || UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME) + if (!RADIO_CheckValidChannel(gSubMenuSelection, false, 0)) + return; // invalid channel + #endif - gAskForConfirmation = 0; - gIsInSubMenu = true; + gAskForConfirmation = 0; + gIsInSubMenu = true; -// if (UI_MENU_GetCurrentMenuId() != MENU_D_LIST) - { - gInputBoxIndex = 0; - edit_index = -1; - } +// if (UI_MENU_GetCurrentMenuId() != MENU_D_LIST) + { + gInputBoxIndex = 0; + edit_index = -1; + } - return; - } + return; + } - if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME) - { - if (edit_index < 0) - { // enter channel name edit mode - if (!RADIO_CheckValidChannel(gSubMenuSelection, false, 0)) - return; + if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME) + { + if (edit_index < 0) + { // enter channel name edit mode + if (!RADIO_CheckValidChannel(gSubMenuSelection, false, 0)) + return; - SETTINGS_FetchChannelName(edit, gSubMenuSelection); + SETTINGS_FetchChannelName(edit, gSubMenuSelection); - // pad the channel name out with '_' - edit_index = strlen(edit); - while (edit_index < 10) - edit[edit_index++] = '_'; - edit[edit_index] = 0; - edit_index = 0; // 'edit_index' is going to be used as the cursor position + // pad the channel name out with '_' + edit_index = strlen(edit); + while (edit_index < 10) + edit[edit_index++] = '_'; + edit[edit_index] = 0; + edit_index = 0; // 'edit_index' is going to be used as the cursor position - // make a copy so we can test for change when exiting the menu item - memcpy(edit_original, edit, sizeof(edit_original)); + // make a copy so we can test for change when exiting the menu item + memcpy(edit_original, edit, sizeof(edit_original)); - return; - } - else - if (edit_index >= 0 && edit_index < 10) - { // editing the channel name characters + return; + } + else + if (edit_index >= 0 && edit_index < 10) + { // editing the channel name characters - if (++edit_index < 10) - return; // next char + if (++edit_index < 10) + return; // next char - // exit - gFlagAcceptSetting = false; - gAskForConfirmation = 0; - if (memcmp(edit_original, edit, sizeof(edit_original)) == 0) { - // no change - drop it - gIsInSubMenu = false; - } - } - } + // exit + gFlagAcceptSetting = false; + gAskForConfirmation = 0; + if (memcmp(edit_original, edit, sizeof(edit_original)) == 0) { + // no change - drop it + gIsInSubMenu = false; + } + } + } - // exiting the sub menu + // exiting the sub menu - if (gIsInSubMenu) - { - if (UI_MENU_GetCurrentMenuId() == MENU_RESET || - UI_MENU_GetCurrentMenuId() == MENU_MEM_CH || - UI_MENU_GetCurrentMenuId() == MENU_DEL_CH || - UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME) - { - switch (gAskForConfirmation) - { - case 0: - gAskForConfirmation = 1; - break; + if (gIsInSubMenu) + { + if (UI_MENU_GetCurrentMenuId() == MENU_RESET || + UI_MENU_GetCurrentMenuId() == MENU_MEM_CH || + UI_MENU_GetCurrentMenuId() == MENU_DEL_CH || + UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME) + { + switch (gAskForConfirmation) + { + case 0: + gAskForConfirmation = 1; + break; - case 1: - gAskForConfirmation = 2; + case 1: + gAskForConfirmation = 2; - UI_DisplayMenu(); + UI_DisplayMenu(); - if (UI_MENU_GetCurrentMenuId() == MENU_RESET) - { - #ifdef ENABLE_VOICE - AUDIO_SetVoiceID(0, VOICE_ID_CONFIRM); - AUDIO_PlaySingleVoice(true); - #endif + if (UI_MENU_GetCurrentMenuId() == MENU_RESET) + { + #ifdef ENABLE_VOICE + AUDIO_SetVoiceID(0, VOICE_ID_CONFIRM); + AUDIO_PlaySingleVoice(true); + #endif - MENU_AcceptSetting(); + MENU_AcceptSetting(); - #if defined(ENABLE_OVERLAY) - overlay_FLASH_RebootToBootloader(); - #else - NVIC_SystemReset(); - #endif - } + #if defined(ENABLE_OVERLAY) + overlay_FLASH_RebootToBootloader(); + #else + NVIC_SystemReset(); + #endif + } - gFlagAcceptSetting = true; - gIsInSubMenu = false; - gAskForConfirmation = 0; - } - } - else - { - gFlagAcceptSetting = true; - gIsInSubMenu = false; - } - } + gFlagAcceptSetting = true; + gIsInSubMenu = false; + gAskForConfirmation = 0; + } + } + else + { + gFlagAcceptSetting = true; + gIsInSubMenu = false; + } + } - SCANNER_Stop(); + SCANNER_Stop(); - #ifdef ENABLE_VOICE - if (UI_MENU_GetCurrentMenuId() == MENU_SCR) - gAnotherVoiceID = (gSubMenuSelection == 0) ? VOICE_ID_SCRAMBLER_OFF : VOICE_ID_SCRAMBLER_ON; - else - gAnotherVoiceID = VOICE_ID_CONFIRM; - #endif + #ifdef ENABLE_VOICE + if (UI_MENU_GetCurrentMenuId() == MENU_SCR) + gAnotherVoiceID = (gSubMenuSelection == 0) ? VOICE_ID_SCRAMBLER_OFF : VOICE_ID_SCRAMBLER_ON; + else + gAnotherVoiceID = VOICE_ID_CONFIRM; + #endif - gInputBoxIndex = 0; + gInputBoxIndex = 0; } static void MENU_Key_STAR(const bool bKeyPressed, const bool bKeyHeld) { - if (bKeyHeld || !bKeyPressed) - return; + if (bKeyHeld || !bKeyPressed) + return; - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0) - { // currently editing the channel name + if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0) + { // currently editing the channel name - if (edit_index < 10) - { - edit[edit_index] = '-'; + if (edit_index < 10) + { + edit[edit_index] = '-'; - if (++edit_index >= 10) - { // exit edit - gFlagAcceptSetting = false; - gAskForConfirmation = 1; - } + if (++edit_index >= 10) + { // exit edit + gFlagAcceptSetting = false; + gAskForConfirmation = 1; + } - gRequestDisplayScreen = DISPLAY_MENU; - } + gRequestDisplayScreen = DISPLAY_MENU; + } - return; - } + return; + } - RADIO_SelectVfos(); + RADIO_SelectVfos(); - #ifdef ENABLE_NOAA - if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gRxVfo->Modulation == MODULATION_FM) - #else - if (gRxVfo->Modulation == MODULATION_FM) - #endif - { - if ((UI_MENU_GetCurrentMenuId() == MENU_R_CTCS || UI_MENU_GetCurrentMenuId() == MENU_R_DCS) && gIsInSubMenu) - { // scan CTCSS or DCS to find the tone/code of the incoming signal - if (!SCANNER_IsScanning()) - MENU_StartCssScan(); - else - MENU_StopCssScan(); - } + #ifdef ENABLE_NOAA + if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gRxVfo->Modulation == MODULATION_FM) + #else + if (gRxVfo->Modulation == MODULATION_FM) + #endif + { + if ((UI_MENU_GetCurrentMenuId() == MENU_R_CTCS || UI_MENU_GetCurrentMenuId() == MENU_R_DCS) && gIsInSubMenu) + { // scan CTCSS or DCS to find the tone/code of the incoming signal + if (!SCANNER_IsScanning()) + MENU_StartCssScan(); + else + MENU_StopCssScan(); + } - gPttWasReleased = true; - return; - } + gPttWasReleased = true; + return; + } - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; } static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction) { - uint8_t VFO; - uint8_t Channel; - bool bCheckScanList; + uint8_t VFO; + uint8_t Channel; + bool bCheckScanList; - if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && gIsInSubMenu && edit_index >= 0) - { // change the character - if (bKeyPressed && edit_index < 10 && Direction != 0) - { - const char unwanted[] = "$%&!\"':;?^`|{}"; - char c = edit[edit_index] + Direction; - unsigned int i = 0; - while (i < sizeof(unwanted) && c >= 32 && c <= 126) - { - if (c == unwanted[i++]) - { // choose next character - c += Direction; - i = 0; - } - } - edit[edit_index] = (c < 32) ? 126 : (c > 126) ? 32 : c; + if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && gIsInSubMenu && edit_index >= 0) + { // change the character + if (bKeyPressed && edit_index < 10 && Direction != 0) + { + const char unwanted[] = "$%&!\"':;?^`|{}"; + char c = edit[edit_index] + Direction; + unsigned int i = 0; + while (i < sizeof(unwanted) && c >= 32 && c <= 126) + { + if (c == unwanted[i++]) + { // choose next character + c += Direction; + i = 0; + } + } + edit[edit_index] = (c < 32) ? 126 : (c > 126) ? 32 : c; - gRequestDisplayScreen = DISPLAY_MENU; - } - return; - } + gRequestDisplayScreen = DISPLAY_MENU; + } + return; + } - if (!bKeyHeld) - { - if (!bKeyPressed) - return; + if (!bKeyHeld) + { + if (!bKeyPressed) + return; - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - gInputBoxIndex = 0; - } - else - if (!bKeyPressed) - return; + gInputBoxIndex = 0; + } + else + if (!bKeyPressed) + return; - if (SCANNER_IsScanning()) { - return; - } + if (SCANNER_IsScanning()) { + return; + } - if (!gIsInSubMenu) - { - gMenuCursor = NUMBER_AddWithWraparound(gMenuCursor, -Direction, 0, gMenuListCount - 1); + if (!gIsInSubMenu) + { + gMenuCursor = NUMBER_AddWithWraparound(gMenuCursor, -Direction, 0, gMenuListCount - 1); - gFlagRefreshSetting = true; + gFlagRefreshSetting = true; - gRequestDisplayScreen = DISPLAY_MENU; + gRequestDisplayScreen = DISPLAY_MENU; - if (UI_MENU_GetCurrentMenuId() != MENU_ABR - && UI_MENU_GetCurrentMenuId() != MENU_ABR_MIN - && UI_MENU_GetCurrentMenuId() != MENU_ABR_MAX - && gEeprom.BACKLIGHT_TIME == 0) // backlight always off and not in the backlight menu - { - BACKLIGHT_TurnOff(); - } + if (UI_MENU_GetCurrentMenuId() != MENU_ABR + && UI_MENU_GetCurrentMenuId() != MENU_ABR_MIN + && UI_MENU_GetCurrentMenuId() != MENU_ABR_MAX + && gEeprom.BACKLIGHT_TIME == 0) // backlight always off and not in the backlight menu + { + BACKLIGHT_TurnOff(); + } - return; - } + return; + } - if (UI_MENU_GetCurrentMenuId() == MENU_OFFSET) - { - int32_t Offset = (Direction * gTxVfo->StepFrequency) + gSubMenuSelection; - if (Offset < 99999990) - { - if (Offset < 0) - Offset = 99999990; - } - else - Offset = 0; + if (UI_MENU_GetCurrentMenuId() == MENU_OFFSET) + { + int32_t Offset = (Direction * gTxVfo->StepFrequency) + gSubMenuSelection; + if (Offset < 99999990) + { + if (Offset < 0) + Offset = 99999990; + } + else + Offset = 0; - gSubMenuSelection = FREQUENCY_RoundToStep(Offset, gTxVfo->StepFrequency); - gRequestDisplayScreen = DISPLAY_MENU; - return; - } + gSubMenuSelection = FREQUENCY_RoundToStep(Offset, gTxVfo->StepFrequency); + gRequestDisplayScreen = DISPLAY_MENU; + return; + } - VFO = 0; + VFO = 0; - switch (UI_MENU_GetCurrentMenuId()) - { - case MENU_DEL_CH: - case MENU_1_CALL: - case MENU_MEM_NAME: - bCheckScanList = false; - break; + switch (UI_MENU_GetCurrentMenuId()) + { + case MENU_DEL_CH: + case MENU_1_CALL: + case MENU_MEM_NAME: + bCheckScanList = false; + break; - case MENU_SLIST3: - bCheckScanList = true; - VFO = 3; - break; - case MENU_SLIST2: - bCheckScanList = true; - VFO = 2; - break; - case MENU_SLIST1: - VFO = 1; - bCheckScanList = true; - break; + case MENU_SLIST3: + bCheckScanList = true; + VFO = 3; + break; + case MENU_SLIST2: + bCheckScanList = true; + VFO = 2; + break; + case MENU_SLIST1: + VFO = 1; + bCheckScanList = true; + break; - default: - MENU_ClampSelection(Direction); - gRequestDisplayScreen = DISPLAY_MENU; - return; - } + default: + MENU_ClampSelection(Direction); + gRequestDisplayScreen = DISPLAY_MENU; + return; + } - Channel = RADIO_FindNextChannel(gSubMenuSelection + Direction, Direction, bCheckScanList, VFO); - if (Channel != 0xFF) - gSubMenuSelection = Channel; + Channel = RADIO_FindNextChannel(gSubMenuSelection + Direction, Direction, bCheckScanList, VFO); + if (Channel != 0xFF) + gSubMenuSelection = Channel; - gRequestDisplayScreen = DISPLAY_MENU; + gRequestDisplayScreen = DISPLAY_MENU; } void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { - switch (Key) - { - case KEY_0: - case KEY_1: - case KEY_2: - case KEY_3: - case KEY_4: - case KEY_5: - case KEY_6: - case KEY_7: - case KEY_8: - case KEY_9: - MENU_Key_0_to_9(Key, bKeyPressed, bKeyHeld); - break; - case KEY_MENU: - MENU_Key_MENU(bKeyPressed, bKeyHeld); - break; - case KEY_UP: - MENU_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1); - break; - case KEY_DOWN: - MENU_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1); - break; - case KEY_EXIT: - MENU_Key_EXIT(bKeyPressed, bKeyHeld); - break; - case KEY_STAR: - MENU_Key_STAR(bKeyPressed, bKeyHeld); - break; - case KEY_F: - if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0) - { // currently editing the channel name - if (!bKeyHeld && bKeyPressed) - { - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - if (edit_index < 10) - { - edit[edit_index] = ' '; - if (++edit_index >= 10) - { // exit edit - gFlagAcceptSetting = false; - gAskForConfirmation = 1; - } - gRequestDisplayScreen = DISPLAY_MENU; - } - } - break; - } + switch (Key) + { + case KEY_0: + case KEY_1: + case KEY_2: + case KEY_3: + case KEY_4: + case KEY_5: + case KEY_6: + case KEY_7: + case KEY_8: + case KEY_9: + MENU_Key_0_to_9(Key, bKeyPressed, bKeyHeld); + break; + case KEY_MENU: + MENU_Key_MENU(bKeyPressed, bKeyHeld); + break; + case KEY_UP: + MENU_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1); + break; + case KEY_DOWN: + MENU_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1); + break; + case KEY_EXIT: + MENU_Key_EXIT(bKeyPressed, bKeyHeld); + break; + case KEY_STAR: + MENU_Key_STAR(bKeyPressed, bKeyHeld); + break; + case KEY_F: + if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0) + { // currently editing the channel name + if (!bKeyHeld && bKeyPressed) + { + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + if (edit_index < 10) + { + edit[edit_index] = ' '; + if (++edit_index >= 10) + { // exit edit + gFlagAcceptSetting = false; + gAskForConfirmation = 1; + } + gRequestDisplayScreen = DISPLAY_MENU; + } + } + break; + } - GENERIC_Key_F(bKeyPressed, bKeyHeld); - break; - case KEY_PTT: - GENERIC_Key_PTT(bKeyPressed); - break; - default: - if (!bKeyHeld && bKeyPressed) - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - break; - } + GENERIC_Key_F(bKeyPressed, bKeyHeld); + break; + case KEY_PTT: + GENERIC_Key_PTT(bKeyPressed); + break; + default: + if (!bKeyHeld && bKeyPressed) + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + break; + } - if (gScreenToDisplay == DISPLAY_MENU) - { - if (UI_MENU_GetCurrentMenuId() == MENU_VOL || - #ifdef ENABLE_F_CAL_MENU - UI_MENU_GetCurrentMenuId() == MENU_F_CALI || - #endif - UI_MENU_GetCurrentMenuId() == MENU_BATCAL) - { - gMenuCountdown = menu_timeout_long_500ms; - } - else - { - gMenuCountdown = menu_timeout_500ms; - } - } + if (gScreenToDisplay == DISPLAY_MENU) + { + if (UI_MENU_GetCurrentMenuId() == MENU_VOL || + #ifdef ENABLE_F_CAL_MENU + UI_MENU_GetCurrentMenuId() == MENU_F_CALI || + #endif + UI_MENU_GetCurrentMenuId() == MENU_BATCAL) + { + gMenuCountdown = menu_timeout_long_500ms; + } + else + { + gMenuCountdown = menu_timeout_500ms; + } + } } diff --git a/app/menu.h b/app/menu.h index 0b8a15c..fbca3bf 100644 --- a/app/menu.h +++ b/app/menu.h @@ -20,7 +20,7 @@ #include "driver/keyboard.h" #ifdef ENABLE_F_CAL_MENU - void writeXtalFreqCal(const int32_t value, const bool update_eeprom); + void writeXtalFreqCal(const int32_t value, const bool update_eeprom); #endif extern uint8_t gUnlockAllTxConfCnt; diff --git a/app/scanner.c b/app/scanner.c index 6ef6108..2d7c523 100644 --- a/app/scanner.c +++ b/app/scanner.c @@ -43,476 +43,476 @@ uint8_t scanHitCount; static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { - if (!bKeyHeld && bKeyPressed) - { - if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) { - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + if (!bKeyHeld && bKeyPressed) + { + if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) { + 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 - gAnotherVoiceID = (VOICE_ID_t)Key; + gAnotherVoiceID = (VOICE_ID_t)Key; #endif - return; - } + return; + } - gInputBoxIndex = 0; + gInputBoxIndex = 0; - uint16_t chan = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1; - if (IS_MR_CHANNEL(chan)) { + 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; + gAnotherVoiceID = (VOICE_ID_t)Key; #endif - gShowChPrefix = RADIO_CheckValidChannel(chan, false, 0); - gScanChannel = (uint8_t)chan; - return; - } - } + gShowChPrefix = RADIO_CheckValidChannel(chan, false, 0); + gScanChannel = (uint8_t)chan; + return; + } + } - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - } + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + } } static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld) { - if (!bKeyHeld && bKeyPressed) { // short pressed - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + if (!bKeyHeld && bKeyPressed) { // short pressed + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - switch (gScannerSaveState) { - case SCAN_SAVE_NO_PROMPT: - SCANNER_Stop(); - gRequestDisplayScreen = DISPLAY_MAIN; - break; + switch (gScannerSaveState) { + case SCAN_SAVE_NO_PROMPT: + SCANNER_Stop(); + gRequestDisplayScreen = DISPLAY_MAIN; + break; - case SCAN_SAVE_CHAN_SEL: - if (gInputBoxIndex > 0) { - gInputBox[--gInputBoxIndex] = 10; - gRequestDisplayScreen = DISPLAY_SCANNER; - break; - } + case SCAN_SAVE_CHAN_SEL: + if (gInputBoxIndex > 0) { + gInputBox[--gInputBoxIndex] = 10; + gRequestDisplayScreen = DISPLAY_SCANNER; + break; + } - // Fallthrough + // Fallthrough - case SCAN_SAVE_CHANNEL: - gScannerSaveState = SCAN_SAVE_NO_PROMPT; + case SCAN_SAVE_CHANNEL: + gScannerSaveState = SCAN_SAVE_NO_PROMPT; #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_CANCEL; + gAnotherVoiceID = VOICE_ID_CANCEL; #endif - gRequestDisplayScreen = DISPLAY_SCANNER; - break; - } - } + gRequestDisplayScreen = DISPLAY_SCANNER; + break; + } + } } static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld) { - if (bKeyHeld || !bKeyPressed) // ignore long press or release button events - return; + if (bKeyHeld || !bKeyPressed) // ignore long press or release button events + return; - if (gScanCssState == SCAN_CSS_STATE_OFF && !gScanSingleFrequency) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + if (gScanCssState == SCAN_CSS_STATE_OFF && !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_SCANNING && gScanSingleFrequency) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } - if (gScanCssState == SCAN_CSS_STATE_FAILED) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + if (gScanCssState == SCAN_CSS_STATE_FAILED) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - switch (gScannerSaveState) { - case SCAN_SAVE_NO_PROMPT: - if (!gScanSingleFrequency) - { - uint32_t freq250 = FREQUENCY_RoundToStep(gScanFrequency, 250); - uint32_t freq625 = FREQUENCY_RoundToStep(gScanFrequency, 625); + switch (gScannerSaveState) { + case SCAN_SAVE_NO_PROMPT: + if (!gScanSingleFrequency) + { + uint32_t freq250 = FREQUENCY_RoundToStep(gScanFrequency, 250); + uint32_t freq625 = FREQUENCY_RoundToStep(gScanFrequency, 625); - uint32_t diff250 = gScanFrequency > freq250 ? gScanFrequency - freq250 : freq250 - gScanFrequency; - uint32_t diff625 = gScanFrequency > freq625 ? gScanFrequency - freq625 : freq625 - gScanFrequency; + uint32_t diff250 = gScanFrequency > freq250 ? gScanFrequency - freq250 : freq250 - gScanFrequency; + uint32_t diff625 = gScanFrequency > freq625 ? gScanFrequency - freq625 : freq625 - gScanFrequency; - if(diff250 > diff625) { - stepSetting = STEP_6_25kHz; - gScanFrequency = freq625; - } - else { - stepSetting = STEP_2_5kHz; - gScanFrequency = freq250; - } - } + if(diff250 > diff625) { + stepSetting = STEP_6_25kHz; + gScanFrequency = freq625; + } + else { + stepSetting = STEP_2_5kHz; + gScanFrequency = freq250; + } + } - 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 { - gScannerSaveState = SCAN_SAVE_CHANNEL; - } + 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 { + gScannerSaveState = SCAN_SAVE_CHANNEL; + } - gScanCssState = SCAN_CSS_STATE_FOUND; + gScanCssState = SCAN_CSS_STATE_FOUND; #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_MEMORY_CHANNEL; + gAnotherVoiceID = VOICE_ID_MEMORY_CHANNEL; #endif - gRequestDisplayScreen = DISPLAY_SCANNER; - - gUpdateStatus = true; - break; + gRequestDisplayScreen = DISPLAY_SCANNER; + + gUpdateStatus = true; + break; - case SCAN_SAVE_CHAN_SEL: - if (gInputBoxIndex == 0) { - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - gRequestDisplayScreen = DISPLAY_SCANNER; - gScannerSaveState = SCAN_SAVE_CHANNEL; - } - break; + case SCAN_SAVE_CHAN_SEL: + if (gInputBoxIndex == 0) { + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gRequestDisplayScreen = DISPLAY_SCANNER; + gScannerSaveState = SCAN_SAVE_CHANNEL; + } + break; - case SCAN_SAVE_CHANNEL: - if (!gScanSingleFrequency) { - RADIO_InitInfo(gTxVfo, gTxVfo->CHANNEL_SAVE, gScanFrequency); + case SCAN_SAVE_CHANNEL: + if (!gScanSingleFrequency) { + RADIO_InitInfo(gTxVfo, gTxVfo->CHANNEL_SAVE, gScanFrequency); - if (gScanUseCssResult) { - gTxVfo->freq_config_RX.CodeType = gScanCssResultType; - gTxVfo->freq_config_RX.Code = gScanCssResultCode; - } + 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 = stepSetting; - } - else { - RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD); - RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD); + gTxVfo->freq_config_TX = gTxVfo->freq_config_RX; + gTxVfo->STEP_SETTING = stepSetting; + } + else { + RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD); + RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD); - gTxVfo->freq_config_RX.CodeType = gScanCssResultType; - gTxVfo->freq_config_RX.Code = gScanCssResultCode; - gTxVfo->freq_config_TX.CodeType = gScanCssResultType; - gTxVfo->freq_config_TX.Code = gScanCssResultCode; - } + gTxVfo->freq_config_RX.CodeType = gScanCssResultType; + gTxVfo->freq_config_RX.Code = gScanCssResultCode; + gTxVfo->freq_config_TX.CodeType = gScanCssResultType; + gTxVfo->freq_config_TX.Code = gScanCssResultCode; + } - uint8_t chan; - if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) { - chan = gScanChannel; - gEeprom.MrChannel[gEeprom.TX_VFO] = chan; - } - else { - chan = gTxVfo->Band + FREQ_CHANNEL_FIRST; - gEeprom.FreqChannel[gEeprom.TX_VFO] = chan; - } + uint8_t chan; + if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) { + chan = gScanChannel; + gEeprom.MrChannel[gEeprom.TX_VFO] = chan; + } + else { + chan = gTxVfo->Band + FREQ_CHANNEL_FIRST; + gEeprom.FreqChannel[gEeprom.TX_VFO] = chan; + } - gTxVfo->CHANNEL_SAVE = chan; - gEeprom.ScreenChannel[gEeprom.TX_VFO] = chan; -#ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_CONFIRM; + 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; + gRequestDisplayScreen = DISPLAY_SCANNER; + gRequestSaveChannel = 2; + gScannerSaveState = SCAN_SAVE_NO_PROMPT; + break; - default: - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - break; - } + default: + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + break; + } } static void SCANNER_Key_STAR(bool bKeyPressed, bool bKeyHeld) { - if (!bKeyHeld && bKeyPressed) { - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - SCANNER_Start(gScanSingleFrequency); - } - return; + if (!bKeyHeld && bKeyPressed) { + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + SCANNER_Start(gScanSingleFrequency); + } + return; } static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Direction) { - if (pKeyHeld) { - if (!bKeyPressed) - return; - } - else { - if (!bKeyPressed) - return; + if (pKeyHeld) { + if (!bKeyPressed) + return; + } + else { + if (!bKeyPressed) + return; - gInputBoxIndex = 0; - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - } + gInputBoxIndex = 0; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + } - if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) { - gScanChannel = NUMBER_AddWithWraparound(gScanChannel, Direction, 0, MR_CHANNEL_LAST); - gShowChPrefix = RADIO_CheckValidChannel(gScanChannel, false, 0); - gRequestDisplayScreen = DISPLAY_SCANNER; - } - else - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) { + gScanChannel = NUMBER_AddWithWraparound(gScanChannel, Direction, 0, MR_CHANNEL_LAST); + gShowChPrefix = RADIO_CheckValidChannel(gScanChannel, false, 0); + gRequestDisplayScreen = DISPLAY_SCANNER; + } + else + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; } void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { - switch (Key) { - case KEY_0...KEY_9: - SCANNER_Key_DIGITS(Key, bKeyPressed, bKeyHeld); - break; - case KEY_MENU: - SCANNER_Key_MENU(bKeyPressed, bKeyHeld); - break; - case KEY_UP: - SCANNER_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1); - break; - case KEY_DOWN: - SCANNER_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1); - break; - case KEY_EXIT: - SCANNER_Key_EXIT(bKeyPressed, bKeyHeld); - break; - case KEY_STAR: - SCANNER_Key_STAR(bKeyPressed, bKeyHeld); - break; - case KEY_PTT: - GENERIC_Key_PTT(bKeyPressed); - break; - default: - if (!bKeyHeld && bKeyPressed) - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - break; - } + switch (Key) { + case KEY_0...KEY_9: + SCANNER_Key_DIGITS(Key, bKeyPressed, bKeyHeld); + break; + case KEY_MENU: + SCANNER_Key_MENU(bKeyPressed, bKeyHeld); + break; + case KEY_UP: + SCANNER_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1); + break; + case KEY_DOWN: + SCANNER_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1); + break; + case KEY_EXIT: + SCANNER_Key_EXIT(bKeyPressed, bKeyHeld); + break; + case KEY_STAR: + SCANNER_Key_STAR(bKeyPressed, bKeyHeld); + break; + case KEY_PTT: + GENERIC_Key_PTT(bKeyPressed); + break; + default: + if (!bKeyHeld && bKeyPressed) + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + break; + } } void SCANNER_Start(bool singleFreq) { - gScanSingleFrequency = singleFreq; - gMonitor = false; + gScanSingleFrequency = singleFreq; + gMonitor = false; #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN; + gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN; #endif - BK4819_StopScan(); - RADIO_SelectVfos(); + BK4819_StopScan(); + RADIO_SelectVfos(); #ifdef ENABLE_NOAA - if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) - gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + BAND6_400MHz; + if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) + gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + BAND6_400MHz; #endif - uint8_t backupStep = gRxVfo->STEP_SETTING; - uint16_t backupFrequency = gRxVfo->StepFrequency; + uint8_t backupStep = gRxVfo->STEP_SETTING; + 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->StepFrequency = backupFrequency; + gRxVfo->STEP_SETTING = backupStep; + gRxVfo->StepFrequency = backupFrequency; - RADIO_SetupRegisters(true); + RADIO_SetupRegisters(true); #ifdef ENABLE_NOAA - gIsNoaaMode = false; + gIsNoaaMode = false; #endif - if (gScanSingleFrequency) { - gScanCssState = SCAN_CSS_STATE_SCANNING; - gScanFrequency = gRxVfo->pRX->Frequency; - stepSetting = gRxVfo->STEP_SETTING; + if (gScanSingleFrequency) { + gScanCssState = SCAN_CSS_STATE_SCANNING; + gScanFrequency = gRxVfo->pRX->Frequency; + stepSetting = gRxVfo->STEP_SETTING; - BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency); - BK4819_SetScanFrequency(gScanFrequency); + BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency); + BK4819_SetScanFrequency(gScanFrequency); - gUpdateStatus = true; - } - else { - gScanCssState = SCAN_CSS_STATE_OFF; - gScanFrequency = 0xFFFFFFFF; + gUpdateStatus = true; + } + else { + gScanCssState = SCAN_CSS_STATE_OFF; + gScanFrequency = 0xFFFFFFFF; - BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency); - BK4819_EnableFrequencyScan(); + BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency); + BK4819_EnableFrequencyScan(); - gUpdateStatus = true; - } + gUpdateStatus = true; + } #ifdef ENABLE_DTMF_CALLING - DTMF_clear_RX(); + DTMF_clear_RX(); #endif - gScanDelay_10ms = scan_delay_10ms; - gScanCssResultCode = 0xFF; - gScanCssResultType = 0xFF; - scanHitCount = 0; - gScanUseCssResult = false; - g_CxCSS_TAIL_Found = false; - g_CDCSS_Lost = false; - gCDCSSCodeType = 0; - g_CTCSS_Lost = false; + gScanDelay_10ms = scan_delay_10ms; + gScanCssResultCode = 0xFF; + gScanCssResultType = 0xFF; + scanHitCount = 0; + gScanUseCssResult = false; + g_CxCSS_TAIL_Found = false; + g_CDCSS_Lost = false; + gCDCSSCodeType = 0; + g_CTCSS_Lost = false; #ifdef ENABLE_VOX - g_VOX_Lost = false; + g_VOX_Lost = false; #endif - g_SquelchLost = false; - gScannerSaveState = SCAN_SAVE_NO_PROMPT; - gScanProgressIndicator = 0; + g_SquelchLost = false; + gScannerSaveState = SCAN_SAVE_NO_PROMPT; + gScanProgressIndicator = 0; } void SCANNER_Stop(void) { - if(SCANNER_IsScanning()) { - gEeprom.CROSS_BAND_RX_TX = gBackup_CROSS_BAND_RX_TX; - gVfoConfigureMode = VFO_CONFIGURE_RELOAD; - gFlagResetVfos = true; - gUpdateStatus = true; - gCssBackgroundScan = false; - gScanUseCssResult = false; + if(SCANNER_IsScanning()) { + gEeprom.CROSS_BAND_RX_TX = gBackup_CROSS_BAND_RX_TX; + gVfoConfigureMode = VFO_CONFIGURE_RELOAD; + gFlagResetVfos = true; + gUpdateStatus = true; + gCssBackgroundScan = false; + gScanUseCssResult = false; #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_CANCEL; + gAnotherVoiceID = VOICE_ID_CANCEL; #endif - BK4819_StopScan(); - } + BK4819_StopScan(); + } } void SCANNER_TimeSlice10ms(void) { - if (!SCANNER_IsScanning()) - return; + if (!SCANNER_IsScanning()) + return; - if (gScanDelay_10ms > 0) { - gScanDelay_10ms--; - return; - } + if (gScanDelay_10ms > 0) { + gScanDelay_10ms--; + return; + } - if (gScannerSaveState != SCAN_SAVE_NO_PROMPT) { - 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; + 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; + int32_t delta = result - gScanFrequency; + gScanFrequency = result; - if (delta < 0) - delta = -delta; - if (delta < 100) - scanHitCount++; - else - scanHitCount = 0; + if (delta < 0) + delta = -delta; + if (delta < 100) + scanHitCount++; + else + scanHitCount = 0; - BK4819_DisableFrequencyScan(); + 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; + if (scanHitCount < 3) { + BK4819_EnableFrequencyScan(); + } + else { + BK4819_SetScanFrequency(gScanFrequency); + gScanCssResultCode = 0xFF; + gScanCssResultType = 0xFF; + scanHitCount = 0; + gScanUseCssResult = false; + gScanProgressIndicator = 0; + gScanCssState = SCAN_CSS_STATE_SCANNING; - if(!gCssBackgroundScan) - GUI_SelectNextDisplay(DISPLAY_SCANNER); + if(!gCssBackgroundScan) + GUI_SelectNextDisplay(DISPLAY_SCANNER); - gUpdateStatus = true; - } + 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; + 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(); + 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; + 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; - } - } + gScanCssResultType = CODE_TYPE_CONTINUOUS_TONE; + gScanCssResultCode = Code; + } + } - if (gScanCssState < SCAN_CSS_STATE_FOUND) { // scanning or off - BK4819_SetScanFrequency(gScanFrequency); - gScanDelay_10ms = scan_delay_10ms; - break; - } + if (gScanCssState < SCAN_CSS_STATE_FOUND) { // scanning or off + BK4819_SetScanFrequency(gScanFrequency); + gScanDelay_10ms = scan_delay_10ms; + break; + } - if(gCssBackgroundScan) { - gCssBackgroundScan = false; - if(gScanUseCssResult) - MENU_CssScanFound(); - } - else - GUI_SelectNextDisplay(DISPLAY_SCANNER); + if(gCssBackgroundScan) { + gCssBackgroundScan = false; + if(gScanUseCssResult) + MENU_CssScanFound(); + } + else + GUI_SelectNextDisplay(DISPLAY_SCANNER); - break; - } - default: - gCssBackgroundScan = false; - break; - } + break; + } + default: + gCssBackgroundScan = false; + break; + } } void SCANNER_TimeSlice500ms(void) { - if (SCANNER_IsScanning() && gScannerSaveState == SCAN_SAVE_NO_PROMPT && gScanCssState < SCAN_CSS_STATE_FOUND) { - gScanProgressIndicator++; + if (SCANNER_IsScanning() && gScannerSaveState == SCAN_SAVE_NO_PROMPT && gScanCssState < SCAN_CSS_STATE_FOUND) { + gScanProgressIndicator++; #ifndef ENABLE_NO_CODE_SCAN_TIMEOUT - if (gScanProgressIndicator > 32) { - if (gScanCssState == SCAN_CSS_STATE_SCANNING && !gScanSingleFrequency) - gScanCssState = SCAN_CSS_STATE_FOUND; - else - gScanCssState = SCAN_CSS_STATE_FAILED; + if (gScanProgressIndicator > 32) { + if (gScanCssState == SCAN_CSS_STATE_SCANNING && !gScanSingleFrequency) + gScanCssState = SCAN_CSS_STATE_FOUND; + else + gScanCssState = SCAN_CSS_STATE_FAILED; - gUpdateStatus = true; - } + gUpdateStatus = true; + } #endif - gUpdateDisplay = true; - } - else if(gCssBackgroundScan) { - gUpdateDisplay = true; - } + gUpdateDisplay = true; + } + else if(gCssBackgroundScan) { + gUpdateDisplay = true; + } } bool SCANNER_IsScanning(void) { - return gCssBackgroundScan || (gScreenToDisplay == DISPLAY_SCANNER); + return gCssBackgroundScan || (gScreenToDisplay == DISPLAY_SCANNER); } \ No newline at end of file diff --git a/app/scanner.h b/app/scanner.h index a62deb6..6217ef5 100644 --- a/app/scanner.h +++ b/app/scanner.h @@ -22,17 +22,17 @@ typedef enum { - SCAN_CSS_STATE_OFF, - SCAN_CSS_STATE_SCANNING, - SCAN_CSS_STATE_FOUND, - SCAN_CSS_STATE_FAILED + SCAN_CSS_STATE_OFF, + SCAN_CSS_STATE_SCANNING, + SCAN_CSS_STATE_FOUND, + SCAN_CSS_STATE_FAILED } SCAN_CssState_t; typedef enum { - 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_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; diff --git a/app/uart.c b/app/uart.c index a1b1fc5..b878d1d 100644 --- a/app/uart.c +++ b/app/uart.c @@ -17,10 +17,10 @@ #include #if !defined(ENABLE_OVERLAY) - #include "ARMCM0.h" + #include "ARMCM0.h" #endif #ifdef ENABLE_FMRADIO - #include "app/fm.h" + #include "app/fm.h" #endif #include "app/uart.h" #include "board.h" @@ -39,7 +39,7 @@ #include "version.h" #if defined(ENABLE_OVERLAY) - #include "sram-overlay.h" + #include "sram-overlay.h" #endif #define UNUSED(x) (void)(x) @@ -47,113 +47,113 @@ #define DMA_INDEX(x, y) (((x) + (y)) % sizeof(UART_DMA_Buffer)) typedef struct { - uint16_t ID; - uint16_t Size; + uint16_t ID; + uint16_t Size; } Header_t; typedef struct { - uint8_t Padding[2]; - uint16_t ID; + uint8_t Padding[2]; + uint16_t ID; } Footer_t; typedef struct { - Header_t Header; - uint32_t Timestamp; + Header_t Header; + uint32_t Timestamp; } CMD_0514_t; typedef struct { - Header_t Header; - struct { - char Version[16]; - bool bHasCustomAesKey; - bool bIsInLockScreen; - uint8_t Padding[2]; - uint32_t Challenge[4]; - } Data; + Header_t Header; + struct { + char Version[16]; + bool bHasCustomAesKey; + bool bIsInLockScreen; + uint8_t Padding[2]; + uint32_t Challenge[4]; + } Data; } REPLY_0514_t; typedef struct { - Header_t Header; - uint16_t Offset; - uint8_t Size; - uint8_t Padding; - uint32_t Timestamp; + Header_t Header; + uint16_t Offset; + uint8_t Size; + uint8_t Padding; + uint32_t Timestamp; } CMD_051B_t; typedef struct { - Header_t Header; - struct { - uint16_t Offset; - uint8_t Size; - uint8_t Padding; - uint8_t Data[128]; - } Data; + Header_t Header; + struct { + uint16_t Offset; + uint8_t Size; + uint8_t Padding; + uint8_t Data[128]; + } Data; } REPLY_051B_t; typedef struct { - Header_t Header; - uint16_t Offset; - uint8_t Size; - bool bAllowPassword; - uint32_t Timestamp; - uint8_t Data[0]; + Header_t Header; + uint16_t Offset; + uint8_t Size; + bool bAllowPassword; + uint32_t Timestamp; + uint8_t Data[0]; } CMD_051D_t; typedef struct { - Header_t Header; - struct { - uint16_t Offset; - } Data; + Header_t Header; + struct { + uint16_t Offset; + } Data; } REPLY_051D_t; typedef struct { - Header_t Header; - struct { - uint16_t RSSI; - uint8_t ExNoiseIndicator; - uint8_t GlitchIndicator; - } Data; + Header_t Header; + struct { + uint16_t RSSI; + uint8_t ExNoiseIndicator; + uint8_t GlitchIndicator; + } Data; } REPLY_0527_t; typedef struct { - Header_t Header; - struct { - uint16_t Voltage; - uint16_t Current; - } Data; + Header_t Header; + struct { + uint16_t Voltage; + uint16_t Current; + } Data; } REPLY_0529_t; typedef struct { - Header_t Header; - uint32_t Response[4]; + Header_t Header; + uint32_t Response[4]; } CMD_052D_t; typedef struct { - Header_t Header; - struct { - bool bIsLocked; - uint8_t Padding[3]; - } Data; + Header_t Header; + struct { + bool bIsLocked; + uint8_t Padding[3]; + } Data; } REPLY_052D_t; typedef struct { - Header_t Header; - uint32_t Timestamp; + Header_t Header; + uint32_t Timestamp; } CMD_052F_t; static const uint8_t Obfuscation[16] = { - 0x16, 0x6C, 0x14, 0xE6, 0x2E, 0x91, 0x0D, 0x40, 0x21, 0x35, 0xD5, 0x40, 0x13, 0x03, 0xE9, 0x80 + 0x16, 0x6C, 0x14, 0xE6, 0x2E, 0x91, 0x0D, 0x40, 0x21, 0x35, 0xD5, 0x40, 0x13, 0x03, 0xE9, 0x80 }; static union { - uint8_t Buffer[256]; - struct - { - Header_t Header; - uint8_t Data[252]; - }; + uint8_t Buffer[256]; + struct + { + Header_t Header; + uint8_t Data[252]; + }; } UART_Command; static uint32_t Timestamp; @@ -162,243 +162,243 @@ static bool bIsEncrypted = true; static void SendReply(void *pReply, uint16_t Size) { - Header_t Header; - Footer_t Footer; + Header_t Header; + Footer_t Footer; - if (bIsEncrypted) - { - uint8_t *pBytes = (uint8_t *)pReply; - unsigned int i; - for (i = 0; i < Size; i++) - pBytes[i] ^= Obfuscation[i % 16]; - } + if (bIsEncrypted) + { + uint8_t *pBytes = (uint8_t *)pReply; + unsigned int i; + for (i = 0; i < Size; i++) + pBytes[i] ^= Obfuscation[i % 16]; + } - Header.ID = 0xCDAB; - Header.Size = Size; - UART_Send(&Header, sizeof(Header)); - UART_Send(pReply, Size); + Header.ID = 0xCDAB; + Header.Size = Size; + UART_Send(&Header, sizeof(Header)); + UART_Send(pReply, Size); - if (bIsEncrypted) - { - Footer.Padding[0] = Obfuscation[(Size + 0) % 16] ^ 0xFF; - Footer.Padding[1] = Obfuscation[(Size + 1) % 16] ^ 0xFF; - } - else - { - Footer.Padding[0] = 0xFF; - Footer.Padding[1] = 0xFF; - } - Footer.ID = 0xBADC; + if (bIsEncrypted) + { + Footer.Padding[0] = Obfuscation[(Size + 0) % 16] ^ 0xFF; + Footer.Padding[1] = Obfuscation[(Size + 1) % 16] ^ 0xFF; + } + else + { + Footer.Padding[0] = 0xFF; + Footer.Padding[1] = 0xFF; + } + Footer.ID = 0xBADC; - UART_Send(&Footer, sizeof(Footer)); + UART_Send(&Footer, sizeof(Footer)); } static void SendVersion(void) { - REPLY_0514_t Reply; + REPLY_0514_t Reply; - Reply.Header.ID = 0x0515; - Reply.Header.Size = sizeof(Reply.Data); - strcpy(Reply.Data.Version, Version); - Reply.Data.bHasCustomAesKey = bHasCustomAesKey; - Reply.Data.bIsInLockScreen = bIsInLockScreen; - Reply.Data.Challenge[0] = gChallenge[0]; - Reply.Data.Challenge[1] = gChallenge[1]; - Reply.Data.Challenge[2] = gChallenge[2]; - Reply.Data.Challenge[3] = gChallenge[3]; + Reply.Header.ID = 0x0515; + Reply.Header.Size = sizeof(Reply.Data); + strcpy(Reply.Data.Version, Version); + Reply.Data.bHasCustomAesKey = bHasCustomAesKey; + Reply.Data.bIsInLockScreen = bIsInLockScreen; + Reply.Data.Challenge[0] = gChallenge[0]; + Reply.Data.Challenge[1] = gChallenge[1]; + Reply.Data.Challenge[2] = gChallenge[2]; + Reply.Data.Challenge[3] = gChallenge[3]; - SendReply(&Reply, sizeof(Reply)); + SendReply(&Reply, sizeof(Reply)); } static bool IsBadChallenge(const uint32_t *pKey, const uint32_t *pIn, const uint32_t *pResponse) { - #ifdef ENABLE_FEAT_F4HWN - UNUSED(pKey); - UNUSED(pIn); - UNUSED(pResponse); + #ifdef ENABLE_FEAT_F4HWN + UNUSED(pKey); + UNUSED(pIn); + UNUSED(pResponse); #else - unsigned int i; - uint32_t IV[4]; + unsigned int i; + uint32_t IV[4]; - IV[0] = 0; - IV[1] = 0; - IV[2] = 0; - IV[3] = 0; + IV[0] = 0; + IV[1] = 0; + IV[2] = 0; + IV[3] = 0; - AES_Encrypt(pKey, IV, pIn, IV, true); + AES_Encrypt(pKey, IV, pIn, IV, true); - for (i = 0; i < 4; i++) - if (IV[i] != pResponse[i]) - return true; - #endif - return false; + for (i = 0; i < 4; i++) + if (IV[i] != pResponse[i]) + return true; + #endif + return false; } // session init, sends back version info and state // timestamp is a session id really static void CMD_0514(const uint8_t *pBuffer) { - const CMD_0514_t *pCmd = (const CMD_0514_t *)pBuffer; + const CMD_0514_t *pCmd = (const CMD_0514_t *)pBuffer; - Timestamp = pCmd->Timestamp; + Timestamp = pCmd->Timestamp; - #ifdef ENABLE_FMRADIO - gFmRadioCountdown_500ms = fm_radio_countdown_500ms; - #endif + #ifdef ENABLE_FMRADIO + gFmRadioCountdown_500ms = fm_radio_countdown_500ms; + #endif - gSerialConfigCountDown_500ms = 12; // 6 sec - - // turn the LCD backlight off - BACKLIGHT_TurnOff(); + gSerialConfigCountDown_500ms = 12; // 6 sec + + // turn the LCD backlight off + BACKLIGHT_TurnOff(); - SendVersion(); + SendVersion(); } // read eeprom static void CMD_051B(const uint8_t *pBuffer) { - const CMD_051B_t *pCmd = (const CMD_051B_t *)pBuffer; - REPLY_051B_t Reply; - bool bLocked = false; + const CMD_051B_t *pCmd = (const CMD_051B_t *)pBuffer; + REPLY_051B_t Reply; + bool bLocked = false; - if (pCmd->Timestamp != Timestamp) - return; + if (pCmd->Timestamp != Timestamp) + return; - gSerialConfigCountDown_500ms = 12; // 6 sec + gSerialConfigCountDown_500ms = 12; // 6 sec - #ifdef ENABLE_FMRADIO - gFmRadioCountdown_500ms = fm_radio_countdown_500ms; - #endif + #ifdef ENABLE_FMRADIO + gFmRadioCountdown_500ms = fm_radio_countdown_500ms; + #endif - memset(&Reply, 0, sizeof(Reply)); - Reply.Header.ID = 0x051C; - Reply.Header.Size = pCmd->Size + 4; - Reply.Data.Offset = pCmd->Offset; - Reply.Data.Size = pCmd->Size; + memset(&Reply, 0, sizeof(Reply)); + Reply.Header.ID = 0x051C; + Reply.Header.Size = pCmd->Size + 4; + Reply.Data.Offset = pCmd->Offset; + Reply.Data.Size = pCmd->Size; - if (bHasCustomAesKey) - bLocked = gIsLocked; + if (bHasCustomAesKey) + bLocked = gIsLocked; - if (!bLocked) - EEPROM_ReadBuffer(pCmd->Offset, Reply.Data.Data, pCmd->Size); + if (!bLocked) + EEPROM_ReadBuffer(pCmd->Offset, Reply.Data.Data, pCmd->Size); - SendReply(&Reply, pCmd->Size + 8); + SendReply(&Reply, pCmd->Size + 8); } // write eeprom static void CMD_051D(const uint8_t *pBuffer) { - const CMD_051D_t *pCmd = (const CMD_051D_t *)pBuffer; - REPLY_051D_t Reply; - bool bReloadEeprom; - bool bIsLocked; + const CMD_051D_t *pCmd = (const CMD_051D_t *)pBuffer; + REPLY_051D_t Reply; + bool bReloadEeprom; + bool bIsLocked; - if (pCmd->Timestamp != Timestamp) - return; + if (pCmd->Timestamp != Timestamp) + return; - gSerialConfigCountDown_500ms = 12; // 6 sec - - bReloadEeprom = false; + gSerialConfigCountDown_500ms = 12; // 6 sec + + bReloadEeprom = false; - #ifdef ENABLE_FMRADIO - gFmRadioCountdown_500ms = fm_radio_countdown_500ms; - #endif + #ifdef ENABLE_FMRADIO + gFmRadioCountdown_500ms = fm_radio_countdown_500ms; + #endif - Reply.Header.ID = 0x051E; - Reply.Header.Size = sizeof(Reply.Data); - Reply.Data.Offset = pCmd->Offset; + Reply.Header.ID = 0x051E; + Reply.Header.Size = sizeof(Reply.Data); + Reply.Data.Offset = pCmd->Offset; - bIsLocked = bHasCustomAesKey ? gIsLocked : bHasCustomAesKey; + bIsLocked = bHasCustomAesKey ? gIsLocked : bHasCustomAesKey; - if (!bIsLocked) - { - unsigned int i; - for (i = 0; i < (pCmd->Size / 8); i++) - { - const uint16_t Offset = pCmd->Offset + (i * 8U); + if (!bIsLocked) + { + unsigned int i; + for (i = 0; i < (pCmd->Size / 8); i++) + { + const uint16_t Offset = pCmd->Offset + (i * 8U); - if (Offset >= 0x0F30 && Offset < 0x0F40) - if (!gIsLocked) - bReloadEeprom = true; + if (Offset >= 0x0F30 && Offset < 0x0F40) + if (!gIsLocked) + bReloadEeprom = true; - if ((Offset < 0x0E98 || Offset >= 0x0EA0) || !bIsInLockScreen || pCmd->bAllowPassword) - EEPROM_WriteBuffer(Offset, &pCmd->Data[i * 8U]); - } + if ((Offset < 0x0E98 || Offset >= 0x0EA0) || !bIsInLockScreen || pCmd->bAllowPassword) + EEPROM_WriteBuffer(Offset, &pCmd->Data[i * 8U]); + } - if (bReloadEeprom) - SETTINGS_InitEEPROM(); - } + if (bReloadEeprom) + SETTINGS_InitEEPROM(); + } - SendReply(&Reply, sizeof(Reply)); + SendReply(&Reply, sizeof(Reply)); } // read RSSI static void CMD_0527(void) { - REPLY_0527_t Reply; + REPLY_0527_t Reply; - Reply.Header.ID = 0x0528; - Reply.Header.Size = sizeof(Reply.Data); - Reply.Data.RSSI = BK4819_ReadRegister(BK4819_REG_67) & 0x01FF; - Reply.Data.ExNoiseIndicator = BK4819_ReadRegister(BK4819_REG_65) & 0x007F; - Reply.Data.GlitchIndicator = BK4819_ReadRegister(BK4819_REG_63); + Reply.Header.ID = 0x0528; + Reply.Header.Size = sizeof(Reply.Data); + Reply.Data.RSSI = BK4819_ReadRegister(BK4819_REG_67) & 0x01FF; + Reply.Data.ExNoiseIndicator = BK4819_ReadRegister(BK4819_REG_65) & 0x007F; + Reply.Data.GlitchIndicator = BK4819_ReadRegister(BK4819_REG_63); - SendReply(&Reply, sizeof(Reply)); + SendReply(&Reply, sizeof(Reply)); } // read ADC static void CMD_0529(void) { - REPLY_0529_t Reply; + REPLY_0529_t Reply; - Reply.Header.ID = 0x52A; - Reply.Header.Size = sizeof(Reply.Data); + Reply.Header.ID = 0x52A; + Reply.Header.Size = sizeof(Reply.Data); - // Original doesn't actually send current! - BOARD_ADC_GetBatteryInfo(&Reply.Data.Voltage, &Reply.Data.Current); + // Original doesn't actually send current! + BOARD_ADC_GetBatteryInfo(&Reply.Data.Voltage, &Reply.Data.Current); - SendReply(&Reply, sizeof(Reply)); + SendReply(&Reply, sizeof(Reply)); } static void CMD_052D(const uint8_t *pBuffer) { - const CMD_052D_t *pCmd = (const CMD_052D_t *)pBuffer; - REPLY_052D_t Reply; - bool bIsLocked; + const CMD_052D_t *pCmd = (const CMD_052D_t *)pBuffer; + REPLY_052D_t Reply; + bool bIsLocked; - #ifdef ENABLE_FMRADIO - gFmRadioCountdown_500ms = fm_radio_countdown_500ms; - #endif - Reply.Header.ID = 0x052E; - Reply.Header.Size = sizeof(Reply.Data); + #ifdef ENABLE_FMRADIO + gFmRadioCountdown_500ms = fm_radio_countdown_500ms; + #endif + Reply.Header.ID = 0x052E; + Reply.Header.Size = sizeof(Reply.Data); - bIsLocked = bHasCustomAesKey; + bIsLocked = bHasCustomAesKey; - if (!bIsLocked) - bIsLocked = IsBadChallenge(gCustomAesKey, gChallenge, pCmd->Response); + if (!bIsLocked) + bIsLocked = IsBadChallenge(gCustomAesKey, gChallenge, pCmd->Response); - if (!bIsLocked) - { - bIsLocked = IsBadChallenge(gDefaultAesKey, gChallenge, pCmd->Response); - if (bIsLocked) - gTryCount++; - } + if (!bIsLocked) + { + bIsLocked = IsBadChallenge(gDefaultAesKey, gChallenge, pCmd->Response); + if (bIsLocked) + gTryCount++; + } - if (gTryCount < 3) - { - if (!bIsLocked) - gTryCount = 0; - } - else - { - gTryCount = 3; - bIsLocked = true; - } - - gIsLocked = bIsLocked; - Reply.Data.bIsLocked = bIsLocked; + if (gTryCount < 3) + { + if (!bIsLocked) + gTryCount = 0; + } + else + { + gTryCount = 3; + bIsLocked = true; + } + + gIsLocked = bIsLocked; + Reply.Data.bIsLocked = bIsLocked; - SendReply(&Reply, sizeof(Reply)); + SendReply(&Reply, sizeof(Reply)); } // session init, sends back version info and state @@ -408,223 +408,223 @@ static void CMD_052D(const uint8_t *pBuffer) // exits power save, sets main VFO to upper, static void CMD_052F(const uint8_t *pBuffer) { - const CMD_052F_t *pCmd = (const CMD_052F_t *)pBuffer; + const CMD_052F_t *pCmd = (const CMD_052F_t *)pBuffer; - gEeprom.DUAL_WATCH = DUAL_WATCH_OFF; - gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF; - gEeprom.RX_VFO = 0; - gEeprom.DTMF_SIDE_TONE = false; - gEeprom.VfoInfo[0].FrequencyReverse = false; - gEeprom.VfoInfo[0].pRX = &gEeprom.VfoInfo[0].freq_config_RX; - gEeprom.VfoInfo[0].pTX = &gEeprom.VfoInfo[0].freq_config_TX; - gEeprom.VfoInfo[0].TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF; - gEeprom.VfoInfo[0].DTMF_PTT_ID_TX_MODE = PTT_ID_OFF; + gEeprom.DUAL_WATCH = DUAL_WATCH_OFF; + gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF; + gEeprom.RX_VFO = 0; + gEeprom.DTMF_SIDE_TONE = false; + gEeprom.VfoInfo[0].FrequencyReverse = false; + gEeprom.VfoInfo[0].pRX = &gEeprom.VfoInfo[0].freq_config_RX; + gEeprom.VfoInfo[0].pTX = &gEeprom.VfoInfo[0].freq_config_TX; + gEeprom.VfoInfo[0].TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF; + gEeprom.VfoInfo[0].DTMF_PTT_ID_TX_MODE = PTT_ID_OFF; #ifdef ENABLE_DTMF_CALLING - gEeprom.VfoInfo[0].DTMF_DECODING_ENABLE = false; + gEeprom.VfoInfo[0].DTMF_DECODING_ENABLE = false; #endif - #ifdef ENABLE_NOAA - gIsNoaaMode = false; - #endif + #ifdef ENABLE_NOAA + gIsNoaaMode = false; + #endif - if (gCurrentFunction == FUNCTION_POWER_SAVE) - FUNCTION_Select(FUNCTION_FOREGROUND); + if (gCurrentFunction == FUNCTION_POWER_SAVE) + FUNCTION_Select(FUNCTION_FOREGROUND); - gSerialConfigCountDown_500ms = 12; // 6 sec + gSerialConfigCountDown_500ms = 12; // 6 sec - Timestamp = pCmd->Timestamp; + Timestamp = pCmd->Timestamp; - // turn the LCD backlight off - BACKLIGHT_TurnOff(); + // turn the LCD backlight off + BACKLIGHT_TurnOff(); - SendVersion(); + SendVersion(); } #ifdef ENABLE_UART_RW_BK_REGS static void CMD_0601_ReadBK4819Reg(const uint8_t *pBuffer) { - typedef struct __attribute__((__packed__)) { - Header_t header; - uint8_t reg; - } CMD_0601_t; + typedef struct __attribute__((__packed__)) { + Header_t header; + uint8_t reg; + } CMD_0601_t; - CMD_0601_t *cmd = (CMD_0601_t*) pBuffer; + CMD_0601_t *cmd = (CMD_0601_t*) pBuffer; - struct __attribute__((__packed__)) { - Header_t header; - struct __attribute__((__packed__)) { - uint8_t reg; - uint16_t value; - } data; - } reply; + struct __attribute__((__packed__)) { + Header_t header; + struct __attribute__((__packed__)) { + uint8_t reg; + uint16_t value; + } data; + } reply; - reply.header.ID = 0x0601; - reply.header.Size = sizeof(reply.data); - reply.data.reg = cmd->reg; - reply.data.value = BK4819_ReadRegister(cmd->reg); - SendReply(&reply, sizeof(reply)); + reply.header.ID = 0x0601; + reply.header.Size = sizeof(reply.data); + reply.data.reg = cmd->reg; + reply.data.value = BK4819_ReadRegister(cmd->reg); + SendReply(&reply, sizeof(reply)); } static void CMD_0602_WriteBK4819Reg(const uint8_t *pBuffer) { - typedef struct __attribute__((__packed__)) { - Header_t header; - uint8_t reg; - uint16_t value; - } CMD_0602_t; + typedef struct __attribute__((__packed__)) { + Header_t header; + uint8_t reg; + uint16_t value; + } CMD_0602_t; - CMD_0602_t *cmd = (CMD_0602_t*) pBuffer; - BK4819_WriteRegister(cmd->reg, cmd->value); + CMD_0602_t *cmd = (CMD_0602_t*) pBuffer; + BK4819_WriteRegister(cmd->reg, cmd->value); } #endif bool UART_IsCommandAvailable(void) { - uint16_t Index; - uint16_t TailIndex; - uint16_t Size; - uint16_t CRC; - uint16_t CommandLength; - uint16_t DmaLength = DMA_CH0->ST & 0xFFFU; + uint16_t Index; + uint16_t TailIndex; + uint16_t Size; + uint16_t CRC; + uint16_t CommandLength; + uint16_t DmaLength = DMA_CH0->ST & 0xFFFU; - while (1) - { - if (gUART_WriteIndex == DmaLength) - return false; + while (1) + { + if (gUART_WriteIndex == DmaLength) + return false; - while (gUART_WriteIndex != DmaLength && UART_DMA_Buffer[gUART_WriteIndex] != 0xABU) - gUART_WriteIndex = DMA_INDEX(gUART_WriteIndex, 1); + while (gUART_WriteIndex != DmaLength && UART_DMA_Buffer[gUART_WriteIndex] != 0xABU) + gUART_WriteIndex = DMA_INDEX(gUART_WriteIndex, 1); - if (gUART_WriteIndex == DmaLength) - return false; + if (gUART_WriteIndex == DmaLength) + return false; - if (gUART_WriteIndex < DmaLength) - CommandLength = DmaLength - gUART_WriteIndex; - else - CommandLength = (DmaLength + sizeof(UART_DMA_Buffer)) - gUART_WriteIndex; + if (gUART_WriteIndex < DmaLength) + CommandLength = DmaLength - gUART_WriteIndex; + else + CommandLength = (DmaLength + sizeof(UART_DMA_Buffer)) - gUART_WriteIndex; - if (CommandLength < 8) - return 0; + if (CommandLength < 8) + return 0; - if (UART_DMA_Buffer[DMA_INDEX(gUART_WriteIndex, 1)] == 0xCD) - break; + if (UART_DMA_Buffer[DMA_INDEX(gUART_WriteIndex, 1)] == 0xCD) + break; - gUART_WriteIndex = DMA_INDEX(gUART_WriteIndex, 1); - } + gUART_WriteIndex = DMA_INDEX(gUART_WriteIndex, 1); + } - Index = DMA_INDEX(gUART_WriteIndex, 2); - Size = (UART_DMA_Buffer[DMA_INDEX(Index, 1)] << 8) | UART_DMA_Buffer[Index]; + Index = DMA_INDEX(gUART_WriteIndex, 2); + Size = (UART_DMA_Buffer[DMA_INDEX(Index, 1)] << 8) | UART_DMA_Buffer[Index]; - if ((Size + 8u) > sizeof(UART_DMA_Buffer)) - { - gUART_WriteIndex = DmaLength; - return false; - } + if ((Size + 8u) > sizeof(UART_DMA_Buffer)) + { + gUART_WriteIndex = DmaLength; + return false; + } - if (CommandLength < (Size + 8)) - return false; + if (CommandLength < (Size + 8)) + return false; - Index = DMA_INDEX(Index, 2); - TailIndex = DMA_INDEX(Index, Size + 2); + Index = DMA_INDEX(Index, 2); + TailIndex = DMA_INDEX(Index, Size + 2); - if (UART_DMA_Buffer[TailIndex] != 0xDC || UART_DMA_Buffer[DMA_INDEX(TailIndex, 1)] != 0xBA) - { - gUART_WriteIndex = DmaLength; - return false; - } + if (UART_DMA_Buffer[TailIndex] != 0xDC || UART_DMA_Buffer[DMA_INDEX(TailIndex, 1)] != 0xBA) + { + gUART_WriteIndex = DmaLength; + return false; + } - if (TailIndex < Index) - { - const uint16_t ChunkSize = sizeof(UART_DMA_Buffer) - Index; - memcpy(UART_Command.Buffer, UART_DMA_Buffer + Index, ChunkSize); - memcpy(UART_Command.Buffer + ChunkSize, UART_DMA_Buffer, TailIndex); - } - else - memcpy(UART_Command.Buffer, UART_DMA_Buffer + Index, TailIndex - Index); + if (TailIndex < Index) + { + const uint16_t ChunkSize = sizeof(UART_DMA_Buffer) - Index; + memcpy(UART_Command.Buffer, UART_DMA_Buffer + Index, ChunkSize); + memcpy(UART_Command.Buffer + ChunkSize, UART_DMA_Buffer, TailIndex); + } + else + memcpy(UART_Command.Buffer, UART_DMA_Buffer + Index, TailIndex - Index); - TailIndex = DMA_INDEX(TailIndex, 2); - if (TailIndex < gUART_WriteIndex) - { - memset(UART_DMA_Buffer + gUART_WriteIndex, 0, sizeof(UART_DMA_Buffer) - gUART_WriteIndex); - memset(UART_DMA_Buffer, 0, TailIndex); - } - else - memset(UART_DMA_Buffer + gUART_WriteIndex, 0, TailIndex - gUART_WriteIndex); + TailIndex = DMA_INDEX(TailIndex, 2); + if (TailIndex < gUART_WriteIndex) + { + memset(UART_DMA_Buffer + gUART_WriteIndex, 0, sizeof(UART_DMA_Buffer) - gUART_WriteIndex); + memset(UART_DMA_Buffer, 0, TailIndex); + } + else + memset(UART_DMA_Buffer + gUART_WriteIndex, 0, TailIndex - gUART_WriteIndex); - gUART_WriteIndex = TailIndex; + gUART_WriteIndex = TailIndex; - if (UART_Command.Header.ID == 0x0514) - bIsEncrypted = false; + if (UART_Command.Header.ID == 0x0514) + bIsEncrypted = false; - if (UART_Command.Header.ID == 0x6902) - bIsEncrypted = true; + if (UART_Command.Header.ID == 0x6902) + bIsEncrypted = true; - if (bIsEncrypted) - { - unsigned int i; - for (i = 0; i < (Size + 2u); i++) - UART_Command.Buffer[i] ^= Obfuscation[i % 16]; - } - - CRC = UART_Command.Buffer[Size] | (UART_Command.Buffer[Size + 1] << 8); + if (bIsEncrypted) + { + unsigned int i; + for (i = 0; i < (Size + 2u); i++) + UART_Command.Buffer[i] ^= Obfuscation[i % 16]; + } + + CRC = UART_Command.Buffer[Size] | (UART_Command.Buffer[Size + 1] << 8); - return (CRC_Calculate(UART_Command.Buffer, Size) != CRC) ? false : true; + return (CRC_Calculate(UART_Command.Buffer, Size) != CRC) ? false : true; } void UART_HandleCommand(void) { - switch (UART_Command.Header.ID) - { - case 0x0514: - CMD_0514(UART_Command.Buffer); - break; - - case 0x051B: - CMD_051B(UART_Command.Buffer); - break; - - case 0x051D: - CMD_051D(UART_Command.Buffer); - break; - - case 0x051F: // Not implementing non-authentic command - break; - - case 0x0521: // Not implementing non-authentic command - break; - - case 0x0527: - CMD_0527(); - break; - - case 0x0529: - CMD_0529(); - break; - - case 0x052D: - CMD_052D(UART_Command.Buffer); - break; - - case 0x052F: - CMD_052F(UART_Command.Buffer); - break; - - case 0x05DD: // reset - #if defined(ENABLE_OVERLAY) - overlay_FLASH_RebootToBootloader(); - #else - NVIC_SystemReset(); - #endif - break; - + switch (UART_Command.Header.ID) + { + case 0x0514: + CMD_0514(UART_Command.Buffer); + break; + + case 0x051B: + CMD_051B(UART_Command.Buffer); + break; + + case 0x051D: + CMD_051D(UART_Command.Buffer); + break; + + case 0x051F: // Not implementing non-authentic command + break; + + case 0x0521: // Not implementing non-authentic command + break; + + case 0x0527: + CMD_0527(); + break; + + case 0x0529: + CMD_0529(); + break; + + case 0x052D: + CMD_052D(UART_Command.Buffer); + break; + + case 0x052F: + CMD_052F(UART_Command.Buffer); + break; + + case 0x05DD: // reset + #if defined(ENABLE_OVERLAY) + overlay_FLASH_RebootToBootloader(); + #else + NVIC_SystemReset(); + #endif + break; + #ifdef ENABLE_UART_RW_BK_REGS - case 0x0601: - CMD_0601_ReadBK4819Reg(UART_Command.Buffer); - break; - - case 0x0602: - CMD_0602_WriteBK4819Reg(UART_Command.Buffer); - break; + case 0x0601: + CMD_0601_ReadBK4819Reg(UART_Command.Buffer); + break; + + case 0x0602: + CMD_0602_WriteBK4819Reg(UART_Command.Buffer); + break; #endif - } + } } diff --git a/audio.c b/audio.c index f15be22..8392c08 100644 --- a/audio.c +++ b/audio.c @@ -15,12 +15,12 @@ */ #ifdef ENABLE_FMRADIO - #include "app/fm.h" + #include "app/fm.h" #endif #include "audio.h" #include "bsp/dp32g030/gpio.h" #ifdef ENABLE_FMRADIO - #include "driver/bk1080.h" + #include "driver/bk1080.h" #endif #include "driver/bk4819.h" #include "driver/gpio.h" @@ -37,162 +37,162 @@ BEEP_Type_t gBeepToPlay = BEEP_NONE; void AUDIO_PlayBeep(BEEP_Type_t Beep) { - if (Beep != BEEP_880HZ_60MS_DOUBLE_BEEP && - Beep != BEEP_500HZ_60MS_DOUBLE_BEEP && - Beep != BEEP_440HZ_500MS && + if (Beep != BEEP_880HZ_60MS_DOUBLE_BEEP && + Beep != BEEP_500HZ_60MS_DOUBLE_BEEP && + Beep != BEEP_440HZ_500MS && #ifdef ENABLE_DTMF_CALLING - Beep != BEEP_880HZ_200MS && - Beep != BEEP_880HZ_500MS && + Beep != BEEP_880HZ_200MS && + Beep != BEEP_880HZ_500MS && #endif #ifdef ENABLE_FEAT_F4HWN - Beep != BEEP_400HZ_30MS && - Beep != BEEP_500HZ_30MS && - Beep != BEEP_600HZ_30MS && + Beep != BEEP_400HZ_30MS && + Beep != BEEP_500HZ_30MS && + Beep != BEEP_600HZ_30MS && #endif - !gEeprom.BEEP_CONTROL) - return; + !gEeprom.BEEP_CONTROL) + return; #ifdef ENABLE_AIRCOPY - if (gScreenToDisplay == DISPLAY_AIRCOPY) - return; + if (gScreenToDisplay == DISPLAY_AIRCOPY) + return; #endif - if (gCurrentFunction == FUNCTION_RECEIVE) - return; + if (gCurrentFunction == FUNCTION_RECEIVE) + return; - if (gCurrentFunction == FUNCTION_MONITOR) - return; + if (gCurrentFunction == FUNCTION_MONITOR) + return; #ifdef ENABLE_FMRADIO - if (gFmRadioMode) - BK1080_Mute(true); + if (gFmRadioMode) + BK1080_Mute(true); #endif - AUDIO_AudioPathOff(); + AUDIO_AudioPathOff(); - if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode) - BK4819_RX_TurnOn(); + if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode) + BK4819_RX_TurnOn(); - SYSTEM_DelayMs(20); + SYSTEM_DelayMs(20); - uint16_t ToneConfig = BK4819_ReadRegister(BK4819_REG_71); + uint16_t ToneConfig = BK4819_ReadRegister(BK4819_REG_71); - uint16_t ToneFrequency; - switch (Beep) - { - default: - case BEEP_NONE: - ToneFrequency = 220; - break; - case BEEP_1KHZ_60MS_OPTIONAL: - ToneFrequency = 1000; - break; - case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL: - case BEEP_500HZ_60MS_DOUBLE_BEEP: - ToneFrequency = 500; - break; - case BEEP_440HZ_500MS: - ToneFrequency = 440; - break; - case BEEP_880HZ_60MS_DOUBLE_BEEP: + uint16_t ToneFrequency; + switch (Beep) + { + default: + case BEEP_NONE: + ToneFrequency = 220; + break; + case BEEP_1KHZ_60MS_OPTIONAL: + ToneFrequency = 1000; + break; + case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL: + case BEEP_500HZ_60MS_DOUBLE_BEEP: + ToneFrequency = 500; + break; + case BEEP_440HZ_500MS: + ToneFrequency = 440; + break; + case BEEP_880HZ_60MS_DOUBLE_BEEP: #ifndef ENABLE_FEAT_F4HWN - case BEEP_880HZ_200MS: - case BEEP_880HZ_500MS: + case BEEP_880HZ_200MS: + case BEEP_880HZ_500MS: #endif - ToneFrequency = 880; - break; + ToneFrequency = 880; + break; #ifdef ENABLE_FEAT_F4HWN - case BEEP_400HZ_30MS: - ToneFrequency = 400; - break; - case BEEP_500HZ_30MS: - ToneFrequency = 500; - break; - case BEEP_600HZ_30MS: - ToneFrequency = 600; - break; + case BEEP_400HZ_30MS: + ToneFrequency = 400; + break; + case BEEP_500HZ_30MS: + ToneFrequency = 500; + break; + case BEEP_600HZ_30MS: + ToneFrequency = 600; + break; #endif - } + } - if(Beep == BEEP_400HZ_30MS || Beep == BEEP_500HZ_30MS || Beep == BEEP_600HZ_30MS) - { - BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | ((1 & 0x7f) << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN)); - } + if(Beep == BEEP_400HZ_30MS || Beep == BEEP_500HZ_30MS || Beep == BEEP_600HZ_30MS) + { + BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | ((1 & 0x7f) << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN)); + } - BK4819_PlayTone(ToneFrequency, true); + BK4819_PlayTone(ToneFrequency, true); - SYSTEM_DelayMs(2); + SYSTEM_DelayMs(2); - AUDIO_AudioPathOn(); + AUDIO_AudioPathOn(); - SYSTEM_DelayMs(60); + SYSTEM_DelayMs(60); - uint16_t Duration; - switch (Beep) - { - case BEEP_880HZ_60MS_DOUBLE_BEEP: - BK4819_ExitTxMute(); - SYSTEM_DelayMs(60); - BK4819_EnterTxMute(); - SYSTEM_DelayMs(20); - [[fallthrough]]; - case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL: - case BEEP_500HZ_60MS_DOUBLE_BEEP: - BK4819_ExitTxMute(); - SYSTEM_DelayMs(60); - BK4819_EnterTxMute(); - SYSTEM_DelayMs(20); - [[fallthrough]]; - case BEEP_1KHZ_60MS_OPTIONAL: - BK4819_ExitTxMute(); - Duration = 60; - break; + uint16_t Duration; + switch (Beep) + { + case BEEP_880HZ_60MS_DOUBLE_BEEP: + BK4819_ExitTxMute(); + SYSTEM_DelayMs(60); + BK4819_EnterTxMute(); + SYSTEM_DelayMs(20); + [[fallthrough]]; + case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL: + case BEEP_500HZ_60MS_DOUBLE_BEEP: + BK4819_ExitTxMute(); + SYSTEM_DelayMs(60); + BK4819_EnterTxMute(); + SYSTEM_DelayMs(20); + [[fallthrough]]; + case BEEP_1KHZ_60MS_OPTIONAL: + BK4819_ExitTxMute(); + Duration = 60; + break; #ifdef ENABLE_FEAT_F4HWN - case BEEP_400HZ_30MS: - case BEEP_500HZ_30MS: - case BEEP_600HZ_30MS: - BK4819_ExitTxMute(); - Duration = 30; - break; + case BEEP_400HZ_30MS: + case BEEP_500HZ_30MS: + case BEEP_600HZ_30MS: + BK4819_ExitTxMute(); + Duration = 30; + break; #endif - case BEEP_440HZ_500MS: + case BEEP_440HZ_500MS: #ifndef ENABLE_FEAT_F4HWN - case BEEP_880HZ_200MS: - BK4819_ExitTxMute(); - Duration = 200; - break; - case BEEP_880HZ_500MS: + case BEEP_880HZ_200MS: + BK4819_ExitTxMute(); + Duration = 200; + break; + case BEEP_880HZ_500MS: #endif - default: - BK4819_ExitTxMute(); - Duration = 500; - break; - } + default: + BK4819_ExitTxMute(); + Duration = 500; + break; + } - SYSTEM_DelayMs(Duration); - BK4819_EnterTxMute(); - SYSTEM_DelayMs(20); + SYSTEM_DelayMs(Duration); + BK4819_EnterTxMute(); + SYSTEM_DelayMs(20); - AUDIO_AudioPathOff(); + AUDIO_AudioPathOff(); - SYSTEM_DelayMs(5); - BK4819_TurnsOffTones_TurnsOnRX(); - SYSTEM_DelayMs(5); - BK4819_WriteRegister(BK4819_REG_71, ToneConfig); + SYSTEM_DelayMs(5); + BK4819_TurnsOffTones_TurnsOnRX(); + SYSTEM_DelayMs(5); + BK4819_WriteRegister(BK4819_REG_71, ToneConfig); - if (gEnableSpeaker) - AUDIO_AudioPathOn(); + if (gEnableSpeaker) + AUDIO_AudioPathOn(); #ifdef ENABLE_FMRADIO - if (gFmRadioMode) - BK1080_Mute(false); + if (gFmRadioMode) + BK1080_Mute(false); #endif - if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode) - BK4819_Sleep(); + if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode) + BK4819_Sleep(); #ifdef ENABLE_VOX - gVoxResumeCountdown = 80; + gVoxResumeCountdown = 80; #endif } @@ -201,28 +201,28 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep) static const uint8_t VoiceClipLengthChinese[58] = { - 0x32, 0x32, 0x32, 0x37, 0x37, 0x32, 0x32, 0x32, - 0x32, 0x37, 0x37, 0x32, 0x64, 0x64, 0x64, 0x64, - 0x64, 0x69, 0x64, 0x69, 0x5A, 0x5F, 0x5F, 0x64, - 0x64, 0x69, 0x64, 0x64, 0x69, 0x69, 0x69, 0x64, - 0x64, 0x6E, 0x69, 0x5F, 0x64, 0x64, 0x64, 0x69, - 0x69, 0x69, 0x64, 0x69, 0x64, 0x64, 0x55, 0x5F, - 0x5A, 0x4B, 0x4B, 0x46, 0x46, 0x69, 0x64, 0x6E, - 0x5A, 0x64, + 0x32, 0x32, 0x32, 0x37, 0x37, 0x32, 0x32, 0x32, + 0x32, 0x37, 0x37, 0x32, 0x64, 0x64, 0x64, 0x64, + 0x64, 0x69, 0x64, 0x69, 0x5A, 0x5F, 0x5F, 0x64, + 0x64, 0x69, 0x64, 0x64, 0x69, 0x69, 0x69, 0x64, + 0x64, 0x6E, 0x69, 0x5F, 0x64, 0x64, 0x64, 0x69, + 0x69, 0x69, 0x64, 0x69, 0x64, 0x64, 0x55, 0x5F, + 0x5A, 0x4B, 0x4B, 0x46, 0x46, 0x69, 0x64, 0x6E, + 0x5A, 0x64, }; static const uint8_t VoiceClipLengthEnglish[76] = { - 0x50, 0x32, 0x2D, 0x2D, 0x2D, 0x37, 0x37, 0x37, - 0x32, 0x32, 0x3C, 0x37, 0x46, 0x46, 0x4B, 0x82, - 0x82, 0x6E, 0x82, 0x46, 0x96, 0x64, 0x46, 0x6E, - 0x78, 0x6E, 0x87, 0x64, 0x96, 0x96, 0x46, 0x9B, - 0x91, 0x82, 0x82, 0x73, 0x78, 0x64, 0x82, 0x6E, - 0x78, 0x82, 0x87, 0x6E, 0x55, 0x78, 0x64, 0x69, - 0x9B, 0x5A, 0x50, 0x3C, 0x32, 0x55, 0x64, 0x64, - 0x50, 0x46, 0x46, 0x46, 0x4B, 0x4B, 0x50, 0x50, - 0x55, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x37, - 0x41, 0x32, 0x3C, 0x37, + 0x50, 0x32, 0x2D, 0x2D, 0x2D, 0x37, 0x37, 0x37, + 0x32, 0x32, 0x3C, 0x37, 0x46, 0x46, 0x4B, 0x82, + 0x82, 0x6E, 0x82, 0x46, 0x96, 0x64, 0x46, 0x6E, + 0x78, 0x6E, 0x87, 0x64, 0x96, 0x96, 0x46, 0x9B, + 0x91, 0x82, 0x82, 0x73, 0x78, 0x64, 0x82, 0x6E, + 0x78, 0x82, 0x87, 0x6E, 0x55, 0x78, 0x64, 0x69, + 0x9B, 0x5A, 0x50, 0x3C, 0x32, 0x55, 0x64, 0x64, + 0x50, 0x46, 0x46, 0x46, 0x4B, 0x4B, 0x50, 0x50, + 0x55, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x37, + 0x41, 0x32, 0x3C, 0x37, }; VOICE_ID_t gVoiceID[8]; @@ -235,236 +235,236 @@ VOICE_ID_t gAnotherVoiceID = VOICE_ID_INVALID; static void AUDIO_PlayVoice(uint8_t VoiceID) { - unsigned int i; + unsigned int i; - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); - SYSTEM_DelayMs(20); - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); + SYSTEM_DelayMs(20); + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); - for (i = 0; i < 8; i++) - { - if ((VoiceID & 0x80U) == 0) - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1); - else - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1); + for (i = 0; i < 8; i++) + { + if ((VoiceID & 0x80U) == 0) + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1); + else + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1); - SYSTICK_DelayUs(1000); - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); - SYSTICK_DelayUs(1200); - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); - VoiceID <<= 1; - SYSTICK_DelayUs(200); - } + SYSTICK_DelayUs(1000); + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); + SYSTICK_DelayUs(1200); + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); + VoiceID <<= 1; + SYSTICK_DelayUs(200); + } } void AUDIO_PlaySingleVoice(bool bFlag) { - uint8_t VoiceID; - uint8_t Delay; + uint8_t VoiceID; + uint8_t Delay; - VoiceID = gVoiceID[0]; + VoiceID = gVoiceID[0]; - if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF && gVoiceWriteIndex > 0) - { - if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE) - { // Chinese - if (VoiceID >= ARRAY_SIZE(VoiceClipLengthChinese)) - goto Bailout; + if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF && gVoiceWriteIndex > 0) + { + if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE) + { // Chinese + if (VoiceID >= ARRAY_SIZE(VoiceClipLengthChinese)) + goto Bailout; - Delay = VoiceClipLengthChinese[VoiceID]; - VoiceID += VOICE_ID_CHI_BASE; - } - else - { // English - if (VoiceID >= ARRAY_SIZE(VoiceClipLengthEnglish)) - goto Bailout; + Delay = VoiceClipLengthChinese[VoiceID]; + VoiceID += VOICE_ID_CHI_BASE; + } + else + { // English + if (VoiceID >= ARRAY_SIZE(VoiceClipLengthEnglish)) + goto Bailout; - Delay = VoiceClipLengthEnglish[VoiceID]; - VoiceID += VOICE_ID_ENG_BASE; - } + Delay = VoiceClipLengthEnglish[VoiceID]; + VoiceID += VOICE_ID_ENG_BASE; + } - if (FUNCTION_IsRx()) // 1of11 - BK4819_SetAF(BK4819_AF_MUTE); + if (FUNCTION_IsRx()) // 1of11 + BK4819_SetAF(BK4819_AF_MUTE); - #ifdef ENABLE_FMRADIO - if (gFmRadioMode) - BK1080_Mute(true); - #endif + #ifdef ENABLE_FMRADIO + if (gFmRadioMode) + BK1080_Mute(true); + #endif - AUDIO_AudioPathOn(); + AUDIO_AudioPathOn(); - #ifdef ENABLE_VOX - gVoxResumeCountdown = 2000; - #endif + #ifdef ENABLE_VOX + gVoxResumeCountdown = 2000; + #endif - SYSTEM_DelayMs(5); - AUDIO_PlayVoice(VoiceID); + SYSTEM_DelayMs(5); + AUDIO_PlayVoice(VoiceID); - if (gVoiceWriteIndex == 1) - Delay += 3; + if (gVoiceWriteIndex == 1) + Delay += 3; - if (bFlag) - { - SYSTEM_DelayMs(Delay * 10); + if (bFlag) + { + SYSTEM_DelayMs(Delay * 10); - if (FUNCTION_IsRx()) // 1of11 - RADIO_SetModulation(gRxVfo->Modulation); + if (FUNCTION_IsRx()) // 1of11 + RADIO_SetModulation(gRxVfo->Modulation); - #ifdef ENABLE_FMRADIO - if (gFmRadioMode) - BK1080_Mute(false); - #endif + #ifdef ENABLE_FMRADIO + if (gFmRadioMode) + BK1080_Mute(false); + #endif - if (!gEnableSpeaker) - AUDIO_AudioPathOff(); + if (!gEnableSpeaker) + AUDIO_AudioPathOff(); - gVoiceWriteIndex = 0; - gVoiceReadIndex = 0; + gVoiceWriteIndex = 0; + gVoiceReadIndex = 0; - #ifdef ENABLE_VOX - gVoxResumeCountdown = 80; - #endif + #ifdef ENABLE_VOX + gVoxResumeCountdown = 80; + #endif - return; - } + return; + } - gVoiceReadIndex = 1; - gCountdownToPlayNextVoice_10ms = Delay; - gFlagPlayQueuedVoice = false; + gVoiceReadIndex = 1; + gCountdownToPlayNextVoice_10ms = Delay; + gFlagPlayQueuedVoice = false; - return; - } + return; + } Bailout: - gVoiceReadIndex = 0; - gVoiceWriteIndex = 0; + gVoiceReadIndex = 0; + gVoiceWriteIndex = 0; } void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID) { - if (Index >= ARRAY_SIZE(gVoiceID)) - return; + if (Index >= ARRAY_SIZE(gVoiceID)) + return; - if (Index == 0) - { - gVoiceWriteIndex = 0; - gVoiceReadIndex = 0; - } + if (Index == 0) + { + gVoiceWriteIndex = 0; + gVoiceReadIndex = 0; + } - gVoiceID[Index] = VoiceID; + gVoiceID[Index] = VoiceID; - gVoiceWriteIndex++; + gVoiceWriteIndex++; } uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value) { - uint16_t Remainder; - uint8_t Result; - uint8_t Count; + uint16_t Remainder; + uint8_t Result; + uint8_t Count; - if (Index == 0) - { - gVoiceWriteIndex = 0; - gVoiceReadIndex = 0; - } + if (Index == 0) + { + gVoiceWriteIndex = 0; + gVoiceReadIndex = 0; + } - Count = 0; - Result = Value / 1000U; - Remainder = Value % 1000U; - if (Remainder < 100U) - { - if (Remainder < 10U) - goto Skip; - } - else - { - Result = Remainder / 100U; - gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result; - Count++; - Remainder -= Result * 100U; - } - Result = Remainder / 10U; - gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result; - Count++; - Remainder -= Result * 10U; + Count = 0; + Result = Value / 1000U; + Remainder = Value % 1000U; + if (Remainder < 100U) + { + if (Remainder < 10U) + goto Skip; + } + else + { + Result = Remainder / 100U; + gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result; + Count++; + Remainder -= Result * 100U; + } + Result = Remainder / 10U; + gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result; + Count++; + Remainder -= Result * 10U; Skip: - gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Remainder; + gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Remainder; - return Count + 1U; + return Count + 1U; } void AUDIO_PlayQueuedVoice(void) { - uint8_t VoiceID; - uint8_t Delay; - bool Skip; + uint8_t VoiceID; + uint8_t Delay; + bool Skip; - Skip = false; + Skip = false; - if (gVoiceReadIndex != gVoiceWriteIndex && gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF) - { - VoiceID = gVoiceID[gVoiceReadIndex]; - if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE) - { - if (VoiceID < ARRAY_SIZE(VoiceClipLengthChinese)) - { - Delay = VoiceClipLengthChinese[VoiceID]; - VoiceID += VOICE_ID_CHI_BASE; - } - else - Skip = true; - } - else - { - if (VoiceID < ARRAY_SIZE(VoiceClipLengthEnglish)) - { - Delay = VoiceClipLengthEnglish[VoiceID]; - VoiceID += VOICE_ID_ENG_BASE; - } - else - Skip = true; - } + if (gVoiceReadIndex != gVoiceWriteIndex && gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF) + { + VoiceID = gVoiceID[gVoiceReadIndex]; + if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE) + { + if (VoiceID < ARRAY_SIZE(VoiceClipLengthChinese)) + { + Delay = VoiceClipLengthChinese[VoiceID]; + VoiceID += VOICE_ID_CHI_BASE; + } + else + Skip = true; + } + else + { + if (VoiceID < ARRAY_SIZE(VoiceClipLengthEnglish)) + { + Delay = VoiceClipLengthEnglish[VoiceID]; + VoiceID += VOICE_ID_ENG_BASE; + } + else + Skip = true; + } - gVoiceReadIndex++; + gVoiceReadIndex++; - if (!Skip) - { - if (gVoiceReadIndex == gVoiceWriteIndex) - Delay += 3; + if (!Skip) + { + if (gVoiceReadIndex == gVoiceWriteIndex) + Delay += 3; - AUDIO_PlayVoice(VoiceID); + AUDIO_PlayVoice(VoiceID); - gCountdownToPlayNextVoice_10ms = Delay; - gFlagPlayQueuedVoice = false; + gCountdownToPlayNextVoice_10ms = Delay; + gFlagPlayQueuedVoice = false; - #ifdef ENABLE_VOX - gVoxResumeCountdown = 2000; - #endif + #ifdef ENABLE_VOX + gVoxResumeCountdown = 2000; + #endif - return; - } - } + return; + } + } - if (FUNCTION_IsRx()) - { - RADIO_SetModulation(gRxVfo->Modulation); // 1of11 - } + if (FUNCTION_IsRx()) + { + RADIO_SetModulation(gRxVfo->Modulation); // 1of11 + } - #ifdef ENABLE_FMRADIO - if (gFmRadioMode) - BK1080_Mute(false); - #endif + #ifdef ENABLE_FMRADIO + if (gFmRadioMode) + BK1080_Mute(false); + #endif - if (!gEnableSpeaker) - AUDIO_AudioPathOff(); + if (!gEnableSpeaker) + AUDIO_AudioPathOff(); - #ifdef ENABLE_VOX - gVoxResumeCountdown = 80; - #endif + #ifdef ENABLE_VOX + gVoxResumeCountdown = 80; + #endif - gVoiceWriteIndex = 0; - gVoiceReadIndex = 0; + gVoiceWriteIndex = 0; + gVoiceReadIndex = 0; } #endif diff --git a/audio.h b/audio.h index e27b437..26ed0b6 100644 --- a/audio.h +++ b/audio.h @@ -25,21 +25,21 @@ enum BEEP_Type_t { - BEEP_NONE = 0, - BEEP_1KHZ_60MS_OPTIONAL, - BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL, - BEEP_440HZ_500MS, + BEEP_NONE = 0, + BEEP_1KHZ_60MS_OPTIONAL, + BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL, + BEEP_440HZ_500MS, #ifdef ENABLE_DTMF_CALLING - BEEP_880HZ_200MS, - BEEP_880HZ_500MS, + BEEP_880HZ_200MS, + BEEP_880HZ_500MS, #endif - BEEP_500HZ_60MS_DOUBLE_BEEP, + BEEP_500HZ_60MS_DOUBLE_BEEP, #ifdef ENABLE_FEAT_F4HWN - BEEP_400HZ_30MS, - BEEP_500HZ_30MS, - BEEP_600HZ_30MS, + BEEP_400HZ_30MS, + BEEP_500HZ_30MS, + BEEP_600HZ_30MS, #endif - BEEP_880HZ_60MS_DOUBLE_BEEP + BEEP_880HZ_60MS_DOUBLE_BEEP }; typedef enum BEEP_Type_t BEEP_Type_t; @@ -47,117 +47,117 @@ typedef enum BEEP_Type_t BEEP_Type_t; extern BEEP_Type_t gBeepToPlay; void AUDIO_PlayBeep(BEEP_Type_t Beep); - + static inline void AUDIO_AudioPathOn(void) { - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); } static inline void AUDIO_AudioPathOff(void) { - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); } #ifdef ENABLE_VOICE - typedef enum VOICE_ID_t VOICE_ID_t; + typedef enum VOICE_ID_t VOICE_ID_t; - enum - { - VOICE_ID_CHI_BASE = 0x10U, - VOICE_ID_ENG_BASE = 0x60U, - }; + enum + { + VOICE_ID_CHI_BASE = 0x10U, + VOICE_ID_ENG_BASE = 0x60U, + }; - enum VOICE_ID_t - { - VOICE_ID_0 = 0x00U, - VOICE_ID_1 = 0x01U, - VOICE_ID_2 = 0x02U, - VOICE_ID_3 = 0x03U, - VOICE_ID_4 = 0x04U, - VOICE_ID_5 = 0x05U, - VOICE_ID_6 = 0x06U, - VOICE_ID_7 = 0x07U, - VOICE_ID_8 = 0x08U, - VOICE_ID_9 = 0x09U, - VOICE_ID_10 = 0x0AU, - VOICE_ID_100 = 0x0BU, - VOICE_ID_WELCOME = 0x0CU, - VOICE_ID_LOCK = 0x0DU, - VOICE_ID_UNLOCK = 0x0EU, - VOICE_ID_SCANNING_BEGIN = 0x0FU, - VOICE_ID_SCANNING_STOP = 0x10U, - VOICE_ID_SCRAMBLER_ON = 0x11U, - VOICE_ID_SCRAMBLER_OFF = 0x12U, - VOICE_ID_FUNCTION = 0x13U, - VOICE_ID_CTCSS = 0x14U, - VOICE_ID_DCS = 0x15U, - VOICE_ID_POWER = 0x16U, - VOICE_ID_SAVE_MODE = 0x17U, - VOICE_ID_MEMORY_CHANNEL = 0x18U, - VOICE_ID_DELETE_CHANNEL = 0x19U, - VOICE_ID_FREQUENCY_STEP = 0x1AU, - VOICE_ID_SQUELCH = 0x1BU, - VOICE_ID_TRANSMIT_OVER_TIME = 0x1CU, - VOICE_ID_BACKLIGHT_SELECTION = 0x1DU, - VOICE_ID_VOX = 0x1EU, - VOICE_ID_TX_OFFSET_FREQUENCY_DIRECTION = 0x1FU, - VOICE_ID_TX_OFFSET_FREQUENCY = 0x20U, - VOICE_ID_TRANSMITING_MEMORY = 0x21U, - VOICE_ID_RECEIVING_MEMORY = 0x22U, - VOICE_ID_EMERGENCY_CALL = 0x23U, - VOICE_ID_LOW_VOLTAGE = 0x24U, - VOICE_ID_CHANNEL_MODE = 0x25U, - VOICE_ID_FREQUENCY_MODE = 0x26U, - VOICE_ID_VOICE_PROMPT = 0x27U, - VOICE_ID_BAND_SELECTION = 0x28U, - VOICE_ID_DUAL_STANDBY = 0x29U, - VOICE_ID_CHANNEL_BANDWIDTH = 0x2AU, - VOICE_ID_OPTIONAL_SIGNAL = 0x2BU, - VOICE_ID_MUTE_MODE = 0x2CU, - VOICE_ID_BUSY_LOCKOUT = 0x2DU, - VOICE_ID_BEEP_PROMPT = 0x2EU, - VOICE_ID_ANI_CODE = 0x2FU, - VOICE_ID_INITIALISATION = 0x30U, - VOICE_ID_CONFIRM = 0x31U, - VOICE_ID_CANCEL = 0x32U, - VOICE_ID_ON = 0x33U, - VOICE_ID_OFF = 0x34U, - VOICE_ID_2_TONE = 0x35U, - VOICE_ID_5_TONE = 0x36U, - VOICE_ID_DIGITAL_SIGNAL = 0x37U, - VOICE_ID_REPEATER = 0x38U, - VOICE_ID_MENU = 0x39U, - VOICE_ID_11 = 0x3AU, - VOICE_ID_12 = 0x3BU, - VOICE_ID_13 = 0x3CU, - VOICE_ID_14 = 0x3DU, - VOICE_ID_15 = 0x3EU, - VOICE_ID_16 = 0x3FU, - VOICE_ID_17 = 0x40U, - VOICE_ID_18 = 0x41U, - VOICE_ID_19 = 0x42U, - VOICE_ID_20 = 0x43U, - VOICE_ID_30 = 0x44U, - VOICE_ID_40 = 0x45U, - VOICE_ID_50 = 0x46U, - VOICE_ID_60 = 0x47U, - VOICE_ID_70 = 0x48U, - VOICE_ID_80 = 0x49U, - VOICE_ID_90 = 0x4AU, - VOICE_ID_END = 0x4BU, + enum VOICE_ID_t + { + VOICE_ID_0 = 0x00U, + VOICE_ID_1 = 0x01U, + VOICE_ID_2 = 0x02U, + VOICE_ID_3 = 0x03U, + VOICE_ID_4 = 0x04U, + VOICE_ID_5 = 0x05U, + VOICE_ID_6 = 0x06U, + VOICE_ID_7 = 0x07U, + VOICE_ID_8 = 0x08U, + VOICE_ID_9 = 0x09U, + VOICE_ID_10 = 0x0AU, + VOICE_ID_100 = 0x0BU, + VOICE_ID_WELCOME = 0x0CU, + VOICE_ID_LOCK = 0x0DU, + VOICE_ID_UNLOCK = 0x0EU, + VOICE_ID_SCANNING_BEGIN = 0x0FU, + VOICE_ID_SCANNING_STOP = 0x10U, + VOICE_ID_SCRAMBLER_ON = 0x11U, + VOICE_ID_SCRAMBLER_OFF = 0x12U, + VOICE_ID_FUNCTION = 0x13U, + VOICE_ID_CTCSS = 0x14U, + VOICE_ID_DCS = 0x15U, + VOICE_ID_POWER = 0x16U, + VOICE_ID_SAVE_MODE = 0x17U, + VOICE_ID_MEMORY_CHANNEL = 0x18U, + VOICE_ID_DELETE_CHANNEL = 0x19U, + VOICE_ID_FREQUENCY_STEP = 0x1AU, + VOICE_ID_SQUELCH = 0x1BU, + VOICE_ID_TRANSMIT_OVER_TIME = 0x1CU, + VOICE_ID_BACKLIGHT_SELECTION = 0x1DU, + VOICE_ID_VOX = 0x1EU, + VOICE_ID_TX_OFFSET_FREQUENCY_DIRECTION = 0x1FU, + VOICE_ID_TX_OFFSET_FREQUENCY = 0x20U, + VOICE_ID_TRANSMITING_MEMORY = 0x21U, + VOICE_ID_RECEIVING_MEMORY = 0x22U, + VOICE_ID_EMERGENCY_CALL = 0x23U, + VOICE_ID_LOW_VOLTAGE = 0x24U, + VOICE_ID_CHANNEL_MODE = 0x25U, + VOICE_ID_FREQUENCY_MODE = 0x26U, + VOICE_ID_VOICE_PROMPT = 0x27U, + VOICE_ID_BAND_SELECTION = 0x28U, + VOICE_ID_DUAL_STANDBY = 0x29U, + VOICE_ID_CHANNEL_BANDWIDTH = 0x2AU, + VOICE_ID_OPTIONAL_SIGNAL = 0x2BU, + VOICE_ID_MUTE_MODE = 0x2CU, + VOICE_ID_BUSY_LOCKOUT = 0x2DU, + VOICE_ID_BEEP_PROMPT = 0x2EU, + VOICE_ID_ANI_CODE = 0x2FU, + VOICE_ID_INITIALISATION = 0x30U, + VOICE_ID_CONFIRM = 0x31U, + VOICE_ID_CANCEL = 0x32U, + VOICE_ID_ON = 0x33U, + VOICE_ID_OFF = 0x34U, + VOICE_ID_2_TONE = 0x35U, + VOICE_ID_5_TONE = 0x36U, + VOICE_ID_DIGITAL_SIGNAL = 0x37U, + VOICE_ID_REPEATER = 0x38U, + VOICE_ID_MENU = 0x39U, + VOICE_ID_11 = 0x3AU, + VOICE_ID_12 = 0x3BU, + VOICE_ID_13 = 0x3CU, + VOICE_ID_14 = 0x3DU, + VOICE_ID_15 = 0x3EU, + VOICE_ID_16 = 0x3FU, + VOICE_ID_17 = 0x40U, + VOICE_ID_18 = 0x41U, + VOICE_ID_19 = 0x42U, + VOICE_ID_20 = 0x43U, + VOICE_ID_30 = 0x44U, + VOICE_ID_40 = 0x45U, + VOICE_ID_50 = 0x46U, + VOICE_ID_60 = 0x47U, + VOICE_ID_70 = 0x48U, + VOICE_ID_80 = 0x49U, + VOICE_ID_90 = 0x4AU, + VOICE_ID_END = 0x4BU, - VOICE_ID_INVALID = 0xFFU, - }; + VOICE_ID_INVALID = 0xFFU, + }; - extern VOICE_ID_t gVoiceID[8]; - extern uint8_t gVoiceReadIndex; - extern uint8_t gVoiceWriteIndex; - extern volatile uint16_t gCountdownToPlayNextVoice_10ms; - extern volatile bool gFlagPlayQueuedVoice; - extern VOICE_ID_t gAnotherVoiceID; - - void AUDIO_PlaySingleVoice(bool bFlag); - void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID); - uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value); - void AUDIO_PlayQueuedVoice(void); + extern VOICE_ID_t gVoiceID[8]; + extern uint8_t gVoiceReadIndex; + extern uint8_t gVoiceWriteIndex; + extern volatile uint16_t gCountdownToPlayNextVoice_10ms; + extern volatile bool gFlagPlayQueuedVoice; + extern VOICE_ID_t gAnotherVoiceID; + + void AUDIO_PlaySingleVoice(bool bFlag); + void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID); + uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value); + void AUDIO_PlayQueuedVoice(void); #endif #endif diff --git a/bitmaps.c b/bitmaps.c index fa746a4..27569e1 100644 --- a/bitmaps.c +++ b/bitmaps.c @@ -4,311 +4,310 @@ // all these images are on their right sides // turn your monitor 90-deg anti-clockwise to see the images - const uint8_t gFontPowerSave[2][6] = { - {0x00, 0x7f, 0x9, 0x9, 0x9, 0x6}, - {0x00, 0x26, 0x49, 0x49, 0x49, 0x32}, + {0x00, 0x7f, 0x9, 0x9, 0x9, 0x6}, + {0x00, 0x26, 0x49, 0x49, 0x49, 0x32}, }; const uint8_t gFontPttOnePush[2][6] = { - {0x00, 0x3e, 0x41, 0x41, 0x41, 0x3e}, - {0x00, 0x7f, 0x9, 0x9, 0x9, 0x6}, + {0x00, 0x3e, 0x41, 0x41, 0x41, 0x3e}, + {0x00, 0x7f, 0x9, 0x9, 0x9, 0x6}, }; const uint8_t gFontPttClassic[2][6] = { - {0x00, 0x3e, 0x41, 0x41, 0x41, 0x22}, - {0x00, 0x7f, 0x40, 0x40, 0x40, 0x40}, + {0x00, 0x3e, 0x41, 0x41, 0x41, 0x22}, + {0x00, 0x7f, 0x40, 0x40, 0x40, 0x40}, }; const uint8_t gFontF[1][8] = { - {0x7f, 0x00, 0x76, 0x76, 0x76, 0x76, 0x7e, 0x7f}, // 'F' + {0x7f, 0x00, 0x76, 0x76, 0x76, 0x76, 0x7e, 0x7f}, // 'F' }; const uint8_t gFontS[1][6] = { - {0x26, 0x49, 0x49, 0x49, 0x49, 0x32}, // 'S' + {0x26, 0x49, 0x49, 0x49, 0x49, 0x32}, // 'S' }; const uint8_t gFontKeyLock[1][9] = { - {0x7c, 0x46, 0x45, 0x45, 0x45, 0x45, 0x45, 0x46, 0x7c} + {0x7c, 0x46, 0x45, 0x45, 0x45, 0x45, 0x45, 0x46, 0x7c} }; const uint8_t gFontLight[9] = { - 0b00001100, - 0b00010010, - 0b00100001, - 0b01101101, - 0b01111001, - 0b01101101, - 0b00100001, - 0b00010010, - 0b00001100, + 0b00001100, + 0b00010010, + 0b00100001, + 0b01101101, + 0b01111001, + 0b01101101, + 0b00100001, + 0b00010010, + 0b00001100, }; const uint8_t gFontXB[2][6] = -{ // "XB" - {0x00, 0x63, 0x14, 0x8, 0x14, 0x63}, - {0x00, 0x7f, 0x49, 0x49, 0x49, 0x36}, +{ // "XB" + {0x00, 0x63, 0x14, 0x8, 0x14, 0x63}, + {0x00, 0x7f, 0x49, 0x49, 0x49, 0x36}, }; const uint8_t gFontMO[2][6] = -{ // "MO" - {0x00, 0x7f, 0x2, 0x1c, 0x2, 0x7f}, - {0x00, 0x3e, 0x41, 0x41, 0x41, 0x3e}, +{ // "MO" + {0x00, 0x7f, 0x2, 0x1c, 0x2, 0x7f}, + {0x00, 0x3e, 0x41, 0x41, 0x41, 0x3e}, }; const uint8_t gFontDWR[3][6] = -{ // "DWR" +{ // "DWR" - {0x00, 0x7f, 0x41, 0x41, 0x41, 0x3e}, - {0x00, 0x3f, 0x40, 0x38, 0x40, 0x3f}, - {0x00, 0x7f, 0x9, 0x19, 0x29, 0x46}, + {0x00, 0x7f, 0x41, 0x41, 0x41, 0x3e}, + {0x00, 0x3f, 0x40, 0x38, 0x40, 0x3f}, + {0x00, 0x7f, 0x9, 0x19, 0x29, 0x46}, }; const uint8_t gFontHold[2][5] = -{ // "><" .. DW on hold - {0x00, 0x41, 0x22, 0x14, 0x8}, - {0x00, 0x8, 0x14, 0x22, 0x41}, +{ // "><" .. DW on hold + {0x00, 0x41, 0x22, 0x14, 0x8}, + {0x00, 0x8, 0x14, 0x22, 0x41}, }; const uint8_t BITMAP_BatteryLevel[2] = { - 0b01011101, - 0b01011101 + 0b01011101, + 0b01011101 }; // Quansheng way (+ pole to the left) const uint8_t BITMAP_BatteryLevel1[17] = { - 0b00000000, - 0b00111110, - 0b00100010, - 0b01000001, - 0b01000001, - 0b01000001, - 0b01000001, - 0b01000001, - 0b01000001, - 0b01000001, - 0b01000001, - 0b01000001, - 0b01000001, - 0b01000001, - 0b01000001, - 0b01000001, - 0b01111111 + 0b00000000, + 0b00111110, + 0b00100010, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01000001, + 0b01111111 }; const uint8_t BITMAP_USB_C[9] = { - 0b00000000, - 0b00011100, - 0b00100111, - 0b01000100, - 0b01000100, - 0b01000100, - 0b01000100, - 0b00100111, - 0b00011100 + 0b00000000, + 0b00011100, + 0b00100111, + 0b01000100, + 0b01000100, + 0b01000100, + 0b01000100, + 0b00100111, + 0b00011100 }; #ifdef ENABLE_VOX - const uint8_t gFontVox[2][6] = - { - {0x00, 0x1f, 0x20, 0x40, 0x20, 0x1f}, - {0x00, 0x63, 0x14, 0x8, 0x14, 0x63}, - }; + const uint8_t gFontVox[2][6] = + { + {0x00, 0x1f, 0x20, 0x40, 0x20, 0x1f}, + {0x00, 0x63, 0x14, 0x8, 0x14, 0x63}, + }; #endif const uint8_t BITMAP_Antenna[5] = { - 0b00000011, - 0b00000101, - 0b01111111, - 0b00000101, - 0b00000011 + 0b00000011, + 0b00000101, + 0b01111111, + 0b00000101, + 0b00000011 }; const uint8_t BITMAP_VFO_Lock[7] = { - 0b01111100, - 0b01000110, - 0b01000101, - 0b01000101, - 0b01000101, - 0b01000110, - 0b01111100, + 0b01111100, + 0b01000110, + 0b01000101, + 0b01000101, + 0b01000101, + 0b01000110, + 0b01111100, }; const uint8_t BITMAP_VFO_Default[7] = { - 0b01111111, - 0b01111111, - 0b00111110, - 0b00111110, - 0b00011100, - 0b00011100, - 0b00001000 + 0b01111111, + 0b01111111, + 0b00111110, + 0b00111110, + 0b00011100, + 0b00011100, + 0b00001000 }; const uint8_t BITMAP_VFO_NotDefault[7] = { - 0b01000001, - 0b01000001, - 0b00100010, - 0b00100010, - 0b00010100, - 0b00010100, - 0b00001000 + 0b01000001, + 0b01000001, + 0b00100010, + 0b00100010, + 0b00010100, + 0b00010100, + 0b00001000 }; const uint8_t BITMAP_ScanList0[7] = -{ // '0' symbol - 0b01111111, - 0b01111111, - 0b01000011, - 0b01011101, - 0b01100001, - 0b01111111, - 0b01111111 +{ // '0' symbol + 0b01111111, + 0b01111111, + 0b01000011, + 0b01011101, + 0b01100001, + 0b01111111, + 0b01111111 }; const uint8_t BITMAP_ScanList1[7] = -{ // '1' symbol - 0b01111111, - 0b01111111, - 0b01111011, - 0b01000001, - 0b01111111, - 0b01111111, - 0b01111111 +{ // '1' symbol + 0b01111111, + 0b01111111, + 0b01111011, + 0b01000001, + 0b01111111, + 0b01111111, + 0b01111111 }; const uint8_t BITMAP_ScanList2[7] = -{ // '2' symbol - 0b01111111, - 0b01111111, - 0b01001101, - 0b01010101, - 0b01011011, - 0b01111111, - 0b01111111 +{ // '2' symbol + 0b01111111, + 0b01111111, + 0b01001101, + 0b01010101, + 0b01011011, + 0b01111111, + 0b01111111 }; const uint8_t BITMAP_ScanList3[7] = -{ // '3' symbol - 0b01111111, - 0b01111111, - 0b01011101, - 0b01010101, - 0b01101011, - 0b01111111, - 0b01111111 +{ // '3' symbol + 0b01111111, + 0b01111111, + 0b01011101, + 0b01010101, + 0b01101011, + 0b01111111, + 0b01111111 }; const uint8_t BITMAP_ScanListE[7] = -{ // 'E' symbol - 0b01111111, - 0b01111111, - 0b01000001, - 0b01010101, - 0b01010101, - 0b01111111, - 0b01111111 +{ // 'E' symbol + 0b01111111, + 0b01111111, + 0b01000001, + 0b01010101, + 0b01010101, + 0b01111111, + 0b01111111 }; const uint8_t BITMAP_ScanList123[19] = { - // 'All' symbol - 0b01111111, - 0b01111111, - 0b01111011, - 0b01000001, - 0b01111111, - 0b01111111, - 0b01111111, - 0b01111111, - 0b01001101, - 0b01010101, - 0b01011011, - 0b01111111, - 0b01111111, - 0b01111111, - 0b01011101, - 0b01010101, - 0b01101011, - 0b01111111, - 0b01111111 + // 'All' symbol + 0b01111111, + 0b01111111, + 0b01111011, + 0b01000001, + 0b01111111, + 0b01111111, + 0b01111111, + 0b01111111, + 0b01001101, + 0b01010101, + 0b01011011, + 0b01111111, + 0b01111111, + 0b01111111, + 0b01011101, + 0b01010101, + 0b01101011, + 0b01111111, + 0b01111111 }; const uint8_t BITMAP_ScanListAll[19] = { - // 'All' symbol - 0b01111111, - 0b01111111, - 0b01000011, - 0b01110101, - 0b01000011, - 0b01111111, - 0b01111111, - 0b01111111, - 0b01000001, - 0b01011111, - 0b01011111, - 0b01111111, - 0b01111111, - 0b01111111, - 0b01000001, - 0b01011111, - 0b01011111, - 0b01111111, - 0b01111111 + // 'All' symbol + 0b01111111, + 0b01111111, + 0b01000011, + 0b01110101, + 0b01000011, + 0b01111111, + 0b01111111, + 0b01111111, + 0b01000001, + 0b01011111, + 0b01011111, + 0b01111111, + 0b01111111, + 0b01111111, + 0b01000001, + 0b01011111, + 0b01011111, + 0b01111111, + 0b01111111 }; const uint8_t BITMAP_compand[6] = { - 0b00000000, - 0b00111100, - 0b01000010, - 0b01000010, - 0b01000010, - 0b00100100 + 0b00000000, + 0b00111100, + 0b01000010, + 0b01000010, + 0b01000010, + 0b00100100 }; const uint8_t BITMAP_Ready[7] = { - 0b00001000, - 0b00010000, - 0b00100000, - 0b00010000, - 0b00001000, - 0b00000100, - 0b00000010, + 0b00001000, + 0b00010000, + 0b00100000, + 0b00010000, + 0b00001000, + 0b00000100, + 0b00000010, }; const uint8_t BITMAP_PowerUser[3] = -{ // 'arrow' symbol - 0b00111110, - 0b00011100, - 0b00001000, +{ // 'arrow' symbol + 0b00111110, + 0b00011100, + 0b00001000, }; #ifndef ENABLE_CUSTOM_MENU_LAYOUT const uint8_t BITMAP_CurrentIndicator[8] = { - 0xFF, - 0xFF, - 0x7E, - 0x7E, - 0x3C, - 0x3C, - 0x18, - 0x18 + 0xFF, + 0xFF, + 0x7E, + 0x7E, + 0x3C, + 0x3C, + 0x18, + 0x18 }; #endif diff --git a/bitmaps.h b/bitmaps.h index 774c7ea..51ef41a 100644 --- a/bitmaps.h +++ b/bitmaps.h @@ -24,7 +24,7 @@ extern const uint8_t BITMAP_USB_C[9]; extern const uint8_t BITMAP_Ready[7]; #ifdef ENABLE_VOX - extern const uint8_t gFontVox[2][6]; + extern const uint8_t gFontVox[2][6]; #endif extern const uint8_t BITMAP_Antenna[5]; @@ -42,7 +42,7 @@ extern const uint8_t BITMAP_PowerUser[3]; extern const uint8_t BITMAP_compand[6]; #ifndef ENABLE_CUSTOM_MENU_LAYOUT - extern const uint8_t BITMAP_CurrentIndicator[8]; + extern const uint8_t BITMAP_CurrentIndicator[8]; #endif #endif diff --git a/board.c b/board.c index 0396d15..e3db3ca 100644 --- a/board.c +++ b/board.c @@ -17,7 +17,7 @@ #include #ifdef ENABLE_FMRADIO - #include "app/fm.h" + #include "app/fm.h" #endif #include "board.h" #include "bsp/dp32g030/gpio.h" @@ -27,7 +27,7 @@ #include "driver/adc.h" #include "driver/backlight.h" #ifdef ENABLE_FMRADIO - #include "driver/bk1080.h" + #include "driver/bk1080.h" #endif #include "driver/crc.h" @@ -41,465 +41,465 @@ #include "misc.h" #include "settings.h" #if defined(ENABLE_OVERLAY) - #include "sram-overlay.h" + #include "sram-overlay.h" #endif #if defined(ENABLE_OVERLAY) - void BOARD_FLASH_Init(void) - { - FLASH_Init(FLASH_READ_MODE_1_CYCLE); - FLASH_ConfigureTrimValues(); - SYSTEM_ConfigureClocks(); + void BOARD_FLASH_Init(void) + { + FLASH_Init(FLASH_READ_MODE_1_CYCLE); + FLASH_ConfigureTrimValues(); + SYSTEM_ConfigureClocks(); - overlay_FLASH_MainClock = 48000000; - overlay_FLASH_ClockMultiplier = 48; + overlay_FLASH_MainClock = 48000000; + overlay_FLASH_ClockMultiplier = 48; - FLASH_Init(FLASH_READ_MODE_2_CYCLE); - } + FLASH_Init(FLASH_READ_MODE_2_CYCLE); + } #endif void BOARD_GPIO_Init(void) { - GPIOA->DIR |= 0 - // A7 = UART1 TX default as OUTPUT from bootloader! - // A8 = UART1 RX default as INPUT from bootloader! - // Key pad + I2C - | GPIO_DIR_10_BITS_OUTPUT - // Key pad + I2C - | GPIO_DIR_11_BITS_OUTPUT - // Key pad + Voice chip - | GPIO_DIR_12_BITS_OUTPUT - // Key pad + Voice chip - | GPIO_DIR_13_BITS_OUTPUT - ; - GPIOA->DIR &= ~(0 - // Key pad - | GPIO_DIR_3_MASK // INPUT - // Key pad - | GPIO_DIR_4_MASK // INPUT - // Key pad - | GPIO_DIR_5_MASK // INPUT - // Key pad - | GPIO_DIR_6_MASK // INPUT - ); - GPIOB->DIR |= 0 - // ST7565 - | GPIO_DIR_9_BITS_OUTPUT - // ST7565 + SWD IO - | GPIO_DIR_11_BITS_OUTPUT - // B14 = SWD_CLK assumed INPUT by default - // BK1080 - | GPIO_DIR_15_BITS_OUTPUT - ; - GPIOC->DIR |= 0 - // BK4819 SCN - | GPIO_DIR_0_BITS_OUTPUT - // BK4819 SCL - | GPIO_DIR_1_BITS_OUTPUT - // BK4819 SDA - | GPIO_DIR_2_BITS_OUTPUT - // Flash light - | GPIO_DIR_3_BITS_OUTPUT - // Speaker - | GPIO_DIR_4_BITS_OUTPUT - ; - GPIOC->DIR &= ~(0 - // PTT button - | GPIO_DIR_5_MASK // INPUT - ); + GPIOA->DIR |= 0 + // A7 = UART1 TX default as OUTPUT from bootloader! + // A8 = UART1 RX default as INPUT from bootloader! + // Key pad + I2C + | GPIO_DIR_10_BITS_OUTPUT + // Key pad + I2C + | GPIO_DIR_11_BITS_OUTPUT + // Key pad + Voice chip + | GPIO_DIR_12_BITS_OUTPUT + // Key pad + Voice chip + | GPIO_DIR_13_BITS_OUTPUT + ; + GPIOA->DIR &= ~(0 + // Key pad + | GPIO_DIR_3_MASK // INPUT + // Key pad + | GPIO_DIR_4_MASK // INPUT + // Key pad + | GPIO_DIR_5_MASK // INPUT + // Key pad + | GPIO_DIR_6_MASK // INPUT + ); + GPIOB->DIR |= 0 + // ST7565 + | GPIO_DIR_9_BITS_OUTPUT + // ST7565 + SWD IO + | GPIO_DIR_11_BITS_OUTPUT + // B14 = SWD_CLK assumed INPUT by default + // BK1080 + | GPIO_DIR_15_BITS_OUTPUT + ; + GPIOC->DIR |= 0 + // BK4819 SCN + | GPIO_DIR_0_BITS_OUTPUT + // BK4819 SCL + | GPIO_DIR_1_BITS_OUTPUT + // BK4819 SDA + | GPIO_DIR_2_BITS_OUTPUT + // Flash light + | GPIO_DIR_3_BITS_OUTPUT + // Speaker + | GPIO_DIR_4_BITS_OUTPUT + ; + GPIOC->DIR &= ~(0 + // PTT button + | GPIO_DIR_5_MASK // INPUT + ); - #if defined(ENABLE_FMRADIO) - GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BK1080); - #endif + #if defined(ENABLE_FMRADIO) + GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BK1080); + #endif } void BOARD_PORTCON_Init(void) { - // PORT A pin selection + // PORT A pin selection - PORTCON_PORTA_SEL0 &= ~(0 - // Key pad - | PORTCON_PORTA_SEL0_A3_MASK - // Key pad - | PORTCON_PORTA_SEL0_A4_MASK - // Key pad - | PORTCON_PORTA_SEL0_A5_MASK - // Key pad - | PORTCON_PORTA_SEL0_A6_MASK - ); - PORTCON_PORTA_SEL0 |= 0 - // Key pad - | PORTCON_PORTA_SEL0_A3_BITS_GPIOA3 - // Key pad - | PORTCON_PORTA_SEL0_A4_BITS_GPIOA4 - // Key pad - | PORTCON_PORTA_SEL0_A5_BITS_GPIOA5 - // Key pad - | PORTCON_PORTA_SEL0_A6_BITS_GPIOA6 - // UART1 TX, wasn't cleared in previous step / relying on default value! - | PORTCON_PORTA_SEL0_A7_BITS_UART1_TX - ; + PORTCON_PORTA_SEL0 &= ~(0 + // Key pad + | PORTCON_PORTA_SEL0_A3_MASK + // Key pad + | PORTCON_PORTA_SEL0_A4_MASK + // Key pad + | PORTCON_PORTA_SEL0_A5_MASK + // Key pad + | PORTCON_PORTA_SEL0_A6_MASK + ); + PORTCON_PORTA_SEL0 |= 0 + // Key pad + | PORTCON_PORTA_SEL0_A3_BITS_GPIOA3 + // Key pad + | PORTCON_PORTA_SEL0_A4_BITS_GPIOA4 + // Key pad + | PORTCON_PORTA_SEL0_A5_BITS_GPIOA5 + // Key pad + | PORTCON_PORTA_SEL0_A6_BITS_GPIOA6 + // UART1 TX, wasn't cleared in previous step / relying on default value! + | PORTCON_PORTA_SEL0_A7_BITS_UART1_TX + ; - PORTCON_PORTA_SEL1 &= ~(0 - // Key pad + I2C - | PORTCON_PORTA_SEL1_A10_MASK - // Key pad + I2C - | PORTCON_PORTA_SEL1_A11_MASK - // Key pad + Voice chip - | PORTCON_PORTA_SEL1_A12_MASK - // Key pad + Voice chip - | PORTCON_PORTA_SEL1_A13_MASK - ); - PORTCON_PORTA_SEL1 |= 0 - // UART1 RX, wasn't cleared in previous step / relying on default value! - | PORTCON_PORTA_SEL1_A8_BITS_UART1_RX - // Battery voltage, wasn't cleared in previous step / relying on default value! - | PORTCON_PORTA_SEL1_A9_BITS_SARADC_CH4 - // Key pad + I2C - | PORTCON_PORTA_SEL1_A10_BITS_GPIOA10 - // Key pad + I2C - | PORTCON_PORTA_SEL1_A11_BITS_GPIOA11 - // Key pad + Voice chip - | PORTCON_PORTA_SEL1_A12_BITS_GPIOA12 - // Key pad + Voice chip - | PORTCON_PORTA_SEL1_A13_BITS_GPIOA13 - // Battery Current, wasn't cleared in previous step / relying on default value! - | PORTCON_PORTA_SEL1_A14_BITS_SARADC_CH9 - ; + PORTCON_PORTA_SEL1 &= ~(0 + // Key pad + I2C + | PORTCON_PORTA_SEL1_A10_MASK + // Key pad + I2C + | PORTCON_PORTA_SEL1_A11_MASK + // Key pad + Voice chip + | PORTCON_PORTA_SEL1_A12_MASK + // Key pad + Voice chip + | PORTCON_PORTA_SEL1_A13_MASK + ); + PORTCON_PORTA_SEL1 |= 0 + // UART1 RX, wasn't cleared in previous step / relying on default value! + | PORTCON_PORTA_SEL1_A8_BITS_UART1_RX + // Battery voltage, wasn't cleared in previous step / relying on default value! + | PORTCON_PORTA_SEL1_A9_BITS_SARADC_CH4 + // Key pad + I2C + | PORTCON_PORTA_SEL1_A10_BITS_GPIOA10 + // Key pad + I2C + | PORTCON_PORTA_SEL1_A11_BITS_GPIOA11 + // Key pad + Voice chip + | PORTCON_PORTA_SEL1_A12_BITS_GPIOA12 + // Key pad + Voice chip + | PORTCON_PORTA_SEL1_A13_BITS_GPIOA13 + // Battery Current, wasn't cleared in previous step / relying on default value! + | PORTCON_PORTA_SEL1_A14_BITS_SARADC_CH9 + ; - // PORT B pin selection + // PORT B pin selection - PORTCON_PORTB_SEL0 &= ~(0 - // SPI0 SSN - | PORTCON_PORTB_SEL0_B7_MASK - ); - PORTCON_PORTB_SEL0 |= 0 - // SPI0 SSN - | PORTCON_PORTB_SEL0_B7_BITS_SPI0_SSN - ; + PORTCON_PORTB_SEL0 &= ~(0 + // SPI0 SSN + | PORTCON_PORTB_SEL0_B7_MASK + ); + PORTCON_PORTB_SEL0 |= 0 + // SPI0 SSN + | PORTCON_PORTB_SEL0_B7_BITS_SPI0_SSN + ; - PORTCON_PORTB_SEL1 &= ~(0 - // ST7565 - | PORTCON_PORTB_SEL1_B9_MASK - // ST7565 + SWD IO - | PORTCON_PORTB_SEL1_B11_MASK - // SWD CLK - | PORTCON_PORTB_SEL1_B14_MASK - // BK1080 - | PORTCON_PORTB_SEL1_B15_MASK - ); - PORTCON_PORTB_SEL1 |= 0 - // SPI0 CLK, wasn't cleared in previous step / relying on default value! - | PORTCON_PORTB_SEL1_B8_BITS_SPI0_CLK - // ST7565 - | PORTCON_PORTB_SEL1_B9_BITS_GPIOB9 - // SPI0 MOSI, wasn't cleared in previous step / relying on default value! - | PORTCON_PORTB_SEL1_B10_BITS_SPI0_MOSI + PORTCON_PORTB_SEL1 &= ~(0 + // ST7565 + | PORTCON_PORTB_SEL1_B9_MASK + // ST7565 + SWD IO + | PORTCON_PORTB_SEL1_B11_MASK + // SWD CLK + | PORTCON_PORTB_SEL1_B14_MASK + // BK1080 + | PORTCON_PORTB_SEL1_B15_MASK + ); + PORTCON_PORTB_SEL1 |= 0 + // SPI0 CLK, wasn't cleared in previous step / relying on default value! + | PORTCON_PORTB_SEL1_B8_BITS_SPI0_CLK + // ST7565 + | PORTCON_PORTB_SEL1_B9_BITS_GPIOB9 + // SPI0 MOSI, wasn't cleared in previous step / relying on default value! + | PORTCON_PORTB_SEL1_B10_BITS_SPI0_MOSI #if defined(ENABLE_SWD) - // SWD IO - | PORTCON_PORTB_SEL1_B11_BITS_SWDIO - // SWD CLK - | PORTCON_PORTB_SEL1_B14_BITS_SWCLK + // SWD IO + | PORTCON_PORTB_SEL1_B11_BITS_SWDIO + // SWD CLK + | PORTCON_PORTB_SEL1_B14_BITS_SWCLK #else - // ST7565 - | PORTCON_PORTB_SEL1_B11_BITS_GPIOB11 + // ST7565 + | PORTCON_PORTB_SEL1_B11_BITS_GPIOB11 #endif - ; + ; - // PORT C pin selection + // PORT C pin selection - PORTCON_PORTC_SEL0 &= ~(0 - // BK4819 SCN - | PORTCON_PORTC_SEL0_C0_MASK - // BK4819 SCL - | PORTCON_PORTC_SEL0_C1_MASK - // BK4819 SDA - | PORTCON_PORTC_SEL0_C2_MASK - // Flash light - | PORTCON_PORTC_SEL0_C3_MASK - // Speaker - | PORTCON_PORTC_SEL0_C4_MASK - // PTT button - | PORTCON_PORTC_SEL0_C5_MASK - ); + PORTCON_PORTC_SEL0 &= ~(0 + // BK4819 SCN + | PORTCON_PORTC_SEL0_C0_MASK + // BK4819 SCL + | PORTCON_PORTC_SEL0_C1_MASK + // BK4819 SDA + | PORTCON_PORTC_SEL0_C2_MASK + // Flash light + | PORTCON_PORTC_SEL0_C3_MASK + // Speaker + | PORTCON_PORTC_SEL0_C4_MASK + // PTT button + | PORTCON_PORTC_SEL0_C5_MASK + ); - // PORT A pin configuration + // PORT A pin configuration - PORTCON_PORTA_IE |= 0 - // Keypad - | PORTCON_PORTA_IE_A3_BITS_ENABLE - // Keypad - | PORTCON_PORTA_IE_A4_BITS_ENABLE - // Keypad - | PORTCON_PORTA_IE_A5_BITS_ENABLE - // Keypad - | PORTCON_PORTA_IE_A6_BITS_ENABLE - // A7 = UART1 TX disabled by default - // UART1 RX - | PORTCON_PORTA_IE_A8_BITS_ENABLE - ; - PORTCON_PORTA_IE &= ~(0 - // Keypad + I2C - | PORTCON_PORTA_IE_A10_MASK - // Keypad + I2C - | PORTCON_PORTA_IE_A11_MASK - // Keypad + Voice chip - | PORTCON_PORTA_IE_A12_MASK - // Keypad + Voice chip - | PORTCON_PORTA_IE_A13_MASK - ); + PORTCON_PORTA_IE |= 0 + // Keypad + | PORTCON_PORTA_IE_A3_BITS_ENABLE + // Keypad + | PORTCON_PORTA_IE_A4_BITS_ENABLE + // Keypad + | PORTCON_PORTA_IE_A5_BITS_ENABLE + // Keypad + | PORTCON_PORTA_IE_A6_BITS_ENABLE + // A7 = UART1 TX disabled by default + // UART1 RX + | PORTCON_PORTA_IE_A8_BITS_ENABLE + ; + PORTCON_PORTA_IE &= ~(0 + // Keypad + I2C + | PORTCON_PORTA_IE_A10_MASK + // Keypad + I2C + | PORTCON_PORTA_IE_A11_MASK + // Keypad + Voice chip + | PORTCON_PORTA_IE_A12_MASK + // Keypad + Voice chip + | PORTCON_PORTA_IE_A13_MASK + ); - PORTCON_PORTA_PU |= 0 - // Keypad - | PORTCON_PORTA_PU_A3_BITS_ENABLE - // Keypad - | PORTCON_PORTA_PU_A4_BITS_ENABLE - // Keypad - | PORTCON_PORTA_PU_A5_BITS_ENABLE - // Keypad - | PORTCON_PORTA_PU_A6_BITS_ENABLE - ; - PORTCON_PORTA_PU &= ~(0 - // Keypad + I2C - | PORTCON_PORTA_PU_A10_MASK - // Keypad + I2C - | PORTCON_PORTA_PU_A11_MASK - // Keypad + Voice chip - | PORTCON_PORTA_PU_A12_MASK - // Keypad + Voice chip - | PORTCON_PORTA_PU_A13_MASK - ); + PORTCON_PORTA_PU |= 0 + // Keypad + | PORTCON_PORTA_PU_A3_BITS_ENABLE + // Keypad + | PORTCON_PORTA_PU_A4_BITS_ENABLE + // Keypad + | PORTCON_PORTA_PU_A5_BITS_ENABLE + // Keypad + | PORTCON_PORTA_PU_A6_BITS_ENABLE + ; + PORTCON_PORTA_PU &= ~(0 + // Keypad + I2C + | PORTCON_PORTA_PU_A10_MASK + // Keypad + I2C + | PORTCON_PORTA_PU_A11_MASK + // Keypad + Voice chip + | PORTCON_PORTA_PU_A12_MASK + // Keypad + Voice chip + | PORTCON_PORTA_PU_A13_MASK + ); - PORTCON_PORTA_PD &= ~(0 - // Keypad - | PORTCON_PORTA_PD_A3_MASK - // Keypad - | PORTCON_PORTA_PD_A4_MASK - // Keypad - | PORTCON_PORTA_PD_A5_MASK - // Keypad - | PORTCON_PORTA_PD_A6_MASK - // Keypad + I2C - | PORTCON_PORTA_PD_A10_MASK - // Keypad + I2C - | PORTCON_PORTA_PD_A11_MASK - // Keypad + Voice chip - | PORTCON_PORTA_PD_A12_MASK - // Keypad + Voice chip - | PORTCON_PORTA_PD_A13_MASK - ); + PORTCON_PORTA_PD &= ~(0 + // Keypad + | PORTCON_PORTA_PD_A3_MASK + // Keypad + | PORTCON_PORTA_PD_A4_MASK + // Keypad + | PORTCON_PORTA_PD_A5_MASK + // Keypad + | PORTCON_PORTA_PD_A6_MASK + // Keypad + I2C + | PORTCON_PORTA_PD_A10_MASK + // Keypad + I2C + | PORTCON_PORTA_PD_A11_MASK + // Keypad + Voice chip + | PORTCON_PORTA_PD_A12_MASK + // Keypad + Voice chip + | PORTCON_PORTA_PD_A13_MASK + ); - PORTCON_PORTA_OD |= 0 - // Keypad - | PORTCON_PORTA_OD_A3_BITS_ENABLE - // Keypad - | PORTCON_PORTA_OD_A4_BITS_ENABLE - // Keypad - | PORTCON_PORTA_OD_A5_BITS_ENABLE - // Keypad - | PORTCON_PORTA_OD_A6_BITS_ENABLE - ; - PORTCON_PORTA_OD &= ~(0 - // Keypad + I2C - | PORTCON_PORTA_OD_A10_MASK - // Keypad + I2C - | PORTCON_PORTA_OD_A11_MASK - // Keypad + Voice chip - | PORTCON_PORTA_OD_A12_MASK - // Keypad + Voice chip - | PORTCON_PORTA_OD_A13_MASK - ); + PORTCON_PORTA_OD |= 0 + // Keypad + | PORTCON_PORTA_OD_A3_BITS_ENABLE + // Keypad + | PORTCON_PORTA_OD_A4_BITS_ENABLE + // Keypad + | PORTCON_PORTA_OD_A5_BITS_ENABLE + // Keypad + | PORTCON_PORTA_OD_A6_BITS_ENABLE + ; + PORTCON_PORTA_OD &= ~(0 + // Keypad + I2C + | PORTCON_PORTA_OD_A10_MASK + // Keypad + I2C + | PORTCON_PORTA_OD_A11_MASK + // Keypad + Voice chip + | PORTCON_PORTA_OD_A12_MASK + // Keypad + Voice chip + | PORTCON_PORTA_OD_A13_MASK + ); - // PORT B pin configuration + // PORT B pin configuration - PORTCON_PORTB_IE |= 0 - | PORTCON_PORTB_IE_B14_BITS_ENABLE - ; - PORTCON_PORTB_IE &= ~(0 - // Back light - | PORTCON_PORTB_IE_B6_MASK - // UART1 - | PORTCON_PORTB_IE_B7_MASK - | PORTCON_PORTB_IE_B8_MASK - // ST7565 - | PORTCON_PORTB_IE_B9_MASK - // SPI0 MOSI - | PORTCON_PORTB_IE_B10_MASK + PORTCON_PORTB_IE |= 0 + | PORTCON_PORTB_IE_B14_BITS_ENABLE + ; + PORTCON_PORTB_IE &= ~(0 + // Back light + | PORTCON_PORTB_IE_B6_MASK + // UART1 + | PORTCON_PORTB_IE_B7_MASK + | PORTCON_PORTB_IE_B8_MASK + // ST7565 + | PORTCON_PORTB_IE_B9_MASK + // SPI0 MOSI + | PORTCON_PORTB_IE_B10_MASK #if !defined(ENABLE_SWD) - // ST7565 - | PORTCON_PORTB_IE_B11_MASK + // ST7565 + | PORTCON_PORTB_IE_B11_MASK #endif - // BK1080 - | PORTCON_PORTB_IE_B15_MASK - ); + // BK1080 + | PORTCON_PORTB_IE_B15_MASK + ); - PORTCON_PORTB_PU &= ~(0 - // Back light - | PORTCON_PORTB_PU_B6_MASK - // ST7565 - | PORTCON_PORTB_PU_B9_MASK - // ST7565 + SWD IO - | PORTCON_PORTB_PU_B11_MASK - // SWD CLK - | PORTCON_PORTB_PU_B14_MASK - // BK1080 - | PORTCON_PORTB_PU_B15_MASK - ); + PORTCON_PORTB_PU &= ~(0 + // Back light + | PORTCON_PORTB_PU_B6_MASK + // ST7565 + | PORTCON_PORTB_PU_B9_MASK + // ST7565 + SWD IO + | PORTCON_PORTB_PU_B11_MASK + // SWD CLK + | PORTCON_PORTB_PU_B14_MASK + // BK1080 + | PORTCON_PORTB_PU_B15_MASK + ); - PORTCON_PORTB_PD &= ~(0 - // Back light - | PORTCON_PORTB_PD_B6_MASK - // ST7565 - | PORTCON_PORTB_PD_B9_MASK - // ST7565 + SWD IO - | PORTCON_PORTB_PD_B11_MASK - // SWD CLK - | PORTCON_PORTB_PD_B14_MASK - // BK1080 - | PORTCON_PORTB_PD_B15_MASK - ); + PORTCON_PORTB_PD &= ~(0 + // Back light + | PORTCON_PORTB_PD_B6_MASK + // ST7565 + | PORTCON_PORTB_PD_B9_MASK + // ST7565 + SWD IO + | PORTCON_PORTB_PD_B11_MASK + // SWD CLK + | PORTCON_PORTB_PD_B14_MASK + // BK1080 + | PORTCON_PORTB_PD_B15_MASK + ); - PORTCON_PORTB_OD &= ~(0 - // Back light - | PORTCON_PORTB_OD_B6_MASK - // ST7565 - | PORTCON_PORTB_OD_B9_MASK - // ST7565 + SWD IO - | PORTCON_PORTB_OD_B11_MASK - // BK1080 - | PORTCON_PORTB_OD_B15_MASK - ); + PORTCON_PORTB_OD &= ~(0 + // Back light + | PORTCON_PORTB_OD_B6_MASK + // ST7565 + | PORTCON_PORTB_OD_B9_MASK + // ST7565 + SWD IO + | PORTCON_PORTB_OD_B11_MASK + // BK1080 + | PORTCON_PORTB_OD_B15_MASK + ); - PORTCON_PORTB_OD |= 0 - // SWD CLK - | PORTCON_PORTB_OD_B14_BITS_ENABLE - ; + PORTCON_PORTB_OD |= 0 + // SWD CLK + | PORTCON_PORTB_OD_B14_BITS_ENABLE + ; - // PORT C pin configuration + // PORT C pin configuration - PORTCON_PORTC_IE |= 0 - // PTT button - | PORTCON_PORTC_IE_C5_BITS_ENABLE - ; - PORTCON_PORTC_IE &= ~(0 - // BK4819 SCN - | PORTCON_PORTC_IE_C0_MASK - // BK4819 SCL - | PORTCON_PORTC_IE_C1_MASK - // BK4819 SDA - | PORTCON_PORTC_IE_C2_MASK - // Flash Light - | PORTCON_PORTC_IE_C3_MASK - // Speaker - | PORTCON_PORTC_IE_C4_MASK - ); + PORTCON_PORTC_IE |= 0 + // PTT button + | PORTCON_PORTC_IE_C5_BITS_ENABLE + ; + PORTCON_PORTC_IE &= ~(0 + // BK4819 SCN + | PORTCON_PORTC_IE_C0_MASK + // BK4819 SCL + | PORTCON_PORTC_IE_C1_MASK + // BK4819 SDA + | PORTCON_PORTC_IE_C2_MASK + // Flash Light + | PORTCON_PORTC_IE_C3_MASK + // Speaker + | PORTCON_PORTC_IE_C4_MASK + ); - PORTCON_PORTC_PU |= 0 - // PTT button - | PORTCON_PORTC_PU_C5_BITS_ENABLE - ; - PORTCON_PORTC_PU &= ~(0 - // BK4819 SCN - | PORTCON_PORTC_PU_C0_MASK - // BK4819 SCL - | PORTCON_PORTC_PU_C1_MASK - // BK4819 SDA - | PORTCON_PORTC_PU_C2_MASK - // Flash Light - | PORTCON_PORTC_PU_C3_MASK - // Speaker - | PORTCON_PORTC_PU_C4_MASK - ); + PORTCON_PORTC_PU |= 0 + // PTT button + | PORTCON_PORTC_PU_C5_BITS_ENABLE + ; + PORTCON_PORTC_PU &= ~(0 + // BK4819 SCN + | PORTCON_PORTC_PU_C0_MASK + // BK4819 SCL + | PORTCON_PORTC_PU_C1_MASK + // BK4819 SDA + | PORTCON_PORTC_PU_C2_MASK + // Flash Light + | PORTCON_PORTC_PU_C3_MASK + // Speaker + | PORTCON_PORTC_PU_C4_MASK + ); - PORTCON_PORTC_PD &= ~(0 - // BK4819 SCN - | PORTCON_PORTC_PD_C0_MASK - // BK4819 SCL - | PORTCON_PORTC_PD_C1_MASK - // BK4819 SDA - | PORTCON_PORTC_PD_C2_MASK - // Flash Light - | PORTCON_PORTC_PD_C3_MASK - // Speaker - | PORTCON_PORTC_PD_C4_MASK - // PTT Button - | PORTCON_PORTC_PD_C5_MASK - ); + PORTCON_PORTC_PD &= ~(0 + // BK4819 SCN + | PORTCON_PORTC_PD_C0_MASK + // BK4819 SCL + | PORTCON_PORTC_PD_C1_MASK + // BK4819 SDA + | PORTCON_PORTC_PD_C2_MASK + // Flash Light + | PORTCON_PORTC_PD_C3_MASK + // Speaker + | PORTCON_PORTC_PD_C4_MASK + // PTT Button + | PORTCON_PORTC_PD_C5_MASK + ); - PORTCON_PORTC_OD &= ~(0 - // BK4819 SCN - | PORTCON_PORTC_OD_C0_MASK - // BK4819 SCL - | PORTCON_PORTC_OD_C1_MASK - // BK4819 SDA - | PORTCON_PORTC_OD_C2_MASK - // Flash Light - | PORTCON_PORTC_OD_C3_MASK - // Speaker - | PORTCON_PORTC_OD_C4_MASK - ); - PORTCON_PORTC_OD |= 0 - // BK4819 SCN - | PORTCON_PORTC_OD_C0_BITS_DISABLE - // BK4819 SCL - | PORTCON_PORTC_OD_C1_BITS_DISABLE - // BK4819 SDA - | PORTCON_PORTC_OD_C2_BITS_DISABLE - // Flash Light - | PORTCON_PORTC_OD_C3_BITS_DISABLE - // Speaker - | PORTCON_PORTC_OD_C4_BITS_DISABLE - // PTT button - | PORTCON_PORTC_OD_C5_BITS_ENABLE - ; + PORTCON_PORTC_OD &= ~(0 + // BK4819 SCN + | PORTCON_PORTC_OD_C0_MASK + // BK4819 SCL + | PORTCON_PORTC_OD_C1_MASK + // BK4819 SDA + | PORTCON_PORTC_OD_C2_MASK + // Flash Light + | PORTCON_PORTC_OD_C3_MASK + // Speaker + | PORTCON_PORTC_OD_C4_MASK + ); + PORTCON_PORTC_OD |= 0 + // BK4819 SCN + | PORTCON_PORTC_OD_C0_BITS_DISABLE + // BK4819 SCL + | PORTCON_PORTC_OD_C1_BITS_DISABLE + // BK4819 SDA + | PORTCON_PORTC_OD_C2_BITS_DISABLE + // Flash Light + | PORTCON_PORTC_OD_C3_BITS_DISABLE + // Speaker + | PORTCON_PORTC_OD_C4_BITS_DISABLE + // PTT button + | PORTCON_PORTC_OD_C5_BITS_ENABLE + ; } void BOARD_ADC_Init(void) { - ADC_Config_t Config; + ADC_Config_t Config; - Config.CLK_SEL = SYSCON_CLK_SEL_W_SARADC_SMPL_VALUE_DIV2; - Config.CH_SEL = ADC_CH4 | ADC_CH9; - Config.AVG = SARADC_CFG_AVG_VALUE_8_SAMPLE; - Config.CONT = SARADC_CFG_CONT_VALUE_SINGLE; - Config.MEM_MODE = SARADC_CFG_MEM_MODE_VALUE_CHANNEL; - Config.SMPL_CLK = SARADC_CFG_SMPL_CLK_VALUE_INTERNAL; - Config.SMPL_WIN = SARADC_CFG_SMPL_WIN_VALUE_15_CYCLE; - Config.SMPL_SETUP = SARADC_CFG_SMPL_SETUP_VALUE_1_CYCLE; - Config.ADC_TRIG = SARADC_CFG_ADC_TRIG_VALUE_CPU; - Config.CALIB_KD_VALID = SARADC_CALIB_KD_VALID_VALUE_YES; - Config.CALIB_OFFSET_VALID = SARADC_CALIB_OFFSET_VALID_VALUE_YES; - Config.DMA_EN = SARADC_CFG_DMA_EN_VALUE_DISABLE; - Config.IE_CHx_EOC = SARADC_IE_CHx_EOC_VALUE_NONE; - Config.IE_FIFO_FULL = SARADC_IE_FIFO_FULL_VALUE_DISABLE; - Config.IE_FIFO_HFULL = SARADC_IE_FIFO_HFULL_VALUE_DISABLE; + Config.CLK_SEL = SYSCON_CLK_SEL_W_SARADC_SMPL_VALUE_DIV2; + Config.CH_SEL = ADC_CH4 | ADC_CH9; + Config.AVG = SARADC_CFG_AVG_VALUE_8_SAMPLE; + Config.CONT = SARADC_CFG_CONT_VALUE_SINGLE; + Config.MEM_MODE = SARADC_CFG_MEM_MODE_VALUE_CHANNEL; + Config.SMPL_CLK = SARADC_CFG_SMPL_CLK_VALUE_INTERNAL; + Config.SMPL_WIN = SARADC_CFG_SMPL_WIN_VALUE_15_CYCLE; + Config.SMPL_SETUP = SARADC_CFG_SMPL_SETUP_VALUE_1_CYCLE; + Config.ADC_TRIG = SARADC_CFG_ADC_TRIG_VALUE_CPU; + Config.CALIB_KD_VALID = SARADC_CALIB_KD_VALID_VALUE_YES; + Config.CALIB_OFFSET_VALID = SARADC_CALIB_OFFSET_VALID_VALUE_YES; + Config.DMA_EN = SARADC_CFG_DMA_EN_VALUE_DISABLE; + Config.IE_CHx_EOC = SARADC_IE_CHx_EOC_VALUE_NONE; + Config.IE_FIFO_FULL = SARADC_IE_FIFO_FULL_VALUE_DISABLE; + Config.IE_FIFO_HFULL = SARADC_IE_FIFO_HFULL_VALUE_DISABLE; - ADC_Configure(&Config); - ADC_Enable(); - ADC_SoftReset(); + ADC_Configure(&Config); + ADC_Enable(); + ADC_SoftReset(); } void BOARD_ADC_GetBatteryInfo(uint16_t *pVoltage, uint16_t *pCurrent) { - ADC_Start(); - while (!ADC_CheckEndOfConversion(ADC_CH9)) {} - *pVoltage = ADC_GetValue(ADC_CH4); - *pCurrent = ADC_GetValue(ADC_CH9); + ADC_Start(); + while (!ADC_CheckEndOfConversion(ADC_CH9)) {} + *pVoltage = ADC_GetValue(ADC_CH4); + *pCurrent = ADC_GetValue(ADC_CH9); } void BOARD_Init(void) { - BOARD_PORTCON_Init(); - BOARD_GPIO_Init(); - BACKLIGHT_InitHardware(); - BOARD_ADC_Init(); - ST7565_Init(); + BOARD_PORTCON_Init(); + BOARD_GPIO_Init(); + BACKLIGHT_InitHardware(); + BOARD_ADC_Init(); + ST7565_Init(); #ifdef ENABLE_FMRADIO - BK1080_Init0(); + BK1080_Init0(); #endif #if defined(ENABLE_UART) || defined(ENABLED_AIRCOPY) - CRC_Init(); + CRC_Init(); #endif } diff --git a/dcs.c b/dcs.c index 4615dc5..ba668e8 100644 --- a/dcs.c +++ b/dcs.c @@ -17,97 +17,97 @@ #include "dcs.h" #ifndef ARRAY_SIZE - #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif // CTCSS Hz * 10 const uint16_t CTCSS_Options[50] = { - 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, - 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, - 1318, 1365, 1413, 1462, 1514, 1567, 1598, 1622, 1655, 1679, - 1713, 1738, 1773, 1799, 1835, 1862, 1899, 1928, 1966, 1995, - 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541 + 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, + 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, + 1318, 1365, 1413, 1462, 1514, 1567, 1598, 1622, 1655, 1679, + 1713, 1738, 1773, 1799, 1835, 1862, 1899, 1928, 1966, 1995, + 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541 }; const uint16_t DCS_Options[104] = { - 0x0013, 0x0015, 0x0016, 0x0019, 0x001A, 0x001E, 0x0023, 0x0027, - 0x0029, 0x002B, 0x002C, 0x0035, 0x0039, 0x003A, 0x003B, 0x003C, - 0x004C, 0x004D, 0x004E, 0x0052, 0x0055, 0x0059, 0x005A, 0x005C, - 0x0063, 0x0065, 0x006A, 0x006D, 0x006E, 0x0072, 0x0075, 0x007A, - 0x007C, 0x0085, 0x008A, 0x0093, 0x0095, 0x0096, 0x00A3, 0x00A4, - 0x00A5, 0x00A6, 0x00A9, 0x00AA, 0x00AD, 0x00B1, 0x00B3, 0x00B5, - 0x00B6, 0x00B9, 0x00BC, 0x00C6, 0x00C9, 0x00CD, 0x00D5, 0x00D9, - 0x00DA, 0x00E3, 0x00E6, 0x00E9, 0x00EE, 0x00F4, 0x00F5, 0x00F9, - 0x0109, 0x010A, 0x010B, 0x0113, 0x0119, 0x011A, 0x0125, 0x0126, - 0x012A, 0x012C, 0x012D, 0x0132, 0x0134, 0x0135, 0x0136, 0x0143, - 0x0146, 0x014E, 0x0153, 0x0156, 0x015A, 0x0166, 0x0175, 0x0186, - 0x018A, 0x0194, 0x0197, 0x0199, 0x019A, 0x01AC, 0x01B2, 0x01B4, - 0x01C3, 0x01CA, 0x01D3, 0x01D9, 0x01DA, 0x01DC, 0x01E3, 0x01EC, + 0x0013, 0x0015, 0x0016, 0x0019, 0x001A, 0x001E, 0x0023, 0x0027, + 0x0029, 0x002B, 0x002C, 0x0035, 0x0039, 0x003A, 0x003B, 0x003C, + 0x004C, 0x004D, 0x004E, 0x0052, 0x0055, 0x0059, 0x005A, 0x005C, + 0x0063, 0x0065, 0x006A, 0x006D, 0x006E, 0x0072, 0x0075, 0x007A, + 0x007C, 0x0085, 0x008A, 0x0093, 0x0095, 0x0096, 0x00A3, 0x00A4, + 0x00A5, 0x00A6, 0x00A9, 0x00AA, 0x00AD, 0x00B1, 0x00B3, 0x00B5, + 0x00B6, 0x00B9, 0x00BC, 0x00C6, 0x00C9, 0x00CD, 0x00D5, 0x00D9, + 0x00DA, 0x00E3, 0x00E6, 0x00E9, 0x00EE, 0x00F4, 0x00F5, 0x00F9, + 0x0109, 0x010A, 0x010B, 0x0113, 0x0119, 0x011A, 0x0125, 0x0126, + 0x012A, 0x012C, 0x012D, 0x0132, 0x0134, 0x0135, 0x0136, 0x0143, + 0x0146, 0x014E, 0x0153, 0x0156, 0x015A, 0x0166, 0x0175, 0x0186, + 0x018A, 0x0194, 0x0197, 0x0199, 0x019A, 0x01AC, 0x01B2, 0x01B4, + 0x01C3, 0x01CA, 0x01D3, 0x01D9, 0x01DA, 0x01DC, 0x01E3, 0x01EC, }; static uint32_t DCS_CalculateGolay(uint32_t CodeWord) { - unsigned int i; - uint32_t Word = CodeWord; - for (i = 0; i < 12; i++) - { - Word <<= 1; - if (Word & 0x1000) - Word ^= 0x08EA; - } - return CodeWord | ((Word & 0x0FFE) << 11); + unsigned int i; + uint32_t Word = CodeWord; + for (i = 0; i < 12; i++) + { + Word <<= 1; + if (Word & 0x1000) + Word ^= 0x08EA; + } + return CodeWord | ((Word & 0x0FFE) << 11); } uint32_t DCS_GetGolayCodeWord(DCS_CodeType_t CodeType, uint8_t Option) { - uint32_t Code = DCS_CalculateGolay(DCS_Options[Option] + 0x800U); - if (CodeType == CODE_TYPE_REVERSE_DIGITAL) - Code ^= 0x7FFFFF; - return Code; + uint32_t Code = DCS_CalculateGolay(DCS_Options[Option] + 0x800U); + if (CodeType == CODE_TYPE_REVERSE_DIGITAL) + Code ^= 0x7FFFFF; + return Code; } uint8_t DCS_GetCdcssCode(uint32_t Code) { - unsigned int i; - for (i = 0; i < 23; i++) - { - uint32_t Shift; + unsigned int i; + for (i = 0; i < 23; i++) + { + uint32_t Shift; - if (((Code >> 9) & 0x7U) == 4) - { - unsigned int j; - for (j = 0; j < ARRAY_SIZE(DCS_Options); j++) - if (DCS_Options[j] == (Code & 0x1FF)) - if (DCS_GetGolayCodeWord(2, j) == Code) - return j; - } + if (((Code >> 9) & 0x7U) == 4) + { + unsigned int j; + for (j = 0; j < ARRAY_SIZE(DCS_Options); j++) + if (DCS_Options[j] == (Code & 0x1FF)) + if (DCS_GetGolayCodeWord(2, j) == Code) + return j; + } - Shift = Code >> 1; - if (Code & 1U) - Shift |= 0x400000U; - Code = Shift; - } + Shift = Code >> 1; + if (Code & 1U) + Shift |= 0x400000U; + Code = Shift; + } - return 0xFF; + return 0xFF; } uint8_t DCS_GetCtcssCode(int Code) { - unsigned int i; - uint8_t Result = 0xFF; - int Smallest = ARRAY_SIZE(CTCSS_Options); + unsigned int i; + uint8_t Result = 0xFF; + int Smallest = ARRAY_SIZE(CTCSS_Options); - for (i = 0; i < ARRAY_SIZE(CTCSS_Options); i++) - { - int Delta = Code - CTCSS_Options[i]; - if (Delta < 0) - Delta = -(Code - CTCSS_Options[i]); - if (Smallest > Delta) - { - Smallest = Delta; - Result = i; - } - } + for (i = 0; i < ARRAY_SIZE(CTCSS_Options); i++) + { + int Delta = Code - CTCSS_Options[i]; + if (Delta < 0) + Delta = -(Code - CTCSS_Options[i]); + if (Smallest > Delta) + { + Smallest = Delta; + Result = i; + } + } - return Result; + return Result; } diff --git a/dcs.h b/dcs.h index 873ddb6..2b4fbdf 100644 --- a/dcs.h +++ b/dcs.h @@ -21,17 +21,17 @@ enum DCS_CodeType_t { - CODE_TYPE_OFF = 0, - CODE_TYPE_CONTINUOUS_TONE, - CODE_TYPE_DIGITAL, - CODE_TYPE_REVERSE_DIGITAL + CODE_TYPE_OFF = 0, + CODE_TYPE_CONTINUOUS_TONE, + CODE_TYPE_DIGITAL, + CODE_TYPE_REVERSE_DIGITAL }; typedef enum DCS_CodeType_t DCS_CodeType_t; enum { - CDCSS_POSITIVE_CODE = 1U, - CDCSS_NEGATIVE_CODE = 2U, + CDCSS_POSITIVE_CODE = 1U, + CDCSS_NEGATIVE_CODE = 2U, }; extern const uint16_t CTCSS_Options[50]; diff --git a/debugging.h b/debugging.h index 68e44cb..aa0bb69 100644 --- a/debugging.h +++ b/debugging.h @@ -11,36 +11,36 @@ static inline void LogUart(const char *const str) { - UART_Send(str, strlen(str)); + UART_Send(str, strlen(str)); } static inline void LogUartf(const char* format, ...) { - char buffer[128]; - va_list va; - va_start(va, format); - vsnprintf(buffer, (size_t)-1, format, va); - va_end(va); - UART_Send(buffer, strlen(buffer)); + char buffer[128]; + va_list va; + va_start(va, format); + vsnprintf(buffer, (size_t)-1, format, va); + va_end(va); + UART_Send(buffer, strlen(buffer)); } static inline void LogRegUart(uint16_t reg) { - uint16_t regVal = BK4819_ReadRegister(reg); - char buf[32]; - sprintf(buf, "reg%02X: %04X\n", reg, regVal); - LogUart(buf); + uint16_t regVal = BK4819_ReadRegister(reg); + char buf[32]; + sprintf(buf, "reg%02X: %04X\n", reg, regVal); + LogUart(buf); } static inline void LogPrint() { - uint16_t rssi = BK4819_GetRSSI(); - uint16_t reg7e = BK4819_ReadRegister(0x7E); - char buf[32]; - sprintf(buf, "reg7E: %d %2d %6d %2d %d rssi: %d\n", (reg7e >> 15), - (reg7e >> 12) & 0b111, (reg7e >> 5) & 0b1111111, - (reg7e >> 2) & 0b111, (reg7e >> 0) & 0b11, rssi); - LogUart(buf); + uint16_t rssi = BK4819_GetRSSI(); + uint16_t reg7e = BK4819_ReadRegister(0x7E); + char buf[32]; + sprintf(buf, "reg7E: %d %2d %6d %2d %d rssi: %d\n", (reg7e >> 15), + (reg7e >> 12) & 0b111, (reg7e >> 5) & 0b1111111, + (reg7e >> 2) & 0b111, (reg7e >> 0) & 0b11, rssi); + LogUart(buf); } #endif diff --git a/driver/adc.c b/driver/adc.c index bde01f0..531b84d 100644 --- a/driver/adc.c +++ b/driver/adc.c @@ -22,40 +22,40 @@ uint8_t ADC_GetChannelNumber(ADC_CH_MASK Mask) { - if (Mask & ADC_CH15) return 15U; - if (Mask & ADC_CH14) return 14U; - if (Mask & ADC_CH13) return 13U; - if (Mask & ADC_CH12) return 12U; - if (Mask & ADC_CH11) return 11U; - if (Mask & ADC_CH10) return 10U; - if (Mask & ADC_CH9) return 9U; - if (Mask & ADC_CH8) return 8U; - if (Mask & ADC_CH7) return 7U; - if (Mask & ADC_CH6) return 6U; - if (Mask & ADC_CH5) return 5U; - if (Mask & ADC_CH4) return 4U; - if (Mask & ADC_CH3) return 3U; - if (Mask & ADC_CH2) return 2U; - if (Mask & ADC_CH1) return 1U; - if (Mask & ADC_CH0) return 0U; + if (Mask & ADC_CH15) return 15U; + if (Mask & ADC_CH14) return 14U; + if (Mask & ADC_CH13) return 13U; + if (Mask & ADC_CH12) return 12U; + if (Mask & ADC_CH11) return 11U; + if (Mask & ADC_CH10) return 10U; + if (Mask & ADC_CH9) return 9U; + if (Mask & ADC_CH8) return 8U; + if (Mask & ADC_CH7) return 7U; + if (Mask & ADC_CH6) return 6U; + if (Mask & ADC_CH5) return 5U; + if (Mask & ADC_CH4) return 4U; + if (Mask & ADC_CH3) return 3U; + if (Mask & ADC_CH2) return 2U; + if (Mask & ADC_CH1) return 1U; + if (Mask & ADC_CH0) return 0U; - return 0U; + return 0U; } void ADC_Disable(void) { - SARADC_CFG = (SARADC_CFG & ~SARADC_CFG_ADC_EN_MASK) | SARADC_CFG_ADC_EN_BITS_DISABLE; + SARADC_CFG = (SARADC_CFG & ~SARADC_CFG_ADC_EN_MASK) | SARADC_CFG_ADC_EN_BITS_DISABLE; } void ADC_Enable(void) { - SARADC_CFG = (SARADC_CFG & ~SARADC_CFG_ADC_EN_MASK) | SARADC_CFG_ADC_EN_BITS_ENABLE; + SARADC_CFG = (SARADC_CFG & ~SARADC_CFG_ADC_EN_MASK) | SARADC_CFG_ADC_EN_BITS_ENABLE; } void ADC_SoftReset(void) { - SARADC_START = (SARADC_START & ~SARADC_START_SOFT_RESET_MASK) | SARADC_START_SOFT_RESET_BITS_ASSERT; - SARADC_START = (SARADC_START & ~SARADC_START_SOFT_RESET_MASK) | SARADC_START_SOFT_RESET_BITS_DEASSERT; + SARADC_START = (SARADC_START & ~SARADC_START_SOFT_RESET_MASK) | SARADC_START_SOFT_RESET_BITS_ASSERT; + SARADC_START = (SARADC_START & ~SARADC_START_SOFT_RESET_MASK) | SARADC_START_SOFT_RESET_BITS_DEASSERT; } // The firmware thinks W_SARADC_SMPL_CLK_SEL is at [8:7] but the TRM says it's at [10:9] @@ -64,102 +64,102 @@ void ADC_SoftReset(void) uint32_t ADC_GetClockConfig(void) { - uint32_t Value; + uint32_t Value; - Value = SYSCON_CLK_SEL; + Value = SYSCON_CLK_SEL; - Value = 0 - | (Value & ~(SYSCON_CLK_SEL_R_PLL_MASK | FW_R_SARADC_SMPL_MASK)) - | (((Value & SYSCON_CLK_SEL_R_PLL_MASK) >> SYSCON_CLK_SEL_R_PLL_SHIFT) << SYSCON_CLK_SEL_W_PLL_SHIFT) - | (((Value & FW_R_SARADC_SMPL_MASK) >> FW_R_SARADC_SMPL_SHIFT) << SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT) - ; + Value = 0 + | (Value & ~(SYSCON_CLK_SEL_R_PLL_MASK | FW_R_SARADC_SMPL_MASK)) + | (((Value & SYSCON_CLK_SEL_R_PLL_MASK) >> SYSCON_CLK_SEL_R_PLL_SHIFT) << SYSCON_CLK_SEL_W_PLL_SHIFT) + | (((Value & FW_R_SARADC_SMPL_MASK) >> FW_R_SARADC_SMPL_SHIFT) << SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT) + ; - return Value; + return Value; } void ADC_Configure(ADC_Config_t *pAdc) { - SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SARADC_MASK) | SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE; + SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SARADC_MASK) | SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE; - ADC_Disable(); + ADC_Disable(); - SYSCON_CLK_SEL = (ADC_GetClockConfig() & ~SYSCON_CLK_SEL_W_SARADC_SMPL_MASK) | ((pAdc->CLK_SEL << SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT) & SYSCON_CLK_SEL_W_SARADC_SMPL_MASK); + SYSCON_CLK_SEL = (ADC_GetClockConfig() & ~SYSCON_CLK_SEL_W_SARADC_SMPL_MASK) | ((pAdc->CLK_SEL << SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT) & SYSCON_CLK_SEL_W_SARADC_SMPL_MASK); - SARADC_CFG = 0 - | (SARADC_CFG & ~(0 - | SARADC_CFG_CH_SEL_MASK - | SARADC_CFG_AVG_MASK - | SARADC_CFG_CONT_MASK - | SARADC_CFG_SMPL_SETUP_MASK - | SARADC_CFG_MEM_MODE_MASK - | SARADC_CFG_SMPL_CLK_MASK - | SARADC_CFG_SMPL_WIN_MASK - | SARADC_CFG_ADC_TRIG_MASK - | SARADC_CFG_DMA_EN_MASK - )) - | ((pAdc->CH_SEL << SARADC_CFG_CH_SEL_SHIFT) & SARADC_CFG_CH_SEL_MASK) - | ((pAdc->AVG << SARADC_CFG_AVG_SHIFT) & SARADC_CFG_AVG_MASK) - | ((pAdc->CONT << SARADC_CFG_CONT_SHIFT) & SARADC_CFG_CONT_MASK) - | ((pAdc->SMPL_SETUP << SARADC_CFG_SMPL_SETUP_SHIFT) & SARADC_CFG_SMPL_SETUP_MASK) - | ((pAdc->MEM_MODE << SARADC_CFG_MEM_MODE_SHIFT) & SARADC_CFG_MEM_MODE_MASK) - | ((pAdc->SMPL_CLK << SARADC_CFG_SMPL_CLK_SHIFT) & SARADC_CFG_SMPL_CLK_MASK) - | ((pAdc->SMPL_WIN << SARADC_CFG_SMPL_WIN_SHIFT) & SARADC_CFG_SMPL_WIN_MASK) - | ((pAdc->ADC_TRIG << SARADC_CFG_ADC_TRIG_SHIFT) & SARADC_CFG_ADC_TRIG_MASK) - | ((pAdc->DMA_EN << SARADC_CFG_DMA_EN_SHIFT) & SARADC_CFG_DMA_EN_MASK) - ; + SARADC_CFG = 0 + | (SARADC_CFG & ~(0 + | SARADC_CFG_CH_SEL_MASK + | SARADC_CFG_AVG_MASK + | SARADC_CFG_CONT_MASK + | SARADC_CFG_SMPL_SETUP_MASK + | SARADC_CFG_MEM_MODE_MASK + | SARADC_CFG_SMPL_CLK_MASK + | SARADC_CFG_SMPL_WIN_MASK + | SARADC_CFG_ADC_TRIG_MASK + | SARADC_CFG_DMA_EN_MASK + )) + | ((pAdc->CH_SEL << SARADC_CFG_CH_SEL_SHIFT) & SARADC_CFG_CH_SEL_MASK) + | ((pAdc->AVG << SARADC_CFG_AVG_SHIFT) & SARADC_CFG_AVG_MASK) + | ((pAdc->CONT << SARADC_CFG_CONT_SHIFT) & SARADC_CFG_CONT_MASK) + | ((pAdc->SMPL_SETUP << SARADC_CFG_SMPL_SETUP_SHIFT) & SARADC_CFG_SMPL_SETUP_MASK) + | ((pAdc->MEM_MODE << SARADC_CFG_MEM_MODE_SHIFT) & SARADC_CFG_MEM_MODE_MASK) + | ((pAdc->SMPL_CLK << SARADC_CFG_SMPL_CLK_SHIFT) & SARADC_CFG_SMPL_CLK_MASK) + | ((pAdc->SMPL_WIN << SARADC_CFG_SMPL_WIN_SHIFT) & SARADC_CFG_SMPL_WIN_MASK) + | ((pAdc->ADC_TRIG << SARADC_CFG_ADC_TRIG_SHIFT) & SARADC_CFG_ADC_TRIG_MASK) + | ((pAdc->DMA_EN << SARADC_CFG_DMA_EN_SHIFT) & SARADC_CFG_DMA_EN_MASK) + ; - SARADC_EXTTRIG_SEL = pAdc->EXTTRIG_SEL; + SARADC_EXTTRIG_SEL = pAdc->EXTTRIG_SEL; - if (pAdc->CALIB_OFFSET_VALID) { - SARADC_CALIB_OFFSET = (SARADC_CALIB_OFFSET & ~SARADC_CALIB_OFFSET_VALID_MASK) | SARADC_CALIB_OFFSET_VALID_BITS_YES; - } else { - SARADC_CALIB_OFFSET = (SARADC_CALIB_OFFSET & ~SARADC_CALIB_OFFSET_VALID_MASK) | SARADC_CALIB_OFFSET_VALID_BITS_NO; - } - if (pAdc->CALIB_KD_VALID) { - SARADC_CALIB_KD = (SARADC_CALIB_KD & ~SARADC_CALIB_KD_VALID_MASK) | SARADC_CALIB_KD_VALID_BITS_YES; - } else { - SARADC_CALIB_KD = (SARADC_CALIB_KD & ~SARADC_CALIB_KD_VALID_MASK) | SARADC_CALIB_KD_VALID_BITS_NO; - } + if (pAdc->CALIB_OFFSET_VALID) { + SARADC_CALIB_OFFSET = (SARADC_CALIB_OFFSET & ~SARADC_CALIB_OFFSET_VALID_MASK) | SARADC_CALIB_OFFSET_VALID_BITS_YES; + } else { + SARADC_CALIB_OFFSET = (SARADC_CALIB_OFFSET & ~SARADC_CALIB_OFFSET_VALID_MASK) | SARADC_CALIB_OFFSET_VALID_BITS_NO; + } + if (pAdc->CALIB_KD_VALID) { + SARADC_CALIB_KD = (SARADC_CALIB_KD & ~SARADC_CALIB_KD_VALID_MASK) | SARADC_CALIB_KD_VALID_BITS_YES; + } else { + SARADC_CALIB_KD = (SARADC_CALIB_KD & ~SARADC_CALIB_KD_VALID_MASK) | SARADC_CALIB_KD_VALID_BITS_NO; + } - SARADC_IF = 0xFFFFFFFF; - SARADC_IE = 0 - | (SARADC_IE & ~(0 - | SARADC_IE_CHx_EOC_MASK - | SARADC_IE_FIFO_FULL_MASK - | SARADC_IE_FIFO_HFULL_MASK - )) - | ((pAdc->IE_CHx_EOC << SARADC_IE_CHx_EOC_SHIFT) & SARADC_IE_CHx_EOC_MASK) - | ((pAdc->IE_FIFO_FULL << SARADC_IE_FIFO_FULL_SHIFT) & SARADC_IE_FIFO_FULL_MASK) - | ((pAdc->IE_FIFO_HFULL << SARADC_IE_FIFO_HFULL_SHIFT) & SARADC_IE_FIFO_HFULL_MASK) - ; + SARADC_IF = 0xFFFFFFFF; + SARADC_IE = 0 + | (SARADC_IE & ~(0 + | SARADC_IE_CHx_EOC_MASK + | SARADC_IE_FIFO_FULL_MASK + | SARADC_IE_FIFO_HFULL_MASK + )) + | ((pAdc->IE_CHx_EOC << SARADC_IE_CHx_EOC_SHIFT) & SARADC_IE_CHx_EOC_MASK) + | ((pAdc->IE_FIFO_FULL << SARADC_IE_FIFO_FULL_SHIFT) & SARADC_IE_FIFO_FULL_MASK) + | ((pAdc->IE_FIFO_HFULL << SARADC_IE_FIFO_HFULL_SHIFT) & SARADC_IE_FIFO_HFULL_MASK) + ; - if (SARADC_IE == 0) { - NVIC_DisableIRQ((IRQn_Type)DP32_SARADC_IRQn); - } else { - NVIC_EnableIRQ((IRQn_Type)DP32_SARADC_IRQn); - } + if (SARADC_IE == 0) { + NVIC_DisableIRQ((IRQn_Type)DP32_SARADC_IRQn); + } else { + NVIC_EnableIRQ((IRQn_Type)DP32_SARADC_IRQn); + } } void ADC_Start(void) { - SARADC_START = (SARADC_START & ~SARADC_START_START_MASK) | SARADC_START_START_BITS_ENABLE; + SARADC_START = (SARADC_START & ~SARADC_START_START_MASK) | SARADC_START_START_BITS_ENABLE; } bool ADC_CheckEndOfConversion(ADC_CH_MASK Mask) { - volatile ADC_Channel_t *pChannels = (volatile ADC_Channel_t *)&SARADC_CH0; - uint8_t Channel = ADC_GetChannelNumber(Mask); + volatile ADC_Channel_t *pChannels = (volatile ADC_Channel_t *)&SARADC_CH0; + uint8_t Channel = ADC_GetChannelNumber(Mask); - return (pChannels[Channel].STAT & ADC_CHx_STAT_EOC_MASK) >> ADC_CHx_STAT_EOC_SHIFT; + return (pChannels[Channel].STAT & ADC_CHx_STAT_EOC_MASK) >> ADC_CHx_STAT_EOC_SHIFT; } uint16_t ADC_GetValue(ADC_CH_MASK Mask) { - volatile ADC_Channel_t *pChannels = (volatile ADC_Channel_t *)&SARADC_CH0; - uint8_t Channel = ADC_GetChannelNumber(Mask); + volatile ADC_Channel_t *pChannels = (volatile ADC_Channel_t *)&SARADC_CH0; + uint8_t Channel = ADC_GetChannelNumber(Mask); - SARADC_IF = 1 << Channel; // TODO: Or just use 'Mask' + SARADC_IF = 1 << Channel; // TODO: Or just use 'Mask' - return (pChannels[Channel].DATA & ADC_CHx_DATA_DATA_MASK) >> ADC_CHx_DATA_DATA_SHIFT; + return (pChannels[Channel].DATA & ADC_CHx_DATA_DATA_MASK) >> ADC_CHx_DATA_DATA_SHIFT; } diff --git a/driver/adc.h b/driver/adc.h index cd5edc2..76539f1 100644 --- a/driver/adc.h +++ b/driver/adc.h @@ -21,44 +21,44 @@ #include enum ADC_CH_MASK { - ADC_CH0 = 0x0001U, - ADC_CH1 = 0x0002U, - ADC_CH2 = 0x0004U, - ADC_CH3 = 0x0008U, - ADC_CH4 = 0x0010U, - ADC_CH5 = 0x0020U, - ADC_CH6 = 0x0040U, - ADC_CH7 = 0x0080U, - ADC_CH8 = 0x0100U, - ADC_CH9 = 0x0200U, - ADC_CH10 = 0x0400U, - ADC_CH11 = 0x0800U, - ADC_CH12 = 0x1000U, - ADC_CH13 = 0x2000U, - ADC_CH14 = 0x4000U, - ADC_CH15 = 0x8000U, + ADC_CH0 = 0x0001U, + ADC_CH1 = 0x0002U, + ADC_CH2 = 0x0004U, + ADC_CH3 = 0x0008U, + ADC_CH4 = 0x0010U, + ADC_CH5 = 0x0020U, + ADC_CH6 = 0x0040U, + ADC_CH7 = 0x0080U, + ADC_CH8 = 0x0100U, + ADC_CH9 = 0x0200U, + ADC_CH10 = 0x0400U, + ADC_CH11 = 0x0800U, + ADC_CH12 = 0x1000U, + ADC_CH13 = 0x2000U, + ADC_CH14 = 0x4000U, + ADC_CH15 = 0x8000U, }; typedef enum ADC_CH_MASK ADC_CH_MASK; typedef struct { - uint16_t EXTTRIG_SEL; - uint16_t IE_CHx_EOC; - ADC_CH_MASK CH_SEL; - uint8_t CLK_SEL; - uint8_t AVG; - uint8_t CONT; - uint8_t MEM_MODE; - uint8_t SMPL_CLK; - uint8_t SMPL_SETUP; - uint8_t SMPL_WIN; - uint8_t ADC_TRIG; - uint8_t DMA_EN; - uint8_t IE_FIFO_HFULL; - uint8_t IE_FIFO_FULL; - bool CALIB_OFFSET_VALID; - bool CALIB_KD_VALID; - uint8_t _pad[1]; + uint16_t EXTTRIG_SEL; + uint16_t IE_CHx_EOC; + ADC_CH_MASK CH_SEL; + uint8_t CLK_SEL; + uint8_t AVG; + uint8_t CONT; + uint8_t MEM_MODE; + uint8_t SMPL_CLK; + uint8_t SMPL_SETUP; + uint8_t SMPL_WIN; + uint8_t ADC_TRIG; + uint8_t DMA_EN; + uint8_t IE_FIFO_HFULL; + uint8_t IE_FIFO_FULL; + bool CALIB_OFFSET_VALID; + bool CALIB_KD_VALID; + uint8_t _pad[1]; } ADC_Config_t; uint8_t ADC_GetChannelNumber(ADC_CH_MASK Mask); diff --git a/driver/aes.c b/driver/aes.c index 6a8b5c0..65906af 100644 --- a/driver/aes.c +++ b/driver/aes.c @@ -21,54 +21,54 @@ static void AES_Setup_ENC_CBC(bool IsDecrypt, const void *pKey, const void *pIv) { - const uint32_t *pK = (const uint32_t *)pKey; - const uint32_t *pI = (const uint32_t *)pIv; + const uint32_t *pK = (const uint32_t *)pKey; + const uint32_t *pI = (const uint32_t *)pIv; - (void)IsDecrypt; // unused - - AES_CR = (AES_CR & ~AES_CR_EN_MASK) | AES_CR_EN_BITS_DISABLE; - AES_CR = AES_CR_CHMOD_BITS_CBC; - AES_KEYR3 = pK[0]; - AES_KEYR2 = pK[1]; - AES_KEYR1 = pK[2]; - AES_KEYR0 = pK[3]; - AES_IVR3 = pI[0]; - AES_IVR2 = pI[1]; - AES_IVR1 = pI[2]; - AES_IVR0 = pI[3]; - AES_CR = (AES_CR & ~AES_CR_EN_MASK) | AES_CR_EN_BITS_ENABLE; + (void)IsDecrypt; // unused + + AES_CR = (AES_CR & ~AES_CR_EN_MASK) | AES_CR_EN_BITS_DISABLE; + AES_CR = AES_CR_CHMOD_BITS_CBC; + AES_KEYR3 = pK[0]; + AES_KEYR2 = pK[1]; + AES_KEYR1 = pK[2]; + AES_KEYR0 = pK[3]; + AES_IVR3 = pI[0]; + AES_IVR2 = pI[1]; + AES_IVR1 = pI[2]; + AES_IVR0 = pI[3]; + AES_CR = (AES_CR & ~AES_CR_EN_MASK) | AES_CR_EN_BITS_ENABLE; } static void AES_Transform(const void *pIn, void *pOut) { - const uint32_t *pI = (const uint32_t *)pIn; - uint32_t *pO = (uint32_t *)pOut; + const uint32_t *pI = (const uint32_t *)pIn; + uint32_t *pO = (uint32_t *)pOut; - AES_DINR = pI[0]; - AES_DINR = pI[1]; - AES_DINR = pI[2]; - AES_DINR = pI[3]; + AES_DINR = pI[0]; + AES_DINR = pI[1]; + AES_DINR = pI[2]; + AES_DINR = pI[3]; - while ((AES_SR & AES_SR_CCF_MASK) == AES_SR_CCF_BITS_NOT_COMPLETE) { - } + while ((AES_SR & AES_SR_CCF_MASK) == AES_SR_CCF_BITS_NOT_COMPLETE) { + } - pO[0] = AES_DOUTR; - pO[1] = AES_DOUTR; - pO[2] = AES_DOUTR; - pO[3] = AES_DOUTR; + pO[0] = AES_DOUTR; + pO[1] = AES_DOUTR; + pO[2] = AES_DOUTR; + pO[3] = AES_DOUTR; - AES_CR |= AES_CR_CCFC_BITS_SET; + AES_CR |= AES_CR_CCFC_BITS_SET; } void AES_Encrypt(const void *pKey, const void *pIv, const void *pIn, void *pOut, uint8_t NumBlocks) { - const uint8_t *pI = (const uint8_t *)pIn; - uint8_t *pO = (uint8_t *)pOut; - uint8_t i; + const uint8_t *pI = (const uint8_t *)pIn; + uint8_t *pO = (uint8_t *)pOut; + uint8_t i; - AES_Setup_ENC_CBC(0, pKey, pIv); - for (i = 0; i < NumBlocks; i++) { - AES_Transform(pI + (i * 16), pO + (i * 16)); - } + AES_Setup_ENC_CBC(0, pKey, pIv); + for (i = 0; i < NumBlocks; i++) { + AES_Transform(pI + (i * 16), pO + (i * 16)); + } } diff --git a/driver/backlight.c b/driver/backlight.c index b6544ed..8bac46a 100644 --- a/driver/backlight.c +++ b/driver/backlight.c @@ -22,9 +22,9 @@ #include "settings.h" #ifdef ENABLE_FEAT_F4HWN - #include "driver/system.h" - #include "audio.h" - #include "misc.h" + #include "driver/system.h" + #include "audio.h" + #include "misc.h" #endif // this is decremented once every 500ms @@ -33,128 +33,128 @@ bool backlightOn; void BACKLIGHT_InitHardware() { - // 48MHz / 94 / 1024 ~ 500Hz - const uint32_t PWM_FREQUENCY_HZ = 25000; - PWM_PLUS0_CLKSRC |= ((48000000 / 1024 / PWM_FREQUENCY_HZ) << 16); - PWM_PLUS0_PERIOD = 1023; + // 48MHz / 94 / 1024 ~ 500Hz + const uint32_t PWM_FREQUENCY_HZ = 25000; + PWM_PLUS0_CLKSRC |= ((48000000 / 1024 / PWM_FREQUENCY_HZ) << 16); + PWM_PLUS0_PERIOD = 1023; - PORTCON_PORTB_SEL0 &= ~(0 - // Back light - | PORTCON_PORTB_SEL0_B6_MASK - ); - PORTCON_PORTB_SEL0 |= 0 - // Back light PWM - | PORTCON_PORTB_SEL0_B6_BITS_PWMP0_CH0 - ; + PORTCON_PORTB_SEL0 &= ~(0 + // Back light + | PORTCON_PORTB_SEL0_B6_MASK + ); + PORTCON_PORTB_SEL0 |= 0 + // Back light PWM + | PORTCON_PORTB_SEL0_B6_BITS_PWMP0_CH0 + ; - PWM_PLUS0_GEN = - PWMPLUS_GEN_CH0_OE_BITS_ENABLE | - PWMPLUS_GEN_CH0_OUTINV_BITS_ENABLE | - 0; + PWM_PLUS0_GEN = + PWMPLUS_GEN_CH0_OE_BITS_ENABLE | + PWMPLUS_GEN_CH0_OUTINV_BITS_ENABLE | + 0; - PWM_PLUS0_CFG = - PWMPLUS_CFG_CNT_REP_BITS_ENABLE | - PWMPLUS_CFG_COUNTER_EN_BITS_ENABLE | - 0; + PWM_PLUS0_CFG = + PWMPLUS_CFG_CNT_REP_BITS_ENABLE | + PWMPLUS_CFG_COUNTER_EN_BITS_ENABLE | + 0; } static void BACKLIGHT_Sound(void) { - if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_SOUND || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_ALL) - { - AUDIO_PlayBeep(BEEP_880HZ_60MS_DOUBLE_BEEP); - AUDIO_PlayBeep(BEEP_880HZ_60MS_DOUBLE_BEEP); - gK5startup = false; - } - else - gK5startup = false; + if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_SOUND || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_ALL) + { + AUDIO_PlayBeep(BEEP_880HZ_60MS_DOUBLE_BEEP); + AUDIO_PlayBeep(BEEP_880HZ_60MS_DOUBLE_BEEP); + gK5startup = false; + } + else + gK5startup = false; } void BACKLIGHT_TurnOn(void) { - #ifdef ENABLE_FEAT_F4HWN - gBacklightBrightnessOld = BACKLIGHT_GetBrightness(); - #endif + #ifdef ENABLE_FEAT_F4HWN + gBacklightBrightnessOld = BACKLIGHT_GetBrightness(); + #endif - if (gEeprom.BACKLIGHT_TIME == 0) { - BACKLIGHT_TurnOff(); - #ifdef ENABLE_FEAT_F4HWN - if(gK5startup == true) - { - BACKLIGHT_Sound(); - } - #endif - return; - } + if (gEeprom.BACKLIGHT_TIME == 0) { + BACKLIGHT_TurnOff(); + #ifdef ENABLE_FEAT_F4HWN + if(gK5startup == true) + { + BACKLIGHT_Sound(); + } + #endif + return; + } - backlightOn = true; + backlightOn = true; #ifdef ENABLE_FEAT_F4HWN - if(gK5startup == true) { - for(uint8_t i = 0; i <= gEeprom.BACKLIGHT_MAX; i++) - { - BACKLIGHT_SetBrightness(i); - SYSTEM_DelayMs(50); - } + if(gK5startup == true) { + for(uint8_t i = 0; i <= gEeprom.BACKLIGHT_MAX; i++) + { + BACKLIGHT_SetBrightness(i); + SYSTEM_DelayMs(50); + } - BACKLIGHT_Sound(); - } - else - { - BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX); - } + BACKLIGHT_Sound(); + } + else + { + BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX); + } #else - BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX); + BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX); #endif - switch (gEeprom.BACKLIGHT_TIME) { - default: - case 1 ... 60: // 5 sec * value - gBacklightCountdown_500ms = 1 + (gEeprom.BACKLIGHT_TIME * 5) * 2; - break; - case 61: // always on - gBacklightCountdown_500ms = 0; - break; - } + switch (gEeprom.BACKLIGHT_TIME) { + default: + case 1 ... 60: // 5 sec * value + gBacklightCountdown_500ms = 1 + (gEeprom.BACKLIGHT_TIME * 5) * 2; + break; + case 61: // always on + gBacklightCountdown_500ms = 0; + break; + } } void BACKLIGHT_TurnOff() { #ifdef ENABLE_BLMIN_TMP_OFF - register uint8_t tmp; + register uint8_t tmp; - if (gEeprom.BACKLIGHT_MIN_STAT == BLMIN_STAT_ON) - tmp = gEeprom.BACKLIGHT_MIN; - else - tmp = 0; + if (gEeprom.BACKLIGHT_MIN_STAT == BLMIN_STAT_ON) + tmp = gEeprom.BACKLIGHT_MIN; + else + tmp = 0; - BACKLIGHT_SetBrightness(tmp); + BACKLIGHT_SetBrightness(tmp); #else - BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MIN); + BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MIN); #endif - gBacklightCountdown_500ms = 0; - backlightOn = false; + gBacklightCountdown_500ms = 0; + backlightOn = false; } bool BACKLIGHT_IsOn() { - return backlightOn; + return backlightOn; } static uint8_t currentBrightness; void BACKLIGHT_SetBrightness(uint8_t brigtness) { - const uint8_t value[] = {0, 3, 6, 9, 15, 24, 38, 62, 100, 159, 255}; + const uint8_t value[] = {0, 3, 6, 9, 15, 24, 38, 62, 100, 159, 255}; - currentBrightness = brigtness; - PWM_PLUS0_CH0_COMP = value[brigtness] * 4; - //PWM_PLUS0_CH0_COMP = (1 << brigtness) - 1; - //PWM_PLUS0_SWLOAD = 1; + currentBrightness = brigtness; + PWM_PLUS0_CH0_COMP = value[brigtness] * 4; + //PWM_PLUS0_CH0_COMP = (1 << brigtness) - 1; + //PWM_PLUS0_SWLOAD = 1; } uint8_t BACKLIGHT_GetBrightness(void) { - return currentBrightness; + return currentBrightness; } diff --git a/driver/bk1080-regs.h b/driver/bk1080-regs.h index 49dfdfc..8a030f7 100644 --- a/driver/bk1080-regs.h +++ b/driver/bk1080-regs.h @@ -18,40 +18,40 @@ #define BK1080_REGS_H enum BK1080_Register_t { - BK1080_REG_00 = 0x00U, - BK1080_REG_02_POWER_CONFIGURATION = 0x02U, - BK1080_REG_03_CHANNEL = 0x03U, - BK1080_REG_05_SYSTEM_CONFIGURATION2 = 0x05U, - BK1080_REG_07 = 0x07U, - BK1080_REG_10 = 0x0AU, - BK1080_REG_25_INTERNAL = 0x19U, + BK1080_REG_00 = 0x00U, + BK1080_REG_02_POWER_CONFIGURATION = 0x02U, + BK1080_REG_03_CHANNEL = 0x03U, + BK1080_REG_05_SYSTEM_CONFIGURATION2 = 0x05U, + BK1080_REG_07 = 0x07U, + BK1080_REG_10 = 0x0AU, + BK1080_REG_25_INTERNAL = 0x19U, }; typedef enum BK1080_Register_t BK1080_Register_t; // REG 07 -#define BK1080_REG_07_SHIFT_FREQD 4 -#define BK1080_REG_07_SHIFT_SNR 0 +#define BK1080_REG_07_SHIFT_FREQD 4 +#define BK1080_REG_07_SHIFT_SNR 0 -#define BK1080_REG_07_MASK_FREQD (0xFFFU << BK1080_REG_07_SHIFT_FREQD) -#define BK1080_REG_07_MASK_SNR (0x00FU << BK1080_REG_07_SHIFT_SNR) +#define BK1080_REG_07_MASK_FREQD (0xFFFU << BK1080_REG_07_SHIFT_FREQD) +#define BK1080_REG_07_MASK_SNR (0x00FU << BK1080_REG_07_SHIFT_SNR) -#define BK1080_REG_07_GET_FREQD(x) (((x) & BK1080_REG_07_MASK_FREQD) >> BK1080_REG_07_SHIFT_FREQD) -#define BK1080_REG_07_GET_SNR(x) (((x) & BK1080_REG_07_MASK_SNR) >> BK1080_REG_07_SHIFT_SNR) +#define BK1080_REG_07_GET_FREQD(x) (((x) & BK1080_REG_07_MASK_FREQD) >> BK1080_REG_07_SHIFT_FREQD) +#define BK1080_REG_07_GET_SNR(x) (((x) & BK1080_REG_07_MASK_SNR) >> BK1080_REG_07_SHIFT_SNR) // REG 10 -#define BK1080_REG_10_SHIFT_AFCRL 12 -#define BK1080_REG_10_SHIFT_RSSI 0 +#define BK1080_REG_10_SHIFT_AFCRL 12 +#define BK1080_REG_10_SHIFT_RSSI 0 -#define BK1080_REG_10_MASK_AFCRL (0x01U << BK1080_REG_10_SHIFT_AFCRL) -#define BK1080_REG_10_MASK_RSSI (0xFFU << BK1080_REG_10_SHIFT_RSSI) +#define BK1080_REG_10_MASK_AFCRL (0x01U << BK1080_REG_10_SHIFT_AFCRL) +#define BK1080_REG_10_MASK_RSSI (0xFFU << BK1080_REG_10_SHIFT_RSSI) -#define BK1080_REG_10_AFCRL_NOT_RAILED (0U << BK1080_REG_10_SHIFT_AFCRL) -#define BK1080_REG_10_AFCRL_RAILED (1U << BK1080_REG_10_SHIFT_AFCRL) +#define BK1080_REG_10_AFCRL_NOT_RAILED (0U << BK1080_REG_10_SHIFT_AFCRL) +#define BK1080_REG_10_AFCRL_RAILED (1U << BK1080_REG_10_SHIFT_AFCRL) -#define BK1080_REG_10_GET_RSSI(x) (((x) & BK1080_REG_10_MASK_RSSI) >> BK1080_REG_10_SHIFT_RSSI) +#define BK1080_REG_10_GET_RSSI(x) (((x) & BK1080_REG_10_MASK_RSSI) >> BK1080_REG_10_SHIFT_RSSI) #endif diff --git a/driver/bk1080.c b/driver/bk1080.c index b14af1a..3c8e921 100644 --- a/driver/bk1080.c +++ b/driver/bk1080.c @@ -22,16 +22,16 @@ #include "misc.h" #ifndef ARRAY_SIZE - #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) #endif static const uint16_t BK1080_RegisterTable[] = { - 0x0008, 0x1080, 0x0201, 0x0000, 0x40C0, 0x0A1F, 0x002E, 0x02FF, - 0x5B11, 0x0000, 0x411E, 0x0000, 0xCE00, 0x0000, 0x0000, 0x1000, - 0x3197, 0x0000, 0x13FF, 0x9852, 0x0000, 0x0000, 0x0008, 0x0000, - 0x51E1, 0xA8BC, 0x2645, 0x00E4, 0x1CD8, 0x3A50, 0xEAE0, 0x3000, - 0x0200, 0x0000, + 0x0008, 0x1080, 0x0201, 0x0000, 0x40C0, 0x0A1F, 0x002E, 0x02FF, + 0x5B11, 0x0000, 0x411E, 0x0000, 0xCE00, 0x0000, 0x0000, 0x1000, + 0x3197, 0x0000, 0x13FF, 0x9852, 0x0000, 0x0000, 0x0008, 0x0000, + 0x51E1, 0xA8BC, 0x2645, 0x00E4, 0x1CD8, 0x3A50, 0xEAE0, 0x3000, + 0x0200, 0x0000, }; static bool gIsInitBK1080; @@ -41,104 +41,104 @@ uint16_t BK1080_FrequencyDeviation; void BK1080_Init0(void) { - BK1080_Init(0,0/*,0*/); + BK1080_Init(0,0/*,0*/); } void BK1080_Init(uint16_t freq, uint8_t band/*, uint8_t space*/) { - unsigned int i; + unsigned int i; - if (freq) { - GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BK1080); + if (freq) { + GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BK1080); - if (!gIsInitBK1080) { - for (i = 0; i < ARRAY_SIZE(BK1080_RegisterTable); i++) - BK1080_WriteRegister(i, BK1080_RegisterTable[i]); + if (!gIsInitBK1080) { + for (i = 0; i < ARRAY_SIZE(BK1080_RegisterTable); i++) + BK1080_WriteRegister(i, BK1080_RegisterTable[i]); - SYSTEM_DelayMs(250); + SYSTEM_DelayMs(250); - BK1080_WriteRegister(BK1080_REG_25_INTERNAL, 0xA83C); - BK1080_WriteRegister(BK1080_REG_25_INTERNAL, 0xA8BC); + BK1080_WriteRegister(BK1080_REG_25_INTERNAL, 0xA83C); + BK1080_WriteRegister(BK1080_REG_25_INTERNAL, 0xA8BC); - SYSTEM_DelayMs(60); + SYSTEM_DelayMs(60); - gIsInitBK1080 = true; - } - else { - BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x0201); - } + gIsInitBK1080 = true; + } + else { + BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x0201); + } - BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, 0x0A1F); - BK1080_SetFrequency(freq, band/*, space*/); - } - else { - BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x0241); - GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BK1080); - } + BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, 0x0A1F); + BK1080_SetFrequency(freq, band/*, space*/); + } + else { + BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x0241); + GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BK1080); + } } uint16_t BK1080_ReadRegister(BK1080_Register_t Register) { - uint8_t Value[2]; + uint8_t Value[2]; - I2C_Start(); - I2C_Write(0x80); - I2C_Write((Register << 1) | I2C_READ); - I2C_ReadBuffer(Value, sizeof(Value)); - I2C_Stop(); + I2C_Start(); + I2C_Write(0x80); + I2C_Write((Register << 1) | I2C_READ); + I2C_ReadBuffer(Value, sizeof(Value)); + I2C_Stop(); - return (Value[0] << 8) | Value[1]; + return (Value[0] << 8) | Value[1]; } void BK1080_WriteRegister(BK1080_Register_t Register, uint16_t Value) { - I2C_Start(); - I2C_Write(0x80); - I2C_Write((Register << 1) | I2C_WRITE); - Value = ((Value >> 8) & 0xFF) | ((Value & 0xFF) << 8); - I2C_WriteBuffer(&Value, sizeof(Value)); - I2C_Stop(); + I2C_Start(); + I2C_Write(0x80); + I2C_Write((Register << 1) | I2C_WRITE); + Value = ((Value >> 8) & 0xFF) | ((Value & 0xFF) << 8); + I2C_WriteBuffer(&Value, sizeof(Value)); + I2C_Stop(); } void BK1080_Mute(bool Mute) { - BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, Mute ? 0x4201 : 0x0201); + BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, Mute ? 0x4201 : 0x0201); } void BK1080_SetFrequency(uint16_t frequency, uint8_t band/*, uint8_t space*/) { - //uint8_t spacings[] = {20,10,5}; - //space %= 3; + //uint8_t spacings[] = {20,10,5}; + //space %= 3; - uint16_t channel = (frequency - BK1080_GetFreqLoLimit(band))/* * 10 / spacings[space]*/; + uint16_t channel = (frequency - BK1080_GetFreqLoLimit(band))/* * 10 / spacings[space]*/; - uint16_t regval = BK1080_ReadRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2); - regval = (regval & ~(0b11 << 6)) | ((band & 0b11) << 6); - //regval = (regval & ~(0b11 << 4)) | ((space & 0b11) << 4); + uint16_t regval = BK1080_ReadRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2); + regval = (regval & ~(0b11 << 6)) | ((band & 0b11) << 6); + //regval = (regval & ~(0b11 << 4)) | ((space & 0b11) << 4); - BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, regval); + BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, regval); - BK1080_WriteRegister(BK1080_REG_03_CHANNEL, channel); - SYSTEM_DelayMs(10); - BK1080_WriteRegister(BK1080_REG_03_CHANNEL, channel | 0x8000); + BK1080_WriteRegister(BK1080_REG_03_CHANNEL, channel); + SYSTEM_DelayMs(10); + BK1080_WriteRegister(BK1080_REG_03_CHANNEL, channel | 0x8000); } void BK1080_GetFrequencyDeviation(uint16_t Frequency) { - BK1080_BaseFrequency = Frequency; - BK1080_FrequencyDeviation = BK1080_ReadRegister(BK1080_REG_07) / 16; + BK1080_BaseFrequency = Frequency; + BK1080_FrequencyDeviation = BK1080_ReadRegister(BK1080_REG_07) / 16; } uint16_t BK1080_GetFreqLoLimit(uint8_t band) { - uint16_t lim[] = {875, 760, 760, 640}; - return lim[band % 4]; + uint16_t lim[] = {875, 760, 760, 640}; + return lim[band % 4]; } uint16_t BK1080_GetFreqHiLimit(uint8_t band) { - band %= 4; - uint16_t lim[] = {1080, 1080, 900, 760}; - return lim[band % 4]; + band %= 4; + uint16_t lim[] = {1080, 1080, 900, 760}; + return lim[band % 4]; } diff --git a/driver/bk4819-regs.h b/driver/bk4819-regs.h index 3b67310..7c33371 100644 --- a/driver/bk4819-regs.h +++ b/driver/bk4819-regs.h @@ -32,179 +32,179 @@ static const RegisterSpec afOutRegSpec = {"AF Output Select", 0x47, 8, 0xF, 1}; static const RegisterSpec afDacGainRegSpec = {"AF DAC Gain", 0x48, 0, 0xF, 1}; enum BK4819_REGISTER_t { - BK4819_REG_00 = 0x00U, - BK4819_REG_02 = 0x02U, - BK4819_REG_06 = 0x06U, - BK4819_REG_07 = 0x07U, - BK4819_REG_08 = 0x08U, - BK4819_REG_09 = 0x09U, - BK4819_REG_0B = 0x0BU, - BK4819_REG_0C = 0x0CU, - BK4819_REG_0D = 0x0DU, - BK4819_REG_0E = 0x0EU, - // RX AGC Gain Table[0] - BK4819_REG_10 = 0x10U, - // RX AGC Gain Table[1] - BK4819_REG_11 = 0x11U, - // RX AGC Gain Table[2] - BK4819_REG_12 = 0x12U, - // RX AGC Gain Table[3] - BK4819_REG_13 = 0x13U, - // RX AGC Gain Table[-1] - BK4819_REG_14 = 0x14U, - BK4819_REG_19 = 0x19U, - BK4819_REG_1F = 0x1FU, - BK4819_REG_20 = 0x20U, - BK4819_REG_21 = 0x21U, - BK4819_REG_24 = 0x24U, - BK4819_REG_28 = 0x28U, - BK4819_REG_29 = 0x29U, - BK4819_REG_2B = 0x2BU, - BK4819_REG_30 = 0x30U, - BK4819_REG_31 = 0x31U, - BK4819_REG_32 = 0x32U, - BK4819_REG_33 = 0x33U, - BK4819_REG_36 = 0x36U, - BK4819_REG_37 = 0x37U, - BK4819_REG_38 = 0x38U, - BK4819_REG_39 = 0x39U, - BK4819_REG_3A = 0x3AU, - BK4819_REG_3B = 0x3BU, - BK4819_REG_3C = 0x3CU, - BK4819_REG_3D = 0x3DU, - BK4819_REG_3E = 0x3EU, - BK4819_REG_3F = 0x3FU, - BK4819_REG_43 = 0x43U, - BK4819_REG_46 = 0x46U, - BK4819_REG_47 = 0x47U, - BK4819_REG_48 = 0x48U, - // REG_49<15:14> 0b00; High/Low Lo selection: - // 0X: Auto High/Low Lo - // 10: Low Lo - // 11: High Lo - // REG_49<13:7> 0x50; RF AGC high threshold, 1 dB/LSB - // REG_49<6:0> 0x30; RF AGC low threshold, 1 dB/LSB - BK4819_REG_49 = 0x49U, - BK4819_REG_4D = 0x4DU, - BK4819_REG_4E = 0x4EU, - BK4819_REG_4F = 0x4FU, - BK4819_REG_50 = 0x50U, - BK4819_REG_51 = 0x51U, - BK4819_REG_52 = 0x52U, - BK4819_REG_58 = 0x58U, - BK4819_REG_59 = 0x59U, - BK4819_REG_5A = 0x5AU, - BK4819_REG_5B = 0x5BU, - BK4819_REG_5C = 0x5CU, - BK4819_REG_5D = 0x5DU, - BK4819_REG_5F = 0x5FU, - BK4819_REG_63 = 0x63U, - BK4819_REG_64 = 0x64U, - BK4819_REG_65 = 0x65U, - BK4819_REG_67 = 0x67U, - BK4819_REG_68 = 0x68U, - BK4819_REG_69 = 0x69U, - BK4819_REG_6A = 0x6AU, - BK4819_REG_6F = 0x6FU, - BK4819_REG_70 = 0x70U, - BK4819_REG_71 = 0x71U, - BK4819_REG_72 = 0x72U, - BK4819_REG_78 = 0x78U, - BK4819_REG_79 = 0x79U, - BK4819_REG_7A = 0x7AU, - // REG_7B<15:0> 0xae34 RSSI table - BK4819_REG_7B = 0x7BU, - // REG_7C<15:0> 0x8000 RSSI table - BK4819_REG_7C = 0x7CU, - BK4819_REG_7D = 0x7DU, - // REG_7E<15> 0; AGC fix mode: - // 1: Fix - // 0: Auto - // REG_7E<14:12> 0b011; AGC fix index: - // 011: Max. - // … - // 100: Min. - // REG_7E<5:3> 0b101; DC filter bandwidth for TX (MIC in): - // 000: Bypass DC filter - // REG_7E<2:0> 0b110; DC filter bandwidth for RX (IF in): - // 000: Bypass DC filter - BK4819_REG_7E = 0x7EU, + BK4819_REG_00 = 0x00U, + BK4819_REG_02 = 0x02U, + BK4819_REG_06 = 0x06U, + BK4819_REG_07 = 0x07U, + BK4819_REG_08 = 0x08U, + BK4819_REG_09 = 0x09U, + BK4819_REG_0B = 0x0BU, + BK4819_REG_0C = 0x0CU, + BK4819_REG_0D = 0x0DU, + BK4819_REG_0E = 0x0EU, + // RX AGC Gain Table[0] + BK4819_REG_10 = 0x10U, + // RX AGC Gain Table[1] + BK4819_REG_11 = 0x11U, + // RX AGC Gain Table[2] + BK4819_REG_12 = 0x12U, + // RX AGC Gain Table[3] + BK4819_REG_13 = 0x13U, + // RX AGC Gain Table[-1] + BK4819_REG_14 = 0x14U, + BK4819_REG_19 = 0x19U, + BK4819_REG_1F = 0x1FU, + BK4819_REG_20 = 0x20U, + BK4819_REG_21 = 0x21U, + BK4819_REG_24 = 0x24U, + BK4819_REG_28 = 0x28U, + BK4819_REG_29 = 0x29U, + BK4819_REG_2B = 0x2BU, + BK4819_REG_30 = 0x30U, + BK4819_REG_31 = 0x31U, + BK4819_REG_32 = 0x32U, + BK4819_REG_33 = 0x33U, + BK4819_REG_36 = 0x36U, + BK4819_REG_37 = 0x37U, + BK4819_REG_38 = 0x38U, + BK4819_REG_39 = 0x39U, + BK4819_REG_3A = 0x3AU, + BK4819_REG_3B = 0x3BU, + BK4819_REG_3C = 0x3CU, + BK4819_REG_3D = 0x3DU, + BK4819_REG_3E = 0x3EU, + BK4819_REG_3F = 0x3FU, + BK4819_REG_43 = 0x43U, + BK4819_REG_46 = 0x46U, + BK4819_REG_47 = 0x47U, + BK4819_REG_48 = 0x48U, + // REG_49<15:14> 0b00; High/Low Lo selection: + // 0X: Auto High/Low Lo + // 10: Low Lo + // 11: High Lo + // REG_49<13:7> 0x50; RF AGC high threshold, 1 dB/LSB + // REG_49<6:0> 0x30; RF AGC low threshold, 1 dB/LSB + BK4819_REG_49 = 0x49U, + BK4819_REG_4D = 0x4DU, + BK4819_REG_4E = 0x4EU, + BK4819_REG_4F = 0x4FU, + BK4819_REG_50 = 0x50U, + BK4819_REG_51 = 0x51U, + BK4819_REG_52 = 0x52U, + BK4819_REG_58 = 0x58U, + BK4819_REG_59 = 0x59U, + BK4819_REG_5A = 0x5AU, + BK4819_REG_5B = 0x5BU, + BK4819_REG_5C = 0x5CU, + BK4819_REG_5D = 0x5DU, + BK4819_REG_5F = 0x5FU, + BK4819_REG_63 = 0x63U, + BK4819_REG_64 = 0x64U, + BK4819_REG_65 = 0x65U, + BK4819_REG_67 = 0x67U, + BK4819_REG_68 = 0x68U, + BK4819_REG_69 = 0x69U, + BK4819_REG_6A = 0x6AU, + BK4819_REG_6F = 0x6FU, + BK4819_REG_70 = 0x70U, + BK4819_REG_71 = 0x71U, + BK4819_REG_72 = 0x72U, + BK4819_REG_78 = 0x78U, + BK4819_REG_79 = 0x79U, + BK4819_REG_7A = 0x7AU, + // REG_7B<15:0> 0xae34 RSSI table + BK4819_REG_7B = 0x7BU, + // REG_7C<15:0> 0x8000 RSSI table + BK4819_REG_7C = 0x7CU, + BK4819_REG_7D = 0x7DU, + // REG_7E<15> 0; AGC fix mode: + // 1: Fix + // 0: Auto + // REG_7E<14:12> 0b011; AGC fix index: + // 011: Max. + // … + // 100: Min. + // REG_7E<5:3> 0b101; DC filter bandwidth for TX (MIC in): + // 000: Bypass DC filter + // REG_7E<2:0> 0b110; DC filter bandwidth for RX (IF in): + // 000: Bypass DC filter + BK4819_REG_7E = 0x7EU, }; typedef enum BK4819_REGISTER_t BK4819_REGISTER_t; enum BK4819_GPIO_PIN_t { - BK4819_GPIO0_PIN28_RX_ENABLE = 0, - BK4819_GPIO1_PIN29_PA_ENABLE = 1, - BK4819_GPIO3_PIN31_UHF_LNA = 3, - BK4819_GPIO4_PIN32_VHF_LNA = 4, - BK4819_GPIO5_PIN1_RED = 5, - BK4819_GPIO6_PIN2_GREEN = 6, + BK4819_GPIO0_PIN28_RX_ENABLE = 0, + BK4819_GPIO1_PIN29_PA_ENABLE = 1, + BK4819_GPIO3_PIN31_UHF_LNA = 3, + BK4819_GPIO4_PIN32_VHF_LNA = 4, + BK4819_GPIO5_PIN1_RED = 5, + BK4819_GPIO6_PIN2_GREEN = 6, }; typedef enum BK4819_GPIO_PIN_t BK4819_GPIO_PIN_t; // REG 02 -#define BK4819_REG_02_SHIFT_FSK_TX_FINISHED 15 -#define BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_EMPTY 14 -#define BK4819_REG_02_SHIFT_FSK_RX_FINISHED 13 -#define BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_FULL 12 -#define BK4819_REG_02_SHIFT_DTMF_5TONE_FOUND 11 -#define BK4819_REG_02_SHIFT_CxCSS_TAIL 10 -#define BK4819_REG_02_SHIFT_CDCSS_FOUND 9 -#define BK4819_REG_02_SHIFT_CDCSS_LOST 8 -#define BK4819_REG_02_SHIFT_CTCSS_FOUND 7 -#define BK4819_REG_02_SHIFT_CTCSS_LOST 6 -#define BK4819_REG_02_SHIFT_VOX_FOUND 5 -#define BK4819_REG_02_SHIFT_VOX_LOST 4 -#define BK4819_REG_02_SHIFT_SQUELCH_FOUND 3 -#define BK4819_REG_02_SHIFT_SQUELCH_LOST 2 -#define BK4819_REG_02_SHIFT_FSK_RX_SYNC 1 +#define BK4819_REG_02_SHIFT_FSK_TX_FINISHED 15 +#define BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_EMPTY 14 +#define BK4819_REG_02_SHIFT_FSK_RX_FINISHED 13 +#define BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_FULL 12 +#define BK4819_REG_02_SHIFT_DTMF_5TONE_FOUND 11 +#define BK4819_REG_02_SHIFT_CxCSS_TAIL 10 +#define BK4819_REG_02_SHIFT_CDCSS_FOUND 9 +#define BK4819_REG_02_SHIFT_CDCSS_LOST 8 +#define BK4819_REG_02_SHIFT_CTCSS_FOUND 7 +#define BK4819_REG_02_SHIFT_CTCSS_LOST 6 +#define BK4819_REG_02_SHIFT_VOX_FOUND 5 +#define BK4819_REG_02_SHIFT_VOX_LOST 4 +#define BK4819_REG_02_SHIFT_SQUELCH_FOUND 3 +#define BK4819_REG_02_SHIFT_SQUELCH_LOST 2 +#define BK4819_REG_02_SHIFT_FSK_RX_SYNC 1 -#define BK4819_REG_02_MASK_FSK_TX_FINISHED (1U << BK4819_REG_02_SHIFT_FSK_TX) -#define BK4819_REG_02_MASK_FSK_FIFO_ALMOST_EMPTY (1U << BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_EMPTY) -#define BK4819_REG_02_MASK_FSK_RX_FINISHED (1U << BK4819_REG_02_SHIFT_FSK_RX_FINISHED) -#define BK4819_REG_02_MASK_FSK_FIFO_ALMOST_FULL (1U << BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_FULL) -#define BK4819_REG_02_MASK_DTMF_5TONE_FOUND (1U << BK4819_REG_02_SHIFT_DTMF_5TONE_FOUND) -#define BK4819_REG_02_MASK_CxCSS_TAIL (1U << BK4819_REG_02_SHIFT_CxCSS_TAIL) -#define BK4819_REG_02_MASK_CDCSS_FOUND (1U << BK4819_REG_02_SHIFT_CDCSS_FOUND) -#define BK4819_REG_02_MASK_CDCSS_LOST (1U << BK4819_REG_02_SHIFT_CDCSS_LOST) -#define BK4819_REG_02_MASK_CTCSS_FOUND (1U << BK4819_REG_02_SHIFT_CTCSS_FOUND) -#define BK4819_REG_02_MASK_CTCSS_LOST (1U << BK4819_REG_02_SHIFT_CTCSS_LOST) -#define BK4819_REG_02_MASK_VOX_FOUND (1U << BK4819_REG_02_SHIFT_VOX_FOUND) -#define BK4819_REG_02_MASK_VOX_LOST (1U << BK4819_REG_02_SHIFT_VOX_LOST) -#define BK4819_REG_02_MASK_SQUELCH_FOUND (1U << BK4819_REG_02_SHIFT_SQUELCH_FOUND) -#define BK4819_REG_02_MASK_SQUELCH_LOST (1U << BK4819_REG_02_SHIFT_SQUELCH_LOST) -#define BK4819_REG_02_MASK_FSK_RX_SYNC (1U << BK4819_REG_02_SHIFT_FSK_RX_SYNC) +#define BK4819_REG_02_MASK_FSK_TX_FINISHED (1U << BK4819_REG_02_SHIFT_FSK_TX) +#define BK4819_REG_02_MASK_FSK_FIFO_ALMOST_EMPTY (1U << BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_EMPTY) +#define BK4819_REG_02_MASK_FSK_RX_FINISHED (1U << BK4819_REG_02_SHIFT_FSK_RX_FINISHED) +#define BK4819_REG_02_MASK_FSK_FIFO_ALMOST_FULL (1U << BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_FULL) +#define BK4819_REG_02_MASK_DTMF_5TONE_FOUND (1U << BK4819_REG_02_SHIFT_DTMF_5TONE_FOUND) +#define BK4819_REG_02_MASK_CxCSS_TAIL (1U << BK4819_REG_02_SHIFT_CxCSS_TAIL) +#define BK4819_REG_02_MASK_CDCSS_FOUND (1U << BK4819_REG_02_SHIFT_CDCSS_FOUND) +#define BK4819_REG_02_MASK_CDCSS_LOST (1U << BK4819_REG_02_SHIFT_CDCSS_LOST) +#define BK4819_REG_02_MASK_CTCSS_FOUND (1U << BK4819_REG_02_SHIFT_CTCSS_FOUND) +#define BK4819_REG_02_MASK_CTCSS_LOST (1U << BK4819_REG_02_SHIFT_CTCSS_LOST) +#define BK4819_REG_02_MASK_VOX_FOUND (1U << BK4819_REG_02_SHIFT_VOX_FOUND) +#define BK4819_REG_02_MASK_VOX_LOST (1U << BK4819_REG_02_SHIFT_VOX_LOST) +#define BK4819_REG_02_MASK_SQUELCH_FOUND (1U << BK4819_REG_02_SHIFT_SQUELCH_FOUND) +#define BK4819_REG_02_MASK_SQUELCH_LOST (1U << BK4819_REG_02_SHIFT_SQUELCH_LOST) +#define BK4819_REG_02_MASK_FSK_RX_SYNC (1U << BK4819_REG_02_SHIFT_FSK_RX_SYNC) -#define BK4819_REG_02_FSK_TX_FINISHED (1U << BK4819_REG_02_SHIFT_FSK_TX_FINISHED) -#define BK4819_REG_02_FSK_FIFO_ALMOST_EMPTY (1U << BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_EMPTY) -#define BK4819_REG_02_FSK_RX_FINISHED (1U << BK4819_REG_02_SHIFT_FSK_RX_FINISHED) -#define BK4819_REG_02_FSK_FIFO_ALMOST_FULL (1U << BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_FULL) -#define BK4819_REG_02_DTMF_5TONE_FOUND (1U << BK4819_REG_02_SHIFT_DTMF_5TONE_FOUND) -#define BK4819_REG_02_CxCSS_TAIL (1U << BK4819_REG_02_SHIFT_CxCSS_TAIL) -#define BK4819_REG_02_CDCSS_FOUND (1U << BK4819_REG_02_SHIFT_CDCSS_FOUND) -#define BK4819_REG_02_CDCSS_LOST (1U << BK4819_REG_02_SHIFT_CDCSS_LOST) -#define BK4819_REG_02_CTCSS_FOUND (1U << BK4819_REG_02_SHIFT_CTCSS_FOUND) -#define BK4819_REG_02_CTCSS_LOST (1U << BK4819_REG_02_SHIFT_CTCSS_LOST) -#define BK4819_REG_02_VOX_FOUND (1U << BK4819_REG_02_SHIFT_VOX_FOUND) -#define BK4819_REG_02_VOX_LOST (1U << BK4819_REG_02_SHIFT_VOX_LOST) -#define BK4819_REG_02_SQUELCH_FOUND (1U << BK4819_REG_02_SHIFT_SQUELCH_FOUND) -#define BK4819_REG_02_SQUELCH_LOST (1U << BK4819_REG_02_SHIFT_SQUELCH_LOST) -#define BK4819_REG_02_FSK_RX_SYNC (1U << BK4819_REG_02_SHIFT_FSK_RX_SYNC) +#define BK4819_REG_02_FSK_TX_FINISHED (1U << BK4819_REG_02_SHIFT_FSK_TX_FINISHED) +#define BK4819_REG_02_FSK_FIFO_ALMOST_EMPTY (1U << BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_EMPTY) +#define BK4819_REG_02_FSK_RX_FINISHED (1U << BK4819_REG_02_SHIFT_FSK_RX_FINISHED) +#define BK4819_REG_02_FSK_FIFO_ALMOST_FULL (1U << BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_FULL) +#define BK4819_REG_02_DTMF_5TONE_FOUND (1U << BK4819_REG_02_SHIFT_DTMF_5TONE_FOUND) +#define BK4819_REG_02_CxCSS_TAIL (1U << BK4819_REG_02_SHIFT_CxCSS_TAIL) +#define BK4819_REG_02_CDCSS_FOUND (1U << BK4819_REG_02_SHIFT_CDCSS_FOUND) +#define BK4819_REG_02_CDCSS_LOST (1U << BK4819_REG_02_SHIFT_CDCSS_LOST) +#define BK4819_REG_02_CTCSS_FOUND (1U << BK4819_REG_02_SHIFT_CTCSS_FOUND) +#define BK4819_REG_02_CTCSS_LOST (1U << BK4819_REG_02_SHIFT_CTCSS_LOST) +#define BK4819_REG_02_VOX_FOUND (1U << BK4819_REG_02_SHIFT_VOX_FOUND) +#define BK4819_REG_02_VOX_LOST (1U << BK4819_REG_02_SHIFT_VOX_LOST) +#define BK4819_REG_02_SQUELCH_FOUND (1U << BK4819_REG_02_SHIFT_SQUELCH_FOUND) +#define BK4819_REG_02_SQUELCH_LOST (1U << BK4819_REG_02_SHIFT_SQUELCH_LOST) +#define BK4819_REG_02_FSK_RX_SYNC (1U << BK4819_REG_02_SHIFT_FSK_RX_SYNC) // REG 07 -#define BK4819_REG_07_SHIFT_FREQUENCY_MODE 13 -#define BK4819_REG_07_SHIFT_FREQUENCY 0 +#define BK4819_REG_07_SHIFT_FREQUENCY_MODE 13 +#define BK4819_REG_07_SHIFT_FREQUENCY 0 -#define BK4819_REG_07_MASK_FREQUENCY_MODE (0x0007U << BK4819_REG_07_SHIFT_FREQUENCY_MODE) -#define BK4819_REG_07_MASK_FREQUENCY (0x1FFFU << BK4819_REG_07_SHIFT_FREQUENCY) +#define BK4819_REG_07_MASK_FREQUENCY_MODE (0x0007U << BK4819_REG_07_SHIFT_FREQUENCY_MODE) +#define BK4819_REG_07_MASK_FREQUENCY (0x1FFFU << BK4819_REG_07_SHIFT_FREQUENCY) -#define BK4819_REG_07_MODE_CTC1 (0U << BK4819_REG_07_SHIFT_FREQUENCY_MODE) -#define BK4819_REG_07_MODE_CTC2 (1U << BK4819_REG_07_SHIFT_FREQUENCY_MODE) -#define BK4819_REG_07_MODE_CDCSS (2U << BK4819_REG_07_SHIFT_FREQUENCY_MODE) +#define BK4819_REG_07_MODE_CTC1 (0U << BK4819_REG_07_SHIFT_FREQUENCY_MODE) +#define BK4819_REG_07_MODE_CTC2 (1U << BK4819_REG_07_SHIFT_FREQUENCY_MODE) +#define BK4819_REG_07_MODE_CDCSS (2U << BK4819_REG_07_SHIFT_FREQUENCY_MODE) // REG 24 @@ -227,100 +227,100 @@ typedef enum BK4819_GPIO_PIN_t BK4819_GPIO_PIN_t; // REG 30 -#define BK4819_REG_30_SHIFT_ENABLE_VCO_CALIB 15 -#define BK4819_REG_30_SHIFT_ENABLE_UNKNOWN 14 -#define BK4819_REG_30_SHIFT_ENABLE_RX_LINK 10 -#define BK4819_REG_30_SHIFT_ENABLE_AF_DAC 9 -#define BK4819_REG_30_SHIFT_ENABLE_DISC_MODE 8 -#define BK4819_REG_30_SHIFT_ENABLE_PLL_VCO 4 -#define BK4819_REG_30_SHIFT_ENABLE_PA_GAIN 3 -#define BK4819_REG_30_SHIFT_ENABLE_MIC_ADC 2 -#define BK4819_REG_30_SHIFT_ENABLE_TX_DSP 1 -#define BK4819_REG_30_SHIFT_ENABLE_RX_DSP 0 +#define BK4819_REG_30_SHIFT_ENABLE_VCO_CALIB 15 +#define BK4819_REG_30_SHIFT_ENABLE_UNKNOWN 14 +#define BK4819_REG_30_SHIFT_ENABLE_RX_LINK 10 +#define BK4819_REG_30_SHIFT_ENABLE_AF_DAC 9 +#define BK4819_REG_30_SHIFT_ENABLE_DISC_MODE 8 +#define BK4819_REG_30_SHIFT_ENABLE_PLL_VCO 4 +#define BK4819_REG_30_SHIFT_ENABLE_PA_GAIN 3 +#define BK4819_REG_30_SHIFT_ENABLE_MIC_ADC 2 +#define BK4819_REG_30_SHIFT_ENABLE_TX_DSP 1 +#define BK4819_REG_30_SHIFT_ENABLE_RX_DSP 0 -#define BK4819_REG_30_MASK_ENABLE_VCO_CALIB (0x1U << BK4819_REG_30_SHIFT_ENABLE_VCO_CALIB) -#define BK4819_REG_30_MASK_ENABLE_UNKNOWN (0x1U << BK4819_REG_30_SHIFT_ENABLE_UNKNOWN) -#define BK4819_REG_30_MASK_ENABLE_RX_LINK (0xFU << BK4819_REG_30_SHIFT_ENABLE_RX_LINK) -#define BK4819_REG_30_MASK_ENABLE_AF_DAC (0x1U << BK4819_REG_30_SHIFT_ENABLE_AF_DAC) -#define BK4819_REG_30_MASK_ENABLE_DISC_MODE (0x1U << BK4819_REG_30_SHIFT_ENABLE_DISC_MODE) -#define BK4819_REG_30_MASK_ENABLE_PLL_VCO (0xFU << BK4819_REG_30_SHIFT_ENABLE_PLL_VCO) -#define BK4819_REG_30_MASK_ENABLE_PA_GAIN (0x1U << BK4819_REG_30_SHIFT_ENABLE_PA_GAIN) -#define BK4819_REG_30_MASK_ENABLE_MIC_ADC (0x1U << BK4819_REG_30_SHIFT_ENABLE_MIC_ADC) -#define BK4819_REG_30_MASK_ENABLE_TX_DSP (0x1U << BK4819_REG_30_SHIFT_ENABLE_TX_DSP) -#define BK4819_REG_30_MASK_ENABLE_RX_DSP (0x1U << BK4819_REG_30_SHIFT_ENABLE_RX_DSP) +#define BK4819_REG_30_MASK_ENABLE_VCO_CALIB (0x1U << BK4819_REG_30_SHIFT_ENABLE_VCO_CALIB) +#define BK4819_REG_30_MASK_ENABLE_UNKNOWN (0x1U << BK4819_REG_30_SHIFT_ENABLE_UNKNOWN) +#define BK4819_REG_30_MASK_ENABLE_RX_LINK (0xFU << BK4819_REG_30_SHIFT_ENABLE_RX_LINK) +#define BK4819_REG_30_MASK_ENABLE_AF_DAC (0x1U << BK4819_REG_30_SHIFT_ENABLE_AF_DAC) +#define BK4819_REG_30_MASK_ENABLE_DISC_MODE (0x1U << BK4819_REG_30_SHIFT_ENABLE_DISC_MODE) +#define BK4819_REG_30_MASK_ENABLE_PLL_VCO (0xFU << BK4819_REG_30_SHIFT_ENABLE_PLL_VCO) +#define BK4819_REG_30_MASK_ENABLE_PA_GAIN (0x1U << BK4819_REG_30_SHIFT_ENABLE_PA_GAIN) +#define BK4819_REG_30_MASK_ENABLE_MIC_ADC (0x1U << BK4819_REG_30_SHIFT_ENABLE_MIC_ADC) +#define BK4819_REG_30_MASK_ENABLE_TX_DSP (0x1U << BK4819_REG_30_SHIFT_ENABLE_TX_DSP) +#define BK4819_REG_30_MASK_ENABLE_RX_DSP (0x1U << BK4819_REG_30_SHIFT_ENABLE_RX_DSP) enum { - BK4819_REG_30_ENABLE_VCO_CALIB = (0x1U << BK4819_REG_30_SHIFT_ENABLE_VCO_CALIB), - BK4819_REG_30_DISABLE_VCO_CALIB = (0x0U << BK4819_REG_30_SHIFT_ENABLE_VCO_CALIB), - BK4819_REG_30_ENABLE_UNKNOWN = (0x1U << BK4819_REG_30_SHIFT_ENABLE_UNKNOWN), - BK4819_REG_30_DISABLE_UNKNOWN = (0x0U << BK4819_REG_30_SHIFT_ENABLE_UNKNOWN), - BK4819_REG_30_ENABLE_RX_LINK = (0xFU << BK4819_REG_30_SHIFT_ENABLE_RX_LINK), - BK4819_REG_30_DISABLE_RX_LINK = (0x0U << BK4819_REG_30_SHIFT_ENABLE_RX_LINK), - BK4819_REG_30_ENABLE_AF_DAC = (0x1U << BK4819_REG_30_SHIFT_ENABLE_AF_DAC), - BK4819_REG_30_DISABLE_AF_DAC = (0x0U << BK4819_REG_30_SHIFT_ENABLE_AF_DAC), - BK4819_REG_30_ENABLE_DISC_MODE = (0x1U << BK4819_REG_30_SHIFT_ENABLE_DISC_MODE), - BK4819_REG_30_DISABLE_DISC_MODE = (0x0U << BK4819_REG_30_SHIFT_ENABLE_DISC_MODE), - BK4819_REG_30_ENABLE_PLL_VCO = (0xFU << BK4819_REG_30_SHIFT_ENABLE_PLL_VCO), - BK4819_REG_30_DISABLE_PLL_VCO = (0x0U << BK4819_REG_30_SHIFT_ENABLE_PLL_VCO), - BK4819_REG_30_ENABLE_PA_GAIN = (0x1U << BK4819_REG_30_SHIFT_ENABLE_PA_GAIN), - BK4819_REG_30_DISABLE_PA_GAIN = (0x0U << BK4819_REG_30_SHIFT_ENABLE_PA_GAIN), - BK4819_REG_30_ENABLE_MIC_ADC = (0x1U << BK4819_REG_30_SHIFT_ENABLE_MIC_ADC), - BK4819_REG_30_DISABLE_MIC_ADC = (0x0U << BK4819_REG_30_SHIFT_ENABLE_MIC_ADC), - BK4819_REG_30_ENABLE_TX_DSP = (0x1U << BK4819_REG_30_SHIFT_ENABLE_TX_DSP), - BK4819_REG_30_DISABLE_TX_DSP = (0x0U << BK4819_REG_30_SHIFT_ENABLE_TX_DSP), - BK4819_REG_30_ENABLE_RX_DSP = (0x1U << BK4819_REG_30_SHIFT_ENABLE_RX_DSP), - BK4819_REG_30_DISABLE_RX_DSP = (0x0U << BK4819_REG_30_SHIFT_ENABLE_RX_DSP), + BK4819_REG_30_ENABLE_VCO_CALIB = (0x1U << BK4819_REG_30_SHIFT_ENABLE_VCO_CALIB), + BK4819_REG_30_DISABLE_VCO_CALIB = (0x0U << BK4819_REG_30_SHIFT_ENABLE_VCO_CALIB), + BK4819_REG_30_ENABLE_UNKNOWN = (0x1U << BK4819_REG_30_SHIFT_ENABLE_UNKNOWN), + BK4819_REG_30_DISABLE_UNKNOWN = (0x0U << BK4819_REG_30_SHIFT_ENABLE_UNKNOWN), + BK4819_REG_30_ENABLE_RX_LINK = (0xFU << BK4819_REG_30_SHIFT_ENABLE_RX_LINK), + BK4819_REG_30_DISABLE_RX_LINK = (0x0U << BK4819_REG_30_SHIFT_ENABLE_RX_LINK), + BK4819_REG_30_ENABLE_AF_DAC = (0x1U << BK4819_REG_30_SHIFT_ENABLE_AF_DAC), + BK4819_REG_30_DISABLE_AF_DAC = (0x0U << BK4819_REG_30_SHIFT_ENABLE_AF_DAC), + BK4819_REG_30_ENABLE_DISC_MODE = (0x1U << BK4819_REG_30_SHIFT_ENABLE_DISC_MODE), + BK4819_REG_30_DISABLE_DISC_MODE = (0x0U << BK4819_REG_30_SHIFT_ENABLE_DISC_MODE), + BK4819_REG_30_ENABLE_PLL_VCO = (0xFU << BK4819_REG_30_SHIFT_ENABLE_PLL_VCO), + BK4819_REG_30_DISABLE_PLL_VCO = (0x0U << BK4819_REG_30_SHIFT_ENABLE_PLL_VCO), + BK4819_REG_30_ENABLE_PA_GAIN = (0x1U << BK4819_REG_30_SHIFT_ENABLE_PA_GAIN), + BK4819_REG_30_DISABLE_PA_GAIN = (0x0U << BK4819_REG_30_SHIFT_ENABLE_PA_GAIN), + BK4819_REG_30_ENABLE_MIC_ADC = (0x1U << BK4819_REG_30_SHIFT_ENABLE_MIC_ADC), + BK4819_REG_30_DISABLE_MIC_ADC = (0x0U << BK4819_REG_30_SHIFT_ENABLE_MIC_ADC), + BK4819_REG_30_ENABLE_TX_DSP = (0x1U << BK4819_REG_30_SHIFT_ENABLE_TX_DSP), + BK4819_REG_30_DISABLE_TX_DSP = (0x0U << BK4819_REG_30_SHIFT_ENABLE_TX_DSP), + BK4819_REG_30_ENABLE_RX_DSP = (0x1U << BK4819_REG_30_SHIFT_ENABLE_RX_DSP), + BK4819_REG_30_DISABLE_RX_DSP = (0x0U << BK4819_REG_30_SHIFT_ENABLE_RX_DSP), }; // REG 3F -#define BK4819_REG_3F_SHIFT_FSK_TX_FINISHED 15 -#define BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_EMPTY 14 -#define BK4819_REG_3F_SHIFT_FSK_RX_FINISHED 13 -#define BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_FULL 12 -#define BK4819_REG_3F_SHIFT_DTMF_5TONE_FOUND 11 -#define BK4819_REG_3F_SHIFT_CxCSS_TAIL 10 -#define BK4819_REG_3F_SHIFT_CDCSS_FOUND 9 -#define BK4819_REG_3F_SHIFT_CDCSS_LOST 8 -#define BK4819_REG_3F_SHIFT_CTCSS_FOUND 7 -#define BK4819_REG_3F_SHIFT_CTCSS_LOST 6 -#define BK4819_REG_3F_SHIFT_VOX_FOUND 5 -#define BK4819_REG_3F_SHIFT_VOX_LOST 4 -#define BK4819_REG_3F_SHIFT_SQUELCH_FOUND 3 -#define BK4819_REG_3F_SHIFT_SQUELCH_LOST 2 -#define BK4819_REG_3F_SHIFT_FSK_RX_SYNC 1 +#define BK4819_REG_3F_SHIFT_FSK_TX_FINISHED 15 +#define BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_EMPTY 14 +#define BK4819_REG_3F_SHIFT_FSK_RX_FINISHED 13 +#define BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_FULL 12 +#define BK4819_REG_3F_SHIFT_DTMF_5TONE_FOUND 11 +#define BK4819_REG_3F_SHIFT_CxCSS_TAIL 10 +#define BK4819_REG_3F_SHIFT_CDCSS_FOUND 9 +#define BK4819_REG_3F_SHIFT_CDCSS_LOST 8 +#define BK4819_REG_3F_SHIFT_CTCSS_FOUND 7 +#define BK4819_REG_3F_SHIFT_CTCSS_LOST 6 +#define BK4819_REG_3F_SHIFT_VOX_FOUND 5 +#define BK4819_REG_3F_SHIFT_VOX_LOST 4 +#define BK4819_REG_3F_SHIFT_SQUELCH_FOUND 3 +#define BK4819_REG_3F_SHIFT_SQUELCH_LOST 2 +#define BK4819_REG_3F_SHIFT_FSK_RX_SYNC 1 -#define BK4819_REG_3F_MASK_FSK_TX_FINISHED (1U << BK4819_REG_3F_SHIFT_FSK_TX) -#define BK4819_REG_3F_MASK_FSK_FIFO_ALMOST_EMPTY (1U << BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_EMPTY) -#define BK4819_REG_3F_MASK_FSK_RX_FINISHED (1U << BK4819_REG_3F_SHIFT_FSK_RX_FINISHED) -#define BK4819_REG_3F_MASK_FSK_FIFO_ALMOST_FULL (1U << BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_FULL) -#define BK4819_REG_3F_MASK_DTMF_5TONE_FOUND (1U << BK4819_REG_3F_SHIFT_DTMF_5TONE_FOUND) -#define BK4819_REG_3F_MASK_CxCSS_TAIL (1U << BK4819_REG_3F_SHIFT_CxCSS_TAIL) -#define BK4819_REG_3F_MASK_CDCSS_FOUND (1U << BK4819_REG_3F_SHIFT_CDCSS_FOUND) -#define BK4819_REG_3F_MASK_CDCSS_LOST (1U << BK4819_REG_3F_SHIFT_CDCSS_LOST) -#define BK4819_REG_3F_MASK_CTCSS_FOUND (1U << BK4819_REG_3F_SHIFT_CTCSS_FOUND) -#define BK4819_REG_3F_MASK_CTCSS_LOST (1U << BK4819_REG_3F_SHIFT_CTCSS_LOST) -#define BK4819_REG_3F_MASK_VOX_FOUND (1U << BK4819_REG_3F_SHIFT_VOX_FOUND) -#define BK4819_REG_3F_MASK_VOX_LOST (1U << BK4819_REG_3F_SHIFT_VOX_LOST) -#define BK4819_REG_3F_MASK_SQUELCH_FOUND (1U << BK4819_REG_3F_SHIFT_SQUELCH_FOUND) -#define BK4819_REG_3F_MASK_SQUELCH_LOST (1U << BK4819_REG_3F_SHIFT_SQUELCH_LOST) -#define BK4819_REG_3F_MASK_FSK_RX_SYNC (1U << BK4819_REG_3F_SHIFT_FSK_RX_SYNC) +#define BK4819_REG_3F_MASK_FSK_TX_FINISHED (1U << BK4819_REG_3F_SHIFT_FSK_TX) +#define BK4819_REG_3F_MASK_FSK_FIFO_ALMOST_EMPTY (1U << BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_EMPTY) +#define BK4819_REG_3F_MASK_FSK_RX_FINISHED (1U << BK4819_REG_3F_SHIFT_FSK_RX_FINISHED) +#define BK4819_REG_3F_MASK_FSK_FIFO_ALMOST_FULL (1U << BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_FULL) +#define BK4819_REG_3F_MASK_DTMF_5TONE_FOUND (1U << BK4819_REG_3F_SHIFT_DTMF_5TONE_FOUND) +#define BK4819_REG_3F_MASK_CxCSS_TAIL (1U << BK4819_REG_3F_SHIFT_CxCSS_TAIL) +#define BK4819_REG_3F_MASK_CDCSS_FOUND (1U << BK4819_REG_3F_SHIFT_CDCSS_FOUND) +#define BK4819_REG_3F_MASK_CDCSS_LOST (1U << BK4819_REG_3F_SHIFT_CDCSS_LOST) +#define BK4819_REG_3F_MASK_CTCSS_FOUND (1U << BK4819_REG_3F_SHIFT_CTCSS_FOUND) +#define BK4819_REG_3F_MASK_CTCSS_LOST (1U << BK4819_REG_3F_SHIFT_CTCSS_LOST) +#define BK4819_REG_3F_MASK_VOX_FOUND (1U << BK4819_REG_3F_SHIFT_VOX_FOUND) +#define BK4819_REG_3F_MASK_VOX_LOST (1U << BK4819_REG_3F_SHIFT_VOX_LOST) +#define BK4819_REG_3F_MASK_SQUELCH_FOUND (1U << BK4819_REG_3F_SHIFT_SQUELCH_FOUND) +#define BK4819_REG_3F_MASK_SQUELCH_LOST (1U << BK4819_REG_3F_SHIFT_SQUELCH_LOST) +#define BK4819_REG_3F_MASK_FSK_RX_SYNC (1U << BK4819_REG_3F_SHIFT_FSK_RX_SYNC) -#define BK4819_REG_3F_FSK_TX_FINISHED (1U << BK4819_REG_3F_SHIFT_FSK_TX_FINISHED) -#define BK4819_REG_3F_FSK_FIFO_ALMOST_EMPTY (1U << BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_EMPTY) -#define BK4819_REG_3F_FSK_RX_FINISHED (1U << BK4819_REG_3F_SHIFT_FSK_RX_FINISHED) -#define BK4819_REG_3F_FSK_FIFO_ALMOST_FULL (1U << BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_FULL) -#define BK4819_REG_3F_DTMF_5TONE_FOUND (1U << BK4819_REG_3F_SHIFT_DTMF_5TONE_FOUND) -#define BK4819_REG_3F_CxCSS_TAIL (1U << BK4819_REG_3F_SHIFT_CxCSS_TAIL) -#define BK4819_REG_3F_CDCSS_FOUND (1U << BK4819_REG_3F_SHIFT_CDCSS_FOUND) -#define BK4819_REG_3F_CDCSS_LOST (1U << BK4819_REG_3F_SHIFT_CDCSS_LOST) -#define BK4819_REG_3F_CTCSS_FOUND (1U << BK4819_REG_3F_SHIFT_CTCSS_FOUND) -#define BK4819_REG_3F_CTCSS_LOST (1U << BK4819_REG_3F_SHIFT_CTCSS_LOST) -#define BK4819_REG_3F_VOX_FOUND (1U << BK4819_REG_3F_SHIFT_VOX_FOUND) -#define BK4819_REG_3F_VOX_LOST (1U << BK4819_REG_3F_SHIFT_VOX_LOST) -#define BK4819_REG_3F_SQUELCH_FOUND (1U << BK4819_REG_3F_SHIFT_SQUELCH_FOUND) -#define BK4819_REG_3F_SQUELCH_LOST (1U << BK4819_REG_3F_SHIFT_SQUELCH_LOST) -#define BK4819_REG_3F_FSK_RX_SYNC (1U << BK4819_REG_3F_SHIFT_FSK_RX_SYNC) +#define BK4819_REG_3F_FSK_TX_FINISHED (1U << BK4819_REG_3F_SHIFT_FSK_TX_FINISHED) +#define BK4819_REG_3F_FSK_FIFO_ALMOST_EMPTY (1U << BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_EMPTY) +#define BK4819_REG_3F_FSK_RX_FINISHED (1U << BK4819_REG_3F_SHIFT_FSK_RX_FINISHED) +#define BK4819_REG_3F_FSK_FIFO_ALMOST_FULL (1U << BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_FULL) +#define BK4819_REG_3F_DTMF_5TONE_FOUND (1U << BK4819_REG_3F_SHIFT_DTMF_5TONE_FOUND) +#define BK4819_REG_3F_CxCSS_TAIL (1U << BK4819_REG_3F_SHIFT_CxCSS_TAIL) +#define BK4819_REG_3F_CDCSS_FOUND (1U << BK4819_REG_3F_SHIFT_CDCSS_FOUND) +#define BK4819_REG_3F_CDCSS_LOST (1U << BK4819_REG_3F_SHIFT_CDCSS_LOST) +#define BK4819_REG_3F_CTCSS_FOUND (1U << BK4819_REG_3F_SHIFT_CTCSS_FOUND) +#define BK4819_REG_3F_CTCSS_LOST (1U << BK4819_REG_3F_SHIFT_CTCSS_LOST) +#define BK4819_REG_3F_VOX_FOUND (1U << BK4819_REG_3F_SHIFT_VOX_FOUND) +#define BK4819_REG_3F_VOX_LOST (1U << BK4819_REG_3F_SHIFT_VOX_LOST) +#define BK4819_REG_3F_SQUELCH_FOUND (1U << BK4819_REG_3F_SHIFT_SQUELCH_FOUND) +#define BK4819_REG_3F_SQUELCH_LOST (1U << BK4819_REG_3F_SHIFT_SQUELCH_LOST) +#define BK4819_REG_3F_FSK_RX_SYNC (1U << BK4819_REG_3F_SHIFT_FSK_RX_SYNC) // REG 51 @@ -345,46 +345,46 @@ enum { #define BK4819_REG_51_MASK_CxCSS_TX_GAIN1 (0x7FU << BK4819_REG_51_SHIFT_CxCSS_TX_GAIN1) enum { - BK4819_REG_51_ENABLE_CxCSS = (1U << BK4819_REG_51_SHIFT_ENABLE_CxCSS), - BK4819_REG_51_DISABLE_CxCSS = (0U << BK4819_REG_51_SHIFT_ENABLE_CxCSS), + BK4819_REG_51_ENABLE_CxCSS = (1U << BK4819_REG_51_SHIFT_ENABLE_CxCSS), + BK4819_REG_51_DISABLE_CxCSS = (0U << BK4819_REG_51_SHIFT_ENABLE_CxCSS), - BK4819_REG_51_GPIO6_PIN2_INPUT = (1U << BK4819_REG_51_SHIFT_GPIO6_PIN2_INPUT), - BK4819_REG_51_GPIO6_PIN2_NORMAL = (0U << BK4819_REG_51_SHIFT_GPIO6_PIN2_INPUT), + BK4819_REG_51_GPIO6_PIN2_INPUT = (1U << BK4819_REG_51_SHIFT_GPIO6_PIN2_INPUT), + BK4819_REG_51_GPIO6_PIN2_NORMAL = (0U << BK4819_REG_51_SHIFT_GPIO6_PIN2_INPUT), - BK4819_REG_51_TX_CDCSS_NEGATIVE = (1U << BK4819_REG_51_SHIFT_TX_CDCSS_POLARITY), - BK4819_REG_51_TX_CDCSS_POSITIVE = (0U << BK4819_REG_51_SHIFT_TX_CDCSS_POLARITY), + BK4819_REG_51_TX_CDCSS_NEGATIVE = (1U << BK4819_REG_51_SHIFT_TX_CDCSS_POLARITY), + BK4819_REG_51_TX_CDCSS_POSITIVE = (0U << BK4819_REG_51_SHIFT_TX_CDCSS_POLARITY), - BK4819_REG_51_MODE_CTCSS = (1U << BK4819_REG_51_SHIFT_CxCSS_MODE), - BK4819_REG_51_MODE_CDCSS = (0U << BK4819_REG_51_SHIFT_CxCSS_MODE), + BK4819_REG_51_MODE_CTCSS = (1U << BK4819_REG_51_SHIFT_CxCSS_MODE), + BK4819_REG_51_MODE_CDCSS = (0U << BK4819_REG_51_SHIFT_CxCSS_MODE), - BK4819_REG_51_CDCSS_24_BIT = (1U << BK4819_REG_51_SHIFT_CDCSS_BIT_WIDTH), - BK4819_REG_51_CDCSS_23_BIT = (0U << BK4819_REG_51_SHIFT_CDCSS_BIT_WIDTH), + BK4819_REG_51_CDCSS_24_BIT = (1U << BK4819_REG_51_SHIFT_CDCSS_BIT_WIDTH), + BK4819_REG_51_CDCSS_23_BIT = (0U << BK4819_REG_51_SHIFT_CDCSS_BIT_WIDTH), - BK4819_REG_51_1050HZ_DETECTION = (1U << BK4819_REG_51_SHIFT_1050HZ_DETECTION), - BK4819_REG_51_1050HZ_NO_DETECTION = (0U << BK4819_REG_51_SHIFT_1050HZ_DETECTION), + BK4819_REG_51_1050HZ_DETECTION = (1U << BK4819_REG_51_SHIFT_1050HZ_DETECTION), + BK4819_REG_51_1050HZ_NO_DETECTION = (0U << BK4819_REG_51_SHIFT_1050HZ_DETECTION), - BK4819_REG_51_AUTO_CDCSS_BW_DISABLE = (1U << BK4819_REG_51_SHIFT_AUTO_CDCSS_BW), - BK4819_REG_51_AUTO_CDCSS_BW_ENABLE = (0U << BK4819_REG_51_SHIFT_AUTO_CDCSS_BW), + BK4819_REG_51_AUTO_CDCSS_BW_DISABLE = (1U << BK4819_REG_51_SHIFT_AUTO_CDCSS_BW), + BK4819_REG_51_AUTO_CDCSS_BW_ENABLE = (0U << BK4819_REG_51_SHIFT_AUTO_CDCSS_BW), - BK4819_REG_51_AUTO_CTCSS_BW_DISABLE = (1U << BK4819_REG_51_SHIFT_AUTO_CTCSS_BW), - BK4819_REG_51_AUTO_CTCSS_BW_ENABLE = (0U << BK4819_REG_51_SHIFT_AUTO_CTCSS_BW), + BK4819_REG_51_AUTO_CTCSS_BW_DISABLE = (1U << BK4819_REG_51_SHIFT_AUTO_CTCSS_BW), + BK4819_REG_51_AUTO_CTCSS_BW_ENABLE = (0U << BK4819_REG_51_SHIFT_AUTO_CTCSS_BW), }; // REG 70 -#define BK4819_REG_70_SHIFT_ENABLE_TONE1 15 -#define BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN 8 -#define BK4819_REG_70_SHIFT_ENABLE_TONE2 7 -#define BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN 0 +#define BK4819_REG_70_SHIFT_ENABLE_TONE1 15 +#define BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN 8 +#define BK4819_REG_70_SHIFT_ENABLE_TONE2 7 +#define BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN 0 -#define BK4819_REG_70_MASK_ENABLE_TONE1 (0x01U << BK4819_REG_70_SHIFT_ENABLE_TONE1) -#define BK4819_REG_70_MASK_TONE1_TUNING_GAIN (0x7FU << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) -#define BK4819_REG_70_MASK_ENABLE_TONE2 (0x01U << BK4819_REG_70_SHIFT_ENABLE_TONE2) -#define BK4819_REG_70_MASK_TONE2_TUNING_GAIN (0x7FU << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN) +#define BK4819_REG_70_MASK_ENABLE_TONE1 (0x01U << BK4819_REG_70_SHIFT_ENABLE_TONE1) +#define BK4819_REG_70_MASK_TONE1_TUNING_GAIN (0x7FU << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) +#define BK4819_REG_70_MASK_ENABLE_TONE2 (0x01U << BK4819_REG_70_SHIFT_ENABLE_TONE2) +#define BK4819_REG_70_MASK_TONE2_TUNING_GAIN (0x7FU << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN) enum { - BK4819_REG_70_ENABLE_TONE1 = (1U << BK4819_REG_70_SHIFT_ENABLE_TONE1), - BK4819_REG_70_ENABLE_TONE2 = (1U << BK4819_REG_70_SHIFT_ENABLE_TONE2), + BK4819_REG_70_ENABLE_TONE1 = (1U << BK4819_REG_70_SHIFT_ENABLE_TONE1), + BK4819_REG_70_ENABLE_TONE2 = (1U << BK4819_REG_70_SHIFT_ENABLE_TONE2), }; #endif diff --git a/driver/bk4819.c b/driver/bk4819.c index d6390a1..8501939 100644 --- a/driver/bk4819.c +++ b/driver/bk4819.c @@ -30,7 +30,7 @@ #ifndef ARRAY_SIZE - #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif static const uint16_t FSK_RogerTable[7] = {0xF1A2, 0x7446, 0x61A4, 0x6544, 0x4E8A, 0xE044, 0xEA84}; @@ -44,743 +44,743 @@ bool gRxIdleMode; __inline uint16_t scale_freq(const uint16_t freq) { -// return (((uint32_t)freq * 1032444u) + 50000u) / 100000u; // with rounding - return (((uint32_t)freq * 1353245u) + (1u << 16)) >> 17; // with rounding +// return (((uint32_t)freq * 1032444u) + 50000u) / 100000u; // with rounding + return (((uint32_t)freq * 1353245u) + (1u << 16)) >> 17; // with rounding } void BK4819_Init(void) { - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); - BK4819_WriteRegister(BK4819_REG_00, 0x8000); - BK4819_WriteRegister(BK4819_REG_00, 0x0000); + BK4819_WriteRegister(BK4819_REG_00, 0x8000); + BK4819_WriteRegister(BK4819_REG_00, 0x0000); - BK4819_WriteRegister(BK4819_REG_37, 0x1D0F); - BK4819_WriteRegister(BK4819_REG_36, 0x0022); + BK4819_WriteRegister(BK4819_REG_37, 0x1D0F); + BK4819_WriteRegister(BK4819_REG_36, 0x0022); - BK4819_InitAGC(false); - BK4819_SetAGC(true); + BK4819_InitAGC(false); + BK4819_SetAGC(true); - BK4819_WriteRegister(BK4819_REG_19, 0b0001000001000001); // <15> MIC AGC 1 = disable 0 = enable + BK4819_WriteRegister(BK4819_REG_19, 0b0001000001000001); // <15> MIC AGC 1 = disable 0 = enable - BK4819_WriteRegister(BK4819_REG_7D, 0xE940); + BK4819_WriteRegister(BK4819_REG_7D, 0xE940); - // REG_48 .. RX AF level - // - // <15:12> 11 ??? 0 to 15 - // - // <11:10> 0 AF Rx Gain-1 - // 0 = 0dB - // 1 = -6dB - // 2 = -12dB - // 3 = -18dB - // - // <9:4> 60 AF Rx Gain-2 -26dB ~ 5.5dB 0.5dB/step - // 63 = max - // 0 = mute - // - // <3:0> 15 AF DAC Gain (after Gain-1 and Gain-2) approx 2dB/step - // 15 = max - // 0 = min - // - BK4819_WriteRegister(BK4819_REG_48, // 0xB3A8); // 1011 00 111010 1000 - (11u << 12) | // ??? 0..15 - ( 0u << 10) | // AF Rx Gain-1 - (58u << 4) | // AF Rx Gain-2 - ( 8u << 0)); // AF DAC Gain (after Gain-1 and Gain-2) + // REG_48 .. RX AF level + // + // <15:12> 11 ??? 0 to 15 + // + // <11:10> 0 AF Rx Gain-1 + // 0 = 0dB + // 1 = -6dB + // 2 = -12dB + // 3 = -18dB + // + // <9:4> 60 AF Rx Gain-2 -26dB ~ 5.5dB 0.5dB/step + // 63 = max + // 0 = mute + // + // <3:0> 15 AF DAC Gain (after Gain-1 and Gain-2) approx 2dB/step + // 15 = max + // 0 = min + // + BK4819_WriteRegister(BK4819_REG_48, // 0xB3A8); // 1011 00 111010 1000 + (11u << 12) | // ??? 0..15 + ( 0u << 10) | // AF Rx Gain-1 + (58u << 4) | // AF Rx Gain-2 + ( 8u << 0)); // AF DAC Gain (after Gain-1 and Gain-2) #if 1 - const uint8_t dtmf_coeffs[] = {111, 107, 103, 98, 80, 71, 58, 44, 65, 55, 37, 23, 228, 203, 181, 159}; - for (unsigned int i = 0; i < ARRAY_SIZE(dtmf_coeffs); i++) - BK4819_WriteRegister(BK4819_REG_09, (i << 12) | dtmf_coeffs[i]); + const uint8_t dtmf_coeffs[] = {111, 107, 103, 98, 80, 71, 58, 44, 65, 55, 37, 23, 228, 203, 181, 159}; + for (unsigned int i = 0; i < ARRAY_SIZE(dtmf_coeffs); i++) + BK4819_WriteRegister(BK4819_REG_09, (i << 12) | dtmf_coeffs[i]); #else - // original code - BK4819_WriteRegister(BK4819_REG_09, 0x006F); // 6F - BK4819_WriteRegister(BK4819_REG_09, 0x106B); // 6B - BK4819_WriteRegister(BK4819_REG_09, 0x2067); // 67 - BK4819_WriteRegister(BK4819_REG_09, 0x3062); // 62 - BK4819_WriteRegister(BK4819_REG_09, 0x4050); // 50 - BK4819_WriteRegister(BK4819_REG_09, 0x5047); // 47 - BK4819_WriteRegister(BK4819_REG_09, 0x603A); // 3A - BK4819_WriteRegister(BK4819_REG_09, 0x702C); // 2C - BK4819_WriteRegister(BK4819_REG_09, 0x8041); // 41 - BK4819_WriteRegister(BK4819_REG_09, 0x9037); // 37 - BK4819_WriteRegister(BK4819_REG_09, 0xA025); // 25 - BK4819_WriteRegister(BK4819_REG_09, 0xB017); // 17 - BK4819_WriteRegister(BK4819_REG_09, 0xC0E4); // E4 - BK4819_WriteRegister(BK4819_REG_09, 0xD0CB); // CB - BK4819_WriteRegister(BK4819_REG_09, 0xE0B5); // B5 - BK4819_WriteRegister(BK4819_REG_09, 0xF09F); // 9F + // original code + BK4819_WriteRegister(BK4819_REG_09, 0x006F); // 6F + BK4819_WriteRegister(BK4819_REG_09, 0x106B); // 6B + BK4819_WriteRegister(BK4819_REG_09, 0x2067); // 67 + BK4819_WriteRegister(BK4819_REG_09, 0x3062); // 62 + BK4819_WriteRegister(BK4819_REG_09, 0x4050); // 50 + BK4819_WriteRegister(BK4819_REG_09, 0x5047); // 47 + BK4819_WriteRegister(BK4819_REG_09, 0x603A); // 3A + BK4819_WriteRegister(BK4819_REG_09, 0x702C); // 2C + BK4819_WriteRegister(BK4819_REG_09, 0x8041); // 41 + BK4819_WriteRegister(BK4819_REG_09, 0x9037); // 37 + BK4819_WriteRegister(BK4819_REG_09, 0xA025); // 25 + BK4819_WriteRegister(BK4819_REG_09, 0xB017); // 17 + BK4819_WriteRegister(BK4819_REG_09, 0xC0E4); // E4 + BK4819_WriteRegister(BK4819_REG_09, 0xD0CB); // CB + BK4819_WriteRegister(BK4819_REG_09, 0xE0B5); // B5 + BK4819_WriteRegister(BK4819_REG_09, 0xF09F); // 9F #endif - BK4819_WriteRegister(BK4819_REG_1F, 0x5454); - BK4819_WriteRegister(BK4819_REG_3E, 0xA037); + BK4819_WriteRegister(BK4819_REG_1F, 0x5454); + BK4819_WriteRegister(BK4819_REG_3E, 0xA037); - gBK4819_GpioOutState = 0x9000; + gBK4819_GpioOutState = 0x9000; - BK4819_WriteRegister(BK4819_REG_33, 0x9000); - BK4819_WriteRegister(BK4819_REG_3F, 0); + BK4819_WriteRegister(BK4819_REG_33, 0x9000); + BK4819_WriteRegister(BK4819_REG_3F, 0); } static uint16_t BK4819_ReadU16(void) { - unsigned int i; - uint16_t Value; + unsigned int i; + uint16_t Value; - PORTCON_PORTC_IE = (PORTCON_PORTC_IE & ~PORTCON_PORTC_IE_C2_MASK) | PORTCON_PORTC_IE_C2_BITS_ENABLE; - GPIOC->DIR = (GPIOC->DIR & ~GPIO_DIR_2_MASK) | GPIO_DIR_2_BITS_INPUT; - SYSTICK_DelayUs(1); - Value = 0; - for (i = 0; i < 16; i++) - { - Value <<= 1; - Value |= GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); - SYSTICK_DelayUs(1); - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); - SYSTICK_DelayUs(1); - } - PORTCON_PORTC_IE = (PORTCON_PORTC_IE & ~PORTCON_PORTC_IE_C2_MASK) | PORTCON_PORTC_IE_C2_BITS_DISABLE; - GPIOC->DIR = (GPIOC->DIR & ~GPIO_DIR_2_MASK) | GPIO_DIR_2_BITS_OUTPUT; + PORTCON_PORTC_IE = (PORTCON_PORTC_IE & ~PORTCON_PORTC_IE_C2_MASK) | PORTCON_PORTC_IE_C2_BITS_ENABLE; + GPIOC->DIR = (GPIOC->DIR & ~GPIO_DIR_2_MASK) | GPIO_DIR_2_BITS_INPUT; + SYSTICK_DelayUs(1); + Value = 0; + for (i = 0; i < 16; i++) + { + Value <<= 1; + Value |= GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); + SYSTICK_DelayUs(1); + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); + SYSTICK_DelayUs(1); + } + PORTCON_PORTC_IE = (PORTCON_PORTC_IE & ~PORTCON_PORTC_IE_C2_MASK) | PORTCON_PORTC_IE_C2_BITS_DISABLE; + GPIOC->DIR = (GPIOC->DIR & ~GPIO_DIR_2_MASK) | GPIO_DIR_2_BITS_OUTPUT; - return Value; + return Value; } uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register) { - uint16_t Value; + uint16_t Value; - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); - SYSTICK_DelayUs(1); + SYSTICK_DelayUs(1); - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); - BK4819_WriteU8(Register | 0x80); - Value = BK4819_ReadU16(); - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); + BK4819_WriteU8(Register | 0x80); + Value = BK4819_ReadU16(); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); - SYSTICK_DelayUs(1); + SYSTICK_DelayUs(1); - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); - return Value; + return Value; } void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data) { - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); - SYSTICK_DelayUs(1); + SYSTICK_DelayUs(1); - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); - BK4819_WriteU8(Register); + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); + BK4819_WriteU8(Register); - SYSTICK_DelayUs(1); + SYSTICK_DelayUs(1); - BK4819_WriteU16(Data); + BK4819_WriteU16(Data); - SYSTICK_DelayUs(1); + SYSTICK_DelayUs(1); - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN); - SYSTICK_DelayUs(1); + SYSTICK_DelayUs(1); - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); } void BK4819_WriteU8(uint8_t Data) { - unsigned int i; + unsigned int i; - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); - for (i = 0; i < 8; i++) - { - if ((Data & 0x80) == 0) - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); - else - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); + for (i = 0; i < 8; i++) + { + if ((Data & 0x80) == 0) + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); + else + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); - SYSTICK_DelayUs(1); - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); - SYSTICK_DelayUs(1); + SYSTICK_DelayUs(1); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); + SYSTICK_DelayUs(1); - Data <<= 1; + Data <<= 1; - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); - SYSTICK_DelayUs(1); - } + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); + SYSTICK_DelayUs(1); + } } void BK4819_WriteU16(uint16_t Data) { - unsigned int i; + unsigned int i; - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); - for (i = 0; i < 16; i++) - { - if ((Data & 0x8000) == 0) - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); - else - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); + for (i = 0; i < 16; i++) + { + if ((Data & 0x8000) == 0) + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); + else + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA); - SYSTICK_DelayUs(1); - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); + SYSTICK_DelayUs(1); + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); - Data <<= 1; + Data <<= 1; - SYSTICK_DelayUs(1); - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); - SYSTICK_DelayUs(1); - } + SYSTICK_DelayUs(1); + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL); + SYSTICK_DelayUs(1); + } } void BK4819_SetAGC(bool enable) { - uint16_t regVal = BK4819_ReadRegister(BK4819_REG_7E); - if(!(regVal & (1 << 15)) == enable) - return; + uint16_t regVal = BK4819_ReadRegister(BK4819_REG_7E); + if(!(regVal & (1 << 15)) == enable) + return; - BK4819_WriteRegister(BK4819_REG_7E, (regVal & ~(1 << 15) & ~(0b111 << 12)) - | (!enable << 15) // 0 AGC fix mode - | (3u << 12) // 3 AGC fix index - ); + BK4819_WriteRegister(BK4819_REG_7E, (regVal & ~(1 << 15) & ~(0b111 << 12)) + | (!enable << 15) // 0 AGC fix mode + | (3u << 12) // 3 AGC fix index + ); - // if(enable) { - // BK4819_WriteRegister(BK4819_REG_7B, 0x8420); - // } - // else { - // BK4819_WriteRegister(BK4819_REG_7B, 0x318C); + // if(enable) { + // BK4819_WriteRegister(BK4819_REG_7B, 0x8420); + // } + // else { + // BK4819_WriteRegister(BK4819_REG_7B, 0x318C); - // BK4819_WriteRegister(BK4819_REG_7C, 0x595E); - // BK4819_WriteRegister(BK4819_REG_20, 0x8DEF); + // BK4819_WriteRegister(BK4819_REG_7C, 0x595E); + // BK4819_WriteRegister(BK4819_REG_20, 0x8DEF); - // for (uint8_t i = 0; i < 8; i++) { - // //BK4819_WriteRegister(BK4819_REG_06, ((i << 13) | 0x2500u) + 0x036u); - // BK4819_WriteRegister(BK4819_REG_06, (i & 7) << 13 | 0x4A << 7 | 0x36); - // } - // } + // for (uint8_t i = 0; i < 8; i++) { + // //BK4819_WriteRegister(BK4819_REG_06, ((i << 13) | 0x2500u) + 0x036u); + // BK4819_WriteRegister(BK4819_REG_06, (i & 7) << 13 | 0x4A << 7 | 0x36); + // } + // } } void BK4819_InitAGC(bool amModulation) { - // REG_10, REG_11, REG_12 REG_13, REG_14 - // - // Rx AGC Gain Table[]. (Index Max->Min is 3,2,1,0,-1) - // - // <15:10> ??? - // - // <9:8> LNA Gain Short - // 3 = 0dB <<< 1o11 read from spectrum reference manual - // 2 = -24dB -19 -11 - // 1 = -30dB -24 -16 - // 0 = -33dB -28 -19 - // - // <7:5> LNA Gain - // 7 = 0dB - // 6 = -2dB - // 5 = -4dB - // 4 = -6dB - // 3 = -9dB - // 2 = -14dB <<< - // 1 = -19dB - // 0 = -24dB - // - // <4:3> MIXER Gain - // 3 = 0dB <<< - // 2 = -3dB - // 1 = -6dB - // 0 = -8dB - // - // <2:0> PGA Gain - // 7 = 0dB - // 6 = -3dB <<< - // 5 = -6dB - // 4 = -9dB - // 3 = -15dB - // 2 = -21dB - // 1 = -27dB - // 0 = -33dB - // + // REG_10, REG_11, REG_12 REG_13, REG_14 + // + // Rx AGC Gain Table[]. (Index Max->Min is 3,2,1,0,-1) + // + // <15:10> ??? + // + // <9:8> LNA Gain Short + // 3 = 0dB <<< 1o11 read from spectrum reference manual + // 2 = -24dB -19 -11 + // 1 = -30dB -24 -16 + // 0 = -33dB -28 -19 + // + // <7:5> LNA Gain + // 7 = 0dB + // 6 = -2dB + // 5 = -4dB + // 4 = -6dB + // 3 = -9dB + // 2 = -14dB <<< + // 1 = -19dB + // 0 = -24dB + // + // <4:3> MIXER Gain + // 3 = 0dB <<< + // 2 = -3dB + // 1 = -6dB + // 0 = -8dB + // + // <2:0> PGA Gain + // 7 = 0dB + // 6 = -3dB <<< + // 5 = -6dB + // 4 = -9dB + // 3 = -15dB + // 2 = -21dB + // 1 = -27dB + // 0 = -33dB + // - BK4819_WriteRegister(BK4819_REG_13, 0x03BE); // 0x03BE / 000000 11 101 11 110 / -7dB - BK4819_WriteRegister(BK4819_REG_12, 0x037B); // 0x037B / 000000 11 011 11 011 / -24dB - BK4819_WriteRegister(BK4819_REG_11, 0x027B); // 0x027B / 000000 10 011 11 011 / -43dB - BK4819_WriteRegister(BK4819_REG_10, 0x007A); // 0x007A / 000000 00 011 11 010 / -58dB - if(amModulation) { - BK4819_WriteRegister(BK4819_REG_14, 0x0000); - BK4819_WriteRegister(BK4819_REG_49, (0 << 14) | (50 << 7) | (32 << 0)); - } - else{ - BK4819_WriteRegister(BK4819_REG_14, 0x0019); // 0x0019 / 000000 00 000 11 001 / -79dB - BK4819_WriteRegister(BK4819_REG_49, (0 << 14) | (84 << 7) | (56 << 0)); //0x2A38 / 00 1010100 0111000 / 84, 56 - } + BK4819_WriteRegister(BK4819_REG_13, 0x03BE); // 0x03BE / 000000 11 101 11 110 / -7dB + BK4819_WriteRegister(BK4819_REG_12, 0x037B); // 0x037B / 000000 11 011 11 011 / -24dB + BK4819_WriteRegister(BK4819_REG_11, 0x027B); // 0x027B / 000000 10 011 11 011 / -43dB + BK4819_WriteRegister(BK4819_REG_10, 0x007A); // 0x007A / 000000 00 011 11 010 / -58dB + if(amModulation) { + BK4819_WriteRegister(BK4819_REG_14, 0x0000); + BK4819_WriteRegister(BK4819_REG_49, (0 << 14) | (50 << 7) | (32 << 0)); + } + else{ + BK4819_WriteRegister(BK4819_REG_14, 0x0019); // 0x0019 / 000000 00 000 11 001 / -79dB + BK4819_WriteRegister(BK4819_REG_49, (0 << 14) | (84 << 7) | (56 << 0)); //0x2A38 / 00 1010100 0111000 / 84, 56 + } - BK4819_WriteRegister(BK4819_REG_7B, 0x8420); + BK4819_WriteRegister(BK4819_REG_7B, 0x8420); } int8_t BK4819_GetRxGain_dB(void) { - union { - struct { - uint16_t pga:3; - uint16_t mixer:2; - uint16_t lna:3; - uint16_t lnaS:2; - }; - uint16_t __raw; - } agcGainReg; + union { + struct { + uint16_t pga:3; + uint16_t mixer:2; + uint16_t lna:3; + uint16_t lnaS:2; + }; + uint16_t __raw; + } agcGainReg; - union { - struct { - uint16_t _ : 5; - uint16_t agcSigStrength : 7; - int16_t gainIdx : 3; - uint16_t agcEnab : 1; - }; - uint16_t __raw; - } reg7e; + union { + struct { + uint16_t _ : 5; + uint16_t agcSigStrength : 7; + int16_t gainIdx : 3; + uint16_t agcEnab : 1; + }; + uint16_t __raw; + } reg7e; - reg7e.__raw = BK4819_ReadRegister(BK4819_REG_7E); - uint8_t gainAddr = reg7e.gainIdx < 0 ? BK4819_REG_14 : BK4819_REG_10 + reg7e.gainIdx; - agcGainReg.__raw = BK4819_ReadRegister(gainAddr); - int8_t lnaShortTab[] = {-28, -24, -19, 0}; - int8_t lnaTab[] = {-24, -19, -14, -9, -6, -4, -2, 0}; - int8_t mixerTab[] = {-8, -6, -3, 0}; - int8_t pgaTab[] = {-33, -27, -21, -15, -9, -6, -3, 0}; - return lnaShortTab[agcGainReg.lnaS] + lnaTab[agcGainReg.lna] + mixerTab[agcGainReg.mixer] + pgaTab[agcGainReg.pga]; + reg7e.__raw = BK4819_ReadRegister(BK4819_REG_7E); + uint8_t gainAddr = reg7e.gainIdx < 0 ? BK4819_REG_14 : BK4819_REG_10 + reg7e.gainIdx; + agcGainReg.__raw = BK4819_ReadRegister(gainAddr); + int8_t lnaShortTab[] = {-28, -24, -19, 0}; + int8_t lnaTab[] = {-24, -19, -14, -9, -6, -4, -2, 0}; + int8_t mixerTab[] = {-8, -6, -3, 0}; + int8_t pgaTab[] = {-33, -27, -21, -15, -9, -6, -3, 0}; + return lnaShortTab[agcGainReg.lnaS] + lnaTab[agcGainReg.lna] + mixerTab[agcGainReg.mixer] + pgaTab[agcGainReg.pga]; } int16_t BK4819_GetRSSI_dBm(void) { - uint16_t rssi = BK4819_GetRSSI(); - return (rssi / 2) - 160;// - BK4819_GetRxGain_dB(); + uint16_t rssi = BK4819_GetRSSI(); + return (rssi / 2) - 160;// - BK4819_GetRxGain_dB(); } void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet) { - if (bSet) - gBK4819_GpioOutState |= (0x40u >> Pin); - else - gBK4819_GpioOutState &= ~(0x40u >> Pin); + if (bSet) + gBK4819_GpioOutState |= (0x40u >> Pin); + else + gBK4819_GpioOutState &= ~(0x40u >> Pin); - BK4819_WriteRegister(BK4819_REG_33, gBK4819_GpioOutState); + BK4819_WriteRegister(BK4819_REG_33, gBK4819_GpioOutState); } void BK4819_SetCDCSSCodeWord(uint32_t CodeWord) { - // REG_51 - // - // <15> 0 - // 1 = Enable TxCTCSS/CDCSS - // 0 = Disable - // - // <14> 0 - // 1 = GPIO0Input for CDCSS - // 0 = Normal Mode (for BK4819 v3) - // - // <13> 0 - // 1 = Transmit negative CDCSS code - // 0 = Transmit positive CDCSS code - // - // <12> 0 CTCSS/CDCSS mode selection - // 1 = CTCSS - // 0 = CDCSS - // - // <11> 0 CDCSS 24/23bit selection - // 1 = 24bit - // 0 = 23bit - // - // <10> 0 1050HzDetectionMode - // 1 = 1050/4 Detect Enable, CTC1 should be set to 1050/4 Hz - // - // <9> 0 Auto CDCSS Bw Mode - // 1 = Disable - // 0 = Enable - // - // <8> 0 Auto CTCSS Bw Mode - // 0 = Enable - // 1 = Disable - // - // <6:0> 0 CTCSS/CDCSS Tx Gain1 Tuning - // 0 = min - // 127 = max + // REG_51 + // + // <15> 0 + // 1 = Enable TxCTCSS/CDCSS + // 0 = Disable + // + // <14> 0 + // 1 = GPIO0Input for CDCSS + // 0 = Normal Mode (for BK4819 v3) + // + // <13> 0 + // 1 = Transmit negative CDCSS code + // 0 = Transmit positive CDCSS code + // + // <12> 0 CTCSS/CDCSS mode selection + // 1 = CTCSS + // 0 = CDCSS + // + // <11> 0 CDCSS 24/23bit selection + // 1 = 24bit + // 0 = 23bit + // + // <10> 0 1050HzDetectionMode + // 1 = 1050/4 Detect Enable, CTC1 should be set to 1050/4 Hz + // + // <9> 0 Auto CDCSS Bw Mode + // 1 = Disable + // 0 = Enable + // + // <8> 0 Auto CTCSS Bw Mode + // 0 = Enable + // 1 = Disable + // + // <6:0> 0 CTCSS/CDCSS Tx Gain1 Tuning + // 0 = min + // 127 = max - // Enable CDCSS - // Transmit positive CDCSS code - // CDCSS Mode - // CDCSS 23bit - // Enable Auto CDCSS Bw Mode - // Enable Auto CTCSS Bw Mode - // CTCSS/CDCSS Tx Gain1 Tuning = 51 - // - BK4819_WriteRegister(BK4819_REG_51, - BK4819_REG_51_ENABLE_CxCSS | - BK4819_REG_51_GPIO6_PIN2_NORMAL | - BK4819_REG_51_TX_CDCSS_POSITIVE | - BK4819_REG_51_MODE_CDCSS | - BK4819_REG_51_CDCSS_23_BIT | - BK4819_REG_51_1050HZ_NO_DETECTION | - BK4819_REG_51_AUTO_CDCSS_BW_ENABLE | - BK4819_REG_51_AUTO_CTCSS_BW_ENABLE | - (51u << BK4819_REG_51_SHIFT_CxCSS_TX_GAIN1)); + // Enable CDCSS + // Transmit positive CDCSS code + // CDCSS Mode + // CDCSS 23bit + // Enable Auto CDCSS Bw Mode + // Enable Auto CTCSS Bw Mode + // CTCSS/CDCSS Tx Gain1 Tuning = 51 + // + BK4819_WriteRegister(BK4819_REG_51, + BK4819_REG_51_ENABLE_CxCSS | + BK4819_REG_51_GPIO6_PIN2_NORMAL | + BK4819_REG_51_TX_CDCSS_POSITIVE | + BK4819_REG_51_MODE_CDCSS | + BK4819_REG_51_CDCSS_23_BIT | + BK4819_REG_51_1050HZ_NO_DETECTION | + BK4819_REG_51_AUTO_CDCSS_BW_ENABLE | + BK4819_REG_51_AUTO_CTCSS_BW_ENABLE | + (51u << BK4819_REG_51_SHIFT_CxCSS_TX_GAIN1)); - // REG_07 <15:0> - // - // When <13> = 0 for CTC1 - // <12:0> = CTC1 frequency control word = - // freq(Hz) * 20.64888 for XTAL 13M/26M or - // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M - // - // When <13> = 1 for CTC2 (Tail 55Hz Rx detection) - // <12:0> = CTC2 (should below 100Hz) frequency control word = - // 25391 / freq(Hz) for XTAL 13M/26M or - // 25000 / freq(Hz) for XTAL 12.8M/19.2M/25.6M/38.4M - // - // When <13> = 2 for CDCSS 134.4Hz - // <12:0> = CDCSS baud rate frequency (134.4Hz) control word = - // freq(Hz) * 20.64888 for XTAL 13M/26M or - // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M - // - BK4819_WriteRegister(BK4819_REG_07, BK4819_REG_07_MODE_CTC1 | 2775u); + // REG_07 <15:0> + // + // When <13> = 0 for CTC1 + // <12:0> = CTC1 frequency control word = + // freq(Hz) * 20.64888 for XTAL 13M/26M or + // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M + // + // When <13> = 1 for CTC2 (Tail 55Hz Rx detection) + // <12:0> = CTC2 (should below 100Hz) frequency control word = + // 25391 / freq(Hz) for XTAL 13M/26M or + // 25000 / freq(Hz) for XTAL 12.8M/19.2M/25.6M/38.4M + // + // When <13> = 2 for CDCSS 134.4Hz + // <12:0> = CDCSS baud rate frequency (134.4Hz) control word = + // freq(Hz) * 20.64888 for XTAL 13M/26M or + // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M + // + BK4819_WriteRegister(BK4819_REG_07, BK4819_REG_07_MODE_CTC1 | 2775u); - // REG_08 <15:0> <15> = 1 for CDCSS high 12bit - // <15> = 0 for CDCSS low 12bit - // <11:0> = CDCSShigh/low 12bit code - // - BK4819_WriteRegister(BK4819_REG_08, (0u << 15) | ((CodeWord >> 0) & 0x0FFF)); // LS 12-bits - BK4819_WriteRegister(BK4819_REG_08, (1u << 15) | ((CodeWord >> 12) & 0x0FFF)); // MS 12-bits + // REG_08 <15:0> <15> = 1 for CDCSS high 12bit + // <15> = 0 for CDCSS low 12bit + // <11:0> = CDCSShigh/low 12bit code + // + BK4819_WriteRegister(BK4819_REG_08, (0u << 15) | ((CodeWord >> 0) & 0x0FFF)); // LS 12-bits + BK4819_WriteRegister(BK4819_REG_08, (1u << 15) | ((CodeWord >> 12) & 0x0FFF)); // MS 12-bits } void BK4819_SetCTCSSFrequency(uint32_t FreqControlWord) { - // REG_51 <15> 0 1 = Enable TxCTCSS/CDCSS 0 = Disable - // REG_51 <14> 0 1 = GPIO0Input for CDCSS 0 = Normal Mode.(for BK4819v3) - // REG_51 <13> 0 1 = Transmit negative CDCSS code 0 = Transmit positive CDCSScode - // REG_51 <12> 0 CTCSS/CDCSS mode selection 1 = CTCSS 0 = CDCSS - // REG_51 <11> 0 CDCSS 24/23bit selection 1 = 24bit 0 = 23bit - // REG_51 <10> 0 1050HzDetectionMode 1 = 1050/4 Detect Enable, CTC1 should be set to 1050/4 Hz - // REG_51 <9> 0 Auto CDCSS Bw Mode 1 = Disable 0 = Enable. - // REG_51 <8> 0 Auto CTCSS Bw Mode 0 = Enable 1 = Disable - // REG_51 <6:0> 0 CTCSS/CDCSS Tx Gain1 Tuning 0 = min 127 = max + // REG_51 <15> 0 1 = Enable TxCTCSS/CDCSS 0 = Disable + // REG_51 <14> 0 1 = GPIO0Input for CDCSS 0 = Normal Mode.(for BK4819v3) + // REG_51 <13> 0 1 = Transmit negative CDCSS code 0 = Transmit positive CDCSScode + // REG_51 <12> 0 CTCSS/CDCSS mode selection 1 = CTCSS 0 = CDCSS + // REG_51 <11> 0 CDCSS 24/23bit selection 1 = 24bit 0 = 23bit + // REG_51 <10> 0 1050HzDetectionMode 1 = 1050/4 Detect Enable, CTC1 should be set to 1050/4 Hz + // REG_51 <9> 0 Auto CDCSS Bw Mode 1 = Disable 0 = Enable. + // REG_51 <8> 0 Auto CTCSS Bw Mode 0 = Enable 1 = Disable + // REG_51 <6:0> 0 CTCSS/CDCSS Tx Gain1 Tuning 0 = min 127 = max - uint16_t Config; - if (FreqControlWord == 2625) - { // Enables 1050Hz detection mode - // Enable TxCTCSS - // CTCSS Mode - // 1050/4 Detect Enable - // Enable Auto CDCSS Bw Mode - // Enable Auto CTCSS Bw Mode - // CTCSS/CDCSS Tx Gain1 Tuning = 74 - // - Config = 0x944A; // 1 0 0 1 0 1 0 0 0 1001010 - } - else - { // Enable TxCTCSS - // CTCSS Mode - // Enable Auto CDCSS Bw Mode - // Enable Auto CTCSS Bw Mode - // CTCSS/CDCSS Tx Gain1 Tuning = 74 - // - Config = 0x904A; // 1 0 0 1 0 0 0 0 0 1001010 - } - BK4819_WriteRegister(BK4819_REG_51, Config); + uint16_t Config; + if (FreqControlWord == 2625) + { // Enables 1050Hz detection mode + // Enable TxCTCSS + // CTCSS Mode + // 1050/4 Detect Enable + // Enable Auto CDCSS Bw Mode + // Enable Auto CTCSS Bw Mode + // CTCSS/CDCSS Tx Gain1 Tuning = 74 + // + Config = 0x944A; // 1 0 0 1 0 1 0 0 0 1001010 + } + else + { // Enable TxCTCSS + // CTCSS Mode + // Enable Auto CDCSS Bw Mode + // Enable Auto CTCSS Bw Mode + // CTCSS/CDCSS Tx Gain1 Tuning = 74 + // + Config = 0x904A; // 1 0 0 1 0 0 0 0 0 1001010 + } + BK4819_WriteRegister(BK4819_REG_51, Config); - // REG_07 <15:0> - // - // When <13> = 0 for CTC1 - // <12:0> = CTC1 frequency control word = - // freq(Hz) * 20.64888 for XTAL 13M/26M or - // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M - // - // When <13> = 1 for CTC2 (Tail RX detection) - // <12:0> = CTC2 (should below 100Hz) frequency control word = - // 25391 / freq(Hz) for XTAL 13M/26M or - // 25000 / freq(Hz) for XTAL 12.8M/19.2M/25.6M/38.4M - // - // When <13> = 2 for CDCSS 134.4Hz - // <12:0> = CDCSS baud rate frequency (134.4Hz) control word = - // freq(Hz) * 20.64888 for XTAL 13M/26M or - // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M - // - BK4819_WriteRegister(BK4819_REG_07, BK4819_REG_07_MODE_CTC1 | (((FreqControlWord * 206488u) + 50000u) / 100000u)); // with rounding + // REG_07 <15:0> + // + // When <13> = 0 for CTC1 + // <12:0> = CTC1 frequency control word = + // freq(Hz) * 20.64888 for XTAL 13M/26M or + // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M + // + // When <13> = 1 for CTC2 (Tail RX detection) + // <12:0> = CTC2 (should below 100Hz) frequency control word = + // 25391 / freq(Hz) for XTAL 13M/26M or + // 25000 / freq(Hz) for XTAL 12.8M/19.2M/25.6M/38.4M + // + // When <13> = 2 for CDCSS 134.4Hz + // <12:0> = CDCSS baud rate frequency (134.4Hz) control word = + // freq(Hz) * 20.64888 for XTAL 13M/26M or + // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M + // + BK4819_WriteRegister(BK4819_REG_07, BK4819_REG_07_MODE_CTC1 | (((FreqControlWord * 206488u) + 50000u) / 100000u)); // with rounding } // freq_10Hz is CTCSS Hz * 10 void BK4819_SetTailDetection(const uint32_t freq_10Hz) { - // REG_07 <15:0> - // - // When <13> = 0 for CTC1 - // <12:0> = CTC1 frequency control word = - // freq(Hz) * 20.64888 for XTAL 13M/26M or - // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M - // - // When <13> = 1 for CTC2 (Tail RX detection) - // <12:0> = CTC2 (should below 100Hz) frequency control word = - // 25391 / freq(Hz) for XTAL 13M/26M or - // 25000 / freq(Hz) for XTAL 12.8M/19.2M/25.6M/38.4M - // - // When <13> = 2 for CDCSS 134.4Hz - // <12:0> = CDCSS baud rate frequency (134.4Hz) control word = - // freq(Hz) * 20.64888 for XTAL 13M/26M or - // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M - // - BK4819_WriteRegister(BK4819_REG_07, BK4819_REG_07_MODE_CTC2 | ((253910 + (freq_10Hz / 2)) / freq_10Hz)); // with rounding + // REG_07 <15:0> + // + // When <13> = 0 for CTC1 + // <12:0> = CTC1 frequency control word = + // freq(Hz) * 20.64888 for XTAL 13M/26M or + // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M + // + // When <13> = 1 for CTC2 (Tail RX detection) + // <12:0> = CTC2 (should below 100Hz) frequency control word = + // 25391 / freq(Hz) for XTAL 13M/26M or + // 25000 / freq(Hz) for XTAL 12.8M/19.2M/25.6M/38.4M + // + // When <13> = 2 for CDCSS 134.4Hz + // <12:0> = CDCSS baud rate frequency (134.4Hz) control word = + // freq(Hz) * 20.64888 for XTAL 13M/26M or + // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M + // + BK4819_WriteRegister(BK4819_REG_07, BK4819_REG_07_MODE_CTC2 | ((253910 + (freq_10Hz / 2)) / freq_10Hz)); // with rounding } void BK4819_EnableVox(uint16_t VoxEnableThreshold, uint16_t VoxDisableThreshold) { - //VOX Algorithm - //if (voxamp>VoxEnableThreshold) VOX = 1; - //else - //if (voxampVoxEnableThreshold) VOX = 1; + //else + //if (voxamp 0 ??? - // - // <14:12> 4 RF filter bandwidth - // 0 = 1.7 kHz - // 1 = 2.0 kHz - // 2 = 2.5 kHz - // 3 = 3.0 kHz - // 4 = 3.75 kHz - // 5 = 4.0 kHz - // 6 = 4.25 kHz - // 7 = 4.5 kHz - // if <5> == 1, RF filter bandwidth * 2 - // - // <11:9> 0 RF filter bandwidth when signal is weak - // 0 = 1.7 kHz - // 1 = 2.0 kHz - // 2 = 2.5 kHz - // 3 = 3.0 kHz - // 4 = 3.75 kHz - // 5 = 4.0 kHz - // 6 = 4.25 kHz - // 7 = 4.5 kHz - // if <5> == 1, RF filter bandwidth * 2 - // - // <8:6> 1 AFTxLPF2 filter Band Width - // 1 = 2.5 kHz (for 12.5k channel space) - // 2 = 2.75 kHz - // 0 = 3.0 kHz (for 25k channel space) - // 3 = 3.5 kHz - // 4 = 4.5 kHz - // 5 = 4.25 kHz - // 6 = 4.0 kHz - // 7 = 3.75 kHz - // - // <5:4> 0 BW Mode Selection - // 0 = 12.5k - // 1 = 6.25k - // 2 = 25k/20k - // - // <3> 1 ??? - // - // <2> 0 Gain after FM Demodulation - // 0 = 0dB - // 1 = 6dB - // - // <1:0> 0 ??? + // REG_43 + // <15> 0 ??? + // + // <14:12> 4 RF filter bandwidth + // 0 = 1.7 kHz + // 1 = 2.0 kHz + // 2 = 2.5 kHz + // 3 = 3.0 kHz + // 4 = 3.75 kHz + // 5 = 4.0 kHz + // 6 = 4.25 kHz + // 7 = 4.5 kHz + // if <5> == 1, RF filter bandwidth * 2 + // + // <11:9> 0 RF filter bandwidth when signal is weak + // 0 = 1.7 kHz + // 1 = 2.0 kHz + // 2 = 2.5 kHz + // 3 = 3.0 kHz + // 4 = 3.75 kHz + // 5 = 4.0 kHz + // 6 = 4.25 kHz + // 7 = 4.5 kHz + // if <5> == 1, RF filter bandwidth * 2 + // + // <8:6> 1 AFTxLPF2 filter Band Width + // 1 = 2.5 kHz (for 12.5k channel space) + // 2 = 2.75 kHz + // 0 = 3.0 kHz (for 25k channel space) + // 3 = 3.5 kHz + // 4 = 4.5 kHz + // 5 = 4.25 kHz + // 6 = 4.0 kHz + // 7 = 3.75 kHz + // + // <5:4> 0 BW Mode Selection + // 0 = 12.5k + // 1 = 6.25k + // 2 = 25k/20k + // + // <3> 1 ??? + // + // <2> 0 Gain after FM Demodulation + // 0 = 0dB + // 1 = 6dB + // + // <1:0> 0 ??? - uint16_t val = 0; - switch (Bandwidth) - { - default: - case BK4819_FILTER_BW_WIDE: // 25kHz - val = (4u << 12) | // *3 RF filter bandwidth - (6u << 6) | // *0 AFTxLPF2 filter Band Width - (2u << 4) | // 2 BW Mode Selection - (1u << 3) | // 1 - (0u << 2); // 0 Gain after FM Demodulation + uint16_t val = 0; + switch (Bandwidth) + { + default: + case BK4819_FILTER_BW_WIDE: // 25kHz + val = (4u << 12) | // *3 RF filter bandwidth + (6u << 6) | // *0 AFTxLPF2 filter Band Width + (2u << 4) | // 2 BW Mode Selection + (1u << 3) | // 1 + (0u << 2); // 0 Gain after FM Demodulation - if (weak_no_different) { - // make the RX bandwidth the same with weak signals - val |= (4u << 9); // *0 RF filter bandwidth when signal is weak - } else { - /// with weak RX signals the RX bandwidth is reduced - val |= (2u << 9); // *0 RF filter bandwidth when signal is weak - } + if (weak_no_different) { + // make the RX bandwidth the same with weak signals + val |= (4u << 9); // *0 RF filter bandwidth when signal is weak + } else { + /// with weak RX signals the RX bandwidth is reduced + val |= (2u << 9); // *0 RF filter bandwidth when signal is weak + } - break; + break; - case BK4819_FILTER_BW_NARROW: // 12.5kHz - val = (4u << 12) | // *4 RF filter bandwidth - (0u << 6) | // *1 AFTxLPF2 filter Band Width - (0u << 4) | // 0 BW Mode Selection - (1u << 3) | // 1 - (0u << 2); // 0 Gain after FM Demodulation + case BK4819_FILTER_BW_NARROW: // 12.5kHz + val = (4u << 12) | // *4 RF filter bandwidth + (0u << 6) | // *1 AFTxLPF2 filter Band Width + (0u << 4) | // 0 BW Mode Selection + (1u << 3) | // 1 + (0u << 2); // 0 Gain after FM Demodulation - if (weak_no_different) { - val |= (4u << 9); // *0 RF filter bandwidth when signal is weak - } else { - val |= (2u << 9); - } + if (weak_no_different) { + val |= (4u << 9); // *0 RF filter bandwidth when signal is weak + } else { + val |= (2u << 9); + } - break; + break; - case BK4819_FILTER_BW_NARROWER: // 6.25kHz - val = (3u << 12) | // 3 RF filter bandwidth - (3u << 9) | // *0 RF filter bandwidth when signal is weak - (1u << 6) | // 1 AFTxLPF2 filter Band Width - (1u << 4) | // 1 BW Mode Selection - (1u << 3) | // 1 - (0u << 2); // 0 Gain after FM Demodulation + case BK4819_FILTER_BW_NARROWER: // 6.25kHz + val = (3u << 12) | // 3 RF filter bandwidth + (3u << 9) | // *0 RF filter bandwidth when signal is weak + (1u << 6) | // 1 AFTxLPF2 filter Band Width + (1u << 4) | // 1 BW Mode Selection + (1u << 3) | // 1 + (0u << 2); // 0 Gain after FM Demodulation - if (weak_no_different) { - val |= (3u << 9); - } else { - val |= (0u << 9); // 0 RF filter bandwidth when signal is weak - } - break; - } + if (weak_no_different) { + val |= (3u << 9); + } else { + val |= (0u << 9); // 0 RF filter bandwidth when signal is weak + } + break; + } - BK4819_WriteRegister(BK4819_REG_43, val); + BK4819_WriteRegister(BK4819_REG_43, val); } void BK4819_SetupPowerAmplifier(const uint8_t bias, const uint32_t frequency) { - // REG_36 <15:8> 0 PA Bias output 0 ~ 3.2V - // 255 = 3.2V - // 0 = 0V - // - // REG_36 <7> 0 - // 1 = Enable PA-CTL output - // 0 = Disable (Output 0 V) - // - // REG_36 <5:3> 7 PA gain 1 tuning - // 7 = max - // 0 = min - // - // REG_36 <2:0> 7 PA gain 2 tuning - // 7 = max - // 0 = min - // - // 280MHz g1=1 g2=0 (-14.9dBm), g1=4 g2=2 (0.13dBm) - const uint8_t gain = (frequency < 28000000) ? (1u << 3) | (0u << 0) : (4u << 3) | (2u << 0); - const uint8_t enable = 1; - BK4819_WriteRegister(BK4819_REG_36, (bias << 8) | (enable << 7) | (gain << 0)); + // REG_36 <15:8> 0 PA Bias output 0 ~ 3.2V + // 255 = 3.2V + // 0 = 0V + // + // REG_36 <7> 0 + // 1 = Enable PA-CTL output + // 0 = Disable (Output 0 V) + // + // REG_36 <5:3> 7 PA gain 1 tuning + // 7 = max + // 0 = min + // + // REG_36 <2:0> 7 PA gain 2 tuning + // 7 = max + // 0 = min + // + // 280MHz g1=1 g2=0 (-14.9dBm), g1=4 g2=2 (0.13dBm) + const uint8_t gain = (frequency < 28000000) ? (1u << 3) | (0u << 0) : (4u << 3) | (2u << 0); + const uint8_t enable = 1; + BK4819_WriteRegister(BK4819_REG_36, (bias << 8) | (enable << 7) | (gain << 0)); } void BK4819_SetFrequency(uint32_t Frequency) { - BK4819_WriteRegister(BK4819_REG_38, (Frequency >> 0) & 0xFFFF); - BK4819_WriteRegister(BK4819_REG_39, (Frequency >> 16) & 0xFFFF); + BK4819_WriteRegister(BK4819_REG_38, (Frequency >> 0) & 0xFFFF); + BK4819_WriteRegister(BK4819_REG_39, (Frequency >> 16) & 0xFFFF); } void BK4819_SetupSquelch( - uint8_t SquelchOpenRSSIThresh, - uint8_t SquelchCloseRSSIThresh, - uint8_t SquelchOpenNoiseThresh, - uint8_t SquelchCloseNoiseThresh, - uint8_t SquelchCloseGlitchThresh, - uint8_t SquelchOpenGlitchThresh) + uint8_t SquelchOpenRSSIThresh, + uint8_t SquelchCloseRSSIThresh, + uint8_t SquelchOpenNoiseThresh, + uint8_t SquelchCloseNoiseThresh, + uint8_t SquelchCloseGlitchThresh, + uint8_t SquelchOpenGlitchThresh) { - // REG_70 - // - // <15> 0 Enable TONE1 - // 1 = Enable - // 0 = Disable - // - // <14:8> 0 TONE1 tuning gain - // 0 ~ 127 - // - // <7> 0 Enable TONE2 - // 1 = Enable - // 0 = Disable - // - // <6:0> 0 TONE2/FSK tuning gain - // 0 ~ 127 - // - BK4819_WriteRegister(BK4819_REG_70, 0); + // REG_70 + // + // <15> 0 Enable TONE1 + // 1 = Enable + // 0 = Disable + // + // <14:8> 0 TONE1 tuning gain + // 0 ~ 127 + // + // <7> 0 Enable TONE2 + // 1 = Enable + // 0 = Disable + // + // <6:0> 0 TONE2/FSK tuning gain + // 0 ~ 127 + // + BK4819_WriteRegister(BK4819_REG_70, 0); - // Glitch threshold for Squelch = close - // - // 0 ~ 255 - // - BK4819_WriteRegister(BK4819_REG_4D, 0xA000 | SquelchCloseGlitchThresh); + // Glitch threshold for Squelch = close + // + // 0 ~ 255 + // + BK4819_WriteRegister(BK4819_REG_4D, 0xA000 | SquelchCloseGlitchThresh); - // REG_4E - // - // <15:14> 1 ??? - // - // <13:11> 5 Squelch = open Delay Setting - // 0 ~ 7 - // - // <10:9> 7 Squelch = close Delay Setting - // 0 ~ 3 - // - // <8> 0 ??? - // - // <7:0> 8 Glitch threshold for Squelch = open - // 0 ~ 255 - // - BK4819_WriteRegister(BK4819_REG_4E, // 01 101 11 1 00000000 + // REG_4E + // + // <15:14> 1 ??? + // + // <13:11> 5 Squelch = open Delay Setting + // 0 ~ 7 + // + // <10:9> 7 Squelch = close Delay Setting + // 0 ~ 3 + // + // <8> 0 ??? + // + // <7:0> 8 Glitch threshold for Squelch = open + // 0 ~ 255 + // + BK4819_WriteRegister(BK4819_REG_4E, // 01 101 11 1 00000000 - // original (*) - (1u << 14) | // 1 ??? - (5u << 11) | // *5 squelch = open delay .. 0 ~ 7 - (6u << 9) | // *3 squelch = close delay .. 0 ~ 3 - SquelchOpenGlitchThresh); // 0 ~ 255 + // original (*) + (1u << 14) | // 1 ??? + (5u << 11) | // *5 squelch = open delay .. 0 ~ 7 + (6u << 9) | // *3 squelch = close delay .. 0 ~ 3 + SquelchOpenGlitchThresh); // 0 ~ 255 - // REG_4F - // - // <14:8> 47 Ex-noise threshold for Squelch = close - // 0 ~ 127 - // - // <7> ??? - // - // <6:0> 46 Ex-noise threshold for Squelch = open - // 0 ~ 127 - // - BK4819_WriteRegister(BK4819_REG_4F, ((uint16_t)SquelchCloseNoiseThresh << 8) | SquelchOpenNoiseThresh); + // REG_4F + // + // <14:8> 47 Ex-noise threshold for Squelch = close + // 0 ~ 127 + // + // <7> ??? + // + // <6:0> 46 Ex-noise threshold for Squelch = open + // 0 ~ 127 + // + BK4819_WriteRegister(BK4819_REG_4F, ((uint16_t)SquelchCloseNoiseThresh << 8) | SquelchOpenNoiseThresh); - // REG_78 - // - // <15:8> 72 RSSI threshold for Squelch = open 0.5dB/step - // - // <7:0> 70 RSSI threshold for Squelch = close 0.5dB/step - // - BK4819_WriteRegister(BK4819_REG_78, ((uint16_t)SquelchOpenRSSIThresh << 8) | SquelchCloseRSSIThresh); + // REG_78 + // + // <15:8> 72 RSSI threshold for Squelch = open 0.5dB/step + // + // <7:0> 70 RSSI threshold for Squelch = close 0.5dB/step + // + BK4819_WriteRegister(BK4819_REG_78, ((uint16_t)SquelchOpenRSSIThresh << 8) | SquelchCloseRSSIThresh); - BK4819_SetAF(BK4819_AF_MUTE); + BK4819_SetAF(BK4819_AF_MUTE); - BK4819_RX_TurnOn(); + BK4819_RX_TurnOn(); } void BK4819_SetAF(BK4819_AF_Type_t AF) { - // AF Output Inverse Mode = Inverse - // Undocumented bits 0x2040 - // -// BK4819_WriteRegister(BK4819_REG_47, 0x6040 | (AF << 8)); - BK4819_WriteRegister(BK4819_REG_47, (6u << 12) | (AF << 8) | (1u << 6)); + // AF Output Inverse Mode = Inverse + // Undocumented bits 0x2040 + // +// BK4819_WriteRegister(BK4819_REG_47, 0x6040 | (AF << 8)); + BK4819_WriteRegister(BK4819_REG_47, (6u << 12) | (AF << 8) | (1u << 6)); } void BK4819_SetRegValue(RegisterSpec s, uint16_t v) { @@ -791,1029 +791,1029 @@ void BK4819_SetRegValue(RegisterSpec s, uint16_t v) { void BK4819_RX_TurnOn(void) { - // DSP Voltage Setting = 1 - // ANA LDO = 2.7v - // VCO LDO = 2.7v - // RF LDO = 2.7v - // PLL LDO = 2.7v - // ANA LDO bypass - // VCO LDO bypass - // RF LDO bypass - // PLL LDO bypass - // Reserved bit is 1 instead of 0 - // Enable DSP - // Enable XTAL - // Enable Band Gap - // - BK4819_WriteRegister(BK4819_REG_37, 0x1F0F); // 0001111100001111 + // DSP Voltage Setting = 1 + // ANA LDO = 2.7v + // VCO LDO = 2.7v + // RF LDO = 2.7v + // PLL LDO = 2.7v + // ANA LDO bypass + // VCO LDO bypass + // RF LDO bypass + // PLL LDO bypass + // Reserved bit is 1 instead of 0 + // Enable DSP + // Enable XTAL + // Enable Band Gap + // + BK4819_WriteRegister(BK4819_REG_37, 0x1F0F); // 0001111100001111 - // Turn off everything - BK4819_WriteRegister(BK4819_REG_30, 0); + // Turn off everything + BK4819_WriteRegister(BK4819_REG_30, 0); - BK4819_WriteRegister(BK4819_REG_30, - BK4819_REG_30_ENABLE_VCO_CALIB | - BK4819_REG_30_DISABLE_UNKNOWN | - BK4819_REG_30_ENABLE_RX_LINK | - BK4819_REG_30_ENABLE_AF_DAC | - BK4819_REG_30_ENABLE_DISC_MODE | - BK4819_REG_30_ENABLE_PLL_VCO | - BK4819_REG_30_DISABLE_PA_GAIN | - BK4819_REG_30_DISABLE_MIC_ADC | - BK4819_REG_30_DISABLE_TX_DSP | - BK4819_REG_30_ENABLE_RX_DSP ); + BK4819_WriteRegister(BK4819_REG_30, + BK4819_REG_30_ENABLE_VCO_CALIB | + BK4819_REG_30_DISABLE_UNKNOWN | + BK4819_REG_30_ENABLE_RX_LINK | + BK4819_REG_30_ENABLE_AF_DAC | + BK4819_REG_30_ENABLE_DISC_MODE | + BK4819_REG_30_ENABLE_PLL_VCO | + BK4819_REG_30_DISABLE_PA_GAIN | + BK4819_REG_30_DISABLE_MIC_ADC | + BK4819_REG_30_DISABLE_TX_DSP | + BK4819_REG_30_ENABLE_RX_DSP ); } void BK4819_PickRXFilterPathBasedOnFrequency(uint32_t Frequency) { - if (Frequency < 28000000) - { // VHF - BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, true); - BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, false); - } - else - if (Frequency == 0xFFFFFFFF) - { // OFF - BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, false); - BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, false); - } - else - { // UHF - BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, false); - BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, true); - } + if (Frequency < 28000000) + { // VHF + BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, true); + BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, false); + } + else + if (Frequency == 0xFFFFFFFF) + { // OFF + BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, false); + BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, false); + } + else + { // UHF + BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, false); + BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, true); + } } void BK4819_DisableScramble(void) { - const uint16_t Value = BK4819_ReadRegister(BK4819_REG_31); - BK4819_WriteRegister(BK4819_REG_31, Value & ~(1u << 1)); + const uint16_t Value = BK4819_ReadRegister(BK4819_REG_31); + BK4819_WriteRegister(BK4819_REG_31, Value & ~(1u << 1)); } void BK4819_EnableScramble(uint8_t Type) { - const uint16_t Value = BK4819_ReadRegister(BK4819_REG_31); - BK4819_WriteRegister(BK4819_REG_31, Value | (1u << 1)); + const uint16_t Value = BK4819_ReadRegister(BK4819_REG_31); + BK4819_WriteRegister(BK4819_REG_31, Value | (1u << 1)); - BK4819_WriteRegister(BK4819_REG_71, 0x68DC + (Type * 1032)); // 0110 1000 1101 1100 + BK4819_WriteRegister(BK4819_REG_71, 0x68DC + (Type * 1032)); // 0110 1000 1101 1100 } bool BK4819_CompanderEnabled(void) { - return (BK4819_ReadRegister(BK4819_REG_31) & (1u << 3)) ? true : false; + return (BK4819_ReadRegister(BK4819_REG_31) & (1u << 3)) ? true : false; } void BK4819_SetCompander(const unsigned int mode) { - // mode 0 .. OFF - // mode 1 .. TX - // mode 2 .. RX - // mode 3 .. TX and RX + // mode 0 .. OFF + // mode 1 .. TX + // mode 2 .. RX + // mode 3 .. TX and RX - const uint16_t r31 = BK4819_ReadRegister(BK4819_REG_31); + const uint16_t r31 = BK4819_ReadRegister(BK4819_REG_31); - if (mode == 0) - { // disable - BK4819_WriteRegister(BK4819_REG_31, r31 & ~(1u << 3)); - return; - } + if (mode == 0) + { // disable + BK4819_WriteRegister(BK4819_REG_31, r31 & ~(1u << 3)); + return; + } - // REG_29 - // - // <15:14> 10 Compress (AF Tx) Ratio - // 00 = Disable - // 01 = 1.333:1 - // 10 = 2:1 - // 11 = 4:1 - // - // <13:7> 86 Compress (AF Tx) 0 dB point (dB) - // - // <6:0> 64 Compress (AF Tx) noise point (dB) - // - const uint16_t compress_ratio = (mode == 1 || mode >= 3) ? 2 : 0; // 2:1 - const uint16_t compress_0dB = 86; - const uint16_t compress_noise_dB = 64; -// AB40 10 1010110 1000000 - BK4819_WriteRegister(BK4819_REG_29, // (BK4819_ReadRegister(BK4819_REG_29) & ~(3u << 14)) | (compress_ratio << 14)); - (compress_ratio << 14) | - (compress_0dB << 7) | - (compress_noise_dB << 0)); + // REG_29 + // + // <15:14> 10 Compress (AF Tx) Ratio + // 00 = Disable + // 01 = 1.333:1 + // 10 = 2:1 + // 11 = 4:1 + // + // <13:7> 86 Compress (AF Tx) 0 dB point (dB) + // + // <6:0> 64 Compress (AF Tx) noise point (dB) + // + const uint16_t compress_ratio = (mode == 1 || mode >= 3) ? 2 : 0; // 2:1 + const uint16_t compress_0dB = 86; + const uint16_t compress_noise_dB = 64; +// AB40 10 1010110 1000000 + BK4819_WriteRegister(BK4819_REG_29, // (BK4819_ReadRegister(BK4819_REG_29) & ~(3u << 14)) | (compress_ratio << 14)); + (compress_ratio << 14) | + (compress_0dB << 7) | + (compress_noise_dB << 0)); - // REG_28 - // - // <15:14> 01 Expander (AF Rx) Ratio - // 00 = Disable - // 01 = 1:2 - // 10 = 1:3 - // 11 = 1:4 - // - // <13:7> 86 Expander (AF Rx) 0 dB point (dB) - // - // <6:0> 56 Expander (AF Rx) noise point (dB) - // - const uint16_t expand_ratio = (mode >= 2) ? 1 : 0; // 1:2 - const uint16_t expand_0dB = 86; - const uint16_t expand_noise_dB = 56; -// 6B38 01 1010110 0111000 - BK4819_WriteRegister(BK4819_REG_28, // (BK4819_ReadRegister(BK4819_REG_28) & ~(3u << 14)) | (expand_ratio << 14)); - (expand_ratio << 14) | - (expand_0dB << 7) | - (expand_noise_dB << 0)); + // REG_28 + // + // <15:14> 01 Expander (AF Rx) Ratio + // 00 = Disable + // 01 = 1:2 + // 10 = 1:3 + // 11 = 1:4 + // + // <13:7> 86 Expander (AF Rx) 0 dB point (dB) + // + // <6:0> 56 Expander (AF Rx) noise point (dB) + // + const uint16_t expand_ratio = (mode >= 2) ? 1 : 0; // 1:2 + const uint16_t expand_0dB = 86; + const uint16_t expand_noise_dB = 56; +// 6B38 01 1010110 0111000 + BK4819_WriteRegister(BK4819_REG_28, // (BK4819_ReadRegister(BK4819_REG_28) & ~(3u << 14)) | (expand_ratio << 14)); + (expand_ratio << 14) | + (expand_0dB << 7) | + (expand_noise_dB << 0)); - // enable - BK4819_WriteRegister(BK4819_REG_31, r31 | (1u << 3)); + // enable + BK4819_WriteRegister(BK4819_REG_31, r31 | (1u << 3)); } void BK4819_DisableVox(void) { - const uint16_t Value = BK4819_ReadRegister(BK4819_REG_31); - BK4819_WriteRegister(BK4819_REG_31, Value & 0xFFFB); + const uint16_t Value = BK4819_ReadRegister(BK4819_REG_31); + BK4819_WriteRegister(BK4819_REG_31, Value & 0xFFFB); } void BK4819_DisableDTMF(void) { - BK4819_WriteRegister(BK4819_REG_24, 0); + BK4819_WriteRegister(BK4819_REG_24, 0); } void BK4819_EnableDTMF(void) { - // no idea what this does - BK4819_WriteRegister(BK4819_REG_21, 0x06D8); // 0000 0110 1101 1000 + // no idea what this does + BK4819_WriteRegister(BK4819_REG_21, 0x06D8); // 0000 0110 1101 1000 - // REG_24 - // - // <15> 1 ??? - // - // <14:7> 24 Threshold - // - // <6> 1 ??? - // - // <5> 0 DTMF/SelCall enable - // 1 = Enable - // 0 = Disable - // - // <4> 1 DTMF or SelCall detection mode - // 1 = for DTMF - // 0 = for SelCall - // - // <3:0> 14 Max symbol number for SelCall detection - // -// const uint16_t threshold = 24; // default, but doesn't decode non-QS radios - const uint16_t threshold = 130; // but 128 ~ 247 does - BK4819_WriteRegister(BK4819_REG_24, // 1 00011000 1 1 1 1110 - (1u << BK4819_REG_24_SHIFT_UNKNOWN_15) | - (threshold << BK4819_REG_24_SHIFT_THRESHOLD) | // 0 ~ 255 - (1u << BK4819_REG_24_SHIFT_UNKNOWN_6) | - BK4819_REG_24_ENABLE | - BK4819_REG_24_SELECT_DTMF | - (15u << BK4819_REG_24_SHIFT_MAX_SYMBOLS)); // 0 ~ 15 + // REG_24 + // + // <15> 1 ??? + // + // <14:7> 24 Threshold + // + // <6> 1 ??? + // + // <5> 0 DTMF/SelCall enable + // 1 = Enable + // 0 = Disable + // + // <4> 1 DTMF or SelCall detection mode + // 1 = for DTMF + // 0 = for SelCall + // + // <3:0> 14 Max symbol number for SelCall detection + // +// const uint16_t threshold = 24; // default, but doesn't decode non-QS radios + const uint16_t threshold = 130; // but 128 ~ 247 does + BK4819_WriteRegister(BK4819_REG_24, // 1 00011000 1 1 1 1110 + (1u << BK4819_REG_24_SHIFT_UNKNOWN_15) | + (threshold << BK4819_REG_24_SHIFT_THRESHOLD) | // 0 ~ 255 + (1u << BK4819_REG_24_SHIFT_UNKNOWN_6) | + BK4819_REG_24_ENABLE | + BK4819_REG_24_SELECT_DTMF | + (15u << BK4819_REG_24_SHIFT_MAX_SYMBOLS)); // 0 ~ 15 } void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch) { - uint16_t ToneConfig = BK4819_REG_70_ENABLE_TONE1; + uint16_t ToneConfig = BK4819_REG_70_ENABLE_TONE1; - BK4819_EnterTxMute(); - BK4819_SetAF(BK4819_AF_BEEP); + BK4819_EnterTxMute(); + BK4819_SetAF(BK4819_AF_BEEP); - if (bTuningGainSwitch == 0) - ToneConfig |= 96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN; - else - ToneConfig |= 28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN; - BK4819_WriteRegister(BK4819_REG_70, ToneConfig); + if (bTuningGainSwitch == 0) + ToneConfig |= 96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN; + else + ToneConfig |= 28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN; + BK4819_WriteRegister(BK4819_REG_70, ToneConfig); - BK4819_WriteRegister(BK4819_REG_30, 0); - BK4819_WriteRegister(BK4819_REG_30, BK4819_REG_30_ENABLE_AF_DAC | BK4819_REG_30_ENABLE_DISC_MODE | BK4819_REG_30_ENABLE_TX_DSP); + BK4819_WriteRegister(BK4819_REG_30, 0); + BK4819_WriteRegister(BK4819_REG_30, BK4819_REG_30_ENABLE_AF_DAC | BK4819_REG_30_ENABLE_DISC_MODE | BK4819_REG_30_ENABLE_TX_DSP); - BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency)); + BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency)); } // level 0 ~ 127 void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay, const unsigned int level, const bool play_speaker) { - BK4819_EnterTxMute(); + BK4819_EnterTxMute(); - if (play_speaker) - { - AUDIO_AudioPathOn(); - BK4819_SetAF(BK4819_AF_BEEP); - } - else - BK4819_SetAF(BK4819_AF_MUTE); + if (play_speaker) + { + AUDIO_AudioPathOn(); + BK4819_SetAF(BK4819_AF_BEEP); + } + else + BK4819_SetAF(BK4819_AF_MUTE); - BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | ((level & 0x7f) << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN)); + BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | ((level & 0x7f) << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN)); - BK4819_EnableTXLink(); - SYSTEM_DelayMs(50); + BK4819_EnableTXLink(); + SYSTEM_DelayMs(50); - BK4819_WriteRegister(BK4819_REG_71, scale_freq(tone_Hz)); + BK4819_WriteRegister(BK4819_REG_71, scale_freq(tone_Hz)); - BK4819_ExitTxMute(); - SYSTEM_DelayMs(delay); - BK4819_EnterTxMute(); + BK4819_ExitTxMute(); + SYSTEM_DelayMs(delay); + BK4819_EnterTxMute(); - if (play_speaker) - { - AUDIO_AudioPathOff(); - BK4819_SetAF(BK4819_AF_MUTE); - } + if (play_speaker) + { + AUDIO_AudioPathOff(); + BK4819_SetAF(BK4819_AF_MUTE); + } - BK4819_WriteRegister(BK4819_REG_70, 0x0000); - BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); - BK4819_ExitTxMute(); + BK4819_WriteRegister(BK4819_REG_70, 0x0000); + BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); + BK4819_ExitTxMute(); } void BK4819_EnterTxMute(void) { - BK4819_WriteRegister(BK4819_REG_50, 0xBB20); + BK4819_WriteRegister(BK4819_REG_50, 0xBB20); } void BK4819_ExitTxMute(void) { - BK4819_WriteRegister(BK4819_REG_50, 0x3B20); + BK4819_WriteRegister(BK4819_REG_50, 0x3B20); } void BK4819_Sleep(void) { - BK4819_WriteRegister(BK4819_REG_30, 0); - BK4819_WriteRegister(BK4819_REG_37, 0x1D00); + BK4819_WriteRegister(BK4819_REG_30, 0); + BK4819_WriteRegister(BK4819_REG_37, 0x1D00); } void BK4819_TurnsOffTones_TurnsOnRX(void) { - BK4819_WriteRegister(BK4819_REG_70, 0); - BK4819_SetAF(BK4819_AF_MUTE); + BK4819_WriteRegister(BK4819_REG_70, 0); + BK4819_SetAF(BK4819_AF_MUTE); - BK4819_ExitTxMute(); + BK4819_ExitTxMute(); - BK4819_WriteRegister(BK4819_REG_30, 0); - BK4819_WriteRegister(BK4819_REG_30, - BK4819_REG_30_ENABLE_VCO_CALIB | - BK4819_REG_30_ENABLE_RX_LINK | - BK4819_REG_30_ENABLE_AF_DAC | - BK4819_REG_30_ENABLE_DISC_MODE | - BK4819_REG_30_ENABLE_PLL_VCO | - BK4819_REG_30_ENABLE_RX_DSP); + BK4819_WriteRegister(BK4819_REG_30, 0); + BK4819_WriteRegister(BK4819_REG_30, + BK4819_REG_30_ENABLE_VCO_CALIB | + BK4819_REG_30_ENABLE_RX_LINK | + BK4819_REG_30_ENABLE_AF_DAC | + BK4819_REG_30_ENABLE_DISC_MODE | + BK4819_REG_30_ENABLE_PLL_VCO | + BK4819_REG_30_ENABLE_RX_DSP); } #ifdef ENABLE_AIRCOPY - void BK4819_SetupAircopy(void) - { - BK4819_WriteRegister(BK4819_REG_70, 0x00E0); // Enable Tone2, tuning gain 48 - BK4819_WriteRegister(BK4819_REG_72, 0x3065); // Tone2 baudrate 1200 - BK4819_WriteRegister(BK4819_REG_58, 0x00C1); // FSK Enable, FSK 1.2K RX Bandwidth, Preamble 0xAA or 0x55, RX Gain 0, RX Mode - // (FSK1.2K, FSK2.4K Rx and NOAA SAME Rx), TX Mode FSK 1.2K and FSK 2.4K Tx - BK4819_WriteRegister(BK4819_REG_5C, 0x5665); // Enable CRC among other things we don't know yet - BK4819_WriteRegister(BK4819_REG_5D, 0x4700); // FSK Data Length 72 Bytes (0xabcd + 2 byte length + 64 byte payload + 2 byte CRC + 0xdcba) - } + void BK4819_SetupAircopy(void) + { + BK4819_WriteRegister(BK4819_REG_70, 0x00E0); // Enable Tone2, tuning gain 48 + BK4819_WriteRegister(BK4819_REG_72, 0x3065); // Tone2 baudrate 1200 + BK4819_WriteRegister(BK4819_REG_58, 0x00C1); // FSK Enable, FSK 1.2K RX Bandwidth, Preamble 0xAA or 0x55, RX Gain 0, RX Mode + // (FSK1.2K, FSK2.4K Rx and NOAA SAME Rx), TX Mode FSK 1.2K and FSK 2.4K Tx + BK4819_WriteRegister(BK4819_REG_5C, 0x5665); // Enable CRC among other things we don't know yet + BK4819_WriteRegister(BK4819_REG_5D, 0x4700); // FSK Data Length 72 Bytes (0xabcd + 2 byte length + 64 byte payload + 2 byte CRC + 0xdcba) + } #endif void BK4819_ResetFSK(void) { - BK4819_WriteRegister(BK4819_REG_3F, 0x0000); // Disable interrupts - BK4819_WriteRegister(BK4819_REG_59, 0x0068); // Sync length 4 bytes, 7 byte preamble + BK4819_WriteRegister(BK4819_REG_3F, 0x0000); // Disable interrupts + BK4819_WriteRegister(BK4819_REG_59, 0x0068); // Sync length 4 bytes, 7 byte preamble - SYSTEM_DelayMs(30); + SYSTEM_DelayMs(30); - BK4819_Idle(); + BK4819_Idle(); } void BK4819_Idle(void) { - BK4819_WriteRegister(BK4819_REG_30, 0x0000); + BK4819_WriteRegister(BK4819_REG_30, 0x0000); } void BK4819_ExitBypass(void) { - BK4819_SetAF(BK4819_AF_MUTE); + BK4819_SetAF(BK4819_AF_MUTE); - // REG_7E - // - // <15> 0 AGC fix mode - // 1 = fix - // 0 = auto - // - // <14:12> 3 AGC fix index - // 3 ( 3) = max - // 2 ( 2) - // 1 ( 1) - // 0 ( 0) - // 7 (-1) - // 6 (-2) - // 5 (-3) - // 4 (-4) = min - // - // <11:6> 0 ??? - // - // <5:3> 5 DC filter band width for Tx (MIC In) - // 0 ~ 7 - // 0 = bypass DC filter - // - // <2:0> 6 DC filter band width for Rx (I.F In) - // 0 ~ 7 - // 0 = bypass DC filter - // + // REG_7E + // + // <15> 0 AGC fix mode + // 1 = fix + // 0 = auto + // + // <14:12> 3 AGC fix index + // 3 ( 3) = max + // 2 ( 2) + // 1 ( 1) + // 0 ( 0) + // 7 (-1) + // 6 (-2) + // 5 (-3) + // 4 (-4) = min + // + // <11:6> 0 ??? + // + // <5:3> 5 DC filter band width for Tx (MIC In) + // 0 ~ 7 + // 0 = bypass DC filter + // + // <2:0> 6 DC filter band width for Rx (I.F In) + // 0 ~ 7 + // 0 = bypass DC filter + // - uint16_t regVal = BK4819_ReadRegister(BK4819_REG_7E); + uint16_t regVal = BK4819_ReadRegister(BK4819_REG_7E); - // 0x302E / 0 011 000000 101 110 - BK4819_WriteRegister(BK4819_REG_7E, (regVal & ~(0b111 << 3)) + // 0x302E / 0 011 000000 101 110 + BK4819_WriteRegister(BK4819_REG_7E, (regVal & ~(0b111 << 3)) - | (5u << 3) // 5 DC Filter band width for Tx (MIC In) + | (5u << 3) // 5 DC Filter band width for Tx (MIC In) - ); + ); } void BK4819_PrepareTransmit(void) { - BK4819_ExitBypass(); - BK4819_ExitTxMute(); - BK4819_TxOn_Beep(); + BK4819_ExitBypass(); + BK4819_ExitTxMute(); + BK4819_TxOn_Beep(); } void BK4819_TxOn_Beep(void) { - BK4819_WriteRegister(BK4819_REG_37, 0x1D0F); - BK4819_WriteRegister(BK4819_REG_52, 0x028F); - BK4819_WriteRegister(BK4819_REG_30, 0x0000); - BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); + BK4819_WriteRegister(BK4819_REG_37, 0x1D0F); + BK4819_WriteRegister(BK4819_REG_52, 0x028F); + BK4819_WriteRegister(BK4819_REG_30, 0x0000); + BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); } void BK4819_ExitSubAu(void) { - // REG_51 - // - // <15> 0 - // 1 = Enable TxCTCSS/CDCSS - // 0 = Disable - // - // <14> 0 - // 1 = GPIO0Input for CDCSS - // 0 = Normal Mode (for BK4819 v3) - // - // <13> 0 - // 1 = Transmit negative CDCSS code - // 0 = Transmit positive CDCSS code - // - // <12> 0 CTCSS/CDCSS mode selection - // 1 = CTCSS - // 0 = CDCSS - // - // <11> 0 CDCSS 24/23bit selection - // 1 = 24bit - // 0 = 23bit - // - // <10> 0 1050HzDetectionMode - // 1 = 1050/4 Detect Enable, CTC1 should be set to 1050/4 Hz - // - // <9> 0 Auto CDCSS Bw Mode - // 1 = Disable - // 0 = Enable - // - // <8> 0 Auto CTCSS Bw Mode - // 0 = Enable - // 1 = Disable - // - // <6:0> 0 CTCSS/CDCSS Tx Gain1 Tuning - // 0 = min - // 127 = max - // - BK4819_WriteRegister(BK4819_REG_51, 0x0000); + // REG_51 + // + // <15> 0 + // 1 = Enable TxCTCSS/CDCSS + // 0 = Disable + // + // <14> 0 + // 1 = GPIO0Input for CDCSS + // 0 = Normal Mode (for BK4819 v3) + // + // <13> 0 + // 1 = Transmit negative CDCSS code + // 0 = Transmit positive CDCSS code + // + // <12> 0 CTCSS/CDCSS mode selection + // 1 = CTCSS + // 0 = CDCSS + // + // <11> 0 CDCSS 24/23bit selection + // 1 = 24bit + // 0 = 23bit + // + // <10> 0 1050HzDetectionMode + // 1 = 1050/4 Detect Enable, CTC1 should be set to 1050/4 Hz + // + // <9> 0 Auto CDCSS Bw Mode + // 1 = Disable + // 0 = Enable + // + // <8> 0 Auto CTCSS Bw Mode + // 0 = Enable + // 1 = Disable + // + // <6:0> 0 CTCSS/CDCSS Tx Gain1 Tuning + // 0 = min + // 127 = max + // + BK4819_WriteRegister(BK4819_REG_51, 0x0000); } void BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable(void) { - if (gRxIdleMode) - { - BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, true); - BK4819_RX_TurnOn(); - } + if (gRxIdleMode) + { + BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, true); + BK4819_RX_TurnOn(); + } } void BK4819_EnterDTMF_TX(bool bLocalLoopback) { - BK4819_EnableDTMF(); - BK4819_EnterTxMute(); - BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE); + BK4819_EnableDTMF(); + BK4819_EnterTxMute(); + BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE); - BK4819_WriteRegister(BK4819_REG_70, - BK4819_REG_70_MASK_ENABLE_TONE1 | - (DTMF_TONE1_GAIN << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) | - BK4819_REG_70_MASK_ENABLE_TONE2 | - (DTMF_TONE2_GAIN << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN)); + BK4819_WriteRegister(BK4819_REG_70, + BK4819_REG_70_MASK_ENABLE_TONE1 | + (DTMF_TONE1_GAIN << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) | + BK4819_REG_70_MASK_ENABLE_TONE2 | + (DTMF_TONE2_GAIN << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN)); - BK4819_EnableTXLink(); + BK4819_EnableTXLink(); } void BK4819_ExitDTMF_TX(bool bKeep) { - BK4819_EnterTxMute(); - BK4819_SetAF(BK4819_AF_MUTE); - BK4819_WriteRegister(BK4819_REG_70, 0x0000); - BK4819_DisableDTMF(); - BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); - if (!bKeep) - BK4819_ExitTxMute(); + BK4819_EnterTxMute(); + BK4819_SetAF(BK4819_AF_MUTE); + BK4819_WriteRegister(BK4819_REG_70, 0x0000); + BK4819_DisableDTMF(); + BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); + if (!bKeep) + BK4819_ExitTxMute(); } void BK4819_EnableTXLink(void) { - BK4819_WriteRegister(BK4819_REG_30, - BK4819_REG_30_ENABLE_VCO_CALIB | - BK4819_REG_30_ENABLE_UNKNOWN | - BK4819_REG_30_DISABLE_RX_LINK | - BK4819_REG_30_ENABLE_AF_DAC | - BK4819_REG_30_ENABLE_DISC_MODE | - BK4819_REG_30_ENABLE_PLL_VCO | - BK4819_REG_30_ENABLE_PA_GAIN | - BK4819_REG_30_DISABLE_MIC_ADC | - BK4819_REG_30_ENABLE_TX_DSP | - BK4819_REG_30_DISABLE_RX_DSP); + BK4819_WriteRegister(BK4819_REG_30, + BK4819_REG_30_ENABLE_VCO_CALIB | + BK4819_REG_30_ENABLE_UNKNOWN | + BK4819_REG_30_DISABLE_RX_LINK | + BK4819_REG_30_ENABLE_AF_DAC | + BK4819_REG_30_ENABLE_DISC_MODE | + BK4819_REG_30_ENABLE_PLL_VCO | + BK4819_REG_30_ENABLE_PA_GAIN | + BK4819_REG_30_DISABLE_MIC_ADC | + BK4819_REG_30_ENABLE_TX_DSP | + BK4819_REG_30_DISABLE_RX_DSP); } void BK4819_PlayDTMF(char Code) { - struct DTMF_TonePair { - uint16_t tone1; - uint16_t tone2; - }; + struct DTMF_TonePair { + uint16_t tone1; + uint16_t tone2; + }; - const struct DTMF_TonePair tones[] = { - {941, 1336}, - {697, 1209}, - {697, 1336}, - {697, 1477}, - {770, 1209}, - {770, 1336}, - {770, 1477}, - {852, 1209}, - {852, 1336}, - {852, 1477}, - {697, 1633}, - {770, 1633}, - {852, 1633}, - {941, 1633}, - {941, 1209}, - {941, 1477}, - }; + const struct DTMF_TonePair tones[] = { + {941, 1336}, + {697, 1209}, + {697, 1336}, + {697, 1477}, + {770, 1209}, + {770, 1336}, + {770, 1477}, + {852, 1209}, + {852, 1336}, + {852, 1477}, + {697, 1633}, + {770, 1633}, + {852, 1633}, + {941, 1633}, + {941, 1209}, + {941, 1477}, + }; - const struct DTMF_TonePair *pSelectedTone = NULL; - switch (Code) - { - case '0'...'9': pSelectedTone = &tones[0 + Code - '0']; break; - case 'A'...'D': pSelectedTone = &tones[10 + Code - 'A']; break; - case '*': pSelectedTone = &tones[14]; break; - case '#': pSelectedTone = &tones[15]; break; - default: pSelectedTone = NULL; - } + const struct DTMF_TonePair *pSelectedTone = NULL; + switch (Code) + { + case '0'...'9': pSelectedTone = &tones[0 + Code - '0']; break; + case 'A'...'D': pSelectedTone = &tones[10 + Code - 'A']; break; + case '*': pSelectedTone = &tones[14]; break; + case '#': pSelectedTone = &tones[15]; break; + default: pSelectedTone = NULL; + } - if (pSelectedTone) { - BK4819_WriteRegister(BK4819_REG_71, (((uint32_t)pSelectedTone->tone1 * 103244) + 5000) / 10000); // with rounding - BK4819_WriteRegister(BK4819_REG_72, (((uint32_t)pSelectedTone->tone2 * 103244) + 5000) / 10000); // with rounding - } + if (pSelectedTone) { + BK4819_WriteRegister(BK4819_REG_71, (((uint32_t)pSelectedTone->tone1 * 103244) + 5000) / 10000); // with rounding + BK4819_WriteRegister(BK4819_REG_72, (((uint32_t)pSelectedTone->tone2 * 103244) + 5000) / 10000); // with rounding + } } void BK4819_PlayDTMFString(const char *pString, bool bDelayFirst, uint16_t FirstCodePersistTime, uint16_t HashCodePersistTime, uint16_t CodePersistTime, uint16_t CodeInternalTime) { - unsigned int i; + unsigned int i; - if (pString == NULL) - return; + if (pString == NULL) + return; - for (i = 0; pString[i]; i++) - { - uint16_t Delay; - BK4819_PlayDTMF(pString[i]); - BK4819_ExitTxMute(); - if (bDelayFirst && i == 0) - Delay = FirstCodePersistTime; - else - if (pString[i] == '*' || pString[i] == '#') - Delay = HashCodePersistTime; - else - Delay = CodePersistTime; - SYSTEM_DelayMs(Delay); - BK4819_EnterTxMute(); - SYSTEM_DelayMs(CodeInternalTime); - } + for (i = 0; pString[i]; i++) + { + uint16_t Delay; + BK4819_PlayDTMF(pString[i]); + BK4819_ExitTxMute(); + if (bDelayFirst && i == 0) + Delay = FirstCodePersistTime; + else + if (pString[i] == '*' || pString[i] == '#') + Delay = HashCodePersistTime; + else + Delay = CodePersistTime; + SYSTEM_DelayMs(Delay); + BK4819_EnterTxMute(); + SYSTEM_DelayMs(CodeInternalTime); + } } void BK4819_TransmitTone(bool bLocalLoopback, uint32_t Frequency) { - BK4819_EnterTxMute(); + BK4819_EnterTxMute(); - // REG_70 - // - // <15> 0 Enable TONE1 - // 1 = Enable - // 0 = Disable - // - // <14:8> 0 TONE1 tuning gain - // 0 ~ 127 - // - // <7> 0 Enable TONE2 - // 1 = Enable - // 0 = Disable - // - // <6:0> 0 TONE2/FSK amplitude - // 0 ~ 127 - // - // set the tone amplitude - // - BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_MASK_ENABLE_TONE1 | (66u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN)); + // REG_70 + // + // <15> 0 Enable TONE1 + // 1 = Enable + // 0 = Disable + // + // <14:8> 0 TONE1 tuning gain + // 0 ~ 127 + // + // <7> 0 Enable TONE2 + // 1 = Enable + // 0 = Disable + // + // <6:0> 0 TONE2/FSK amplitude + // 0 ~ 127 + // + // set the tone amplitude + // + BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_MASK_ENABLE_TONE1 | (66u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN)); - BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency)); + BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency)); - BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE); + BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE); - BK4819_EnableTXLink(); + BK4819_EnableTXLink(); - SYSTEM_DelayMs(50); + SYSTEM_DelayMs(50); - BK4819_ExitTxMute(); + BK4819_ExitTxMute(); } void BK4819_GenTail(uint8_t Tail) { - // REG_52 - // - // <15> 0 Enable 120/180/240 degree shift CTCSS or 134.4Hz Tail when CDCSS mode - // 0 = Normal - // 1 = Enable - // - // <14:13> 0 CTCSS tail mode selection (only valid when REG_52 <15> = 1) - // 00 = for 134.4Hz CTCSS Tail when CDCSS mode - // 01 = CTCSS0 120° phase shift - // 10 = CTCSS0 180° phase shift - // 11 = CTCSS0 240° phase shift - // - // <12> 0 CTCSSDetectionThreshold Mode - // 1 = ~0.1% - // 0 = 0.1 Hz - // - // <11:6> 0x0A CTCSS found detect threshold - // - // <5:0> 0x0F CTCSS lost detect threshold + // REG_52 + // + // <15> 0 Enable 120/180/240 degree shift CTCSS or 134.4Hz Tail when CDCSS mode + // 0 = Normal + // 1 = Enable + // + // <14:13> 0 CTCSS tail mode selection (only valid when REG_52 <15> = 1) + // 00 = for 134.4Hz CTCSS Tail when CDCSS mode + // 01 = CTCSS0 120° phase shift + // 10 = CTCSS0 180° phase shift + // 11 = CTCSS0 240° phase shift + // + // <12> 0 CTCSSDetectionThreshold Mode + // 1 = ~0.1% + // 0 = 0.1 Hz + // + // <11:6> 0x0A CTCSS found detect threshold + // + // <5:0> 0x0F CTCSS lost detect threshold - // REG_07 <15:0> - // - // When <13> = 0 for CTC1 - // <12:0> = CTC1 frequency control word = - // freq(Hz) * 20.64888 for XTAL 13M/26M or - // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M - // - // When <13> = 1 for CTC2 (Tail 55Hz Rx detection) - // <12:0> = CTC2 (should below 100Hz) frequency control word = - // 25391 / freq(Hz) for XTAL 13M/26M or - // 25000 / freq(Hz) for XTAL 12.8M/19.2M/25.6M/38.4M - // - // When <13> = 2 for CDCSS 134.4Hz - // <12:0> = CDCSS baud rate frequency (134.4Hz) control word = - // freq(Hz) * 20.64888 for XTAL 13M/26M or - // freq(Hz)*20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M + // REG_07 <15:0> + // + // When <13> = 0 for CTC1 + // <12:0> = CTC1 frequency control word = + // freq(Hz) * 20.64888 for XTAL 13M/26M or + // freq(Hz) * 20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M + // + // When <13> = 1 for CTC2 (Tail 55Hz Rx detection) + // <12:0> = CTC2 (should below 100Hz) frequency control word = + // 25391 / freq(Hz) for XTAL 13M/26M or + // 25000 / freq(Hz) for XTAL 12.8M/19.2M/25.6M/38.4M + // + // When <13> = 2 for CDCSS 134.4Hz + // <12:0> = CDCSS baud rate frequency (134.4Hz) control word = + // freq(Hz) * 20.64888 for XTAL 13M/26M or + // freq(Hz)*20.97152 for XTAL 12.8M/19.2M/25.6M/38.4M - switch (Tail) - { - case 0: // 134.4Hz CTCSS Tail - BK4819_WriteRegister(BK4819_REG_52, 0x828F); // 1 00 0 001010 001111 - break; - case 1: // 120° phase shift - BK4819_WriteRegister(BK4819_REG_52, 0xA28F); // 1 01 0 001010 001111 - break; - case 2: // 180° phase shift - BK4819_WriteRegister(BK4819_REG_52, 0xC28F); // 1 10 0 001010 001111 - break; - case 3: // 240° phase shift - BK4819_WriteRegister(BK4819_REG_52, 0xE28F); // 1 11 0 001010 001111 - break; - case 4: // 55Hz tone freq - BK4819_WriteRegister(BK4819_REG_07, 0x046f); // 0 00 0 010001 101111 - break; - } + switch (Tail) + { + case 0: // 134.4Hz CTCSS Tail + BK4819_WriteRegister(BK4819_REG_52, 0x828F); // 1 00 0 001010 001111 + break; + case 1: // 120° phase shift + BK4819_WriteRegister(BK4819_REG_52, 0xA28F); // 1 01 0 001010 001111 + break; + case 2: // 180° phase shift + BK4819_WriteRegister(BK4819_REG_52, 0xC28F); // 1 10 0 001010 001111 + break; + case 3: // 240° phase shift + BK4819_WriteRegister(BK4819_REG_52, 0xE28F); // 1 11 0 001010 001111 + break; + case 4: // 55Hz tone freq + BK4819_WriteRegister(BK4819_REG_07, 0x046f); // 0 00 0 010001 101111 + break; + } } void BK4819_PlayCDCSSTail(void) { - BK4819_GenTail(0); // CTC134 - BK4819_WriteRegister(BK4819_REG_51, 0x804A); // 1 0 0 0 0 0 0 0 0 1001010 + BK4819_GenTail(0); // CTC134 + BK4819_WriteRegister(BK4819_REG_51, 0x804A); // 1 0 0 0 0 0 0 0 0 1001010 } void BK4819_PlayCTCSSTail(void) { - #ifdef ENABLE_CTCSS_TAIL_PHASE_SHIFT - BK4819_GenTail(2); // 180° phase shift - #else - BK4819_GenTail(4); // 55Hz tone freq - #endif + #ifdef ENABLE_CTCSS_TAIL_PHASE_SHIFT + BK4819_GenTail(2); // 180° phase shift + #else + BK4819_GenTail(4); // 55Hz tone freq + #endif - // REG_51 - // - // <15> 0 - // 1 = Enable TxCTCSS/CDCSS - // 0 = Disable - // - // <14> 0 - // 1 = GPIO0Input for CDCSS - // 0 = Normal Mode (for BK4819 v3) - // - // <13> 0 - // 1 = Transmit negative CDCSS code - // 0 = Transmit positive CDCSS code - // - // <12> 0 CTCSS/CDCSS mode selection - // 1 = CTCSS - // 0 = CDCSS - // - // <11> 0 CDCSS 24/23bit selection - // 1 = 24bit - // 0 = 23bit - // - // <10> 0 1050HzDetectionMode - // 1 = 1050/4 Detect Enable, CTC1 should be set to 1050/4 Hz - // - // <9> 0 Auto CDCSS Bw Mode - // 1 = Disable - // 0 = Enable - // - // <8> 0 Auto CTCSS Bw Mode - // 0 = Enable - // 1 = Disable - // - // <6:0> 0 CTCSS/CDCSS Tx Gain1 Tuning - // 0 = min - // 127 = max + // REG_51 + // + // <15> 0 + // 1 = Enable TxCTCSS/CDCSS + // 0 = Disable + // + // <14> 0 + // 1 = GPIO0Input for CDCSS + // 0 = Normal Mode (for BK4819 v3) + // + // <13> 0 + // 1 = Transmit negative CDCSS code + // 0 = Transmit positive CDCSS code + // + // <12> 0 CTCSS/CDCSS mode selection + // 1 = CTCSS + // 0 = CDCSS + // + // <11> 0 CDCSS 24/23bit selection + // 1 = 24bit + // 0 = 23bit + // + // <10> 0 1050HzDetectionMode + // 1 = 1050/4 Detect Enable, CTC1 should be set to 1050/4 Hz + // + // <9> 0 Auto CDCSS Bw Mode + // 1 = Disable + // 0 = Enable + // + // <8> 0 Auto CTCSS Bw Mode + // 0 = Enable + // 1 = Disable + // + // <6:0> 0 CTCSS/CDCSS Tx Gain1 Tuning + // 0 = min + // 127 = max - BK4819_WriteRegister(BK4819_REG_51, 0x904A); // 1 0 0 1 0 0 0 0 0 1001010 + BK4819_WriteRegister(BK4819_REG_51, 0x904A); // 1 0 0 1 0 0 0 0 0 1001010 } uint16_t BK4819_GetRSSI(void) { - return BK4819_ReadRegister(BK4819_REG_67) & 0x01FF; + return BK4819_ReadRegister(BK4819_REG_67) & 0x01FF; } uint8_t BK4819_GetGlitchIndicator(void) { - return BK4819_ReadRegister(BK4819_REG_63) & 0x00FF; + return BK4819_ReadRegister(BK4819_REG_63) & 0x00FF; } uint8_t BK4819_GetExNoiceIndicator(void) { - return BK4819_ReadRegister(BK4819_REG_65) & 0x007F; + return BK4819_ReadRegister(BK4819_REG_65) & 0x007F; } uint16_t BK4819_GetVoiceAmplitudeOut(void) { - return BK4819_ReadRegister(BK4819_REG_64); + return BK4819_ReadRegister(BK4819_REG_64); } uint8_t BK4819_GetAfTxRx(void) { - return BK4819_ReadRegister(BK4819_REG_6F) & 0x003F; + return BK4819_ReadRegister(BK4819_REG_6F) & 0x003F; } bool BK4819_GetFrequencyScanResult(uint32_t *pFrequency) { - const uint16_t High = BK4819_ReadRegister(BK4819_REG_0D); - const bool Finished = (High & 0x8000) == 0; - if (Finished) - { - const uint16_t Low = BK4819_ReadRegister(BK4819_REG_0E); - *pFrequency = (uint32_t)((High & 0x7FF) << 16) | Low; - } - return Finished; + const uint16_t High = BK4819_ReadRegister(BK4819_REG_0D); + const bool Finished = (High & 0x8000) == 0; + if (Finished) + { + const uint16_t Low = BK4819_ReadRegister(BK4819_REG_0E); + *pFrequency = (uint32_t)((High & 0x7FF) << 16) | Low; + } + return Finished; } BK4819_CssScanResult_t BK4819_GetCxCSSScanResult(uint32_t *pCdcssFreq, uint16_t *pCtcssFreq) { - uint16_t Low; - uint16_t High = BK4819_ReadRegister(BK4819_REG_69); + uint16_t Low; + uint16_t High = BK4819_ReadRegister(BK4819_REG_69); - if ((High & 0x8000) == 0) - { - Low = BK4819_ReadRegister(BK4819_REG_6A); - *pCdcssFreq = ((High & 0xFFF) << 12) | (Low & 0xFFF); - return BK4819_CSS_RESULT_CDCSS; - } + if ((High & 0x8000) == 0) + { + Low = BK4819_ReadRegister(BK4819_REG_6A); + *pCdcssFreq = ((High & 0xFFF) << 12) | (Low & 0xFFF); + return BK4819_CSS_RESULT_CDCSS; + } - Low = BK4819_ReadRegister(BK4819_REG_68); + Low = BK4819_ReadRegister(BK4819_REG_68); - if ((Low & 0x8000) == 0) - { - *pCtcssFreq = ((Low & 0x1FFF) * 4843) / 10000; - return BK4819_CSS_RESULT_CTCSS; - } + if ((Low & 0x8000) == 0) + { + *pCtcssFreq = ((Low & 0x1FFF) * 4843) / 10000; + return BK4819_CSS_RESULT_CTCSS; + } - return BK4819_CSS_RESULT_NOT_FOUND; + return BK4819_CSS_RESULT_NOT_FOUND; } void BK4819_DisableFrequencyScan(void) { - // REG_32 - // - // <15:14> 0 frequency scan time - // 0 = 0.2 sec - // 1 = 0.4 sec - // 2 = 0.8 sec - // 3 = 1.6 sec - // - // <13:1> ??? - // - // <0> 0 frequency scan enable - // 1 = enable - // 0 = disable - // - BK4819_WriteRegister(BK4819_REG_32, // 0x0244); // 00 0000100100010 0 - ( 0u << 14) | // 0 frequency scan Time - (290u << 1) | // ??? - ( 0u << 0)); // 0 frequency scan enable + // REG_32 + // + // <15:14> 0 frequency scan time + // 0 = 0.2 sec + // 1 = 0.4 sec + // 2 = 0.8 sec + // 3 = 1.6 sec + // + // <13:1> ??? + // + // <0> 0 frequency scan enable + // 1 = enable + // 0 = disable + // + BK4819_WriteRegister(BK4819_REG_32, // 0x0244); // 00 0000100100010 0 + ( 0u << 14) | // 0 frequency scan Time + (290u << 1) | // ??? + ( 0u << 0)); // 0 frequency scan enable } void BK4819_EnableFrequencyScan(void) { - // REG_32 - // - // <15:14> 0 frequency scan time - // 0 = 0.2 sec - // 1 = 0.4 sec - // 2 = 0.8 sec - // 3 = 1.6 sec - // - // <13:1> ??? - // - // <0> 0 frequency scan enable - // 1 = enable - // 0 = disable - // - BK4819_WriteRegister(BK4819_REG_32, // 0x0245); // 00 0000100100010 1 - ( 0u << 14) | // 0 frequency scan time - (290u << 1) | // ??? - ( 1u << 0)); // 1 frequency scan enable + // REG_32 + // + // <15:14> 0 frequency scan time + // 0 = 0.2 sec + // 1 = 0.4 sec + // 2 = 0.8 sec + // 3 = 1.6 sec + // + // <13:1> ??? + // + // <0> 0 frequency scan enable + // 1 = enable + // 0 = disable + // + BK4819_WriteRegister(BK4819_REG_32, // 0x0245); // 00 0000100100010 1 + ( 0u << 14) | // 0 frequency scan time + (290u << 1) | // ??? + ( 1u << 0)); // 1 frequency scan enable } void BK4819_SetScanFrequency(uint32_t Frequency) { - BK4819_SetFrequency(Frequency); + BK4819_SetFrequency(Frequency); - // REG_51 - // - // <15> 0 - // 1 = Enable TxCTCSS/CDCSS - // 0 = Disable - // - // <14> 0 - // 1 = GPIO0Input for CDCSS - // 0 = Normal Mode (for BK4819 v3) - // - // <13> 0 - // 1 = Transmit negative CDCSS code - // 0 = Transmit positive CDCSS code - // - // <12> 0 CTCSS/CDCSS mode selection - // 1 = CTCSS - // 0 = CDCSS - // - // <11> 0 CDCSS 24/23bit selection - // 1 = 24bit - // 0 = 23bit - // - // <10> 0 1050HzDetectionMode - // 1 = 1050/4 Detect Enable, CTC1 should be set to 1050/4 Hz - // - // <9> 0 Auto CDCSS Bw Mode - // 1 = Disable - // 0 = Enable - // - // <8> 0 Auto CTCSS Bw Mode - // 0 = Enable - // 1 = Disable - // - // <6:0> 0 CTCSS/CDCSS Tx Gain1 Tuning - // 0 = min - // 127 = max - // - BK4819_WriteRegister(BK4819_REG_51, - BK4819_REG_51_DISABLE_CxCSS | - BK4819_REG_51_GPIO6_PIN2_NORMAL | - BK4819_REG_51_TX_CDCSS_POSITIVE | - BK4819_REG_51_MODE_CDCSS | - BK4819_REG_51_CDCSS_23_BIT | - BK4819_REG_51_1050HZ_NO_DETECTION | - BK4819_REG_51_AUTO_CDCSS_BW_DISABLE | - BK4819_REG_51_AUTO_CTCSS_BW_DISABLE); + // REG_51 + // + // <15> 0 + // 1 = Enable TxCTCSS/CDCSS + // 0 = Disable + // + // <14> 0 + // 1 = GPIO0Input for CDCSS + // 0 = Normal Mode (for BK4819 v3) + // + // <13> 0 + // 1 = Transmit negative CDCSS code + // 0 = Transmit positive CDCSS code + // + // <12> 0 CTCSS/CDCSS mode selection + // 1 = CTCSS + // 0 = CDCSS + // + // <11> 0 CDCSS 24/23bit selection + // 1 = 24bit + // 0 = 23bit + // + // <10> 0 1050HzDetectionMode + // 1 = 1050/4 Detect Enable, CTC1 should be set to 1050/4 Hz + // + // <9> 0 Auto CDCSS Bw Mode + // 1 = Disable + // 0 = Enable + // + // <8> 0 Auto CTCSS Bw Mode + // 0 = Enable + // 1 = Disable + // + // <6:0> 0 CTCSS/CDCSS Tx Gain1 Tuning + // 0 = min + // 127 = max + // + BK4819_WriteRegister(BK4819_REG_51, + BK4819_REG_51_DISABLE_CxCSS | + BK4819_REG_51_GPIO6_PIN2_NORMAL | + BK4819_REG_51_TX_CDCSS_POSITIVE | + BK4819_REG_51_MODE_CDCSS | + BK4819_REG_51_CDCSS_23_BIT | + BK4819_REG_51_1050HZ_NO_DETECTION | + BK4819_REG_51_AUTO_CDCSS_BW_DISABLE | + BK4819_REG_51_AUTO_CTCSS_BW_DISABLE); - BK4819_RX_TurnOn(); + BK4819_RX_TurnOn(); } void BK4819_Disable(void) { - BK4819_WriteRegister(BK4819_REG_30, 0); + BK4819_WriteRegister(BK4819_REG_30, 0); } void BK4819_StopScan(void) { - BK4819_DisableFrequencyScan(); - BK4819_Disable(); + BK4819_DisableFrequencyScan(); + BK4819_Disable(); } uint8_t BK4819_GetDTMF_5TONE_Code(void) { - return (BK4819_ReadRegister(BK4819_REG_0B) >> 8) & 0x0F; + return (BK4819_ReadRegister(BK4819_REG_0B) >> 8) & 0x0F; } uint8_t BK4819_GetCDCSSCodeType(void) { - return (BK4819_ReadRegister(BK4819_REG_0C) >> 14) & 3u; + return (BK4819_ReadRegister(BK4819_REG_0C) >> 14) & 3u; } uint8_t BK4819_GetCTCShift(void) { - return (BK4819_ReadRegister(BK4819_REG_0C) >> 12) & 3u; + return (BK4819_ReadRegister(BK4819_REG_0C) >> 12) & 3u; } uint8_t BK4819_GetCTCType(void) { - return (BK4819_ReadRegister(BK4819_REG_0C) >> 10) & 3u; + return (BK4819_ReadRegister(BK4819_REG_0C) >> 10) & 3u; } void BK4819_SendFSKData(uint16_t *pData) { - unsigned int i; - uint8_t Timeout = 200; + unsigned int i; + uint8_t Timeout = 200; - SYSTEM_DelayMs(20); + SYSTEM_DelayMs(20); - BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_TX_FINISHED); - BK4819_WriteRegister(BK4819_REG_59, 0x8068); - BK4819_WriteRegister(BK4819_REG_59, 0x0068); + BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_TX_FINISHED); + BK4819_WriteRegister(BK4819_REG_59, 0x8068); + BK4819_WriteRegister(BK4819_REG_59, 0x0068); - for (i = 0; i < 36; i++) - BK4819_WriteRegister(BK4819_REG_5F, pData[i]); + for (i = 0; i < 36; i++) + BK4819_WriteRegister(BK4819_REG_5F, pData[i]); - SYSTEM_DelayMs(20); + SYSTEM_DelayMs(20); - BK4819_WriteRegister(BK4819_REG_59, 0x2868); + BK4819_WriteRegister(BK4819_REG_59, 0x2868); - while (Timeout-- && (BK4819_ReadRegister(BK4819_REG_0C) & 1u) == 0) - SYSTEM_DelayMs(5); + while (Timeout-- && (BK4819_ReadRegister(BK4819_REG_0C) & 1u) == 0) + SYSTEM_DelayMs(5); - BK4819_WriteRegister(BK4819_REG_02, 0); + BK4819_WriteRegister(BK4819_REG_02, 0); - SYSTEM_DelayMs(20); + SYSTEM_DelayMs(20); - BK4819_ResetFSK(); + BK4819_ResetFSK(); } void BK4819_PrepareFSKReceive(void) { - BK4819_ResetFSK(); - BK4819_WriteRegister(BK4819_REG_02, 0); - BK4819_WriteRegister(BK4819_REG_3F, 0); - BK4819_RX_TurnOn(); - BK4819_WriteRegister(BK4819_REG_3F, 0 | BK4819_REG_3F_FSK_RX_FINISHED | BK4819_REG_3F_FSK_FIFO_ALMOST_FULL); + BK4819_ResetFSK(); + BK4819_WriteRegister(BK4819_REG_02, 0); + BK4819_WriteRegister(BK4819_REG_3F, 0); + BK4819_RX_TurnOn(); + BK4819_WriteRegister(BK4819_REG_3F, 0 | BK4819_REG_3F_FSK_RX_FINISHED | BK4819_REG_3F_FSK_FIFO_ALMOST_FULL); - // Clear RX FIFO - // FSK Preamble Length 7 bytes - // FSK SyncLength Selection - BK4819_WriteRegister(BK4819_REG_59, 0x4068); + // Clear RX FIFO + // FSK Preamble Length 7 bytes + // FSK SyncLength Selection + BK4819_WriteRegister(BK4819_REG_59, 0x4068); - // Enable FSK Scramble - // Enable FSK RX - // FSK Preamble Length 7 bytes - // FSK SyncLength Selection - BK4819_WriteRegister(BK4819_REG_59, 0x3068); + // Enable FSK Scramble + // Enable FSK RX + // FSK Preamble Length 7 bytes + // FSK SyncLength Selection + BK4819_WriteRegister(BK4819_REG_59, 0x3068); } static void BK4819_PlayRogerNormal(void) { - #if 0 - const uint32_t tone1_Hz = 500; - const uint32_t tone2_Hz = 700; - #else - // motorola type - const uint32_t tone1_Hz = 1540; - const uint32_t tone2_Hz = 1310; - #endif + #if 0 + const uint32_t tone1_Hz = 500; + const uint32_t tone2_Hz = 700; + #else + // motorola type + const uint32_t tone1_Hz = 1540; + const uint32_t tone2_Hz = 1310; + #endif - BK4819_EnterTxMute(); - BK4819_SetAF(BK4819_AF_MUTE); + BK4819_EnterTxMute(); + BK4819_SetAF(BK4819_AF_MUTE); - BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (66u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN)); + BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (66u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN)); - BK4819_EnableTXLink(); - SYSTEM_DelayMs(50); + BK4819_EnableTXLink(); + SYSTEM_DelayMs(50); - BK4819_WriteRegister(BK4819_REG_71, scale_freq(tone1_Hz)); + BK4819_WriteRegister(BK4819_REG_71, scale_freq(tone1_Hz)); - BK4819_ExitTxMute(); - SYSTEM_DelayMs(80); - BK4819_EnterTxMute(); + BK4819_ExitTxMute(); + SYSTEM_DelayMs(80); + BK4819_EnterTxMute(); - BK4819_WriteRegister(BK4819_REG_71, scale_freq(tone2_Hz)); + BK4819_WriteRegister(BK4819_REG_71, scale_freq(tone2_Hz)); - BK4819_ExitTxMute(); - SYSTEM_DelayMs(80); - BK4819_EnterTxMute(); + BK4819_ExitTxMute(); + SYSTEM_DelayMs(80); + BK4819_EnterTxMute(); - BK4819_WriteRegister(BK4819_REG_70, 0x0000); - BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); // 1 1 0000 0 1 1111 1 1 1 0 + BK4819_WriteRegister(BK4819_REG_70, 0x0000); + BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); // 1 1 0000 0 1 1111 1 1 1 0 } void BK4819_PlayRogerMDC(void) { - struct reg_value { - BK4819_REGISTER_t reg; - uint16_t value; - }; + struct reg_value { + BK4819_REGISTER_t reg; + uint16_t value; + }; - struct reg_value RogerMDC_Configuration [] = { - { BK4819_REG_58, 0x37C3 }, // FSK Enable, - // RX Bandwidth FFSK 1200/1800 - // 0xAA or 0x55 Preamble - // 11 RX Gain, - // 101 RX Mode - // TX FFSK 1200/1800 - { BK4819_REG_72, 0x3065 }, // Set Tone-2 to 1200Hz - { BK4819_REG_70, 0x00E0 }, // Enable Tone-2 and Set Tone2 Gain - { BK4819_REG_5D, 0x0D00 }, // Set FSK data length to 13 bytes - { BK4819_REG_59, 0x8068 }, // 4 byte sync length, 6 byte preamble, clear TX FIFO - { BK4819_REG_59, 0x0068 }, // Same, but clear TX FIFO is now unset (clearing done) - { BK4819_REG_5A, 0x5555 }, // First two sync bytes - { BK4819_REG_5B, 0x55AA }, // End of sync bytes. Total 4 bytes: 555555aa - { BK4819_REG_5C, 0xAA30 }, // Disable CRC - }; + struct reg_value RogerMDC_Configuration [] = { + { BK4819_REG_58, 0x37C3 }, // FSK Enable, + // RX Bandwidth FFSK 1200/1800 + // 0xAA or 0x55 Preamble + // 11 RX Gain, + // 101 RX Mode + // TX FFSK 1200/1800 + { BK4819_REG_72, 0x3065 }, // Set Tone-2 to 1200Hz + { BK4819_REG_70, 0x00E0 }, // Enable Tone-2 and Set Tone2 Gain + { BK4819_REG_5D, 0x0D00 }, // Set FSK data length to 13 bytes + { BK4819_REG_59, 0x8068 }, // 4 byte sync length, 6 byte preamble, clear TX FIFO + { BK4819_REG_59, 0x0068 }, // Same, but clear TX FIFO is now unset (clearing done) + { BK4819_REG_5A, 0x5555 }, // First two sync bytes + { BK4819_REG_5B, 0x55AA }, // End of sync bytes. Total 4 bytes: 555555aa + { BK4819_REG_5C, 0xAA30 }, // Disable CRC + }; - BK4819_SetAF(BK4819_AF_MUTE); + BK4819_SetAF(BK4819_AF_MUTE); - for (unsigned int i = 0; i < ARRAY_SIZE(RogerMDC_Configuration); i++) { - BK4819_WriteRegister(RogerMDC_Configuration[i].reg, RogerMDC_Configuration[i].value); - } + for (unsigned int i = 0; i < ARRAY_SIZE(RogerMDC_Configuration); i++) { + BK4819_WriteRegister(RogerMDC_Configuration[i].reg, RogerMDC_Configuration[i].value); + } - // Send the data from the roger table - for (unsigned int i = 0; i < ARRAY_SIZE(FSK_RogerTable); i++) { - BK4819_WriteRegister(BK4819_REG_5F, FSK_RogerTable[i]); - } + // Send the data from the roger table + for (unsigned int i = 0; i < ARRAY_SIZE(FSK_RogerTable); i++) { + BK4819_WriteRegister(BK4819_REG_5F, FSK_RogerTable[i]); + } - SYSTEM_DelayMs(20); + SYSTEM_DelayMs(20); - // 4 sync bytes, 6 byte preamble, Enable FSK TX - BK4819_WriteRegister(BK4819_REG_59, 0x0868); + // 4 sync bytes, 6 byte preamble, Enable FSK TX + BK4819_WriteRegister(BK4819_REG_59, 0x0868); - SYSTEM_DelayMs(180); + SYSTEM_DelayMs(180); - // Stop FSK TX, reset Tone-2, disable FSK - BK4819_WriteRegister(BK4819_REG_59, 0x0068); - BK4819_WriteRegister(BK4819_REG_70, 0x0000); - BK4819_WriteRegister(BK4819_REG_58, 0x0000); + // Stop FSK TX, reset Tone-2, disable FSK + BK4819_WriteRegister(BK4819_REG_59, 0x0068); + BK4819_WriteRegister(BK4819_REG_70, 0x0000); + BK4819_WriteRegister(BK4819_REG_58, 0x0000); } void BK4819_PlayRoger(void) { - if (gEeprom.ROGER == ROGER_MODE_ROGER) { - BK4819_PlayRogerNormal(); - } else if (gEeprom.ROGER == ROGER_MODE_MDC) { - BK4819_PlayRogerMDC(); - } + if (gEeprom.ROGER == ROGER_MODE_ROGER) { + BK4819_PlayRogerNormal(); + } else if (gEeprom.ROGER == ROGER_MODE_MDC) { + BK4819_PlayRogerMDC(); + } } void BK4819_Enable_AfDac_DiscMode_TxDsp(void) { - BK4819_WriteRegister(BK4819_REG_30, 0x0000); - BK4819_WriteRegister(BK4819_REG_30, 0x0302); + BK4819_WriteRegister(BK4819_REG_30, 0x0000); + BK4819_WriteRegister(BK4819_REG_30, 0x0302); } void BK4819_GetVoxAmp(uint16_t *pResult) { - *pResult = BK4819_ReadRegister(BK4819_REG_64) & 0x7FFF; + *pResult = BK4819_ReadRegister(BK4819_REG_64) & 0x7FFF; } void BK4819_SetScrambleFrequencyControlWord(uint32_t Frequency) { - BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency)); + BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency)); } void BK4819_PlayDTMFEx(bool bLocalLoopback, char Code) { - BK4819_EnableDTMF(); - BK4819_EnterTxMute(); + BK4819_EnableDTMF(); + BK4819_EnterTxMute(); - BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE); + BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE); - BK4819_WriteRegister(BK4819_REG_70, - BK4819_REG_70_MASK_ENABLE_TONE1 | - (DTMF_TONE1_GAIN << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) | - BK4819_REG_70_MASK_ENABLE_TONE2 | - (DTMF_TONE2_GAIN << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN)); + BK4819_WriteRegister(BK4819_REG_70, + BK4819_REG_70_MASK_ENABLE_TONE1 | + (DTMF_TONE1_GAIN << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) | + BK4819_REG_70_MASK_ENABLE_TONE2 | + (DTMF_TONE2_GAIN << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN)); - BK4819_EnableTXLink(); + BK4819_EnableTXLink(); - SYSTEM_DelayMs(50); + SYSTEM_DelayMs(50); - BK4819_PlayDTMF(Code); + BK4819_PlayDTMF(Code); - BK4819_ExitTxMute(); + BK4819_ExitTxMute(); } diff --git a/driver/bk4819.h b/driver/bk4819.h index 1a6d06e..b700377 100644 --- a/driver/bk4819.h +++ b/driver/bk4819.h @@ -24,40 +24,40 @@ enum BK4819_AF_Type_t { - BK4819_AF_MUTE = 0u, // - BK4819_AF_FM = 1u, // FM - BK4819_AF_ALAM = 2u, // - BK4819_AF_BEEP = 3u, // - BK4819_AF_BASEBAND1 = 4u, // RAW - BK4819_AF_BASEBAND2 = 5u, // USB - BK4819_AF_CTCO = 6u, // strange LF audio .. maybe the CTCSS LF line ? - BK4819_AF_AM = 7u, // AM - BK4819_AF_FSKO = 8u, // nothing - BK4819_AF_UNKNOWN3 = 9u, // BYP - BK4819_AF_UNKNOWN4 = 10u, // nothing at all - BK4819_AF_UNKNOWN5 = 11u, // distorted - BK4819_AF_UNKNOWN6 = 12u, // distorted - BK4819_AF_UNKNOWN7 = 13u, // interesting - BK4819_AF_UNKNOWN8 = 14u, // interesting - BK4819_AF_UNKNOWN9 = 15u // not a lot + BK4819_AF_MUTE = 0u, // + BK4819_AF_FM = 1u, // FM + BK4819_AF_ALAM = 2u, // + BK4819_AF_BEEP = 3u, // + BK4819_AF_BASEBAND1 = 4u, // RAW + BK4819_AF_BASEBAND2 = 5u, // USB + BK4819_AF_CTCO = 6u, // strange LF audio .. maybe the CTCSS LF line ? + BK4819_AF_AM = 7u, // AM + BK4819_AF_FSKO = 8u, // nothing + BK4819_AF_UNKNOWN3 = 9u, // BYP + BK4819_AF_UNKNOWN4 = 10u, // nothing at all + BK4819_AF_UNKNOWN5 = 11u, // distorted + BK4819_AF_UNKNOWN6 = 12u, // distorted + BK4819_AF_UNKNOWN7 = 13u, // interesting + BK4819_AF_UNKNOWN8 = 14u, // interesting + BK4819_AF_UNKNOWN9 = 15u // not a lot }; typedef enum BK4819_AF_Type_t BK4819_AF_Type_t; enum BK4819_FilterBandwidth_t { - BK4819_FILTER_BW_WIDE = 0, - BK4819_FILTER_BW_NARROW, - BK4819_FILTER_BW_NARROWER + BK4819_FILTER_BW_WIDE = 0, + BK4819_FILTER_BW_NARROW, + BK4819_FILTER_BW_NARROWER }; typedef enum BK4819_FilterBandwidth_t BK4819_FilterBandwidth_t; enum BK4819_CssScanResult_t { - BK4819_CSS_RESULT_NOT_FOUND = 0, - BK4819_CSS_RESULT_CTCSS, - BK4819_CSS_RESULT_CDCSS + BK4819_CSS_RESULT_NOT_FOUND = 0, + BK4819_CSS_RESULT_CTCSS, + BK4819_CSS_RESULT_CDCSS }; typedef enum BK4819_CssScanResult_t BK4819_CssScanResult_t; @@ -85,12 +85,12 @@ void BK4819_SetFilterBandwidth(const BK4819_FilterBandwidth_t Bandwidth, con void BK4819_SetupPowerAmplifier(const uint8_t bias, const uint32_t frequency); void BK4819_SetFrequency(uint32_t Frequency); void BK4819_SetupSquelch( - uint8_t SquelchOpenRSSIThresh, - uint8_t SquelchCloseRSSIThresh, - uint8_t SquelchOpenNoiseThresh, - uint8_t SquelchCloseNoiseThresh, - uint8_t SquelchCloseGlitchThresh, - uint8_t SquelchOpenGlitchThresh); + uint8_t SquelchOpenRSSIThresh, + uint8_t SquelchCloseRSSIThresh, + uint8_t SquelchOpenNoiseThresh, + uint8_t SquelchCloseNoiseThresh, + uint8_t SquelchCloseGlitchThresh, + uint8_t SquelchOpenGlitchThresh); void BK4819_SetAF(BK4819_AF_Type_t AF); void BK4819_RX_TurnOn(void); @@ -111,7 +111,7 @@ void BK4819_ExitTxMute(void); void BK4819_Sleep(void); void BK4819_TurnsOffTones_TurnsOnRX(void); #ifdef ENABLE_AIRCOPY - void BK4819_SetupAircopy(void); + void BK4819_SetupAircopy(void); #endif void BK4819_ResetFSK(void); void BK4819_Idle(void); diff --git a/driver/crc.c b/driver/crc.c index 6acb966..d3fd2af 100644 --- a/driver/crc.c +++ b/driver/crc.c @@ -19,31 +19,31 @@ void CRC_Init(void) { - CRC_CR = 0 - | CRC_CR_CRC_EN_BITS_DISABLE - | CRC_CR_INPUT_REV_BITS_NORMAL - | CRC_CR_INPUT_INV_BITS_NORMAL - | CRC_CR_OUTPUT_REV_BITS_NORMAL - | CRC_CR_OUTPUT_INV_BITS_NORMAL - | CRC_CR_DATA_WIDTH_BITS_8 - | CRC_CR_CRC_SEL_BITS_CRC_16_CCITT - ; - CRC_IV = 0; + CRC_CR = 0 + | CRC_CR_CRC_EN_BITS_DISABLE + | CRC_CR_INPUT_REV_BITS_NORMAL + | CRC_CR_INPUT_INV_BITS_NORMAL + | CRC_CR_OUTPUT_REV_BITS_NORMAL + | CRC_CR_OUTPUT_INV_BITS_NORMAL + | CRC_CR_DATA_WIDTH_BITS_8 + | CRC_CR_CRC_SEL_BITS_CRC_16_CCITT + ; + CRC_IV = 0; } uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size) { - const uint8_t *pData = (const uint8_t *)pBuffer; - uint16_t i, Crc; + const uint8_t *pData = (const uint8_t *)pBuffer; + uint16_t i, Crc; - CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_ENABLE; + CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_ENABLE; - for (i = 0; i < Size; i++) { - CRC_DATAIN = pData[i]; - } - Crc = (uint16_t)CRC_DATAOUT; + for (i = 0; i < Size; i++) { + CRC_DATAIN = pData[i]; + } + Crc = (uint16_t)CRC_DATAOUT; - CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_DISABLE; + CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_DISABLE; - return Crc; + return Crc; } diff --git a/driver/eeprom.c b/driver/eeprom.c index 07cca2e..4357f65 100644 --- a/driver/eeprom.c +++ b/driver/eeprom.c @@ -23,41 +23,41 @@ void EEPROM_ReadBuffer(uint16_t Address, void *pBuffer, uint8_t Size) { - I2C_Start(); + I2C_Start(); - I2C_Write(0xA0); + I2C_Write(0xA0); - I2C_Write((Address >> 8) & 0xFF); - I2C_Write((Address >> 0) & 0xFF); + I2C_Write((Address >> 8) & 0xFF); + I2C_Write((Address >> 0) & 0xFF); - I2C_Start(); + I2C_Start(); - I2C_Write(0xA1); + I2C_Write(0xA1); - I2C_ReadBuffer(pBuffer, Size); + I2C_ReadBuffer(pBuffer, Size); - I2C_Stop(); + I2C_Stop(); } void EEPROM_WriteBuffer(uint16_t Address, const void *pBuffer) { - if (pBuffer == NULL || Address >= 0x2000) - return; + if (pBuffer == NULL || Address >= 0x2000) + return; - uint8_t buffer[8]; - EEPROM_ReadBuffer(Address, buffer, 8); - if (memcmp(pBuffer, buffer, 8) == 0) { - return; - } + uint8_t buffer[8]; + EEPROM_ReadBuffer(Address, buffer, 8); + if (memcmp(pBuffer, buffer, 8) == 0) { + return; + } - I2C_Start(); - I2C_Write(0xA0); - I2C_Write((Address >> 8) & 0xFF); - I2C_Write((Address >> 0) & 0xFF); - I2C_WriteBuffer(pBuffer, 8); - I2C_Stop(); + I2C_Start(); + I2C_Write(0xA0); + I2C_Write((Address >> 8) & 0xFF); + I2C_Write((Address >> 0) & 0xFF); + I2C_WriteBuffer(pBuffer, 8); + I2C_Stop(); - // give the EEPROM time to burn the data in (apparently takes 5ms) - SYSTEM_DelayMs(8); + // give the EEPROM time to burn the data in (apparently takes 5ms) + SYSTEM_DelayMs(8); } diff --git a/driver/flash.c b/driver/flash.c index aa4116d..8f0cf66 100644 --- a/driver/flash.c +++ b/driver/flash.c @@ -19,15 +19,15 @@ void FLASH_Init(FLASH_READ_MODE ReadMode) { - overlay_FLASH_Init(ReadMode); + overlay_FLASH_Init(ReadMode); } void FLASH_ConfigureTrimValues(void) { - overlay_FLASH_ConfigureTrimValues(); + overlay_FLASH_ConfigureTrimValues(); } uint32_t FLASH_ReadNvrWord(uint32_t Address) { - return overlay_FLASH_ReadNvrWord(Address); + return overlay_FLASH_ReadNvrWord(Address); } diff --git a/driver/flash.h b/driver/flash.h index 7947163..b827c4c 100644 --- a/driver/flash.h +++ b/driver/flash.h @@ -20,33 +20,33 @@ #include "bsp/dp32g030/flash.h" enum FLASH_READ_MODE { - FLASH_READ_MODE_1_CYCLE = FLASH_CFG_READ_MD_VALUE_1_CYCLE, - FLASH_READ_MODE_2_CYCLE = FLASH_CFG_READ_MD_VALUE_2_CYCLE, + FLASH_READ_MODE_1_CYCLE = FLASH_CFG_READ_MD_VALUE_1_CYCLE, + FLASH_READ_MODE_2_CYCLE = FLASH_CFG_READ_MD_VALUE_2_CYCLE, }; typedef enum FLASH_READ_MODE FLASH_READ_MODE; enum FLASH_MASK_SELECTION { - FLASH_MASK_SELECTION_NONE = FLASH_MASK_SEL_VALUE_NONE, - FLASH_MASK_SELECTION_2KB = FLASH_MASK_SEL_VALUE_2KB, - FLASH_MASK_SELECTION_4KB = FLASH_MASK_SEL_VALUE_4KB, - FLASH_MASK_SELECTION_8KB = FLASH_MASK_SEL_VALUE_8KB, + FLASH_MASK_SELECTION_NONE = FLASH_MASK_SEL_VALUE_NONE, + FLASH_MASK_SELECTION_2KB = FLASH_MASK_SEL_VALUE_2KB, + FLASH_MASK_SELECTION_4KB = FLASH_MASK_SEL_VALUE_4KB, + FLASH_MASK_SELECTION_8KB = FLASH_MASK_SEL_VALUE_8KB, }; typedef enum FLASH_MASK_SELECTION FLASH_MASK_SELECTION; enum FLASH_MODE { - FLASH_MODE_READ_AHB = FLASH_CFG_MODE_VALUE_READ_AHB, - FLASH_MODE_PROGRAM = FLASH_CFG_MODE_VALUE_PROGRAM, - FLASH_MODE_ERASE = FLASH_CFG_MODE_VALUE_ERASE, - FLASH_MODE_READ_APB = FLASH_CFG_MODE_VALUE_READ_APB, + FLASH_MODE_READ_AHB = FLASH_CFG_MODE_VALUE_READ_AHB, + FLASH_MODE_PROGRAM = FLASH_CFG_MODE_VALUE_PROGRAM, + FLASH_MODE_ERASE = FLASH_CFG_MODE_VALUE_ERASE, + FLASH_MODE_READ_APB = FLASH_CFG_MODE_VALUE_READ_APB, }; typedef enum FLASH_MODE FLASH_MODE; enum FLASH_AREA { - FLASH_AREA_MAIN = FLASH_CFG_NVR_SEL_VALUE_MAIN, - FLASH_AREA_NVR = FLASH_CFG_NVR_SEL_VALUE_NVR, + FLASH_AREA_MAIN = FLASH_CFG_NVR_SEL_VALUE_MAIN, + FLASH_AREA_NVR = FLASH_CFG_NVR_SEL_VALUE_NVR, }; typedef enum FLASH_AREA FLASH_AREA; diff --git a/driver/gpio.h b/driver/gpio.h index 4de7e8b..5488392 100644 --- a/driver/gpio.h +++ b/driver/gpio.h @@ -20,58 +20,58 @@ #include enum GPIOA_PINS { - GPIOA_PIN_KEYBOARD_0 = 3, - GPIOA_PIN_KEYBOARD_1 = 4, - GPIOA_PIN_KEYBOARD_2 = 5, - GPIOA_PIN_KEYBOARD_3 = 6, - GPIOA_PIN_KEYBOARD_4 = 10, // Shared with I2C! - GPIOA_PIN_KEYBOARD_5 = 11, // Shared with I2C! - GPIOA_PIN_KEYBOARD_6 = 12, // Shared with voice chip! - GPIOA_PIN_KEYBOARD_7 = 13, // Shared with voice chip! + GPIOA_PIN_KEYBOARD_0 = 3, + GPIOA_PIN_KEYBOARD_1 = 4, + GPIOA_PIN_KEYBOARD_2 = 5, + GPIOA_PIN_KEYBOARD_3 = 6, + GPIOA_PIN_KEYBOARD_4 = 10, // Shared with I2C! + GPIOA_PIN_KEYBOARD_5 = 11, // Shared with I2C! + GPIOA_PIN_KEYBOARD_6 = 12, // Shared with voice chip! + GPIOA_PIN_KEYBOARD_7 = 13, // Shared with voice chip! - GPIOA_PIN_I2C_SCL = 10, // Shared with keyboard! - GPIOA_PIN_I2C_SDA = 11, // Shared with keyboard! + GPIOA_PIN_I2C_SCL = 10, // Shared with keyboard! + GPIOA_PIN_I2C_SDA = 11, // Shared with keyboard! - GPIOA_PIN_VOICE_0 = 12, // Shared with keyboard! - GPIOA_PIN_VOICE_1 = 13 // Shared with keyboard! + GPIOA_PIN_VOICE_0 = 12, // Shared with keyboard! + GPIOA_PIN_VOICE_1 = 13 // Shared with keyboard! }; enum GPIOB_PINS { - GPIOB_PIN_BACKLIGHT = 6, + GPIOB_PIN_BACKLIGHT = 6, - GPIOB_PIN_ST7565_A0 = 9, - GPIOB_PIN_ST7565_RES = 11, // Shared with SWD! + GPIOB_PIN_ST7565_A0 = 9, + GPIOB_PIN_ST7565_RES = 11, // Shared with SWD! - GPIOB_PIN_SWD_IO = 11, // Shared with ST7565! - GPIOB_PIN_SWD_CLK = 14, + GPIOB_PIN_SWD_IO = 11, // Shared with ST7565! + GPIOB_PIN_SWD_CLK = 14, - GPIOB_PIN_BK1080 = 15 + GPIOB_PIN_BK1080 = 15 }; enum GPIOC_PINS { - GPIOC_PIN_BK4819_SCN = 0, - GPIOC_PIN_BK4819_SCL = 1, - GPIOC_PIN_BK4819_SDA = 2, + GPIOC_PIN_BK4819_SCN = 0, + GPIOC_PIN_BK4819_SCL = 1, + GPIOC_PIN_BK4819_SDA = 2, - GPIOC_PIN_FLASHLIGHT = 3, - GPIOC_PIN_AUDIO_PATH = 4, - GPIOC_PIN_PTT = 5 + GPIOC_PIN_FLASHLIGHT = 3, + GPIOC_PIN_AUDIO_PATH = 4, + GPIOC_PIN_PTT = 5 }; static inline void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit) { - *pReg &= ~(1U << Bit); + *pReg &= ~(1U << Bit); } static inline uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit) { - return (*pReg >> Bit) & 1U; + return (*pReg >> Bit) & 1U; } static inline void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit) { - *pReg ^= 1U << Bit; + *pReg ^= 1U << Bit; } static inline void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit) { - *pReg |= 1U << Bit; + *pReg |= 1U << Bit; } #endif diff --git a/driver/i2c.c b/driver/i2c.c index 6200364..9b80c23 100644 --- a/driver/i2c.c +++ b/driver/i2c.c @@ -22,143 +22,143 @@ void I2C_Start(void) { - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); - SYSTICK_DelayUs(1); - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); - SYSTICK_DelayUs(1); - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); + SYSTICK_DelayUs(1); + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); + SYSTICK_DelayUs(1); + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); } void I2C_Stop(void) { - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); - SYSTICK_DelayUs(1); - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); - SYSTICK_DelayUs(1); + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); + SYSTICK_DelayUs(1); + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); + SYSTICK_DelayUs(1); } uint8_t I2C_Read(bool bFinal) { - uint8_t i, Data; + uint8_t i, Data; - PORTCON_PORTA_IE |= PORTCON_PORTA_IE_A11_BITS_ENABLE; - PORTCON_PORTA_OD &= ~PORTCON_PORTA_OD_A11_MASK; - GPIOA->DIR &= ~GPIO_DIR_11_MASK; + PORTCON_PORTA_IE |= PORTCON_PORTA_IE_A11_BITS_ENABLE; + PORTCON_PORTA_OD &= ~PORTCON_PORTA_OD_A11_MASK; + GPIOA->DIR &= ~GPIO_DIR_11_MASK; - Data = 0; - for (i = 0; i < 8; i++) { - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); - Data <<= 1; - SYSTICK_DelayUs(1); - if (GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA)) { - Data |= 1U; - } - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); - } + Data = 0; + for (i = 0; i < 8; i++) { + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); + Data <<= 1; + SYSTICK_DelayUs(1); + if (GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA)) { + Data |= 1U; + } + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); + } - PORTCON_PORTA_IE &= ~PORTCON_PORTA_IE_A11_MASK; - PORTCON_PORTA_OD |= PORTCON_PORTA_OD_A11_BITS_ENABLE; - GPIOA->DIR |= GPIO_DIR_11_BITS_OUTPUT; - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); - if (bFinal) { - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); - } else { - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); - } - SYSTICK_DelayUs(1); - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); + PORTCON_PORTA_IE &= ~PORTCON_PORTA_IE_A11_MASK; + PORTCON_PORTA_OD |= PORTCON_PORTA_OD_A11_BITS_ENABLE; + GPIOA->DIR |= GPIO_DIR_11_BITS_OUTPUT; + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); + if (bFinal) { + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); + } else { + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); + } + SYSTICK_DelayUs(1); + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); - return Data; + return Data; } int I2C_Write(uint8_t Data) { - uint8_t i; - int ret = -1; + uint8_t i; + int ret = -1; - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); - for (i = 0; i < 8; i++) { - if ((Data & 0x80) == 0) { - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); - } else { - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); - } - Data <<= 1; - SYSTICK_DelayUs(1); - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); - } + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); + for (i = 0; i < 8; i++) { + if ((Data & 0x80) == 0) { + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); + } else { + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); + } + Data <<= 1; + SYSTICK_DelayUs(1); + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); + } - PORTCON_PORTA_IE |= PORTCON_PORTA_IE_A11_BITS_ENABLE; - PORTCON_PORTA_OD &= ~PORTCON_PORTA_OD_A11_MASK; - GPIOA->DIR &= ~GPIO_DIR_11_MASK; - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); - SYSTICK_DelayUs(1); - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); + PORTCON_PORTA_IE |= PORTCON_PORTA_IE_A11_BITS_ENABLE; + PORTCON_PORTA_OD &= ~PORTCON_PORTA_OD_A11_MASK; + GPIOA->DIR &= ~GPIO_DIR_11_MASK; + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); + SYSTICK_DelayUs(1); + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); - for (i = 0; i < 255; i++) { - if (GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA) == 0) { - ret = 0; - break; - } - } + for (i = 0; i < 255; i++) { + if (GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA) == 0) { + ret = 0; + break; + } + } - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); - SYSTICK_DelayUs(1); - PORTCON_PORTA_IE &= ~PORTCON_PORTA_IE_A11_MASK; - PORTCON_PORTA_OD |= PORTCON_PORTA_OD_A11_BITS_ENABLE; - GPIOA->DIR |= GPIO_DIR_11_BITS_OUTPUT; - GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); + SYSTICK_DelayUs(1); + PORTCON_PORTA_IE &= ~PORTCON_PORTA_IE_A11_MASK; + PORTCON_PORTA_OD |= PORTCON_PORTA_OD_A11_BITS_ENABLE; + GPIOA->DIR |= GPIO_DIR_11_BITS_OUTPUT; + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); - return ret; + return ret; } int I2C_ReadBuffer(void *pBuffer, uint8_t Size) { - uint8_t *pData = (uint8_t *)pBuffer; - uint8_t i; + uint8_t *pData = (uint8_t *)pBuffer; + uint8_t i; - for (i = 0; i < Size - 1; i++) { - SYSTICK_DelayUs(1); - pData[i] = I2C_Read(false); - } + for (i = 0; i < Size - 1; i++) { + SYSTICK_DelayUs(1); + pData[i] = I2C_Read(false); + } - SYSTICK_DelayUs(1); - pData[i] = I2C_Read(true); + SYSTICK_DelayUs(1); + pData[i] = I2C_Read(true); - return Size; + return Size; } int I2C_WriteBuffer(const void *pBuffer, uint8_t Size) { - const uint8_t *pData = (const uint8_t *)pBuffer; - uint8_t i; + const uint8_t *pData = (const uint8_t *)pBuffer; + uint8_t i; - for (i = 0; i < Size; i++) { - if (I2C_Write(*pData++) < 0) { - return -1; - } - } + for (i = 0; i < Size; i++) { + if (I2C_Write(*pData++) < 0) { + return -1; + } + } - return 0; + return 0; } diff --git a/driver/i2c.h b/driver/i2c.h index f4dbbbb..42e4403 100644 --- a/driver/i2c.h +++ b/driver/i2c.h @@ -21,8 +21,8 @@ #include enum { - I2C_WRITE = 0U, - I2C_READ = 1U, + I2C_WRITE = 0U, + I2C_READ = 1U, }; void I2C_Start(void); diff --git a/driver/keyboard.c b/driver/keyboard.c index 0a39b94..bc55381 100644 --- a/driver/keyboard.c +++ b/driver/keyboard.c @@ -29,125 +29,125 @@ bool gWasFKeyPressed = false; static const struct { - // Using a 16 bit pre-calculated shift and invert is cheaper - // than using 8 bit and doing shift and invert in code. - uint16_t set_to_zero_mask; + // Using a 16 bit pre-calculated shift and invert is cheaper + // than using 8 bit and doing shift and invert in code. + uint16_t set_to_zero_mask; - // We are very fortunate. - // The key and pin defines fit together in a single u8, making this very efficient - struct { - KEY_Code_t key : 5; - uint8_t pin : 3; // Pin 6 is highest - } pins[4]; + // We are very fortunate. + // The key and pin defines fit together in a single u8, making this very efficient + struct { + KEY_Code_t key : 5; + uint8_t pin : 3; // Pin 6 is highest + } pins[4]; } keyboard[] = { - { // Zero row - // Set to zero to handle special case of nothing pulled down - .set_to_zero_mask = 0xffff, - .pins = { - { .key = KEY_SIDE1, .pin = GPIOA_PIN_KEYBOARD_0}, - { .key = KEY_SIDE2, .pin = GPIOA_PIN_KEYBOARD_1}, + { // Zero row + // Set to zero to handle special case of nothing pulled down + .set_to_zero_mask = 0xffff, + .pins = { + { .key = KEY_SIDE1, .pin = GPIOA_PIN_KEYBOARD_0}, + { .key = KEY_SIDE2, .pin = GPIOA_PIN_KEYBOARD_1}, - // Duplicate to fill the array with valid values - { .key = KEY_INVALID, .pin = GPIOA_PIN_KEYBOARD_1}, - { .key = KEY_INVALID, .pin = GPIOA_PIN_KEYBOARD_1} - } - }, - { // First row - .set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_4) & 0xffff, - .pins = { - { .key = KEY_MENU, .pin = GPIOA_PIN_KEYBOARD_0}, - { .key = KEY_1, .pin = GPIOA_PIN_KEYBOARD_1}, - { .key = KEY_4, .pin = GPIOA_PIN_KEYBOARD_2}, - { .key = KEY_7, .pin = GPIOA_PIN_KEYBOARD_3} - } - }, - { // Second row - .set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_5) & 0xffff, - .pins = { - { .key = KEY_UP, .pin = GPIOA_PIN_KEYBOARD_0}, - { .key = KEY_2 , .pin = GPIOA_PIN_KEYBOARD_1}, - { .key = KEY_5 , .pin = GPIOA_PIN_KEYBOARD_2}, - { .key = KEY_8 , .pin = GPIOA_PIN_KEYBOARD_3} - } - }, - { // Third row - .set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_6) & 0xffff, - .pins = { - { .key = KEY_DOWN, .pin = GPIOA_PIN_KEYBOARD_0}, - { .key = KEY_3 , .pin = GPIOA_PIN_KEYBOARD_1}, - { .key = KEY_6 , .pin = GPIOA_PIN_KEYBOARD_2}, - { .key = KEY_9 , .pin = GPIOA_PIN_KEYBOARD_3} - } - }, - { // Fourth row - .set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_7) & 0xffff, - .pins = { - { .key = KEY_EXIT, .pin = GPIOA_PIN_KEYBOARD_0}, - { .key = KEY_STAR, .pin = GPIOA_PIN_KEYBOARD_1}, - { .key = KEY_0 , .pin = GPIOA_PIN_KEYBOARD_2}, - { .key = KEY_F , .pin = GPIOA_PIN_KEYBOARD_3} - } - } + // Duplicate to fill the array with valid values + { .key = KEY_INVALID, .pin = GPIOA_PIN_KEYBOARD_1}, + { .key = KEY_INVALID, .pin = GPIOA_PIN_KEYBOARD_1} + } + }, + { // First row + .set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_4) & 0xffff, + .pins = { + { .key = KEY_MENU, .pin = GPIOA_PIN_KEYBOARD_0}, + { .key = KEY_1, .pin = GPIOA_PIN_KEYBOARD_1}, + { .key = KEY_4, .pin = GPIOA_PIN_KEYBOARD_2}, + { .key = KEY_7, .pin = GPIOA_PIN_KEYBOARD_3} + } + }, + { // Second row + .set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_5) & 0xffff, + .pins = { + { .key = KEY_UP, .pin = GPIOA_PIN_KEYBOARD_0}, + { .key = KEY_2 , .pin = GPIOA_PIN_KEYBOARD_1}, + { .key = KEY_5 , .pin = GPIOA_PIN_KEYBOARD_2}, + { .key = KEY_8 , .pin = GPIOA_PIN_KEYBOARD_3} + } + }, + { // Third row + .set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_6) & 0xffff, + .pins = { + { .key = KEY_DOWN, .pin = GPIOA_PIN_KEYBOARD_0}, + { .key = KEY_3 , .pin = GPIOA_PIN_KEYBOARD_1}, + { .key = KEY_6 , .pin = GPIOA_PIN_KEYBOARD_2}, + { .key = KEY_9 , .pin = GPIOA_PIN_KEYBOARD_3} + } + }, + { // Fourth row + .set_to_zero_mask = ~(1u << GPIOA_PIN_KEYBOARD_7) & 0xffff, + .pins = { + { .key = KEY_EXIT, .pin = GPIOA_PIN_KEYBOARD_0}, + { .key = KEY_STAR, .pin = GPIOA_PIN_KEYBOARD_1}, + { .key = KEY_0 , .pin = GPIOA_PIN_KEYBOARD_2}, + { .key = KEY_F , .pin = GPIOA_PIN_KEYBOARD_3} + } + } }; KEY_Code_t KEYBOARD_Poll(void) { - KEY_Code_t Key = KEY_INVALID; + KEY_Code_t Key = KEY_INVALID; -// if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT)) -// return KEY_PTT; +// if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT)) +// return KEY_PTT; - // ***************** + // ***************** - for (unsigned int j = 0; j < ARRAY_SIZE(keyboard); j++) - { - uint16_t reg; - unsigned int i; - unsigned int k; + for (unsigned int j = 0; j < ARRAY_SIZE(keyboard); j++) + { + uint16_t reg; + unsigned int i; + unsigned int k; - // Set all high - GPIOA->DATA |= 1u << GPIOA_PIN_KEYBOARD_4 | - 1u << GPIOA_PIN_KEYBOARD_5 | - 1u << GPIOA_PIN_KEYBOARD_6 | - 1u << GPIOA_PIN_KEYBOARD_7; + // Set all high + GPIOA->DATA |= 1u << GPIOA_PIN_KEYBOARD_4 | + 1u << GPIOA_PIN_KEYBOARD_5 | + 1u << GPIOA_PIN_KEYBOARD_6 | + 1u << GPIOA_PIN_KEYBOARD_7; - // Clear the pin we are selecting - GPIOA->DATA &= keyboard[j].set_to_zero_mask; + // Clear the pin we are selecting + GPIOA->DATA &= keyboard[j].set_to_zero_mask; - // Read all 4 GPIO pins at once .. with de-noise, max of 8 sample loops - for (i = 0, k = 0, reg = 0; i < 3 && k < 8; i++, k++) { - SYSTICK_DelayUs(1); - uint16_t reg2 = GPIOA->DATA; - i *= reg == reg2; - reg = reg2; - } + // Read all 4 GPIO pins at once .. with de-noise, max of 8 sample loops + for (i = 0, k = 0, reg = 0; i < 3 && k < 8; i++, k++) { + SYSTICK_DelayUs(1); + uint16_t reg2 = GPIOA->DATA; + i *= reg == reg2; + reg = reg2; + } - if (i < 3) - break; // noise is too bad + if (i < 3) + break; // noise is too bad - for (unsigned int i = 0; i < ARRAY_SIZE(keyboard[j].pins); i++) - { - const uint16_t mask = 1u << keyboard[j].pins[i].pin; - if (!(reg & mask)) - { - Key = keyboard[j].pins[i].key; - break; - } - } + for (unsigned int i = 0; i < ARRAY_SIZE(keyboard[j].pins); i++) + { + const uint16_t mask = 1u << keyboard[j].pins[i].pin; + if (!(reg & mask)) + { + Key = keyboard[j].pins[i].key; + break; + } + } - if (Key != KEY_INVALID) - break; - } + if (Key != KEY_INVALID) + break; + } - // Create I2C stop condition since we might have toggled I2C pins - // This leaves GPIOA_PIN_KEYBOARD_4 and GPIOA_PIN_KEYBOARD_5 high - I2C_Stop(); + // Create I2C stop condition since we might have toggled I2C pins + // This leaves GPIOA_PIN_KEYBOARD_4 and GPIOA_PIN_KEYBOARD_5 high + I2C_Stop(); - // Reset VOICE pins - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6); - GPIO_SetBit( &GPIOA->DATA, GPIOA_PIN_KEYBOARD_7); + // Reset VOICE pins + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6); + GPIO_SetBit( &GPIOA->DATA, GPIOA_PIN_KEYBOARD_7); - return Key; + return Key; } diff --git a/driver/keyboard.h b/driver/keyboard.h index 5a7d839..5a01844 100644 --- a/driver/keyboard.h +++ b/driver/keyboard.h @@ -22,26 +22,26 @@ #include enum KEY_Code_e { - KEY_0 = 0, // 0 - KEY_1, // 1 - KEY_2, // 2 - KEY_3, // 3 - KEY_4, // 4 - KEY_5, // 5 - KEY_6, // 6 - KEY_7, // 7 - KEY_8, // 8 - KEY_9, // 9 - KEY_MENU, // A - KEY_UP, // B - KEY_DOWN, // C - KEY_EXIT, // D - KEY_STAR, // * - KEY_F, // # - KEY_PTT, // - KEY_SIDE2, // - KEY_SIDE1, // - KEY_INVALID // + KEY_0 = 0, // 0 + KEY_1, // 1 + KEY_2, // 2 + KEY_3, // 3 + KEY_4, // 4 + KEY_5, // 5 + KEY_6, // 6 + KEY_7, // 7 + KEY_8, // 8 + KEY_9, // 9 + KEY_MENU, // A + KEY_UP, // B + KEY_DOWN, // C + KEY_EXIT, // D + KEY_STAR, // * + KEY_F, // # + KEY_PTT, // + KEY_SIDE2, // + KEY_SIDE1, // + KEY_INVALID // }; typedef enum KEY_Code_e KEY_Code_t; diff --git a/driver/spi.c b/driver/spi.c index 4a1a279..b792635 100644 --- a/driver/spi.c +++ b/driver/spi.c @@ -22,95 +22,95 @@ void SPI0_Init(void) { - SPI_Config_t Config; + SPI_Config_t Config; - SPI_Disable(&SPI0->CR); + SPI_Disable(&SPI0->CR); - Config.TXFIFO_EMPTY = 0; - Config.RXFIFO_HFULL = 0; - Config.RXFIFO_FULL = 0; - Config.RXFIFO_OVF = 0; - Config.MSTR = 1; - Config.SPR = 2; - Config.CPHA = 1; - Config.CPOL = 1; - Config.LSB = 0; - Config.TF_CLR = 0; - Config.RF_CLR = 0; - Config.TXFIFO_HFULL = 0; - SPI_Configure(SPI0, &Config); + Config.TXFIFO_EMPTY = 0; + Config.RXFIFO_HFULL = 0; + Config.RXFIFO_FULL = 0; + Config.RXFIFO_OVF = 0; + Config.MSTR = 1; + Config.SPR = 2; + Config.CPHA = 1; + Config.CPOL = 1; + Config.LSB = 0; + Config.TF_CLR = 0; + Config.RF_CLR = 0; + Config.TXFIFO_HFULL = 0; + SPI_Configure(SPI0, &Config); - SPI_Enable(&SPI0->CR); + SPI_Enable(&SPI0->CR); } void SPI_WaitForUndocumentedTxFifoStatusBit(void) { - uint32_t Timeout; + uint32_t Timeout; - Timeout = 0; - do { - // Undocumented bit! - if ((SPI0->IF & 0x20) == 0) { - break; - } - Timeout++; - } while (Timeout <= 100000); + Timeout = 0; + do { + // Undocumented bit! + if ((SPI0->IF & 0x20) == 0) { + break; + } + Timeout++; + } while (Timeout <= 100000); } void SPI_Disable(volatile uint32_t *pCR) { - *pCR = (*pCR & ~SPI_CR_SPE_MASK) | SPI_CR_SPE_BITS_DISABLE; + *pCR = (*pCR & ~SPI_CR_SPE_MASK) | SPI_CR_SPE_BITS_DISABLE; } void SPI_Configure(volatile SPI_Port_t *pPort, SPI_Config_t *pConfig) { - if (pPort == SPI0) { - SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SPI0_MASK) | SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE; - } else if (pPort == SPI1) { - SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SPI1_MASK) | SYSCON_DEV_CLK_GATE_SPI1_BITS_ENABLE; - } + if (pPort == SPI0) { + SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SPI0_MASK) | SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE; + } else if (pPort == SPI1) { + SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SPI1_MASK) | SYSCON_DEV_CLK_GATE_SPI1_BITS_ENABLE; + } - SPI_Disable(&pPort->CR); + SPI_Disable(&pPort->CR); - pPort->CR = 0 - | (pPort->CR & ~(SPI_CR_SPR_MASK | SPI_CR_CPHA_MASK | SPI_CR_CPOL_MASK | SPI_CR_MSTR_MASK | SPI_CR_LSB_MASK | SPI_CR_RF_CLR_MASK)) - | ((pConfig->SPR << SPI_CR_SPR_SHIFT) & SPI_CR_SPR_MASK) - | ((pConfig->CPHA << SPI_CR_CPHA_SHIFT) & SPI_CR_CPHA_MASK) - | ((pConfig->CPOL << SPI_CR_CPOL_SHIFT) & SPI_CR_CPOL_MASK) - | ((pConfig->MSTR << SPI_CR_MSTR_SHIFT) & SPI_CR_MSTR_MASK) - | ((pConfig->LSB << SPI_CR_LSB_SHIFT) & SPI_CR_LSB_MASK) - | ((pConfig->RF_CLR << SPI_CR_RF_CLR_SHIFT) & SPI_CR_RF_CLR_MASK) - | ((pConfig->TF_CLR << SPI_CR_TF_CLR_SHIFT) & SPI_CR_TF_CLR_MASK) - ; + pPort->CR = 0 + | (pPort->CR & ~(SPI_CR_SPR_MASK | SPI_CR_CPHA_MASK | SPI_CR_CPOL_MASK | SPI_CR_MSTR_MASK | SPI_CR_LSB_MASK | SPI_CR_RF_CLR_MASK)) + | ((pConfig->SPR << SPI_CR_SPR_SHIFT) & SPI_CR_SPR_MASK) + | ((pConfig->CPHA << SPI_CR_CPHA_SHIFT) & SPI_CR_CPHA_MASK) + | ((pConfig->CPOL << SPI_CR_CPOL_SHIFT) & SPI_CR_CPOL_MASK) + | ((pConfig->MSTR << SPI_CR_MSTR_SHIFT) & SPI_CR_MSTR_MASK) + | ((pConfig->LSB << SPI_CR_LSB_SHIFT) & SPI_CR_LSB_MASK) + | ((pConfig->RF_CLR << SPI_CR_RF_CLR_SHIFT) & SPI_CR_RF_CLR_MASK) + | ((pConfig->TF_CLR << SPI_CR_TF_CLR_SHIFT) & SPI_CR_TF_CLR_MASK) + ; - pPort->IE = 0 - | ((pConfig->RXFIFO_OVF << SPI_IE_RXFIFO_OVF_SHIFT) & SPI_IE_RXFIFO_OVF_MASK) - | ((pConfig->RXFIFO_FULL << SPI_IE_RXFIFO_FULL_SHIFT) & SPI_IE_RXFIFO_FULL_MASK) - | ((pConfig->RXFIFO_HFULL << SPI_IE_RXFIFO_HFULL_SHIFT) & SPI_IE_RXFIFO_HFULL_MASK) - | ((pConfig->TXFIFO_EMPTY << SPI_IE_TXFIFO_EMPTY_SHIFT) & SPI_IE_TXFIFO_EMPTY_MASK) - | ((pConfig->TXFIFO_HFULL << SPI_IE_TXFIFO_HFULL_SHIFT) & SPI_IE_TXFIFO_HFULL_MASK) - ; + pPort->IE = 0 + | ((pConfig->RXFIFO_OVF << SPI_IE_RXFIFO_OVF_SHIFT) & SPI_IE_RXFIFO_OVF_MASK) + | ((pConfig->RXFIFO_FULL << SPI_IE_RXFIFO_FULL_SHIFT) & SPI_IE_RXFIFO_FULL_MASK) + | ((pConfig->RXFIFO_HFULL << SPI_IE_RXFIFO_HFULL_SHIFT) & SPI_IE_RXFIFO_HFULL_MASK) + | ((pConfig->TXFIFO_EMPTY << SPI_IE_TXFIFO_EMPTY_SHIFT) & SPI_IE_TXFIFO_EMPTY_MASK) + | ((pConfig->TXFIFO_HFULL << SPI_IE_TXFIFO_HFULL_SHIFT) & SPI_IE_TXFIFO_HFULL_MASK) + ; - if (pPort->IE) { - if (pPort == SPI0) { - NVIC_EnableIRQ((IRQn_Type)DP32_SPI0_IRQn); - } else if (pPort == SPI1) { - NVIC_EnableIRQ((IRQn_Type)DP32_SPI1_IRQn); - } - } + if (pPort->IE) { + if (pPort == SPI0) { + NVIC_EnableIRQ((IRQn_Type)DP32_SPI0_IRQn); + } else if (pPort == SPI1) { + NVIC_EnableIRQ((IRQn_Type)DP32_SPI1_IRQn); + } + } } void SPI_ToggleMasterMode(volatile uint32_t *pCR, bool bIsMaster) { - if (bIsMaster) { - *pCR = (*pCR & ~SPI_CR_MSR_SSN_MASK) | SPI_CR_MSR_SSN_BITS_ENABLE; - } else { - *pCR = (*pCR & ~SPI_CR_MSR_SSN_MASK) | SPI_CR_MSR_SSN_BITS_DISABLE; - } + if (bIsMaster) { + *pCR = (*pCR & ~SPI_CR_MSR_SSN_MASK) | SPI_CR_MSR_SSN_BITS_ENABLE; + } else { + *pCR = (*pCR & ~SPI_CR_MSR_SSN_MASK) | SPI_CR_MSR_SSN_BITS_DISABLE; + } } void SPI_Enable(volatile uint32_t *pCR) { - *pCR = (*pCR & ~SPI_CR_SPE_MASK) | SPI_CR_SPE_BITS_ENABLE; + *pCR = (*pCR & ~SPI_CR_SPE_MASK) | SPI_CR_SPE_BITS_ENABLE; } diff --git a/driver/spi.h b/driver/spi.h index a3cc8a4..e94f5e5 100644 --- a/driver/spi.h +++ b/driver/spi.h @@ -21,18 +21,18 @@ #include typedef struct { - uint8_t MSTR; - uint8_t SPR; - uint8_t CPHA; - uint8_t CPOL; - uint8_t LSB; - uint8_t TF_CLR; - uint8_t RF_CLR; - uint8_t TXFIFO_HFULL; - uint8_t TXFIFO_EMPTY; - uint8_t RXFIFO_HFULL; - uint8_t RXFIFO_FULL; - uint8_t RXFIFO_OVF; + uint8_t MSTR; + uint8_t SPR; + uint8_t CPHA; + uint8_t CPOL; + uint8_t LSB; + uint8_t TF_CLR; + uint8_t RF_CLR; + uint8_t TXFIFO_HFULL; + uint8_t TXFIFO_EMPTY; + uint8_t RXFIFO_HFULL; + uint8_t RXFIFO_FULL; + uint8_t RXFIFO_OVF; } SPI_Config_t; void SPI0_Init(void); diff --git a/driver/st7565.c b/driver/st7565.c index af17e24..4e008f3 100644 --- a/driver/st7565.c +++ b/driver/st7565.c @@ -29,104 +29,104 @@ uint8_t gStatusLine[LCD_WIDTH]; uint8_t gFrameBuffer[FRAME_LINES][LCD_WIDTH]; static void DrawLine(uint8_t column, uint8_t line, const uint8_t * lineBuffer, unsigned size_defVal) -{ - ST7565_SelectColumnAndLine(column + 4, line); - GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0); - for (unsigned i = 0; i < size_defVal; i++) { - while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} - SPI0->WDR = lineBuffer ? lineBuffer[i] : size_defVal; - } - SPI_WaitForUndocumentedTxFifoStatusBit(); +{ + ST7565_SelectColumnAndLine(column + 4, line); + GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0); + for (unsigned i = 0; i < size_defVal; i++) { + while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} + SPI0->WDR = lineBuffer ? lineBuffer[i] : size_defVal; + } + SPI_WaitForUndocumentedTxFifoStatusBit(); } void ST7565_DrawLine(const unsigned int Column, const unsigned int Line, const uint8_t *pBitmap, const unsigned int Size) { - SPI_ToggleMasterMode(&SPI0->CR, false); - DrawLine(Column, Line, pBitmap, Size); - SPI_ToggleMasterMode(&SPI0->CR, true); + SPI_ToggleMasterMode(&SPI0->CR, false); + DrawLine(Column, Line, pBitmap, Size); + SPI_ToggleMasterMode(&SPI0->CR, true); } #ifdef ENABLE_FEAT_F4HWN - // Optimization - // - // ST7565_BlitScreen(0) = ST7565_BlitStatusLine() - // ST7565_BlitScreen(1..7) = ST7565_BlitLine() - // ST7565_BlitScreen(8) = ST7565_BlitFullScreen() - // + // Optimization + // + // ST7565_BlitScreen(0) = ST7565_BlitStatusLine() + // ST7565_BlitScreen(1..7) = ST7565_BlitLine() + // ST7565_BlitScreen(8) = ST7565_BlitFullScreen() + // - static void ST7565_BlitScreen(uint8_t line) - { - SPI_ToggleMasterMode(&SPI0->CR, false); - ST7565_WriteByte(0x40); + static void ST7565_BlitScreen(uint8_t line) + { + SPI_ToggleMasterMode(&SPI0->CR, false); + ST7565_WriteByte(0x40); - if(line == 0) - { - DrawLine(0, 0, gStatusLine, LCD_WIDTH); - } - else if(line <= FRAME_LINES) - { - DrawLine(0, line, gFrameBuffer[line - 1], LCD_WIDTH); - } - else - { - for (line = 1; line <= FRAME_LINES; line++) { - DrawLine(0, line, gFrameBuffer[line - 1], LCD_WIDTH); - } - } + if(line == 0) + { + DrawLine(0, 0, gStatusLine, LCD_WIDTH); + } + else if(line <= FRAME_LINES) + { + DrawLine(0, line, gFrameBuffer[line - 1], LCD_WIDTH); + } + else + { + for (line = 1; line <= FRAME_LINES; line++) { + DrawLine(0, line, gFrameBuffer[line - 1], LCD_WIDTH); + } + } - SPI_ToggleMasterMode(&SPI0->CR, true); - } + SPI_ToggleMasterMode(&SPI0->CR, true); + } - void ST7565_BlitFullScreen(void) - { - ST7565_BlitScreen(8); - } + void ST7565_BlitFullScreen(void) + { + ST7565_BlitScreen(8); + } - void ST7565_BlitLine(unsigned line) - { - ST7565_BlitScreen(line + 1); - } + void ST7565_BlitLine(unsigned line) + { + ST7565_BlitScreen(line + 1); + } - void ST7565_BlitStatusLine(void) - { - ST7565_BlitScreen(0); - } + void ST7565_BlitStatusLine(void) + { + ST7565_BlitScreen(0); + } #else - void ST7565_BlitFullScreen(void) - { - SPI_ToggleMasterMode(&SPI0->CR, false); - ST7565_WriteByte(0x40); - for (unsigned line = 0; line < FRAME_LINES; line++) { - DrawLine(0, line+1, gFrameBuffer[line], LCD_WIDTH); - } - SPI_ToggleMasterMode(&SPI0->CR, true); - } + void ST7565_BlitFullScreen(void) + { + SPI_ToggleMasterMode(&SPI0->CR, false); + ST7565_WriteByte(0x40); + for (unsigned line = 0; line < FRAME_LINES; line++) { + DrawLine(0, line+1, gFrameBuffer[line], LCD_WIDTH); + } + SPI_ToggleMasterMode(&SPI0->CR, true); + } - void ST7565_BlitLine(unsigned line) - { - SPI_ToggleMasterMode(&SPI0->CR, false); - ST7565_WriteByte(0x40); // start line ? - DrawLine(0, line+1, gFrameBuffer[line], LCD_WIDTH); - SPI_ToggleMasterMode(&SPI0->CR, true); - } + void ST7565_BlitLine(unsigned line) + { + SPI_ToggleMasterMode(&SPI0->CR, false); + ST7565_WriteByte(0x40); // start line ? + DrawLine(0, line+1, gFrameBuffer[line], LCD_WIDTH); + SPI_ToggleMasterMode(&SPI0->CR, true); + } - void ST7565_BlitStatusLine(void) - { // the top small text line on the display - SPI_ToggleMasterMode(&SPI0->CR, false); - ST7565_WriteByte(0x40); // start line ? - DrawLine(0, 0, gStatusLine, LCD_WIDTH); - SPI_ToggleMasterMode(&SPI0->CR, true); - } + void ST7565_BlitStatusLine(void) + { // the top small text line on the display + SPI_ToggleMasterMode(&SPI0->CR, false); + ST7565_WriteByte(0x40); // start line ? + DrawLine(0, 0, gStatusLine, LCD_WIDTH); + SPI_ToggleMasterMode(&SPI0->CR, true); + } #endif void ST7565_FillScreen(uint8_t value) { - SPI_ToggleMasterMode(&SPI0->CR, false); - for (unsigned i = 0; i < 8; i++) { - DrawLine(0, i, NULL, value); - } - SPI_ToggleMasterMode(&SPI0->CR, true); + SPI_ToggleMasterMode(&SPI0->CR, false); + for (unsigned i = 0; i < 8; i++) { + DrawLine(0, i, NULL, value); + } + SPI_ToggleMasterMode(&SPI0->CR, true); } // Software reset @@ -179,121 +179,121 @@ const uint8_t ST7565_CMD_SET_START_LINE = 0x40; const uint8_t ST7565_CMD_DISPLAY_ON_OFF = 0xAE; uint8_t cmds[] = { - ST7565_CMD_BIAS_SELECT | 0, // Select bias setting: 1/9 - ST7565_CMD_COM_DIRECTION | (0 << 3), // Set output direction of COM: normal - ST7565_CMD_SEG_DIRECTION | 1, // Set scan direction of SEG: reverse - ST7565_CMD_INVERSE_DISPLAY | 0, // Inverse Display: false - ST7565_CMD_ALL_PIXEL_ON | 0, // All Pixel ON: false - normal display - ST7565_CMD_REGULATION_RATIO | (4 << 0), // Regulation Ratio 5.0 + ST7565_CMD_BIAS_SELECT | 0, // Select bias setting: 1/9 + ST7565_CMD_COM_DIRECTION | (0 << 3), // Set output direction of COM: normal + ST7565_CMD_SEG_DIRECTION | 1, // Set scan direction of SEG: reverse + ST7565_CMD_INVERSE_DISPLAY | 0, // Inverse Display: false + ST7565_CMD_ALL_PIXEL_ON | 0, // All Pixel ON: false - normal display + ST7565_CMD_REGULATION_RATIO | (4 << 0), // Regulation Ratio 5.0 - ST7565_CMD_SET_EV, // Set contrast - 31, + ST7565_CMD_SET_EV, // Set contrast + 31, - ST7565_CMD_POWER_CIRCUIT | 0b111, // Built-in power circuit ON/OFF: VB=1 VR=1 VF=1 - ST7565_CMD_SET_START_LINE | 0, // Set Start Line: 0 - ST7565_CMD_DISPLAY_ON_OFF | 1, // Display ON/OFF: ON + ST7565_CMD_POWER_CIRCUIT | 0b111, // Built-in power circuit ON/OFF: VB=1 VR=1 VF=1 + ST7565_CMD_SET_START_LINE | 0, // Set Start Line: 0 + ST7565_CMD_DISPLAY_ON_OFF | 1, // Display ON/OFF: ON }; #ifdef ENABLE_FEAT_F4HWN - static void ST7565_Cmd(uint8_t i) - { - switch(i) { - case 3: - ST7565_WriteByte(ST7565_CMD_INVERSE_DISPLAY | gSetting_set_inv); - break; - case 7: - ST7565_WriteByte(21 + gSetting_set_ctr); - break; - default: - ST7565_WriteByte(cmds[i]); - } - } + static void ST7565_Cmd(uint8_t i) + { + switch(i) { + case 3: + ST7565_WriteByte(ST7565_CMD_INVERSE_DISPLAY | gSetting_set_inv); + break; + case 7: + ST7565_WriteByte(21 + gSetting_set_ctr); + break; + default: + ST7565_WriteByte(cmds[i]); + } + } - void ST7565_ContrastAndInv(void) - { - SPI_ToggleMasterMode(&SPI0->CR, false); - ST7565_WriteByte(ST7565_CMD_SOFTWARE_RESET); // software reset + void ST7565_ContrastAndInv(void) + { + SPI_ToggleMasterMode(&SPI0->CR, false); + ST7565_WriteByte(ST7565_CMD_SOFTWARE_RESET); // software reset - for(uint8_t i = 0; i < 8; i++) - { - ST7565_Cmd(i); - } - } + for(uint8_t i = 0; i < 8; i++) + { + ST7565_Cmd(i); + } + } #endif - + void ST7565_Init(void) { - SPI0_Init(); - ST7565_HardwareReset(); - SPI_ToggleMasterMode(&SPI0->CR, false); - ST7565_WriteByte(ST7565_CMD_SOFTWARE_RESET); // software reset - SYSTEM_DelayMs(120); + SPI0_Init(); + ST7565_HardwareReset(); + SPI_ToggleMasterMode(&SPI0->CR, false); + ST7565_WriteByte(ST7565_CMD_SOFTWARE_RESET); // software reset + SYSTEM_DelayMs(120); - for(uint8_t i = 0; i < 8; i++) - { + for(uint8_t i = 0; i < 8; i++) + { #ifdef ENABLE_FEAT_F4HWN - ST7565_Cmd(i); + ST7565_Cmd(i); #else - ST7565_WriteByte(cmds[i]); + ST7565_WriteByte(cmds[i]); #endif - } + } - ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b011); // VB=0 VR=1 VF=1 - SYSTEM_DelayMs(1); - ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b110); // VB=1 VR=1 VF=0 - SYSTEM_DelayMs(1); + ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b011); // VB=0 VR=1 VF=1 + SYSTEM_DelayMs(1); + ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b110); // VB=1 VR=1 VF=0 + SYSTEM_DelayMs(1); - for(uint8_t i = 0; i < 4; i++) // why 4 times? - ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b111); // VB=1 VR=1 VF=1 + for(uint8_t i = 0; i < 4; i++) // why 4 times? + ST7565_WriteByte(ST7565_CMD_POWER_CIRCUIT | 0b111); // VB=1 VR=1 VF=1 - SYSTEM_DelayMs(40); - - ST7565_WriteByte(ST7565_CMD_SET_START_LINE | 0); // line 0 - ST7565_WriteByte(ST7565_CMD_DISPLAY_ON_OFF | 1); // D=1 - SPI_WaitForUndocumentedTxFifoStatusBit(); - SPI_ToggleMasterMode(&SPI0->CR, true); + SYSTEM_DelayMs(40); + + ST7565_WriteByte(ST7565_CMD_SET_START_LINE | 0); // line 0 + ST7565_WriteByte(ST7565_CMD_DISPLAY_ON_OFF | 1); // D=1 + SPI_WaitForUndocumentedTxFifoStatusBit(); + SPI_ToggleMasterMode(&SPI0->CR, true); - ST7565_FillScreen(0x00); + ST7565_FillScreen(0x00); } void ST7565_FixInterfGlitch(void) { - SPI_ToggleMasterMode(&SPI0->CR, false); - for(uint8_t i = 0; i < ARRAY_SIZE(cmds); i++) + SPI_ToggleMasterMode(&SPI0->CR, false); + for(uint8_t i = 0; i < ARRAY_SIZE(cmds); i++) #ifdef ENABLE_FEAT_F4HWN - ST7565_Cmd(i); + ST7565_Cmd(i); #else - ST7565_WriteByte(cmds[i]); + ST7565_WriteByte(cmds[i]); #endif - SPI_WaitForUndocumentedTxFifoStatusBit(); - SPI_ToggleMasterMode(&SPI0->CR, true); + SPI_WaitForUndocumentedTxFifoStatusBit(); + SPI_ToggleMasterMode(&SPI0->CR, true); } void ST7565_HardwareReset(void) { - GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES); - SYSTEM_DelayMs(1); - GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES); - SYSTEM_DelayMs(20); - GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES); - SYSTEM_DelayMs(120); + GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES); + SYSTEM_DelayMs(1); + GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES); + SYSTEM_DelayMs(20); + GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES); + SYSTEM_DelayMs(120); } void ST7565_SelectColumnAndLine(uint8_t Column, uint8_t Line) { - GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0); - while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} - SPI0->WDR = Line + 176; - while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} - SPI0->WDR = ((Column >> 4) & 0x0F) | 0x10; - while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} - SPI0->WDR = ((Column >> 0) & 0x0F); - SPI_WaitForUndocumentedTxFifoStatusBit(); + GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0); + while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} + SPI0->WDR = Line + 176; + while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} + SPI0->WDR = ((Column >> 4) & 0x0F) | 0x10; + while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} + SPI0->WDR = ((Column >> 0) & 0x0F); + SPI_WaitForUndocumentedTxFifoStatusBit(); } void ST7565_WriteByte(uint8_t Value) { - GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0); - while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} - SPI0->WDR = Value; + GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0); + while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} + SPI0->WDR = Value; } diff --git a/driver/st7565.h b/driver/st7565.h index b5ec79c..80b43e1 100644 --- a/driver/st7565.h +++ b/driver/st7565.h @@ -39,7 +39,7 @@ void ST7565_SelectColumnAndLine(uint8_t Column, uint8_t Line); void ST7565_WriteByte(uint8_t Value); #ifdef ENABLE_FEAT_F4HWN - void ST7565_ContrastAndInv(void); + void ST7565_ContrastAndInv(void); #endif #endif diff --git a/driver/system.c b/driver/system.c index 813ddec..e9f16f7 100644 --- a/driver/system.c +++ b/driver/system.c @@ -21,17 +21,17 @@ void SYSTEM_DelayMs(uint32_t Delay) { - SYSTICK_DelayUs(Delay * 1000); + SYSTICK_DelayUs(Delay * 1000); } void SYSTEM_ConfigureClocks(void) { - // Set source clock from external crystal - PMU_SRC_CFG = (PMU_SRC_CFG & ~(PMU_SRC_CFG_RCHF_SEL_MASK | PMU_SRC_CFG_RCHF_EN_MASK)) | PMU_SRC_CFG_RCHF_SEL_BITS_48MHZ | PMU_SRC_CFG_RCHF_EN_BITS_ENABLE; + // Set source clock from external crystal + PMU_SRC_CFG = (PMU_SRC_CFG & ~(PMU_SRC_CFG_RCHF_SEL_MASK | PMU_SRC_CFG_RCHF_EN_MASK)) | PMU_SRC_CFG_RCHF_SEL_BITS_48MHZ | PMU_SRC_CFG_RCHF_EN_BITS_ENABLE; - // Divide by 2 - SYSCON_CLK_SEL = SYSCON_CLK_SEL_DIV_BITS_2; + // Divide by 2 + SYSCON_CLK_SEL = SYSCON_CLK_SEL_DIV_BITS_2; - // Disable division clock gate - SYSCON_DIV_CLK_GATE = (SYSCON_DIV_CLK_GATE & ~SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_MASK) | SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_BITS_DISABLE; + // Disable division clock gate + SYSCON_DIV_CLK_GATE = (SYSCON_DIV_CLK_GATE & ~SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_MASK) | SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_BITS_DISABLE; } diff --git a/driver/systick.c b/driver/systick.c index c7cbed3..ff8182c 100644 --- a/driver/systick.c +++ b/driver/systick.c @@ -23,27 +23,27 @@ static uint32_t gTickMultiplier; void SYSTICK_Init(void) { - SysTick_Config(480000); - gTickMultiplier = 48; + SysTick_Config(480000); + gTickMultiplier = 48; } void SYSTICK_DelayUs(uint32_t Delay) { - const uint32_t ticks = Delay * gTickMultiplier; - uint32_t elapsed_ticks = 0; - uint32_t Start = SysTick->LOAD; - uint32_t Previous = SysTick->VAL; - do { - uint32_t Current; + const uint32_t ticks = Delay * gTickMultiplier; + uint32_t elapsed_ticks = 0; + uint32_t Start = SysTick->LOAD; + uint32_t Previous = SysTick->VAL; + do { + uint32_t Current; - do { - Current = SysTick->VAL; - } while (Current == Previous); + do { + Current = SysTick->VAL; + } while (Current == Previous); - uint32_t Delta = ((Current < Previous) ? - Current : Start - Current); + uint32_t Delta = ((Current < Previous) ? - Current : Start - Current); - elapsed_ticks += Delta + Previous; + elapsed_ticks += Delta + Previous; - Previous = Current; - } while (elapsed_ticks < ticks); + Previous = Current; + } while (elapsed_ticks < ticks); } diff --git a/driver/uart.c b/driver/uart.c index cb97d94..5ea744c 100644 --- a/driver/uart.c +++ b/driver/uart.c @@ -25,80 +25,80 @@ uint8_t UART_DMA_Buffer[256]; void UART_Init(void) { - uint32_t Delta; - uint32_t Positive; - uint32_t Frequency; + uint32_t Delta; + uint32_t Positive; + uint32_t Frequency; - UART1->CTRL = (UART1->CTRL & ~UART_CTRL_UARTEN_MASK) | UART_CTRL_UARTEN_BITS_DISABLE; - Delta = SYSCON_RC_FREQ_DELTA; - Positive = (Delta & SYSCON_RC_FREQ_DELTA_RCHF_SIG_MASK) >> SYSCON_RC_FREQ_DELTA_RCHF_SIG_SHIFT; - Frequency = (Delta & SYSCON_RC_FREQ_DELTA_RCHF_DELTA_MASK) >> SYSCON_RC_FREQ_DELTA_RCHF_DELTA_SHIFT; - if (Positive) { - Frequency += 48000000U; - } else { - Frequency = 48000000U - Frequency; - } + UART1->CTRL = (UART1->CTRL & ~UART_CTRL_UARTEN_MASK) | UART_CTRL_UARTEN_BITS_DISABLE; + Delta = SYSCON_RC_FREQ_DELTA; + Positive = (Delta & SYSCON_RC_FREQ_DELTA_RCHF_SIG_MASK) >> SYSCON_RC_FREQ_DELTA_RCHF_SIG_SHIFT; + Frequency = (Delta & SYSCON_RC_FREQ_DELTA_RCHF_DELTA_MASK) >> SYSCON_RC_FREQ_DELTA_RCHF_DELTA_SHIFT; + if (Positive) { + Frequency += 48000000U; + } else { + Frequency = 48000000U - Frequency; + } - UART1->BAUD = Frequency / 39053U; - UART1->CTRL = UART_CTRL_RXEN_BITS_ENABLE | UART_CTRL_TXEN_BITS_ENABLE | UART_CTRL_RXDMAEN_BITS_ENABLE; - UART1->RXTO = 4; - UART1->FC = 0; - UART1->FIFO = UART_FIFO_RF_LEVEL_BITS_8_BYTE | UART_FIFO_RF_CLR_BITS_ENABLE | UART_FIFO_TF_CLR_BITS_ENABLE; - UART1->IE = 0; + UART1->BAUD = Frequency / 39053U; + UART1->CTRL = UART_CTRL_RXEN_BITS_ENABLE | UART_CTRL_TXEN_BITS_ENABLE | UART_CTRL_RXDMAEN_BITS_ENABLE; + UART1->RXTO = 4; + UART1->FC = 0; + UART1->FIFO = UART_FIFO_RF_LEVEL_BITS_8_BYTE | UART_FIFO_RF_CLR_BITS_ENABLE | UART_FIFO_TF_CLR_BITS_ENABLE; + UART1->IE = 0; - DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_DISABLE; + DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_DISABLE; - DMA_CH0->MSADDR = (uint32_t)(uintptr_t)&UART1->RDR; - DMA_CH0->MDADDR = (uint32_t)(uintptr_t)UART_DMA_Buffer; - DMA_CH0->MOD = 0 - // Source - | DMA_CH_MOD_MS_ADDMOD_BITS_NONE - | DMA_CH_MOD_MS_SIZE_BITS_8BIT - | DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS1 - // Destination - | DMA_CH_MOD_MD_ADDMOD_BITS_INCREMENT - | DMA_CH_MOD_MD_SIZE_BITS_8BIT - | DMA_CH_MOD_MD_SEL_BITS_SRAM - ; - DMA_INTEN = 0; - DMA_INTST = 0 - | DMA_INTST_CH0_TC_INTST_BITS_SET - | DMA_INTST_CH1_TC_INTST_BITS_SET - | DMA_INTST_CH2_TC_INTST_BITS_SET - | DMA_INTST_CH3_TC_INTST_BITS_SET - | DMA_INTST_CH0_THC_INTST_BITS_SET - | DMA_INTST_CH1_THC_INTST_BITS_SET - | DMA_INTST_CH2_THC_INTST_BITS_SET - | DMA_INTST_CH3_THC_INTST_BITS_SET - ; - DMA_CH0->CTR = 0 - | DMA_CH_CTR_CH_EN_BITS_ENABLE - | ((0xFF << DMA_CH_CTR_LENGTH_SHIFT) & DMA_CH_CTR_LENGTH_MASK) - | DMA_CH_CTR_LOOP_BITS_ENABLE - | DMA_CH_CTR_PRI_BITS_MEDIUM - ; - UART1->IF = UART_IF_RXTO_BITS_SET; + DMA_CH0->MSADDR = (uint32_t)(uintptr_t)&UART1->RDR; + DMA_CH0->MDADDR = (uint32_t)(uintptr_t)UART_DMA_Buffer; + DMA_CH0->MOD = 0 + // Source + | DMA_CH_MOD_MS_ADDMOD_BITS_NONE + | DMA_CH_MOD_MS_SIZE_BITS_8BIT + | DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS1 + // Destination + | DMA_CH_MOD_MD_ADDMOD_BITS_INCREMENT + | DMA_CH_MOD_MD_SIZE_BITS_8BIT + | DMA_CH_MOD_MD_SEL_BITS_SRAM + ; + DMA_INTEN = 0; + DMA_INTST = 0 + | DMA_INTST_CH0_TC_INTST_BITS_SET + | DMA_INTST_CH1_TC_INTST_BITS_SET + | DMA_INTST_CH2_TC_INTST_BITS_SET + | DMA_INTST_CH3_TC_INTST_BITS_SET + | DMA_INTST_CH0_THC_INTST_BITS_SET + | DMA_INTST_CH1_THC_INTST_BITS_SET + | DMA_INTST_CH2_THC_INTST_BITS_SET + | DMA_INTST_CH3_THC_INTST_BITS_SET + ; + DMA_CH0->CTR = 0 + | DMA_CH_CTR_CH_EN_BITS_ENABLE + | ((0xFF << DMA_CH_CTR_LENGTH_SHIFT) & DMA_CH_CTR_LENGTH_MASK) + | DMA_CH_CTR_LOOP_BITS_ENABLE + | DMA_CH_CTR_PRI_BITS_MEDIUM + ; + UART1->IF = UART_IF_RXTO_BITS_SET; - DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_ENABLE; + DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_ENABLE; - UART1->CTRL |= UART_CTRL_UARTEN_BITS_ENABLE; + UART1->CTRL |= UART_CTRL_UARTEN_BITS_ENABLE; } void UART_Send(const void *pBuffer, uint32_t Size) { - const uint8_t *pData = (const uint8_t *)pBuffer; - uint32_t i; + const uint8_t *pData = (const uint8_t *)pBuffer; + uint32_t i; - for (i = 0; i < Size; i++) { - UART1->TDR = pData[i]; - while ((UART1->IF & UART_IF_TXFIFO_FULL_MASK) != UART_IF_TXFIFO_FULL_BITS_NOT_SET) { - } - } + for (i = 0; i < Size; i++) { + UART1->TDR = pData[i]; + while ((UART1->IF & UART_IF_TXFIFO_FULL_MASK) != UART_IF_TXFIFO_FULL_BITS_NOT_SET) { + } + } } void UART_LogSend(const void *pBuffer, uint32_t Size) { - if (UART_IsLogEnabled) { - UART_Send(pBuffer, Size); - } + if (UART_IsLogEnabled) { + UART_Send(pBuffer, Size); + } } diff --git a/font.c b/font.c index 67252dc..4b2732f 100644 --- a/font.c +++ b/font.c @@ -22,633 +22,633 @@ const uint8_t gFontBig[95 - 1][16 - 2] = { #if 0 // {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // ' ' - {0x00, 0x00, 0x70, 0xF8, 0xF8, 0x70, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '!' - {0x00, 0x1E, 0x3E, 0x00, 0x00, 0x3E, 0x1E, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '"' - {0x40, 0xF0, 0xF0, 0x40, 0xF0, 0xF0, 0x40, /*0x00,*/ 0x04, 0x1F, 0x1F, 0x04, 0x1F, 0x1F, 0x04}, // , 0x00}, // '#' - {0x70, 0xF8, 0x88, 0x8F, 0x8F, 0x98, 0x30, /*0x00,*/ 0x06, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // , 0x00}, // '$' - {0x60, 0x60, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x18, 0x18}, // , 0x00}, // '%' - {0x00, 0xB0, 0xF8, 0xC8, 0x78, 0xB0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // '&' - {0x00, 0x20, 0x3E, 0x1E, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // ''' - {0x00, 0x00, 0xE0, 0xF0, 0x18, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x00}, // , 0x00}, // '(' - {0x00, 0x00, 0x08, 0x18, 0xF0, 0xE0, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x18, 0x0F, 0x07, 0x00}, // , 0x00}, // ')' - {0x00, 0x40, 0xC0, 0x80, 0x80, 0xC0, 0x40, /*0x00,*/ 0x01, 0x05, 0x07, 0x03, 0x03, 0x07, 0x05}, // , 0x01}, // '*' - {0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, /*0x00,*/ 0x00, 0x01, 0x01, 0x07, 0x07, 0x01, 0x01}, // , 0x00}, // '+' - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x20, 0x3C, 0x1C, 0x00, 0x00}, // , 0x00}, // ',' - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, // , 0x00}, // '-' - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, // , 0x00}, // '.' - {0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00}, // , 0x00}, // '/' - {0xF0, 0xF8, 0x08, 0x88, 0x48, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x12, 0x11, 0x10, 0x1F, 0x0F}, // , 0x00}, // '0' - {0x00, 0x20, 0x30, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10}, // , 0x00}, // '1' - {0x10, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x18}, // , 0x00}, // '2' - {0x10, 0x18, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '3' - {0x80, 0xC0, 0x60, 0x30, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x11, 0x1F, 0x1F, 0x11}, // , 0x00}, // '4' - {0xF8, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x08, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x11, 0x1F, 0x0F}, // , 0x00}, // '5' - {0xE0, 0xF0, 0x98, 0x88, 0x88, 0x80, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '6' - {0x18, 0x18, 0x08, 0x08, 0x88, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x1E, 0x1F, 0x01, 0x00, 0x00}, // , 0x00}, // '7' - {0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '8' - {0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0xF0, /*0x00,*/ 0x00, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // '9' - {0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // , 0x00}, // ':' - {0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1C, 0x0C, 0x00, 0x00}, // , 0x00}, // ';' - {0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x10, /*0x00,*/ 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18, 0x10}, // , 0x00}, // '<' - {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, // , 0x00}, // '=' - {0x00, 0x10, 0x30, 0x60, 0xC0, 0x80, 0x00, /*0x00,*/ 0x00, 0x10, 0x18, 0x0C, 0x06, 0x03, 0x01}, // , 0x00}, // '>' - {0x30, 0x38, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '?' - {0xE0, 0xF0, 0x10, 0x90, 0x90, 0xF0, 0xE0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x17, 0x17, 0x17, 0x03}, // , 0x00}, // '@' - {0xC0, 0xE0, 0x30, 0x18, 0x30, 0xE0, 0xC0, /*0x00,*/ 0x1F, 0x1F, 0x01, 0x01, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'A' - {0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'B' - {0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x10, 0x18, 0x0C}, // , 0x00}, // 'C' - {0x08, 0xF8, 0xF8, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'D' - {0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x11, 0x18, 0x1C}, // , 0x00}, // 'E' - {0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x01, 0x00, 0x00}, // , 0x00}, // 'F' - {0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x11, 0x11, 0x0F, 0x1F}, // , 0x00}, // 'G' - {0xF8, 0xF8, 0x80, 0x80, 0x80, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'H' - {0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'I' - {0x00, 0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, /*0x00,*/ 0x0E, 0x1E, 0x10, 0x10, 0x1F, 0x0F, 0x00}, // , 0x00}, // 'J' - {0x08, 0xF8, 0xF8, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x01, 0x03, 0x1E, 0x1C}, // , 0x00}, // 'K' - {0x08, 0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x18, 0x1C}, // , 0x00}, // 'L' - {0xF8, 0xF8, 0x70, 0xE0, 0x70, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'M' - {0xF8, 0xF8, 0x70, 0xE0, 0xC0, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'N' - {0xE0, 0xF0, 0x18, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'O' - {0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'P' - {0xF0, 0xF8, 0x08, 0x08, 0x08, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x1C, 0x78, 0x7F, 0x4F}, // , 0x00}, // 'Q' - {0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x01, 0x1F, 0x1E}, // , 0x00}, // 'R' - {0x30, 0x78, 0xC8, 0x88, 0x88, 0x38, 0x30, /*0x00,*/ 0x0C, 0x1C, 0x10, 0x10, 0x11, 0x1F, 0x0E}, // , 0x00}, // 'S' - {0x00, 0x38, 0x18, 0xF8, 0xF8, 0x18, 0x38, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'T' - {0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'U' - {0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x03, 0x07, 0x0C, 0x18, 0x0C, 0x07, 0x03}, // , 0x00}, // 'V' - {0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x07, 0x1F, 0x1C, 0x07, 0x1C, 0x1F, 0x07}, // , 0x00}, // 'W' - {0x18, 0x78, 0xE0, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x18, 0x1E, 0x07, 0x01, 0x07, 0x1E, 0x18}, // , 0x00}, // 'X' - {0x00, 0x78, 0xF8, 0x80, 0x80, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'Y' - {0x38, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x38, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x1C}, // , 0x00}, // 'Z' - {0x00, 0x00, 0xF8, 0xF8, 0x08, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x00}, // , 0x00}, // '[' - {0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x1C}, // , 0x00}, // '"\' - {0x00, 0x00, 0x08, 0x08, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x00}, // , 0x00}, // ']' - {0x10, 0x18, 0x0E, 0x07, 0x0E, 0x18, 0x10, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '^' - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, // , 0x40}, // '_' - {0x00, 0x00, 0x07, 0x0F, 0x08, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '`' - {0x00, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x0E, 0x1F, 0x11, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'a' - {0x08, 0xF8, 0xF8, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x10, 0x1F, 0x0F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'b' - {0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x18, 0x08}, // , 0x00}, // 'c' - {0x00, 0x80, 0xC0, 0x48, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'd' - {0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x11, 0x11, 0x11, 0x19, 0x09}, // , 0x00}, // 'e' - {0x80, 0xF0, 0xF8, 0x88, 0x18, 0x30, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'f' - {0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x4F, 0xDF, 0x90, 0x90, 0xFF, 0x7F, 0x00}, // , 0x00}, // 'g' - {0x08, 0xF8, 0xF8, 0x80, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'h' - {0x00, 0x00, 0x40, 0xD8, 0xD8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'i' - {0x00, 0x00, 0x00, 0x00, 0x40, 0xD8, 0xD8, /*0x00,*/ 0x00, 0x60, 0xE0, 0x80, 0x80, 0xFF, 0x7F}, // , 0x00}, // 'j' - {0x08, 0xF8, 0xF8, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x03, 0x07, 0x1C, 0x18}, // , 0x00}, // 'k' - {0x00, 0x00, 0x08, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'l' - {0xC0, 0xC0, 0xC0, 0x80, 0xC0, 0xC0, 0x80, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'm' - {0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'n' - {0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'o' - {0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x80, 0xFF, 0xFF, 0x90, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'p' - {0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x90, 0xFF, 0xFF, 0x80}, // , 0x00}, // 'q' - {0x40, 0xC0, 0x80, 0xC0, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x01}, // , 0x00}, // 'r' - {0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x08, 0x19, 0x13, 0x12, 0x16, 0x1C, 0x08}, // , 0x00}, // 's' - {0x40, 0x40, 0xF0, 0xF8, 0x40, 0x40, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x18, 0x08}, // , 0x00}, // 't' - {0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'u' - {0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x00, 0x07, 0x0F, 0x18, 0x18, 0x0F, 0x07}, // , 0x00}, // 'v' - {0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x0F, 0x1F, 0x18, 0x0E, 0x18, 0x1F, 0x0F}, // , 0x00}, // 'w' - {0x40, 0xC0, 0x80, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x18, 0x0F, 0x07, 0x0F, 0x18, 0x10}, // , 0x00}, // 'x' - {0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x8F, 0x9F, 0x90, 0x90, 0xD0, 0x7F, 0x3F}, // , 0x00}, // 'y' - {0xC0, 0xC0, 0x40, 0x40, 0xC0, 0xC0, 0x40, /*0x00,*/ 0x18, 0x1C, 0x16, 0x13, 0x11, 0x18, 0x18}, // , 0x00}, // 'z' - {0x00, 0x80, 0x80, 0xF0, 0x78, 0x08, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10}, // , 0x00}, // '{' - {0x00, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00}, // , 0x00}, // '|' - {0x00, 0x08, 0x08, 0x78, 0xF0, 0x80, 0x80, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x0F, 0x00, 0x00}, // , 0x00}, // '}' - {0x10, 0x18, 0x08, 0x18, 0x10, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // , 0x00} // '->' + {0x00, 0x00, 0x70, 0xF8, 0xF8, 0x70, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '!' + {0x00, 0x1E, 0x3E, 0x00, 0x00, 0x3E, 0x1E, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '"' + {0x40, 0xF0, 0xF0, 0x40, 0xF0, 0xF0, 0x40, /*0x00,*/ 0x04, 0x1F, 0x1F, 0x04, 0x1F, 0x1F, 0x04}, // , 0x00}, // '#' + {0x70, 0xF8, 0x88, 0x8F, 0x8F, 0x98, 0x30, /*0x00,*/ 0x06, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // , 0x00}, // '$' + {0x60, 0x60, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x18, 0x18}, // , 0x00}, // '%' + {0x00, 0xB0, 0xF8, 0xC8, 0x78, 0xB0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // '&' + {0x00, 0x20, 0x3E, 0x1E, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // ''' + {0x00, 0x00, 0xE0, 0xF0, 0x18, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x00}, // , 0x00}, // '(' + {0x00, 0x00, 0x08, 0x18, 0xF0, 0xE0, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x18, 0x0F, 0x07, 0x00}, // , 0x00}, // ')' + {0x00, 0x40, 0xC0, 0x80, 0x80, 0xC0, 0x40, /*0x00,*/ 0x01, 0x05, 0x07, 0x03, 0x03, 0x07, 0x05}, // , 0x01}, // '*' + {0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, /*0x00,*/ 0x00, 0x01, 0x01, 0x07, 0x07, 0x01, 0x01}, // , 0x00}, // '+' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x20, 0x3C, 0x1C, 0x00, 0x00}, // , 0x00}, // ',' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, // , 0x00}, // '-' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, // , 0x00}, // '.' + {0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00}, // , 0x00}, // '/' + {0xF0, 0xF8, 0x08, 0x88, 0x48, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x12, 0x11, 0x10, 0x1F, 0x0F}, // , 0x00}, // '0' + {0x00, 0x20, 0x30, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10}, // , 0x00}, // '1' + {0x10, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x18}, // , 0x00}, // '2' + {0x10, 0x18, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '3' + {0x80, 0xC0, 0x60, 0x30, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x11, 0x1F, 0x1F, 0x11}, // , 0x00}, // '4' + {0xF8, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x08, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x11, 0x1F, 0x0F}, // , 0x00}, // '5' + {0xE0, 0xF0, 0x98, 0x88, 0x88, 0x80, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '6' + {0x18, 0x18, 0x08, 0x08, 0x88, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x1E, 0x1F, 0x01, 0x00, 0x00}, // , 0x00}, // '7' + {0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '8' + {0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0xF0, /*0x00,*/ 0x00, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // '9' + {0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // , 0x00}, // ':' + {0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1C, 0x0C, 0x00, 0x00}, // , 0x00}, // ';' + {0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x10, /*0x00,*/ 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18, 0x10}, // , 0x00}, // '<' + {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, // , 0x00}, // '=' + {0x00, 0x10, 0x30, 0x60, 0xC0, 0x80, 0x00, /*0x00,*/ 0x00, 0x10, 0x18, 0x0C, 0x06, 0x03, 0x01}, // , 0x00}, // '>' + {0x30, 0x38, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '?' + {0xE0, 0xF0, 0x10, 0x90, 0x90, 0xF0, 0xE0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x17, 0x17, 0x17, 0x03}, // , 0x00}, // '@' + {0xC0, 0xE0, 0x30, 0x18, 0x30, 0xE0, 0xC0, /*0x00,*/ 0x1F, 0x1F, 0x01, 0x01, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'A' + {0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'B' + {0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x10, 0x18, 0x0C}, // , 0x00}, // 'C' + {0x08, 0xF8, 0xF8, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'D' + {0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x11, 0x18, 0x1C}, // , 0x00}, // 'E' + {0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x01, 0x00, 0x00}, // , 0x00}, // 'F' + {0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x11, 0x11, 0x0F, 0x1F}, // , 0x00}, // 'G' + {0xF8, 0xF8, 0x80, 0x80, 0x80, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'H' + {0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'I' + {0x00, 0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, /*0x00,*/ 0x0E, 0x1E, 0x10, 0x10, 0x1F, 0x0F, 0x00}, // , 0x00}, // 'J' + {0x08, 0xF8, 0xF8, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x01, 0x03, 0x1E, 0x1C}, // , 0x00}, // 'K' + {0x08, 0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x18, 0x1C}, // , 0x00}, // 'L' + {0xF8, 0xF8, 0x70, 0xE0, 0x70, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'M' + {0xF8, 0xF8, 0x70, 0xE0, 0xC0, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'N' + {0xE0, 0xF0, 0x18, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'O' + {0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'P' + {0xF0, 0xF8, 0x08, 0x08, 0x08, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x1C, 0x78, 0x7F, 0x4F}, // , 0x00}, // 'Q' + {0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x01, 0x1F, 0x1E}, // , 0x00}, // 'R' + {0x30, 0x78, 0xC8, 0x88, 0x88, 0x38, 0x30, /*0x00,*/ 0x0C, 0x1C, 0x10, 0x10, 0x11, 0x1F, 0x0E}, // , 0x00}, // 'S' + {0x00, 0x38, 0x18, 0xF8, 0xF8, 0x18, 0x38, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'T' + {0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'U' + {0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x03, 0x07, 0x0C, 0x18, 0x0C, 0x07, 0x03}, // , 0x00}, // 'V' + {0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x07, 0x1F, 0x1C, 0x07, 0x1C, 0x1F, 0x07}, // , 0x00}, // 'W' + {0x18, 0x78, 0xE0, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x18, 0x1E, 0x07, 0x01, 0x07, 0x1E, 0x18}, // , 0x00}, // 'X' + {0x00, 0x78, 0xF8, 0x80, 0x80, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'Y' + {0x38, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x38, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x1C}, // , 0x00}, // 'Z' + {0x00, 0x00, 0xF8, 0xF8, 0x08, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x00}, // , 0x00}, // '[' + {0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x1C}, // , 0x00}, // '"\' + {0x00, 0x00, 0x08, 0x08, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x00}, // , 0x00}, // ']' + {0x10, 0x18, 0x0E, 0x07, 0x0E, 0x18, 0x10, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '^' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, // , 0x40}, // '_' + {0x00, 0x00, 0x07, 0x0F, 0x08, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '`' + {0x00, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x0E, 0x1F, 0x11, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'a' + {0x08, 0xF8, 0xF8, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x10, 0x1F, 0x0F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'b' + {0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x18, 0x08}, // , 0x00}, // 'c' + {0x00, 0x80, 0xC0, 0x48, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'd' + {0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x11, 0x11, 0x11, 0x19, 0x09}, // , 0x00}, // 'e' + {0x80, 0xF0, 0xF8, 0x88, 0x18, 0x30, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'f' + {0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x4F, 0xDF, 0x90, 0x90, 0xFF, 0x7F, 0x00}, // , 0x00}, // 'g' + {0x08, 0xF8, 0xF8, 0x80, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'h' + {0x00, 0x00, 0x40, 0xD8, 0xD8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'i' + {0x00, 0x00, 0x00, 0x00, 0x40, 0xD8, 0xD8, /*0x00,*/ 0x00, 0x60, 0xE0, 0x80, 0x80, 0xFF, 0x7F}, // , 0x00}, // 'j' + {0x08, 0xF8, 0xF8, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x03, 0x07, 0x1C, 0x18}, // , 0x00}, // 'k' + {0x00, 0x00, 0x08, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'l' + {0xC0, 0xC0, 0xC0, 0x80, 0xC0, 0xC0, 0x80, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'm' + {0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'n' + {0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'o' + {0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x80, 0xFF, 0xFF, 0x90, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'p' + {0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x90, 0xFF, 0xFF, 0x80}, // , 0x00}, // 'q' + {0x40, 0xC0, 0x80, 0xC0, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x01}, // , 0x00}, // 'r' + {0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x08, 0x19, 0x13, 0x12, 0x16, 0x1C, 0x08}, // , 0x00}, // 's' + {0x40, 0x40, 0xF0, 0xF8, 0x40, 0x40, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x18, 0x08}, // , 0x00}, // 't' + {0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'u' + {0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x00, 0x07, 0x0F, 0x18, 0x18, 0x0F, 0x07}, // , 0x00}, // 'v' + {0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x0F, 0x1F, 0x18, 0x0E, 0x18, 0x1F, 0x0F}, // , 0x00}, // 'w' + {0x40, 0xC0, 0x80, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x18, 0x0F, 0x07, 0x0F, 0x18, 0x10}, // , 0x00}, // 'x' + {0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x8F, 0x9F, 0x90, 0x90, 0xD0, 0x7F, 0x3F}, // , 0x00}, // 'y' + {0xC0, 0xC0, 0x40, 0x40, 0xC0, 0xC0, 0x40, /*0x00,*/ 0x18, 0x1C, 0x16, 0x13, 0x11, 0x18, 0x18}, // , 0x00}, // 'z' + {0x00, 0x80, 0x80, 0xF0, 0x78, 0x08, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10}, // , 0x00}, // '{' + {0x00, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00}, // , 0x00}, // '|' + {0x00, 0x08, 0x08, 0x78, 0xF0, 0x80, 0x80, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x0F, 0x00, 0x00}, // , 0x00}, // '}' + {0x10, 0x18, 0x08, 0x18, 0x10, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // , 0x00} // '->' #else // {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' ' - {0x00, 0x00, 0x00, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '!' - {0x00, 0x0F, 0x1F, 0x00, 0x00, 0x1F, 0x0F, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '"' - {0x20, 0xF8, 0xF8, 0x20, 0xF8, 0xF8, 0x20, /*0x00,*/ 0x02, 0x0F, 0x0F, 0x02, 0x0F, 0x0F, 0x02}, // '#' - {0x70, 0xF8, 0x88, 0x8E, 0x8E, 0x98, 0x10, /*0x00,*/ 0x04, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // '$' - {0x30, 0x30, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x0C, 0x0C}, // '%' - {0x80, 0xD8, 0x7C, 0xE4, 0xBC, 0xD8, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x07, 0x0F, 0x08}, // '&' - {0x00, 0x10, 0x1F, 0x0F, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ''' - {0x00, 0x00, 0xF0, 0xF8, 0x0C, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x03, 0x07, 0x0C, 0x08, 0x00}, // '(' - {0x00, 0x00, 0x04, 0x0C, 0xF8, 0xF0, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0C, 0x07, 0x03, 0x00}, // ')' - {0x00, 0x80, 0xA0, 0xE0, 0xC0, 0xE0, 0xA0, /*0x80,*/ 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x02}, // '*' - {0x00, 0x80, 0x80, 0xE0, 0xE0, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00}, // '+' - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1E, 0x0E, 0x00, 0x00}, // ',' - {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '-' - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // '.' - {0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00}, // '/' - {0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '0' - {0x00, 0x10, 0x18, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08}, // '1' - {0x18, 0x1C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // '2' - {0x18, 0x1C, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '3' - {0x80, 0xC0, 0x60, 0x30, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x0F}, // '4' - {0x7C, 0x7C, 0x44, 0x44, 0x44, 0xC4, 0x84, /*0x00,*/ 0x04, 0x0C, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '5' - {0xF0, 0xF8, 0x4C, 0x44, 0x44, 0xC4, 0x80, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '6' - {0x04, 0x04, 0x04, 0x84, 0xE4, 0x7C, 0x1C, /*0x00,*/ 0x00, 0x00, 0x0E, 0x0F, 0x01, 0x00, 0x00}, // '7' - {0xB8, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '8' - {0x78, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x00, 0x08, 0x08, 0x08, 0x0C, 0x07, 0x03}, // '9' - {0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00}, // ':' - {0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0E, 0x06, 0x00, 0x00}, // ';' - {0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x08}, // '<' - {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /*0x00,*/ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}, // '=' - {0x00, 0x08, 0x18, 0x30, 0x60, 0xC0, 0x80, /*0x00,*/ 0x00, 0x08, 0x0C, 0x06, 0x03, 0x01, 0x00}, // '>' - {0x38, 0x3C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '?' - {0xF0, 0xF8, 0x08, 0xC8, 0xC8, 0xF8, 0xF0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x01}, // '@' - {0xF8, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'A' - {0xFC, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'B' - {0xF8, 0xFC, 0x04, 0x04, 0x04, 0x1C, 0x18, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0E, 0x06}, // 'C' - {0xFC, 0xFC, 0x04, 0x04, 0x0C, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x0C, 0x07, 0x03}, // 'D' - {0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'E' - {0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'F' - {0xF8, 0xFC, 0x04, 0x84, 0x84, 0x9C, 0x98, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'G' - {0xFC, 0xFC, 0x40, 0x40, 0x40, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'H' - {0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'I' - {0x00, 0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x0F, 0x07, 0x00}, // 'J' - {0xFC, 0xFC, 0xE0, 0x30, 0x18, 0x0C, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'K' - {0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'L' - {0xFC, 0xFC, 0x18, 0x70, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'M' - {0xFC, 0xFC, 0x60, 0xC0, 0x80, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0F}, // 'N' - {0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'O' - {0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'P' - {0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0C, 0x0C, 0x1F, 0x17}, // 'Q' - {0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'R' - {0x38, 0x7C, 0x44, 0x44, 0x44, 0xCC, 0x88, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'S' - {0x00, 0x04, 0x04, 0xFC, 0xFC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'T' - {0xFC, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'U' - {0x7C, 0xFC, 0x80, 0x00, 0x80, 0xFC, 0x7C, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'V' - {0xFC, 0xFC, 0x00, 0x80, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x06, 0x03, 0x06, 0x0F, 0x0F}, // 'W' - {0x0C, 0x3C, 0xF0, 0xC0, 0xF0, 0x3C, 0x0C, /*0x00,*/ 0x0C, 0x0F, 0x03, 0x00, 0x03, 0x0F, 0x0C}, // 'X' - {0x00, 0x3C, 0x7C, 0xC0, 0xC0, 0x7C, 0x3C, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'Y' - {0x04, 0x04, 0x84, 0xC4, 0x64, 0x3C, 0x1C, /*0x00,*/ 0x0E, 0x0F, 0x09, 0x08, 0x08, 0x08, 0x08}, // 'Z' - {0x00, 0x00, 0xFC, 0xFC, 0x04, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x00}, // '[' - {0x38, 0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E}, // '"\' - {0x00, 0x00, 0x04, 0x04, 0xFC, 0xFC, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x00}, // ']' - {0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '^' - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, // '_' - {0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '`' - {0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'a' - {0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'b' - {0xC0, 0xE0, 0x20, 0x20, 0x20, 0x60, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0C, 0x04}, // 'c' - {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'd' - {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x09, 0x09, 0x09, 0x09, 0x01}, // 'e' - {0x20, 0x20, 0xF8, 0xFC, 0x24, 0x24, 0x04, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00}, // 'f' - {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'g' - {0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'h' - {0x00, 0x00, 0x20, 0xEC, 0xEC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'i' - {0x00, 0x00, 0x00, 0x00, 0x20, 0xEC, 0xEC, /*0x00,*/ 0x00, 0x30, 0x70, 0x40, 0x40, 0x7F, 0x3F}, // 'j' - {0xFC, 0xFC, 0x00, 0x80, 0xC0, 0x60, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'k' - {0x00, 0x00, 0x04, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'l' - {0xE0, 0xE0, 0x20, 0xE0, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x0F}, // 'm' - {0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'n' - {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'o' - {0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x7F, 0x7F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'p' - {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x7F, 0x7F}, // 'q' - {0xE0, 0xE0, 0x60, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'r' - {0xC0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x08, 0x09, 0x09, 0x09, 0x09, 0x0F, 0x06}, // 's' - {0x20, 0x20, 0xFC, 0xFC, 0x20, 0x20, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08}, // 't' - {0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'u' - {0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'v' - {0xE0, 0xE0, 0x00, 0x80, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0F, 0x08, 0x0F, 0x07}, // 'w' - {0x60, 0xE0, 0x80, 0x00, 0x80, 0xE0, 0x60, /*0x00,*/ 0x0C, 0x0E, 0x03, 0x01, 0x03, 0x0E, 0x0C}, // 'x' - {0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'y' - {0x20, 0x20, 0x20, 0xA0, 0xE0, 0x60, 0x20, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // 'z' - {0x00, 0x00, 0x40, 0xF8, 0xBC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08}, // '{' - {0x00, 0x00, 0x00, 0xBC, 0xBC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // '|' - {0x00, 0x04, 0x04, 0xBC, 0xF8, 0x40, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x07, 0x00, 0x00}, // '}' - {0x08, 0x0C, 0x04, 0x0C, 0x08, 0x0C, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // '->' + {0x00, 0x00, 0x00, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '!' + {0x00, 0x0F, 0x1F, 0x00, 0x00, 0x1F, 0x0F, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '"' + {0x20, 0xF8, 0xF8, 0x20, 0xF8, 0xF8, 0x20, /*0x00,*/ 0x02, 0x0F, 0x0F, 0x02, 0x0F, 0x0F, 0x02}, // '#' + {0x70, 0xF8, 0x88, 0x8E, 0x8E, 0x98, 0x10, /*0x00,*/ 0x04, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // '$' + {0x30, 0x30, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x0C, 0x0C}, // '%' + {0x80, 0xD8, 0x7C, 0xE4, 0xBC, 0xD8, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x07, 0x0F, 0x08}, // '&' + {0x00, 0x10, 0x1F, 0x0F, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ''' + {0x00, 0x00, 0xF0, 0xF8, 0x0C, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x03, 0x07, 0x0C, 0x08, 0x00}, // '(' + {0x00, 0x00, 0x04, 0x0C, 0xF8, 0xF0, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0C, 0x07, 0x03, 0x00}, // ')' + {0x00, 0x80, 0xA0, 0xE0, 0xC0, 0xE0, 0xA0, /*0x80,*/ 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x02}, // '*' + {0x00, 0x80, 0x80, 0xE0, 0xE0, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00}, // '+' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1E, 0x0E, 0x00, 0x00}, // ',' + {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '-' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // '.' + {0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00}, // '/' + {0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '0' + {0x00, 0x10, 0x18, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08}, // '1' + {0x18, 0x1C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // '2' + {0x18, 0x1C, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '3' + {0x80, 0xC0, 0x60, 0x30, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x0F}, // '4' + {0x7C, 0x7C, 0x44, 0x44, 0x44, 0xC4, 0x84, /*0x00,*/ 0x04, 0x0C, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '5' + {0xF0, 0xF8, 0x4C, 0x44, 0x44, 0xC4, 0x80, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '6' + {0x04, 0x04, 0x04, 0x84, 0xE4, 0x7C, 0x1C, /*0x00,*/ 0x00, 0x00, 0x0E, 0x0F, 0x01, 0x00, 0x00}, // '7' + {0xB8, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '8' + {0x78, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x00, 0x08, 0x08, 0x08, 0x0C, 0x07, 0x03}, // '9' + {0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00}, // ':' + {0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0E, 0x06, 0x00, 0x00}, // ';' + {0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x08}, // '<' + {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /*0x00,*/ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}, // '=' + {0x00, 0x08, 0x18, 0x30, 0x60, 0xC0, 0x80, /*0x00,*/ 0x00, 0x08, 0x0C, 0x06, 0x03, 0x01, 0x00}, // '>' + {0x38, 0x3C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '?' + {0xF0, 0xF8, 0x08, 0xC8, 0xC8, 0xF8, 0xF0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x01}, // '@' + {0xF8, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'A' + {0xFC, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'B' + {0xF8, 0xFC, 0x04, 0x04, 0x04, 0x1C, 0x18, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0E, 0x06}, // 'C' + {0xFC, 0xFC, 0x04, 0x04, 0x0C, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x0C, 0x07, 0x03}, // 'D' + {0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'E' + {0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'F' + {0xF8, 0xFC, 0x04, 0x84, 0x84, 0x9C, 0x98, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'G' + {0xFC, 0xFC, 0x40, 0x40, 0x40, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'H' + {0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'I' + {0x00, 0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x0F, 0x07, 0x00}, // 'J' + {0xFC, 0xFC, 0xE0, 0x30, 0x18, 0x0C, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'K' + {0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'L' + {0xFC, 0xFC, 0x18, 0x70, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'M' + {0xFC, 0xFC, 0x60, 0xC0, 0x80, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0F}, // 'N' + {0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'O' + {0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'P' + {0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0C, 0x0C, 0x1F, 0x17}, // 'Q' + {0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'R' + {0x38, 0x7C, 0x44, 0x44, 0x44, 0xCC, 0x88, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'S' + {0x00, 0x04, 0x04, 0xFC, 0xFC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'T' + {0xFC, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'U' + {0x7C, 0xFC, 0x80, 0x00, 0x80, 0xFC, 0x7C, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'V' + {0xFC, 0xFC, 0x00, 0x80, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x06, 0x03, 0x06, 0x0F, 0x0F}, // 'W' + {0x0C, 0x3C, 0xF0, 0xC0, 0xF0, 0x3C, 0x0C, /*0x00,*/ 0x0C, 0x0F, 0x03, 0x00, 0x03, 0x0F, 0x0C}, // 'X' + {0x00, 0x3C, 0x7C, 0xC0, 0xC0, 0x7C, 0x3C, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'Y' + {0x04, 0x04, 0x84, 0xC4, 0x64, 0x3C, 0x1C, /*0x00,*/ 0x0E, 0x0F, 0x09, 0x08, 0x08, 0x08, 0x08}, // 'Z' + {0x00, 0x00, 0xFC, 0xFC, 0x04, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x00}, // '[' + {0x38, 0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E}, // '"\' + {0x00, 0x00, 0x04, 0x04, 0xFC, 0xFC, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x00}, // ']' + {0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '^' + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, // '_' + {0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '`' + {0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'a' + {0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'b' + {0xC0, 0xE0, 0x20, 0x20, 0x20, 0x60, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0C, 0x04}, // 'c' + {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'd' + {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x09, 0x09, 0x09, 0x09, 0x01}, // 'e' + {0x20, 0x20, 0xF8, 0xFC, 0x24, 0x24, 0x04, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00}, // 'f' + {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'g' + {0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'h' + {0x00, 0x00, 0x20, 0xEC, 0xEC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'i' + {0x00, 0x00, 0x00, 0x00, 0x20, 0xEC, 0xEC, /*0x00,*/ 0x00, 0x30, 0x70, 0x40, 0x40, 0x7F, 0x3F}, // 'j' + {0xFC, 0xFC, 0x00, 0x80, 0xC0, 0x60, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'k' + {0x00, 0x00, 0x04, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'l' + {0xE0, 0xE0, 0x20, 0xE0, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x0F}, // 'm' + {0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'n' + {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'o' + {0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x7F, 0x7F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'p' + {0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x7F, 0x7F}, // 'q' + {0xE0, 0xE0, 0x60, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'r' + {0xC0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x08, 0x09, 0x09, 0x09, 0x09, 0x0F, 0x06}, // 's' + {0x20, 0x20, 0xFC, 0xFC, 0x20, 0x20, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08}, // 't' + {0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'u' + {0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'v' + {0xE0, 0xE0, 0x00, 0x80, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0F, 0x08, 0x0F, 0x07}, // 'w' + {0x60, 0xE0, 0x80, 0x00, 0x80, 0xE0, 0x60, /*0x00,*/ 0x0C, 0x0E, 0x03, 0x01, 0x03, 0x0E, 0x0C}, // 'x' + {0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'y' + {0x20, 0x20, 0x20, 0xA0, 0xE0, 0x60, 0x20, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // 'z' + {0x00, 0x00, 0x40, 0xF8, 0xBC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08}, // '{' + {0x00, 0x00, 0x00, 0xBC, 0xBC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // '|' + {0x00, 0x04, 0x04, 0xBC, 0xF8, 0x40, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x07, 0x00, 0x00}, // '}' + {0x08, 0x0C, 0x04, 0x0C, 0x08, 0x0C, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // '->' #endif }; #if 0 - // original font - const uint8_t gFontBigDigits[11][26] = - { - {0x00, 0xC0, 0xF0, 0xF8, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1C, 0xF8, 0xF0, 0xE0, 0x00, 0x07, 0x1F, 0x3F, 0x78, 0x60, 0x60, 0x60, 0x60, 0x70, 0x3F, 0x1F, 0x0F}, - {0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x10, 0x38, 0x38, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0xFC, 0xF8, 0xF0, 0x00, 0x00, 0x70, 0x78, 0x7C, 0x7C, 0x6E, 0x66, 0x67, 0x67, 0x63, 0x61, 0x60, 0x00}, - {0x00, 0x10, 0x18, 0x18, 0x9C, 0x8C, 0x8C, 0x8C, 0x8C, 0xCC, 0xF8, 0xF8, 0x70, 0x00, 0x30, 0x30, 0x30, 0x71, 0x61, 0x61, 0x61, 0x61, 0x71, 0x3F, 0x3F, 0x1E}, - {0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x1C, 0x1E, 0x1F, 0x1F, 0x19, 0x18, 0x18, 0x18, 0x7F, 0x7F, 0x7F, 0x18}, - {0x00, 0x00, 0xFC, 0xFC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x8C, 0x0C, 0x00, 0x00, 0x18, 0x30, 0x70, 0x60, 0x60, 0x60, 0x60, 0x71, 0x7B, 0x3F, 0x1F}, - {0x00, 0xC0, 0xF0, 0xF8, 0x38, 0x9C, 0x8C, 0x8C, 0x8C, 0x8C, 0x9C, 0x38, 0x30, 0x00, 0x0F, 0x1F, 0x3F, 0x73, 0x61, 0x61, 0x61, 0x61, 0x73, 0x33, 0x3F, 0x1E}, - {0x00, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x8C, 0xEC, 0xFC, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x40, 0x60, 0x78, 0x7C, 0x1F, 0x07, 0x03, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x78, 0xF8, 0xDC, 0x8C, 0x8C, 0x8C, 0x8C, 0xDC, 0xF8, 0x78, 0x00, 0x00, 0x1E, 0x3F, 0x3F, 0x73, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x3F, 0x1E}, - {0x00, 0xF0, 0xF8, 0xB8, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1C, 0xB8, 0xF0, 0xE0, 0x00, 0x11, 0x33, 0x77, 0x67, 0x66, 0x66, 0x66, 0x76, 0x33, 0x3F, 0x1F, 0x07}, - {0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} - }; + // original font + const uint8_t gFontBigDigits[11][26] = + { + {0x00, 0xC0, 0xF0, 0xF8, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1C, 0xF8, 0xF0, 0xE0, 0x00, 0x07, 0x1F, 0x3F, 0x78, 0x60, 0x60, 0x60, 0x60, 0x70, 0x3F, 0x1F, 0x0F}, + {0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x10, 0x38, 0x38, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0xFC, 0xF8, 0xF0, 0x00, 0x00, 0x70, 0x78, 0x7C, 0x7C, 0x6E, 0x66, 0x67, 0x67, 0x63, 0x61, 0x60, 0x00}, + {0x00, 0x10, 0x18, 0x18, 0x9C, 0x8C, 0x8C, 0x8C, 0x8C, 0xCC, 0xF8, 0xF8, 0x70, 0x00, 0x30, 0x30, 0x30, 0x71, 0x61, 0x61, 0x61, 0x61, 0x71, 0x3F, 0x3F, 0x1E}, + {0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x1C, 0x1E, 0x1F, 0x1F, 0x19, 0x18, 0x18, 0x18, 0x7F, 0x7F, 0x7F, 0x18}, + {0x00, 0x00, 0xFC, 0xFC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x8C, 0x0C, 0x00, 0x00, 0x18, 0x30, 0x70, 0x60, 0x60, 0x60, 0x60, 0x71, 0x7B, 0x3F, 0x1F}, + {0x00, 0xC0, 0xF0, 0xF8, 0x38, 0x9C, 0x8C, 0x8C, 0x8C, 0x8C, 0x9C, 0x38, 0x30, 0x00, 0x0F, 0x1F, 0x3F, 0x73, 0x61, 0x61, 0x61, 0x61, 0x73, 0x33, 0x3F, 0x1E}, + {0x00, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x8C, 0xEC, 0xFC, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x40, 0x60, 0x78, 0x7C, 0x1F, 0x07, 0x03, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x78, 0xF8, 0xDC, 0x8C, 0x8C, 0x8C, 0x8C, 0xDC, 0xF8, 0x78, 0x00, 0x00, 0x1E, 0x3F, 0x3F, 0x73, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x3F, 0x1E}, + {0x00, 0xF0, 0xF8, 0xB8, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1C, 0xB8, 0xF0, 0xE0, 0x00, 0x11, 0x33, 0x77, 0x67, 0x66, 0x66, 0x66, 0x76, 0x33, 0x3F, 0x1F, 0x07}, + {0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} + }; - // 6 Empty columns removed + // 6 Empty columns removed #elif 0 - // VCR font - const uint8_t gFontBigDigits[11][26 - 6] = - { - {/*0x00, 0x00,*/ 0xF8, 0xFC, 0x06, 0x86, 0xC6, 0xE6, 0xF6, 0x76, 0xFC, 0xF8, /*0x00,*/ /*0x00, 0x00,*/ 0x1F, 0x3F, 0x77, 0x67, 0x63, 0x61, 0x60, 0x70, 0x3F, 0x1F, /*0x00*/}, - {/*0x00, 0x00,*/ 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x60, 0x60, 0x00, 0x00, /*0x00*/}, - {/*0x00, 0x00,*/ 0x18, 0x1C, 0x86, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x7E, 0x7F, 0x63, 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x60, /*0x00*/}, - {/*0x00, 0x00,*/ 0x18, 0x1C, 0x06, 0x06, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x70, 0x60, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/}, - {/*0x00, 0x00,*/ 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0xFE, 0xFE, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x7F, 0x7F, 0x06, 0x06, /*0x00*/}, - {/*0x00, 0x00,*/ 0x7E, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x66, 0xE6, 0xC6, 0x86, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x70, 0x60, 0x60, 0x60, 0x60, 0x70, 0x3F, 0x1F, /*0x00*/}, - {/*0x00, 0x00,*/ 0xF8, 0xFC, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x1C, 0x18, /*0x00,*/ /*0x00, 0x00,*/ 0x1F, 0x3F, 0x71, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/}, - {/*0x00, 0x00,*/ 0x06, 0x06, 0x06, 0x06, 0x06, 0x86, 0xC6, 0xE6, 0x7E, 0x3E, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, /*0x00*/}, - {/*0x00, 0x00,*/ 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x1E, 0x3F, 0x73, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/}, - {/*0x00, 0x00,*/ 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0x86, 0xFC, 0xF8, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x71, 0x61, 0x61, 0x61, 0x61, 0x71, 0x3F, 0x1F, /*0x00*/}, - {/*0x00, 0x00,*/ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, /*0x00*/} - }; + // VCR font + const uint8_t gFontBigDigits[11][26 - 6] = + { + {/*0x00, 0x00,*/ 0xF8, 0xFC, 0x06, 0x86, 0xC6, 0xE6, 0xF6, 0x76, 0xFC, 0xF8, /*0x00,*/ /*0x00, 0x00,*/ 0x1F, 0x3F, 0x77, 0x67, 0x63, 0x61, 0x60, 0x70, 0x3F, 0x1F, /*0x00*/}, + {/*0x00, 0x00,*/ 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x60, 0x60, 0x00, 0x00, /*0x00*/}, + {/*0x00, 0x00,*/ 0x18, 0x1C, 0x86, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x7E, 0x7F, 0x63, 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x60, /*0x00*/}, + {/*0x00, 0x00,*/ 0x18, 0x1C, 0x06, 0x06, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x70, 0x60, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/}, + {/*0x00, 0x00,*/ 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0xFE, 0xFE, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x7F, 0x7F, 0x06, 0x06, /*0x00*/}, + {/*0x00, 0x00,*/ 0x7E, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x66, 0xE6, 0xC6, 0x86, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x70, 0x60, 0x60, 0x60, 0x60, 0x70, 0x3F, 0x1F, /*0x00*/}, + {/*0x00, 0x00,*/ 0xF8, 0xFC, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x1C, 0x18, /*0x00,*/ /*0x00, 0x00,*/ 0x1F, 0x3F, 0x71, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/}, + {/*0x00, 0x00,*/ 0x06, 0x06, 0x06, 0x06, 0x06, 0x86, 0xC6, 0xE6, 0x7E, 0x3E, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, /*0x00*/}, + {/*0x00, 0x00,*/ 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x1E, 0x3F, 0x73, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/}, + {/*0x00, 0x00,*/ 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0x86, 0xFC, 0xF8, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x71, 0x61, 0x61, 0x61, 0x61, 0x71, 0x3F, 0x1F, /*0x00*/}, + {/*0x00, 0x00,*/ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, /*0x00*/} + }; #else - // Terminus font + // Terminus font - const uint8_t gFontBigDigits[11][26 - 6] = - { - {/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/}, - {/*0x00, 0x00,*/ 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x7F, 0x60, 0x60, 0x00, /*0x00*/}, - {/*0x00, 0x00,*/ 0x1C, 0x1E, 0x1E, 0x06, 0x06, 0x06, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x60, 0x70, 0x78, 0x7C, 0x6E, 0x67, 0x63, 0x61, 0x60, 0x60, /*0x00*/}, - {/*0x00, 0x00,*/ 0x0C, 0x0E, 0x0E, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3E, /*0x00*/}, - {/*0x00, 0x00,*/ 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0xFE, 0xFE, 0xFE, /*0x00,*/ /*0x00, 0x00,*/ 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x7F, 0x7F, 0x7F, /*0x00*/}, - {/*0x00, 0x00,*/ 0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x86, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/}, - {/*0x00, 0x00,*/ 0xF8, 0xFC, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x80, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/}, - {/*0x00, 0x00,*/ 0x0E, 0x0E, 0x0E, 0x06, 0x06, 0x86, 0xE6, 0xFE, 0x7E, 0x1E, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7F, 0x7F, 0x03, 0x00, 0x00, /*0x00*/}, - {/*0x00, 0x00,*/ 0x7C, 0xFE, 0xFE, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3F, /*0x00*/}, - {/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x01, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7F, 0x3F, 0x1F, /*0x00*/}, - {/*0x00, 0x00,*/ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, /*0x00*/} - }; + const uint8_t gFontBigDigits[11][26 - 6] = + { + {/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/}, + {/*0x00, 0x00,*/ 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x7F, 0x60, 0x60, 0x00, /*0x00*/}, + {/*0x00, 0x00,*/ 0x1C, 0x1E, 0x1E, 0x06, 0x06, 0x06, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x60, 0x70, 0x78, 0x7C, 0x6E, 0x67, 0x63, 0x61, 0x60, 0x60, /*0x00*/}, + {/*0x00, 0x00,*/ 0x0C, 0x0E, 0x0E, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3E, /*0x00*/}, + {/*0x00, 0x00,*/ 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0xFE, 0xFE, 0xFE, /*0x00,*/ /*0x00, 0x00,*/ 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x7F, 0x7F, 0x7F, /*0x00*/}, + {/*0x00, 0x00,*/ 0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x86, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/}, + {/*0x00, 0x00,*/ 0xF8, 0xFC, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x80, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/}, + {/*0x00, 0x00,*/ 0x0E, 0x0E, 0x0E, 0x06, 0x06, 0x86, 0xE6, 0xFE, 0x7E, 0x1E, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7F, 0x7F, 0x03, 0x00, 0x00, /*0x00*/}, + {/*0x00, 0x00,*/ 0x7C, 0xFE, 0xFE, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3F, /*0x00*/}, + {/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x01, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7F, 0x3F, 0x1F, /*0x00*/}, + {/*0x00, 0x00,*/ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, /*0x00*/} + }; #endif /* const uint8_t gFontSmallDigits[11][7] = { - {0x00, 0x3E, 0x41, 0x41, 0x41, 0x41, 0x3E}, // '0' - {0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00}, // '1' - {0x00, 0x62, 0x51, 0x51, 0x49, 0x49, 0x46}, // '2' - {0x00, 0x22, 0x41, 0x49, 0x49, 0x4D, 0x32}, // '3' - {0x00, 0x18, 0x14, 0x12, 0x11, 0x7F, 0x10}, // '4' - {0x00, 0x27, 0x45, 0x45, 0x45, 0x45, 0x39}, // '5' - {0x00, 0x3E, 0x49, 0x49, 0x49, 0x49, 0x30}, // '6' - {0x00, 0x01, 0x71, 0x09, 0x05, 0x03, 0x00}, // '7' - {0x00, 0x36, 0x49, 0x49, 0x49, 0x49, 0x36}, // '8' - {0x00, 0x46, 0x49, 0x49, 0x49, 0x29, 0x1E}, // '9' - {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00} // '-' + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x41, 0x3E}, // '0' + {0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00}, // '1' + {0x00, 0x62, 0x51, 0x51, 0x49, 0x49, 0x46}, // '2' + {0x00, 0x22, 0x41, 0x49, 0x49, 0x4D, 0x32}, // '3' + {0x00, 0x18, 0x14, 0x12, 0x11, 0x7F, 0x10}, // '4' + {0x00, 0x27, 0x45, 0x45, 0x45, 0x45, 0x39}, // '5' + {0x00, 0x3E, 0x49, 0x49, 0x49, 0x49, 0x30}, // '6' + {0x00, 0x01, 0x71, 0x09, 0x05, 0x03, 0x00}, // '7' + {0x00, 0x36, 0x49, 0x49, 0x49, 0x49, 0x36}, // '8' + {0x00, 0x46, 0x49, 0x49, 0x49, 0x29, 0x1E}, // '9' + {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00} // '-' }; */ const uint8_t gFontSmall[95-1][6] = { // {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' ' - {0x00, 0x00, 0x5E, 0x00, 0x00, 0x00}, // '!' - {0x00, 0x06, 0x00, 0x06, 0x00, 0x00}, // '"' - {0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00}, // '#' - {0x26, 0x49, 0x7F, 0x49, 0x32, 0x00}, // '$' - {0x63, 0x13, 0x08, 0x04, 0x62, 0x61}, // '%' - {0x30, 0x4B, 0x4D, 0x55, 0x22, 0x50}, // '&' - {0x00, 0x00, 0x07, 0x07, 0x00, 0x00}, // ''' - {0x00, 0x1C, 0x22, 0x41, 0x00, 0x00}, // '(' - {0x00, 0x41, 0x22, 0x1C, 0x00, 0x00}, // ')' - {0x00, 0x2A, 0x1C, 0x1C, 0x2A, 0x00}, // '*' - {0x08, 0x08, 0x3E, 0x08, 0x08, 0x00}, // '+' - {0x00, 0x40, 0x60, 0x20, 0x00, 0x00}, // ',' - {0x00, 0x08, 0x08, 0x08, 0x08, 0x00}, // '-' - {0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, // '.' - {0x40, 0x20, 0x10, 0x08, 0x04, 0x02}, // '/' - {0x3E, 0x41, 0x41, 0x41, 0x41, 0x3E}, // '0' - {0x00, 0x40, 0x42, 0x7F, 0x40, 0x40}, // '1' - {0x62, 0x51, 0x51, 0x49, 0x49, 0x46}, // '2' - {0x22, 0x41, 0x49, 0x49, 0x49, 0x36}, // '3' - {0x18, 0x14, 0x12, 0x11, 0x7F, 0x10}, // '4' - {0x27, 0x45, 0x45, 0x45, 0x45, 0x39}, // '5' - {0x3E, 0x49, 0x49, 0x49, 0x49, 0x32}, // '6' - {0x01, 0x01, 0x71, 0x09, 0x05, 0x03}, // '7' - {0x36, 0x49, 0x49, 0x49, 0x49, 0x36}, // '8' - {0x46, 0x49, 0x49, 0x49, 0x29, 0x1E}, // '9' - {0x00, 0x00, 0x6C, 0x6C, 0x00, 0x00}, // ':' - {0x00, 0x40, 0x6C, 0x2C, 0x00, 0x00}, // ';' - {0x08, 0x14, 0x22, 0x41, 0x00, 0x00}, // '<' - {0x14, 0x14, 0x14, 0x14, 0x14, 0x00}, // '=' - {0x00, 0x41, 0x22, 0x14, 0x08, 0x00}, // '>' - {0x02, 0x01, 0x51, 0x09, 0x06, 0x00}, // '?' - {0x30, 0x4A, 0x4A, 0x52, 0x3C, 0x00}, // '@' - {0x7E, 0x09, 0x09, 0x09, 0x09, 0x7E}, // 'A' - {0x7F, 0x49, 0x49, 0x49, 0x49, 0x36}, // 'B' - {0x3E, 0x41, 0x41, 0x41, 0x41, 0x22}, // 'C' - {0x7F, 0x41, 0x41, 0x41, 0x41, 0x3E}, // 'D' - {0x7F, 0x49, 0x49, 0x49, 0x49, 0x41}, // 'E' - {0x7F, 0x09, 0x09, 0x09, 0x09, 0x01}, // 'F' - {0x3E, 0x41, 0x49, 0x49, 0x49, 0x3A}, // 'G' - {0x7F, 0x08, 0x08, 0x08, 0x08, 0x7F}, // 'H' - {0x41, 0x41, 0x7F, 0x41, 0x41, 0x00}, // 'I' - {0x20, 0x41, 0x41, 0x3F, 0x01, 0x01}, // 'J' - {0x7F, 0x08, 0x0C, 0x12, 0x21, 0x40}, // 'K' - {0x7F, 0x40, 0x40, 0x40, 0x40, 0x40}, // 'L' - {0x7F, 0x02, 0x04, 0x04, 0x02, 0x7F}, // 'M' - {0x7F, 0x02, 0x04, 0x08, 0x10, 0x7F}, // 'N' - {0x3E, 0x41, 0x41, 0x41, 0x41, 0x3E}, // 'O' - {0x7F, 0x09, 0x09, 0x09, 0x09, 0x06}, // 'P' - {0x3E, 0x41, 0x51, 0x61, 0x41, 0x3E}, // 'Q' - {0x7F, 0x09, 0x09, 0x19, 0x29, 0x46}, // 'R' - {0x26, 0x49, 0x49, 0x49, 0x49, 0x32}, // 'S' - {0x01, 0x01, 0x7F, 0x01, 0x01, 0x00}, // 'T' - {0x3F, 0x40, 0x40, 0x40, 0x40, 0x3F}, // 'U' - {0x07, 0x38, 0x40, 0x40, 0x38, 0x07}, // 'V' - {0x3F, 0x40, 0x30, 0x30, 0x40, 0x3F}, // 'W' - {0x63, 0x14, 0x08, 0x08, 0x14, 0x63}, // 'X' - {0x07, 0x08, 0x70, 0x08, 0x07, 0x00}, // 'Y' - {0x61, 0x51, 0x49, 0x45, 0x43, 0x41}, // 'Z' - {0x00, 0x7F, 0x41, 0x41, 0x00, 0x00}, // '[' - {0x01, 0x02, 0x04, 0x08, 0x10, 0x60}, // '"\' - {0x00, 0x00, 0x41, 0x41, 0x7F, 0x00}, // ']' - {0x04, 0x02, 0x01, 0x02, 0x04, 0x00}, // '^' - {0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, // '_' - {0x00, 0x03, 0x07, 0x06, 0x00, 0x00}, // '`' - {0x20, 0x54, 0x54, 0x54, 0x78, 0x00}, // 'a' - {0x7F, 0x44, 0x44, 0x44, 0x38, 0x00}, // 'b' - {0x38, 0x44, 0x44, 0x44, 0x28, 0x00}, // 'c' - {0x38, 0x44, 0x44, 0x44, 0x7F, 0x00}, // 'd' - {0x38, 0x54, 0x54, 0x54, 0x48, 0x00}, // 'e' - {0x7C, 0x0A, 0x0A, 0x0A, 0x02, 0x00}, // 'f' - {0x58, 0x54, 0x54, 0x54, 0x3C, 0x00}, // 'g' - {0x7F, 0x04, 0x04, 0x04, 0x78, 0x00}, // 'h' - {0x00, 0x00, 0x7A, 0x00, 0x00, 0x00}, // 'i' - {0x20, 0x40, 0x40, 0x3D, 0x00, 0x00}, // 'j' - {0x00, 0x7F, 0x10, 0x28, 0x44, 0x00}, // 'k' - {0x00, 0x00, 0x3F, 0x40, 0x00, 0x00}, // 'l' - {0x7C, 0x08, 0x10, 0x10, 0x08, 0x7C}, // 'm' - {0x7C, 0x04, 0x04, 0x04, 0x78, 0x00}, // 'n' - {0x38, 0x44, 0x44, 0x44, 0x38, 0x00}, // 'o' - {0x7C, 0x14, 0x14, 0x14, 0x08, 0x00}, // 'p' - {0x08, 0x14, 0x14, 0x14, 0x7C, 0x40}, // 'q' - {0x7C, 0x04, 0x04, 0x04, 0x08, 0x00}, // 'r' - {0x08, 0x54, 0x54, 0x54, 0x20, 0x00}, // 's' - {0x3F, 0x44, 0x44, 0x44, 0x40, 0x00}, // 't' - {0x3C, 0x40, 0x40, 0x40, 0x3C, 0x00}, // 'u' - {0x0C, 0x30, 0x40, 0x30, 0x0C, 0x00}, // 'v' - {0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00}, // 'w' - {0x44, 0x28, 0x10, 0x28, 0x44, 0x00}, // 'x' - {0x0C, 0x50, 0x50, 0x50, 0x3C, 0x00}, // 'y' - {0x44, 0x64, 0x54, 0x4C, 0x44, 0x00}, // 'z' - {0x08, 0x36, 0x41, 0x00, 0x00, 0x00}, // '{' - {0x00, 0x00, 0x7F, 0x00, 0x00, 0x00}, // '|' - {0x00, 0x00, 0x41, 0x36, 0x08, 0x00}, // '}' - {0x04, 0x02, 0x04, 0x08, 0x04, 0x00} // '->' + {0x00, 0x00, 0x5E, 0x00, 0x00, 0x00}, // '!' + {0x00, 0x06, 0x00, 0x06, 0x00, 0x00}, // '"' + {0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00}, // '#' + {0x26, 0x49, 0x7F, 0x49, 0x32, 0x00}, // '$' + {0x63, 0x13, 0x08, 0x04, 0x62, 0x61}, // '%' + {0x30, 0x4B, 0x4D, 0x55, 0x22, 0x50}, // '&' + {0x00, 0x00, 0x07, 0x07, 0x00, 0x00}, // ''' + {0x00, 0x1C, 0x22, 0x41, 0x00, 0x00}, // '(' + {0x00, 0x41, 0x22, 0x1C, 0x00, 0x00}, // ')' + {0x00, 0x2A, 0x1C, 0x1C, 0x2A, 0x00}, // '*' + {0x08, 0x08, 0x3E, 0x08, 0x08, 0x00}, // '+' + {0x00, 0x40, 0x60, 0x20, 0x00, 0x00}, // ',' + {0x00, 0x08, 0x08, 0x08, 0x08, 0x00}, // '-' + {0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, // '.' + {0x40, 0x20, 0x10, 0x08, 0x04, 0x02}, // '/' + {0x3E, 0x41, 0x41, 0x41, 0x41, 0x3E}, // '0' + {0x00, 0x40, 0x42, 0x7F, 0x40, 0x40}, // '1' + {0x62, 0x51, 0x51, 0x49, 0x49, 0x46}, // '2' + {0x22, 0x41, 0x49, 0x49, 0x49, 0x36}, // '3' + {0x18, 0x14, 0x12, 0x11, 0x7F, 0x10}, // '4' + {0x27, 0x45, 0x45, 0x45, 0x45, 0x39}, // '5' + {0x3E, 0x49, 0x49, 0x49, 0x49, 0x32}, // '6' + {0x01, 0x01, 0x71, 0x09, 0x05, 0x03}, // '7' + {0x36, 0x49, 0x49, 0x49, 0x49, 0x36}, // '8' + {0x46, 0x49, 0x49, 0x49, 0x29, 0x1E}, // '9' + {0x00, 0x00, 0x6C, 0x6C, 0x00, 0x00}, // ':' + {0x00, 0x40, 0x6C, 0x2C, 0x00, 0x00}, // ';' + {0x08, 0x14, 0x22, 0x41, 0x00, 0x00}, // '<' + {0x14, 0x14, 0x14, 0x14, 0x14, 0x00}, // '=' + {0x00, 0x41, 0x22, 0x14, 0x08, 0x00}, // '>' + {0x02, 0x01, 0x51, 0x09, 0x06, 0x00}, // '?' + {0x30, 0x4A, 0x4A, 0x52, 0x3C, 0x00}, // '@' + {0x7E, 0x09, 0x09, 0x09, 0x09, 0x7E}, // 'A' + {0x7F, 0x49, 0x49, 0x49, 0x49, 0x36}, // 'B' + {0x3E, 0x41, 0x41, 0x41, 0x41, 0x22}, // 'C' + {0x7F, 0x41, 0x41, 0x41, 0x41, 0x3E}, // 'D' + {0x7F, 0x49, 0x49, 0x49, 0x49, 0x41}, // 'E' + {0x7F, 0x09, 0x09, 0x09, 0x09, 0x01}, // 'F' + {0x3E, 0x41, 0x49, 0x49, 0x49, 0x3A}, // 'G' + {0x7F, 0x08, 0x08, 0x08, 0x08, 0x7F}, // 'H' + {0x41, 0x41, 0x7F, 0x41, 0x41, 0x00}, // 'I' + {0x20, 0x41, 0x41, 0x3F, 0x01, 0x01}, // 'J' + {0x7F, 0x08, 0x0C, 0x12, 0x21, 0x40}, // 'K' + {0x7F, 0x40, 0x40, 0x40, 0x40, 0x40}, // 'L' + {0x7F, 0x02, 0x04, 0x04, 0x02, 0x7F}, // 'M' + {0x7F, 0x02, 0x04, 0x08, 0x10, 0x7F}, // 'N' + {0x3E, 0x41, 0x41, 0x41, 0x41, 0x3E}, // 'O' + {0x7F, 0x09, 0x09, 0x09, 0x09, 0x06}, // 'P' + {0x3E, 0x41, 0x51, 0x61, 0x41, 0x3E}, // 'Q' + {0x7F, 0x09, 0x09, 0x19, 0x29, 0x46}, // 'R' + {0x26, 0x49, 0x49, 0x49, 0x49, 0x32}, // 'S' + {0x01, 0x01, 0x7F, 0x01, 0x01, 0x00}, // 'T' + {0x3F, 0x40, 0x40, 0x40, 0x40, 0x3F}, // 'U' + {0x07, 0x38, 0x40, 0x40, 0x38, 0x07}, // 'V' + {0x3F, 0x40, 0x30, 0x30, 0x40, 0x3F}, // 'W' + {0x63, 0x14, 0x08, 0x08, 0x14, 0x63}, // 'X' + {0x07, 0x08, 0x70, 0x08, 0x07, 0x00}, // 'Y' + {0x61, 0x51, 0x49, 0x45, 0x43, 0x41}, // 'Z' + {0x00, 0x7F, 0x41, 0x41, 0x00, 0x00}, // '[' + {0x01, 0x02, 0x04, 0x08, 0x10, 0x60}, // '"\' + {0x00, 0x00, 0x41, 0x41, 0x7F, 0x00}, // ']' + {0x04, 0x02, 0x01, 0x02, 0x04, 0x00}, // '^' + {0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, // '_' + {0x00, 0x03, 0x07, 0x06, 0x00, 0x00}, // '`' + {0x20, 0x54, 0x54, 0x54, 0x78, 0x00}, // 'a' + {0x7F, 0x44, 0x44, 0x44, 0x38, 0x00}, // 'b' + {0x38, 0x44, 0x44, 0x44, 0x28, 0x00}, // 'c' + {0x38, 0x44, 0x44, 0x44, 0x7F, 0x00}, // 'd' + {0x38, 0x54, 0x54, 0x54, 0x48, 0x00}, // 'e' + {0x7C, 0x0A, 0x0A, 0x0A, 0x02, 0x00}, // 'f' + {0x58, 0x54, 0x54, 0x54, 0x3C, 0x00}, // 'g' + {0x7F, 0x04, 0x04, 0x04, 0x78, 0x00}, // 'h' + {0x00, 0x00, 0x7A, 0x00, 0x00, 0x00}, // 'i' + {0x20, 0x40, 0x40, 0x3D, 0x00, 0x00}, // 'j' + {0x00, 0x7F, 0x10, 0x28, 0x44, 0x00}, // 'k' + {0x00, 0x00, 0x3F, 0x40, 0x00, 0x00}, // 'l' + {0x7C, 0x08, 0x10, 0x10, 0x08, 0x7C}, // 'm' + {0x7C, 0x04, 0x04, 0x04, 0x78, 0x00}, // 'n' + {0x38, 0x44, 0x44, 0x44, 0x38, 0x00}, // 'o' + {0x7C, 0x14, 0x14, 0x14, 0x08, 0x00}, // 'p' + {0x08, 0x14, 0x14, 0x14, 0x7C, 0x40}, // 'q' + {0x7C, 0x04, 0x04, 0x04, 0x08, 0x00}, // 'r' + {0x08, 0x54, 0x54, 0x54, 0x20, 0x00}, // 's' + {0x3F, 0x44, 0x44, 0x44, 0x40, 0x00}, // 't' + {0x3C, 0x40, 0x40, 0x40, 0x3C, 0x00}, // 'u' + {0x0C, 0x30, 0x40, 0x30, 0x0C, 0x00}, // 'v' + {0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00}, // 'w' + {0x44, 0x28, 0x10, 0x28, 0x44, 0x00}, // 'x' + {0x0C, 0x50, 0x50, 0x50, 0x3C, 0x00}, // 'y' + {0x44, 0x64, 0x54, 0x4C, 0x44, 0x00}, // 'z' + {0x08, 0x36, 0x41, 0x00, 0x00, 0x00}, // '{' + {0x00, 0x00, 0x7F, 0x00, 0x00, 0x00}, // '|' + {0x00, 0x00, 0x41, 0x36, 0x08, 0x00}, // '}' + {0x04, 0x02, 0x04, 0x08, 0x04, 0x00} // '->' }; #ifdef ENABLE_SMALL_BOLD - const uint8_t gFontSmallBold[95 - 1][6] = - { -// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x5E, 0x5E, 0x00, 0x00}, - {0x06, 0x06, 0x00, 0x06, 0x06, 0x00}, - {0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00}, - {0x2E, 0x6B, 0x7F, 0x6B, 0x3A, 0x00}, - {0x63, 0x33, 0x18, 0x0C, 0x66, 0x63}, - {0x30, 0x4B, 0x4D, 0x55, 0x22, 0x50}, - {0x00, 0x00, 0x07, 0x07, 0x00, 0x00}, - {0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00}, - {0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00}, - {0x00, 0x2A, 0x1C, 0x1C, 0x2A, 0x00}, - {0x18, 0x18, 0x7E, 0x7E, 0x18, 0x18}, - {0x00, 0x40, 0x60, 0x20, 0x00, 0x00}, - {0x00, 0x18, 0x18, 0x18, 0x18, 0x00}, - {0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, - {0x60, 0x30, 0x18, 0x0C, 0x06, 0x03}, - {0x3E, 0x7F, 0x63, 0x63, 0x7F, 0x3E}, - {0x64, 0x66, 0x7F, 0x7F, 0x60, 0x60}, - {0x62, 0x73, 0x7B, 0x7B, 0x6F, 0x66}, - {0x63, 0x63, 0x6B, 0x6B, 0x7F, 0x36}, - {0x38, 0x3C, 0x36, 0x7F, 0x7F, 0x30}, - {0x6F, 0x6F, 0x6B, 0x6B, 0x7B, 0x33}, - {0x3E, 0x7F, 0x6B, 0x6B, 0x7B, 0x32}, - {0x03, 0x03, 0x73, 0x7B, 0x0F, 0x07}, - {0x36, 0x7F, 0x6B, 0x6B, 0x7F, 0x36}, - {0x06, 0x6F, 0x6B, 0x6B, 0x7F, 0x3E}, - {0x00, 0x00, 0x6C, 0x6C, 0x00, 0x00}, - {0x00, 0x40, 0x6C, 0x2C, 0x00, 0x00}, - {0x08, 0x14, 0x22, 0x41, 0x00, 0x00}, - {0x36, 0x36, 0x36, 0x36, 0x36, 0x00}, - {0x00, 0x41, 0x22, 0x14, 0x08, 0x00}, - {0x06, 0x07, 0x53, 0x5B, 0x1F, 0x0E}, - {0x30, 0x7B, 0x6B, 0x7B, 0x7F, 0x3E}, - {0x7E, 0x7F, 0x1B, 0x1B, 0x7F, 0x7E}, - {0x7F, 0x7F, 0x6B, 0x6B, 0x7F, 0x36}, - {0x3E, 0x7F, 0x63, 0x63, 0x63, 0x36}, - {0x7F, 0x7F, 0x63, 0x63, 0x7F, 0x3E}, - {0x7F, 0x7F, 0x6B, 0x6B, 0x6B, 0x63}, - {0x7F, 0x7F, 0x1B, 0x1B, 0x1B, 0x03}, - {0x3E, 0x7F, 0x63, 0x6B, 0x7B, 0x3A}, - {0x7F, 0x7F, 0x0C, 0x0C, 0x7F, 0x7F}, - {0x63, 0x63, 0x7F, 0x7F, 0x63, 0x63}, - {0x30, 0x73, 0x63, 0x7F, 0x3F, 0x03}, - {0x7F, 0x7F, 0x1C, 0x36, 0x63, 0x41}, - {0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60}, - {0x7F, 0x7F, 0x06, 0x06, 0x7F, 0x7F}, - {0x7F, 0x7F, 0x0C, 0x18, 0x7F, 0x7F}, - {0x3E, 0x7F, 0x63, 0x63, 0x7F, 0x3E}, - {0x7F, 0x7F, 0x1B, 0x1B, 0x1F, 0x0E}, - {0x3E, 0x7F, 0x63, 0x73, 0x7F, 0x7E}, - {0x7F, 0x7F, 0x1B, 0x3B, 0x7F, 0x66}, - {0x66, 0x6F, 0x6B, 0x6B, 0x7B, 0x33}, - {0x03, 0x03, 0x7F, 0x7F, 0x03, 0x03}, - {0x3F, 0x7F, 0x60, 0x60, 0x7F, 0x3F}, - {0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F}, - {0x3F, 0x7F, 0x30, 0x30, 0x7F, 0x3F}, - {0x63, 0x77, 0x1C, 0x1C, 0x77, 0x63}, - {0x07, 0x0F, 0x78, 0x78, 0x0F, 0x07}, - {0x63, 0x73, 0x7B, 0x6F, 0x67, 0x63}, - {0x00, 0x7F, 0x7F, 0x63, 0x63, 0x00}, - {0x01, 0x02, 0x04, 0x08, 0x10, 0x60}, - {0x00, 0x63, 0x63, 0x7F, 0x7F, 0x00}, - {0x0C, 0x0E, 0x03, 0x03, 0x0E, 0x0C}, - {0x60, 0x60, 0x60, 0x60, 0x60, 0x60}, - {0x00, 0x03, 0x07, 0x06, 0x00, 0x00}, - {0x20, 0x76, 0x56, 0x56, 0x7E, 0x3C}, - {0x7F, 0x7F, 0x6C, 0x6C, 0x7C, 0x38}, - {0x38, 0x7C, 0x6C, 0x6C, 0x6C, 0x00}, - {0x38, 0x7C, 0x6C, 0x6C, 0x7F, 0x7F}, - {0x3C, 0x7E, 0x56, 0x56, 0x5E, 0x0C}, - {0x7E, 0x7F, 0x1B, 0x1B, 0x02, 0x00}, - {0x0C, 0x5E, 0x56, 0x56, 0x7E, 0x3C}, - {0x7F, 0x7F, 0x0C, 0x0C, 0x7C, 0x78}, - {0x00, 0x00, 0x7A, 0x7A, 0x00, 0x00}, - {0x30, 0x60, 0x60, 0x7D, 0x3D, 0x00}, - {0x7F, 0x7F, 0x18, 0x3C, 0x7E, 0x66}, - {0x00, 0x3F, 0x7F, 0x40, 0x00, 0x00}, - {0x7C, 0x7C, 0x18, 0x18, 0x7C, 0x7C}, - {0x7C, 0x7C, 0x0C, 0x0C, 0x7C, 0x78}, - {0x3C, 0x7E, 0x66, 0x66, 0x7E, 0x3C}, - {0x7E, 0x7E, 0x36, 0x36, 0x3E, 0x1C}, - {0x1C, 0x3E, 0x36, 0x7E, 0x7E, 0x60}, - {0x7C, 0x7C, 0x0C, 0x0C, 0x18, 0x00}, - {0x4C, 0x5E, 0x56, 0x56, 0x76, 0x20}, - {0x3F, 0x7F, 0x6C, 0x6C, 0x60, 0x00}, - {0x3C, 0x7C, 0x60, 0x60, 0x7C, 0x3C}, - {0x0C, 0x3C, 0x70, 0x70, 0x3C, 0x0C}, - {0x3C, 0x7C, 0x30, 0x30, 0x7C, 0x3C}, - {0x44, 0x6C, 0x38, 0x38, 0x6C, 0x44}, - {0x06, 0x6E, 0x68, 0x68, 0x7E, 0x3E}, - {0x66, 0x76, 0x7E, 0x6E, 0x66, 0x00}, - {0x08, 0x3E, 0x77, 0x41, 0x00, 0x00}, - {0x00, 0x00, 0x7F, 0x00, 0x00, 0x00}, - {0x00, 0x41, 0x77, 0x3E, 0x08, 0x00}, - {0x0C, 0x06, 0x0C, 0x18, 0x0C, 0x00} - }; + const uint8_t gFontSmallBold[95 - 1][6] = + { +// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x5E, 0x5E, 0x00, 0x00}, + {0x06, 0x06, 0x00, 0x06, 0x06, 0x00}, + {0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00}, + {0x2E, 0x6B, 0x7F, 0x6B, 0x3A, 0x00}, + {0x63, 0x33, 0x18, 0x0C, 0x66, 0x63}, + {0x30, 0x4B, 0x4D, 0x55, 0x22, 0x50}, + {0x00, 0x00, 0x07, 0x07, 0x00, 0x00}, + {0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00}, + {0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00}, + {0x00, 0x2A, 0x1C, 0x1C, 0x2A, 0x00}, + {0x18, 0x18, 0x7E, 0x7E, 0x18, 0x18}, + {0x00, 0x40, 0x60, 0x20, 0x00, 0x00}, + {0x00, 0x18, 0x18, 0x18, 0x18, 0x00}, + {0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, + {0x60, 0x30, 0x18, 0x0C, 0x06, 0x03}, + {0x3E, 0x7F, 0x63, 0x63, 0x7F, 0x3E}, + {0x64, 0x66, 0x7F, 0x7F, 0x60, 0x60}, + {0x62, 0x73, 0x7B, 0x7B, 0x6F, 0x66}, + {0x63, 0x63, 0x6B, 0x6B, 0x7F, 0x36}, + {0x38, 0x3C, 0x36, 0x7F, 0x7F, 0x30}, + {0x6F, 0x6F, 0x6B, 0x6B, 0x7B, 0x33}, + {0x3E, 0x7F, 0x6B, 0x6B, 0x7B, 0x32}, + {0x03, 0x03, 0x73, 0x7B, 0x0F, 0x07}, + {0x36, 0x7F, 0x6B, 0x6B, 0x7F, 0x36}, + {0x06, 0x6F, 0x6B, 0x6B, 0x7F, 0x3E}, + {0x00, 0x00, 0x6C, 0x6C, 0x00, 0x00}, + {0x00, 0x40, 0x6C, 0x2C, 0x00, 0x00}, + {0x08, 0x14, 0x22, 0x41, 0x00, 0x00}, + {0x36, 0x36, 0x36, 0x36, 0x36, 0x00}, + {0x00, 0x41, 0x22, 0x14, 0x08, 0x00}, + {0x06, 0x07, 0x53, 0x5B, 0x1F, 0x0E}, + {0x30, 0x7B, 0x6B, 0x7B, 0x7F, 0x3E}, + {0x7E, 0x7F, 0x1B, 0x1B, 0x7F, 0x7E}, + {0x7F, 0x7F, 0x6B, 0x6B, 0x7F, 0x36}, + {0x3E, 0x7F, 0x63, 0x63, 0x63, 0x36}, + {0x7F, 0x7F, 0x63, 0x63, 0x7F, 0x3E}, + {0x7F, 0x7F, 0x6B, 0x6B, 0x6B, 0x63}, + {0x7F, 0x7F, 0x1B, 0x1B, 0x1B, 0x03}, + {0x3E, 0x7F, 0x63, 0x6B, 0x7B, 0x3A}, + {0x7F, 0x7F, 0x0C, 0x0C, 0x7F, 0x7F}, + {0x63, 0x63, 0x7F, 0x7F, 0x63, 0x63}, + {0x30, 0x73, 0x63, 0x7F, 0x3F, 0x03}, + {0x7F, 0x7F, 0x1C, 0x36, 0x63, 0x41}, + {0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60}, + {0x7F, 0x7F, 0x06, 0x06, 0x7F, 0x7F}, + {0x7F, 0x7F, 0x0C, 0x18, 0x7F, 0x7F}, + {0x3E, 0x7F, 0x63, 0x63, 0x7F, 0x3E}, + {0x7F, 0x7F, 0x1B, 0x1B, 0x1F, 0x0E}, + {0x3E, 0x7F, 0x63, 0x73, 0x7F, 0x7E}, + {0x7F, 0x7F, 0x1B, 0x3B, 0x7F, 0x66}, + {0x66, 0x6F, 0x6B, 0x6B, 0x7B, 0x33}, + {0x03, 0x03, 0x7F, 0x7F, 0x03, 0x03}, + {0x3F, 0x7F, 0x60, 0x60, 0x7F, 0x3F}, + {0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F}, + {0x3F, 0x7F, 0x30, 0x30, 0x7F, 0x3F}, + {0x63, 0x77, 0x1C, 0x1C, 0x77, 0x63}, + {0x07, 0x0F, 0x78, 0x78, 0x0F, 0x07}, + {0x63, 0x73, 0x7B, 0x6F, 0x67, 0x63}, + {0x00, 0x7F, 0x7F, 0x63, 0x63, 0x00}, + {0x01, 0x02, 0x04, 0x08, 0x10, 0x60}, + {0x00, 0x63, 0x63, 0x7F, 0x7F, 0x00}, + {0x0C, 0x0E, 0x03, 0x03, 0x0E, 0x0C}, + {0x60, 0x60, 0x60, 0x60, 0x60, 0x60}, + {0x00, 0x03, 0x07, 0x06, 0x00, 0x00}, + {0x20, 0x76, 0x56, 0x56, 0x7E, 0x3C}, + {0x7F, 0x7F, 0x6C, 0x6C, 0x7C, 0x38}, + {0x38, 0x7C, 0x6C, 0x6C, 0x6C, 0x00}, + {0x38, 0x7C, 0x6C, 0x6C, 0x7F, 0x7F}, + {0x3C, 0x7E, 0x56, 0x56, 0x5E, 0x0C}, + {0x7E, 0x7F, 0x1B, 0x1B, 0x02, 0x00}, + {0x0C, 0x5E, 0x56, 0x56, 0x7E, 0x3C}, + {0x7F, 0x7F, 0x0C, 0x0C, 0x7C, 0x78}, + {0x00, 0x00, 0x7A, 0x7A, 0x00, 0x00}, + {0x30, 0x60, 0x60, 0x7D, 0x3D, 0x00}, + {0x7F, 0x7F, 0x18, 0x3C, 0x7E, 0x66}, + {0x00, 0x3F, 0x7F, 0x40, 0x00, 0x00}, + {0x7C, 0x7C, 0x18, 0x18, 0x7C, 0x7C}, + {0x7C, 0x7C, 0x0C, 0x0C, 0x7C, 0x78}, + {0x3C, 0x7E, 0x66, 0x66, 0x7E, 0x3C}, + {0x7E, 0x7E, 0x36, 0x36, 0x3E, 0x1C}, + {0x1C, 0x3E, 0x36, 0x7E, 0x7E, 0x60}, + {0x7C, 0x7C, 0x0C, 0x0C, 0x18, 0x00}, + {0x4C, 0x5E, 0x56, 0x56, 0x76, 0x20}, + {0x3F, 0x7F, 0x6C, 0x6C, 0x60, 0x00}, + {0x3C, 0x7C, 0x60, 0x60, 0x7C, 0x3C}, + {0x0C, 0x3C, 0x70, 0x70, 0x3C, 0x0C}, + {0x3C, 0x7C, 0x30, 0x30, 0x7C, 0x3C}, + {0x44, 0x6C, 0x38, 0x38, 0x6C, 0x44}, + {0x06, 0x6E, 0x68, 0x68, 0x7E, 0x3E}, + {0x66, 0x76, 0x7E, 0x6E, 0x66, 0x00}, + {0x08, 0x3E, 0x77, 0x41, 0x00, 0x00}, + {0x00, 0x00, 0x7F, 0x00, 0x00, 0x00}, + {0x00, 0x41, 0x77, 0x3E, 0x08, 0x00}, + {0x0C, 0x06, 0x0C, 0x18, 0x0C, 0x00} + }; #endif //#ifdef ENABLE_SPECTRUM - const uint8_t gFont3x5[][3] = - { - {0x00, 0x00, 0x00}, // 32 - space - {0x00, 0x17, 0x00}, // 33 - exclam - {0x03, 0x00, 0x03}, // 34 - quotedbl - {0x1f, 0x0a, 0x1f}, // 35 - numbersign - {0x0a, 0x1f, 0x05}, // 36 - dollar - {0x09, 0x04, 0x12}, // 37 - percent - {0x0f, 0x17, 0x1c}, // 38 - ampersand - {0x00, 0x03, 0x00}, // 39 - quotesingle - {0x00, 0x0e, 0x11}, // 40 - parenleft - {0x11, 0x0e, 0x00}, // 41 - parenright - {0x05, 0x02, 0x05}, // 42 - asterisk - {0x04, 0x0e, 0x04}, // 43 - plus - {0x10, 0x08, 0x00}, // 44 - comma - {0x04, 0x04, 0x04}, // 45 - hyphen - {0x00, 0x10, 0x00}, // 46 - period - {0x18, 0x04, 0x03}, // 47 - slash - {0x1e, 0x11, 0x0f}, // 48 - zero - {0x02, 0x1f, 0x00}, // 49 - one - {0x19, 0x15, 0x12}, // 50 - two - {0x11, 0x15, 0x0a}, // 51 - three - {0x07, 0x04, 0x1f}, // 52 - four - {0x17, 0x15, 0x09}, // 53 - five - {0x1e, 0x15, 0x1d}, // 54 - six - {0x19, 0x05, 0x03}, // 55 - seven - {0x1f, 0x15, 0x1f}, // 56 - eight - {0x17, 0x15, 0x0f}, // 57 - nine - {0x00, 0x0a, 0x00}, // 58 - colon - {0x10, 0x0a, 0x00}, // 59 - semicolon - {0x04, 0x0a, 0x11}, // 60 - less - {0x0a, 0x0a, 0x0a}, // 61 - equal - {0x11, 0x0a, 0x04}, // 62 - greater - {0x01, 0x15, 0x03}, // 63 - question - {0x0e, 0x15, 0x16}, // 64 - at - {0x1e, 0x05, 0x1e}, // 65 - A - {0x1f, 0x15, 0x0a}, // 66 - B - {0x0e, 0x11, 0x11}, // 67 - C - {0x1f, 0x11, 0x0e}, // 68 - D - {0x1f, 0x15, 0x15}, // 69 - E - {0x1f, 0x05, 0x05}, // 70 - F - {0x0e, 0x15, 0x1d}, // 71 - G - {0x1f, 0x04, 0x1f}, // 72 - H - {0x11, 0x1f, 0x11}, // 73 - I - {0x08, 0x10, 0x0f}, // 74 - J - {0x1f, 0x04, 0x1b}, // 75 - K - {0x1f, 0x10, 0x10}, // 76 - L - {0x1f, 0x06, 0x1f}, // 77 - M - {0x1f, 0x0e, 0x1f}, // 78 - N - {0x0e, 0x11, 0x0e}, // 79 - O - {0x1f, 0x05, 0x02}, // 80 - P - {0x0e, 0x19, 0x1e}, // 81 - Q - {0x1f, 0x0d, 0x16}, // 82 - R - {0x12, 0x15, 0x09}, // 83 - S - {0x01, 0x1f, 0x01}, // 84 - T - {0x0f, 0x10, 0x1f}, // 85 - U - {0x07, 0x18, 0x07}, // 86 - V - {0x1f, 0x0c, 0x1f}, // 87 - W - {0x1b, 0x04, 0x1b}, // 88 - X - {0x03, 0x1c, 0x03}, // 89 - Y - {0x19, 0x15, 0x13}, // 90 - Z - {0x1f, 0x11, 0x11}, // 91 - bracketleft - {0x02, 0x04, 0x08}, // 92 - backslash - {0x11, 0x11, 0x1f}, // 93 - bracketright - {0x02, 0x01, 0x02}, // 94 - asciicircum - {0x10, 0x10, 0x10}, // 95 - underscore - {0x01, 0x02, 0x00}, // 96 - grave - {0x1a, 0x16, 0x1c}, // 97 - a - {0x1f, 0x12, 0x0c}, // 98 - b - {0x0c, 0x12, 0x12}, // 99 - c - {0x0c, 0x12, 0x1f}, // 100 - d - {0x0c, 0x1a, 0x16}, // 101 - e - {0x04, 0x1e, 0x05}, // 102 - f - {0x0c, 0x2a, 0x1e}, // 103 - g - {0x1f, 0x02, 0x1c}, // 104 - h - {0x00, 0x1d, 0x00}, // 105 - i - {0x10, 0x20, 0x1d}, // 106 - j - {0x1f, 0x0c, 0x12}, // 107 - k - {0x11, 0x1f, 0x10}, // 108 - l - {0x1e, 0x0e, 0x1e}, // 109 - m - {0x1e, 0x02, 0x1c}, // 110 - n - {0x0c, 0x12, 0x0c}, // 111 - o - {0x3e, 0x12, 0x0c}, // 112 - p - {0x0c, 0x12, 0x3e}, // 113 - q - {0x1c, 0x02, 0x02}, // 114 - r - {0x14, 0x1e, 0x0a}, // 115 - s - {0x02, 0x1f, 0x12}, // 116 - t - {0x0e, 0x10, 0x1e}, // 117 - u - {0x0e, 0x18, 0x0e}, // 118 - v - {0x1e, 0x1c, 0x1e}, // 119 - w - {0x12, 0x0c, 0x12}, // 120 - x - {0x06, 0x28, 0x1e}, // 121 - y - {0x1a, 0x1e, 0x16}, // 122 - z - {0x04, 0x1b, 0x11}, // 123 - braceleft - {0x00, 0x1b, 0x00}, // 124 - bar - {0x11, 0x1b, 0x04}, // 125 - braceright - {0x02, 0x03, 0x01}, // 126 - asciitilde + const uint8_t gFont3x5[][3] = + { + {0x00, 0x00, 0x00}, // 32 - space + {0x00, 0x17, 0x00}, // 33 - exclam + {0x03, 0x00, 0x03}, // 34 - quotedbl + {0x1f, 0x0a, 0x1f}, // 35 - numbersign + {0x0a, 0x1f, 0x05}, // 36 - dollar + {0x09, 0x04, 0x12}, // 37 - percent + {0x0f, 0x17, 0x1c}, // 38 - ampersand + {0x00, 0x03, 0x00}, // 39 - quotesingle + {0x00, 0x0e, 0x11}, // 40 - parenleft + {0x11, 0x0e, 0x00}, // 41 - parenright + {0x05, 0x02, 0x05}, // 42 - asterisk + {0x04, 0x0e, 0x04}, // 43 - plus + {0x10, 0x08, 0x00}, // 44 - comma + {0x04, 0x04, 0x04}, // 45 - hyphen + {0x00, 0x10, 0x00}, // 46 - period + {0x18, 0x04, 0x03}, // 47 - slash + {0x1e, 0x11, 0x0f}, // 48 - zero + {0x02, 0x1f, 0x00}, // 49 - one + {0x19, 0x15, 0x12}, // 50 - two + {0x11, 0x15, 0x0a}, // 51 - three + {0x07, 0x04, 0x1f}, // 52 - four + {0x17, 0x15, 0x09}, // 53 - five + {0x1e, 0x15, 0x1d}, // 54 - six + {0x19, 0x05, 0x03}, // 55 - seven + {0x1f, 0x15, 0x1f}, // 56 - eight + {0x17, 0x15, 0x0f}, // 57 - nine + {0x00, 0x0a, 0x00}, // 58 - colon + {0x10, 0x0a, 0x00}, // 59 - semicolon + {0x04, 0x0a, 0x11}, // 60 - less + {0x0a, 0x0a, 0x0a}, // 61 - equal + {0x11, 0x0a, 0x04}, // 62 - greater + {0x01, 0x15, 0x03}, // 63 - question + {0x0e, 0x15, 0x16}, // 64 - at + {0x1e, 0x05, 0x1e}, // 65 - A + {0x1f, 0x15, 0x0a}, // 66 - B + {0x0e, 0x11, 0x11}, // 67 - C + {0x1f, 0x11, 0x0e}, // 68 - D + {0x1f, 0x15, 0x15}, // 69 - E + {0x1f, 0x05, 0x05}, // 70 - F + {0x0e, 0x15, 0x1d}, // 71 - G + {0x1f, 0x04, 0x1f}, // 72 - H + {0x11, 0x1f, 0x11}, // 73 - I + {0x08, 0x10, 0x0f}, // 74 - J + {0x1f, 0x04, 0x1b}, // 75 - K + {0x1f, 0x10, 0x10}, // 76 - L + {0x1f, 0x06, 0x1f}, // 77 - M + {0x1f, 0x0e, 0x1f}, // 78 - N + {0x0e, 0x11, 0x0e}, // 79 - O + {0x1f, 0x05, 0x02}, // 80 - P + {0x0e, 0x19, 0x1e}, // 81 - Q + {0x1f, 0x0d, 0x16}, // 82 - R + {0x12, 0x15, 0x09}, // 83 - S + {0x01, 0x1f, 0x01}, // 84 - T + {0x0f, 0x10, 0x1f}, // 85 - U + {0x07, 0x18, 0x07}, // 86 - V + {0x1f, 0x0c, 0x1f}, // 87 - W + {0x1b, 0x04, 0x1b}, // 88 - X + {0x03, 0x1c, 0x03}, // 89 - Y + {0x19, 0x15, 0x13}, // 90 - Z + {0x1f, 0x11, 0x11}, // 91 - bracketleft + {0x02, 0x04, 0x08}, // 92 - backslash + {0x11, 0x11, 0x1f}, // 93 - bracketright + {0x02, 0x01, 0x02}, // 94 - asciicircum + {0x10, 0x10, 0x10}, // 95 - underscore + {0x01, 0x02, 0x00}, // 96 - grave + {0x1a, 0x16, 0x1c}, // 97 - a + {0x1f, 0x12, 0x0c}, // 98 - b + {0x0c, 0x12, 0x12}, // 99 - c + {0x0c, 0x12, 0x1f}, // 100 - d + {0x0c, 0x1a, 0x16}, // 101 - e + {0x04, 0x1e, 0x05}, // 102 - f + {0x0c, 0x2a, 0x1e}, // 103 - g + {0x1f, 0x02, 0x1c}, // 104 - h + {0x00, 0x1d, 0x00}, // 105 - i + {0x10, 0x20, 0x1d}, // 106 - j + {0x1f, 0x0c, 0x12}, // 107 - k + {0x11, 0x1f, 0x10}, // 108 - l + {0x1e, 0x0e, 0x1e}, // 109 - m + {0x1e, 0x02, 0x1c}, // 110 - n + {0x0c, 0x12, 0x0c}, // 111 - o + {0x3e, 0x12, 0x0c}, // 112 - p + {0x0c, 0x12, 0x3e}, // 113 - q + {0x1c, 0x02, 0x02}, // 114 - r + {0x14, 0x1e, 0x0a}, // 115 - s + {0x02, 0x1f, 0x12}, // 116 - t + {0x0e, 0x10, 0x1e}, // 117 - u + {0x0e, 0x18, 0x0e}, // 118 - v + {0x1e, 0x1c, 0x1e}, // 119 - w + {0x12, 0x0c, 0x12}, // 120 - x + {0x06, 0x28, 0x1e}, // 121 - y + {0x1a, 0x1e, 0x16}, // 122 - z + {0x04, 0x1b, 0x11}, // 123 - braceleft + {0x00, 0x1b, 0x00}, // 124 - bar + {0x11, 0x1b, 0x04}, // 125 - braceright + {0x02, 0x03, 0x01}, // 126 - asciitilde - {0x12, 0x17, 0x12}, // 127 - plusminus + {0x12, 0x17, 0x12}, // 127 - plusminus - // {0x00, 0x00, 0x00}, // 127 - empty - // {0x00, 0x00, 0x00}, // 128 - empty - // {0x00, 0x00, 0x00}, // 129 - empty - // {0x00, 0x00, 0x00}, // 130 - empty - // {0x00, 0x00, 0x00}, // 131 - empty - // {0x00, 0x00, 0x00}, // 132 - empty - // {0x00, 0x00, 0x00}, // 133 - empty - // {0x00, 0x00, 0x00}, // 134 - empty - // {0x00, 0x00, 0x00}, // 135 - empty - // {0x00, 0x00, 0x00}, // 136 - empty - // {0x00, 0x00, 0x00}, // 137 - empty - // {0x00, 0x00, 0x00}, // 138 - empty - // {0x00, 0x00, 0x00}, // 139 - empty - // {0x00, 0x00, 0x00}, // 140 - empty - // {0x00, 0x00, 0x00}, // 141 - empty - // {0x00, 0x00, 0x00}, // 142 - empty - // {0x00, 0x00, 0x00}, // 143 - empty - // {0x00, 0x00, 0x00}, // 144 - empty - // {0x00, 0x00, 0x00}, // 145 - empty - // {0x00, 0x00, 0x00}, // 146 - empty - // {0x00, 0x00, 0x00}, // 147 - empty - // {0x00, 0x00, 0x00}, // 148 - empty - // {0x00, 0x00, 0x00}, // 149 - empty - // {0x00, 0x00, 0x00}, // 150 - empty - // {0x00, 0x00, 0x00}, // 151 - empty - // {0x00, 0x00, 0x00}, // 152 - empty - // {0x00, 0x00, 0x00}, // 153 - empty - // {0x00, 0x00, 0x00}, // 154 - empty - // {0x00, 0x00, 0x00}, // 155 - empty - // {0x00, 0x00, 0x00}, // 156 - empty - // {0x00, 0x00, 0x00}, // 157 - empty - // {0x00, 0x00, 0x00}, // 158 - empty - // {0x00, 0x00, 0x00}, // 159 - empty - // {0x00, 0x00, 0x00}, // 160 - empty - // {0x00, 0x1d, 0x00}, // 161 - exclamdown - // {0x0e, 0x1b, 0x0a}, // 162 - cent - // {0x14, 0x1f, 0x15}, // 163 - sterling - // {0x15, 0x0e, 0x15}, // 164 - currency - // {0x0b, 0x1c, 0x0b}, // 165 - yen - // {0x00, 0x1b, 0x00}, // 166 - brokenbar - // {0x14, 0x1b, 0x05}, // 167 - section - // {0x01, 0x00, 0x01}, // 168 - dieresis - // {0x02, 0x05, 0x05}, // 169 - copyright - // {0x16, 0x15, 0x17}, // 170 - ordfeminine - // {0x02, 0x05, 0x00}, // 171 - guillemotleft - // {0x02, 0x02, 0x06}, // 172 - logicalnot - // {0x04, 0x04, 0x00}, // 173 - softhyphen - // {0x07, 0x03, 0x04}, // 174 - registered - // {0x01, 0x01, 0x01}, // 175 - macron - // {0x02, 0x05, 0x02}, // 176 - degree - // {0x12, 0x17, 0x12}, // 177 - plusminus - // {0x01, 0x07, 0x04}, // 178 - twosuperior - // {0x05, 0x07, 0x07}, // 179 - threesuperior - // {0x00, 0x02, 0x01}, // 180 - acute - // {0x1f, 0x08, 0x07}, // 181 - mu - // {0x02, 0x1d, 0x1f}, // 182 - paragraph - // {0x0e, 0x0e, 0x0e}, // 183 - periodcentered - // {0x10, 0x14, 0x08}, // 184 - cedilla - // {0x00, 0x07, 0x00}, // 185 - onesuperior - // {0x12, 0x15, 0x12}, // 186 - ordmasculine - // {0x00, 0x05, 0x02}, // 187 - guillemotright - // {0x03, 0x08, 0x18}, // 188 - onequarter - // {0x0b, 0x18, 0x10}, // 189 - onehalf - // {0x03, 0x0b, 0x18}, // 190 - threequarters - // {0x18, 0x15, 0x10}, // 191 - questiondown - }; + // {0x00, 0x00, 0x00}, // 127 - empty + // {0x00, 0x00, 0x00}, // 128 - empty + // {0x00, 0x00, 0x00}, // 129 - empty + // {0x00, 0x00, 0x00}, // 130 - empty + // {0x00, 0x00, 0x00}, // 131 - empty + // {0x00, 0x00, 0x00}, // 132 - empty + // {0x00, 0x00, 0x00}, // 133 - empty + // {0x00, 0x00, 0x00}, // 134 - empty + // {0x00, 0x00, 0x00}, // 135 - empty + // {0x00, 0x00, 0x00}, // 136 - empty + // {0x00, 0x00, 0x00}, // 137 - empty + // {0x00, 0x00, 0x00}, // 138 - empty + // {0x00, 0x00, 0x00}, // 139 - empty + // {0x00, 0x00, 0x00}, // 140 - empty + // {0x00, 0x00, 0x00}, // 141 - empty + // {0x00, 0x00, 0x00}, // 142 - empty + // {0x00, 0x00, 0x00}, // 143 - empty + // {0x00, 0x00, 0x00}, // 144 - empty + // {0x00, 0x00, 0x00}, // 145 - empty + // {0x00, 0x00, 0x00}, // 146 - empty + // {0x00, 0x00, 0x00}, // 147 - empty + // {0x00, 0x00, 0x00}, // 148 - empty + // {0x00, 0x00, 0x00}, // 149 - empty + // {0x00, 0x00, 0x00}, // 150 - empty + // {0x00, 0x00, 0x00}, // 151 - empty + // {0x00, 0x00, 0x00}, // 152 - empty + // {0x00, 0x00, 0x00}, // 153 - empty + // {0x00, 0x00, 0x00}, // 154 - empty + // {0x00, 0x00, 0x00}, // 155 - empty + // {0x00, 0x00, 0x00}, // 156 - empty + // {0x00, 0x00, 0x00}, // 157 - empty + // {0x00, 0x00, 0x00}, // 158 - empty + // {0x00, 0x00, 0x00}, // 159 - empty + // {0x00, 0x00, 0x00}, // 160 - empty + // {0x00, 0x1d, 0x00}, // 161 - exclamdown + // {0x0e, 0x1b, 0x0a}, // 162 - cent + // {0x14, 0x1f, 0x15}, // 163 - sterling + // {0x15, 0x0e, 0x15}, // 164 - currency + // {0x0b, 0x1c, 0x0b}, // 165 - yen + // {0x00, 0x1b, 0x00}, // 166 - brokenbar + // {0x14, 0x1b, 0x05}, // 167 - section + // {0x01, 0x00, 0x01}, // 168 - dieresis + // {0x02, 0x05, 0x05}, // 169 - copyright + // {0x16, 0x15, 0x17}, // 170 - ordfeminine + // {0x02, 0x05, 0x00}, // 171 - guillemotleft + // {0x02, 0x02, 0x06}, // 172 - logicalnot + // {0x04, 0x04, 0x00}, // 173 - softhyphen + // {0x07, 0x03, 0x04}, // 174 - registered + // {0x01, 0x01, 0x01}, // 175 - macron + // {0x02, 0x05, 0x02}, // 176 - degree + // {0x12, 0x17, 0x12}, // 177 - plusminus + // {0x01, 0x07, 0x04}, // 178 - twosuperior + // {0x05, 0x07, 0x07}, // 179 - threesuperior + // {0x00, 0x02, 0x01}, // 180 - acute + // {0x1f, 0x08, 0x07}, // 181 - mu + // {0x02, 0x1d, 0x1f}, // 182 - paragraph + // {0x0e, 0x0e, 0x0e}, // 183 - periodcentered + // {0x10, 0x14, 0x08}, // 184 - cedilla + // {0x00, 0x07, 0x00}, // 185 - onesuperior + // {0x12, 0x15, 0x12}, // 186 - ordmasculine + // {0x00, 0x05, 0x02}, // 187 - guillemotright + // {0x03, 0x08, 0x18}, // 188 - onequarter + // {0x0b, 0x18, 0x10}, // 189 - onehalf + // {0x03, 0x0b, 0x18}, // 190 - threequarters + // {0x18, 0x15, 0x10}, // 191 - questiondown + }; //#endif diff --git a/font.h b/font.h index f93ef50..8972aab 100644 --- a/font.h +++ b/font.h @@ -25,7 +25,7 @@ extern const uint8_t gFontBigDigits[11][26 - 6]; extern const uint8_t gFont3x5[96][3]; extern const uint8_t gFontSmall[95 - 1][6]; #ifdef ENABLE_SMALL_BOLD - extern const uint8_t gFontSmallBold[95 - 1][6]; + extern const uint8_t gFontSmallBold[95 - 1][6]; #endif #endif diff --git a/frequencies.c b/frequencies.c index 000ff6d..daad6ff 100644 --- a/frequencies.c +++ b/frequencies.c @@ -29,87 +29,87 @@ const freq_band_table_t BX4819_band2 = {84000000, BX4819_band2_upper}; const freq_band_table_t frequencyBandTable[] = { - #ifndef ENABLE_WIDE_RX - // QS original - [BAND1_50MHz ]={.lower = 5000000, .upper = 7600000}, - [BAND7_470MHz]={.lower = 47000000, .upper = 60000000}, - #else - // extended range - [BAND1_50MHz ]={.lower = BX4819_band1_lower, .upper = 10800000}, - [BAND7_470MHz]={.lower = 47000000, .upper = BX4819_band2_upper}, - #endif - [BAND2_108MHz]={.lower = 10800000, .upper = 13700000}, - [BAND3_137MHz]={.lower = 13700000, .upper = 17400000}, - [BAND4_174MHz]={.lower = 17400000, .upper = 35000000}, - [BAND5_350MHz]={.lower = 35000000, .upper = 40000000}, - [BAND6_400MHz]={.lower = 40000000, .upper = 47000000} + #ifndef ENABLE_WIDE_RX + // QS original + [BAND1_50MHz ]={.lower = 5000000, .upper = 7600000}, + [BAND7_470MHz]={.lower = 47000000, .upper = 60000000}, + #else + // extended range + [BAND1_50MHz ]={.lower = BX4819_band1_lower, .upper = 10800000}, + [BAND7_470MHz]={.lower = 47000000, .upper = BX4819_band2_upper}, + #endif + [BAND2_108MHz]={.lower = 10800000, .upper = 13700000}, + [BAND3_137MHz]={.lower = 13700000, .upper = 17400000}, + [BAND4_174MHz]={.lower = 17400000, .upper = 35000000}, + [BAND5_350MHz]={.lower = 35000000, .upper = 40000000}, + [BAND6_400MHz]={.lower = 40000000, .upper = 47000000} }; #ifdef ENABLE_NOAA - const uint32_t NoaaFrequencyTable[10] = - { - 16255000, - 16240000, - 16247500, - 16242500, - 16245000, - 16250000, - 16252500, - 16152500, - 16177500, - 16327500 - }; + const uint32_t NoaaFrequencyTable[10] = + { + 16255000, + 16240000, + 16247500, + 16242500, + 16245000, + 16250000, + 16252500, + 16152500, + 16177500, + 16327500 + }; #endif // this order of steps has to be preserved for backwards compatibility with other/stock firmwares const uint16_t gStepFrequencyTable[] = { // standard steps - [STEP_2_5kHz] = 250, - [STEP_5kHz] = 500, - [STEP_6_25kHz] = 625, - [STEP_10kHz] = 1000, - [STEP_12_5kHz] = 1250, - [STEP_25kHz] = 2500, - [STEP_8_33kHz] = 833, + [STEP_2_5kHz] = 250, + [STEP_5kHz] = 500, + [STEP_6_25kHz] = 625, + [STEP_10kHz] = 1000, + [STEP_12_5kHz] = 1250, + [STEP_25kHz] = 2500, + [STEP_8_33kHz] = 833, // custom steps - [STEP_0_01kHz] = 1, - [STEP_0_05kHz] = 5, - [STEP_0_1kHz] = 10, - [STEP_0_25kHz] = 25, - [STEP_0_5kHz] = 50, - [STEP_1kHz] = 100, - [STEP_1_25kHz] = 125, - [STEP_9kHz] = 900, - [STEP_15kHz] = 1500, - [STEP_20kHz] = 2000, - [STEP_30kHz] = 3000, - [STEP_50kHz] = 5000, - [STEP_100kHz] = 10000, - [STEP_125kHz] = 12500, - [STEP_200kHz] = 20000, - [STEP_250kHz] = 25000, - [STEP_500kHz] = 50000 + [STEP_0_01kHz] = 1, + [STEP_0_05kHz] = 5, + [STEP_0_1kHz] = 10, + [STEP_0_25kHz] = 25, + [STEP_0_5kHz] = 50, + [STEP_1kHz] = 100, + [STEP_1_25kHz] = 125, + [STEP_9kHz] = 900, + [STEP_15kHz] = 1500, + [STEP_20kHz] = 2000, + [STEP_30kHz] = 3000, + [STEP_50kHz] = 5000, + [STEP_100kHz] = 10000, + [STEP_125kHz] = 12500, + [STEP_200kHz] = 20000, + [STEP_250kHz] = 25000, + [STEP_500kHz] = 50000 }; const STEP_Setting_t StepSortedIndexes[] = { - STEP_0_01kHz, STEP_0_05kHz, STEP_0_1kHz, STEP_0_25kHz, STEP_0_5kHz, STEP_1kHz, STEP_1_25kHz, STEP_2_5kHz, STEP_5kHz, STEP_6_25kHz, - STEP_8_33kHz, STEP_9kHz, STEP_10kHz, STEP_12_5kHz, STEP_15kHz, STEP_20kHz, STEP_25kHz, STEP_30kHz, STEP_50kHz, STEP_100kHz, - STEP_125kHz, STEP_200kHz, STEP_250kHz, STEP_500kHz + STEP_0_01kHz, STEP_0_05kHz, STEP_0_1kHz, STEP_0_25kHz, STEP_0_5kHz, STEP_1kHz, STEP_1_25kHz, STEP_2_5kHz, STEP_5kHz, STEP_6_25kHz, + STEP_8_33kHz, STEP_9kHz, STEP_10kHz, STEP_12_5kHz, STEP_15kHz, STEP_20kHz, STEP_25kHz, STEP_30kHz, STEP_50kHz, STEP_100kHz, + STEP_125kHz, STEP_200kHz, STEP_250kHz, STEP_500kHz }; STEP_Setting_t FREQUENCY_GetStepIdxFromSortedIdx(uint8_t sortedIdx) { - return StepSortedIndexes[sortedIdx]; + return StepSortedIndexes[sortedIdx]; } uint32_t FREQUENCY_GetSortedIdxFromStepIdx(uint8_t stepIdx) { - for(uint8_t i = 0; i < ARRAY_SIZE(gStepFrequencyTable); i++) - if(StepSortedIndexes[i] == stepIdx) - return i; - return 0; + for(uint8_t i = 0; i < ARRAY_SIZE(gStepFrequencyTable); i++) + if(StepSortedIndexes[i] == stepIdx) + return i; + return 0; } static_assert(ARRAY_SIZE(gStepFrequencyTable) == STEP_N_ELEM); @@ -117,165 +117,165 @@ static_assert(ARRAY_SIZE(gStepFrequencyTable) == STEP_N_ELEM); FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency) { - for (int32_t band = BAND_N_ELEM - 1; band >= 0; band--) - if (Frequency >= frequencyBandTable[band].lower) - return (FREQUENCY_Band_t)band; + for (int32_t band = BAND_N_ELEM - 1; band >= 0; band--) + if (Frequency >= frequencyBandTable[band].lower) + return (FREQUENCY_Band_t)band; - return BAND1_50MHz; + return BAND1_50MHz; } uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, int32_t LowerLimit, int32_t Middle, int32_t UpperLimit, int32_t Frequency) { - if (Frequency <= LowerLimit) - return TxpLow; + if (Frequency <= LowerLimit) + return TxpLow; - if (UpperLimit <= Frequency) - return TxpHigh; + if (UpperLimit <= Frequency) + return TxpHigh; - if (Frequency <= Middle) - { - TxpMid += ((TxpMid - TxpLow) * (Frequency - LowerLimit)) / (Middle - LowerLimit); - return TxpMid; - } + if (Frequency <= Middle) + { + TxpMid += ((TxpMid - TxpLow) * (Frequency - LowerLimit)) / (Middle - LowerLimit); + return TxpMid; + } - TxpMid += ((TxpHigh - TxpMid) * (Frequency - Middle)) / (UpperLimit - Middle); + TxpMid += ((TxpHigh - TxpMid) * (Frequency - Middle)) / (UpperLimit - Middle); - return TxpMid; + return TxpMid; } uint32_t FREQUENCY_RoundToStep(uint32_t freq, uint16_t step) { - if(step == 833) { + if(step == 833) { uint32_t base = freq/2500*2500; int chno = (freq - base) / 700; // convert entered aviation 8.33Khz channel number scheme to actual frequency. return base + (chno * 833) + (chno == 3); - } + } - if(step == 1) - return freq; - if(step >= 1000) - step = step/2; - return (freq + (step + 1) / 2) / step * step; + if(step == 1) + return freq; + if(step >= 1000) + step = step/2; + return (freq + (step + 1) / 2) / step * step; } int32_t TX_freq_check(const uint32_t Frequency) -{ // return '0' if TX frequency is allowed - // otherwise return '-1' +{ // return '0' if TX frequency is allowed + // otherwise return '-1' - if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper) - return 1; // not allowed outside this range + if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper) + return 1; // not allowed outside this range - if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) - return -1; // BX chip does not work in this range + if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) + return -1; // BX chip does not work in this range - switch (gSetting_F_LOCK) - { - case F_LOCK_DEF: - if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < frequencyBandTable[BAND3_137MHz].upper) - return 0; - if (Frequency >= frequencyBandTable[BAND4_174MHz].lower && Frequency < frequencyBandTable[BAND4_174MHz].upper) - if (gSetting_200TX) - return 0; - if (Frequency >= frequencyBandTable[BAND5_350MHz].lower && Frequency < frequencyBandTable[BAND5_350MHz].upper) - if (gSetting_350TX && gSetting_350EN) - return 0; - if (Frequency >= frequencyBandTable[BAND6_400MHz].lower && Frequency < frequencyBandTable[BAND6_400MHz].upper) - return 0; - if (Frequency >= frequencyBandTable[BAND7_470MHz].lower && Frequency <= 60000000) - if (gSetting_500TX) - return 0; - break; + switch (gSetting_F_LOCK) + { + case F_LOCK_DEF: + if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < frequencyBandTable[BAND3_137MHz].upper) + return 0; + if (Frequency >= frequencyBandTable[BAND4_174MHz].lower && Frequency < frequencyBandTable[BAND4_174MHz].upper) + if (gSetting_200TX) + return 0; + if (Frequency >= frequencyBandTable[BAND5_350MHz].lower && Frequency < frequencyBandTable[BAND5_350MHz].upper) + if (gSetting_350TX && gSetting_350EN) + return 0; + if (Frequency >= frequencyBandTable[BAND6_400MHz].lower && Frequency < frequencyBandTable[BAND6_400MHz].upper) + return 0; + if (Frequency >= frequencyBandTable[BAND7_470MHz].lower && Frequency <= 60000000) + if (gSetting_500TX) + return 0; + break; - case F_LOCK_FCC: - if (Frequency >= 14400000 && Frequency < 14800000) - return 0; - if (Frequency >= 42000000 && Frequency < 45000000) - return 0; - break; + case F_LOCK_FCC: + if (Frequency >= 14400000 && Frequency < 14800000) + return 0; + if (Frequency >= 42000000 && Frequency < 45000000) + return 0; + break; - case F_LOCK_CE: - if (Frequency >= 14400000 && Frequency < 14600000) - return 0; - if (Frequency >= 43000000 && Frequency < 44000000) - return 0; - break; + case F_LOCK_CE: + if (Frequency >= 14400000 && Frequency < 14600000) + return 0; + if (Frequency >= 43000000 && Frequency < 44000000) + return 0; + break; - case F_LOCK_GB: - if (Frequency >= 14400000 && Frequency < 14800000) - return 0; - if (Frequency >= 43000000 && Frequency < 44000000) - return 0; - break; + case F_LOCK_GB: + if (Frequency >= 14400000 && Frequency < 14800000) + return 0; + if (Frequency >= 43000000 && Frequency < 44000000) + return 0; + break; - case F_LOCK_430: - if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000) - return 0; - if (Frequency >= 40000000 && Frequency < 43000000) - return 0; - break; + case F_LOCK_430: + if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000) + return 0; + if (Frequency >= 40000000 && Frequency < 43000000) + return 0; + break; - case F_LOCK_438: - if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000) - return 0; - if (Frequency >= 40000000 && Frequency < 43800000) - return 0; - break; + case F_LOCK_438: + if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000) + return 0; + if (Frequency >= 40000000 && Frequency < 43800000) + return 0; + break; #ifdef ENABLE_FEAT_F4HWN_PMR - case F_LOCK_PMR: - if (Frequency >= 44600625 && Frequency <= 44619375) - return 0; - break; + case F_LOCK_PMR: + if (Frequency >= 44600625 && Frequency <= 44619375) + return 0; + break; #endif #ifdef ENABLE_FEAT_F4HWN_GMRS_FRS_MURS - case F_LOCK_GMRS_FRS_MURS: - // https://forums.radioreference.com/threads/the-great-unofficial-radioreference-frs-gmrs-murs-fact-sheet.275370/ - if ((Frequency >= 46255000 && Frequency <= 46272500) || - (Frequency >= 46755000 && Frequency <= 46772500)) // FRS/GMRS - return 0; - if (Frequency == 15182000 || - Frequency == 15188000 || - Frequency == 15194000 || - Frequency == 15457000 || - Frequency == 15460000) // MURS - return 0; - break; + case F_LOCK_GMRS_FRS_MURS: + // https://forums.radioreference.com/threads/the-great-unofficial-radioreference-frs-gmrs-murs-fact-sheet.275370/ + if ((Frequency >= 46255000 && Frequency <= 46272500) || + (Frequency >= 46755000 && Frequency <= 46772500)) // FRS/GMRS + return 0; + if (Frequency == 15182000 || + Frequency == 15188000 || + Frequency == 15194000 || + Frequency == 15457000 || + Frequency == 15460000) // MURS + return 0; + break; #endif -#ifdef ENABLE_FEAT_F4HWN_CA - case F_LOCK_CA: - if (Frequency >= 14400000 && Frequency < 14800000) - return 0; - if (Frequency >= 43000000 && Frequency < 45000000) - return 0; - break; +#ifdef ENABLE_FEAT_F4HWN_CA + case F_LOCK_CA: + if (Frequency >= 14400000 && Frequency < 14800000) + return 0; + if (Frequency >= 43000000 && Frequency < 45000000) + return 0; + break; #endif - case F_LOCK_ALL: - break; + case F_LOCK_ALL: + break; - case F_LOCK_NONE: - for (uint32_t i = 0; i < ARRAY_SIZE(frequencyBandTable); i++) - if (Frequency >= frequencyBandTable[i].lower && Frequency < frequencyBandTable[i].upper) - return 0; - break; - } + case F_LOCK_NONE: + for (uint32_t i = 0; i < ARRAY_SIZE(frequencyBandTable); i++) + if (Frequency >= frequencyBandTable[i].lower && Frequency < frequencyBandTable[i].upper) + return 0; + break; + } - // dis-allowed TX frequency - return -1; + // dis-allowed TX frequency + return -1; } int32_t RX_freq_check(const uint32_t Frequency) -{ // return '0' if RX frequency is allowed - // otherwise return '-1' +{ // return '0' if RX frequency is allowed + // otherwise return '-1' - if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper) - return -1; + if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper) + return -1; - if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) - return -1; + if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) + return -1; - return 0; // OK frequency + return 0; // OK frequency } diff --git a/frequencies.h b/frequencies.h index b5d4c16..2e49ea1 100644 --- a/frequencies.h +++ b/frequencies.h @@ -22,70 +22,70 @@ #define _1GHz_in_KHz 100000000 typedef struct { - const uint32_t lower; - const uint32_t upper; + const uint32_t lower; + const uint32_t upper; } freq_band_table_t; extern const freq_band_table_t BX4819_band1; extern const freq_band_table_t BX4819_band2; typedef enum { - BAND_NONE = -1, - BAND1_50MHz = 0, - BAND2_108MHz, - BAND3_137MHz, - BAND4_174MHz, - BAND5_350MHz, - BAND6_400MHz, - BAND7_470MHz, - BAND_N_ELEM + BAND_NONE = -1, + BAND1_50MHz = 0, + BAND2_108MHz, + BAND3_137MHz, + BAND4_174MHz, + BAND5_350MHz, + BAND6_400MHz, + BAND7_470MHz, + BAND_N_ELEM } FREQUENCY_Band_t; extern const freq_band_table_t frequencyBandTable[]; typedef enum { // standard steps - STEP_2_5kHz, - STEP_5kHz, - STEP_6_25kHz, - STEP_10kHz, - STEP_12_5kHz, - STEP_25kHz, - STEP_8_33kHz, + STEP_2_5kHz, + STEP_5kHz, + STEP_6_25kHz, + STEP_10kHz, + STEP_12_5kHz, + STEP_25kHz, + STEP_8_33kHz, // custom steps - STEP_0_01kHz, - STEP_0_05kHz, - STEP_0_1kHz, - STEP_0_25kHz, - STEP_0_5kHz, - STEP_1kHz, - STEP_1_25kHz, - STEP_9kHz, - STEP_15kHz, - STEP_20kHz, - STEP_30kHz, - STEP_50kHz, - STEP_100kHz, - STEP_125kHz, - STEP_200kHz, - STEP_250kHz, - STEP_500kHz, - STEP_N_ELEM + STEP_0_01kHz, + STEP_0_05kHz, + STEP_0_1kHz, + STEP_0_25kHz, + STEP_0_5kHz, + STEP_1kHz, + STEP_1_25kHz, + STEP_9kHz, + STEP_15kHz, + STEP_20kHz, + STEP_30kHz, + STEP_50kHz, + STEP_100kHz, + STEP_125kHz, + STEP_200kHz, + STEP_250kHz, + STEP_500kHz, + STEP_N_ELEM } STEP_Setting_t; extern const uint16_t gStepFrequencyTable[]; #ifdef ENABLE_NOAA - extern const uint32_t NoaaFrequencyTable[10]; + extern const uint32_t NoaaFrequencyTable[10]; #endif FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency); uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, int32_t LowerLimit, int32_t Middle, int32_t UpperLimit, int32_t Frequency); -uint32_t FREQUENCY_RoundToStep(uint32_t freq, uint16_t step); +uint32_t FREQUENCY_RoundToStep(uint32_t freq, uint16_t step); STEP_Setting_t FREQUENCY_GetStepIdxFromSortedIdx(uint8_t sortedIdx); -uint32_t FREQUENCY_GetSortedIdxFromStepIdx(uint8_t step); +uint32_t FREQUENCY_GetSortedIdxFromStepIdx(uint8_t step); int32_t TX_freq_check(uint32_t Frequency); int32_t RX_freq_check(uint32_t Frequency); diff --git a/functions.c b/functions.c index 3a98566..7743005 100644 --- a/functions.c +++ b/functions.c @@ -18,14 +18,14 @@ #include "app/dtmf.h" #if defined(ENABLE_FMRADIO) - #include "app/fm.h" + #include "app/fm.h" #endif #include "audio.h" #include "bsp/dp32g030/gpio.h" #include "dcs.h" #include "driver/backlight.h" #if defined(ENABLE_FMRADIO) - #include "driver/bk1080.h" + #include "driver/bk1080.h" #endif #include "driver/bk4819.h" #include "driver/gpio.h" @@ -44,235 +44,235 @@ FUNCTION_Type_t gCurrentFunction; bool FUNCTION_IsRx() { - return gCurrentFunction == FUNCTION_MONITOR || - gCurrentFunction == FUNCTION_INCOMING || - gCurrentFunction == FUNCTION_RECEIVE; + return gCurrentFunction == FUNCTION_MONITOR || + gCurrentFunction == FUNCTION_INCOMING || + gCurrentFunction == FUNCTION_RECEIVE; } void FUNCTION_Init(void) { - g_CxCSS_TAIL_Found = false; - g_CDCSS_Lost = false; - g_CTCSS_Lost = false; + g_CxCSS_TAIL_Found = false; + g_CDCSS_Lost = false; + g_CTCSS_Lost = false; - g_SquelchLost = false; + g_SquelchLost = false; - gFlagTailNoteEliminationComplete = false; - gTailNoteEliminationCountdown_10ms = 0; - gFoundCTCSS = false; - gFoundCDCSS = false; - gFoundCTCSSCountdown_10ms = 0; - gFoundCDCSSCountdown_10ms = 0; - gEndOfRxDetectedMaybe = false; + gFlagTailNoteEliminationComplete = false; + gTailNoteEliminationCountdown_10ms = 0; + gFoundCTCSS = false; + gFoundCDCSS = false; + gFoundCTCSSCountdown_10ms = 0; + gFoundCDCSSCountdown_10ms = 0; + gEndOfRxDetectedMaybe = false; - gCurrentCodeType = (gRxVfo->Modulation != MODULATION_FM) ? CODE_TYPE_OFF : gRxVfo->pRX->CodeType; + gCurrentCodeType = (gRxVfo->Modulation != MODULATION_FM) ? CODE_TYPE_OFF : gRxVfo->pRX->CodeType; #ifdef ENABLE_VOX - g_VOX_Lost = false; + g_VOX_Lost = false; #endif #ifdef ENABLE_DTMF_CALLING - DTMF_clear_RX(); + DTMF_clear_RX(); #endif #ifdef ENABLE_NOAA - gNOAACountdown_10ms = 0; + gNOAACountdown_10ms = 0; - if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) { - gCurrentCodeType = CODE_TYPE_CONTINUOUS_TONE; - } + if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) { + gCurrentCodeType = CODE_TYPE_CONTINUOUS_TONE; + } #endif - gUpdateStatus = true; + gUpdateStatus = true; } void FUNCTION_Foreground(const FUNCTION_Type_t PreviousFunction) { #ifdef ENABLE_DTMF_CALLING - if (gDTMF_ReplyState != DTMF_REPLY_NONE) - RADIO_PrepareCssTX(); + if (gDTMF_ReplyState != DTMF_REPLY_NONE) + RADIO_PrepareCssTX(); #endif - if (PreviousFunction == FUNCTION_TRANSMIT) { - ST7565_FixInterfGlitch(); - gVFO_RSSI_bar_level[0] = 0; - gVFO_RSSI_bar_level[1] = 0; - } else if (PreviousFunction != FUNCTION_RECEIVE) { - return; - } + if (PreviousFunction == FUNCTION_TRANSMIT) { + ST7565_FixInterfGlitch(); + gVFO_RSSI_bar_level[0] = 0; + gVFO_RSSI_bar_level[1] = 0; + } else if (PreviousFunction != FUNCTION_RECEIVE) { + return; + } #if defined(ENABLE_FMRADIO) - if (gFmRadioMode) - gFM_RestoreCountdown_10ms = fm_restore_countdown_10ms; + if (gFmRadioMode) + gFM_RestoreCountdown_10ms = fm_restore_countdown_10ms; #endif #ifdef ENABLE_DTMF_CALLING - if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT || - gDTMF_CallState == DTMF_CALL_STATE_RECEIVED || - gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY) - { - gDTMF_auto_reset_time_500ms = gEeprom.DTMF_auto_reset_time * 2; - } + if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT || + gDTMF_CallState == DTMF_CALL_STATE_RECEIVED || + gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY) + { + gDTMF_auto_reset_time_500ms = gEeprom.DTMF_auto_reset_time * 2; + } #endif - gUpdateStatus = true; + gUpdateStatus = true; } void FUNCTION_PowerSave() { - gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10; - gPowerSaveCountdownExpired = false; + gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10; + gPowerSaveCountdownExpired = false; - gRxIdleMode = true; + gRxIdleMode = true; - gMonitor = false; + gMonitor = false; - BK4819_DisableVox(); - BK4819_Sleep(); + BK4819_DisableVox(); + BK4819_Sleep(); - BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false); + BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false); - gUpdateStatus = true; + gUpdateStatus = true; - if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu - GUI_SelectNextDisplay(DISPLAY_MAIN); + if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu + GUI_SelectNextDisplay(DISPLAY_MAIN); } void FUNCTION_Transmit() { - // if DTMF is enabled when TX'ing, it changes the TX audio filtering !! .. 1of11 - BK4819_DisableDTMF(); + // if DTMF is enabled when TX'ing, it changes the TX audio filtering !! .. 1of11 + BK4819_DisableDTMF(); #ifdef ENABLE_DTMF_CALLING - // clear the DTMF RX buffer - DTMF_clear_RX(); + // clear the DTMF RX buffer + DTMF_clear_RX(); #endif - // clear the DTMF RX live decoder buffer - gDTMF_RX_live_timeout = 0; - memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); + // clear the DTMF RX live decoder buffer + gDTMF_RX_live_timeout = 0; + memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); #if defined(ENABLE_FMRADIO) - if (gFmRadioMode) - BK1080_Init0(); + if (gFmRadioMode) + BK1080_Init0(); #endif #ifdef ENABLE_ALARM - if (gAlarmState == ALARM_STATE_SITE_ALARM) - { - GUI_DisplayScreen(); + if (gAlarmState == ALARM_STATE_SITE_ALARM) + { + GUI_DisplayScreen(); - AUDIO_AudioPathOff(); + AUDIO_AudioPathOff(); - SYSTEM_DelayMs(20); - BK4819_PlayTone(500, 0); - SYSTEM_DelayMs(2); + SYSTEM_DelayMs(20); + BK4819_PlayTone(500, 0); + SYSTEM_DelayMs(2); - AUDIO_AudioPathOn(); + AUDIO_AudioPathOn(); - gEnableSpeaker = true; + gEnableSpeaker = true; - SYSTEM_DelayMs(60); - BK4819_ExitTxMute(); + SYSTEM_DelayMs(60); + BK4819_ExitTxMute(); - gAlarmToneCounter = 0; - return; - } + gAlarmToneCounter = 0; + return; + } #endif - gUpdateStatus = true; + gUpdateStatus = true; - GUI_DisplayScreen(); + GUI_DisplayScreen(); - RADIO_SetTxParameters(); + RADIO_SetTxParameters(); - // turn the RED LED on - BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); + // turn the RED LED on + BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); - DTMF_Reply(); + DTMF_Reply(); - if (gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO) - BK4819_PlaySingleTone(2525, 250, 0, gEeprom.DTMF_SIDE_TONE); + if (gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_APOLLO) + BK4819_PlaySingleTone(2525, 250, 0, gEeprom.DTMF_SIDE_TONE); #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) - if (gAlarmState != ALARM_STATE_OFF) { - #ifdef ENABLE_TX1750 - if (gAlarmState == ALARM_STATE_TX1750) - BK4819_TransmitTone(true, 1750); - #endif + if (gAlarmState != ALARM_STATE_OFF) { + #ifdef ENABLE_TX1750 + if (gAlarmState == ALARM_STATE_TX1750) + BK4819_TransmitTone(true, 1750); + #endif - #ifdef ENABLE_ALARM - if (gAlarmState == ALARM_STATE_TXALARM) - BK4819_TransmitTone(true, 500); + #ifdef ENABLE_ALARM + if (gAlarmState == ALARM_STATE_TXALARM) + BK4819_TransmitTone(true, 500); - gAlarmToneCounter = 0; - #endif + gAlarmToneCounter = 0; + #endif - SYSTEM_DelayMs(2); - AUDIO_AudioPathOn(); - gEnableSpeaker = true; + SYSTEM_DelayMs(2); + AUDIO_AudioPathOn(); + gEnableSpeaker = true; - gVfoConfigureMode = VFO_CONFIGURE; - return; - } + gVfoConfigureMode = VFO_CONFIGURE; + return; + } #endif #ifdef ENABLE_FEAT_F4HWN - BK4819_DisableScramble(); + BK4819_DisableScramble(); #else - if (gCurrentVfo->SCRAMBLING_TYPE > 0 && gSetting_ScrambleEnable) - BK4819_EnableScramble(gCurrentVfo->SCRAMBLING_TYPE - 1); - else - BK4819_DisableScramble(); + if (gCurrentVfo->SCRAMBLING_TYPE > 0 && gSetting_ScrambleEnable) + BK4819_EnableScramble(gCurrentVfo->SCRAMBLING_TYPE - 1); + else + BK4819_DisableScramble(); #endif - if (gSetting_backlight_on_tx_rx & BACKLIGHT_ON_TR_TX) { - BACKLIGHT_TurnOn(); - } + if (gSetting_backlight_on_tx_rx & BACKLIGHT_ON_TR_TX) { + BACKLIGHT_TurnOn(); + } } void FUNCTION_Select(FUNCTION_Type_t Function) { - const FUNCTION_Type_t PreviousFunction = gCurrentFunction; - const bool bWasPowerSave = PreviousFunction == FUNCTION_POWER_SAVE; + const FUNCTION_Type_t PreviousFunction = gCurrentFunction; + const bool bWasPowerSave = PreviousFunction == FUNCTION_POWER_SAVE; - gCurrentFunction = Function; + gCurrentFunction = Function; - if (bWasPowerSave && Function != FUNCTION_POWER_SAVE) { - BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable(); - gRxIdleMode = false; - UI_DisplayStatus(); - } + if (bWasPowerSave && Function != FUNCTION_POWER_SAVE) { + BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable(); + gRxIdleMode = false; + UI_DisplayStatus(); + } - switch (Function) { - case FUNCTION_FOREGROUND: - FUNCTION_Foreground(PreviousFunction); - return; + switch (Function) { + case FUNCTION_FOREGROUND: + FUNCTION_Foreground(PreviousFunction); + return; - case FUNCTION_POWER_SAVE: - FUNCTION_PowerSave(); - return; + case FUNCTION_POWER_SAVE: + FUNCTION_PowerSave(); + return; - case FUNCTION_TRANSMIT: - FUNCTION_Transmit(); - break; + case FUNCTION_TRANSMIT: + FUNCTION_Transmit(); + break; - case FUNCTION_MONITOR: - gMonitor = true; - break; + case FUNCTION_MONITOR: + gMonitor = true; + break; - case FUNCTION_INCOMING: - case FUNCTION_RECEIVE: - case FUNCTION_BAND_SCOPE: - default: - break; - } + case FUNCTION_INCOMING: + case FUNCTION_RECEIVE: + case FUNCTION_BAND_SCOPE: + default: + break; + } - gBatterySaveCountdown_10ms = battery_save_count_10ms; - gSchedulePowerSave = false; + gBatterySaveCountdown_10ms = battery_save_count_10ms; + gSchedulePowerSave = false; #if defined(ENABLE_FMRADIO) - if(Function != FUNCTION_INCOMING) - gFM_RestoreCountdown_10ms = 0; + if(Function != FUNCTION_INCOMING) + gFM_RestoreCountdown_10ms = 0; #endif } diff --git a/functions.h b/functions.h index bfec351..ec1d983 100644 --- a/functions.h +++ b/functions.h @@ -21,14 +21,14 @@ enum FUNCTION_Type_t { - FUNCTION_FOREGROUND = 0, // ??? - FUNCTION_TRANSMIT, // transmitting - FUNCTION_MONITOR, // receiving with squelch forced open - FUNCTION_INCOMING, // receiving a signal (squelch is open) - FUNCTION_RECEIVE, // RX mode, squelch closed - FUNCTION_POWER_SAVE, // sleeping - FUNCTION_BAND_SCOPE, // bandscope mode (panadpter/spectrum) .. not yet implemented - FUNCTION_N_ELEM + FUNCTION_FOREGROUND = 0, // ??? + FUNCTION_TRANSMIT, // transmitting + FUNCTION_MONITOR, // receiving with squelch forced open + FUNCTION_INCOMING, // receiving a signal (squelch is open) + FUNCTION_RECEIVE, // RX mode, squelch closed + FUNCTION_POWER_SAVE, // sleeping + FUNCTION_BAND_SCOPE, // bandscope mode (panadpter/spectrum) .. not yet implemented + FUNCTION_N_ELEM }; typedef enum FUNCTION_Type_t FUNCTION_Type_t; diff --git a/helper/battery.c b/helper/battery.c index ee8fe46..f61974a 100644 --- a/helper/battery.c +++ b/helper/battery.c @@ -40,207 +40,207 @@ bool gLowBatteryConfirmed; uint16_t gBatteryCheckCounter; typedef enum { - BATTERY_LOW_INACTIVE, - BATTERY_LOW_ACTIVE, - BATTERY_LOW_CONFIRMED + BATTERY_LOW_INACTIVE, + BATTERY_LOW_ACTIVE, + BATTERY_LOW_CONFIRMED } BatteryLow_t; uint16_t lowBatteryCountdown; -const uint16_t lowBatteryPeriod = 30; +const uint16_t lowBatteryPeriod = 30; volatile uint16_t gPowerSave_10ms; const uint16_t Voltage2PercentageTable[][7][3] = { - [BATTERY_TYPE_1600_MAH] = { - {828, 100}, - {814, 97 }, - {760, 25 }, - {729, 6 }, - {630, 0 }, - {0, 0 }, - {0, 0 }, - }, + [BATTERY_TYPE_1600_MAH] = { + {828, 100}, + {814, 97 }, + {760, 25 }, + {729, 6 }, + {630, 0 }, + {0, 0 }, + {0, 0 }, + }, - [BATTERY_TYPE_2200_MAH] = { - {832, 100}, - {813, 95 }, - {740, 60 }, - {707, 21 }, - {682, 5 }, - {630, 0 }, - {0, 0 }, - }, + [BATTERY_TYPE_2200_MAH] = { + {832, 100}, + {813, 95 }, + {740, 60 }, + {707, 21 }, + {682, 5 }, + {630, 0 }, + {0, 0 }, + }, - [BATTERY_TYPE_3500_MAH] = { - {837, 100}, - {826, 95 }, - {750, 50 }, - {700, 25 }, - {620, 5 }, - {600, 0 }, - {0, 0 }, - }, + [BATTERY_TYPE_3500_MAH] = { + {837, 100}, + {826, 95 }, + {750, 50 }, + {700, 25 }, + {620, 5 }, + {600, 0 }, + {0, 0 }, + }, }; static_assert( - (ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_1600_MAH]) == - ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_2200_MAH])) && - (ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_2200_MAH]) == - ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_3500_MAH])) - ); + (ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_1600_MAH]) == + ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_2200_MAH])) && + (ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_2200_MAH]) == + ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_3500_MAH])) + ); unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV) { - const uint16_t (*crv)[3] = Voltage2PercentageTable[gEeprom.BATTERY_TYPE]; - const int mulipl = 1000; - for (unsigned int i = 1; i < ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_2200_MAH]); i++) { - if (voltage_10mV > crv[i][0]) { - const int a = (crv[i - 1][1] - crv[i][1]) * mulipl / (crv[i - 1][0] - crv[i][0]); - const int b = crv[i][1] - a * crv[i][0] / mulipl; - const int p = a * voltage_10mV / mulipl + b; - return MIN(p, 100); - } - } + const uint16_t (*crv)[3] = Voltage2PercentageTable[gEeprom.BATTERY_TYPE]; + const int mulipl = 1000; + for (unsigned int i = 1; i < ARRAY_SIZE(Voltage2PercentageTable[BATTERY_TYPE_2200_MAH]); i++) { + if (voltage_10mV > crv[i][0]) { + const int a = (crv[i - 1][1] - crv[i][1]) * mulipl / (crv[i - 1][0] - crv[i][0]); + const int b = crv[i][1] - a * crv[i][0] / mulipl; + const int p = a * voltage_10mV / mulipl + b; + return MIN(p, 100); + } + } - return 0; + return 0; } void BATTERY_GetReadings(const bool bDisplayBatteryLevel) { - const uint8_t PreviousBatteryLevel = gBatteryDisplayLevel; - const uint16_t Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] + gBatteryVoltages[3]) / 4; + const uint8_t PreviousBatteryLevel = gBatteryDisplayLevel; + const uint16_t Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] + gBatteryVoltages[3]) / 4; - gBatteryVoltageAverage = (Voltage * 760) / gBatteryCalibration[3]; + gBatteryVoltageAverage = (Voltage * 760) / gBatteryCalibration[3]; - if(gBatteryVoltageAverage > 890) - gBatteryDisplayLevel = 7; // battery overvoltage - else if(gBatteryVoltageAverage < 630 && (gEeprom.BATTERY_TYPE == BATTERY_TYPE_1600_MAH || gEeprom.BATTERY_TYPE == BATTERY_TYPE_2200_MAH)) - gBatteryDisplayLevel = 0; // battery critical - else if(gBatteryVoltageAverage < 600 && (gEeprom.BATTERY_TYPE == BATTERY_TYPE_3500_MAH)) - gBatteryDisplayLevel = 0; // battery critical - else { - gBatteryDisplayLevel = 1; - const uint8_t levels[] = {5,17,41,65,88}; - uint8_t perc = BATTERY_VoltsToPercent(gBatteryVoltageAverage); - //char str[64]; - //LogUart("----------\n"); - //sprintf(str, "%d %d %d %d %d %d %d\n", gBatteryVoltages[0], gBatteryVoltages[1], gBatteryVoltages[2], gBatteryVoltages[3], Voltage, gBatteryVoltageAverage, perc); - //LogUart(str); + if(gBatteryVoltageAverage > 890) + gBatteryDisplayLevel = 7; // battery overvoltage + else if(gBatteryVoltageAverage < 630 && (gEeprom.BATTERY_TYPE == BATTERY_TYPE_1600_MAH || gEeprom.BATTERY_TYPE == BATTERY_TYPE_2200_MAH)) + gBatteryDisplayLevel = 0; // battery critical + else if(gBatteryVoltageAverage < 600 && (gEeprom.BATTERY_TYPE == BATTERY_TYPE_3500_MAH)) + gBatteryDisplayLevel = 0; // battery critical + else { + gBatteryDisplayLevel = 1; + const uint8_t levels[] = {5,17,41,65,88}; + uint8_t perc = BATTERY_VoltsToPercent(gBatteryVoltageAverage); + //char str[64]; + //LogUart("----------\n"); + //sprintf(str, "%d %d %d %d %d %d %d\n", gBatteryVoltages[0], gBatteryVoltages[1], gBatteryVoltages[2], gBatteryVoltages[3], Voltage, gBatteryVoltageAverage, perc); + //LogUart(str); - for(uint8_t i = 6; i >= 2; i--){ - //sprintf(str, "%d %d %d\n", perc, levels[i-2], i); - //LogUart(str); - if (perc > levels[i-2]) { - gBatteryDisplayLevel = i; - break; - } - } - } + for(uint8_t i = 6; i >= 2; i--){ + //sprintf(str, "%d %d %d\n", perc, levels[i-2], i); + //LogUart(str); + if (perc > levels[i-2]) { + gBatteryDisplayLevel = i; + break; + } + } + } - if ((gScreenToDisplay == DISPLAY_MENU) && UI_MENU_GetCurrentMenuId() == MENU_VOL) - gUpdateDisplay = true; + if ((gScreenToDisplay == DISPLAY_MENU) && UI_MENU_GetCurrentMenuId() == MENU_VOL) + gUpdateDisplay = true; - if (gBatteryCurrent < 501) - { - if (gChargingWithTypeC) - { - gUpdateStatus = true; - gUpdateDisplay = true; - } + if (gBatteryCurrent < 501) + { + if (gChargingWithTypeC) + { + gUpdateStatus = true; + gUpdateDisplay = true; + } - gChargingWithTypeC = false; - } - else - { - if (!gChargingWithTypeC) - { - gUpdateStatus = true; - gUpdateDisplay = true; - BACKLIGHT_TurnOn(); - } + gChargingWithTypeC = false; + } + else + { + if (!gChargingWithTypeC) + { + gUpdateStatus = true; + gUpdateDisplay = true; + BACKLIGHT_TurnOn(); + } - gChargingWithTypeC = true; - } + gChargingWithTypeC = true; + } - if (PreviousBatteryLevel != gBatteryDisplayLevel) - { - if(gBatteryDisplayLevel > 2) - gLowBatteryConfirmed = false; - else if (gBatteryDisplayLevel < 2) - { - gLowBattery = true; - } - else - { - gLowBattery = false; + if (PreviousBatteryLevel != gBatteryDisplayLevel) + { + if(gBatteryDisplayLevel > 2) + gLowBatteryConfirmed = false; + else if (gBatteryDisplayLevel < 2) + { + gLowBattery = true; + } + else + { + gLowBattery = false; - if (bDisplayBatteryLevel) - UI_DisplayBattery(gBatteryDisplayLevel, gLowBatteryBlink); - } + if (bDisplayBatteryLevel) + UI_DisplayBattery(gBatteryDisplayLevel, gLowBatteryBlink); + } - if(!gLowBatteryConfirmed) - gUpdateDisplay = true; + if(!gLowBatteryConfirmed) + gUpdateDisplay = true; - lowBatteryCountdown = 0; - } + lowBatteryCountdown = 0; + } } void BATTERY_TimeSlice500ms(void) { - if (!gLowBattery) { - return; - } + if (!gLowBattery) { + return; + } - gLowBatteryBlink = ++lowBatteryCountdown & 1; + gLowBatteryBlink = ++lowBatteryCountdown & 1; - UI_DisplayBattery(0, gLowBatteryBlink); + UI_DisplayBattery(0, gLowBatteryBlink); - if (gCurrentFunction == FUNCTION_TRANSMIT) { - return; - } + if (gCurrentFunction == FUNCTION_TRANSMIT) { + return; + } - // not transmitting + // not transmitting - if (lowBatteryCountdown < lowBatteryPeriod) { - if (lowBatteryCountdown == lowBatteryPeriod-1 && !gChargingWithTypeC && !gLowBatteryConfirmed) { - AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP); - } - return; - } + if (lowBatteryCountdown < lowBatteryPeriod) { + if (lowBatteryCountdown == lowBatteryPeriod-1 && !gChargingWithTypeC && !gLowBatteryConfirmed) { + AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP); + } + return; + } - lowBatteryCountdown = 0; + lowBatteryCountdown = 0; - if (gChargingWithTypeC) { - return; - } + if (gChargingWithTypeC) { + return; + } - // not on charge - if (!gLowBatteryConfirmed) { - AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP); + // not on charge + if (!gLowBatteryConfirmed) { + AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP); #ifdef ENABLE_VOICE - AUDIO_SetVoiceID(0, VOICE_ID_LOW_VOLTAGE); + AUDIO_SetVoiceID(0, VOICE_ID_LOW_VOLTAGE); #endif - } + } - if (gBatteryDisplayLevel != 0) { + if (gBatteryDisplayLevel != 0) { #ifdef ENABLE_VOICE - AUDIO_PlaySingleVoice(false); + AUDIO_PlaySingleVoice(false); #endif - return; - } + return; + } #ifdef ENABLE_VOICE - AUDIO_PlaySingleVoice(true); + AUDIO_PlaySingleVoice(true); #endif - gReducedService = true; + gReducedService = true; - FUNCTION_Select(FUNCTION_POWER_SAVE); + FUNCTION_Select(FUNCTION_POWER_SAVE); - ST7565_HardwareReset(); + ST7565_HardwareReset(); - if (gEeprom.BACKLIGHT_TIME < 61) { - BACKLIGHT_TurnOff(); - } + if (gEeprom.BACKLIGHT_TIME < 61) { + BACKLIGHT_TurnOff(); + } } diff --git a/helper/boot.c b/helper/boot.c index 4ac9d5c..2739ce0 100644 --- a/helper/boot.c +++ b/helper/boot.c @@ -17,7 +17,7 @@ #include #ifdef ENABLE_AIRCOPY - #include "app/aircopy.h" + #include "app/aircopy.h" #endif #include "bsp/dp32g030/gpio.h" #include "driver/bk4819.h" @@ -33,81 +33,81 @@ BOOT_Mode_t BOOT_GetMode(void) { - unsigned int i; - KEY_Code_t Keys[2]; + unsigned int i; + KEY_Code_t Keys[2]; - for (i = 0; i < 2; i++) - { - if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT)) - return BOOT_MODE_NORMAL; // PTT not pressed - Keys[i] = KEYBOARD_Poll(); - SYSTEM_DelayMs(20); - } + for (i = 0; i < 2; i++) + { + if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT)) + return BOOT_MODE_NORMAL; // PTT not pressed + Keys[i] = KEYBOARD_Poll(); + SYSTEM_DelayMs(20); + } - if (Keys[0] == Keys[1]) - { - gKeyReading0 = Keys[0]; - gKeyReading1 = Keys[0]; + if (Keys[0] == Keys[1]) + { + gKeyReading0 = Keys[0]; + gKeyReading1 = Keys[0]; - gDebounceCounter = 2; + gDebounceCounter = 2; - if (Keys[0] == KEY_SIDE1) - return BOOT_MODE_F_LOCK; + if (Keys[0] == KEY_SIDE1) + return BOOT_MODE_F_LOCK; - #ifdef ENABLE_AIRCOPY - if (Keys[0] == KEY_SIDE2) - return BOOT_MODE_AIRCOPY; - #endif - } + #ifdef ENABLE_AIRCOPY + if (Keys[0] == KEY_SIDE2) + return BOOT_MODE_AIRCOPY; + #endif + } - return BOOT_MODE_NORMAL; + return BOOT_MODE_NORMAL; } void BOOT_ProcessMode(BOOT_Mode_t Mode) { - if (Mode == BOOT_MODE_F_LOCK) - { - GUI_SelectNextDisplay(DISPLAY_MENU); - } - #ifdef ENABLE_AIRCOPY - else - if (Mode == BOOT_MODE_AIRCOPY) - { - gEeprom.DUAL_WATCH = DUAL_WATCH_OFF; - gEeprom.BATTERY_SAVE = 0; - #ifdef ENABLE_VOX - gEeprom.VOX_SWITCH = false; - #endif - gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF; - gEeprom.AUTO_KEYPAD_LOCK = false; - gEeprom.KEY_1_SHORT_PRESS_ACTION = ACTION_OPT_NONE; - gEeprom.KEY_1_LONG_PRESS_ACTION = ACTION_OPT_NONE; - gEeprom.KEY_2_SHORT_PRESS_ACTION = ACTION_OPT_NONE; - gEeprom.KEY_2_LONG_PRESS_ACTION = ACTION_OPT_NONE; - gEeprom.KEY_M_LONG_PRESS_ACTION = ACTION_OPT_NONE; + if (Mode == BOOT_MODE_F_LOCK) + { + GUI_SelectNextDisplay(DISPLAY_MENU); + } + #ifdef ENABLE_AIRCOPY + else + if (Mode == BOOT_MODE_AIRCOPY) + { + gEeprom.DUAL_WATCH = DUAL_WATCH_OFF; + gEeprom.BATTERY_SAVE = 0; + #ifdef ENABLE_VOX + gEeprom.VOX_SWITCH = false; + #endif + gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF; + gEeprom.AUTO_KEYPAD_LOCK = false; + gEeprom.KEY_1_SHORT_PRESS_ACTION = ACTION_OPT_NONE; + gEeprom.KEY_1_LONG_PRESS_ACTION = ACTION_OPT_NONE; + gEeprom.KEY_2_SHORT_PRESS_ACTION = ACTION_OPT_NONE; + gEeprom.KEY_2_LONG_PRESS_ACTION = ACTION_OPT_NONE; + gEeprom.KEY_M_LONG_PRESS_ACTION = ACTION_OPT_NONE; - RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_LAST - 1, 43400000); // LPD + RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_LAST - 1, 43400000); // LPD - gRxVfo->CHANNEL_BANDWIDTH = BANDWIDTH_NARROW; - gRxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW1; + gRxVfo->CHANNEL_BANDWIDTH = BANDWIDTH_NARROW; + gRxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW1; - RADIO_ConfigureSquelchAndOutputPower(gRxVfo); + RADIO_ConfigureSquelchAndOutputPower(gRxVfo); - gCurrentVfo = gRxVfo; + gCurrentVfo = gRxVfo; - RADIO_SetupRegisters(true); - BK4819_SetupAircopy(); - BK4819_ResetFSK(); + RADIO_SetupRegisters(true); + BK4819_SetupAircopy(); + BK4819_ResetFSK(); - gAircopyState = AIRCOPY_READY; + gAircopyState = AIRCOPY_READY; - gEeprom.BACKLIGHT_TIME = 61; + gEeprom.BACKLIGHT_TIME = 61; - GUI_SelectNextDisplay(DISPLAY_AIRCOPY); - } - #endif - else - { - GUI_SelectNextDisplay(DISPLAY_MAIN); - } + GUI_SelectNextDisplay(DISPLAY_AIRCOPY); + } + #endif + else + { + GUI_SelectNextDisplay(DISPLAY_MAIN); + } } diff --git a/helper/boot.h b/helper/boot.h index fd6c96e..e04c462 100644 --- a/helper/boot.h +++ b/helper/boot.h @@ -22,11 +22,11 @@ enum BOOT_Mode_t { - BOOT_MODE_NORMAL = 0, - BOOT_MODE_F_LOCK, - #ifdef ENABLE_AIRCOPY - BOOT_MODE_AIRCOPY - #endif + BOOT_MODE_NORMAL = 0, + BOOT_MODE_F_LOCK, + #ifdef ENABLE_AIRCOPY + BOOT_MODE_AIRCOPY + #endif }; typedef enum BOOT_Mode_t BOOT_Mode_t; diff --git a/init.c b/init.c index 3e9266a..2cda663 100644 --- a/init.c +++ b/init.c @@ -30,18 +30,18 @@ void DATA_Init(void); void BSS_Init(void) { - for (uint32_t *pBss = __bss_start__; pBss < __bss_end__; pBss++) { - *pBss = 0; - } + for (uint32_t *pBss = __bss_start__; pBss < __bss_end__; pBss++) { + *pBss = 0; + } } void DATA_Init(void) { - volatile uint32_t *pDataRam = (volatile uint32_t *)sram_data_start; - volatile uint32_t *pDataFlash = (volatile uint32_t *)flash_data_start; - uint32_t Size = (uint32_t)sram_data_end - (uint32_t)sram_data_start; + volatile uint32_t *pDataRam = (volatile uint32_t *)sram_data_start; + volatile uint32_t *pDataFlash = (volatile uint32_t *)flash_data_start; + uint32_t Size = (uint32_t)sram_data_end - (uint32_t)sram_data_start; - for (unsigned int i = 0; i < (Size / 4); i++) { - *pDataRam++ = *pDataFlash++; - } + for (unsigned int i = 0; i < (Size / 4); i++) { + *pDataRam++ = *pDataFlash++; + } } diff --git a/main.c b/main.c index 7359658..ec83117 100644 --- a/main.c +++ b/main.c @@ -19,7 +19,7 @@ #include // NULL #ifdef ENABLE_AM_FIX - #include "am_fix.h" + #include "am_fix.h" #endif #include "audio.h" @@ -41,7 +41,7 @@ #include "driver/systick.h" #include "driver/eeprom.h" #ifdef ENABLE_UART - #include "driver/uart.h" + #include "driver/uart.h" #endif #include "helper/battery.h" @@ -54,200 +54,200 @@ void _putchar(__attribute__((unused)) char c) { #ifdef ENABLE_UART - UART_Send((uint8_t *)&c, 1); + UART_Send((uint8_t *)&c, 1); #endif } void Main(void) { - // Enable clock gating of blocks we need - SYSCON_DEV_CLK_GATE = 0 - | SYSCON_DEV_CLK_GATE_GPIOA_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_GPIOB_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_GPIOC_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_UART1_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_CRC_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_AES_BITS_ENABLE - | SYSCON_DEV_CLK_GATE_PWM_PLUS0_BITS_ENABLE; + // Enable clock gating of blocks we need + SYSCON_DEV_CLK_GATE = 0 + | SYSCON_DEV_CLK_GATE_GPIOA_BITS_ENABLE + | SYSCON_DEV_CLK_GATE_GPIOB_BITS_ENABLE + | SYSCON_DEV_CLK_GATE_GPIOC_BITS_ENABLE + | SYSCON_DEV_CLK_GATE_UART1_BITS_ENABLE + | SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE + | SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE + | SYSCON_DEV_CLK_GATE_CRC_BITS_ENABLE + | SYSCON_DEV_CLK_GATE_AES_BITS_ENABLE + | SYSCON_DEV_CLK_GATE_PWM_PLUS0_BITS_ENABLE; - SYSTICK_Init(); - BOARD_Init(); + SYSTICK_Init(); + BOARD_Init(); - boot_counter_10ms = 250; // 2.5 sec + boot_counter_10ms = 250; // 2.5 sec #ifdef ENABLE_UART - UART_Init(); - UART_Send(UART_Version, strlen(UART_Version)); + UART_Init(); + UART_Send(UART_Version, strlen(UART_Version)); #endif - // Not implementing authentic device checks + // Not implementing authentic device checks - memset(gDTMF_String, '-', sizeof(gDTMF_String)); - gDTMF_String[sizeof(gDTMF_String) - 1] = 0; + memset(gDTMF_String, '-', sizeof(gDTMF_String)); + gDTMF_String[sizeof(gDTMF_String) - 1] = 0; - BK4819_Init(); + BK4819_Init(); - BOARD_ADC_GetBatteryInfo(&gBatteryCurrentVoltage, &gBatteryCurrent); + BOARD_ADC_GetBatteryInfo(&gBatteryCurrentVoltage, &gBatteryCurrent); - SETTINGS_InitEEPROM(); + SETTINGS_InitEEPROM(); - #ifdef ENABLE_FEAT_F4HWN - gDW = gEeprom.DUAL_WATCH; - gCB = gEeprom.CROSS_BAND_RX_TX; - #endif + #ifdef ENABLE_FEAT_F4HWN + gDW = gEeprom.DUAL_WATCH; + gCB = gEeprom.CROSS_BAND_RX_TX; + #endif - SETTINGS_WriteBuildOptions(); - SETTINGS_LoadCalibration(); + SETTINGS_WriteBuildOptions(); + SETTINGS_LoadCalibration(); - RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD); - RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD); + RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD); + RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD); - RADIO_SelectVfos(); + RADIO_SelectVfos(); - RADIO_SetupRegisters(true); + RADIO_SetupRegisters(true); - for (unsigned int i = 0; i < ARRAY_SIZE(gBatteryVoltages); i++) - BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[i], &gBatteryCurrent); + for (unsigned int i = 0; i < ARRAY_SIZE(gBatteryVoltages); i++) + BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[i], &gBatteryCurrent); - BATTERY_GetReadings(false); + BATTERY_GetReadings(false); #ifdef ENABLE_AM_FIX - AM_fix_init(); + AM_fix_init(); #endif - const BOOT_Mode_t BootMode = BOOT_GetMode(); + const BOOT_Mode_t BootMode = BOOT_GetMode(); - if (BootMode == BOOT_MODE_F_LOCK) - { + if (BootMode == BOOT_MODE_F_LOCK) + { - gF_LOCK = true; // flag to say include the hidden menu items - #ifdef ENABLE_FEAT_F4HWN - gEeprom.KEY_LOCK = 0; - SETTINGS_SaveSettings(); - #ifndef ENABLE_VOX - gMenuCursor = 64; // move to hidden section, fix me if change... !!! Remove VOX and Mic Bar - #else - gMenuCursor = 66; // move to hidden section, fix me if change... !!! - #endif - gSubMenuSelection = gSetting_F_LOCK; - #endif - } + gF_LOCK = true; // flag to say include the hidden menu items + #ifdef ENABLE_FEAT_F4HWN + gEeprom.KEY_LOCK = 0; + SETTINGS_SaveSettings(); + #ifndef ENABLE_VOX + gMenuCursor = 64; // move to hidden section, fix me if change... !!! Remove VOX and Mic Bar + #else + gMenuCursor = 66; // move to hidden section, fix me if change... !!! + #endif + gSubMenuSelection = gSetting_F_LOCK; + #endif + } - // count the number of menu items - gMenuListCount = 0; - while (MenuList[gMenuListCount].name[0] != '\0') { - if(!gF_LOCK && MenuList[gMenuListCount].menu_id == FIRST_HIDDEN_MENU_ITEM) - break; + // count the number of menu items + gMenuListCount = 0; + while (MenuList[gMenuListCount].name[0] != '\0') { + if(!gF_LOCK && MenuList[gMenuListCount].menu_id == FIRST_HIDDEN_MENU_ITEM) + break; - gMenuListCount++; - } + gMenuListCount++; + } - // wait for user to release all butts before moving on - if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || - KEYBOARD_Poll() != KEY_INVALID || - BootMode != BOOT_MODE_NORMAL) - { // keys are pressed - UI_DisplayReleaseKeys(); - BACKLIGHT_TurnOn(); + // wait for user to release all butts before moving on + if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || + KEYBOARD_Poll() != KEY_INVALID || + BootMode != BOOT_MODE_NORMAL) + { // keys are pressed + UI_DisplayReleaseKeys(); + BACKLIGHT_TurnOn(); - // 500ms - for (int i = 0; i < 50;) - { - i = (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && KEYBOARD_Poll() == KEY_INVALID) ? i + 1 : 0; - SYSTEM_DelayMs(10); - } - gKeyReading0 = KEY_INVALID; - gKeyReading1 = KEY_INVALID; - gDebounceCounter = 0; - } + // 500ms + for (int i = 0; i < 50;) + { + i = (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && KEYBOARD_Poll() == KEY_INVALID) ? i + 1 : 0; + SYSTEM_DelayMs(10); + } + gKeyReading0 = KEY_INVALID; + gKeyReading1 = KEY_INVALID; + gDebounceCounter = 0; + } - if (!gChargingWithTypeC && gBatteryDisplayLevel == 0) - { - FUNCTION_Select(FUNCTION_POWER_SAVE); + if (!gChargingWithTypeC && gBatteryDisplayLevel == 0) + { + FUNCTION_Select(FUNCTION_POWER_SAVE); - if (gEeprom.BACKLIGHT_TIME < 61) // backlight is not set to be always on - BACKLIGHT_TurnOff(); // turn the backlight OFF - else - BACKLIGHT_TurnOn(); // turn the backlight ON + if (gEeprom.BACKLIGHT_TIME < 61) // backlight is not set to be always on + BACKLIGHT_TurnOff(); // turn the backlight OFF + else + BACKLIGHT_TurnOn(); // turn the backlight ON - gReducedService = true; - } - else - { - UI_DisplayWelcome(); + gReducedService = true; + } + else + { + UI_DisplayWelcome(); - BACKLIGHT_TurnOn(); + BACKLIGHT_TurnOn(); #ifdef ENABLE_FEAT_F4HWN - if (gEeprom.POWER_ON_DISPLAY_MODE != POWER_ON_DISPLAY_MODE_NONE && gEeprom.POWER_ON_DISPLAY_MODE != POWER_ON_DISPLAY_MODE_SOUND) + if (gEeprom.POWER_ON_DISPLAY_MODE != POWER_ON_DISPLAY_MODE_NONE && gEeprom.POWER_ON_DISPLAY_MODE != POWER_ON_DISPLAY_MODE_SOUND) #else - if (gEeprom.POWER_ON_DISPLAY_MODE != POWER_ON_DISPLAY_MODE_NONE) + if (gEeprom.POWER_ON_DISPLAY_MODE != POWER_ON_DISPLAY_MODE_NONE) #endif - { // 2.55 second boot-up screen - while (boot_counter_10ms > 0) - { - if (KEYBOARD_Poll() != KEY_INVALID) - { // halt boot beeps - boot_counter_10ms = 0; - break; - } - } - RADIO_SetupRegisters(true); - } + { // 2.55 second boot-up screen + while (boot_counter_10ms > 0) + { + if (KEYBOARD_Poll() != KEY_INVALID) + { // halt boot beeps + boot_counter_10ms = 0; + break; + } + } + RADIO_SetupRegisters(true); + } #ifdef ENABLE_PWRON_PASSWORD - if (gEeprom.POWER_ON_PASSWORD < 1000000) - { - bIsInLockScreen = true; - UI_DisplayLock(); - bIsInLockScreen = false; - } + if (gEeprom.POWER_ON_PASSWORD < 1000000) + { + bIsInLockScreen = true; + UI_DisplayLock(); + bIsInLockScreen = false; + } #endif - BOOT_ProcessMode(BootMode); + BOOT_ProcessMode(BootMode); - GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); + GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); - gUpdateStatus = true; + gUpdateStatus = true; #ifdef ENABLE_VOICE - { - uint8_t Channel; + { + uint8_t Channel; - AUDIO_SetVoiceID(0, VOICE_ID_WELCOME); + AUDIO_SetVoiceID(0, VOICE_ID_WELCOME); - Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO]; - if (IS_MR_CHANNEL(Channel)) - { - AUDIO_SetVoiceID(1, VOICE_ID_CHANNEL_MODE); - AUDIO_SetDigitVoice(2, Channel + 1); - } - else if (IS_FREQ_CHANNEL(Channel)) - AUDIO_SetVoiceID(1, VOICE_ID_FREQUENCY_MODE); + Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO]; + if (IS_MR_CHANNEL(Channel)) + { + AUDIO_SetVoiceID(1, VOICE_ID_CHANNEL_MODE); + AUDIO_SetDigitVoice(2, Channel + 1); + } + else if (IS_FREQ_CHANNEL(Channel)) + AUDIO_SetVoiceID(1, VOICE_ID_FREQUENCY_MODE); - AUDIO_PlaySingleVoice(0); - } + AUDIO_PlaySingleVoice(0); + } #endif #ifdef ENABLE_NOAA - RADIO_ConfigureNOAA(); + RADIO_ConfigureNOAA(); #endif - } + } - while (true) { - APP_Update(); + while (true) { + APP_Update(); - if (gNextTimeslice) { + if (gNextTimeslice) { - APP_TimeSlice10ms(); + APP_TimeSlice10ms(); - if (gNextTimeslice_500ms) { - APP_TimeSlice500ms(); - } - } - } + if (gNextTimeslice_500ms) { + APP_TimeSlice500ms(); + } + } + } } diff --git a/misc.c b/misc.c index 811d1eb..6abf843 100644 --- a/misc.c +++ b/misc.c @@ -45,21 +45,21 @@ const uint16_t key_debounce_10ms = 20 / 10; // 20ms const uint8_t scan_delay_10ms = 210 / 10; // 210ms #ifdef ENABLE_FEAT_F4HWN - const uint16_t dual_watch_count_after_tx_10ms = 420; // 4.2 sec after TX ends - const uint16_t dual_watch_count_after_rx_10ms = 1000 / 10; // 1 sec after RX ends ? - const uint16_t dual_watch_count_after_1_10ms = 5000 / 10; // 5 sec - const uint16_t dual_watch_count_after_2_10ms = 420; // 4.2 sec - const uint16_t dual_watch_count_noaa_10ms = 70 / 10; // 70ms + const uint16_t dual_watch_count_after_tx_10ms = 420; // 4.2 sec after TX ends + const uint16_t dual_watch_count_after_rx_10ms = 1000 / 10; // 1 sec after RX ends ? + const uint16_t dual_watch_count_after_1_10ms = 5000 / 10; // 5 sec + const uint16_t dual_watch_count_after_2_10ms = 420; // 4.2 sec + const uint16_t dual_watch_count_noaa_10ms = 70 / 10; // 70ms #else - const uint16_t dual_watch_count_after_tx_10ms = 3600 / 10; // 3.6 sec after TX ends - const uint16_t dual_watch_count_after_rx_10ms = 1000 / 10; // 1 sec after RX ends ? - const uint16_t dual_watch_count_after_1_10ms = 5000 / 10; // 5 sec - const uint16_t dual_watch_count_after_2_10ms = 3600 / 10; // 3.6 sec - const uint16_t dual_watch_count_noaa_10ms = 70 / 10; // 70ms + const uint16_t dual_watch_count_after_tx_10ms = 3600 / 10; // 3.6 sec after TX ends + const uint16_t dual_watch_count_after_rx_10ms = 1000 / 10; // 1 sec after RX ends ? + const uint16_t dual_watch_count_after_1_10ms = 5000 / 10; // 5 sec + const uint16_t dual_watch_count_after_2_10ms = 3600 / 10; // 3.6 sec + const uint16_t dual_watch_count_noaa_10ms = 70 / 10; // 70ms #endif #ifdef ENABLE_VOX - const uint16_t dual_watch_count_after_vox_10ms = 200 / 10; // 200ms + const uint16_t dual_watch_count_after_vox_10ms = 200 / 10; // 200ms #endif const uint16_t dual_watch_count_toggle_10ms = 100 / 10; // 100ms between VFO toggles @@ -77,7 +77,7 @@ const uint16_t power_save1_10ms = 100 / 10; // 100ms const uint16_t power_save2_10ms = 200 / 10; // 200ms #ifdef ENABLE_VOX - const uint16_t vox_stop_count_down_10ms = 1000 / 10; // 1 second + const uint16_t vox_stop_count_down_10ms = 1000 / 10; // 1 second #endif const uint16_t NOAA_countdown_10ms = 5000 / 10; // 5 seconds @@ -101,32 +101,32 @@ bool gSetting_ScrambleEnable; enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx; #ifdef ENABLE_AM_FIX - bool gSetting_AM_fix = true; + bool gSetting_AM_fix = true; #endif #ifdef ENABLE_FEAT_F4HWN - uint8_t gSetting_set_pwr = 1; - bool gSetting_set_ptt = 0; - uint8_t gSetting_set_tot = 0; - uint8_t gSetting_set_ctr = 11; - bool gSetting_set_inv = false; - uint8_t gSetting_set_eot = 0; - bool gSetting_set_lck = false; - bool gSetting_set_met = 0; - bool gSetting_set_gui = 0; - bool gSetting_set_tmr = 0; - bool gSetting_set_ptt_session; - uint8_t gDebug; - uint8_t gDW = 0; - uint8_t gCB = 0; - bool gSaveRxMode = false; - uint8_t crc[15] = { 0 }; - uint8_t lErrorsDuringAirCopy = 0; - uint8_t gAircopyStep = 0; + uint8_t gSetting_set_pwr = 1; + bool gSetting_set_ptt = 0; + uint8_t gSetting_set_tot = 0; + uint8_t gSetting_set_ctr = 11; + bool gSetting_set_inv = false; + uint8_t gSetting_set_eot = 0; + bool gSetting_set_lck = false; + bool gSetting_set_met = 0; + bool gSetting_set_gui = 0; + bool gSetting_set_tmr = 0; + bool gSetting_set_ptt_session; + uint8_t gDebug; + uint8_t gDW = 0; + uint8_t gCB = 0; + bool gSaveRxMode = false; + uint8_t crc[15] = { 0 }; + uint8_t lErrorsDuringAirCopy = 0; + uint8_t gAircopyStep = 0; #endif #ifdef ENABLE_AUDIO_BAR - bool gSetting_mic_bar; + bool gSetting_mic_bar; #endif bool gSetting_live_DTMF_decoder; uint8_t gSetting_battery_text; @@ -164,12 +164,12 @@ volatile uint16_t gTxTimerCountdown_500ms; volatile bool gTxTimeoutReached; #ifdef ENABLE_FEAT_F4HWN - volatile uint16_t gTxTimerCountdownAlert_500ms; - volatile bool gTxTimeoutReachedAlert; - volatile uint16_t gTxTimeoutToneAlert = 800; - #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER - volatile uint16_t gRxTimerCountdown_500ms; - #endif + volatile uint16_t gTxTimerCountdownAlert_500ms; + volatile bool gTxTimeoutReachedAlert; + volatile uint16_t gTxTimeoutToneAlert = 800; + #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER + volatile uint16_t gRxTimerCountdown_500ms; + #endif #endif volatile uint16_t gTailNoteEliminationCountdown_10ms; @@ -177,7 +177,7 @@ volatile uint16_t gTailNoteEliminationCountdown_10ms; volatile uint8_t gVFOStateResumeCountdown_500ms; #ifdef ENABLE_NOAA - volatile uint16_t gNOAA_Countdown_10ms; + volatile uint16_t gNOAA_Countdown_10ms; #endif bool gEnableSpeaker; @@ -195,13 +195,13 @@ uint8_t gVFO_RSSI_bar_level[2]; uint8_t gReducedService; uint8_t gBatteryVoltageIndex; -bool gCssBackgroundScan; +bool gCssBackgroundScan; volatile bool gScheduleScanListen = true; volatile uint16_t gScanPauseDelayIn_10ms; #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) - AlarmState_t gAlarmState; + AlarmState_t gAlarmState; #endif uint16_t gMenuCountdown; bool gPttWasReleased; @@ -214,7 +214,7 @@ bool gRequestSaveVFO; uint8_t gRequestSaveChannel; bool gRequestSaveSettings; #ifdef ENABLE_FMRADIO - bool gRequestSaveFM; + bool gRequestSaveFM; #endif bool gFlagPrepareTX; @@ -222,17 +222,17 @@ bool gFlagAcceptSetting; bool gFlagRefreshSetting; #ifdef ENABLE_FMRADIO - bool gFlagSaveFM; + bool gFlagSaveFM; #endif bool g_CDCSS_Lost; uint8_t gCDCSSCodeType; bool g_CTCSS_Lost; bool g_CxCSS_TAIL_Found; #ifdef ENABLE_VOX - bool g_VOX_Lost; - bool gVOX_NoiseDetected; - uint16_t gVoxResumeCountdown; - uint16_t gVoxPauseCountdown; + bool g_VOX_Lost; + bool gVOX_NoiseDetected; + uint16_t gVoxResumeCountdown; + uint16_t gVoxPauseCountdown; #endif bool g_SquelchLost; @@ -244,8 +244,8 @@ ReceptionMode_t gRxReceptionMode; bool gRxVfoIsActive; #ifdef ENABLE_ALARM - uint8_t gAlarmToneCounter; - uint16_t gAlarmRunningCounter; + uint8_t gAlarmToneCounter; + uint16_t gAlarmRunningCounter; #endif bool gKeyBeingHeld; bool gPttIsPressed; @@ -256,8 +256,8 @@ uint8_t gScanDelay_10ms; uint8_t gFSKWriteIndex; #ifdef ENABLE_NOAA - bool gIsNoaaMode; - uint8_t gNoaaChannel; + bool gIsNoaaMode; + uint8_t gNoaaChannel; #endif bool gUpdateDisplay; @@ -270,16 +270,16 @@ volatile bool gNextTimeslice; volatile uint8_t gFoundCDCSSCountdown_10ms; volatile uint8_t gFoundCTCSSCountdown_10ms; #ifdef ENABLE_VOX - volatile uint16_t gVoxStopCountdown_10ms; + volatile uint16_t gVoxStopCountdown_10ms; #endif volatile bool gNextTimeslice40ms; #ifdef ENABLE_NOAA - volatile uint16_t gNOAACountdown_10ms = 0; - volatile bool gScheduleNOAA = true; + volatile uint16_t gNOAACountdown_10ms = 0; + volatile bool gScheduleNOAA = true; #endif volatile bool gFlagTailNoteEliminationComplete; #ifdef ENABLE_FMRADIO - volatile bool gScheduleFM; + volatile bool gScheduleFM; #endif volatile uint8_t boot_counter_10ms; @@ -288,12 +288,12 @@ uint8_t gIsLocked = 0xFF; #ifdef ENABLE_FEAT_F4HWN - bool gK5startup = true; - bool gBackLight = false; - uint8_t gBacklightTimeOriginal; - uint8_t gBacklightBrightnessOld; - uint8_t gPttOnePushCounter = 0; - uint32_t gBlinkCounter = 0; + bool gK5startup = true; + bool gBackLight = false; + uint8_t gBacklightTimeOriginal; + uint8_t gBacklightBrightnessOld; + uint8_t gPttOnePushCounter = 0; + uint32_t gBlinkCounter = 0; #endif inline void FUNCTION_NOP() { ; } @@ -301,25 +301,25 @@ inline void FUNCTION_NOP() { ; } int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit) { - Base += Add; + Base += Add; - if (Base == 0x7fffffff || Base < LowerLimit) - return UpperLimit; + if (Base == 0x7fffffff || Base < LowerLimit) + return UpperLimit; - if (Base > UpperLimit) - return LowerLimit; + if (Base > UpperLimit) + return LowerLimit; - return Base; + return Base; } unsigned long StrToUL(const char * str) { - unsigned long ul = 0; - for(uint8_t i = 0; i < strlen(str); i++){ - char c = str[i]; - if(c < '0' || c > '9') - break; - ul = ul * 10 + (uint8_t)(c-'0'); - } - return ul; + unsigned long ul = 0; + for(uint8_t i = 0; i < strlen(str); i++){ + char c = str[i]; + if(c < '0' || c > '9') + break; + ul = ul * 10 + (uint8_t)(c-'0'); + } + return ul; } diff --git a/misc.h b/misc.h index 4fb8cb0..854e6e4 100644 --- a/misc.h +++ b/misc.h @@ -21,19 +21,19 @@ #include #ifndef ARRAY_SIZE - #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif #ifndef MAX - #define MAX(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; }) + #define MAX(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; }) #endif #ifndef MIN - #define MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; }) + #define MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; }) #endif #ifndef SWAP - #define SWAP(a, b) ({ __typeof__ (a) _c = (a); a = b; b = _c; }) + #define SWAP(a, b) ({ __typeof__ (a) _c = (a); a = b; b = _c; }) #endif #define IS_MR_CHANNEL(x) ((x) <= MR_CHANNEL_LAST) @@ -42,41 +42,41 @@ #define IS_NOAA_CHANNEL(x) ((x) >= NOAA_CHANNEL_FIRST && (x) <= NOAA_CHANNEL_LAST) enum { - MR_CHANNEL_FIRST = 0, - MR_CHANNEL_LAST = 199u, - FREQ_CHANNEL_FIRST = 200u, - FREQ_CHANNEL_LAST = 206u, - NOAA_CHANNEL_FIRST = 207u, - NOAA_CHANNEL_LAST = 216u, - LAST_CHANNEL + MR_CHANNEL_FIRST = 0, + MR_CHANNEL_LAST = 199u, + FREQ_CHANNEL_FIRST = 200u, + FREQ_CHANNEL_LAST = 206u, + NOAA_CHANNEL_FIRST = 207u, + NOAA_CHANNEL_LAST = 216u, + LAST_CHANNEL }; enum { - VFO_CONFIGURE_NONE = 0, - VFO_CONFIGURE, - VFO_CONFIGURE_RELOAD + VFO_CONFIGURE_NONE = 0, + VFO_CONFIGURE, + VFO_CONFIGURE_RELOAD }; enum AlarmState_t { - ALARM_STATE_OFF = 0, - ALARM_STATE_TXALARM, - ALARM_STATE_SITE_ALARM, - ALARM_STATE_TX1750 + ALARM_STATE_OFF = 0, + ALARM_STATE_TXALARM, + ALARM_STATE_SITE_ALARM, + ALARM_STATE_TX1750 }; typedef enum AlarmState_t AlarmState_t; enum ReceptionMode_t { - RX_MODE_NONE = 0, // squelch close ? - RX_MODE_DETECTED, // signal detected - RX_MODE_LISTENING // + RX_MODE_NONE = 0, // squelch close ? + RX_MODE_DETECTED, // signal detected + RX_MODE_LISTENING // }; typedef enum ReceptionMode_t ReceptionMode_t; enum BacklightOnRxTx_t { - BACKLIGHT_ON_TR_OFF, - BACKLIGHT_ON_TR_TX, - BACKLIGHT_ON_TR_RX, - BACKLIGHT_ON_TR_TXRX + BACKLIGHT_ON_TR_OFF, + BACKLIGHT_ON_TR_TX, + BACKLIGHT_ON_TR_RX, + BACKLIGHT_ON_TR_TXRX }; extern const uint8_t fm_radio_countdown_500ms; @@ -110,7 +110,7 @@ extern const uint16_t power_save1_10ms; extern const uint16_t power_save2_10ms; #ifdef ENABLE_VOX - extern const uint16_t vox_stop_count_down_10ms; + extern const uint16_t vox_stop_count_down_10ms; #endif extern const uint16_t NOAA_countdown_10ms; @@ -124,7 +124,7 @@ extern const uint16_t dual_watch_count_after_2_10ms; extern const uint16_t dual_watch_count_toggle_10ms; extern const uint16_t dual_watch_count_noaa_10ms; #ifdef ENABLE_VOX - extern const uint16_t dual_watch_count_after_vox_10ms; + extern const uint16_t dual_watch_count_after_vox_10ms; #endif extern const uint16_t scan_pause_delay_in_1_10ms; @@ -153,32 +153,32 @@ extern bool gSetting_ScrambleEnable; extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx; #ifdef ENABLE_AM_FIX - extern bool gSetting_AM_fix; + extern bool gSetting_AM_fix; #endif #ifdef ENABLE_FEAT_F4HWN - extern uint8_t gSetting_set_pwr; - extern bool gSetting_set_ptt; - extern uint8_t gSetting_set_tot; - extern uint8_t gSetting_set_ctr; - extern bool gSetting_set_inv; - extern uint8_t gSetting_set_eot; - extern bool gSetting_set_lck; - extern bool gSetting_set_met; - extern bool gSetting_set_gui; - extern bool gSetting_set_tmr; - extern bool gSetting_set_ptt_session; - extern uint8_t gDebug; - extern uint8_t gDW; - extern uint8_t gCB; - extern bool gSaveRxMode; - extern uint8_t crc[15]; - extern uint8_t lErrorsDuringAirCopy; - extern uint8_t gAircopyStep; + extern uint8_t gSetting_set_pwr; + extern bool gSetting_set_ptt; + extern uint8_t gSetting_set_tot; + extern uint8_t gSetting_set_ctr; + extern bool gSetting_set_inv; + extern uint8_t gSetting_set_eot; + extern bool gSetting_set_lck; + extern bool gSetting_set_met; + extern bool gSetting_set_gui; + extern bool gSetting_set_tmr; + extern bool gSetting_set_ptt_session; + extern uint8_t gDebug; + extern uint8_t gDW; + extern uint8_t gCB; + extern bool gSaveRxMode; + extern uint8_t crc[15]; + extern uint8_t lErrorsDuringAirCopy; + extern uint8_t gAircopyStep; #endif #ifdef ENABLE_AUDIO_BAR - extern bool gSetting_mic_bar; + extern bool gSetting_mic_bar; #endif extern bool gSetting_live_DTMF_decoder; extern uint8_t gSetting_battery_text; @@ -229,18 +229,18 @@ extern volatile uint16_t gTxTimerCountdown_500ms; extern volatile bool gTxTimeoutReached; #ifdef ENABLE_FEAT_F4HWN - extern volatile uint16_t gTxTimerCountdownAlert_500ms; - extern volatile bool gTxTimeoutReachedAlert; - extern volatile uint16_t gTxTimeoutToneAlert; - #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER - extern volatile uint16_t gRxTimerCountdown_500ms; - #endif + extern volatile uint16_t gTxTimerCountdownAlert_500ms; + extern volatile bool gTxTimeoutReachedAlert; + extern volatile uint16_t gTxTimeoutToneAlert; + #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER + extern volatile uint16_t gRxTimerCountdown_500ms; + #endif #endif extern volatile uint16_t gTailNoteEliminationCountdown_10ms; #ifdef ENABLE_NOAA - extern volatile uint16_t gNOAA_Countdown_10ms; + extern volatile uint16_t gNOAA_Countdown_10ms; #endif extern bool gEnableSpeaker; extern uint8_t gKeyInputCountdown; @@ -265,9 +265,9 @@ extern bool gCssBackgroundScan; enum { - SCAN_REV = -1, - SCAN_OFF = 0, - SCAN_FWD = +1 + SCAN_REV = -1, + SCAN_OFF = 0, + SCAN_FWD = +1 }; extern volatile bool gScheduleScanListen; @@ -284,7 +284,7 @@ extern bool gRequestSaveVFO; extern uint8_t gRequestSaveChannel; extern bool gRequestSaveSettings; #ifdef ENABLE_FMRADIO - extern bool gRequestSaveFM; + extern bool gRequestSaveFM; #endif extern uint8_t gKeypadLocked; extern bool gFlagPrepareTX; @@ -293,17 +293,17 @@ extern bool gFlagAcceptSetting; // accept menu setting extern bool gFlagRefreshSetting; // refresh menu display #ifdef ENABLE_FMRADIO - extern bool gFlagSaveFM; + extern bool gFlagSaveFM; #endif extern bool g_CDCSS_Lost; extern uint8_t gCDCSSCodeType; extern bool g_CTCSS_Lost; extern bool g_CxCSS_TAIL_Found; #ifdef ENABLE_VOX - extern bool g_VOX_Lost; - extern bool gVOX_NoiseDetected; - extern uint16_t gVoxResumeCountdown; - extern uint16_t gVoxPauseCountdown; + extern bool g_VOX_Lost; + extern bool gVOX_NoiseDetected; + extern uint16_t gVoxResumeCountdown; + extern uint16_t gVoxPauseCountdown; #endif // true means we are receiving signal @@ -327,41 +327,41 @@ extern uint8_t gBackup_CROSS_BAND_RX_TX; extern uint8_t gScanDelay_10ms; extern uint8_t gFSKWriteIndex; #ifdef ENABLE_NOAA - extern bool gIsNoaaMode; - extern uint8_t gNoaaChannel; + extern bool gIsNoaaMode; + extern uint8_t gNoaaChannel; #endif extern volatile bool gNextTimeslice; extern bool gUpdateDisplay; extern bool gF_LOCK; #ifdef ENABLE_FMRADIO - extern uint8_t gFM_ChannelPosition; + extern uint8_t gFM_ChannelPosition; #endif extern uint8_t gShowChPrefix; extern volatile uint8_t gFoundCDCSSCountdown_10ms; extern volatile uint8_t gFoundCTCSSCountdown_10ms; #ifdef ENABLE_VOX - extern volatile uint16_t gVoxStopCountdown_10ms; + extern volatile uint16_t gVoxStopCountdown_10ms; #endif extern volatile bool gNextTimeslice40ms; #ifdef ENABLE_NOAA - extern volatile uint16_t gNOAACountdown_10ms; - extern volatile bool gScheduleNOAA; + extern volatile uint16_t gNOAACountdown_10ms; + extern volatile bool gScheduleNOAA; #endif extern volatile bool gFlagTailNoteEliminationComplete; extern volatile uint8_t gVFOStateResumeCountdown_500ms; #ifdef ENABLE_FMRADIO - extern volatile bool gScheduleFM; + extern volatile bool gScheduleFM; #endif extern uint8_t gIsLocked; extern volatile uint8_t boot_counter_10ms; #ifdef ENABLE_FEAT_F4HWN - extern bool gK5startup; - extern bool gBackLight; - extern uint8_t gBacklightTimeOriginal; - extern uint8_t gBacklightBrightnessOld; - extern uint8_t gPttOnePushCounter; - extern uint32_t gBlinkCounter; + extern bool gK5startup; + extern bool gBackLight; + extern uint8_t gBacklightTimeOriginal; + extern uint8_t gBacklightBrightnessOld; + extern uint8_t gPttOnePushCounter; + extern uint32_t gBlinkCounter; #endif int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit); diff --git a/radio.c b/radio.c index 634b893..5170545 100644 --- a/radio.c +++ b/radio.c @@ -20,7 +20,7 @@ #include "am_fix.h" #include "app/dtmf.h" #ifdef ENABLE_FMRADIO - #include "app/fm.h" + #include "app/fm.h" #endif #include "audio.h" #include "bsp/dp32g030/gpio.h" @@ -44,1156 +44,1156 @@ DCS_CodeType_t gCurrentCodeType; VfoState_t VfoState[2]; const char gModulationStr[MODULATION_UKNOWN][4] = { - [MODULATION_FM]="FM", - [MODULATION_AM]="AM", - [MODULATION_USB]="USB", + [MODULATION_FM]="FM", + [MODULATION_AM]="AM", + [MODULATION_USB]="USB", #ifdef ENABLE_BYP_RAW_DEMODULATORS - [MODULATION_BYP]="BYP", - [MODULATION_RAW]="RAW" + [MODULATION_BYP]="BYP", + [MODULATION_RAW]="RAW" #endif }; bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanList) { - // return true if the channel appears valid - if (!IS_MR_CHANNEL(channel)) - return false; + // return true if the channel appears valid + if (!IS_MR_CHANNEL(channel)) + return false; - const ChannelAttributes_t att = gMR_ChannelAttributes[channel]; + const ChannelAttributes_t att = gMR_ChannelAttributes[channel]; - if (checkScanList && gMR_ChannelExclude[channel] == true) - return false; + if (checkScanList && gMR_ChannelExclude[channel] == true) + return false; - if (att.band > BAND7_470MHz) - return false; + if (att.band > BAND7_470MHz) + return false; - if (!checkScanList || scanList > 4) - return true; + if (!checkScanList || scanList > 4) + return true; - /* - if(scanList == 0 && (att.scanlist1 == 1 || att.scanlist2 == 1 || att.scanlist3 == 1)) - { - return false; - } - else if(scanList == 1 && att.scanlist1 != 1) - { - return false; - } - else if(scanList == 2 && att.scanlist2 != 1) - { - return false; - } - else if(scanList == 3 && att.scanlist3 != 1) - { - return false; - } - else if(scanList == 4 && (att.scanlist1 == 0 && att.scanlist2 == 0 && att.scanlist3 == 0)) - { - return false; - } - */ + /* + if(scanList == 0 && (att.scanlist1 == 1 || att.scanlist2 == 1 || att.scanlist3 == 1)) + { + return false; + } + else if(scanList == 1 && att.scanlist1 != 1) + { + return false; + } + else if(scanList == 2 && att.scanlist2 != 1) + { + return false; + } + else if(scanList == 3 && att.scanlist3 != 1) + { + return false; + } + else if(scanList == 4 && (att.scanlist1 == 0 && att.scanlist2 == 0 && att.scanlist3 == 0)) + { + return false; + } + */ - if ((scanList == 0 && (att.scanlist1 == 1 || att.scanlist2 == 1 || att.scanlist3 == 1)) || - (scanList == 1 && att.scanlist1 != 1) || - (scanList == 2 && att.scanlist2 != 1) || - (scanList == 3 && att.scanlist3 != 1) || - (scanList == 4 && (att.scanlist1 == 0 && att.scanlist2 == 0 && att.scanlist3 == 0))) { - return false; - } + if ((scanList == 0 && (att.scanlist1 == 1 || att.scanlist2 == 1 || att.scanlist3 == 1)) || + (scanList == 1 && att.scanlist1 != 1) || + (scanList == 2 && att.scanlist2 != 1) || + (scanList == 3 && att.scanlist3 != 1) || + (scanList == 4 && (att.scanlist1 == 0 && att.scanlist2 == 0 && att.scanlist3 == 0))) { + return false; + } - //return true; + //return true; - // I don't understand what this code is for... - - const uint8_t PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[scanList - 1]; - const uint8_t PriorityCh2 = gEeprom.SCANLIST_PRIORITY_CH2[scanList - 1]; + // I don't understand what this code is for... + + const uint8_t PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[scanList - 1]; + const uint8_t PriorityCh2 = gEeprom.SCANLIST_PRIORITY_CH2[scanList - 1]; - return PriorityCh1 != channel && PriorityCh2 != channel; + return PriorityCh1 != channel && PriorityCh2 != channel; } uint8_t RADIO_FindNextChannel(uint8_t Channel, int8_t Direction, bool bCheckScanList, uint8_t VFO) { - for (unsigned int i = 0; IS_MR_CHANNEL(i); i++, Channel += Direction) { - if (Channel == 0xFF) { - Channel = MR_CHANNEL_LAST; - } else if (!IS_MR_CHANNEL(Channel)) { - Channel = MR_CHANNEL_FIRST; - } + for (unsigned int i = 0; IS_MR_CHANNEL(i); i++, Channel += Direction) { + if (Channel == 0xFF) { + Channel = MR_CHANNEL_LAST; + } else if (!IS_MR_CHANNEL(Channel)) { + Channel = MR_CHANNEL_FIRST; + } - if (RADIO_CheckValidChannel(Channel, bCheckScanList, VFO)) { - return Channel; - } - } + if (RADIO_CheckValidChannel(Channel, bCheckScanList, VFO)) { + return Channel; + } + } - return 0xFF; + return 0xFF; } void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t Frequency) { - memset(pInfo, 0, sizeof(*pInfo)); + memset(pInfo, 0, sizeof(*pInfo)); - pInfo->Band = FREQUENCY_GetBand(Frequency); - pInfo->SCANLIST1_PARTICIPATION = false; - pInfo->SCANLIST2_PARTICIPATION = false; - pInfo->SCANLIST3_PARTICIPATION = false; - pInfo->STEP_SETTING = STEP_12_5kHz; - pInfo->StepFrequency = gStepFrequencyTable[pInfo->STEP_SETTING]; - pInfo->CHANNEL_SAVE = ChannelSave; - pInfo->FrequencyReverse = false; - pInfo->TX_LOCK = true; - pInfo->OUTPUT_POWER = OUTPUT_POWER_LOW1; - pInfo->freq_config_RX.Frequency = Frequency; - pInfo->freq_config_TX.Frequency = Frequency; - pInfo->pRX = &pInfo->freq_config_RX; - pInfo->pTX = &pInfo->freq_config_TX; - pInfo->Compander = 0; // off + pInfo->Band = FREQUENCY_GetBand(Frequency); + pInfo->SCANLIST1_PARTICIPATION = false; + pInfo->SCANLIST2_PARTICIPATION = false; + pInfo->SCANLIST3_PARTICIPATION = false; + pInfo->STEP_SETTING = STEP_12_5kHz; + pInfo->StepFrequency = gStepFrequencyTable[pInfo->STEP_SETTING]; + pInfo->CHANNEL_SAVE = ChannelSave; + pInfo->FrequencyReverse = false; + pInfo->TX_LOCK = true; + pInfo->OUTPUT_POWER = OUTPUT_POWER_LOW1; + pInfo->freq_config_RX.Frequency = Frequency; + pInfo->freq_config_TX.Frequency = Frequency; + pInfo->pRX = &pInfo->freq_config_RX; + pInfo->pTX = &pInfo->freq_config_TX; + pInfo->Compander = 0; // off - if (ChannelSave == (FREQ_CHANNEL_FIRST + BAND2_108MHz)) - pInfo->Modulation = MODULATION_AM; - else - pInfo->Modulation = MODULATION_FM; + if (ChannelSave == (FREQ_CHANNEL_FIRST + BAND2_108MHz)) + pInfo->Modulation = MODULATION_AM; + else + pInfo->Modulation = MODULATION_FM; - RADIO_ConfigureSquelchAndOutputPower(pInfo); + RADIO_ConfigureSquelchAndOutputPower(pInfo); } void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure) { - VFO_Info_t *pVfo = &gEeprom.VfoInfo[VFO]; + VFO_Info_t *pVfo = &gEeprom.VfoInfo[VFO]; - if (!gSetting_350EN) { - if (gEeprom.FreqChannel[VFO] == FREQ_CHANNEL_FIRST + BAND5_350MHz) - gEeprom.FreqChannel[VFO] = FREQ_CHANNEL_FIRST + BAND6_400MHz; + if (!gSetting_350EN) { + if (gEeprom.FreqChannel[VFO] == FREQ_CHANNEL_FIRST + BAND5_350MHz) + gEeprom.FreqChannel[VFO] = FREQ_CHANNEL_FIRST + BAND6_400MHz; - if (gEeprom.ScreenChannel[VFO] == FREQ_CHANNEL_FIRST + BAND5_350MHz) - gEeprom.ScreenChannel[VFO] = FREQ_CHANNEL_FIRST + BAND6_400MHz; - } + if (gEeprom.ScreenChannel[VFO] == FREQ_CHANNEL_FIRST + BAND5_350MHz) + gEeprom.ScreenChannel[VFO] = FREQ_CHANNEL_FIRST + BAND6_400MHz; + } - uint8_t channel = gEeprom.ScreenChannel[VFO]; + uint8_t channel = gEeprom.ScreenChannel[VFO]; - if (IS_VALID_CHANNEL(channel)) { + if (IS_VALID_CHANNEL(channel)) { #ifdef ENABLE_NOAA - if (IS_NOAA_CHANNEL(channel)) - { - RADIO_InitInfo(pVfo, gEeprom.ScreenChannel[VFO], NoaaFrequencyTable[channel - NOAA_CHANNEL_FIRST]); + if (IS_NOAA_CHANNEL(channel)) + { + RADIO_InitInfo(pVfo, gEeprom.ScreenChannel[VFO], NoaaFrequencyTable[channel - NOAA_CHANNEL_FIRST]); - if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) - return; + if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) + return; - gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF; + gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF; - gUpdateStatus = true; - return; - } + gUpdateStatus = true; + return; + } #endif - if (IS_MR_CHANNEL(channel)) { - channel = RADIO_FindNextChannel(channel, RADIO_CHANNEL_UP, false, VFO); - if (channel == 0xFF) { - channel = gEeprom.FreqChannel[VFO]; - gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO]; - } - else { - gEeprom.ScreenChannel[VFO] = channel; - gEeprom.MrChannel[VFO] = channel; - } - } - } - else - channel = FREQ_CHANNEL_LAST - 1; + if (IS_MR_CHANNEL(channel)) { + channel = RADIO_FindNextChannel(channel, RADIO_CHANNEL_UP, false, VFO); + if (channel == 0xFF) { + channel = gEeprom.FreqChannel[VFO]; + gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO]; + } + else { + gEeprom.ScreenChannel[VFO] = channel; + gEeprom.MrChannel[VFO] = channel; + } + } + } + else + channel = FREQ_CHANNEL_LAST - 1; - ChannelAttributes_t att = gMR_ChannelAttributes[channel]; - if (att.__val == 0xFF) { // invalid/unused channel - if (IS_MR_CHANNEL(channel)) { - channel = gEeprom.FreqChannel[VFO]; - gEeprom.ScreenChannel[VFO] = channel; - } + ChannelAttributes_t att = gMR_ChannelAttributes[channel]; + if (att.__val == 0xFF) { // invalid/unused channel + if (IS_MR_CHANNEL(channel)) { + channel = gEeprom.FreqChannel[VFO]; + gEeprom.ScreenChannel[VFO] = channel; + } - uint8_t bandIdx = channel - FREQ_CHANNEL_FIRST; - RADIO_InitInfo(pVfo, channel, frequencyBandTable[bandIdx].lower); - return; - } + uint8_t bandIdx = channel - FREQ_CHANNEL_FIRST; + RADIO_InitInfo(pVfo, channel, frequencyBandTable[bandIdx].lower); + return; + } - uint8_t band = att.band; - if (band > BAND7_470MHz) { - band = BAND6_400MHz; - } + uint8_t band = att.band; + if (band > BAND7_470MHz) { + band = BAND6_400MHz; + } - bool bParticipation1; - bool bParticipation2; - bool bParticipation3; + bool bParticipation1; + bool bParticipation2; + bool bParticipation3; - if (IS_MR_CHANNEL(channel)) { - bParticipation1 = att.scanlist1; - bParticipation2 = att.scanlist2; - bParticipation3 = att.scanlist3; - } - else { - band = channel - FREQ_CHANNEL_FIRST; - bParticipation1 = true; - bParticipation2 = true; - bParticipation3 = true; - } + if (IS_MR_CHANNEL(channel)) { + bParticipation1 = att.scanlist1; + bParticipation2 = att.scanlist2; + bParticipation3 = att.scanlist3; + } + else { + band = channel - FREQ_CHANNEL_FIRST; + bParticipation1 = true; + bParticipation2 = true; + bParticipation3 = true; + } - pVfo->Band = band; - pVfo->SCANLIST1_PARTICIPATION = bParticipation1; - pVfo->SCANLIST2_PARTICIPATION = bParticipation2; - pVfo->SCANLIST3_PARTICIPATION = bParticipation3; - pVfo->CHANNEL_SAVE = channel; + pVfo->Band = band; + pVfo->SCANLIST1_PARTICIPATION = bParticipation1; + pVfo->SCANLIST2_PARTICIPATION = bParticipation2; + pVfo->SCANLIST3_PARTICIPATION = bParticipation3; + pVfo->CHANNEL_SAVE = channel; - uint16_t base; - if (IS_MR_CHANNEL(channel)) - base = channel * 16; - else - base = 0x0C80 + ((channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16); + uint16_t base; + if (IS_MR_CHANNEL(channel)) + base = channel * 16; + else + base = 0x0C80 + ((channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16); - if (configure == VFO_CONFIGURE_RELOAD || IS_FREQ_CHANNEL(channel)) - { - uint8_t tmp; - uint8_t data[8]; - - // *************** + if (configure == VFO_CONFIGURE_RELOAD || IS_FREQ_CHANNEL(channel)) + { + uint8_t tmp; + uint8_t data[8]; + + // *************** - EEPROM_ReadBuffer(base + 8, data, sizeof(data)); + EEPROM_ReadBuffer(base + 8, data, sizeof(data)); - tmp = data[3] & 0x0F; - if (tmp > TX_OFFSET_FREQUENCY_DIRECTION_SUB) - tmp = 0; - pVfo->TX_OFFSET_FREQUENCY_DIRECTION = tmp; - tmp = data[3] >> 4; - if (tmp >= MODULATION_UKNOWN) - tmp = MODULATION_FM; - pVfo->Modulation = tmp; + tmp = data[3] & 0x0F; + if (tmp > TX_OFFSET_FREQUENCY_DIRECTION_SUB) + tmp = 0; + pVfo->TX_OFFSET_FREQUENCY_DIRECTION = tmp; + tmp = data[3] >> 4; + if (tmp >= MODULATION_UKNOWN) + tmp = MODULATION_FM; + pVfo->Modulation = tmp; - tmp = data[6]; - if (tmp >= STEP_N_ELEM) - tmp = STEP_12_5kHz; - pVfo->STEP_SETTING = tmp; - pVfo->StepFrequency = gStepFrequencyTable[tmp]; + tmp = data[6]; + if (tmp >= STEP_N_ELEM) + tmp = STEP_12_5kHz; + pVfo->STEP_SETTING = tmp; + pVfo->StepFrequency = gStepFrequencyTable[tmp]; - tmp = data[7]; + tmp = data[7]; #ifndef ENABLE_FEAT_F4HWN - if (tmp > (ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1)) - tmp = 0; - pVfo->SCRAMBLING_TYPE = tmp; + if (tmp > (ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1)) + tmp = 0; + pVfo->SCRAMBLING_TYPE = tmp; #else - pVfo->SCRAMBLING_TYPE = 0; + pVfo->SCRAMBLING_TYPE = 0; #endif - pVfo->freq_config_RX.CodeType = (data[2] >> 0) & 0x0F; - pVfo->freq_config_TX.CodeType = (data[2] >> 4) & 0x0F; + pVfo->freq_config_RX.CodeType = (data[2] >> 0) & 0x0F; + pVfo->freq_config_TX.CodeType = (data[2] >> 4) & 0x0F; - tmp = data[0]; - switch (pVfo->freq_config_RX.CodeType) - { - default: - case CODE_TYPE_OFF: - pVfo->freq_config_RX.CodeType = CODE_TYPE_OFF; - tmp = 0; - break; + tmp = data[0]; + switch (pVfo->freq_config_RX.CodeType) + { + default: + case CODE_TYPE_OFF: + pVfo->freq_config_RX.CodeType = CODE_TYPE_OFF; + tmp = 0; + break; - case CODE_TYPE_CONTINUOUS_TONE: - if (tmp > (ARRAY_SIZE(CTCSS_Options) - 1)) - tmp = 0; - break; + case CODE_TYPE_CONTINUOUS_TONE: + if (tmp > (ARRAY_SIZE(CTCSS_Options) - 1)) + tmp = 0; + break; - case CODE_TYPE_DIGITAL: - case CODE_TYPE_REVERSE_DIGITAL: - if (tmp > (ARRAY_SIZE(DCS_Options) - 1)) - tmp = 0; - break; - } - pVfo->freq_config_RX.Code = tmp; + case CODE_TYPE_DIGITAL: + case CODE_TYPE_REVERSE_DIGITAL: + if (tmp > (ARRAY_SIZE(DCS_Options) - 1)) + tmp = 0; + break; + } + pVfo->freq_config_RX.Code = tmp; - tmp = data[1]; - switch (pVfo->freq_config_TX.CodeType) - { - default: - case CODE_TYPE_OFF: - pVfo->freq_config_TX.CodeType = CODE_TYPE_OFF; - tmp = 0; - break; + tmp = data[1]; + switch (pVfo->freq_config_TX.CodeType) + { + default: + case CODE_TYPE_OFF: + pVfo->freq_config_TX.CodeType = CODE_TYPE_OFF; + tmp = 0; + break; - case CODE_TYPE_CONTINUOUS_TONE: - if (tmp > (ARRAY_SIZE(CTCSS_Options) - 1)) - tmp = 0; - break; + case CODE_TYPE_CONTINUOUS_TONE: + if (tmp > (ARRAY_SIZE(CTCSS_Options) - 1)) + tmp = 0; + break; - case CODE_TYPE_DIGITAL: - case CODE_TYPE_REVERSE_DIGITAL: - if (tmp > (ARRAY_SIZE(DCS_Options) - 1)) - tmp = 0; - break; - } - pVfo->freq_config_TX.Code = tmp; + case CODE_TYPE_DIGITAL: + case CODE_TYPE_REVERSE_DIGITAL: + if (tmp > (ARRAY_SIZE(DCS_Options) - 1)) + tmp = 0; + break; + } + pVfo->freq_config_TX.Code = tmp; - if (data[4] == 0xFF) - { - pVfo->FrequencyReverse = false; - pVfo->CHANNEL_BANDWIDTH = BK4819_FILTER_BW_WIDE; - pVfo->OUTPUT_POWER = OUTPUT_POWER_LOW1; - pVfo->BUSY_CHANNEL_LOCK = false; - pVfo->TX_LOCK = true; - } - else - { - const uint8_t d4 = data[4]; - pVfo->FrequencyReverse = !!((d4 >> 0) & 1u); - pVfo->CHANNEL_BANDWIDTH = !!((d4 >> 1) & 1u); - pVfo->OUTPUT_POWER = ((d4 >> 2) & 7u); - pVfo->BUSY_CHANNEL_LOCK = !!((d4 >> 5) & 1u); - pVfo->TX_LOCK = !!((d4 >> 6) & 1u); - } + if (data[4] == 0xFF) + { + pVfo->FrequencyReverse = false; + pVfo->CHANNEL_BANDWIDTH = BK4819_FILTER_BW_WIDE; + pVfo->OUTPUT_POWER = OUTPUT_POWER_LOW1; + pVfo->BUSY_CHANNEL_LOCK = false; + pVfo->TX_LOCK = true; + } + else + { + const uint8_t d4 = data[4]; + pVfo->FrequencyReverse = !!((d4 >> 0) & 1u); + pVfo->CHANNEL_BANDWIDTH = !!((d4 >> 1) & 1u); + pVfo->OUTPUT_POWER = ((d4 >> 2) & 7u); + pVfo->BUSY_CHANNEL_LOCK = !!((d4 >> 5) & 1u); + pVfo->TX_LOCK = !!((d4 >> 6) & 1u); + } - if (data[5] == 0xFF) - { + if (data[5] == 0xFF) + { #ifdef ENABLE_DTMF_CALLING - pVfo->DTMF_DECODING_ENABLE = false; + pVfo->DTMF_DECODING_ENABLE = false; #endif - pVfo->DTMF_PTT_ID_TX_MODE = PTT_ID_OFF; - } - else - { + pVfo->DTMF_PTT_ID_TX_MODE = PTT_ID_OFF; + } + else + { #ifdef ENABLE_DTMF_CALLING - pVfo->DTMF_DECODING_ENABLE = ((data[5] >> 0) & 1u) ? true : false; + pVfo->DTMF_DECODING_ENABLE = ((data[5] >> 0) & 1u) ? true : false; #endif - uint8_t pttId = ((data[5] >> 1) & 7u); - pVfo->DTMF_PTT_ID_TX_MODE = pttId < ARRAY_SIZE(gSubMenu_PTT_ID) ? pttId : PTT_ID_OFF; - } + uint8_t pttId = ((data[5] >> 1) & 7u); + pVfo->DTMF_PTT_ID_TX_MODE = pttId < ARRAY_SIZE(gSubMenu_PTT_ID) ? pttId : PTT_ID_OFF; + } - // *************** + // *************** - struct { - uint32_t Frequency; - uint32_t Offset; - } __attribute__((packed)) info; - EEPROM_ReadBuffer(base, &info, sizeof(info)); - if(info.Frequency==0xFFFFFFFF) - pVfo->freq_config_RX.Frequency = frequencyBandTable[band].lower; - else - pVfo->freq_config_RX.Frequency = info.Frequency; + struct { + uint32_t Frequency; + uint32_t Offset; + } __attribute__((packed)) info; + EEPROM_ReadBuffer(base, &info, sizeof(info)); + if(info.Frequency==0xFFFFFFFF) + pVfo->freq_config_RX.Frequency = frequencyBandTable[band].lower; + else + pVfo->freq_config_RX.Frequency = info.Frequency; - if (info.Offset >= _1GHz_in_KHz) - info.Offset = _1GHz_in_KHz / 100; + if (info.Offset >= _1GHz_in_KHz) + info.Offset = _1GHz_in_KHz / 100; - pVfo->TX_OFFSET_FREQUENCY = info.Offset; + pVfo->TX_OFFSET_FREQUENCY = info.Offset; - // *************** - } + // *************** + } - uint32_t frequency = pVfo->freq_config_RX.Frequency; + uint32_t frequency = pVfo->freq_config_RX.Frequency; - // fix previously set incorrect band - band = FREQUENCY_GetBand(frequency); + // fix previously set incorrect band + band = FREQUENCY_GetBand(frequency); - if (frequency < frequencyBandTable[band].lower) - frequency = frequencyBandTable[band].lower; - else if (frequency > frequencyBandTable[band].upper) - frequency = frequencyBandTable[band].upper; - else if (channel >= FREQ_CHANNEL_FIRST) - frequency = FREQUENCY_RoundToStep(frequency, pVfo->StepFrequency); + if (frequency < frequencyBandTable[band].lower) + frequency = frequencyBandTable[band].lower; + else if (frequency > frequencyBandTable[band].upper) + frequency = frequencyBandTable[band].upper; + else if (channel >= FREQ_CHANNEL_FIRST) + frequency = FREQUENCY_RoundToStep(frequency, pVfo->StepFrequency); - pVfo->freq_config_RX.Frequency = frequency; + pVfo->freq_config_RX.Frequency = frequency; - if (frequency >= frequencyBandTable[BAND2_108MHz].upper && frequency < frequencyBandTable[BAND2_108MHz].upper) - pVfo->TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF; - else if (!IS_MR_CHANNEL(channel)) - pVfo->TX_OFFSET_FREQUENCY = FREQUENCY_RoundToStep(pVfo->TX_OFFSET_FREQUENCY, pVfo->StepFrequency); + if (frequency >= frequencyBandTable[BAND2_108MHz].upper && frequency < frequencyBandTable[BAND2_108MHz].upper) + pVfo->TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF; + else if (!IS_MR_CHANNEL(channel)) + pVfo->TX_OFFSET_FREQUENCY = FREQUENCY_RoundToStep(pVfo->TX_OFFSET_FREQUENCY, pVfo->StepFrequency); - RADIO_ApplyOffset(pVfo); + RADIO_ApplyOffset(pVfo); - if (IS_MR_CHANNEL(channel)) - { // 16 bytes allocated to the channel name but only 10 used, the rest are 0's - SETTINGS_FetchChannelName(pVfo->Name, channel); - } + if (IS_MR_CHANNEL(channel)) + { // 16 bytes allocated to the channel name but only 10 used, the rest are 0's + SETTINGS_FetchChannelName(pVfo->Name, channel); + } - if (!pVfo->FrequencyReverse) - { - pVfo->pRX = &pVfo->freq_config_RX; - pVfo->pTX = &pVfo->freq_config_TX; - } - else - { - pVfo->pRX = &pVfo->freq_config_TX; - pVfo->pTX = &pVfo->freq_config_RX; - } + if (!pVfo->FrequencyReverse) + { + pVfo->pRX = &pVfo->freq_config_RX; + pVfo->pTX = &pVfo->freq_config_TX; + } + else + { + pVfo->pRX = &pVfo->freq_config_TX; + pVfo->pTX = &pVfo->freq_config_RX; + } - if (!gSetting_350EN) - { - FREQ_Config_t *pConfig = pVfo->pRX; - if (pConfig->Frequency >= 35000000 && pConfig->Frequency < 40000000) - pConfig->Frequency = 43300000; - } + if (!gSetting_350EN) + { + FREQ_Config_t *pConfig = pVfo->pRX; + if (pConfig->Frequency >= 35000000 && pConfig->Frequency < 40000000) + pConfig->Frequency = 43300000; + } - pVfo->Compander = att.compander; + pVfo->Compander = att.compander; - RADIO_ConfigureSquelchAndOutputPower(pVfo); + RADIO_ConfigureSquelchAndOutputPower(pVfo); } void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo) { - // ******************************* - // squelch + // ******************************* + // squelch - FREQUENCY_Band_t Band = FREQUENCY_GetBand(pInfo->pRX->Frequency); - uint16_t Base = (Band < BAND4_174MHz) ? 0x1E60 : 0x1E00; + FREQUENCY_Band_t Band = FREQUENCY_GetBand(pInfo->pRX->Frequency); + uint16_t Base = (Band < BAND4_174MHz) ? 0x1E60 : 0x1E00; - if (gEeprom.SQUELCH_LEVEL == 0) - { // squelch == 0 (off) - pInfo->SquelchOpenRSSIThresh = 0; // 0 ~ 255 - pInfo->SquelchOpenNoiseThresh = 127; // 127 ~ 0 - pInfo->SquelchCloseGlitchThresh = 255; // 255 ~ 0 + if (gEeprom.SQUELCH_LEVEL == 0) + { // squelch == 0 (off) + pInfo->SquelchOpenRSSIThresh = 0; // 0 ~ 255 + pInfo->SquelchOpenNoiseThresh = 127; // 127 ~ 0 + pInfo->SquelchCloseGlitchThresh = 255; // 255 ~ 0 - pInfo->SquelchCloseRSSIThresh = 0; // 0 ~ 255 - pInfo->SquelchCloseNoiseThresh = 127; // 127 ~ 0 - pInfo->SquelchOpenGlitchThresh = 255; // 255 ~ 0 - } - else - { // squelch >= 1 - Base += gEeprom.SQUELCH_LEVEL; // my eeprom squelch-1 - // VHF UHF - EEPROM_ReadBuffer(Base + 0x00, &pInfo->SquelchOpenRSSIThresh, 1); // 50 10 - EEPROM_ReadBuffer(Base + 0x10, &pInfo->SquelchCloseRSSIThresh, 1); // 40 5 + pInfo->SquelchCloseRSSIThresh = 0; // 0 ~ 255 + pInfo->SquelchCloseNoiseThresh = 127; // 127 ~ 0 + pInfo->SquelchOpenGlitchThresh = 255; // 255 ~ 0 + } + else + { // squelch >= 1 + Base += gEeprom.SQUELCH_LEVEL; // my eeprom squelch-1 + // VHF UHF + EEPROM_ReadBuffer(Base + 0x00, &pInfo->SquelchOpenRSSIThresh, 1); // 50 10 + EEPROM_ReadBuffer(Base + 0x10, &pInfo->SquelchCloseRSSIThresh, 1); // 40 5 - EEPROM_ReadBuffer(Base + 0x20, &pInfo->SquelchOpenNoiseThresh, 1); // 65 90 - EEPROM_ReadBuffer(Base + 0x30, &pInfo->SquelchCloseNoiseThresh, 1); // 70 100 + EEPROM_ReadBuffer(Base + 0x20, &pInfo->SquelchOpenNoiseThresh, 1); // 65 90 + EEPROM_ReadBuffer(Base + 0x30, &pInfo->SquelchCloseNoiseThresh, 1); // 70 100 - EEPROM_ReadBuffer(Base + 0x40, &pInfo->SquelchCloseGlitchThresh, 1); // 90 90 - EEPROM_ReadBuffer(Base + 0x50, &pInfo->SquelchOpenGlitchThresh, 1); // 100 100 + EEPROM_ReadBuffer(Base + 0x40, &pInfo->SquelchCloseGlitchThresh, 1); // 90 90 + EEPROM_ReadBuffer(Base + 0x50, &pInfo->SquelchOpenGlitchThresh, 1); // 100 100 - uint16_t noise_open = pInfo->SquelchOpenNoiseThresh; - uint16_t noise_close = pInfo->SquelchCloseNoiseThresh; + uint16_t noise_open = pInfo->SquelchOpenNoiseThresh; + uint16_t noise_close = pInfo->SquelchCloseNoiseThresh; #if ENABLE_SQUELCH_MORE_SENSITIVE - uint16_t rssi_open = pInfo->SquelchOpenRSSIThresh; - uint16_t rssi_close = pInfo->SquelchCloseRSSIThresh; - uint16_t glitch_open = pInfo->SquelchOpenGlitchThresh; - uint16_t glitch_close = pInfo->SquelchCloseGlitchThresh; - // make squelch more sensitive - // note that 'noise' and 'glitch' values are inverted compared to 'rssi' values - rssi_open = (rssi_open * 1) / 2; - noise_open = (noise_open * 2) / 1; - glitch_open = (glitch_open * 2) / 1; + uint16_t rssi_open = pInfo->SquelchOpenRSSIThresh; + uint16_t rssi_close = pInfo->SquelchCloseRSSIThresh; + uint16_t glitch_open = pInfo->SquelchOpenGlitchThresh; + uint16_t glitch_close = pInfo->SquelchCloseGlitchThresh; + // make squelch more sensitive + // note that 'noise' and 'glitch' values are inverted compared to 'rssi' values + rssi_open = (rssi_open * 1) / 2; + noise_open = (noise_open * 2) / 1; + glitch_open = (glitch_open * 2) / 1; - // ensure the 'close' threshold is lower than the 'open' threshold - if (rssi_close == rssi_open && rssi_close >= 2) - rssi_close -= 2; - if (noise_close == noise_open && noise_close <= 125) - noise_close += 2; - if (glitch_close == glitch_open && glitch_close <= 253) - glitch_close += 2; + // ensure the 'close' threshold is lower than the 'open' threshold + if (rssi_close == rssi_open && rssi_close >= 2) + rssi_close -= 2; + if (noise_close == noise_open && noise_close <= 125) + noise_close += 2; + if (glitch_close == glitch_open && glitch_close <= 253) + glitch_close += 2; - pInfo->SquelchOpenRSSIThresh = (rssi_open > 255) ? 255 : rssi_open; - pInfo->SquelchCloseRSSIThresh = (rssi_close > 255) ? 255 : rssi_close; - pInfo->SquelchOpenGlitchThresh = (glitch_open > 255) ? 255 : glitch_open; - pInfo->SquelchCloseGlitchThresh = (glitch_close > 255) ? 255 : glitch_close; + pInfo->SquelchOpenRSSIThresh = (rssi_open > 255) ? 255 : rssi_open; + pInfo->SquelchCloseRSSIThresh = (rssi_close > 255) ? 255 : rssi_close; + pInfo->SquelchOpenGlitchThresh = (glitch_open > 255) ? 255 : glitch_open; + pInfo->SquelchCloseGlitchThresh = (glitch_close > 255) ? 255 : glitch_close; #endif - pInfo->SquelchOpenNoiseThresh = (noise_open > 127) ? 127 : noise_open; - pInfo->SquelchCloseNoiseThresh = (noise_close > 127) ? 127 : noise_close; - } + pInfo->SquelchOpenNoiseThresh = (noise_open > 127) ? 127 : noise_open; + pInfo->SquelchCloseNoiseThresh = (noise_close > 127) ? 127 : noise_close; + } - // ******************************* - // output power + // ******************************* + // output power - Band = FREQUENCY_GetBand(pInfo->pTX->Frequency); + Band = FREQUENCY_GetBand(pInfo->pTX->Frequency); - // my eeprom calibration data - // - // 1ED0 32 32 32 64 64 64 8c 8c 8c ff ff ff ff ff ff ff 50 MHz - // 1EE0 32 32 32 64 64 64 8c 8c 8c ff ff ff ff ff ff ff 108 MHz - // 1EF0 5f 5f 5f 69 69 69 87 87 87 ff ff ff ff ff ff ff 137 MHz - // 1F00 32 32 32 64 64 64 8c 8c 8c ff ff ff ff ff ff ff 174 MHz - // 1F10 5f 5f 5f 69 69 69 87 87 87 ff ff ff ff ff ff ff 350 MHz - // 1F20 5f 5f 5f 69 69 69 87 87 87 ff ff ff ff ff ff ff 400 MHz - // 1F30 32 32 32 64 64 64 8c 8c 8c ff ff ff ff ff ff ff 470 MHz + // my eeprom calibration data + // + // 1ED0 32 32 32 64 64 64 8c 8c 8c ff ff ff ff ff ff ff 50 MHz + // 1EE0 32 32 32 64 64 64 8c 8c 8c ff ff ff ff ff ff ff 108 MHz + // 1EF0 5f 5f 5f 69 69 69 87 87 87 ff ff ff ff ff ff ff 137 MHz + // 1F00 32 32 32 64 64 64 8c 8c 8c ff ff ff ff ff ff ff 174 MHz + // 1F10 5f 5f 5f 69 69 69 87 87 87 ff ff ff ff ff ff ff 350 MHz + // 1F20 5f 5f 5f 69 69 69 87 87 87 ff ff ff ff ff ff ff 400 MHz + // 1F30 32 32 32 64 64 64 8c 8c 8c ff ff ff ff ff ff ff 470 MHz - uint8_t Txp[3]; - uint8_t Op = 0; // Low eeprom calibration data - uint8_t currentPower = pInfo->OUTPUT_POWER; + uint8_t Txp[3]; + uint8_t Op = 0; // Low eeprom calibration data + uint8_t currentPower = pInfo->OUTPUT_POWER; - if(currentPower == OUTPUT_POWER_USER) - { - if(gSetting_set_pwr == 5) - { - Op = 1; // Mid eeprom calibration data - } - else if(gSetting_set_pwr == 6) - { - Op = 2; // High eeprom calibration data - } - currentPower = gSetting_set_pwr; - } - else - { - if (currentPower == OUTPUT_POWER_MID) - { - Op = 1; // Mid eeprom calibration data - } - else if(currentPower == OUTPUT_POWER_HIGH) - { - Op = 2; // High eeprom calibration data - } - currentPower--; - } + if(currentPower == OUTPUT_POWER_USER) + { + if(gSetting_set_pwr == 5) + { + Op = 1; // Mid eeprom calibration data + } + else if(gSetting_set_pwr == 6) + { + Op = 2; // High eeprom calibration data + } + currentPower = gSetting_set_pwr; + } + else + { + if (currentPower == OUTPUT_POWER_MID) + { + Op = 1; // Mid eeprom calibration data + } + else if(currentPower == OUTPUT_POWER_HIGH) + { + Op = 2; // High eeprom calibration data + } + currentPower--; + } - EEPROM_ReadBuffer(0x1ED0 + (Band * 16) + (Op * 3), Txp, 3); + EEPROM_ReadBuffer(0x1ED0 + (Band * 16) + (Op * 3), Txp, 3); #ifdef ENABLE_FEAT_F4HWN - // make low and mid even lower - // and use calibration values - // be aware with toxic fucking closed firmwares + // make low and mid even lower + // and use calibration values + // be aware with toxic fucking closed firmwares - /* - uint8_t shift[] = {0, 0, 0, 0, 0}; + /* + uint8_t shift[] = {0, 0, 0, 0, 0}; - if(Band == 5) // UHF - { - shift[0] = 0; - shift[1] = 0; - shift[2] = 0; - shift[3] = 0; - shift[4] = 0; - } - */ + if(Band == 5) // UHF + { + shift[0] = 0; + shift[1] = 0; + shift[2] = 0; + shift[3] = 0; + shift[4] = 0; + } + */ - for(uint8_t p = 0; p < 3; p++) - { - switch (currentPower) - { - case 0: - Txp[p] = (Txp[p] * 4) / 25; //+ shift[pInfo->OUTPUT_POWER]; - break; - case 1: - Txp[p] = (Txp[p] * 4) / 19; // + shift[pInfo->OUTPUT_POWER]; - break; - case 2: - Txp[p] = (Txp[p] * 4) / 13; // + shift[pInfo->OUTPUT_POWER]; - break; - case 3: - Txp[p] = (Txp[p] * 4) / 10; // + shift[pInfo->OUTPUT_POWER]; - break; - case 4: - Txp[p] = (Txp[p] * 4) / 7; // + shift[pInfo->OUTPUT_POWER]; - break; - case 5: - Txp[p] = (Txp[p] * 3) / 4; - break; - case 6: - Txp[p] = Txp[p] + 30; - break; - } - } + for(uint8_t p = 0; p < 3; p++) + { + switch (currentPower) + { + case 0: + Txp[p] = (Txp[p] * 4) / 25; //+ shift[pInfo->OUTPUT_POWER]; + break; + case 1: + Txp[p] = (Txp[p] * 4) / 19; // + shift[pInfo->OUTPUT_POWER]; + break; + case 2: + Txp[p] = (Txp[p] * 4) / 13; // + shift[pInfo->OUTPUT_POWER]; + break; + case 3: + Txp[p] = (Txp[p] * 4) / 10; // + shift[pInfo->OUTPUT_POWER]; + break; + case 4: + Txp[p] = (Txp[p] * 4) / 7; // + shift[pInfo->OUTPUT_POWER]; + break; + case 5: + Txp[p] = (Txp[p] * 3) / 4; + break; + case 6: + Txp[p] = Txp[p] + 30; + break; + } + } #else - #ifdef ENABLE_REDUCE_LOW_MID_TX_POWER - // make low and mid even lower - if (pInfo->OUTPUT_POWER == OUTPUT_POWER_LOW) { - Txp[0] /= 5; - Txp[1] /= 5; - Txp[2] /= 5; - } - else if (pInfo->OUTPUT_POWER == OUTPUT_POWER_MID){ - Txp[0] /= 3; - Txp[1] /= 3; - Txp[2] /= 3; - } - #endif + #ifdef ENABLE_REDUCE_LOW_MID_TX_POWER + // make low and mid even lower + if (pInfo->OUTPUT_POWER == OUTPUT_POWER_LOW) { + Txp[0] /= 5; + Txp[1] /= 5; + Txp[2] /= 5; + } + else if (pInfo->OUTPUT_POWER == OUTPUT_POWER_MID){ + Txp[0] /= 3; + Txp[1] /= 3; + Txp[2] /= 3; + } + #endif #endif - pInfo->TXP_CalculatedSetting = FREQUENCY_CalculateOutputPower( - Txp[0], - Txp[1], - Txp[2], - frequencyBandTable[Band].lower, - (frequencyBandTable[Band].lower + frequencyBandTable[Band].upper) / 2, - frequencyBandTable[Band].upper, - pInfo->pTX->Frequency); + pInfo->TXP_CalculatedSetting = FREQUENCY_CalculateOutputPower( + Txp[0], + Txp[1], + Txp[2], + frequencyBandTable[Band].lower, + (frequencyBandTable[Band].lower + frequencyBandTable[Band].upper) / 2, + frequencyBandTable[Band].upper, + pInfo->pTX->Frequency); - // ******************************* + // ******************************* } void RADIO_ApplyOffset(VFO_Info_t *pInfo) { - uint32_t Frequency = pInfo->freq_config_RX.Frequency; + uint32_t Frequency = pInfo->freq_config_RX.Frequency; - switch (pInfo->TX_OFFSET_FREQUENCY_DIRECTION) - { - case TX_OFFSET_FREQUENCY_DIRECTION_OFF: - break; - case TX_OFFSET_FREQUENCY_DIRECTION_ADD: - Frequency += pInfo->TX_OFFSET_FREQUENCY; - break; - case TX_OFFSET_FREQUENCY_DIRECTION_SUB: - Frequency -= pInfo->TX_OFFSET_FREQUENCY; - break; - } + switch (pInfo->TX_OFFSET_FREQUENCY_DIRECTION) + { + case TX_OFFSET_FREQUENCY_DIRECTION_OFF: + break; + case TX_OFFSET_FREQUENCY_DIRECTION_ADD: + Frequency += pInfo->TX_OFFSET_FREQUENCY; + break; + case TX_OFFSET_FREQUENCY_DIRECTION_SUB: + Frequency -= pInfo->TX_OFFSET_FREQUENCY; + break; + } - pInfo->freq_config_TX.Frequency = Frequency; + pInfo->freq_config_TX.Frequency = Frequency; } static void RADIO_SelectCurrentVfo(void) { - // if crossband is active and DW not the gCurrentVfo is gTxVfo (gTxVfo/TX_VFO is only ever changed by the user) - // otherwise it is set to gRxVfo which is set to gTxVfo in RADIO_SelectVfos - // so in the end gCurrentVfo is equal to gTxVfo unless dual watch changes it on incomming transmition (again, this can only happen when XB off) - // note: it is called only in certain situations so could be not up-to-date - gCurrentVfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF || gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) ? gRxVfo : gTxVfo; + // if crossband is active and DW not the gCurrentVfo is gTxVfo (gTxVfo/TX_VFO is only ever changed by the user) + // otherwise it is set to gRxVfo which is set to gTxVfo in RADIO_SelectVfos + // so in the end gCurrentVfo is equal to gTxVfo unless dual watch changes it on incomming transmition (again, this can only happen when XB off) + // note: it is called only in certain situations so could be not up-to-date + gCurrentVfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF || gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) ? gRxVfo : gTxVfo; } void RADIO_SelectVfos(void) { - // if crossband without DW is used then RX_VFO is the opposite to the TX_VFO - gEeprom.RX_VFO = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF || gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) ? gEeprom.TX_VFO : !gEeprom.TX_VFO; + // if crossband without DW is used then RX_VFO is the opposite to the TX_VFO + gEeprom.RX_VFO = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF || gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) ? gEeprom.TX_VFO : !gEeprom.TX_VFO; - gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_VFO]; - gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO]; + gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_VFO]; + gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO]; - RADIO_SelectCurrentVfo(); + RADIO_SelectCurrentVfo(); } void RADIO_SetupRegisters(bool switchToForeground) { - BK4819_FilterBandwidth_t Bandwidth = gRxVfo->CHANNEL_BANDWIDTH; + BK4819_FilterBandwidth_t Bandwidth = gRxVfo->CHANNEL_BANDWIDTH; - AUDIO_AudioPathOff(); + AUDIO_AudioPathOff(); - gEnableSpeaker = false; + gEnableSpeaker = false; - BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false); + BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false); - switch (Bandwidth) - { - default: - Bandwidth = BK4819_FILTER_BW_WIDE; - [[fallthrough]]; - case BK4819_FILTER_BW_WIDE: - case BK4819_FILTER_BW_NARROW: - #ifdef ENABLE_AM_FIX -// BK4819_SetFilterBandwidth(Bandwidth, gRxVfo->Modulation == MODULATION_AM && gSetting_AM_fix); - BK4819_SetFilterBandwidth(Bandwidth, true); - #else - BK4819_SetFilterBandwidth(Bandwidth, false); - #endif - break; - } + switch (Bandwidth) + { + default: + Bandwidth = BK4819_FILTER_BW_WIDE; + [[fallthrough]]; + case BK4819_FILTER_BW_WIDE: + case BK4819_FILTER_BW_NARROW: + #ifdef ENABLE_AM_FIX +// BK4819_SetFilterBandwidth(Bandwidth, gRxVfo->Modulation == MODULATION_AM && gSetting_AM_fix); + BK4819_SetFilterBandwidth(Bandwidth, true); + #else + BK4819_SetFilterBandwidth(Bandwidth, false); + #endif + break; + } - BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false); + BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false); - BK4819_SetupPowerAmplifier(0, 0); + BK4819_SetupPowerAmplifier(0, 0); - BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false); + BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false); - while (1) - { - const uint16_t Status = BK4819_ReadRegister(BK4819_REG_0C); - if ((Status & 1u) == 0) // INTERRUPT REQUEST - break; + while (1) + { + const uint16_t Status = BK4819_ReadRegister(BK4819_REG_0C); + if ((Status & 1u) == 0) // INTERRUPT REQUEST + break; - BK4819_WriteRegister(BK4819_REG_02, 0); - SYSTEM_DelayMs(1); - } - BK4819_WriteRegister(BK4819_REG_3F, 0); + BK4819_WriteRegister(BK4819_REG_02, 0); + SYSTEM_DelayMs(1); + } + BK4819_WriteRegister(BK4819_REG_3F, 0); - // mic gain 0.5dB/step 0 to 31 - BK4819_WriteRegister(BK4819_REG_7D, 0xE940 | (gEeprom.MIC_SENSITIVITY_TUNING & 0x1f)); + // mic gain 0.5dB/step 0 to 31 + BK4819_WriteRegister(BK4819_REG_7D, 0xE940 | (gEeprom.MIC_SENSITIVITY_TUNING & 0x1f)); - uint32_t Frequency; - #ifdef ENABLE_NOAA - if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) || !gIsNoaaMode) - Frequency = gRxVfo->pRX->Frequency; - else - Frequency = NoaaFrequencyTable[gNoaaChannel]; - #else - Frequency = gRxVfo->pRX->Frequency; - #endif - BK4819_SetFrequency(Frequency); + uint32_t Frequency; + #ifdef ENABLE_NOAA + if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) || !gIsNoaaMode) + Frequency = gRxVfo->pRX->Frequency; + else + Frequency = NoaaFrequencyTable[gNoaaChannel]; + #else + Frequency = gRxVfo->pRX->Frequency; + #endif + BK4819_SetFrequency(Frequency); - BK4819_SetupSquelch( - gRxVfo->SquelchOpenRSSIThresh, gRxVfo->SquelchCloseRSSIThresh, - gRxVfo->SquelchOpenNoiseThresh, gRxVfo->SquelchCloseNoiseThresh, - gRxVfo->SquelchCloseGlitchThresh, gRxVfo->SquelchOpenGlitchThresh); + BK4819_SetupSquelch( + gRxVfo->SquelchOpenRSSIThresh, gRxVfo->SquelchCloseRSSIThresh, + gRxVfo->SquelchOpenNoiseThresh, gRxVfo->SquelchCloseNoiseThresh, + gRxVfo->SquelchCloseGlitchThresh, gRxVfo->SquelchOpenGlitchThresh); - BK4819_PickRXFilterPathBasedOnFrequency(Frequency); + BK4819_PickRXFilterPathBasedOnFrequency(Frequency); - // what does this in do ? - BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, true); + // what does this in do ? + BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, true); - // AF RX Gain and DAC - //BK4819_WriteRegister(BK4819_REG_48, 0xB3A8); // 1011 00 111010 1000 - BK4819_WriteRegister(BK4819_REG_48, - (11u << 12) | // ??? .. 0 ~ 15, doesn't seem to make any difference - ( 0u << 10) | // AF Rx Gain-1 - (gEeprom.VOLUME_GAIN << 4) | // AF Rx Gain-2 - (gEeprom.DAC_GAIN << 0)); // AF DAC Gain (after Gain-1 and Gain-2) + // AF RX Gain and DAC + //BK4819_WriteRegister(BK4819_REG_48, 0xB3A8); // 1011 00 111010 1000 + BK4819_WriteRegister(BK4819_REG_48, + (11u << 12) | // ??? .. 0 ~ 15, doesn't seem to make any difference + ( 0u << 10) | // AF Rx Gain-1 + (gEeprom.VOLUME_GAIN << 4) | // AF Rx Gain-2 + (gEeprom.DAC_GAIN << 0)); // AF DAC Gain (after Gain-1 and Gain-2) - uint16_t InterruptMask = BK4819_REG_3F_SQUELCH_FOUND | BK4819_REG_3F_SQUELCH_LOST; + uint16_t InterruptMask = BK4819_REG_3F_SQUELCH_FOUND | BK4819_REG_3F_SQUELCH_LOST; - #ifdef ENABLE_NOAA - if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) - #endif - { - if (gRxVfo->Modulation == MODULATION_FM) - { // FM - uint8_t CodeType = gRxVfo->pRX->CodeType; - uint8_t Code = gRxVfo->pRX->Code; + #ifdef ENABLE_NOAA + if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) + #endif + { + if (gRxVfo->Modulation == MODULATION_FM) + { // FM + uint8_t CodeType = gRxVfo->pRX->CodeType; + uint8_t Code = gRxVfo->pRX->Code; - switch (CodeType) - { - default: - case CODE_TYPE_OFF: - BK4819_SetCTCSSFrequency(670); + switch (CodeType) + { + default: + case CODE_TYPE_OFF: + BK4819_SetCTCSSFrequency(670); - //#ifndef ENABLE_CTCSS_TAIL_PHASE_SHIFT - BK4819_SetTailDetection(550); // QS's 55Hz tone method - //#else - // BK4819_SetTailDetection(670); // 67Hz - //#endif + //#ifndef ENABLE_CTCSS_TAIL_PHASE_SHIFT + BK4819_SetTailDetection(550); // QS's 55Hz tone method + //#else + // BK4819_SetTailDetection(670); // 67Hz + //#endif - InterruptMask = BK4819_REG_3F_CxCSS_TAIL | BK4819_REG_3F_SQUELCH_FOUND | BK4819_REG_3F_SQUELCH_LOST; - break; + InterruptMask = BK4819_REG_3F_CxCSS_TAIL | BK4819_REG_3F_SQUELCH_FOUND | BK4819_REG_3F_SQUELCH_LOST; + break; - case CODE_TYPE_CONTINUOUS_TONE: - BK4819_SetCTCSSFrequency(CTCSS_Options[Code]); + case CODE_TYPE_CONTINUOUS_TONE: + BK4819_SetCTCSSFrequency(CTCSS_Options[Code]); - //#ifndef ENABLE_CTCSS_TAIL_PHASE_SHIFT - BK4819_SetTailDetection(550); // QS's 55Hz tone method - //#else - // BK4819_SetTailDetection(CTCSS_Options[Code]); - //#endif + //#ifndef ENABLE_CTCSS_TAIL_PHASE_SHIFT + BK4819_SetTailDetection(550); // QS's 55Hz tone method + //#else + // BK4819_SetTailDetection(CTCSS_Options[Code]); + //#endif - InterruptMask = 0 - | BK4819_REG_3F_CxCSS_TAIL - | BK4819_REG_3F_CTCSS_FOUND - | BK4819_REG_3F_CTCSS_LOST - | BK4819_REG_3F_SQUELCH_FOUND - | BK4819_REG_3F_SQUELCH_LOST; + InterruptMask = 0 + | BK4819_REG_3F_CxCSS_TAIL + | BK4819_REG_3F_CTCSS_FOUND + | BK4819_REG_3F_CTCSS_LOST + | BK4819_REG_3F_SQUELCH_FOUND + | BK4819_REG_3F_SQUELCH_LOST; - break; + break; - case CODE_TYPE_DIGITAL: - case CODE_TYPE_REVERSE_DIGITAL: - BK4819_SetCDCSSCodeWord(DCS_GetGolayCodeWord(CodeType, Code)); - InterruptMask = 0 - | BK4819_REG_3F_CxCSS_TAIL - | BK4819_REG_3F_CDCSS_FOUND - | BK4819_REG_3F_CDCSS_LOST - | BK4819_REG_3F_SQUELCH_FOUND - | BK4819_REG_3F_SQUELCH_LOST; - break; - } + case CODE_TYPE_DIGITAL: + case CODE_TYPE_REVERSE_DIGITAL: + BK4819_SetCDCSSCodeWord(DCS_GetGolayCodeWord(CodeType, Code)); + InterruptMask = 0 + | BK4819_REG_3F_CxCSS_TAIL + | BK4819_REG_3F_CDCSS_FOUND + | BK4819_REG_3F_CDCSS_LOST + | BK4819_REG_3F_SQUELCH_FOUND + | BK4819_REG_3F_SQUELCH_LOST; + break; + } #ifndef ENABLE_FEAT_F4HWN - if (gRxVfo->SCRAMBLING_TYPE > 0 && gSetting_ScrambleEnable) - BK4819_EnableScramble(gRxVfo->SCRAMBLING_TYPE - 1); - else - BK4819_DisableScramble(); + if (gRxVfo->SCRAMBLING_TYPE > 0 && gSetting_ScrambleEnable) + BK4819_EnableScramble(gRxVfo->SCRAMBLING_TYPE - 1); + else + BK4819_DisableScramble(); #else - BK4819_DisableScramble(); + BK4819_DisableScramble(); #endif - } - } - #ifdef ENABLE_NOAA - else - { - BK4819_SetCTCSSFrequency(2625); - InterruptMask = 0 - | BK4819_REG_3F_CTCSS_FOUND - | BK4819_REG_3F_CTCSS_LOST - | BK4819_REG_3F_SQUELCH_FOUND - | BK4819_REG_3F_SQUELCH_LOST; - } - #endif + } + } + #ifdef ENABLE_NOAA + else + { + BK4819_SetCTCSSFrequency(2625); + InterruptMask = 0 + | BK4819_REG_3F_CTCSS_FOUND + | BK4819_REG_3F_CTCSS_LOST + | BK4819_REG_3F_SQUELCH_FOUND + | BK4819_REG_3F_SQUELCH_LOST; + } + #endif #ifdef ENABLE_VOX - if (gEeprom.VOX_SWITCH && gCurrentVfo->Modulation == MODULATION_FM + if (gEeprom.VOX_SWITCH && gCurrentVfo->Modulation == MODULATION_FM #ifdef ENABLE_NOAA - && !IS_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE) + && !IS_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE) #endif #ifdef ENABLE_FMRADIO - && !gFmRadioMode + && !gFmRadioMode #endif - ){ - BK4819_EnableVox(gEeprom.VOX1_THRESHOLD, gEeprom.VOX0_THRESHOLD); - InterruptMask |= BK4819_REG_3F_VOX_FOUND | BK4819_REG_3F_VOX_LOST; - } - else + ){ + BK4819_EnableVox(gEeprom.VOX1_THRESHOLD, gEeprom.VOX0_THRESHOLD); + InterruptMask |= BK4819_REG_3F_VOX_FOUND | BK4819_REG_3F_VOX_LOST; + } + else #endif - { - BK4819_DisableVox(); - } + { + BK4819_DisableVox(); + } - // RX expander - BK4819_SetCompander((gRxVfo->Modulation == MODULATION_FM && gRxVfo->Compander >= 2) ? gRxVfo->Compander : 0); + // RX expander + BK4819_SetCompander((gRxVfo->Modulation == MODULATION_FM && gRxVfo->Compander >= 2) ? gRxVfo->Compander : 0); - BK4819_EnableDTMF(); - InterruptMask |= BK4819_REG_3F_DTMF_5TONE_FOUND; + BK4819_EnableDTMF(); + InterruptMask |= BK4819_REG_3F_DTMF_5TONE_FOUND; - RADIO_SetupAGC(gRxVfo->Modulation == MODULATION_AM, false); + RADIO_SetupAGC(gRxVfo->Modulation == MODULATION_AM, false); - // enable/disable BK4819 selected interrupts - BK4819_WriteRegister(BK4819_REG_3F, InterruptMask); + // enable/disable BK4819 selected interrupts + BK4819_WriteRegister(BK4819_REG_3F, InterruptMask); - FUNCTION_Init(); + FUNCTION_Init(); - if (switchToForeground) - FUNCTION_Select(FUNCTION_FOREGROUND); + if (switchToForeground) + FUNCTION_Select(FUNCTION_FOREGROUND); } #ifdef ENABLE_NOAA - void RADIO_ConfigureNOAA(void) - { - uint8_t ChanAB; + void RADIO_ConfigureNOAA(void) + { + uint8_t ChanAB; - gUpdateStatus = true; + gUpdateStatus = true; - if (gEeprom.NOAA_AUTO_SCAN) - { - if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) - { - if (!IS_NOAA_CHANNEL(gEeprom.ScreenChannel[0])) - { - if (!IS_NOAA_CHANNEL(gEeprom.ScreenChannel[1])) - { - gIsNoaaMode = false; - return; - } - ChanAB = 1; - } - else - ChanAB = 0; + if (gEeprom.NOAA_AUTO_SCAN) + { + if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + { + if (!IS_NOAA_CHANNEL(gEeprom.ScreenChannel[0])) + { + if (!IS_NOAA_CHANNEL(gEeprom.ScreenChannel[1])) + { + gIsNoaaMode = false; + return; + } + ChanAB = 1; + } + else + ChanAB = 0; - if (!gIsNoaaMode) - gNoaaChannel = gEeprom.VfoInfo[ChanAB].CHANNEL_SAVE - NOAA_CHANNEL_FIRST; + if (!gIsNoaaMode) + gNoaaChannel = gEeprom.VfoInfo[ChanAB].CHANNEL_SAVE - NOAA_CHANNEL_FIRST; - gIsNoaaMode = true; - return; - } + gIsNoaaMode = true; + return; + } - if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) - { - gIsNoaaMode = true; - gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST; - gNOAA_Countdown_10ms = NOAA_countdown_2_10ms; - gScheduleNOAA = false; - } - else - gIsNoaaMode = false; - } - else - gIsNoaaMode = false; - } + if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) + { + gIsNoaaMode = true; + gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST; + gNOAA_Countdown_10ms = NOAA_countdown_2_10ms; + gScheduleNOAA = false; + } + else + gIsNoaaMode = false; + } + else + gIsNoaaMode = false; + } #endif void RADIO_SetTxParameters(void) { - BK4819_FilterBandwidth_t Bandwidth = gCurrentVfo->CHANNEL_BANDWIDTH; + BK4819_FilterBandwidth_t Bandwidth = gCurrentVfo->CHANNEL_BANDWIDTH; - AUDIO_AudioPathOff(); + AUDIO_AudioPathOff(); - gEnableSpeaker = false; + gEnableSpeaker = false; - BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false); + BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false); - switch (Bandwidth) - { - default: - Bandwidth = BK4819_FILTER_BW_WIDE; - [[fallthrough]]; - case BK4819_FILTER_BW_WIDE: - case BK4819_FILTER_BW_NARROW: - #ifdef ENABLE_AM_FIX -// BK4819_SetFilterBandwidth(Bandwidth, gCurrentVfo->Modulation == MODULATION_AM && gSetting_AM_fix); - BK4819_SetFilterBandwidth(Bandwidth, true); - #else - BK4819_SetFilterBandwidth(Bandwidth, false); - #endif - break; - } + switch (Bandwidth) + { + default: + Bandwidth = BK4819_FILTER_BW_WIDE; + [[fallthrough]]; + case BK4819_FILTER_BW_WIDE: + case BK4819_FILTER_BW_NARROW: + #ifdef ENABLE_AM_FIX +// BK4819_SetFilterBandwidth(Bandwidth, gCurrentVfo->Modulation == MODULATION_AM && gSetting_AM_fix); + BK4819_SetFilterBandwidth(Bandwidth, true); + #else + BK4819_SetFilterBandwidth(Bandwidth, false); + #endif + break; + } - BK4819_SetFrequency(gCurrentVfo->pTX->Frequency); + BK4819_SetFrequency(gCurrentVfo->pTX->Frequency); - // TX compressor - BK4819_SetCompander((gRxVfo->Modulation == MODULATION_FM && (gRxVfo->Compander == 1 || gRxVfo->Compander >= 3)) ? gRxVfo->Compander : 0); + // TX compressor + BK4819_SetCompander((gRxVfo->Modulation == MODULATION_FM && (gRxVfo->Compander == 1 || gRxVfo->Compander >= 3)) ? gRxVfo->Compander : 0); - BK4819_PrepareTransmit(); + BK4819_PrepareTransmit(); - SYSTEM_DelayMs(10); + SYSTEM_DelayMs(10); - BK4819_PickRXFilterPathBasedOnFrequency(gCurrentVfo->pTX->Frequency); + BK4819_PickRXFilterPathBasedOnFrequency(gCurrentVfo->pTX->Frequency); - BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, true); + BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, true); - SYSTEM_DelayMs(5); + SYSTEM_DelayMs(5); - BK4819_SetupPowerAmplifier(gCurrentVfo->TXP_CalculatedSetting, gCurrentVfo->pTX->Frequency); + BK4819_SetupPowerAmplifier(gCurrentVfo->TXP_CalculatedSetting, gCurrentVfo->pTX->Frequency); - SYSTEM_DelayMs(10); + SYSTEM_DelayMs(10); - switch (gCurrentVfo->pTX->CodeType) - { - default: - case CODE_TYPE_OFF: - BK4819_ExitSubAu(); - break; + switch (gCurrentVfo->pTX->CodeType) + { + default: + case CODE_TYPE_OFF: + BK4819_ExitSubAu(); + break; - case CODE_TYPE_CONTINUOUS_TONE: - BK4819_SetCTCSSFrequency(CTCSS_Options[gCurrentVfo->pTX->Code]); - break; + case CODE_TYPE_CONTINUOUS_TONE: + BK4819_SetCTCSSFrequency(CTCSS_Options[gCurrentVfo->pTX->Code]); + break; - case CODE_TYPE_DIGITAL: - case CODE_TYPE_REVERSE_DIGITAL: - BK4819_SetCDCSSCodeWord(DCS_GetGolayCodeWord(gCurrentVfo->pTX->CodeType, gCurrentVfo->pTX->Code)); - break; - } + case CODE_TYPE_DIGITAL: + case CODE_TYPE_REVERSE_DIGITAL: + BK4819_SetCDCSSCodeWord(DCS_GetGolayCodeWord(gCurrentVfo->pTX->CodeType, gCurrentVfo->pTX->Code)); + break; + } } void RADIO_SetModulation(ModulationMode_t modulation) { - BK4819_AF_Type_t mod; - switch(modulation) { - default: - case MODULATION_FM: - mod = BK4819_AF_FM; - break; - case MODULATION_AM: - mod = BK4819_AF_AM; - break; - case MODULATION_USB: - mod = BK4819_AF_BASEBAND2; - break; + BK4819_AF_Type_t mod; + switch(modulation) { + default: + case MODULATION_FM: + mod = BK4819_AF_FM; + break; + case MODULATION_AM: + mod = BK4819_AF_AM; + break; + case MODULATION_USB: + mod = BK4819_AF_BASEBAND2; + break; #ifdef ENABLE_BYP_RAW_DEMODULATORS - case MODULATION_BYP: - mod = BK4819_AF_UNKNOWN3; - break; - case MODULATION_RAW: - mod = BK4819_AF_BASEBAND1; - break; + case MODULATION_BYP: + mod = BK4819_AF_UNKNOWN3; + break; + case MODULATION_RAW: + mod = BK4819_AF_BASEBAND1; + break; #endif - } + } - BK4819_SetAF(mod); + BK4819_SetAF(mod); - BK4819_SetRegValue(afDacGainRegSpec, 0xF); - BK4819_WriteRegister(BK4819_REG_3D, modulation == MODULATION_USB ? 0 : 0x2AAB); - BK4819_SetRegValue(afcDisableRegSpec, modulation != MODULATION_FM); + BK4819_SetRegValue(afDacGainRegSpec, 0xF); + BK4819_WriteRegister(BK4819_REG_3D, modulation == MODULATION_USB ? 0 : 0x2AAB); + BK4819_SetRegValue(afcDisableRegSpec, modulation != MODULATION_FM); - RADIO_SetupAGC(modulation == MODULATION_AM, false); + RADIO_SetupAGC(modulation == MODULATION_AM, false); } void RADIO_SetupAGC(bool listeningAM, bool disable) { - static uint8_t lastSettings; - uint8_t newSettings = (listeningAM << 1) | (disable << 1); - if(lastSettings == newSettings) - return; - lastSettings = newSettings; + static uint8_t lastSettings; + uint8_t newSettings = (listeningAM << 1) | (disable << 1); + if(lastSettings == newSettings) + return; + lastSettings = newSettings; - if(!listeningAM) { // if not actively listening AM we don't need any AM specific regulation - BK4819_SetAGC(!disable); - BK4819_InitAGC(false); - } - else { + if(!listeningAM) { // if not actively listening AM we don't need any AM specific regulation + BK4819_SetAGC(!disable); + BK4819_InitAGC(false); + } + else { #ifdef ENABLE_AM_FIX - if(gSetting_AM_fix) { // if AM fix active lock AGC so AM-fix can do it's job - BK4819_SetAGC(0); - AM_fix_enable(!disable); - } - else + if(gSetting_AM_fix) { // if AM fix active lock AGC so AM-fix can do it's job + BK4819_SetAGC(0); + AM_fix_enable(!disable); + } + else #endif - { - BK4819_SetAGC(!disable); - BK4819_InitAGC(true); - } - } + { + BK4819_SetAGC(!disable); + BK4819_InitAGC(true); + } + } } void RADIO_SetVfoState(VfoState_t State) { - if (State == VFO_STATE_NORMAL) { - VfoState[0] = VFO_STATE_NORMAL; - VfoState[1] = VFO_STATE_NORMAL; - } else if (State == VFO_STATE_VOLTAGE_HIGH) { - VfoState[0] = VFO_STATE_VOLTAGE_HIGH; - VfoState[1] = VFO_STATE_TX_DISABLE; - } else { - // 1of11 - const unsigned int vfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO; - VfoState[vfo] = State; - } + if (State == VFO_STATE_NORMAL) { + VfoState[0] = VFO_STATE_NORMAL; + VfoState[1] = VFO_STATE_NORMAL; + } else if (State == VFO_STATE_VOLTAGE_HIGH) { + VfoState[0] = VFO_STATE_VOLTAGE_HIGH; + VfoState[1] = VFO_STATE_TX_DISABLE; + } else { + // 1of11 + const unsigned int vfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO; + VfoState[vfo] = State; + } - gVFOStateResumeCountdown_500ms = (State == VFO_STATE_NORMAL) ? 0 : vfo_state_resume_countdown_500ms; - gUpdateDisplay = true; + gVFOStateResumeCountdown_500ms = (State == VFO_STATE_NORMAL) ? 0 : vfo_state_resume_countdown_500ms; + gUpdateDisplay = true; } void RADIO_PrepareTX(void) { - VfoState_t State = VFO_STATE_NORMAL; // default to OK to TX + VfoState_t State = VFO_STATE_NORMAL; // default to OK to TX - if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) - { // dual-RX is enabled + if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + { // dual-RX is enabled - gDualWatchCountdown_10ms = dual_watch_count_after_tx_10ms; - gScheduleDualWatch = false; + gDualWatchCountdown_10ms = dual_watch_count_after_tx_10ms; + gScheduleDualWatch = false; - if (!gRxVfoIsActive) - { // use the current RX vfo - gEeprom.RX_VFO = gEeprom.TX_VFO; - gRxVfo = gTxVfo; - gRxVfoIsActive = true; - } + if (!gRxVfoIsActive) + { // use the current RX vfo + gEeprom.RX_VFO = gEeprom.TX_VFO; + gRxVfo = gTxVfo; + gRxVfoIsActive = true; + } - // let the user see that DW is not active - gDualWatchActive = false; - gUpdateStatus = true; - } + // let the user see that DW is not active + gDualWatchActive = false; + gUpdateStatus = true; + } - RADIO_SelectCurrentVfo(); + RADIO_SelectCurrentVfo(); #ifdef ENABLE_FEAT_F4HWN - if(TX_freq_check(gCurrentVfo->pTX->Frequency) != 0 && gCurrentVfo->TX_LOCK == true - #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) - && gAlarmState != ALARM_STATE_SITE_ALARM - #endif + if(TX_freq_check(gCurrentVfo->pTX->Frequency) != 0 && gCurrentVfo->TX_LOCK == true + #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) + && gAlarmState != ALARM_STATE_SITE_ALARM + #endif #else - if(TX_freq_check(gCurrentVfo->pTX->Frequency) != 0 - #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) - && gAlarmState != ALARM_STATE_SITE_ALARM - #endif + if(TX_freq_check(gCurrentVfo->pTX->Frequency) != 0 + #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) + && gAlarmState != ALARM_STATE_SITE_ALARM + #endif #endif - ){ - // TX frequency not allowed - State = VFO_STATE_TX_DISABLE; - gVfoConfigureMode = VFO_CONFIGURE; - } else if (SerialConfigInProgress()) { - // TX is disabled or config upload/download in progress - State = VFO_STATE_TX_DISABLE; - } else if (gCurrentVfo->BUSY_CHANNEL_LOCK && gCurrentFunction == FUNCTION_RECEIVE) { - // busy RX'ing a station - State = VFO_STATE_BUSY; - } else if (gBatteryDisplayLevel == 0) { - // charge your battery !git co - State = VFO_STATE_BAT_LOW; - } else if (gBatteryDisplayLevel > 6) { - // over voltage .. this is being a pain - State = VFO_STATE_VOLTAGE_HIGH; - } + ){ + // TX frequency not allowed + State = VFO_STATE_TX_DISABLE; + gVfoConfigureMode = VFO_CONFIGURE; + } else if (SerialConfigInProgress()) { + // TX is disabled or config upload/download in progress + State = VFO_STATE_TX_DISABLE; + } else if (gCurrentVfo->BUSY_CHANNEL_LOCK && gCurrentFunction == FUNCTION_RECEIVE) { + // busy RX'ing a station + State = VFO_STATE_BUSY; + } else if (gBatteryDisplayLevel == 0) { + // charge your battery !git co + State = VFO_STATE_BAT_LOW; + } else if (gBatteryDisplayLevel > 6) { + // over voltage .. this is being a pain + State = VFO_STATE_VOLTAGE_HIGH; + } #ifndef ENABLE_TX_WHEN_AM - else if (gCurrentVfo->Modulation != MODULATION_FM) { - // not allowed to TX if in AM mode - State = VFO_STATE_TX_DISABLE; - } + else if (gCurrentVfo->Modulation != MODULATION_FM) { + // not allowed to TX if in AM mode + State = VFO_STATE_TX_DISABLE; + } #endif - if (State != VFO_STATE_NORMAL) { - // TX not allowed - RADIO_SetVfoState(State); + if (State != VFO_STATE_NORMAL) { + // TX not allowed + RADIO_SetVfoState(State); #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) - gAlarmState = ALARM_STATE_OFF; + gAlarmState = ALARM_STATE_OFF; #endif #ifdef ENABLE_DTMF_CALLING - gDTMF_ReplyState = DTMF_REPLY_NONE; + gDTMF_ReplyState = DTMF_REPLY_NONE; #endif - AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL); - return; - } + AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL); + return; + } - // TX is allowed + // TX is allowed #ifdef ENABLE_DTMF_CALLING - if (gDTMF_ReplyState == DTMF_REPLY_ANI) - { - gDTMF_IsTx = gDTMF_CallMode == DTMF_CALL_MODE_DTMF; + if (gDTMF_ReplyState == DTMF_REPLY_ANI) + { + gDTMF_IsTx = gDTMF_CallMode == DTMF_CALL_MODE_DTMF; - if (gDTMF_IsTx) { - gDTMF_CallState = DTMF_CALL_STATE_NONE; - gDTMF_TxStopCountdown_500ms = DTMF_txstop_countdown_500ms; - } else { - gDTMF_CallState = DTMF_CALL_STATE_CALL_OUT; - } - } + if (gDTMF_IsTx) { + gDTMF_CallState = DTMF_CALL_STATE_NONE; + gDTMF_TxStopCountdown_500ms = DTMF_txstop_countdown_500ms; + } else { + gDTMF_CallState = DTMF_CALL_STATE_CALL_OUT; + } + } #endif - FUNCTION_Select(FUNCTION_TRANSMIT); + FUNCTION_Select(FUNCTION_TRANSMIT); - gTxTimerCountdown_500ms = 0; // no timeout + gTxTimerCountdown_500ms = 0; // no timeout - #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) - if (gAlarmState == ALARM_STATE_OFF) - #endif - { + #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) + if (gAlarmState == ALARM_STATE_OFF) + #endif + { - gTxTimerCountdown_500ms = ((gEeprom.TX_TIMEOUT_TIMER + 1) * 5) * 2; + gTxTimerCountdown_500ms = ((gEeprom.TX_TIMEOUT_TIMER + 1) * 5) * 2; - /* - if (gEeprom.TX_TIMEOUT_TIMER == 0) - gTxTimerCountdown_500ms = 60; // 30 sec - else if (gEeprom.TX_TIMEOUT_TIMER < (ARRAY_SIZE(gSubMenu_TOT) - 1)) - gTxTimerCountdown_500ms = 120 * gEeprom.TX_TIMEOUT_TIMER; // minutes - else - gTxTimerCountdown_500ms = 120 * 15; // 15 minutes - */ + /* + if (gEeprom.TX_TIMEOUT_TIMER == 0) + gTxTimerCountdown_500ms = 60; // 30 sec + else if (gEeprom.TX_TIMEOUT_TIMER < (ARRAY_SIZE(gSubMenu_TOT) - 1)) + gTxTimerCountdown_500ms = 120 * gEeprom.TX_TIMEOUT_TIMER; // minutes + else + gTxTimerCountdown_500ms = 120 * 15; // 15 minutes + */ #ifdef ENABLE_FEAT_F4HWN - gTxTimerCountdownAlert_500ms = gTxTimerCountdown_500ms; + gTxTimerCountdownAlert_500ms = gTxTimerCountdown_500ms; #endif - } + } - gTxTimeoutReached = false; + gTxTimeoutReached = false; #ifdef ENABLE_FEAT_F4HWN - gTxTimeoutReachedAlert = false; + gTxTimeoutReachedAlert = false; #endif - - gFlagEndTransmission = false; - gRTTECountdown_10ms = 0; + + gFlagEndTransmission = false; + gRTTECountdown_10ms = 0; #ifdef ENABLE_DTMF_CALLING - gDTMF_ReplyState = DTMF_REPLY_NONE; + gDTMF_ReplyState = DTMF_REPLY_NONE; #endif } void RADIO_SendCssTail(void) { - switch (gCurrentVfo->pTX->CodeType) { - case CODE_TYPE_DIGITAL: - case CODE_TYPE_REVERSE_DIGITAL: - BK4819_PlayCDCSSTail(); - break; - default: - BK4819_PlayCTCSSTail(); - break; - } + switch (gCurrentVfo->pTX->CodeType) { + case CODE_TYPE_DIGITAL: + case CODE_TYPE_REVERSE_DIGITAL: + BK4819_PlayCDCSSTail(); + break; + default: + BK4819_PlayCTCSSTail(); + break; + } - SYSTEM_DelayMs(200); + SYSTEM_DelayMs(200); } void RADIO_SendEndOfTransmission(void) { - BK4819_PlayRoger(); - DTMF_SendEndOfTransmission(); + BK4819_PlayRoger(); + DTMF_SendEndOfTransmission(); - // send the CTCSS/DCS tail tone - allows the receivers to mute the usual FM squelch tail/crash - if(gEeprom.TAIL_TONE_ELIMINATION) - RADIO_SendCssTail(); - RADIO_SetupRegisters(false); + // send the CTCSS/DCS tail tone - allows the receivers to mute the usual FM squelch tail/crash + if(gEeprom.TAIL_TONE_ELIMINATION) + RADIO_SendCssTail(); + RADIO_SetupRegisters(false); } void RADIO_PrepareCssTX(void) { - RADIO_PrepareTX(); + RADIO_PrepareTX(); - SYSTEM_DelayMs(200); + SYSTEM_DelayMs(200); - if(gEeprom.TAIL_TONE_ELIMINATION) - RADIO_SendCssTail(); - RADIO_SetupRegisters(true); + if(gEeprom.TAIL_TONE_ELIMINATION) + RADIO_SendCssTail(); + RADIO_SetupRegisters(true); } diff --git a/radio.h b/radio.h index 5320973..19f5b8b 100644 --- a/radio.h +++ b/radio.h @@ -24,114 +24,114 @@ #include "frequencies.h" enum { - RADIO_CHANNEL_UP = 0x01u, - RADIO_CHANNEL_DOWN = 0xFFu, + RADIO_CHANNEL_UP = 0x01u, + RADIO_CHANNEL_DOWN = 0xFFu, }; enum { - BANDWIDTH_WIDE = 0, - BANDWIDTH_NARROW + BANDWIDTH_WIDE = 0, + BANDWIDTH_NARROW }; enum PTT_ID_t { - PTT_ID_OFF = 0, // OFF - PTT_ID_TX_UP, // BEGIN OF TX - PTT_ID_TX_DOWN, // END OF TX - PTT_ID_BOTH, // BOTH - PTT_ID_APOLLO // Apolo quindar tones + PTT_ID_OFF = 0, // OFF + PTT_ID_TX_UP, // BEGIN OF TX + PTT_ID_TX_DOWN, // END OF TX + PTT_ID_BOTH, // BOTH + PTT_ID_APOLLO // Apolo quindar tones }; typedef enum PTT_ID_t PTT_ID_t; enum VfoState_t { - VFO_STATE_NORMAL = 0, - VFO_STATE_BUSY, - VFO_STATE_BAT_LOW, - VFO_STATE_TX_DISABLE, - VFO_STATE_TIMEOUT, - VFO_STATE_ALARM, - VFO_STATE_VOLTAGE_HIGH, - _VFO_STATE_LAST_ELEMENT + VFO_STATE_NORMAL = 0, + VFO_STATE_BUSY, + VFO_STATE_BAT_LOW, + VFO_STATE_TX_DISABLE, + VFO_STATE_TIMEOUT, + VFO_STATE_ALARM, + VFO_STATE_VOLTAGE_HIGH, + _VFO_STATE_LAST_ELEMENT }; typedef enum VfoState_t VfoState_t; typedef enum { - MODULATION_FM, - MODULATION_AM, - MODULATION_USB, + MODULATION_FM, + MODULATION_AM, + MODULATION_USB, #ifdef ENABLE_BYP_RAW_DEMODULATORS - MODULATION_BYP, - MODULATION_RAW, + MODULATION_BYP, + MODULATION_RAW, #endif - MODULATION_UKNOWN + MODULATION_UKNOWN } ModulationMode_t; extern const char gModulationStr[MODULATION_UKNOWN][4]; typedef struct { - uint32_t Frequency; - DCS_CodeType_t CodeType; - uint8_t Code; - uint8_t Padding[2]; + uint32_t Frequency; + DCS_CodeType_t CodeType; + uint8_t Code; + uint8_t Padding[2]; } FREQ_Config_t; typedef struct VFO_Info_t { - FREQ_Config_t freq_config_RX; - FREQ_Config_t freq_config_TX; + FREQ_Config_t freq_config_RX; + FREQ_Config_t freq_config_TX; - // this is for a purpose of the FrequencyReverse function - // it points to freq_config_RX normally and to freq_config_TX if reverse function is active - // - FREQ_Config_t *pRX; + // this is for a purpose of the FrequencyReverse function + // it points to freq_config_RX normally and to freq_config_TX if reverse function is active + // + FREQ_Config_t *pRX; - // this is for a purpose of the FrequencyReverse function - // it points to freq_config_TX normally and to freq_config_RX if reverse function is active - FREQ_Config_t *pTX; + // this is for a purpose of the FrequencyReverse function + // it points to freq_config_TX normally and to freq_config_RX if reverse function is active + FREQ_Config_t *pTX; - uint32_t TX_OFFSET_FREQUENCY; - uint16_t StepFrequency; + uint32_t TX_OFFSET_FREQUENCY; + uint16_t StepFrequency; - uint8_t CHANNEL_SAVE; + uint8_t CHANNEL_SAVE; - uint8_t TX_OFFSET_FREQUENCY_DIRECTION; + uint8_t TX_OFFSET_FREQUENCY_DIRECTION; - uint8_t SquelchOpenRSSIThresh; - uint8_t SquelchOpenNoiseThresh; - uint8_t SquelchCloseGlitchThresh; - uint8_t SquelchCloseRSSIThresh; - uint8_t SquelchCloseNoiseThresh; - uint8_t SquelchOpenGlitchThresh; + uint8_t SquelchOpenRSSIThresh; + uint8_t SquelchOpenNoiseThresh; + uint8_t SquelchCloseGlitchThresh; + uint8_t SquelchCloseRSSIThresh; + uint8_t SquelchCloseNoiseThresh; + uint8_t SquelchOpenGlitchThresh; - STEP_Setting_t STEP_SETTING; - uint8_t TX_LOCK; - uint8_t OUTPUT_POWER; - uint8_t TXP_CalculatedSetting; - bool FrequencyReverse; + STEP_Setting_t STEP_SETTING; + uint8_t TX_LOCK; + uint8_t OUTPUT_POWER; + uint8_t TXP_CalculatedSetting; + bool FrequencyReverse; - uint8_t SCRAMBLING_TYPE; - uint8_t CHANNEL_BANDWIDTH; + uint8_t SCRAMBLING_TYPE; + uint8_t CHANNEL_BANDWIDTH; - uint8_t SCANLIST1_PARTICIPATION; - uint8_t SCANLIST2_PARTICIPATION; - uint8_t SCANLIST3_PARTICIPATION; + uint8_t SCANLIST1_PARTICIPATION; + uint8_t SCANLIST2_PARTICIPATION; + uint8_t SCANLIST3_PARTICIPATION; - uint8_t Band; + uint8_t Band; #ifdef ENABLE_DTMF_CALLING - uint8_t DTMF_DECODING_ENABLE; + uint8_t DTMF_DECODING_ENABLE; #endif - PTT_ID_t DTMF_PTT_ID_TX_MODE; + PTT_ID_t DTMF_PTT_ID_TX_MODE; - uint8_t BUSY_CHANNEL_LOCK; + uint8_t BUSY_CHANNEL_LOCK; - ModulationMode_t Modulation; + ModulationMode_t Modulation; - uint8_t Compander; + uint8_t Compander; - char Name[16]; + char Name[16]; } VFO_Info_t; // Settings of the main VFO that is selected by the user @@ -159,10 +159,10 @@ void RADIO_ApplyOffset(VFO_Info_t *pInfo); void RADIO_SelectVfos(void); void RADIO_SetupRegisters(bool switchToForeground); #ifdef ENABLE_NOAA - void RADIO_ConfigureNOAA(void); + void RADIO_ConfigureNOAA(void); #endif void RADIO_SetTxParameters(void); -void RADIO_SetupAGC(bool listeningAM, bool disable); +void RADIO_SetupAGC(bool listeningAM, bool disable); void RADIO_SetModulation(ModulationMode_t modulation); void RADIO_SetVfoState(VfoState_t State); void RADIO_PrepareTX(void); diff --git a/scheduler.c b/scheduler.c index 0c4e2a3..bc4ee5c 100644 --- a/scheduler.c +++ b/scheduler.c @@ -16,7 +16,7 @@ #include "app/chFrScanner.h" #ifdef ENABLE_FMRADIO - #include "app/fm.h" + #include "app/fm.h" #endif #include "app/scanner.h" #include "audio.h" @@ -30,17 +30,17 @@ #include "driver/gpio.h" #define DECREMENT(cnt) \ - do { \ - if (cnt > 0) \ - cnt--; \ - } while (0) + do { \ + if (cnt > 0) \ + cnt--; \ + } while (0) #define DECREMENT_AND_TRIGGER(cnt, flag) \ - do { \ - if (cnt > 0) \ - if (--cnt == 0) \ - flag = true; \ - } while (0) + do { \ + if (cnt > 0) \ + if (--cnt == 0) \ + flag = true; \ + } while (0) static volatile uint32_t gGlobalSysTickCounter; @@ -49,71 +49,71 @@ void SystickHandler(void); // we come here every 10ms void SystickHandler(void) { - gGlobalSysTickCounter++; - - gNextTimeslice = true; + gGlobalSysTickCounter++; + + gNextTimeslice = true; - if ((gGlobalSysTickCounter % 50) == 0) { - gNextTimeslice_500ms = true; + if ((gGlobalSysTickCounter % 50) == 0) { + gNextTimeslice_500ms = true; #ifdef ENABLE_FEAT_F4HWN - DECREMENT_AND_TRIGGER(gTxTimerCountdownAlert_500ms - ALERT_TOT * 2, gTxTimeoutReachedAlert); - #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER - DECREMENT(gRxTimerCountdown_500ms); - #endif + DECREMENT_AND_TRIGGER(gTxTimerCountdownAlert_500ms - ALERT_TOT * 2, gTxTimeoutReachedAlert); + #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER + DECREMENT(gRxTimerCountdown_500ms); + #endif #endif - - DECREMENT_AND_TRIGGER(gTxTimerCountdown_500ms, gTxTimeoutReached); - DECREMENT(gSerialConfigCountDown_500ms); - } + + DECREMENT_AND_TRIGGER(gTxTimerCountdown_500ms, gTxTimeoutReached); + DECREMENT(gSerialConfigCountDown_500ms); + } - if ((gGlobalSysTickCounter & 3) == 0) - gNextTimeslice40ms = true; + if ((gGlobalSysTickCounter & 3) == 0) + gNextTimeslice40ms = true; #ifdef ENABLE_NOAA - DECREMENT(gNOAACountdown_10ms); + DECREMENT(gNOAACountdown_10ms); #endif - DECREMENT(gFoundCDCSSCountdown_10ms); + DECREMENT(gFoundCDCSSCountdown_10ms); - DECREMENT(gFoundCTCSSCountdown_10ms); + DECREMENT(gFoundCTCSSCountdown_10ms); - if (gCurrentFunction == FUNCTION_FOREGROUND) - DECREMENT_AND_TRIGGER(gBatterySaveCountdown_10ms, gSchedulePowerSave); + if (gCurrentFunction == FUNCTION_FOREGROUND) + DECREMENT_AND_TRIGGER(gBatterySaveCountdown_10ms, gSchedulePowerSave); - if (gCurrentFunction == FUNCTION_POWER_SAVE) - DECREMENT_AND_TRIGGER(gPowerSave_10ms, gPowerSaveCountdownExpired); + if (gCurrentFunction == FUNCTION_POWER_SAVE) + DECREMENT_AND_TRIGGER(gPowerSave_10ms, gPowerSaveCountdownExpired); - if (gScanStateDir == SCAN_OFF && !gCssBackgroundScan && gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) - if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_RECEIVE) - DECREMENT_AND_TRIGGER(gDualWatchCountdown_10ms, gScheduleDualWatch); + if (gScanStateDir == SCAN_OFF && !gCssBackgroundScan && gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_RECEIVE) + DECREMENT_AND_TRIGGER(gDualWatchCountdown_10ms, gScheduleDualWatch); #ifdef ENABLE_NOAA - if (gScanStateDir == SCAN_OFF && !gCssBackgroundScan && gEeprom.DUAL_WATCH == DUAL_WATCH_OFF) - if (gIsNoaaMode && gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT) - if (gCurrentFunction != FUNCTION_RECEIVE) - DECREMENT_AND_TRIGGER(gNOAA_Countdown_10ms, gScheduleNOAA); + if (gScanStateDir == SCAN_OFF && !gCssBackgroundScan && gEeprom.DUAL_WATCH == DUAL_WATCH_OFF) + if (gIsNoaaMode && gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT) + if (gCurrentFunction != FUNCTION_RECEIVE) + DECREMENT_AND_TRIGGER(gNOAA_Countdown_10ms, gScheduleNOAA); #endif - if (gScanStateDir != SCAN_OFF) - if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT) - DECREMENT_AND_TRIGGER(gScanPauseDelayIn_10ms, gScheduleScanListen); + if (gScanStateDir != SCAN_OFF) + if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT) + DECREMENT_AND_TRIGGER(gScanPauseDelayIn_10ms, gScheduleScanListen); - DECREMENT_AND_TRIGGER(gTailNoteEliminationCountdown_10ms, gFlagTailNoteEliminationComplete); + DECREMENT_AND_TRIGGER(gTailNoteEliminationCountdown_10ms, gFlagTailNoteEliminationComplete); #ifdef ENABLE_VOICE - DECREMENT_AND_TRIGGER(gCountdownToPlayNextVoice_10ms, gFlagPlayQueuedVoice); + DECREMENT_AND_TRIGGER(gCountdownToPlayNextVoice_10ms, gFlagPlayQueuedVoice); #endif #ifdef ENABLE_FMRADIO - if (gFM_ScanState != FM_SCAN_OFF && gCurrentFunction != FUNCTION_MONITOR) - if (gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_RECEIVE) - DECREMENT_AND_TRIGGER(gFmPlayCountdown_10ms, gScheduleFM); + if (gFM_ScanState != FM_SCAN_OFF && gCurrentFunction != FUNCTION_MONITOR) + if (gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_RECEIVE) + DECREMENT_AND_TRIGGER(gFmPlayCountdown_10ms, gScheduleFM); #endif #ifdef ENABLE_VOX - DECREMENT(gVoxStopCountdown_10ms); + DECREMENT(gVoxStopCountdown_10ms); #endif - DECREMENT(boot_counter_10ms); + DECREMENT(boot_counter_10ms); } diff --git a/screenshot.h b/screenshot.h index abc2fd9..64d31ed 100644 --- a/screenshot.h +++ b/screenshot.h @@ -19,33 +19,33 @@ static inline void getScreenShot(void) { - char str[2] = ""; + char str[2] = ""; - LogUart("P1\n"); - LogUart("128 64\n"); + LogUart("P1\n"); + LogUart("128 64\n"); - for(uint8_t b = 0; b < 8; b++) - { - for(uint8_t i = 0; i < 128; i++) - { - sprintf(str, "%d ", ((gStatusLine[i] >> b) & 0x01)); - LogUart(str); - } - LogUart("\n"); - } + for(uint8_t b = 0; b < 8; b++) + { + for(uint8_t i = 0; i < 128; i++) + { + sprintf(str, "%d ", ((gStatusLine[i] >> b) & 0x01)); + LogUart(str); + } + LogUart("\n"); + } - for(uint8_t l = 0; l < 7; l++) - { - for(uint8_t b = 0; b < 8; b++) - { - for(uint8_t i = 0; i < 128; i++) - { - sprintf(str, "%d ", ((gFrameBuffer[l][i] >> b) & 0x01)); - LogUart(str); - } - } - LogUart("\n"); - } + for(uint8_t l = 0; l < 7; l++) + { + for(uint8_t b = 0; b < 8; b++) + { + for(uint8_t i = 0; i < 128; i++) + { + sprintf(str, "%d ", ((gFrameBuffer[l][i] >> b) & 0x01)); + LogUart(str); + } + } + LogUart("\n"); + } - LogUart("\n----------------\n"); + LogUart("\n----------------\n"); } \ No newline at end of file diff --git a/settings.c b/settings.c index 298ae4d..2211a77 100644 --- a/settings.c +++ b/settings.c @@ -18,7 +18,7 @@ #include "app/dtmf.h" #ifdef ENABLE_FMRADIO - #include "app/fm.h" + #include "app/fm.h" #endif #include "driver/bk1080.h" #include "driver/bk4819.h" @@ -29,870 +29,870 @@ static const uint32_t gDefaultFrequencyTable[] = { - 14500000, // - 14550000, // - 43300000, // - 43320000, // - 43350000 // + 14500000, // + 14550000, // + 43300000, // + 43320000, // + 43350000 // }; EEPROM_Config_t gEeprom = { 0 }; void SETTINGS_InitEEPROM(void) { - uint8_t Data[16] = {0}; - // 0E70..0E77 - EEPROM_ReadBuffer(0x0E70, Data, 8); - gEeprom.CHAN_1_CALL = IS_MR_CHANNEL(Data[0]) ? Data[0] : MR_CHANNEL_FIRST; - gEeprom.SQUELCH_LEVEL = (Data[1] < 10) ? Data[1] : 1; - gEeprom.TX_TIMEOUT_TIMER = (Data[2] > 4 && Data[2] < 180) ? Data[2] : 11; - #ifdef ENABLE_NOAA - gEeprom.NOAA_AUTO_SCAN = (Data[3] < 2) ? Data[3] : false; - #endif - gEeprom.KEY_LOCK = (Data[4] < 2) ? Data[4] : false; - #ifdef ENABLE_VOX - gEeprom.VOX_SWITCH = (Data[5] < 2) ? Data[5] : false; - gEeprom.VOX_LEVEL = (Data[6] < 10) ? Data[6] : 1; - #endif - gEeprom.MIC_SENSITIVITY = (Data[7] < 5) ? Data[7] : 4; + uint8_t Data[16] = {0}; + // 0E70..0E77 + EEPROM_ReadBuffer(0x0E70, Data, 8); + gEeprom.CHAN_1_CALL = IS_MR_CHANNEL(Data[0]) ? Data[0] : MR_CHANNEL_FIRST; + gEeprom.SQUELCH_LEVEL = (Data[1] < 10) ? Data[1] : 1; + gEeprom.TX_TIMEOUT_TIMER = (Data[2] > 4 && Data[2] < 180) ? Data[2] : 11; + #ifdef ENABLE_NOAA + gEeprom.NOAA_AUTO_SCAN = (Data[3] < 2) ? Data[3] : false; + #endif + gEeprom.KEY_LOCK = (Data[4] < 2) ? Data[4] : false; + #ifdef ENABLE_VOX + gEeprom.VOX_SWITCH = (Data[5] < 2) ? Data[5] : false; + gEeprom.VOX_LEVEL = (Data[6] < 10) ? Data[6] : 1; + #endif + gEeprom.MIC_SENSITIVITY = (Data[7] < 5) ? Data[7] : 4; - // 0E78..0E7F - EEPROM_ReadBuffer(0x0E78, Data, 8); - gEeprom.BACKLIGHT_MAX = (Data[0] & 0xF) <= 10 ? (Data[0] & 0xF) : 10; - gEeprom.BACKLIGHT_MIN = (Data[0] >> 4) < gEeprom.BACKLIGHT_MAX ? (Data[0] >> 4) : 0; + // 0E78..0E7F + EEPROM_ReadBuffer(0x0E78, Data, 8); + gEeprom.BACKLIGHT_MAX = (Data[0] & 0xF) <= 10 ? (Data[0] & 0xF) : 10; + gEeprom.BACKLIGHT_MIN = (Data[0] >> 4) < gEeprom.BACKLIGHT_MAX ? (Data[0] >> 4) : 0; #ifdef ENABLE_BLMIN_TMP_OFF - gEeprom.BACKLIGHT_MIN_STAT = BLMIN_STAT_ON; + gEeprom.BACKLIGHT_MIN_STAT = BLMIN_STAT_ON; #endif - gEeprom.CHANNEL_DISPLAY_MODE = (Data[1] < 4) ? Data[1] : MDF_FREQUENCY; // 4 instead of 3 - extra display mode - gEeprom.CROSS_BAND_RX_TX = (Data[2] < 3) ? Data[2] : CROSS_BAND_OFF; - gEeprom.BATTERY_SAVE = (Data[3] < 5) ? Data[3] : 4; - gEeprom.DUAL_WATCH = (Data[4] < 3) ? Data[4] : DUAL_WATCH_CHAN_A; - gEeprom.BACKLIGHT_TIME = (Data[5] < 62) ? Data[5] : 12; - gEeprom.TAIL_TONE_ELIMINATION = (Data[6] < 2) ? Data[6] : false; - gEeprom.VFO_OPEN = (Data[7] < 2) ? Data[7] : true; + gEeprom.CHANNEL_DISPLAY_MODE = (Data[1] < 4) ? Data[1] : MDF_FREQUENCY; // 4 instead of 3 - extra display mode + gEeprom.CROSS_BAND_RX_TX = (Data[2] < 3) ? Data[2] : CROSS_BAND_OFF; + gEeprom.BATTERY_SAVE = (Data[3] < 5) ? Data[3] : 4; + gEeprom.DUAL_WATCH = (Data[4] < 3) ? Data[4] : DUAL_WATCH_CHAN_A; + gEeprom.BACKLIGHT_TIME = (Data[5] < 62) ? Data[5] : 12; + gEeprom.TAIL_TONE_ELIMINATION = (Data[6] < 2) ? Data[6] : false; + gEeprom.VFO_OPEN = (Data[7] < 2) ? Data[7] : true; - // 0E80..0E87 - EEPROM_ReadBuffer(0x0E80, Data, 8); - gEeprom.ScreenChannel[0] = IS_VALID_CHANNEL(Data[0]) ? Data[0] : (FREQ_CHANNEL_FIRST + BAND6_400MHz); - gEeprom.ScreenChannel[1] = IS_VALID_CHANNEL(Data[3]) ? Data[3] : (FREQ_CHANNEL_FIRST + BAND6_400MHz); - gEeprom.MrChannel[0] = IS_MR_CHANNEL(Data[1]) ? Data[1] : MR_CHANNEL_FIRST; - gEeprom.MrChannel[1] = IS_MR_CHANNEL(Data[4]) ? Data[4] : MR_CHANNEL_FIRST; - gEeprom.FreqChannel[0] = IS_FREQ_CHANNEL(Data[2]) ? Data[2] : (FREQ_CHANNEL_FIRST + BAND6_400MHz); - gEeprom.FreqChannel[1] = IS_FREQ_CHANNEL(Data[5]) ? Data[5] : (FREQ_CHANNEL_FIRST + BAND6_400MHz); + // 0E80..0E87 + EEPROM_ReadBuffer(0x0E80, Data, 8); + gEeprom.ScreenChannel[0] = IS_VALID_CHANNEL(Data[0]) ? Data[0] : (FREQ_CHANNEL_FIRST + BAND6_400MHz); + gEeprom.ScreenChannel[1] = IS_VALID_CHANNEL(Data[3]) ? Data[3] : (FREQ_CHANNEL_FIRST + BAND6_400MHz); + gEeprom.MrChannel[0] = IS_MR_CHANNEL(Data[1]) ? Data[1] : MR_CHANNEL_FIRST; + gEeprom.MrChannel[1] = IS_MR_CHANNEL(Data[4]) ? Data[4] : MR_CHANNEL_FIRST; + gEeprom.FreqChannel[0] = IS_FREQ_CHANNEL(Data[2]) ? Data[2] : (FREQ_CHANNEL_FIRST + BAND6_400MHz); + gEeprom.FreqChannel[1] = IS_FREQ_CHANNEL(Data[5]) ? Data[5] : (FREQ_CHANNEL_FIRST + BAND6_400MHz); #ifdef ENABLE_NOAA - gEeprom.NoaaChannel[0] = IS_NOAA_CHANNEL(Data[6]) ? Data[6] : NOAA_CHANNEL_FIRST; - gEeprom.NoaaChannel[1] = IS_NOAA_CHANNEL(Data[7]) ? Data[7] : NOAA_CHANNEL_FIRST; + gEeprom.NoaaChannel[0] = IS_NOAA_CHANNEL(Data[6]) ? Data[6] : NOAA_CHANNEL_FIRST; + gEeprom.NoaaChannel[1] = IS_NOAA_CHANNEL(Data[7]) ? Data[7] : NOAA_CHANNEL_FIRST; #endif #ifdef ENABLE_FMRADIO - { // 0E88..0E8F - struct - { - uint16_t selFreq; - uint8_t selChn; - uint8_t isMrMode:1; - uint8_t band:2; - //uint8_t space:2; - } __attribute__((packed)) fmCfg; - EEPROM_ReadBuffer(0x0E88, &fmCfg, 4); + { // 0E88..0E8F + struct + { + uint16_t selFreq; + uint8_t selChn; + uint8_t isMrMode:1; + uint8_t band:2; + //uint8_t space:2; + } __attribute__((packed)) fmCfg; + EEPROM_ReadBuffer(0x0E88, &fmCfg, 4); - gEeprom.FM_Band = fmCfg.band; - //gEeprom.FM_Space = fmCfg.space; - gEeprom.FM_SelectedFrequency = - (fmCfg.selFreq >= BK1080_GetFreqLoLimit(gEeprom.FM_Band) && fmCfg.selFreq <= BK1080_GetFreqHiLimit(gEeprom.FM_Band)) ? - fmCfg.selFreq : BK1080_GetFreqLoLimit(gEeprom.FM_Band); - - gEeprom.FM_SelectedChannel = fmCfg.selChn; - gEeprom.FM_IsMrMode = fmCfg.isMrMode; - } + gEeprom.FM_Band = fmCfg.band; + //gEeprom.FM_Space = fmCfg.space; + gEeprom.FM_SelectedFrequency = + (fmCfg.selFreq >= BK1080_GetFreqLoLimit(gEeprom.FM_Band) && fmCfg.selFreq <= BK1080_GetFreqHiLimit(gEeprom.FM_Band)) ? + fmCfg.selFreq : BK1080_GetFreqLoLimit(gEeprom.FM_Band); + + gEeprom.FM_SelectedChannel = fmCfg.selChn; + gEeprom.FM_IsMrMode = fmCfg.isMrMode; + } - // 0E40..0E67 - EEPROM_ReadBuffer(0x0E40, gFM_Channels, sizeof(gFM_Channels)); - FM_ConfigureChannelState(); + // 0E40..0E67 + EEPROM_ReadBuffer(0x0E40, gFM_Channels, sizeof(gFM_Channels)); + FM_ConfigureChannelState(); #endif - // 0E90..0E97 - EEPROM_ReadBuffer(0x0E90, Data, 8); - gEeprom.BEEP_CONTROL = Data[0] & 1; - gEeprom.KEY_M_LONG_PRESS_ACTION = ((Data[0] >> 1) < ACTION_OPT_LEN) ? (Data[0] >> 1) : ACTION_OPT_NONE; - gEeprom.KEY_1_SHORT_PRESS_ACTION = (Data[1] < ACTION_OPT_LEN) ? Data[1] : ACTION_OPT_MONITOR; - gEeprom.KEY_1_LONG_PRESS_ACTION = (Data[2] < ACTION_OPT_LEN) ? Data[2] : ACTION_OPT_NONE; - gEeprom.KEY_2_SHORT_PRESS_ACTION = (Data[3] < ACTION_OPT_LEN) ? Data[3] : ACTION_OPT_SCAN; - gEeprom.KEY_2_LONG_PRESS_ACTION = (Data[4] < ACTION_OPT_LEN) ? Data[4] : ACTION_OPT_NONE; - gEeprom.SCAN_RESUME_MODE = (Data[5] < 3) ? Data[5] : SCAN_RESUME_CO; - gEeprom.AUTO_KEYPAD_LOCK = (Data[6] < 2) ? Data[6] : false; + // 0E90..0E97 + EEPROM_ReadBuffer(0x0E90, Data, 8); + gEeprom.BEEP_CONTROL = Data[0] & 1; + gEeprom.KEY_M_LONG_PRESS_ACTION = ((Data[0] >> 1) < ACTION_OPT_LEN) ? (Data[0] >> 1) : ACTION_OPT_NONE; + gEeprom.KEY_1_SHORT_PRESS_ACTION = (Data[1] < ACTION_OPT_LEN) ? Data[1] : ACTION_OPT_MONITOR; + gEeprom.KEY_1_LONG_PRESS_ACTION = (Data[2] < ACTION_OPT_LEN) ? Data[2] : ACTION_OPT_NONE; + gEeprom.KEY_2_SHORT_PRESS_ACTION = (Data[3] < ACTION_OPT_LEN) ? Data[3] : ACTION_OPT_SCAN; + gEeprom.KEY_2_LONG_PRESS_ACTION = (Data[4] < ACTION_OPT_LEN) ? Data[4] : ACTION_OPT_NONE; + gEeprom.SCAN_RESUME_MODE = (Data[5] < 3) ? Data[5] : SCAN_RESUME_CO; + gEeprom.AUTO_KEYPAD_LOCK = (Data[6] < 2) ? Data[6] : false; #ifdef ENABLE_FEAT_F4HWN - gEeprom.POWER_ON_DISPLAY_MODE = (Data[7] < 6) ? Data[7] : POWER_ON_DISPLAY_MODE_VOLTAGE; + gEeprom.POWER_ON_DISPLAY_MODE = (Data[7] < 6) ? Data[7] : POWER_ON_DISPLAY_MODE_VOLTAGE; #else - gEeprom.POWER_ON_DISPLAY_MODE = (Data[7] < 4) ? Data[7] : POWER_ON_DISPLAY_MODE_VOLTAGE; + gEeprom.POWER_ON_DISPLAY_MODE = (Data[7] < 4) ? Data[7] : POWER_ON_DISPLAY_MODE_VOLTAGE; #endif - // 0E98..0E9F - #ifdef ENABLE_PWRON_PASSWORD - EEPROM_ReadBuffer(0x0E98, Data, 8); - memcpy(&gEeprom.POWER_ON_PASSWORD, Data, 4); - #endif + // 0E98..0E9F + #ifdef ENABLE_PWRON_PASSWORD + EEPROM_ReadBuffer(0x0E98, Data, 8); + memcpy(&gEeprom.POWER_ON_PASSWORD, Data, 4); + #endif - // 0EA0..0EA7 - EEPROM_ReadBuffer(0x0EA0, Data, 8); - #ifdef ENABLE_VOICE - gEeprom.VOICE_PROMPT = (Data[0] < 3) ? Data[0] : VOICE_PROMPT_ENGLISH; - #endif - #ifdef ENABLE_RSSI_BAR - if((Data[1] < 200 && Data[1] > 90) && (Data[2] < Data[1]-9 && Data[1] < 160 && Data[2] > 50)) { - gEeprom.S0_LEVEL = Data[1]; - gEeprom.S9_LEVEL = Data[2]; - } - else { - gEeprom.S0_LEVEL = 130; - gEeprom.S9_LEVEL = 76; - } - #endif + // 0EA0..0EA7 + EEPROM_ReadBuffer(0x0EA0, Data, 8); + #ifdef ENABLE_VOICE + gEeprom.VOICE_PROMPT = (Data[0] < 3) ? Data[0] : VOICE_PROMPT_ENGLISH; + #endif + #ifdef ENABLE_RSSI_BAR + if((Data[1] < 200 && Data[1] > 90) && (Data[2] < Data[1]-9 && Data[1] < 160 && Data[2] > 50)) { + gEeprom.S0_LEVEL = Data[1]; + gEeprom.S9_LEVEL = Data[2]; + } + else { + gEeprom.S0_LEVEL = 130; + gEeprom.S9_LEVEL = 76; + } + #endif - // 0EA8..0EAF - EEPROM_ReadBuffer(0x0EA8, Data, 8); - #ifdef ENABLE_ALARM - gEeprom.ALARM_MODE = (Data[0] < 2) ? Data[0] : true; - #endif - gEeprom.ROGER = (Data[1] < 3) ? Data[1] : ROGER_MODE_OFF; - gEeprom.REPEATER_TAIL_TONE_ELIMINATION = (Data[2] < 11) ? Data[2] : 0; - gEeprom.TX_VFO = (Data[3] < 2) ? Data[3] : 0; - gEeprom.BATTERY_TYPE = (Data[4] < BATTERY_TYPE_UNKNOWN) ? Data[4] : BATTERY_TYPE_1600_MAH; + // 0EA8..0EAF + EEPROM_ReadBuffer(0x0EA8, Data, 8); + #ifdef ENABLE_ALARM + gEeprom.ALARM_MODE = (Data[0] < 2) ? Data[0] : true; + #endif + gEeprom.ROGER = (Data[1] < 3) ? Data[1] : ROGER_MODE_OFF; + gEeprom.REPEATER_TAIL_TONE_ELIMINATION = (Data[2] < 11) ? Data[2] : 0; + gEeprom.TX_VFO = (Data[3] < 2) ? Data[3] : 0; + gEeprom.BATTERY_TYPE = (Data[4] < BATTERY_TYPE_UNKNOWN) ? Data[4] : BATTERY_TYPE_1600_MAH; - // 0ED0..0ED7 - EEPROM_ReadBuffer(0x0ED0, Data, 8); - gEeprom.DTMF_SIDE_TONE = (Data[0] < 2) ? Data[0] : true; + // 0ED0..0ED7 + EEPROM_ReadBuffer(0x0ED0, Data, 8); + gEeprom.DTMF_SIDE_TONE = (Data[0] < 2) ? Data[0] : true; #ifdef ENABLE_DTMF_CALLING - gEeprom.DTMF_SEPARATE_CODE = DTMF_ValidateCodes((char *)(Data + 1), 1) ? Data[1] : '*'; - gEeprom.DTMF_GROUP_CALL_CODE = DTMF_ValidateCodes((char *)(Data + 2), 1) ? Data[2] : '#'; - gEeprom.DTMF_DECODE_RESPONSE = (Data[3] < 4) ? Data[3] : 0; - gEeprom.DTMF_auto_reset_time = (Data[4] < 61) ? Data[4] : (Data[4] >= 5) ? Data[4] : 10; + gEeprom.DTMF_SEPARATE_CODE = DTMF_ValidateCodes((char *)(Data + 1), 1) ? Data[1] : '*'; + gEeprom.DTMF_GROUP_CALL_CODE = DTMF_ValidateCodes((char *)(Data + 2), 1) ? Data[2] : '#'; + gEeprom.DTMF_DECODE_RESPONSE = (Data[3] < 4) ? Data[3] : 0; + gEeprom.DTMF_auto_reset_time = (Data[4] < 61) ? Data[4] : (Data[4] >= 5) ? Data[4] : 10; #endif - gEeprom.DTMF_PRELOAD_TIME = (Data[5] < 101) ? Data[5] * 10 : 300; - gEeprom.DTMF_FIRST_CODE_PERSIST_TIME = (Data[6] < 101) ? Data[6] * 10 : 100; - gEeprom.DTMF_HASH_CODE_PERSIST_TIME = (Data[7] < 101) ? Data[7] * 10 : 100; + gEeprom.DTMF_PRELOAD_TIME = (Data[5] < 101) ? Data[5] * 10 : 300; + gEeprom.DTMF_FIRST_CODE_PERSIST_TIME = (Data[6] < 101) ? Data[6] * 10 : 100; + gEeprom.DTMF_HASH_CODE_PERSIST_TIME = (Data[7] < 101) ? Data[7] * 10 : 100; - // 0ED8..0EDF - EEPROM_ReadBuffer(0x0ED8, Data, 8); - gEeprom.DTMF_CODE_PERSIST_TIME = (Data[0] < 101) ? Data[0] * 10 : 100; - gEeprom.DTMF_CODE_INTERVAL_TIME = (Data[1] < 101) ? Data[1] * 10 : 100; + // 0ED8..0EDF + EEPROM_ReadBuffer(0x0ED8, Data, 8); + gEeprom.DTMF_CODE_PERSIST_TIME = (Data[0] < 101) ? Data[0] * 10 : 100; + gEeprom.DTMF_CODE_INTERVAL_TIME = (Data[1] < 101) ? Data[1] * 10 : 100; #ifdef ENABLE_DTMF_CALLING - gEeprom.PERMIT_REMOTE_KILL = (Data[2] < 2) ? Data[2] : true; + gEeprom.PERMIT_REMOTE_KILL = (Data[2] < 2) ? Data[2] : true; - // 0EE0..0EE7 + // 0EE0..0EE7 - EEPROM_ReadBuffer(0x0EE0, Data, sizeof(gEeprom.ANI_DTMF_ID)); - if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.ANI_DTMF_ID))) { - memcpy(gEeprom.ANI_DTMF_ID, Data, sizeof(gEeprom.ANI_DTMF_ID)); - } else { - strcpy(gEeprom.ANI_DTMF_ID, "123"); - } + EEPROM_ReadBuffer(0x0EE0, Data, sizeof(gEeprom.ANI_DTMF_ID)); + if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.ANI_DTMF_ID))) { + memcpy(gEeprom.ANI_DTMF_ID, Data, sizeof(gEeprom.ANI_DTMF_ID)); + } else { + strcpy(gEeprom.ANI_DTMF_ID, "123"); + } - // 0EE8..0EEF - EEPROM_ReadBuffer(0x0EE8, Data, sizeof(gEeprom.KILL_CODE)); - if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.KILL_CODE))) { - memcpy(gEeprom.KILL_CODE, Data, sizeof(gEeprom.KILL_CODE)); - } else { - strcpy(gEeprom.KILL_CODE, "ABCD9"); - } + // 0EE8..0EEF + EEPROM_ReadBuffer(0x0EE8, Data, sizeof(gEeprom.KILL_CODE)); + if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.KILL_CODE))) { + memcpy(gEeprom.KILL_CODE, Data, sizeof(gEeprom.KILL_CODE)); + } else { + strcpy(gEeprom.KILL_CODE, "ABCD9"); + } - // 0EF0..0EF7 - EEPROM_ReadBuffer(0x0EF0, Data, sizeof(gEeprom.REVIVE_CODE)); - if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.REVIVE_CODE))) { - memcpy(gEeprom.REVIVE_CODE, Data, sizeof(gEeprom.REVIVE_CODE)); - } else { - strcpy(gEeprom.REVIVE_CODE, "9DCBA"); - } + // 0EF0..0EF7 + EEPROM_ReadBuffer(0x0EF0, Data, sizeof(gEeprom.REVIVE_CODE)); + if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.REVIVE_CODE))) { + memcpy(gEeprom.REVIVE_CODE, Data, sizeof(gEeprom.REVIVE_CODE)); + } else { + strcpy(gEeprom.REVIVE_CODE, "9DCBA"); + } #endif - // 0EF8..0F07 - EEPROM_ReadBuffer(0x0EF8, Data, sizeof(gEeprom.DTMF_UP_CODE)); - if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.DTMF_UP_CODE))) { - memcpy(gEeprom.DTMF_UP_CODE, Data, sizeof(gEeprom.DTMF_UP_CODE)); - } else { - strcpy(gEeprom.DTMF_UP_CODE, "12345"); - } + // 0EF8..0F07 + EEPROM_ReadBuffer(0x0EF8, Data, sizeof(gEeprom.DTMF_UP_CODE)); + if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.DTMF_UP_CODE))) { + memcpy(gEeprom.DTMF_UP_CODE, Data, sizeof(gEeprom.DTMF_UP_CODE)); + } else { + strcpy(gEeprom.DTMF_UP_CODE, "12345"); + } - // 0F08..0F17 - EEPROM_ReadBuffer(0x0F08, Data, sizeof(gEeprom.DTMF_DOWN_CODE)); - if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.DTMF_DOWN_CODE))) { - memcpy(gEeprom.DTMF_DOWN_CODE, Data, sizeof(gEeprom.DTMF_DOWN_CODE)); - } else { - strcpy(gEeprom.DTMF_DOWN_CODE, "54321"); - } + // 0F08..0F17 + EEPROM_ReadBuffer(0x0F08, Data, sizeof(gEeprom.DTMF_DOWN_CODE)); + if (DTMF_ValidateCodes((char *)Data, sizeof(gEeprom.DTMF_DOWN_CODE))) { + memcpy(gEeprom.DTMF_DOWN_CODE, Data, sizeof(gEeprom.DTMF_DOWN_CODE)); + } else { + strcpy(gEeprom.DTMF_DOWN_CODE, "54321"); + } - // 0F18..0F1F - EEPROM_ReadBuffer(0x0F18, Data, 8); - gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 6) ? Data[0] : 0; // we now have 'all' channel scan option + // 0F18..0F1F + EEPROM_ReadBuffer(0x0F18, Data, 8); + gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 6) ? Data[0] : 0; // we now have 'all' channel scan option - // Fake data - /* - gEeprom.SCAN_LIST_ENABLED[0] = 0; - gEeprom.SCAN_LIST_ENABLED[1] = 0; - gEeprom.SCAN_LIST_ENABLED[2] = 0; + // Fake data + /* + gEeprom.SCAN_LIST_ENABLED[0] = 0; + gEeprom.SCAN_LIST_ENABLED[1] = 0; + gEeprom.SCAN_LIST_ENABLED[2] = 0; - gEeprom.SCANLIST_PRIORITY_CH1[0] = 0; - gEeprom.SCANLIST_PRIORITY_CH2[0] = 2; + gEeprom.SCANLIST_PRIORITY_CH1[0] = 0; + gEeprom.SCANLIST_PRIORITY_CH2[0] = 2; - gEeprom.SCANLIST_PRIORITY_CH1[1] = 14; - gEeprom.SCANLIST_PRIORITY_CH2[1] = 15; + gEeprom.SCANLIST_PRIORITY_CH1[1] = 14; + gEeprom.SCANLIST_PRIORITY_CH2[1] = 15; - gEeprom.SCANLIST_PRIORITY_CH1[2] = 40; - gEeprom.SCANLIST_PRIORITY_CH2[2] = 41; - */ + gEeprom.SCANLIST_PRIORITY_CH1[2] = 40; + gEeprom.SCANLIST_PRIORITY_CH2[2] = 41; + */ - // Fix me probably after Chirp update... - for (unsigned int i = 0; i < 3; i++) - { - gEeprom.SCAN_LIST_ENABLED[i] = (Data[1] >> i) & 1; - } + // Fix me probably after Chirp update... + for (unsigned int i = 0; i < 3; i++) + { + gEeprom.SCAN_LIST_ENABLED[i] = (Data[1] >> i) & 1; + } - for (unsigned int i = 0; i < 3; i++) - { - const unsigned int j = 1 + (i * 2); - gEeprom.SCANLIST_PRIORITY_CH1[i] = Data[j + 1]; - gEeprom.SCANLIST_PRIORITY_CH2[i] = Data[j + 2]; - } + for (unsigned int i = 0; i < 3; i++) + { + const unsigned int j = 1 + (i * 2); + gEeprom.SCANLIST_PRIORITY_CH1[i] = Data[j + 1]; + gEeprom.SCANLIST_PRIORITY_CH2[i] = Data[j + 2]; + } - // 0F40..0F47 - EEPROM_ReadBuffer(0x0F40, Data, 8); - gSetting_F_LOCK = (Data[0] < F_LOCK_LEN) ? Data[0] : F_LOCK_DEF; - gSetting_350TX = (Data[1] < 2) ? Data[1] : false; // was true + // 0F40..0F47 + EEPROM_ReadBuffer(0x0F40, Data, 8); + gSetting_F_LOCK = (Data[0] < F_LOCK_LEN) ? Data[0] : F_LOCK_DEF; + gSetting_350TX = (Data[1] < 2) ? Data[1] : false; // was true #ifdef ENABLE_DTMF_CALLING - gSetting_KILLED = (Data[2] < 2) ? Data[2] : false; + gSetting_KILLED = (Data[2] < 2) ? Data[2] : false; #endif - gSetting_200TX = (Data[3] < 2) ? Data[3] : false; - gSetting_500TX = (Data[4] < 2) ? Data[4] : false; - gSetting_350EN = (Data[5] < 2) ? Data[5] : true; + gSetting_200TX = (Data[3] < 2) ? Data[3] : false; + gSetting_500TX = (Data[4] < 2) ? Data[4] : false; + gSetting_350EN = (Data[5] < 2) ? Data[5] : true; #ifdef ENABLE_FEAT_F4HWN - gSetting_ScrambleEnable = false; + gSetting_ScrambleEnable = false; #else - gSetting_ScrambleEnable = (Data[6] < 2) ? Data[6] : true; + gSetting_ScrambleEnable = (Data[6] < 2) ? Data[6] : true; #endif - //gSetting_TX_EN = (Data[7] & (1u << 0)) ? true : false; - gSetting_live_DTMF_decoder = !!(Data[7] & (1u << 1)); - gSetting_battery_text = (((Data[7] >> 2) & 3u) <= 2) ? (Data[7] >> 2) & 3 : 2; - #ifdef ENABLE_AUDIO_BAR - gSetting_mic_bar = !!(Data[7] & (1u << 4)); - #endif - #ifndef ENABLE_FEAT_F4HWN - #ifdef ENABLE_AM_FIX - gSetting_AM_fix = !!(Data[7] & (1u << 5)); - #endif - #endif - gSetting_backlight_on_tx_rx = (Data[7] >> 6) & 3u; + //gSetting_TX_EN = (Data[7] & (1u << 0)) ? true : false; + gSetting_live_DTMF_decoder = !!(Data[7] & (1u << 1)); + gSetting_battery_text = (((Data[7] >> 2) & 3u) <= 2) ? (Data[7] >> 2) & 3 : 2; + #ifdef ENABLE_AUDIO_BAR + gSetting_mic_bar = !!(Data[7] & (1u << 4)); + #endif + #ifndef ENABLE_FEAT_F4HWN + #ifdef ENABLE_AM_FIX + gSetting_AM_fix = !!(Data[7] & (1u << 5)); + #endif + #endif + gSetting_backlight_on_tx_rx = (Data[7] >> 6) & 3u; - if (!gEeprom.VFO_OPEN) - { - gEeprom.ScreenChannel[0] = gEeprom.MrChannel[0]; - gEeprom.ScreenChannel[1] = gEeprom.MrChannel[1]; - } + if (!gEeprom.VFO_OPEN) + { + gEeprom.ScreenChannel[0] = gEeprom.MrChannel[0]; + gEeprom.ScreenChannel[1] = gEeprom.MrChannel[1]; + } - // 0D60..0E27 - EEPROM_ReadBuffer(0x0D60, gMR_ChannelAttributes, sizeof(gMR_ChannelAttributes)); - for(uint16_t i = 0; i < sizeof(gMR_ChannelAttributes); i++) { - ChannelAttributes_t *att = &gMR_ChannelAttributes[i]; - if(att->__val == 0xff){ - att->__val = 0; - att->band = 0x7; - } - gMR_ChannelExclude[i] = false; - } + // 0D60..0E27 + EEPROM_ReadBuffer(0x0D60, gMR_ChannelAttributes, sizeof(gMR_ChannelAttributes)); + for(uint16_t i = 0; i < sizeof(gMR_ChannelAttributes); i++) { + ChannelAttributes_t *att = &gMR_ChannelAttributes[i]; + if(att->__val == 0xff){ + att->__val = 0; + att->band = 0x7; + } + gMR_ChannelExclude[i] = false; + } - // 0F30..0F3F - EEPROM_ReadBuffer(0x0F30, gCustomAesKey, sizeof(gCustomAesKey)); - bHasCustomAesKey = false; - for (unsigned int i = 0; i < ARRAY_SIZE(gCustomAesKey); i++) - { - if (gCustomAesKey[i] != 0xFFFFFFFFu) - { - bHasCustomAesKey = true; - return; - } - } + // 0F30..0F3F + EEPROM_ReadBuffer(0x0F30, gCustomAesKey, sizeof(gCustomAesKey)); + bHasCustomAesKey = false; + for (unsigned int i = 0; i < ARRAY_SIZE(gCustomAesKey); i++) + { + if (gCustomAesKey[i] != 0xFFFFFFFFu) + { + bHasCustomAesKey = true; + return; + } + } - #ifdef ENABLE_FEAT_F4HWN - // 1FF0..0x1FF7 - EEPROM_ReadBuffer(0x1FF0, Data, 8); - gSetting_set_pwr = (((Data[7] & 0xF0) >> 4) < 7) ? ((Data[7] & 0xF0) >> 4) : 0; - gSetting_set_ptt = (((Data[7] & 0x0F)) < 2) ? ((Data[7] & 0x0F)) : 0; + #ifdef ENABLE_FEAT_F4HWN + // 1FF0..0x1FF7 + EEPROM_ReadBuffer(0x1FF0, Data, 8); + gSetting_set_pwr = (((Data[7] & 0xF0) >> 4) < 7) ? ((Data[7] & 0xF0) >> 4) : 0; + gSetting_set_ptt = (((Data[7] & 0x0F)) < 2) ? ((Data[7] & 0x0F)) : 0; - gSetting_set_tot = (((Data[6] & 0xF0) >> 4) < 4) ? ((Data[6] & 0xF0) >> 4) : 0; - gSetting_set_eot = (((Data[6] & 0x0F)) < 4) ? ((Data[6] & 0x0F)) : 0; + gSetting_set_tot = (((Data[6] & 0xF0) >> 4) < 4) ? ((Data[6] & 0xF0) >> 4) : 0; + gSetting_set_eot = (((Data[6] & 0x0F)) < 4) ? ((Data[6] & 0x0F)) : 0; - /* - int tmp = ((Data[5] & 0xF0) >> 4); + /* + int tmp = ((Data[5] & 0xF0) >> 4); - gSetting_set_inv = (((tmp >> 0) & 0x01) < 2) ? ((tmp >> 0) & 0x01): 0; - gSetting_set_lck = (((tmp >> 1) & 0x01) < 2) ? ((tmp >> 1) & 0x01): 0; - gSetting_set_met = (((tmp >> 2) & 0x01) < 2) ? ((tmp >> 2) & 0x01): 0; - gSetting_set_gui = (((tmp >> 3) & 0x01) < 2) ? ((tmp >> 3) & 0x01): 0; - gSetting_set_ctr = (((Data[5] & 0x0F)) > 00 && ((Data[5] & 0x0F)) < 16) ? ((Data[5] & 0x0F)) : 10; + gSetting_set_inv = (((tmp >> 0) & 0x01) < 2) ? ((tmp >> 0) & 0x01): 0; + gSetting_set_lck = (((tmp >> 1) & 0x01) < 2) ? ((tmp >> 1) & 0x01): 0; + gSetting_set_met = (((tmp >> 2) & 0x01) < 2) ? ((tmp >> 2) & 0x01): 0; + gSetting_set_gui = (((tmp >> 3) & 0x01) < 2) ? ((tmp >> 3) & 0x01): 0; + gSetting_set_ctr = (((Data[5] & 0x0F)) > 00 && ((Data[5] & 0x0F)) < 16) ? ((Data[5] & 0x0F)) : 10; - gSetting_set_tmr = ((Data[4] & 1) < 2) ? (Data[4] & 1): 0; - */ + gSetting_set_tmr = ((Data[4] & 1) < 2) ? (Data[4] & 1): 0; + */ - int tmp = (Data[5] & 0xF0) >> 4; + int tmp = (Data[5] & 0xF0) >> 4; - gSetting_set_inv = (tmp >> 0) & 0x01; - gSetting_set_lck = (tmp >> 1) & 0x01; - gSetting_set_met = (tmp >> 2) & 0x01; - gSetting_set_gui = (tmp >> 3) & 0x01; + gSetting_set_inv = (tmp >> 0) & 0x01; + gSetting_set_lck = (tmp >> 1) & 0x01; + gSetting_set_met = (tmp >> 2) & 0x01; + gSetting_set_gui = (tmp >> 3) & 0x01; - int ctr_value = Data[5] & 0x0F; - gSetting_set_ctr = (ctr_value > 0 && ctr_value < 16) ? ctr_value : 10; + int ctr_value = Data[5] & 0x0F; + gSetting_set_ctr = (ctr_value > 0 && ctr_value < 16) ? ctr_value : 10; - gSetting_set_tmr = Data[4] & 1; + gSetting_set_tmr = Data[4] & 1; - // And set special session settings for actions - gSetting_set_ptt_session = gSetting_set_ptt; - gEeprom.KEY_LOCK_PTT = gSetting_set_lck; - #endif + // And set special session settings for actions + gSetting_set_ptt_session = gSetting_set_ptt; + gEeprom.KEY_LOCK_PTT = gSetting_set_lck; + #endif } void SETTINGS_LoadCalibration(void) { -// uint8_t Mic; +// uint8_t Mic; - EEPROM_ReadBuffer(0x1EC0, gEEPROM_RSSI_CALIB[3], 8); - memcpy(gEEPROM_RSSI_CALIB[4], gEEPROM_RSSI_CALIB[3], 8); - memcpy(gEEPROM_RSSI_CALIB[5], gEEPROM_RSSI_CALIB[3], 8); - memcpy(gEEPROM_RSSI_CALIB[6], gEEPROM_RSSI_CALIB[3], 8); + EEPROM_ReadBuffer(0x1EC0, gEEPROM_RSSI_CALIB[3], 8); + memcpy(gEEPROM_RSSI_CALIB[4], gEEPROM_RSSI_CALIB[3], 8); + memcpy(gEEPROM_RSSI_CALIB[5], gEEPROM_RSSI_CALIB[3], 8); + memcpy(gEEPROM_RSSI_CALIB[6], gEEPROM_RSSI_CALIB[3], 8); - EEPROM_ReadBuffer(0x1EC8, gEEPROM_RSSI_CALIB[0], 8); - memcpy(gEEPROM_RSSI_CALIB[1], gEEPROM_RSSI_CALIB[0], 8); - memcpy(gEEPROM_RSSI_CALIB[2], gEEPROM_RSSI_CALIB[0], 8); + EEPROM_ReadBuffer(0x1EC8, gEEPROM_RSSI_CALIB[0], 8); + memcpy(gEEPROM_RSSI_CALIB[1], gEEPROM_RSSI_CALIB[0], 8); + memcpy(gEEPROM_RSSI_CALIB[2], gEEPROM_RSSI_CALIB[0], 8); - EEPROM_ReadBuffer(0x1F40, gBatteryCalibration, 12); - if (gBatteryCalibration[0] >= 5000) - { - gBatteryCalibration[0] = 1900; - gBatteryCalibration[1] = 2000; - } - gBatteryCalibration[5] = 2300; + EEPROM_ReadBuffer(0x1F40, gBatteryCalibration, 12); + if (gBatteryCalibration[0] >= 5000) + { + gBatteryCalibration[0] = 1900; + gBatteryCalibration[1] = 2000; + } + gBatteryCalibration[5] = 2300; - #ifdef ENABLE_VOX - EEPROM_ReadBuffer(0x1F50 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX1_THRESHOLD, 2); - EEPROM_ReadBuffer(0x1F68 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX0_THRESHOLD, 2); - #endif + #ifdef ENABLE_VOX + EEPROM_ReadBuffer(0x1F50 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX1_THRESHOLD, 2); + EEPROM_ReadBuffer(0x1F68 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX0_THRESHOLD, 2); + #endif - //EEPROM_ReadBuffer(0x1F80 + gEeprom.MIC_SENSITIVITY, &Mic, 1); - //gEeprom.MIC_SENSITIVITY_TUNING = (Mic < 32) ? Mic : 15; - gEeprom.MIC_SENSITIVITY_TUNING = gMicGain_dB2[gEeprom.MIC_SENSITIVITY]; + //EEPROM_ReadBuffer(0x1F80 + gEeprom.MIC_SENSITIVITY, &Mic, 1); + //gEeprom.MIC_SENSITIVITY_TUNING = (Mic < 32) ? Mic : 15; + gEeprom.MIC_SENSITIVITY_TUNING = gMicGain_dB2[gEeprom.MIC_SENSITIVITY]; - { - struct - { - int16_t BK4819_XtalFreqLow; - uint16_t EEPROM_1F8A; - uint16_t EEPROM_1F8C; - uint8_t VOLUME_GAIN; - uint8_t DAC_GAIN; - } __attribute__((packed)) Misc; + { + struct + { + int16_t BK4819_XtalFreqLow; + uint16_t EEPROM_1F8A; + uint16_t EEPROM_1F8C; + uint8_t VOLUME_GAIN; + uint8_t DAC_GAIN; + } __attribute__((packed)) Misc; - // radio 1 .. 04 00 46 00 50 00 2C 0E - // radio 2 .. 05 00 46 00 50 00 2C 0E - EEPROM_ReadBuffer(0x1F88, &Misc, 8); + // radio 1 .. 04 00 46 00 50 00 2C 0E + // radio 2 .. 05 00 46 00 50 00 2C 0E + EEPROM_ReadBuffer(0x1F88, &Misc, 8); - gEeprom.BK4819_XTAL_FREQ_LOW = (Misc.BK4819_XtalFreqLow >= -1000 && Misc.BK4819_XtalFreqLow <= 1000) ? Misc.BK4819_XtalFreqLow : 0; - gEEPROM_1F8A = Misc.EEPROM_1F8A & 0x01FF; - gEEPROM_1F8C = Misc.EEPROM_1F8C & 0x01FF; - gEeprom.VOLUME_GAIN = (Misc.VOLUME_GAIN < 64) ? Misc.VOLUME_GAIN : 58; - gEeprom.DAC_GAIN = (Misc.DAC_GAIN < 16) ? Misc.DAC_GAIN : 8; + gEeprom.BK4819_XTAL_FREQ_LOW = (Misc.BK4819_XtalFreqLow >= -1000 && Misc.BK4819_XtalFreqLow <= 1000) ? Misc.BK4819_XtalFreqLow : 0; + gEEPROM_1F8A = Misc.EEPROM_1F8A & 0x01FF; + gEEPROM_1F8C = Misc.EEPROM_1F8C & 0x01FF; + gEeprom.VOLUME_GAIN = (Misc.VOLUME_GAIN < 64) ? Misc.VOLUME_GAIN : 58; + gEeprom.DAC_GAIN = (Misc.DAC_GAIN < 16) ? Misc.DAC_GAIN : 8; - BK4819_WriteRegister(BK4819_REG_3B, 22656 + gEeprom.BK4819_XTAL_FREQ_LOW); -// BK4819_WriteRegister(BK4819_REG_3C, gEeprom.BK4819_XTAL_FREQ_HIGH); - } + BK4819_WriteRegister(BK4819_REG_3B, 22656 + gEeprom.BK4819_XTAL_FREQ_LOW); +// BK4819_WriteRegister(BK4819_REG_3C, gEeprom.BK4819_XTAL_FREQ_HIGH); + } } uint32_t SETTINGS_FetchChannelFrequency(const int channel) { - struct - { - uint32_t frequency; - uint32_t offset; - } __attribute__((packed)) info; + struct + { + uint32_t frequency; + uint32_t offset; + } __attribute__((packed)) info; - EEPROM_ReadBuffer(channel * 16, &info, sizeof(info)); + EEPROM_ReadBuffer(channel * 16, &info, sizeof(info)); - return info.frequency; + return info.frequency; } void SETTINGS_FetchChannelName(char *s, const int channel) { - if (s == NULL) - return; + if (s == NULL) + return; - s[0] = 0; + s[0] = 0; - if (channel < 0) - return; + if (channel < 0) + return; - if (!RADIO_CheckValidChannel(channel, false, 0)) - return; + if (!RADIO_CheckValidChannel(channel, false, 0)) + return; - EEPROM_ReadBuffer(0x0F50 + (channel * 16), s, 10); + EEPROM_ReadBuffer(0x0F50 + (channel * 16), s, 10); - int i; - for (i = 0; i < 10; i++) - if (s[i] < 32 || s[i] > 127) - break; // invalid char + int i; + for (i = 0; i < 10; i++) + if (s[i] < 32 || s[i] > 127) + break; // invalid char - s[i--] = 0; // null term + s[i--] = 0; // null term - while (i >= 0 && s[i] == 32) // trim trailing spaces - s[i--] = 0; // null term + while (i >= 0 && s[i] == 32) // trim trailing spaces + s[i--] = 0; // null term } void SETTINGS_FactoryReset(bool bIsAll) { - uint16_t i; - uint8_t Template[8]; + uint16_t i; + uint8_t Template[8]; - memset(Template, 0xFF, sizeof(Template)); + memset(Template, 0xFF, sizeof(Template)); - //for (i = 0x0C80; i < 0x1E00; i += 8) - for (i = 0x0000; i < 0x1E00; i += 8) - { - if ( - !(i >= 0x0EE0 && i < 0x0F18) && // ANI ID + DTMF codes - !(i >= 0x0F30 && i < 0x0F50) && // AES KEY + F LOCK + Scramble Enable - !(i >= 0x1C00 && i < 0x1E00) && // DTMF contacts - !(i >= 0x0EB0 && i < 0x0ED0) && // Welcome strings - !(i >= 0x0EA0 && i < 0x0EA8) && // Voice Prompt - (bIsAll || - ( - !(i >= 0x0D60 && i < 0x0E28) && // MR Channel Attributes - !(i >= 0x0F18 && i < 0x0F30) && // Scan List - !(i >= 0x0F50 && i < 0x1C00) && // MR Channel Names - !(i >= 0x0E40 && i < 0x0E70) && // FM Channels - !(i >= 0x0E88 && i < 0x0E90) // FM settings - )) - ) - { - EEPROM_WriteBuffer(i, Template); - } - } + //for (i = 0x0C80; i < 0x1E00; i += 8) + for (i = 0x0000; i < 0x1E00; i += 8) + { + if ( + !(i >= 0x0EE0 && i < 0x0F18) && // ANI ID + DTMF codes + !(i >= 0x0F30 && i < 0x0F50) && // AES KEY + F LOCK + Scramble Enable + !(i >= 0x1C00 && i < 0x1E00) && // DTMF contacts + !(i >= 0x0EB0 && i < 0x0ED0) && // Welcome strings + !(i >= 0x0EA0 && i < 0x0EA8) && // Voice Prompt + (bIsAll || + ( + !(i >= 0x0D60 && i < 0x0E28) && // MR Channel Attributes + !(i >= 0x0F18 && i < 0x0F30) && // Scan List + !(i >= 0x0F50 && i < 0x1C00) && // MR Channel Names + !(i >= 0x0E40 && i < 0x0E70) && // FM Channels + !(i >= 0x0E88 && i < 0x0E90) // FM settings + )) + ) + { + EEPROM_WriteBuffer(i, Template); + } + } - if (bIsAll) - { - RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_FIRST + BAND6_400MHz, 43350000); + if (bIsAll) + { + RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_FIRST + BAND6_400MHz, 43350000); - // set the first few memory channels - for (i = 0; i < ARRAY_SIZE(gDefaultFrequencyTable); i++) - { - const uint32_t Frequency = gDefaultFrequencyTable[i]; - gRxVfo->freq_config_RX.Frequency = Frequency; - gRxVfo->freq_config_TX.Frequency = Frequency; - gRxVfo->Band = FREQUENCY_GetBand(Frequency); - SETTINGS_SaveChannel(MR_CHANNEL_FIRST + i, 0, gRxVfo, 2); - } + // set the first few memory channels + for (i = 0; i < ARRAY_SIZE(gDefaultFrequencyTable); i++) + { + const uint32_t Frequency = gDefaultFrequencyTable[i]; + gRxVfo->freq_config_RX.Frequency = Frequency; + gRxVfo->freq_config_TX.Frequency = Frequency; + gRxVfo->Band = FREQUENCY_GetBand(Frequency); + SETTINGS_SaveChannel(MR_CHANNEL_FIRST + i, 0, gRxVfo, 2); + } - #ifdef ENABLE_FEAT_F4HWN - EEPROM_WriteBuffer(0x1FF0, Template); - #endif - } + #ifdef ENABLE_FEAT_F4HWN + EEPROM_WriteBuffer(0x1FF0, Template); + #endif + } } #ifdef ENABLE_FMRADIO void SETTINGS_SaveFM(void) - { - union { - struct { - uint16_t selFreq; - uint8_t selChn; - uint8_t isMrMode:1; - uint8_t band:2; - //uint8_t space:2; - }; - uint8_t __raw[8]; - } __attribute__((packed)) fmCfg; + { + union { + struct { + uint16_t selFreq; + uint8_t selChn; + uint8_t isMrMode:1; + uint8_t band:2; + //uint8_t space:2; + }; + uint8_t __raw[8]; + } __attribute__((packed)) fmCfg; - memset(fmCfg.__raw, 0xFF, sizeof(fmCfg.__raw)); - fmCfg.selChn = gEeprom.FM_SelectedChannel; - fmCfg.selFreq = gEeprom.FM_SelectedFrequency; - fmCfg.isMrMode = gEeprom.FM_IsMrMode; - fmCfg.band = gEeprom.FM_Band; - //fmCfg.space = gEeprom.FM_Space; - EEPROM_WriteBuffer(0x0E88, fmCfg.__raw); + memset(fmCfg.__raw, 0xFF, sizeof(fmCfg.__raw)); + fmCfg.selChn = gEeprom.FM_SelectedChannel; + fmCfg.selFreq = gEeprom.FM_SelectedFrequency; + fmCfg.isMrMode = gEeprom.FM_IsMrMode; + fmCfg.band = gEeprom.FM_Band; + //fmCfg.space = gEeprom.FM_Space; + EEPROM_WriteBuffer(0x0E88, fmCfg.__raw); - for (unsigned i = 0; i < 5; i++) - EEPROM_WriteBuffer(0x0E40 + (i * 8), &gFM_Channels[i * 4]); - } + for (unsigned i = 0; i < 5; i++) + EEPROM_WriteBuffer(0x0E40 + (i * 8), &gFM_Channels[i * 4]); + } #endif void SETTINGS_SaveVfoIndices(void) { - uint8_t State[8]; + uint8_t State[8]; - #ifndef ENABLE_NOAA - EEPROM_ReadBuffer(0x0E80, State, sizeof(State)); - #endif + #ifndef ENABLE_NOAA + EEPROM_ReadBuffer(0x0E80, State, sizeof(State)); + #endif - State[0] = gEeprom.ScreenChannel[0]; - State[1] = gEeprom.MrChannel[0]; - State[2] = gEeprom.FreqChannel[0]; - State[3] = gEeprom.ScreenChannel[1]; - State[4] = gEeprom.MrChannel[1]; - State[5] = gEeprom.FreqChannel[1]; - #ifdef ENABLE_NOAA - State[6] = gEeprom.NoaaChannel[0]; - State[7] = gEeprom.NoaaChannel[1]; - #endif + State[0] = gEeprom.ScreenChannel[0]; + State[1] = gEeprom.MrChannel[0]; + State[2] = gEeprom.FreqChannel[0]; + State[3] = gEeprom.ScreenChannel[1]; + State[4] = gEeprom.MrChannel[1]; + State[5] = gEeprom.FreqChannel[1]; + #ifdef ENABLE_NOAA + State[6] = gEeprom.NoaaChannel[0]; + State[7] = gEeprom.NoaaChannel[1]; + #endif - EEPROM_WriteBuffer(0x0E80, State); + EEPROM_WriteBuffer(0x0E80, State); } void SETTINGS_SaveSettings(void) { - uint8_t State[8]; - uint8_t tmp = 0; + uint8_t State[8]; + uint8_t tmp = 0; - #ifdef ENABLE_PWRON_PASSWORD - uint32_t Password[2]; - #endif + #ifdef ENABLE_PWRON_PASSWORD + uint32_t Password[2]; + #endif - State[0] = gEeprom.CHAN_1_CALL; - State[1] = gEeprom.SQUELCH_LEVEL; - State[2] = gEeprom.TX_TIMEOUT_TIMER; - #ifdef ENABLE_NOAA - State[3] = gEeprom.NOAA_AUTO_SCAN; - #else - State[3] = false; - #endif - State[4] = gEeprom.KEY_LOCK; - #ifdef ENABLE_VOX - State[5] = gEeprom.VOX_SWITCH; - State[6] = gEeprom.VOX_LEVEL; - #else - State[5] = false; - State[6] = 0; - #endif - State[7] = gEeprom.MIC_SENSITIVITY; - EEPROM_WriteBuffer(0x0E70, State); + State[0] = gEeprom.CHAN_1_CALL; + State[1] = gEeprom.SQUELCH_LEVEL; + State[2] = gEeprom.TX_TIMEOUT_TIMER; + #ifdef ENABLE_NOAA + State[3] = gEeprom.NOAA_AUTO_SCAN; + #else + State[3] = false; + #endif + State[4] = gEeprom.KEY_LOCK; + #ifdef ENABLE_VOX + State[5] = gEeprom.VOX_SWITCH; + State[6] = gEeprom.VOX_LEVEL; + #else + State[5] = false; + State[6] = 0; + #endif + State[7] = gEeprom.MIC_SENSITIVITY; + EEPROM_WriteBuffer(0x0E70, State); - State[0] = (gEeprom.BACKLIGHT_MIN << 4) + gEeprom.BACKLIGHT_MAX; - State[1] = gEeprom.CHANNEL_DISPLAY_MODE; - State[2] = gEeprom.CROSS_BAND_RX_TX; - State[3] = gEeprom.BATTERY_SAVE; - State[4] = gEeprom.DUAL_WATCH; + State[0] = (gEeprom.BACKLIGHT_MIN << 4) + gEeprom.BACKLIGHT_MAX; + State[1] = gEeprom.CHANNEL_DISPLAY_MODE; + State[2] = gEeprom.CROSS_BAND_RX_TX; + State[3] = gEeprom.BATTERY_SAVE; + State[4] = gEeprom.DUAL_WATCH; - #ifdef ENABLE_FEAT_F4HWN - if(!gSaveRxMode) - { - State[2] = gCB; - State[4] = gDW; - } - if(gBackLight) - { - State[5] = gBacklightTimeOriginal; - } - else - { - State[5] = gEeprom.BACKLIGHT_TIME; - } - #else - State[5] = gEeprom.BACKLIGHT_TIME; - #endif + #ifdef ENABLE_FEAT_F4HWN + if(!gSaveRxMode) + { + State[2] = gCB; + State[4] = gDW; + } + if(gBackLight) + { + State[5] = gBacklightTimeOriginal; + } + else + { + State[5] = gEeprom.BACKLIGHT_TIME; + } + #else + State[5] = gEeprom.BACKLIGHT_TIME; + #endif - State[6] = gEeprom.TAIL_TONE_ELIMINATION; - State[7] = gEeprom.VFO_OPEN; - EEPROM_WriteBuffer(0x0E78, State); + State[6] = gEeprom.TAIL_TONE_ELIMINATION; + State[7] = gEeprom.VFO_OPEN; + EEPROM_WriteBuffer(0x0E78, State); - State[0] = gEeprom.BEEP_CONTROL; - State[0] |= gEeprom.KEY_M_LONG_PRESS_ACTION << 1; - State[1] = gEeprom.KEY_1_SHORT_PRESS_ACTION; - State[2] = gEeprom.KEY_1_LONG_PRESS_ACTION; - State[3] = gEeprom.KEY_2_SHORT_PRESS_ACTION; - State[4] = gEeprom.KEY_2_LONG_PRESS_ACTION; - State[5] = gEeprom.SCAN_RESUME_MODE; - State[6] = gEeprom.AUTO_KEYPAD_LOCK; - State[7] = gEeprom.POWER_ON_DISPLAY_MODE; - EEPROM_WriteBuffer(0x0E90, State); + State[0] = gEeprom.BEEP_CONTROL; + State[0] |= gEeprom.KEY_M_LONG_PRESS_ACTION << 1; + State[1] = gEeprom.KEY_1_SHORT_PRESS_ACTION; + State[2] = gEeprom.KEY_1_LONG_PRESS_ACTION; + State[3] = gEeprom.KEY_2_SHORT_PRESS_ACTION; + State[4] = gEeprom.KEY_2_LONG_PRESS_ACTION; + State[5] = gEeprom.SCAN_RESUME_MODE; + State[6] = gEeprom.AUTO_KEYPAD_LOCK; + State[7] = gEeprom.POWER_ON_DISPLAY_MODE; + EEPROM_WriteBuffer(0x0E90, State); - #ifdef ENABLE_PWRON_PASSWORD - memset(Password, 0xFF, sizeof(Password)); - Password[0] = gEeprom.POWER_ON_PASSWORD; - EEPROM_WriteBuffer(0x0E98, Password); - #endif + #ifdef ENABLE_PWRON_PASSWORD + memset(Password, 0xFF, sizeof(Password)); + Password[0] = gEeprom.POWER_ON_PASSWORD; + EEPROM_WriteBuffer(0x0E98, Password); + #endif - memset(State, 0xFF, sizeof(State)); + memset(State, 0xFF, sizeof(State)); #ifdef ENABLE_VOICE - State[0] = gEeprom.VOICE_PROMPT; + State[0] = gEeprom.VOICE_PROMPT; #endif #ifdef ENABLE_RSSI_BAR - State[1] = gEeprom.S0_LEVEL; - State[2] = gEeprom.S9_LEVEL; + State[1] = gEeprom.S0_LEVEL; + State[2] = gEeprom.S9_LEVEL; #endif - EEPROM_WriteBuffer(0x0EA0, State); + EEPROM_WriteBuffer(0x0EA0, State); - #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) - State[0] = gEeprom.ALARM_MODE; - #else - State[0] = false; - #endif - State[1] = gEeprom.ROGER; - State[2] = gEeprom.REPEATER_TAIL_TONE_ELIMINATION; - State[3] = gEeprom.TX_VFO; - State[4] = gEeprom.BATTERY_TYPE; - EEPROM_WriteBuffer(0x0EA8, State); + #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) + State[0] = gEeprom.ALARM_MODE; + #else + State[0] = false; + #endif + State[1] = gEeprom.ROGER; + State[2] = gEeprom.REPEATER_TAIL_TONE_ELIMINATION; + State[3] = gEeprom.TX_VFO; + State[4] = gEeprom.BATTERY_TYPE; + EEPROM_WriteBuffer(0x0EA8, State); - State[0] = gEeprom.DTMF_SIDE_TONE; + State[0] = gEeprom.DTMF_SIDE_TONE; #ifdef ENABLE_DTMF_CALLING - State[1] = gEeprom.DTMF_SEPARATE_CODE; - State[2] = gEeprom.DTMF_GROUP_CALL_CODE; - State[3] = gEeprom.DTMF_DECODE_RESPONSE; - State[4] = gEeprom.DTMF_auto_reset_time; + State[1] = gEeprom.DTMF_SEPARATE_CODE; + State[2] = gEeprom.DTMF_GROUP_CALL_CODE; + State[3] = gEeprom.DTMF_DECODE_RESPONSE; + State[4] = gEeprom.DTMF_auto_reset_time; #endif - State[5] = gEeprom.DTMF_PRELOAD_TIME / 10U; - State[6] = gEeprom.DTMF_FIRST_CODE_PERSIST_TIME / 10U; - State[7] = gEeprom.DTMF_HASH_CODE_PERSIST_TIME / 10U; - EEPROM_WriteBuffer(0x0ED0, State); + State[5] = gEeprom.DTMF_PRELOAD_TIME / 10U; + State[6] = gEeprom.DTMF_FIRST_CODE_PERSIST_TIME / 10U; + State[7] = gEeprom.DTMF_HASH_CODE_PERSIST_TIME / 10U; + EEPROM_WriteBuffer(0x0ED0, State); - memset(State, 0xFF, sizeof(State)); - State[0] = gEeprom.DTMF_CODE_PERSIST_TIME / 10U; - State[1] = gEeprom.DTMF_CODE_INTERVAL_TIME / 10U; + memset(State, 0xFF, sizeof(State)); + State[0] = gEeprom.DTMF_CODE_PERSIST_TIME / 10U; + State[1] = gEeprom.DTMF_CODE_INTERVAL_TIME / 10U; #ifdef ENABLE_DTMF_CALLING - State[2] = gEeprom.PERMIT_REMOTE_KILL; + State[2] = gEeprom.PERMIT_REMOTE_KILL; #endif - EEPROM_WriteBuffer(0x0ED8, State); + EEPROM_WriteBuffer(0x0ED8, State); - State[0] = gEeprom.SCAN_LIST_DEFAULT; + State[0] = gEeprom.SCAN_LIST_DEFAULT; - tmp = 0; + tmp = 0; - if (gEeprom.SCAN_LIST_ENABLED[0] == 1) - tmp = tmp | (1 << 0); - if (gEeprom.SCAN_LIST_ENABLED[1] == 1) - tmp = tmp | (1 << 1); - if (gEeprom.SCAN_LIST_ENABLED[2] == 1) - tmp = tmp | (1 << 2); + if (gEeprom.SCAN_LIST_ENABLED[0] == 1) + tmp = tmp | (1 << 0); + if (gEeprom.SCAN_LIST_ENABLED[1] == 1) + tmp = tmp | (1 << 1); + if (gEeprom.SCAN_LIST_ENABLED[2] == 1) + tmp = tmp | (1 << 2); - State[1] = tmp; - State[2] = gEeprom.SCANLIST_PRIORITY_CH1[0]; - State[3] = gEeprom.SCANLIST_PRIORITY_CH2[0]; - State[4] = gEeprom.SCANLIST_PRIORITY_CH1[1]; - State[5] = gEeprom.SCANLIST_PRIORITY_CH2[1]; - State[6] = gEeprom.SCANLIST_PRIORITY_CH1[2]; - State[7] = gEeprom.SCANLIST_PRIORITY_CH2[2]; - EEPROM_WriteBuffer(0x0F18, State); + State[1] = tmp; + State[2] = gEeprom.SCANLIST_PRIORITY_CH1[0]; + State[3] = gEeprom.SCANLIST_PRIORITY_CH2[0]; + State[4] = gEeprom.SCANLIST_PRIORITY_CH1[1]; + State[5] = gEeprom.SCANLIST_PRIORITY_CH2[1]; + State[6] = gEeprom.SCANLIST_PRIORITY_CH1[2]; + State[7] = gEeprom.SCANLIST_PRIORITY_CH2[2]; + EEPROM_WriteBuffer(0x0F18, State); - memset(State, 0xFF, sizeof(State)); - State[0] = gSetting_F_LOCK; - State[1] = gSetting_350TX; + memset(State, 0xFF, sizeof(State)); + State[0] = gSetting_F_LOCK; + State[1] = gSetting_350TX; #ifdef ENABLE_DTMF_CALLING - State[2] = gSetting_KILLED; + State[2] = gSetting_KILLED; #endif - State[3] = gSetting_200TX; - State[4] = gSetting_500TX; - State[5] = gSetting_350EN; + State[3] = gSetting_200TX; + State[4] = gSetting_500TX; + State[5] = gSetting_350EN; #ifdef ENABLE_FEAT_F4HWN - State[6] = false; + State[6] = false; #else - State[6] = gSetting_ScrambleEnable; + State[6] = gSetting_ScrambleEnable; #endif - //if (!gSetting_TX_EN) State[7] &= ~(1u << 0); - if (!gSetting_live_DTMF_decoder) State[7] &= ~(1u << 1); - State[7] = (State[7] & ~(3u << 2)) | ((gSetting_battery_text & 3u) << 2); - #ifdef ENABLE_AUDIO_BAR - if (!gSetting_mic_bar) State[7] &= ~(1u << 4); - #endif - #ifndef ENABLE_FEAT_F4HWN - #ifdef ENABLE_AM_FIX - if (!gSetting_AM_fix) State[7] &= ~(1u << 5); - #endif - #endif - State[7] = (State[7] & ~(3u << 6)) | ((gSetting_backlight_on_tx_rx & 3u) << 6); + //if (!gSetting_TX_EN) State[7] &= ~(1u << 0); + if (!gSetting_live_DTMF_decoder) State[7] &= ~(1u << 1); + State[7] = (State[7] & ~(3u << 2)) | ((gSetting_battery_text & 3u) << 2); + #ifdef ENABLE_AUDIO_BAR + if (!gSetting_mic_bar) State[7] &= ~(1u << 4); + #endif + #ifndef ENABLE_FEAT_F4HWN + #ifdef ENABLE_AM_FIX + if (!gSetting_AM_fix) State[7] &= ~(1u << 5); + #endif + #endif + State[7] = (State[7] & ~(3u << 6)) | ((gSetting_backlight_on_tx_rx & 3u) << 6); - EEPROM_WriteBuffer(0x0F40, State); + EEPROM_WriteBuffer(0x0F40, State); #ifdef ENABLE_FEAT_F4HWN - memset(State, 0xFF, sizeof(State)); + memset(State, 0xFF, sizeof(State)); - /* - tmp = 0; + /* + tmp = 0; - if(gSetting_set_tmr == 1) - tmp = tmp | (1 << 0); + if(gSetting_set_tmr == 1) + tmp = tmp | (1 << 0); - State[4] = tmp; + State[4] = tmp; - tmp = 0; + tmp = 0; - if(gSetting_set_inv == 1) - tmp = tmp | (1 << 0); - if (gSetting_set_lck == 1) - tmp = tmp | (1 << 1); - if (gSetting_set_met == 1) - tmp = tmp | (1 << 2); - if (gSetting_set_gui == 1) - tmp = tmp | (1 << 3); - */ + if(gSetting_set_inv == 1) + tmp = tmp | (1 << 0); + if (gSetting_set_lck == 1) + tmp = tmp | (1 << 1); + if (gSetting_set_met == 1) + tmp = tmp | (1 << 2); + if (gSetting_set_gui == 1) + tmp = tmp | (1 << 3); + */ - State[4] = gSetting_set_tmr ? (1 << 0) : 0; + State[4] = gSetting_set_tmr ? (1 << 0) : 0; - tmp = (gSetting_set_inv << 0) | - (gSetting_set_lck << 1) | - (gSetting_set_met << 2) | - (gSetting_set_gui << 3); + tmp = (gSetting_set_inv << 0) | + (gSetting_set_lck << 1) | + (gSetting_set_met << 2) | + (gSetting_set_gui << 3); - State[5] = ((tmp << 4) | (gSetting_set_ctr & 0x0F)); - State[6] = ((gSetting_set_tot << 4) | (gSetting_set_eot & 0x0F)); - State[7] = ((gSetting_set_pwr << 4) | (gSetting_set_ptt & 0x0F)); + State[5] = ((tmp << 4) | (gSetting_set_ctr & 0x0F)); + State[6] = ((gSetting_set_tot << 4) | (gSetting_set_eot & 0x0F)); + State[7] = ((gSetting_set_pwr << 4) | (gSetting_set_ptt & 0x0F)); - gEeprom.KEY_LOCK_PTT = gSetting_set_lck; + gEeprom.KEY_LOCK_PTT = gSetting_set_lck; - EEPROM_WriteBuffer(0x1FF0, State); + EEPROM_WriteBuffer(0x1FF0, State); #endif } void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode) { #ifdef ENABLE_NOAA - if (IS_NOAA_CHANNEL(Channel)) - return; + if (IS_NOAA_CHANNEL(Channel)) + return; #endif - uint16_t OffsetVFO = Channel * 16; + uint16_t OffsetVFO = Channel * 16; - if (IS_FREQ_CHANNEL(Channel)) { // it's a VFO, not a channel - OffsetVFO = (VFO == 0) ? 0x0C80 : 0x0C90; - OffsetVFO += (Channel - FREQ_CHANNEL_FIRST) * 32; - } + if (IS_FREQ_CHANNEL(Channel)) { // it's a VFO, not a channel + OffsetVFO = (VFO == 0) ? 0x0C80 : 0x0C90; + OffsetVFO += (Channel - FREQ_CHANNEL_FIRST) * 32; + } - if (Mode >= 2 || IS_FREQ_CHANNEL(Channel)) { // copy VFO to a channel - union { - uint8_t _8[8]; - uint32_t _32[2]; - } State; + if (Mode >= 2 || IS_FREQ_CHANNEL(Channel)) { // copy VFO to a channel + union { + uint8_t _8[8]; + uint32_t _32[2]; + } State; - State._32[0] = pVFO->freq_config_RX.Frequency; - State._32[1] = pVFO->TX_OFFSET_FREQUENCY; - EEPROM_WriteBuffer(OffsetVFO + 0, State._32); + State._32[0] = pVFO->freq_config_RX.Frequency; + State._32[1] = pVFO->TX_OFFSET_FREQUENCY; + EEPROM_WriteBuffer(OffsetVFO + 0, State._32); - State._8[0] = pVFO->freq_config_RX.Code; - State._8[1] = pVFO->freq_config_TX.Code; - State._8[2] = (pVFO->freq_config_TX.CodeType << 4) | pVFO->freq_config_RX.CodeType; - State._8[3] = (pVFO->Modulation << 4) | pVFO->TX_OFFSET_FREQUENCY_DIRECTION; - State._8[4] = 0 - | (pVFO->TX_LOCK << 6) - | (pVFO->BUSY_CHANNEL_LOCK << 5) - | (pVFO->OUTPUT_POWER << 2) - | (pVFO->CHANNEL_BANDWIDTH << 1) - | (pVFO->FrequencyReverse << 0); - State._8[5] = ((pVFO->DTMF_PTT_ID_TX_MODE & 7u) << 1) + State._8[0] = pVFO->freq_config_RX.Code; + State._8[1] = pVFO->freq_config_TX.Code; + State._8[2] = (pVFO->freq_config_TX.CodeType << 4) | pVFO->freq_config_RX.CodeType; + State._8[3] = (pVFO->Modulation << 4) | pVFO->TX_OFFSET_FREQUENCY_DIRECTION; + State._8[4] = 0 + | (pVFO->TX_LOCK << 6) + | (pVFO->BUSY_CHANNEL_LOCK << 5) + | (pVFO->OUTPUT_POWER << 2) + | (pVFO->CHANNEL_BANDWIDTH << 1) + | (pVFO->FrequencyReverse << 0); + State._8[5] = ((pVFO->DTMF_PTT_ID_TX_MODE & 7u) << 1) #ifdef ENABLE_DTMF_CALLING - | ((pVFO->DTMF_DECODING_ENABLE & 1u) << 0) + | ((pVFO->DTMF_DECODING_ENABLE & 1u) << 0) #endif - ; - State._8[6] = pVFO->STEP_SETTING; + ; + State._8[6] = pVFO->STEP_SETTING; #ifdef ENABLE_FEAT_F4HWN - State._8[7] = 0; + State._8[7] = 0; #else - State._8[7] = pVFO->SCRAMBLING_TYPE; + State._8[7] = pVFO->SCRAMBLING_TYPE; #endif - EEPROM_WriteBuffer(OffsetVFO + 8, State._8); + EEPROM_WriteBuffer(OffsetVFO + 8, State._8); - SETTINGS_UpdateChannel(Channel, pVFO, true, true, true); + SETTINGS_UpdateChannel(Channel, pVFO, true, true, true); - if (IS_MR_CHANNEL(Channel)) { + if (IS_MR_CHANNEL(Channel)) { #ifndef ENABLE_KEEP_MEM_NAME - // clear/reset the channel name - SETTINGS_SaveChannelName(Channel, ""); + // clear/reset the channel name + SETTINGS_SaveChannelName(Channel, ""); #else - if (Mode >= 3) { - SETTINGS_SaveChannelName(Channel, pVFO->Name); - } + if (Mode >= 3) { + SETTINGS_SaveChannelName(Channel, pVFO->Name); + } #endif - } - } + } + } } void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration) { - uint16_t buf[4]; - EEPROM_WriteBuffer(0x1F40, batteryCalibration); - EEPROM_ReadBuffer( 0x1F48, buf, sizeof(buf)); - buf[0] = batteryCalibration[4]; - buf[1] = batteryCalibration[5]; - EEPROM_WriteBuffer(0x1F48, buf); + uint16_t buf[4]; + EEPROM_WriteBuffer(0x1F40, batteryCalibration); + EEPROM_ReadBuffer( 0x1F48, buf, sizeof(buf)); + buf[0] = batteryCalibration[4]; + buf[1] = batteryCalibration[5]; + EEPROM_WriteBuffer(0x1F48, buf); } void SETTINGS_SaveChannelName(uint8_t channel, const char * name) { - uint16_t offset = channel * 16; - uint8_t buf[16] = {0}; - memcpy(buf, name, MIN(strlen(name), 10u)); - EEPROM_WriteBuffer(0x0F50 + offset, buf); - EEPROM_WriteBuffer(0x0F58 + offset, buf + 8); + uint16_t offset = channel * 16; + uint8_t buf[16] = {0}; + memcpy(buf, name, MIN(strlen(name), 10u)); + EEPROM_WriteBuffer(0x0F50 + offset, buf); + EEPROM_WriteBuffer(0x0F58 + offset, buf + 8); } void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep, bool check, bool save) { #ifdef ENABLE_NOAA - if (!IS_NOAA_CHANNEL(channel)) + if (!IS_NOAA_CHANNEL(channel)) #endif - { - uint8_t state[8]; - ChannelAttributes_t att = { - .band = 0x7, - .compander = 0, - .scanlist1 = 0, - .scanlist2 = 0, - .scanlist3 = 0, - }; // default attributes + { + uint8_t state[8]; + ChannelAttributes_t att = { + .band = 0x7, + .compander = 0, + .scanlist1 = 0, + .scanlist2 = 0, + .scanlist3 = 0, + }; // default attributes - uint16_t offset = 0x0D60 + (channel & ~7u); - EEPROM_ReadBuffer(offset, state, sizeof(state)); + uint16_t offset = 0x0D60 + (channel & ~7u); + EEPROM_ReadBuffer(offset, state, sizeof(state)); - if (keep) { - att.band = pVFO->Band; - att.scanlist1 = pVFO->SCANLIST1_PARTICIPATION; - att.scanlist2 = pVFO->SCANLIST2_PARTICIPATION; - att.scanlist3 = pVFO->SCANLIST3_PARTICIPATION; - att.compander = pVFO->Compander; - if (check && state[channel & 7u] == att.__val) - return; // no change in the attributes - } + if (keep) { + att.band = pVFO->Band; + att.scanlist1 = pVFO->SCANLIST1_PARTICIPATION; + att.scanlist2 = pVFO->SCANLIST2_PARTICIPATION; + att.scanlist3 = pVFO->SCANLIST3_PARTICIPATION; + att.compander = pVFO->Compander; + if (check && state[channel & 7u] == att.__val) + return; // no change in the attributes + } - state[channel & 7u] = att.__val; + state[channel & 7u] = att.__val; #ifdef ENABLE_FEAT_F4HWN - if(save) - { - EEPROM_WriteBuffer(offset, state); - } + if(save) + { + EEPROM_WriteBuffer(offset, state); + } #else - EEPROM_WriteBuffer(offset, state); + EEPROM_WriteBuffer(offset, state); #endif - gMR_ChannelAttributes[channel] = att; + gMR_ChannelAttributes[channel] = att; - if (IS_MR_CHANNEL(channel)) { // it's a memory channel - if (!keep) { - // clear/reset the channel name - SETTINGS_SaveChannelName(channel, ""); - } - } - } + if (IS_MR_CHANNEL(channel)) { // it's a memory channel + if (!keep) { + // clear/reset the channel name + SETTINGS_SaveChannelName(channel, ""); + } + } + } } void SETTINGS_WriteBuildOptions(void) { - uint8_t buf[8] = {0}; + uint8_t buf[8] = {0}; #ifdef ENABLE_FEAT_F4HWN - EEPROM_ReadBuffer(0x1FF0, buf, 8); + EEPROM_ReadBuffer(0x1FF0, buf, 8); #endif - + buf[0] = 0 #ifdef ENABLE_FMRADIO | (1 << 0) @@ -940,5 +940,5 @@ buf[1] = 0 | (1 << 5) #endif ; - EEPROM_WriteBuffer(0x1FF0, buf); + EEPROM_WriteBuffer(0x1FF0, buf); } \ No newline at end of file diff --git a/settings.h b/settings.h index 900421f..410a857 100644 --- a/settings.h +++ b/settings.h @@ -27,258 +27,258 @@ enum POWER_OnDisplayMode_t { #ifdef ENABLE_FEAT_F4HWN - POWER_ON_DISPLAY_MODE_ALL, - POWER_ON_DISPLAY_MODE_SOUND, + POWER_ON_DISPLAY_MODE_ALL, + POWER_ON_DISPLAY_MODE_SOUND, #else - POWER_ON_DISPLAY_MODE_FULL_SCREEN = 0, + POWER_ON_DISPLAY_MODE_FULL_SCREEN = 0, #endif - POWER_ON_DISPLAY_MODE_MESSAGE, - POWER_ON_DISPLAY_MODE_VOLTAGE, - POWER_ON_DISPLAY_MODE_NONE + POWER_ON_DISPLAY_MODE_MESSAGE, + POWER_ON_DISPLAY_MODE_VOLTAGE, + POWER_ON_DISPLAY_MODE_NONE }; typedef enum POWER_OnDisplayMode_t POWER_OnDisplayMode_t; enum TxLockModes_t { - F_LOCK_DEF, //all default frequencies + configurable - F_LOCK_FCC, + F_LOCK_DEF, //all default frequencies + configurable + F_LOCK_FCC, #ifdef ENABLE_FEAT_F4HWN_CA - F_LOCK_CA, + F_LOCK_CA, #endif - F_LOCK_CE, - F_LOCK_GB, - F_LOCK_430, - F_LOCK_438, + F_LOCK_CE, + F_LOCK_GB, + F_LOCK_430, + F_LOCK_438, #ifdef ENABLE_FEAT_F4HWN_PMR - F_LOCK_PMR, + F_LOCK_PMR, #endif #ifdef ENABLE_FEAT_F4HWN_GMRS_FRS_MURS - F_LOCK_GMRS_FRS_MURS, + F_LOCK_GMRS_FRS_MURS, #endif - F_LOCK_ALL, // disable TX on all frequencies - F_LOCK_NONE, // enable TX on all frequencies - F_LOCK_LEN + F_LOCK_ALL, // disable TX on all frequencies + F_LOCK_NONE, // enable TX on all frequencies + F_LOCK_LEN }; enum { - SCAN_RESUME_TO = 0, - SCAN_RESUME_CO, - SCAN_RESUME_SE + SCAN_RESUME_TO = 0, + SCAN_RESUME_CO, + SCAN_RESUME_SE }; enum { - CROSS_BAND_OFF = 0, - CROSS_BAND_CHAN_A, - CROSS_BAND_CHAN_B + CROSS_BAND_OFF = 0, + CROSS_BAND_CHAN_A, + CROSS_BAND_CHAN_B }; enum { - DUAL_WATCH_OFF = 0, - DUAL_WATCH_CHAN_A, - DUAL_WATCH_CHAN_B + DUAL_WATCH_OFF = 0, + DUAL_WATCH_CHAN_A, + DUAL_WATCH_CHAN_B }; enum { - TX_OFFSET_FREQUENCY_DIRECTION_OFF = 0, - TX_OFFSET_FREQUENCY_DIRECTION_ADD, - TX_OFFSET_FREQUENCY_DIRECTION_SUB + TX_OFFSET_FREQUENCY_DIRECTION_OFF = 0, + TX_OFFSET_FREQUENCY_DIRECTION_ADD, + TX_OFFSET_FREQUENCY_DIRECTION_SUB }; enum { - OUTPUT_POWER_USER = 0, - OUTPUT_POWER_LOW1, - OUTPUT_POWER_LOW2, - OUTPUT_POWER_LOW3, - OUTPUT_POWER_LOW4, - OUTPUT_POWER_LOW5, - OUTPUT_POWER_MID, - OUTPUT_POWER_HIGH + OUTPUT_POWER_USER = 0, + OUTPUT_POWER_LOW1, + OUTPUT_POWER_LOW2, + OUTPUT_POWER_LOW3, + OUTPUT_POWER_LOW4, + OUTPUT_POWER_LOW5, + OUTPUT_POWER_MID, + OUTPUT_POWER_HIGH }; enum ACTION_OPT_t { - ACTION_OPT_NONE = 0, - ACTION_OPT_FLASHLIGHT, - ACTION_OPT_POWER, - ACTION_OPT_MONITOR, - ACTION_OPT_SCAN, - ACTION_OPT_VOX, - ACTION_OPT_ALARM, - ACTION_OPT_FM, - ACTION_OPT_1750, - ACTION_OPT_KEYLOCK, - ACTION_OPT_A_B, - ACTION_OPT_VFO_MR, - ACTION_OPT_SWITCH_DEMODUL, - ACTION_OPT_BLMIN_TMP_OFF, //BackLight Minimum Temporay OFF + ACTION_OPT_NONE = 0, + ACTION_OPT_FLASHLIGHT, + ACTION_OPT_POWER, + ACTION_OPT_MONITOR, + ACTION_OPT_SCAN, + ACTION_OPT_VOX, + ACTION_OPT_ALARM, + ACTION_OPT_FM, + ACTION_OPT_1750, + ACTION_OPT_KEYLOCK, + ACTION_OPT_A_B, + ACTION_OPT_VFO_MR, + ACTION_OPT_SWITCH_DEMODUL, + ACTION_OPT_BLMIN_TMP_OFF, //BackLight Minimum Temporay OFF #ifdef ENABLE_FEAT_F4HWN - ACTION_OPT_RXMODE, - ACTION_OPT_MAINONLY, - ACTION_OPT_PTT, - ACTION_OPT_WN, - ACTION_OPT_BACKLIGHT, + ACTION_OPT_RXMODE, + ACTION_OPT_MAINONLY, + ACTION_OPT_PTT, + ACTION_OPT_WN, + ACTION_OPT_BACKLIGHT, #endif - ACTION_OPT_LEN + ACTION_OPT_LEN }; #ifdef ENABLE_VOICE - enum VOICE_Prompt_t - { - VOICE_PROMPT_OFF = 0, - VOICE_PROMPT_CHINESE, - VOICE_PROMPT_ENGLISH - }; - typedef enum VOICE_Prompt_t VOICE_Prompt_t; + enum VOICE_Prompt_t + { + VOICE_PROMPT_OFF = 0, + VOICE_PROMPT_CHINESE, + VOICE_PROMPT_ENGLISH + }; + typedef enum VOICE_Prompt_t VOICE_Prompt_t; #endif enum ALARM_Mode_t { - ALARM_MODE_SITE = 0, - ALARM_MODE_TONE + ALARM_MODE_SITE = 0, + ALARM_MODE_TONE }; typedef enum ALARM_Mode_t ALARM_Mode_t; enum ROGER_Mode_t { - ROGER_MODE_OFF = 0, - ROGER_MODE_ROGER, - ROGER_MODE_MDC + ROGER_MODE_OFF = 0, + ROGER_MODE_ROGER, + ROGER_MODE_MDC }; typedef enum ROGER_Mode_t ROGER_Mode_t; enum CHANNEL_DisplayMode_t { - MDF_FREQUENCY = 0, - MDF_CHANNEL, - MDF_NAME, - MDF_NAME_FREQ + MDF_FREQUENCY = 0, + MDF_CHANNEL, + MDF_NAME, + MDF_NAME_FREQ }; typedef enum CHANNEL_DisplayMode_t CHANNEL_DisplayMode_t; typedef struct { - uint8_t ScreenChannel[2]; // current channels set in the radio (memory or frequency channels) - uint8_t FreqChannel[2]; // last frequency channels used - uint8_t MrChannel[2]; // last memory channels used + uint8_t ScreenChannel[2]; // current channels set in the radio (memory or frequency channels) + uint8_t FreqChannel[2]; // last frequency channels used + uint8_t MrChannel[2]; // last memory channels used #ifdef ENABLE_NOAA - uint8_t NoaaChannel[2]; + uint8_t NoaaChannel[2]; #endif - // The actual VFO index (0-upper/1-lower) that is now used for RX, - // It is being alternated by dual watch, and flipped by crossband - uint8_t RX_VFO; + // The actual VFO index (0-upper/1-lower) that is now used for RX, + // It is being alternated by dual watch, and flipped by crossband + uint8_t RX_VFO; - // The main VFO index (0-upper/1-lower) selected by the user - // - uint8_t TX_VFO; + // The main VFO index (0-upper/1-lower) selected by the user + // + uint8_t TX_VFO; - uint8_t field7_0xa; - uint8_t field8_0xb; + uint8_t field7_0xa; + uint8_t field8_0xb; #ifdef ENABLE_FMRADIO - uint16_t FM_SelectedFrequency; - uint8_t FM_SelectedChannel; - bool FM_IsMrMode; - uint16_t FM_FrequencyPlaying; - uint8_t FM_Band : 2; - //uint8_t FM_Space : 2; + uint16_t FM_SelectedFrequency; + uint8_t FM_SelectedChannel; + bool FM_IsMrMode; + uint16_t FM_FrequencyPlaying; + uint8_t FM_Band : 2; + //uint8_t FM_Space : 2; #endif - uint8_t SQUELCH_LEVEL; - uint8_t TX_TIMEOUT_TIMER; - bool KEY_LOCK; + uint8_t SQUELCH_LEVEL; + uint8_t TX_TIMEOUT_TIMER; + bool KEY_LOCK; #ifdef ENABLE_FEAT_F4HWN - bool KEY_LOCK_PTT; + bool KEY_LOCK_PTT; #endif - bool VOX_SWITCH; - uint8_t VOX_LEVEL; + bool VOX_SWITCH; + uint8_t VOX_LEVEL; #ifdef ENABLE_VOICE - VOICE_Prompt_t VOICE_PROMPT; + VOICE_Prompt_t VOICE_PROMPT; #endif - bool BEEP_CONTROL; - uint8_t CHANNEL_DISPLAY_MODE; - bool TAIL_TONE_ELIMINATION; - bool VFO_OPEN; - uint8_t DUAL_WATCH; - uint8_t CROSS_BAND_RX_TX; - uint8_t BATTERY_SAVE; - uint8_t BACKLIGHT_TIME; - uint8_t SCAN_RESUME_MODE; - uint8_t SCAN_LIST_DEFAULT; - bool SCAN_LIST_ENABLED[3]; - uint8_t SCANLIST_PRIORITY_CH1[3]; - uint8_t SCANLIST_PRIORITY_CH2[3]; + bool BEEP_CONTROL; + uint8_t CHANNEL_DISPLAY_MODE; + bool TAIL_TONE_ELIMINATION; + bool VFO_OPEN; + uint8_t DUAL_WATCH; + uint8_t CROSS_BAND_RX_TX; + uint8_t BATTERY_SAVE; + uint8_t BACKLIGHT_TIME; + uint8_t SCAN_RESUME_MODE; + uint8_t SCAN_LIST_DEFAULT; + bool SCAN_LIST_ENABLED[3]; + uint8_t SCANLIST_PRIORITY_CH1[3]; + uint8_t SCANLIST_PRIORITY_CH2[3]; - uint8_t field29_0x26; - uint8_t field30_0x27; - - uint8_t field37_0x32; - uint8_t field38_0x33; + uint8_t field29_0x26; + uint8_t field30_0x27; + + uint8_t field37_0x32; + uint8_t field38_0x33; - bool AUTO_KEYPAD_LOCK; + bool AUTO_KEYPAD_LOCK; #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) - ALARM_Mode_t ALARM_MODE; + ALARM_Mode_t ALARM_MODE; #endif - POWER_OnDisplayMode_t POWER_ON_DISPLAY_MODE; - ROGER_Mode_t ROGER; - uint8_t REPEATER_TAIL_TONE_ELIMINATION; - uint8_t KEY_1_SHORT_PRESS_ACTION; - uint8_t KEY_1_LONG_PRESS_ACTION; - uint8_t KEY_2_SHORT_PRESS_ACTION; - uint8_t KEY_2_LONG_PRESS_ACTION; - uint8_t MIC_SENSITIVITY; - uint8_t MIC_SENSITIVITY_TUNING; - uint8_t CHAN_1_CALL; + POWER_OnDisplayMode_t POWER_ON_DISPLAY_MODE; + ROGER_Mode_t ROGER; + uint8_t REPEATER_TAIL_TONE_ELIMINATION; + uint8_t KEY_1_SHORT_PRESS_ACTION; + uint8_t KEY_1_LONG_PRESS_ACTION; + uint8_t KEY_2_SHORT_PRESS_ACTION; + uint8_t KEY_2_LONG_PRESS_ACTION; + uint8_t MIC_SENSITIVITY; + uint8_t MIC_SENSITIVITY_TUNING; + uint8_t CHAN_1_CALL; #ifdef ENABLE_DTMF_CALLING - char ANI_DTMF_ID[8]; - char KILL_CODE[8]; - char REVIVE_CODE[8]; + char ANI_DTMF_ID[8]; + char KILL_CODE[8]; + char REVIVE_CODE[8]; #endif - char DTMF_UP_CODE[16]; + char DTMF_UP_CODE[16]; - uint8_t field57_0x6c; - uint8_t field58_0x6d; + uint8_t field57_0x6c; + uint8_t field58_0x6d; - char DTMF_DOWN_CODE[16]; + char DTMF_DOWN_CODE[16]; - uint8_t field60_0x7e; - uint8_t field61_0x7f; + uint8_t field60_0x7e; + uint8_t field61_0x7f; #ifdef ENABLE_DTMF_CALLING - char DTMF_SEPARATE_CODE; - char DTMF_GROUP_CALL_CODE; - uint8_t DTMF_DECODE_RESPONSE; - uint8_t DTMF_auto_reset_time; -#endif - uint16_t DTMF_PRELOAD_TIME; - uint16_t DTMF_FIRST_CODE_PERSIST_TIME; - uint16_t DTMF_HASH_CODE_PERSIST_TIME; - uint16_t DTMF_CODE_PERSIST_TIME; - uint16_t DTMF_CODE_INTERVAL_TIME; - bool DTMF_SIDE_TONE; + char DTMF_SEPARATE_CODE; + char DTMF_GROUP_CALL_CODE; + uint8_t DTMF_DECODE_RESPONSE; + uint8_t DTMF_auto_reset_time; +#endif + uint16_t DTMF_PRELOAD_TIME; + uint16_t DTMF_FIRST_CODE_PERSIST_TIME; + uint16_t DTMF_HASH_CODE_PERSIST_TIME; + uint16_t DTMF_CODE_PERSIST_TIME; + uint16_t DTMF_CODE_INTERVAL_TIME; + bool DTMF_SIDE_TONE; #ifdef ENABLE_DTMF_CALLING - bool PERMIT_REMOTE_KILL; + bool PERMIT_REMOTE_KILL; #endif - int16_t BK4819_XTAL_FREQ_LOW; + int16_t BK4819_XTAL_FREQ_LOW; #ifdef ENABLE_NOAA - bool NOAA_AUTO_SCAN; + bool NOAA_AUTO_SCAN; #endif - uint8_t VOLUME_GAIN; - uint8_t DAC_GAIN; + uint8_t VOLUME_GAIN; + uint8_t DAC_GAIN; - VFO_Info_t VfoInfo[2]; - uint32_t POWER_ON_PASSWORD; - uint16_t VOX1_THRESHOLD; - uint16_t VOX0_THRESHOLD; + VFO_Info_t VfoInfo[2]; + uint32_t POWER_ON_PASSWORD; + uint16_t VOX1_THRESHOLD; + uint16_t VOX0_THRESHOLD; - uint8_t field77_0x95; - uint8_t field78_0x96; - uint8_t field79_0x97; + uint8_t field77_0x95; + uint8_t field78_0x96; + uint8_t field79_0x97; - uint8_t KEY_M_LONG_PRESS_ACTION; - uint8_t BACKLIGHT_MIN; + uint8_t KEY_M_LONG_PRESS_ACTION; + uint8_t BACKLIGHT_MIN; #ifdef ENABLE_BLMIN_TMP_OFF - BLMIN_STAT_t BACKLIGHT_MIN_STAT; + BLMIN_STAT_t BACKLIGHT_MIN_STAT; #endif - uint8_t BACKLIGHT_MAX; - BATTERY_Type_t BATTERY_TYPE; + uint8_t BACKLIGHT_MAX; + BATTERY_Type_t BATTERY_TYPE; #ifdef ENABLE_RSSI_BAR - uint8_t S0_LEVEL; - uint8_t S9_LEVEL; + uint8_t S0_LEVEL; + uint8_t S9_LEVEL; #endif } EEPROM_Config_t; @@ -290,7 +290,7 @@ uint32_t SETTINGS_FetchChannelFrequency(const int channel); void SETTINGS_FetchChannelName(char *s, const int channel); void SETTINGS_FactoryReset(bool bIsAll); #ifdef ENABLE_FMRADIO - void SETTINGS_SaveFM(void); + void SETTINGS_SaveFM(void); #endif void SETTINGS_SaveVfoIndices(void); void SETTINGS_SaveSettings(void); diff --git a/sram-overlay.c b/sram-overlay.c index 844351e..96bb0a9 100644 --- a/sram-overlay.c +++ b/sram-overlay.c @@ -27,172 +27,172 @@ uint32_t overlay_0x20000478; // Nothing is using this?? void overlay_FLASH_RebootToBootloader(void) { - overlay_FLASH_MaskUnlock(); - overlay_FLASH_SetMaskSel(FLASH_MASK_SELECTION_NONE); - overlay_FLASH_MaskLock(); - overlay_SystemReset(); + overlay_FLASH_MaskUnlock(); + overlay_FLASH_SetMaskSel(FLASH_MASK_SELECTION_NONE); + overlay_FLASH_MaskLock(); + overlay_SystemReset(); } bool overlay_FLASH_IsBusy(void) { - return (FLASH_ST & FLASH_ST_BUSY_MASK) != FLASH_ST_BUSY_BITS_READY; + return (FLASH_ST & FLASH_ST_BUSY_MASK) != FLASH_ST_BUSY_BITS_READY; } bool overlay_FLASH_IsInitComplete(void) { - return (FLASH_ST & FLASH_ST_INIT_BUSY_MASK) == FLASH_ST_INIT_BUSY_BITS_COMPLETE; + return (FLASH_ST & FLASH_ST_INIT_BUSY_MASK) == FLASH_ST_INIT_BUSY_BITS_COMPLETE; } void overlay_FLASH_Start(void) { - overlay_FLASH_Unlock(); - FLASH_START |= FLASH_START_START_BITS_START; + overlay_FLASH_Unlock(); + FLASH_START |= FLASH_START_START_BITS_START; } void overlay_FLASH_Init(FLASH_READ_MODE ReadMode) { - overlay_FLASH_WakeFromDeepSleep(); - overlay_FLASH_SetMode(FLASH_MODE_READ_AHB); - overlay_FLASH_SetReadMode(ReadMode); - overlay_FLASH_SetEraseTime(); - overlay_FLASH_SetProgramTime(); - overlay_FLASH_Lock(); + overlay_FLASH_WakeFromDeepSleep(); + overlay_FLASH_SetMode(FLASH_MODE_READ_AHB); + overlay_FLASH_SetReadMode(ReadMode); + overlay_FLASH_SetEraseTime(); + overlay_FLASH_SetProgramTime(); + overlay_FLASH_Lock(); } void overlay_FLASH_MaskLock(void) { - FLASH_MASK = (FLASH_MASK & ~FLASH_MASK_LOCK_MASK) | FLASH_MASK_LOCK_BITS_SET; + FLASH_MASK = (FLASH_MASK & ~FLASH_MASK_LOCK_MASK) | FLASH_MASK_LOCK_BITS_SET; } void overlay_FLASH_SetMaskSel(FLASH_MASK_SELECTION Mask) { - FLASH_MASK = (FLASH_MASK & ~FLASH_MASK_SEL_MASK) | ((Mask << FLASH_MASK_SEL_SHIFT) & FLASH_MASK_SEL_MASK); + FLASH_MASK = (FLASH_MASK & ~FLASH_MASK_SEL_MASK) | ((Mask << FLASH_MASK_SEL_SHIFT) & FLASH_MASK_SEL_MASK); } void overlay_FLASH_MaskUnlock(void) { - FLASH_MASK = (FLASH_MASK & ~FLASH_MASK_LOCK_MASK) | FLASH_MASK_LOCK_BITS_NOT_SET; + FLASH_MASK = (FLASH_MASK & ~FLASH_MASK_LOCK_MASK) | FLASH_MASK_LOCK_BITS_NOT_SET; } void overlay_FLASH_Lock(void) { - FLASH_LOCK = FLASH_LOCK_LOCK_BITS_LOCK; + FLASH_LOCK = FLASH_LOCK_LOCK_BITS_LOCK; } void overlay_FLASH_Unlock(void) { - FLASH_UNLOCK = FLASH_UNLOCK_UNLOCK_BITS_UNLOCK; + FLASH_UNLOCK = FLASH_UNLOCK_UNLOCK_BITS_UNLOCK; } uint32_t overlay_FLASH_ReadByAHB(uint32_t Offset) { - return pFlash[(Offset & ~3U) / 4]; + return pFlash[(Offset & ~3U) / 4]; } uint32_t overlay_FLASH_ReadByAPB(uint32_t Offset) { - uint32_t Data; + uint32_t Data; - while (overlay_FLASH_IsBusy()) {} + while (overlay_FLASH_IsBusy()) {} - overlay_FLASH_SetMode(FLASH_MODE_READ_APB); - FLASH_ADDR = Offset >> 2; + overlay_FLASH_SetMode(FLASH_MODE_READ_APB); + FLASH_ADDR = Offset >> 2; - overlay_FLASH_Start(); + overlay_FLASH_Start(); - while (overlay_FLASH_IsBusy()) {} + while (overlay_FLASH_IsBusy()) {} - Data = FLASH_RDATA; + Data = FLASH_RDATA; - overlay_FLASH_SetMode(FLASH_MODE_READ_AHB); - overlay_FLASH_Lock(); + overlay_FLASH_SetMode(FLASH_MODE_READ_AHB); + overlay_FLASH_Lock(); - return Data; + return Data; } void overlay_FLASH_SetArea(FLASH_AREA Area) { - FLASH_CFG = (FLASH_CFG & ~FLASH_CFG_NVR_SEL_MASK) | ((Area << FLASH_CFG_NVR_SEL_SHIFT) & FLASH_CFG_NVR_SEL_MASK); + FLASH_CFG = (FLASH_CFG & ~FLASH_CFG_NVR_SEL_MASK) | ((Area << FLASH_CFG_NVR_SEL_SHIFT) & FLASH_CFG_NVR_SEL_MASK); } void overlay_FLASH_SetReadMode(FLASH_READ_MODE Mode) { - if (Mode == FLASH_READ_MODE_1_CYCLE) - FLASH_CFG = (FLASH_CFG & ~FLASH_CFG_READ_MD_MASK) | FLASH_CFG_READ_MD_BITS_1_CYCLE; - else - if (Mode == FLASH_READ_MODE_2_CYCLE) - FLASH_CFG = (FLASH_CFG & ~FLASH_CFG_READ_MD_MASK) | FLASH_CFG_READ_MD_BITS_2_CYCLE; + if (Mode == FLASH_READ_MODE_1_CYCLE) + FLASH_CFG = (FLASH_CFG & ~FLASH_CFG_READ_MD_MASK) | FLASH_CFG_READ_MD_BITS_1_CYCLE; + else + if (Mode == FLASH_READ_MODE_2_CYCLE) + FLASH_CFG = (FLASH_CFG & ~FLASH_CFG_READ_MD_MASK) | FLASH_CFG_READ_MD_BITS_2_CYCLE; } void overlay_FLASH_SetEraseTime(void) { - FLASH_ERASETIME = ((overlay_FLASH_ClockMultiplier & 0xFFFFU) * 0x1A00000U) + (overlay_FLASH_ClockMultiplier * 3600U); + FLASH_ERASETIME = ((overlay_FLASH_ClockMultiplier & 0xFFFFU) * 0x1A00000U) + (overlay_FLASH_ClockMultiplier * 3600U); } void overlay_FLASH_WakeFromDeepSleep(void) { - FLASH_CFG = (FLASH_CFG & ~FLASH_CFG_DEEP_PD_MASK) | FLASH_CFG_DEEP_PD_BITS_NORMAL; - while (!overlay_FLASH_IsInitComplete()) {} + FLASH_CFG = (FLASH_CFG & ~FLASH_CFG_DEEP_PD_MASK) | FLASH_CFG_DEEP_PD_BITS_NORMAL; + while (!overlay_FLASH_IsInitComplete()) {} } void overlay_FLASH_SetMode(FLASH_MODE Mode) { - FLASH_CFG = (FLASH_CFG & ~FLASH_CFG_MODE_MASK) | ((Mode << FLASH_CFG_MODE_SHIFT) & FLASH_CFG_MODE_MASK); + FLASH_CFG = (FLASH_CFG & ~FLASH_CFG_MODE_MASK) | ((Mode << FLASH_CFG_MODE_SHIFT) & FLASH_CFG_MODE_MASK); } void overlay_FLASH_SetProgramTime(void) { - FLASH_PROGTIME = overlay_FLASH_ClockMultiplier * 45074; + FLASH_PROGTIME = overlay_FLASH_ClockMultiplier * 45074; } void overlay_SystemReset(void) { - // Lifted from core_cm0.h to preserve function order in the object file. + // Lifted from core_cm0.h to preserve function order in the object file. - __DSB(); // Ensure all outstanding memory accesses included buffered write are completed before reset - SCB->AIRCR = (0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk; - __DSB(); // Ensure completion of memory access + __DSB(); // Ensure all outstanding memory accesses included buffered write are completed before reset + SCB->AIRCR = (0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk; + __DSB(); // Ensure completion of memory access - for (;;) // wait until reset - __NOP(); + for (;;) // wait until reset + __NOP(); } uint32_t overlay_FLASH_ReadNvrWord(uint32_t Offset) { - uint32_t Data; - overlay_FLASH_SetArea(FLASH_AREA_NVR); - Data = overlay_FLASH_ReadByAHB(Offset); - overlay_FLASH_SetArea(FLASH_AREA_MAIN); - return Data; + uint32_t Data; + overlay_FLASH_SetArea(FLASH_AREA_NVR); + Data = overlay_FLASH_ReadByAHB(Offset); + overlay_FLASH_SetArea(FLASH_AREA_MAIN); + return Data; } void overlay_FLASH_ConfigureTrimValues(void) { - uint32_t Data; + uint32_t Data; - overlay_FLASH_SetArea(FLASH_AREA_NVR); + overlay_FLASH_SetArea(FLASH_AREA_NVR); - SYSCON_CHIP_ID0 = overlay_FLASH_ReadByAPB(0xF018); - SYSCON_CHIP_ID1 = overlay_FLASH_ReadByAPB(0xF01C); - SYSCON_CHIP_ID2 = overlay_FLASH_ReadByAPB(0xF020); - SYSCON_CHIP_ID3 = overlay_FLASH_ReadByAPB(0xF024); + SYSCON_CHIP_ID0 = overlay_FLASH_ReadByAPB(0xF018); + SYSCON_CHIP_ID1 = overlay_FLASH_ReadByAPB(0xF01C); + SYSCON_CHIP_ID2 = overlay_FLASH_ReadByAPB(0xF020); + SYSCON_CHIP_ID3 = overlay_FLASH_ReadByAPB(0xF024); - SYSCON_RC_FREQ_DELTA = overlay_FLASH_ReadByAHB(0x07C8); - SYSCON_VREF_VOLT_DELTA = overlay_FLASH_ReadByAHB(0x07C4); + SYSCON_RC_FREQ_DELTA = overlay_FLASH_ReadByAHB(0x07C8); + SYSCON_VREF_VOLT_DELTA = overlay_FLASH_ReadByAHB(0x07C4); - PMU_TRIM_POW0 = overlay_FLASH_ReadByAHB(0x07E4); - PMU_TRIM_POW1 = overlay_FLASH_ReadByAHB(0x07E0); - PMU_TRIM_RCHF = overlay_FLASH_ReadByAHB(0x07D8); - PMU_TRIM_RCLF = overlay_FLASH_ReadByAHB(0x07D4); - PMU_TRIM_OPA = overlay_FLASH_ReadByAHB(0x07D0); - PMU_TRIM_PLL = overlay_FLASH_ReadByAHB(0x07CC); + PMU_TRIM_POW0 = overlay_FLASH_ReadByAHB(0x07E4); + PMU_TRIM_POW1 = overlay_FLASH_ReadByAHB(0x07E0); + PMU_TRIM_RCHF = overlay_FLASH_ReadByAHB(0x07D8); + PMU_TRIM_RCLF = overlay_FLASH_ReadByAHB(0x07D4); + PMU_TRIM_OPA = overlay_FLASH_ReadByAHB(0x07D0); + PMU_TRIM_PLL = overlay_FLASH_ReadByAHB(0x07CC); - overlay_0x20000478 = overlay_FLASH_ReadByAHB(0x07B8); + overlay_0x20000478 = overlay_FLASH_ReadByAHB(0x07B8); - Data = overlay_FLASH_ReadByAHB(0x07BC); - SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SARADC_MASK) | SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE; - SARADC_CALIB_OFFSET = ((Data & 0xFFFF) << SARADC_CALIB_OFFSET_OFFSET_SHIFT) & SARADC_CALIB_OFFSET_OFFSET_MASK; - SARADC_CALIB_KD = (((Data >> 16) & 0xFFFF) << SARADC_CALIB_KD_KD_SHIFT) & SARADC_CALIB_KD_KD_MASK; - overlay_FLASH_SetArea(FLASH_AREA_MAIN); + Data = overlay_FLASH_ReadByAHB(0x07BC); + SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SARADC_MASK) | SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE; + SARADC_CALIB_OFFSET = ((Data & 0xFFFF) << SARADC_CALIB_OFFSET_OFFSET_SHIFT) & SARADC_CALIB_OFFSET_OFFSET_MASK; + SARADC_CALIB_KD = (((Data >> 16) & 0xFFFF) << SARADC_CALIB_KD_KD_SHIFT) & SARADC_CALIB_KD_KD_MASK; + overlay_FLASH_SetArea(FLASH_AREA_MAIN); } diff --git a/ui/aircopy.c b/ui/aircopy.c index 0c3da4c..8dd1666 100644 --- a/ui/aircopy.c +++ b/ui/aircopy.c @@ -37,83 +37,83 @@ static int get_bit(uint8_t* array, int bit_index) { void UI_DisplayAircopy(void) { - char String[16] = { 0 }; - char *pPrintStr = { 0 }; - uint16_t percent; + char String[16] = { 0 }; + char *pPrintStr = { 0 }; + uint16_t percent; - UI_DisplayClear(); + UI_DisplayClear(); - if (gAircopyState == AIRCOPY_READY) { - pPrintStr = "AIR COPY(RDY)"; - } else if (gAircopyState == AIRCOPY_TRANSFER) { - pPrintStr = "AIR COPY"; - } else { - pPrintStr = "AIR COPY(CMP)"; - gAircopyState = AIRCOPY_READY; - } + if (gAircopyState == AIRCOPY_READY) { + pPrintStr = "AIR COPY(RDY)"; + } else if (gAircopyState == AIRCOPY_TRANSFER) { + pPrintStr = "AIR COPY"; + } else { + pPrintStr = "AIR COPY(CMP)"; + gAircopyState = AIRCOPY_READY; + } - UI_PrintString(pPrintStr, 2, 127, 0, 8); + UI_PrintString(pPrintStr, 2, 127, 0, 8); - if (gInputBoxIndex == 0) { - uint32_t frequency = gRxVfo->freq_config_RX.Frequency; - sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000); - // show the remaining 2 small frequency digits - UI_PrintStringSmallNormal(String + 7, 97, 0, 3); - String[7] = 0; - // show the main large frequency digits - UI_DisplayFrequency(String, 16, 2, false); - } else { - const char *ascii = INPUTBOX_GetAscii(); - sprintf(String, "%.3s.%.3s", ascii, ascii + 3); - UI_DisplayFrequency(String, 16, 2, false); - } + if (gInputBoxIndex == 0) { + uint32_t frequency = gRxVfo->freq_config_RX.Frequency; + sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000); + // show the remaining 2 small frequency digits + UI_PrintStringSmallNormal(String + 7, 97, 0, 3); + String[7] = 0; + // show the main large frequency digits + UI_DisplayFrequency(String, 16, 2, false); + } else { + const char *ascii = INPUTBOX_GetAscii(); + sprintf(String, "%.3s.%.3s", ascii, ascii + 3); + UI_DisplayFrequency(String, 16, 2, false); + } - memset(String, 0, sizeof(String)); + memset(String, 0, sizeof(String)); - percent = (gAirCopyBlockNumber * 10000) / 120; + percent = (gAirCopyBlockNumber * 10000) / 120; - if (gAirCopyIsSendMode == 0) { - sprintf(String, "RCV:%02u.%02u%% E:%d", percent / 100, percent % 100, gErrorsDuringAirCopy); - } else if (gAirCopyIsSendMode == 1) { - sprintf(String, "SND:%02u.%02u%%", percent / 100, percent % 100); - } + if (gAirCopyIsSendMode == 0) { + sprintf(String, "RCV:%02u.%02u%% E:%d", percent / 100, percent % 100, gErrorsDuringAirCopy); + } else if (gAirCopyIsSendMode == 1) { + sprintf(String, "SND:%02u.%02u%%", percent / 100, percent % 100); + } - // Draw gauge - if(gAircopyStep != 0) - { - UI_PrintString(String, 2, 127, 5, 8); + // Draw gauge + if(gAircopyStep != 0) + { + UI_PrintString(String, 2, 127, 5, 8); - gFrameBuffer[4][1] = 0x3c; - gFrameBuffer[4][2] = 0x42; + gFrameBuffer[4][1] = 0x3c; + gFrameBuffer[4][2] = 0x42; - for(uint8_t i = 1; i <= 122; i++) - { - gFrameBuffer[4][2 + i] = 0x81; - } + for(uint8_t i = 1; i <= 122; i++) + { + gFrameBuffer[4][2 + i] = 0x81; + } - gFrameBuffer[4][125] = 0x42; - gFrameBuffer[4][126] = 0x3c; - } + gFrameBuffer[4][125] = 0x42; + gFrameBuffer[4][126] = 0x3c; + } - if(gAirCopyBlockNumber + gErrorsDuringAirCopy != 0) - { - // Check CRC - if(gErrorsDuringAirCopy != lErrorsDuringAirCopy) - { - set_bit(crc, gAirCopyBlockNumber + gErrorsDuringAirCopy); - lErrorsDuringAirCopy = gErrorsDuringAirCopy; - } + if(gAirCopyBlockNumber + gErrorsDuringAirCopy != 0) + { + // Check CRC + if(gErrorsDuringAirCopy != lErrorsDuringAirCopy) + { + set_bit(crc, gAirCopyBlockNumber + gErrorsDuringAirCopy); + lErrorsDuringAirCopy = gErrorsDuringAirCopy; + } - for(uint8_t i = 0; i < (gAirCopyBlockNumber + gErrorsDuringAirCopy); i++) - { - if(get_bit(crc, i) == 0) - { - gFrameBuffer[4][i + 4] = 0xbd; - } - } - } + for(uint8_t i = 0; i < (gAirCopyBlockNumber + gErrorsDuringAirCopy); i++) + { + if(get_bit(crc, i) == 0) + { + gFrameBuffer[4][i + 4] = 0xbd; + } + } + } - ST7565_BlitFullScreen(); + ST7565_BlitFullScreen(); } #endif diff --git a/ui/aircopy.h b/ui/aircopy.h index 2c78aec..186e86b 100644 --- a/ui/aircopy.h +++ b/ui/aircopy.h @@ -18,7 +18,7 @@ #define UI_AIRCOPY_H #ifdef ENABLE_AIRCOPY - void UI_DisplayAircopy(void); + void UI_DisplayAircopy(void); #endif #endif diff --git a/ui/battery.c b/ui/battery.c index 1dd8e75..ec0f777 100644 --- a/ui/battery.c +++ b/ui/battery.c @@ -25,31 +25,31 @@ void UI_DrawBattery(uint8_t* bitmap, uint8_t level, uint8_t blink) { - if (level < 2 && blink == 1) { - memset(bitmap, 0, sizeof(BITMAP_BatteryLevel1)); - return; - } + if (level < 2 && blink == 1) { + memset(bitmap, 0, sizeof(BITMAP_BatteryLevel1)); + return; + } - memcpy(bitmap, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1)); + memcpy(bitmap, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1)); - if (level <= 2) { - return; - } + if (level <= 2) { + return; + } - const uint8_t bars = MIN(4, level - 2); + const uint8_t bars = MIN(4, level - 2); - for (int i = 0; i < bars; i++) { + for (int i = 0; i < bars; i++) { #ifndef ENABLE_REVERSE_BAT_SYMBOL - memcpy(bitmap + sizeof(BITMAP_BatteryLevel1) - 4 - (i * 3), BITMAP_BatteryLevel, 2); + memcpy(bitmap + sizeof(BITMAP_BatteryLevel1) - 4 - (i * 3), BITMAP_BatteryLevel, 2); #else - memcpy(bitmap + 3 + (i * 3) + 0, BITMAP_BatteryLevel, 2); + memcpy(bitmap + 3 + (i * 3) + 0, BITMAP_BatteryLevel, 2); #endif - } + } } void UI_DisplayBattery(uint8_t level, uint8_t blink) { - uint8_t bitmap[sizeof(BITMAP_BatteryLevel1)]; - UI_DrawBattery(bitmap, level, blink); - ST7565_DrawLine(LCD_WIDTH - sizeof(bitmap), 0, bitmap, sizeof(bitmap)); + uint8_t bitmap[sizeof(BITMAP_BatteryLevel1)]; + UI_DrawBattery(bitmap, level, blink); + ST7565_DrawLine(LCD_WIDTH - sizeof(bitmap), 0, bitmap, sizeof(bitmap)); } diff --git a/ui/fmradio.c b/ui/fmradio.c index 022464b..f6f20c1 100644 --- a/ui/fmradio.c +++ b/ui/fmradio.c @@ -31,72 +31,72 @@ void UI_DisplayFM(void) { - char String[16] = {0}; - char *pPrintStr = String; - UI_DisplayClear(); + char String[16] = {0}; + char *pPrintStr = String; + UI_DisplayClear(); - UI_PrintString("FM", 2, 0, 0, 8); + UI_PrintString("FM", 2, 0, 0, 8); - sprintf(String, "%d%s-%dM", - BK1080_GetFreqLoLimit(gEeprom.FM_Band)/10, - gEeprom.FM_Band == 0 ? ".5" : "", - BK1080_GetFreqHiLimit(gEeprom.FM_Band)/10 - ); - - UI_PrintStringSmallNormal(String, 1, 0, 6); + sprintf(String, "%d%s-%dM", + BK1080_GetFreqLoLimit(gEeprom.FM_Band)/10, + gEeprom.FM_Band == 0 ? ".5" : "", + BK1080_GetFreqHiLimit(gEeprom.FM_Band)/10 + ); + + UI_PrintStringSmallNormal(String, 1, 0, 6); - //uint8_t spacings[] = {20,10,5}; - //sprintf(String, "%d0k", spacings[gEeprom.FM_Space % 3]); - //UI_PrintStringSmallNormal(String, 127 - 4*7, 0, 6); + //uint8_t spacings[] = {20,10,5}; + //sprintf(String, "%d0k", spacings[gEeprom.FM_Space % 3]); + //UI_PrintStringSmallNormal(String, 127 - 4*7, 0, 6); - if (gAskToSave) { - pPrintStr = "SAVE?"; - } else if (gAskToDelete) { - pPrintStr = "DEL?"; - } else if (gFM_ScanState == FM_SCAN_OFF) { - if (gEeprom.FM_IsMrMode) { - sprintf(String, "MR(CH%02u)", gEeprom.FM_SelectedChannel + 1); - pPrintStr = String; - } else { - pPrintStr = "VFO"; - for (unsigned int i = 0; i < 20; i++) { - if (gEeprom.FM_FrequencyPlaying == gFM_Channels[i]) { - sprintf(String, "VFO(CH%02u)", i + 1); - pPrintStr = String; - break; - } - } - } - } else if (gFM_AutoScan) { - sprintf(String, "A-SCAN(%u)", gFM_ChannelPosition + 1); - pPrintStr = String; - } else { - pPrintStr = "M-SCAN"; - } + if (gAskToSave) { + pPrintStr = "SAVE?"; + } else if (gAskToDelete) { + pPrintStr = "DEL?"; + } else if (gFM_ScanState == FM_SCAN_OFF) { + if (gEeprom.FM_IsMrMode) { + sprintf(String, "MR(CH%02u)", gEeprom.FM_SelectedChannel + 1); + pPrintStr = String; + } else { + pPrintStr = "VFO"; + for (unsigned int i = 0; i < 20; i++) { + if (gEeprom.FM_FrequencyPlaying == gFM_Channels[i]) { + sprintf(String, "VFO(CH%02u)", i + 1); + pPrintStr = String; + break; + } + } + } + } else if (gFM_AutoScan) { + sprintf(String, "A-SCAN(%u)", gFM_ChannelPosition + 1); + pPrintStr = String; + } else { + pPrintStr = "M-SCAN"; + } - UI_PrintString(pPrintStr, 0, 127, 3, 10); // memory, vfo, scan + UI_PrintString(pPrintStr, 0, 127, 3, 10); // memory, vfo, scan - memset(String, 0, sizeof(String)); - if (gAskToSave || (gEeprom.FM_IsMrMode && gInputBoxIndex > 0)) { - UI_GenerateChannelString(String, gFM_ChannelPosition); - } else if (gAskToDelete) { - sprintf(String, "CH-%02u", gEeprom.FM_SelectedChannel + 1); - } else { - if (gInputBoxIndex == 0) { - sprintf(String, "%3d.%d", gEeprom.FM_FrequencyPlaying / 10, gEeprom.FM_FrequencyPlaying % 10); - } else { - const char * ascii = INPUTBOX_GetAscii(); - sprintf(String, "%.3s.%.1s",ascii, ascii + 3); - } + memset(String, 0, sizeof(String)); + if (gAskToSave || (gEeprom.FM_IsMrMode && gInputBoxIndex > 0)) { + UI_GenerateChannelString(String, gFM_ChannelPosition); + } else if (gAskToDelete) { + sprintf(String, "CH-%02u", gEeprom.FM_SelectedChannel + 1); + } else { + if (gInputBoxIndex == 0) { + sprintf(String, "%3d.%d", gEeprom.FM_FrequencyPlaying / 10, gEeprom.FM_FrequencyPlaying % 10); + } else { + const char * ascii = INPUTBOX_GetAscii(); + sprintf(String, "%.3s.%.1s",ascii, ascii + 3); + } - UI_DisplayFrequency(String, 36, 1, gInputBoxIndex == 0); // frequency - ST7565_BlitFullScreen(); - return; - } + UI_DisplayFrequency(String, 36, 1, gInputBoxIndex == 0); // frequency + ST7565_BlitFullScreen(); + return; + } - UI_PrintString(String, 0, 127, 1, 10); + UI_PrintString(String, 0, 127, 1, 10); - ST7565_BlitFullScreen(); + ST7565_BlitFullScreen(); } #endif diff --git a/ui/fmradio.h b/ui/fmradio.h index 9aee109..b1f7e31 100644 --- a/ui/fmradio.h +++ b/ui/fmradio.h @@ -18,7 +18,7 @@ #define UI_FM_H #ifdef ENABLE_FMRADIO - void UI_DisplayFM(void); + void UI_DisplayFM(void); #endif #endif diff --git a/ui/helper.c b/ui/helper.c index e462970..c42c445 100644 --- a/ui/helper.c +++ b/ui/helper.c @@ -24,288 +24,288 @@ #include "misc.h" #ifndef ARRAY_SIZE - #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0])) + #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0])) #endif void UI_GenerateChannelString(char *pString, const uint8_t Channel) { - unsigned int i; + unsigned int i; - if (gInputBoxIndex == 0) - { - sprintf(pString, "CH-%02u", Channel + 1); - return; - } + if (gInputBoxIndex == 0) + { + sprintf(pString, "CH-%02u", Channel + 1); + return; + } - pString[0] = 'C'; - pString[1] = 'H'; - pString[2] = '-'; - for (i = 0; i < 2; i++) - pString[i + 3] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0'; + pString[0] = 'C'; + pString[1] = 'H'; + pString[2] = '-'; + for (i = 0; i < 2; i++) + pString[i + 3] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0'; } void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uint8_t ChannelNumber) { - if (gInputBoxIndex > 0) { - for (unsigned int i = 0; i < 3; i++) { - pString[i] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0'; - } + if (gInputBoxIndex > 0) { + for (unsigned int i = 0; i < 3; i++) { + pString[i] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0'; + } - pString[3] = 0; - return; - } + pString[3] = 0; + return; + } - if (bShowPrefix) { - // BUG here? Prefixed NULLs are allowed - sprintf(pString, "CH-%03u", ChannelNumber + 1); - } else if (ChannelNumber == 0xFF) { - strcpy(pString, "NULL"); - } else { - sprintf(pString, "%03u", ChannelNumber + 1); - } + if (bShowPrefix) { + // BUG here? Prefixed NULLs are allowed + sprintf(pString, "CH-%03u", ChannelNumber + 1); + } else if (ChannelNumber == 0xFF) { + strcpy(pString, "NULL"); + } else { + sprintf(pString, "%03u", ChannelNumber + 1); + } } void UI_PrintStringBuffer(const char *pString, uint8_t * buffer, uint32_t char_width, const uint8_t *font) { - const size_t Length = strlen(pString); - const unsigned int char_spacing = char_width + 1; - for (size_t i = 0; i < Length; i++) { - const unsigned int index = pString[i] - ' ' - 1; - if (pString[i] > ' ' && pString[i] < 127) { - const uint32_t offset = i * char_spacing + 1; - memcpy(buffer + offset, font + index * char_width, char_width); - } - } + const size_t Length = strlen(pString); + const unsigned int char_spacing = char_width + 1; + for (size_t i = 0; i < Length; i++) { + const unsigned int index = pString[i] - ' ' - 1; + if (pString[i] > ' ' && pString[i] < 127) { + const uint32_t offset = i * char_spacing + 1; + memcpy(buffer + offset, font + index * char_width, char_width); + } + } } void UI_PrintString(const char *pString, uint8_t Start, uint8_t End, uint8_t Line, uint8_t Width) { - size_t i; - size_t Length = strlen(pString); + size_t i; + size_t Length = strlen(pString); - if (End > Start) - Start += (((End - Start) - (Length * Width)) + 1) / 2; + if (End > Start) + Start += (((End - Start) - (Length * Width)) + 1) / 2; - for (i = 0; i < Length; i++) - { - const unsigned int ofs = (unsigned int)Start + (i * Width); - if (pString[i] > ' ' && pString[i] < 127) - { - const unsigned int index = pString[i] - ' ' - 1; - memcpy(gFrameBuffer[Line + 0] + ofs, &gFontBig[index][0], 7); - memcpy(gFrameBuffer[Line + 1] + ofs, &gFontBig[index][7], 7); - } - } + for (i = 0; i < Length; i++) + { + const unsigned int ofs = (unsigned int)Start + (i * Width); + if (pString[i] > ' ' && pString[i] < 127) + { + const unsigned int index = pString[i] - ' ' - 1; + memcpy(gFrameBuffer[Line + 0] + ofs, &gFontBig[index][0], 7); + memcpy(gFrameBuffer[Line + 1] + ofs, &gFontBig[index][7], 7); + } + } } void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_t Line, uint8_t char_width, const uint8_t *font) { - const size_t Length = strlen(pString); - const unsigned int char_spacing = char_width + 1; + const size_t Length = strlen(pString); + const unsigned int char_spacing = char_width + 1; - if (End > Start) { - Start += (((End - Start) - Length * char_spacing) + 1) / 2; - } + if (End > Start) { + Start += (((End - Start) - Length * char_spacing) + 1) / 2; + } - UI_PrintStringBuffer(pString, gFrameBuffer[Line] + Start, char_width, font); + UI_PrintStringBuffer(pString, gFrameBuffer[Line] + Start, char_width, font); } void UI_PrintStringSmallNormal(const char *pString, uint8_t Start, uint8_t End, uint8_t Line) { - UI_PrintStringSmall(pString, Start, End, Line, ARRAY_SIZE(gFontSmall[0]), (const uint8_t *)gFontSmall); + UI_PrintStringSmall(pString, Start, End, Line, ARRAY_SIZE(gFontSmall[0]), (const uint8_t *)gFontSmall); } void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line) { #ifdef ENABLE_SMALL_BOLD - const uint8_t *font = (uint8_t *)gFontSmallBold; - const uint8_t char_width = ARRAY_SIZE(gFontSmallBold[0]); + const uint8_t *font = (uint8_t *)gFontSmallBold; + const uint8_t char_width = ARRAY_SIZE(gFontSmallBold[0]); #else - const uint8_t *font = (uint8_t *)gFontSmall; - const uint8_t char_width = ARRAY_SIZE(gFontSmall[0]); + const uint8_t *font = (uint8_t *)gFontSmall; + const uint8_t char_width = ARRAY_SIZE(gFontSmall[0]); #endif - UI_PrintStringSmall(pString, Start, End, Line, char_width, font); + UI_PrintStringSmall(pString, Start, End, Line, char_width, font); } void UI_PrintStringSmallBufferNormal(const char *pString, uint8_t * buffer) { - UI_PrintStringBuffer(pString, buffer, ARRAY_SIZE(gFontSmall[0]), (uint8_t *)gFontSmall); + UI_PrintStringBuffer(pString, buffer, ARRAY_SIZE(gFontSmall[0]), (uint8_t *)gFontSmall); } void UI_PrintStringSmallBufferBold(const char *pString, uint8_t * buffer) { #ifdef ENABLE_SMALL_BOLD - const uint8_t *font = (uint8_t *)gFontSmallBold; - const uint8_t char_width = ARRAY_SIZE(gFontSmallBold[0]); + const uint8_t *font = (uint8_t *)gFontSmallBold; + const uint8_t char_width = ARRAY_SIZE(gFontSmallBold[0]); #else - const uint8_t *font = (uint8_t *)gFontSmall; - const uint8_t char_width = ARRAY_SIZE(gFontSmall[0]); + const uint8_t *font = (uint8_t *)gFontSmall; + const uint8_t char_width = ARRAY_SIZE(gFontSmall[0]); #endif - UI_PrintStringBuffer(pString, buffer, char_width, font); + UI_PrintStringBuffer(pString, buffer, char_width, font); } void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center) { - const unsigned int char_width = 13; - uint8_t *pFb0 = gFrameBuffer[Y] + X; - uint8_t *pFb1 = pFb0 + 128; - bool bCanDisplay = false; + const unsigned int char_width = 13; + uint8_t *pFb0 = gFrameBuffer[Y] + X; + uint8_t *pFb1 = pFb0 + 128; + bool bCanDisplay = false; - uint8_t len = strlen(string); - for(int i = 0; i < len; i++) { - char c = string[i]; - if(c=='-') c = '9' + 1; - if (bCanDisplay || c != ' ') - { - bCanDisplay = true; - if(c>='0' && c<='9' + 1) { - memcpy(pFb0 + 2, gFontBigDigits[c-'0'], char_width - 3); - memcpy(pFb1 + 2, gFontBigDigits[c-'0'] + char_width - 3, char_width - 3); - } - else if(c=='.') { - *pFb1 = 0x60; pFb0++; pFb1++; - *pFb1 = 0x60; pFb0++; pFb1++; - *pFb1 = 0x60; pFb0++; pFb1++; - continue; - } + uint8_t len = strlen(string); + for(int i = 0; i < len; i++) { + char c = string[i]; + if(c=='-') c = '9' + 1; + if (bCanDisplay || c != ' ') + { + bCanDisplay = true; + if(c>='0' && c<='9' + 1) { + memcpy(pFb0 + 2, gFontBigDigits[c-'0'], char_width - 3); + memcpy(pFb1 + 2, gFontBigDigits[c-'0'] + char_width - 3, char_width - 3); + } + else if(c=='.') { + *pFb1 = 0x60; pFb0++; pFb1++; + *pFb1 = 0x60; pFb0++; pFb1++; + *pFb1 = 0x60; pFb0++; pFb1++; + continue; + } - } - else if (center) { - pFb0 -= 6; - pFb1 -= 6; - } - pFb0 += char_width; - pFb1 += char_width; - } + } + else if (center) { + pFb0 -= 6; + pFb1 -= 6; + } + pFb0 += char_width; + pFb1 += char_width; + } } void UI_DrawPixelBuffer(uint8_t (*buffer)[128], uint8_t x, uint8_t y, bool black) { - const uint8_t pattern = 1 << (y % 8); - if(black) - buffer[y/8][x] |= pattern; - else - buffer[y/8][x] &= ~pattern; + const uint8_t pattern = 1 << (y % 8); + if(black) + buffer[y/8][x] |= pattern; + else + buffer[y/8][x] &= ~pattern; } static void sort(int16_t *a, int16_t *b) { - if(*a > *b) { - int16_t t = *a; - *a = *b; - *b = t; - } + if(*a > *b) { + int16_t t = *a; + *a = *b; + *b = t; + } } #ifdef ENABLE_FEAT_F4HWN - /* - void UI_DrawLineDottedBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black) - { - if(x2==x1) { - sort(&y1, &y2); - for(int16_t i = y1; i <= y2; i+=2) { - UI_DrawPixelBuffer(buffer, x1, i, black); - } - } else { - const int multipl = 1000; - int a = (y2-y1)*multipl / (x2-x1); - int b = y1 - a * x1 / multipl; + /* + void UI_DrawLineDottedBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black) + { + if(x2==x1) { + sort(&y1, &y2); + for(int16_t i = y1; i <= y2; i+=2) { + UI_DrawPixelBuffer(buffer, x1, i, black); + } + } else { + const int multipl = 1000; + int a = (y2-y1)*multipl / (x2-x1); + int b = y1 - a * x1 / multipl; - sort(&x1, &x2); - for(int i = x1; i<= x2; i+=2) - { - UI_DrawPixelBuffer(buffer, i, i*a/multipl +b, black); - } - } - } - */ + sort(&x1, &x2); + for(int i = x1; i<= x2; i+=2) + { + UI_DrawPixelBuffer(buffer, i, i*a/multipl +b, black); + } + } + } + */ - void PutPixel(uint8_t x, uint8_t y, bool fill) { - UI_DrawPixelBuffer(gFrameBuffer, x, y, fill); - } + void PutPixel(uint8_t x, uint8_t y, bool fill) { + UI_DrawPixelBuffer(gFrameBuffer, x, y, fill); + } - void PutPixelStatus(uint8_t x, uint8_t y, bool fill) { - UI_DrawPixelBuffer(&gStatusLine, x, y, fill); - } + void PutPixelStatus(uint8_t x, uint8_t y, bool fill) { + UI_DrawPixelBuffer(&gStatusLine, x, y, fill); + } - void GUI_DisplaySmallest(const char *pString, uint8_t x, uint8_t y, - bool statusbar, bool fill) { - uint8_t c; - uint8_t pixels; - const uint8_t *p = (const uint8_t *)pString; + void GUI_DisplaySmallest(const char *pString, uint8_t x, uint8_t y, + bool statusbar, bool fill) { + uint8_t c; + uint8_t pixels; + const uint8_t *p = (const uint8_t *)pString; - while ((c = *p++) && c != '\0') { - c -= 0x20; - for (int i = 0; i < 3; ++i) { - pixels = gFont3x5[c][i]; - for (int j = 0; j < 6; ++j) { - if (pixels & 1) { - if (statusbar) - PutPixelStatus(x + i, y + j, fill); - else - PutPixel(x + i, y + j, fill); - } - pixels >>= 1; - } - } - x += 4; - } - } + while ((c = *p++) && c != '\0') { + c -= 0x20; + for (int i = 0; i < 3; ++i) { + pixels = gFont3x5[c][i]; + for (int j = 0; j < 6; ++j) { + if (pixels & 1) { + if (statusbar) + PutPixelStatus(x + i, y + j, fill); + else + PutPixel(x + i, y + j, fill); + } + pixels >>= 1; + } + } + x += 4; + } + } #endif - + void UI_DrawLineBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black) { - if(x2==x1) { - sort(&y1, &y2); - for(int16_t i = y1; i <= y2; i++) { - UI_DrawPixelBuffer(buffer, x1, i, black); - } - } else { - const int multipl = 1000; - int a = (y2-y1)*multipl / (x2-x1); - int b = y1 - a * x1 / multipl; + if(x2==x1) { + sort(&y1, &y2); + for(int16_t i = y1; i <= y2; i++) { + UI_DrawPixelBuffer(buffer, x1, i, black); + } + } else { + const int multipl = 1000; + int a = (y2-y1)*multipl / (x2-x1); + int b = y1 - a * x1 / multipl; - sort(&x1, &x2); - for(int i = x1; i<= x2; i++) - { - UI_DrawPixelBuffer(buffer, i, i*a/multipl +b, black); - } - } + sort(&x1, &x2); + for(int i = x1; i<= x2; i++) + { + UI_DrawPixelBuffer(buffer, i, i*a/multipl +b, black); + } + } } void UI_DrawRectangleBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black) { - UI_DrawLineBuffer(buffer, x1,y1, x1,y2, black); - UI_DrawLineBuffer(buffer, x1,y1, x2,y1, black); - UI_DrawLineBuffer(buffer, x2,y1, x2,y2, black); - UI_DrawLineBuffer(buffer, x1,y2, x2,y2, black); + UI_DrawLineBuffer(buffer, x1,y1, x1,y2, black); + UI_DrawLineBuffer(buffer, x1,y1, x2,y1, black); + UI_DrawLineBuffer(buffer, x2,y1, x2,y2, black); + UI_DrawLineBuffer(buffer, x1,y2, x2,y2, black); } void UI_DisplayPopup(const char *string) { - UI_DisplayClear(); + UI_DisplayClear(); - // for(uint8_t i = 1; i < 5; i++) { - // memset(gFrameBuffer[i]+8, 0x00, 111); - // } + // for(uint8_t i = 1; i < 5; i++) { + // memset(gFrameBuffer[i]+8, 0x00, 111); + // } - // for(uint8_t x = 10; x < 118; x++) { - // UI_DrawPixelBuffer(x, 10, true); - // UI_DrawPixelBuffer(x, 46-9, true); - // } + // for(uint8_t x = 10; x < 118; x++) { + // UI_DrawPixelBuffer(x, 10, true); + // UI_DrawPixelBuffer(x, 46-9, true); + // } - // for(uint8_t y = 11; y < 37; y++) { - // UI_DrawPixelBuffer(10, y, true); - // UI_DrawPixelBuffer(117, y, true); - // } - // DrawRectangle(9,9, 118,38, true); - UI_PrintString(string, 9, 118, 2, 8); - UI_PrintStringSmallNormal("Press EXIT", 9, 118, 6); + // for(uint8_t y = 11; y < 37; y++) { + // UI_DrawPixelBuffer(10, y, true); + // UI_DrawPixelBuffer(117, y, true); + // } + // DrawRectangle(9,9, 118,38, true); + UI_PrintString(string, 9, 118, 2, 8); + UI_PrintStringSmallNormal("Press EXIT", 9, 118, 6); } void UI_DisplayClear() { - memset(gFrameBuffer, 0, sizeof(gFrameBuffer)); + memset(gFrameBuffer, 0, sizeof(gFrameBuffer)); } diff --git a/ui/helper.h b/ui/helper.h index 294c744..2dea9ea 100644 --- a/ui/helper.h +++ b/ui/helper.h @@ -33,10 +33,10 @@ void UI_DisplayPopup(const char *string); void UI_DrawPixelBuffer(uint8_t (*buffer)[128], uint8_t x, uint8_t y, bool black); #ifdef ENABLE_FEAT_F4HWN - //void UI_DrawLineDottedBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black); - void PutPixel(uint8_t x, uint8_t y, bool fill); - void PutPixelStatus(uint8_t x, uint8_t y, bool fill); - void GUI_DisplaySmallest(const char *pString, uint8_t x, uint8_t y, bool statusbar, bool fill); + //void UI_DrawLineDottedBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black); + void PutPixel(uint8_t x, uint8_t y, bool fill); + void PutPixelStatus(uint8_t x, uint8_t y, bool fill); + void GUI_DisplaySmallest(const char *pString, uint8_t x, uint8_t y, bool statusbar, bool fill); #endif void UI_DrawLineBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black); void UI_DrawRectangleBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black); diff --git a/ui/inputbox.c b/ui/inputbox.c index 39a6596..2a13a6d 100644 --- a/ui/inputbox.c +++ b/ui/inputbox.c @@ -24,21 +24,21 @@ uint8_t gInputBoxIndex; void INPUTBOX_Append(const KEY_Code_t Digit) { - if (gInputBoxIndex >= sizeof(gInputBox)) - return; + if (gInputBoxIndex >= sizeof(gInputBox)) + return; - if (gInputBoxIndex == 0) - memset(gInputBox, 10, sizeof(gInputBox)); + if (gInputBoxIndex == 0) + memset(gInputBox, 10, sizeof(gInputBox)); - if (Digit != KEY_INVALID) - gInputBox[gInputBoxIndex++] = (char)(Digit - KEY_0); + if (Digit != KEY_INVALID) + gInputBox[gInputBoxIndex++] = (char)(Digit - KEY_0); } const char* INPUTBOX_GetAscii() { - for(int i = 0; i < 8; i++) { - char c = gInputBox[i]; - inputBoxAscii[i] = (c==10)? '-' : '0' + c; - } - return inputBoxAscii; + for(int i = 0; i < 8; i++) { + char c = gInputBox[i]; + inputBoxAscii[i] = (c==10)? '-' : '0' + c; + } + return inputBoxAscii; } \ No newline at end of file diff --git a/ui/lock.c b/ui/lock.c index 44423bf..a34d1a0 100644 --- a/ui/lock.c +++ b/ui/lock.c @@ -31,131 +31,131 @@ static void Render(void) { - unsigned int i; - char String[7]; + unsigned int i; + char String[7]; - memset(gStatusLine, 0, sizeof(gStatusLine)); - UI_DisplayClear(); + memset(gStatusLine, 0, sizeof(gStatusLine)); + UI_DisplayClear(); - UI_PrintString("LOCK", 0, 127, 1, 10); - for (i = 0; i < 6; i++) - String[i] = (gInputBox[i] == 10) ? '-' : '*'; - String[6] = 0; - UI_PrintString(String, 0, 127, 3, 12); + UI_PrintString("LOCK", 0, 127, 1, 10); + for (i = 0; i < 6; i++) + String[i] = (gInputBox[i] == 10) ? '-' : '*'; + String[6] = 0; + UI_PrintString(String, 0, 127, 3, 12); - ST7565_BlitStatusLine(); - ST7565_BlitFullScreen(); + ST7565_BlitStatusLine(); + ST7565_BlitFullScreen(); } void UI_DisplayLock(void) { - KEY_Code_t Key; - BEEP_Type_t Beep; + KEY_Code_t Key; + BEEP_Type_t Beep; - gUpdateDisplay = true; + gUpdateDisplay = true; - memset(gInputBox, 10, sizeof(gInputBox)); + memset(gInputBox, 10, sizeof(gInputBox)); - while (1) - { - while (!gNextTimeslice) {} + while (1) + { + while (!gNextTimeslice) {} - // TODO: Original code doesn't do the below, but is needed for proper key debounce + // TODO: Original code doesn't do the below, but is needed for proper key debounce - gNextTimeslice = false; + gNextTimeslice = false; - Key = KEYBOARD_Poll(); + Key = KEYBOARD_Poll(); - if (gKeyReading0 == Key) - { - if (++gDebounceCounter == key_debounce_10ms) - { - if (Key == KEY_INVALID) - { - gKeyReading1 = KEY_INVALID; - } - else - { - gKeyReading1 = Key; + if (gKeyReading0 == Key) + { + if (++gDebounceCounter == key_debounce_10ms) + { + if (Key == KEY_INVALID) + { + gKeyReading1 = KEY_INVALID; + } + else + { + gKeyReading1 = Key; - switch (Key) - { - case KEY_0: - case KEY_1: - case KEY_2: - case KEY_3: - case KEY_4: - case KEY_5: - case KEY_6: - case KEY_7: - case KEY_8: - case KEY_9: - INPUTBOX_Append(Key - KEY_0); + switch (Key) + { + case KEY_0: + case KEY_1: + case KEY_2: + case KEY_3: + case KEY_4: + case KEY_5: + case KEY_6: + case KEY_7: + case KEY_8: + case KEY_9: + INPUTBOX_Append(Key - KEY_0); - if (gInputBoxIndex < 6) // 6 frequency digits - { - Beep = BEEP_1KHZ_60MS_OPTIONAL; - } - else - { - uint32_t Password; + if (gInputBoxIndex < 6) // 6 frequency digits + { + Beep = BEEP_1KHZ_60MS_OPTIONAL; + } + else + { + uint32_t Password; - gInputBoxIndex = 0; - Password = StrToUL(INPUTBOX_GetAscii()); + gInputBoxIndex = 0; + Password = StrToUL(INPUTBOX_GetAscii()); - if ((gEeprom.POWER_ON_PASSWORD) == Password) - { - AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL); - return; - } + if ((gEeprom.POWER_ON_PASSWORD) == Password) + { + AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL); + return; + } - memset(gInputBox, 10, sizeof(gInputBox)); + memset(gInputBox, 10, sizeof(gInputBox)); - Beep = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - } + Beep = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + } - AUDIO_PlayBeep(Beep); + AUDIO_PlayBeep(Beep); - gUpdateDisplay = true; - break; + gUpdateDisplay = true; + break; - case KEY_EXIT: - if (gInputBoxIndex > 0) - { - gInputBox[--gInputBoxIndex] = 10; - gUpdateDisplay = true; - } + case KEY_EXIT: + if (gInputBoxIndex > 0) + { + gInputBox[--gInputBoxIndex] = 10; + gUpdateDisplay = true; + } - AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL); + AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL); - default: - break; - } - } + default: + break; + } + } - gKeyBeingHeld = false; - } - } - else - { - gDebounceCounter = 0; - gKeyReading0 = Key; - } + gKeyBeingHeld = false; + } + } + else + { + gDebounceCounter = 0; + gKeyReading0 = Key; + } #ifdef ENABLE_UART - if (UART_IsCommandAvailable()) - { - __disable_irq(); - UART_HandleCommand(); - __enable_irq(); - } + if (UART_IsCommandAvailable()) + { + __disable_irq(); + UART_HandleCommand(); + __enable_irq(); + } #endif - if (gUpdateDisplay) - { - Render(); - gUpdateDisplay = false; - } - } + if (gUpdateDisplay) + { + Render(); + gUpdateDisplay = false; + } + } } #endif diff --git a/ui/lock.h b/ui/lock.h index e42758d..d8a7fa9 100644 --- a/ui/lock.h +++ b/ui/lock.h @@ -18,7 +18,7 @@ #define UI_LOCK_H #ifdef ENABLE_PWRON_PASSWORD - void UI_DisplayLock(void); + void UI_DisplayLock(void); #endif #endif diff --git a/ui/main.c b/ui/main.c index 1be3346..6b9d6f3 100644 --- a/ui/main.c +++ b/ui/main.c @@ -20,7 +20,7 @@ #include "app/chFrScanner.h" #include "app/dtmf.h" #ifdef ENABLE_AM_FIX - #include "am_fix.h" + #include "am_fix.h" #endif #include "bitmaps.h" #include "board.h" @@ -39,52 +39,52 @@ #include "audio.h" #ifdef ENABLE_FEAT_F4HWN - #include "driver/system.h" + #include "driver/system.h" #endif center_line_t center_line = CENTER_LINE_NONE; #ifdef ENABLE_FEAT_F4HWN - static int8_t RxBlink; - static int8_t RxBlinkLed = 0; - static int8_t RxBlinkLedCounter; - static int8_t RxLine; - static uint32_t RxOnVfofrequency; + static int8_t RxBlink; + static int8_t RxBlinkLed = 0; + static int8_t RxBlinkLedCounter; + static int8_t RxLine; + static uint32_t RxOnVfofrequency; - bool isMainOnlyInputDTMF = false; + bool isMainOnlyInputDTMF = false; - static int16_t map(int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max) { - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; - } + static int16_t map(int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } - static bool isMainOnly(bool checkGui) - { - if(checkGui) - { - if(((gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2 == 0) || gSetting_set_gui) - return true; - else - return false; - } - else - { - if((gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2 == 0) - return true; - else - return false; - } - } + static bool isMainOnly(bool checkGui) + { + if(checkGui) + { + if(((gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2 == 0) || gSetting_set_gui) + return true; + else + return false; + } + else + { + if((gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2 == 0) + return true; + else + return false; + } + } #endif const int8_t dBmCorrTable[7] = { - -15, // band 1 - -25, // band 2 - -20, // band 3 - -4, // band 4 - -7, // band 5 - -6, // band 6 - -1 // band 7 - }; + -15, // band 1 + -25, // band 2 + -20, // band 3 + -4, // band 4 + -7, // band 5 + -6, // band 6 + -1 // band 7 + }; const char *VfoStateStr[] = { [VFO_STATE_NORMAL]="", @@ -100,159 +100,159 @@ const char *VfoStateStr[] = { static void DrawSmallAntennaAndBars(uint8_t *p, unsigned int level) { - if(level>6) - level = 6; + if(level>6) + level = 6; - memcpy(p, BITMAP_Antenna, ARRAY_SIZE(BITMAP_Antenna)); + memcpy(p, BITMAP_Antenna, ARRAY_SIZE(BITMAP_Antenna)); - for(uint8_t i = 1; i <= level; i++) { - char bar = (0xff << (6-i)) & 0x7F; - memset(p + 2 + i*3, bar, 2); - } + for(uint8_t i = 1; i <= level; i++) { + char bar = (0xff << (6-i)) & 0x7F; + memset(p + 2 + i*3, bar, 2); + } } #if defined ENABLE_AUDIO_BAR || defined ENABLE_RSSI_BAR static void DrawLevelBar(uint8_t xpos, uint8_t line, uint8_t level) { #ifndef ENABLE_FEAT_F4HWN - const char hollowBar[] = { - 0b01111111, - 0b01000001, - 0b01000001, - 0b01111111 - }; + const char hollowBar[] = { + 0b01111111, + 0b01000001, + 0b01000001, + 0b01111111 + }; #endif - - uint8_t *p_line = gFrameBuffer[line]; - level = MIN(level, 13); + + uint8_t *p_line = gFrameBuffer[line]; + level = MIN(level, 13); - for(uint8_t i = 0; i < level; i++) { + for(uint8_t i = 0; i < level; i++) { #ifdef ENABLE_FEAT_F4HWN - if(gSetting_set_met) - { - const char hollowBar[] = { - 0b01111111, - 0b01000001, - 0b01000001, - 0b01111111 - }; + if(gSetting_set_met) + { + const char hollowBar[] = { + 0b01111111, + 0b01000001, + 0b01000001, + 0b01111111 + }; - if(i < 9) { - for(uint8_t j = 0; j < 4; j++) - p_line[xpos + i * 5 + j] = (~(0x7F >> (i+1))) & 0x7F; - } - else { - memcpy(p_line + (xpos + i * 5), &hollowBar, ARRAY_SIZE(hollowBar)); - } - } - else - { - const char hollowBar[] = { - 0b00111110, - 0b00100010, - 0b00100010, - 0b00111110 - }; + if(i < 9) { + for(uint8_t j = 0; j < 4; j++) + p_line[xpos + i * 5 + j] = (~(0x7F >> (i+1))) & 0x7F; + } + else { + memcpy(p_line + (xpos + i * 5), &hollowBar, ARRAY_SIZE(hollowBar)); + } + } + else + { + const char hollowBar[] = { + 0b00111110, + 0b00100010, + 0b00100010, + 0b00111110 + }; - const char simpleBar[] = { - 0b00111110, - 0b00111110, - 0b00111110, - 0b00111110 - }; + const char simpleBar[] = { + 0b00111110, + 0b00111110, + 0b00111110, + 0b00111110 + }; - if(i < 9) { - memcpy(p_line + (xpos + i * 5), &simpleBar, ARRAY_SIZE(simpleBar)); - } - else { - memcpy(p_line + (xpos + i * 5), &hollowBar, ARRAY_SIZE(hollowBar)); - } - } + if(i < 9) { + memcpy(p_line + (xpos + i * 5), &simpleBar, ARRAY_SIZE(simpleBar)); + } + else { + memcpy(p_line + (xpos + i * 5), &hollowBar, ARRAY_SIZE(hollowBar)); + } + } #else - if(i < 9) { - for(uint8_t j = 0; j < 4; j++) - p_line[xpos + i * 5 + j] = (~(0x7F >> (i+1))) & 0x7F; - } - else { - memcpy(p_line + (xpos + i * 5), &hollowBar, ARRAY_SIZE(hollowBar)); - } + if(i < 9) { + for(uint8_t j = 0; j < 4; j++) + p_line[xpos + i * 5 + j] = (~(0x7F >> (i+1))) & 0x7F; + } + else { + memcpy(p_line + (xpos + i * 5), &hollowBar, ARRAY_SIZE(hollowBar)); + } #endif - } + } } #endif #ifdef ENABLE_AUDIO_BAR unsigned int sqrt16(unsigned int value) -{ // return square root of 'value' - unsigned int shift = 16; // number of bits supplied in 'value' .. 2 ~ 32 - unsigned int bit = 1u << --shift; - unsigned int sqrti = 0; - while (bit) - { - const unsigned int temp = ((sqrti << 1) | bit) << shift--; - if (value >= temp) { - value -= temp; - sqrti |= bit; - } - bit >>= 1; - } - return sqrti; +{ // return square root of 'value' + unsigned int shift = 16; // number of bits supplied in 'value' .. 2 ~ 32 + unsigned int bit = 1u << --shift; + unsigned int sqrti = 0; + while (bit) + { + const unsigned int temp = ((sqrti << 1) | bit) << shift--; + if (value >= temp) { + value -= temp; + sqrti |= bit; + } + bit >>= 1; + } + return sqrti; } void UI_DisplayAudioBar(void) { - if (gSetting_mic_bar) - { - if(gLowBattery && !gLowBatteryConfirmed) - return; + if (gSetting_mic_bar) + { + if(gLowBattery && !gLowBatteryConfirmed) + return; #ifdef ENABLE_FEAT_F4HWN - RxBlinkLed = 0; - RxBlinkLedCounter = 0; - BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false); - unsigned int line; - if (isMainOnly(false)) - { - line = 5; - } - else - { - line = 3; - } + RxBlinkLed = 0; + RxBlinkLedCounter = 0; + BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false); + unsigned int line; + if (isMainOnly(false)) + { + line = 5; + } + else + { + line = 3; + } #else - const unsigned int line = 3; + const unsigned int line = 3; #endif - if (gCurrentFunction != FUNCTION_TRANSMIT || - gScreenToDisplay != DISPLAY_MAIN + if (gCurrentFunction != FUNCTION_TRANSMIT || + gScreenToDisplay != DISPLAY_MAIN #ifdef ENABLE_DTMF_CALLING - || gDTMF_CallState != DTMF_CALL_STATE_NONE + || gDTMF_CallState != DTMF_CALL_STATE_NONE #endif - ) - { - return; // screen is in use - } + ) + { + return; // screen is in use + } #if defined(ENABLE_ALARM) || defined(ENABLE_TX1750) - if (gAlarmState != ALARM_STATE_OFF) - return; + if (gAlarmState != ALARM_STATE_OFF) + return; #endif - const unsigned int voice_amp = BK4819_GetVoiceAmplitudeOut(); // 15:0 + const unsigned int voice_amp = BK4819_GetVoiceAmplitudeOut(); // 15:0 - // make non-linear to make more sensitive at low values - const unsigned int level = MIN(voice_amp * 8, 65535u); - const unsigned int sqrt_level = MIN(sqrt16(level), 124u); - uint8_t bars = 13 * sqrt_level / 124; + // make non-linear to make more sensitive at low values + const unsigned int level = MIN(voice_amp * 8, 65535u); + const unsigned int sqrt_level = MIN(sqrt16(level), 124u); + uint8_t bars = 13 * sqrt_level / 124; - uint8_t *p_line = gFrameBuffer[line]; - memset(p_line, 0, LCD_WIDTH); + uint8_t *p_line = gFrameBuffer[line]; + memset(p_line, 0, LCD_WIDTH); - DrawLevelBar(62, line, bars); + DrawLevelBar(62, line, bars); - if (gCurrentFunction == FUNCTION_TRANSMIT) - ST7565_BlitFullScreen(); - } + if (gCurrentFunction == FUNCTION_TRANSMIT) + ST7565_BlitFullScreen(); + } } #endif @@ -260,185 +260,185 @@ void DisplayRSSIBar(const bool now) { #if defined(ENABLE_RSSI_BAR) - const unsigned int txt_width = 7 * 8; // 8 text chars - const unsigned int bar_x = 2 + txt_width + 4; // X coord of bar graph + const unsigned int txt_width = 7 * 8; // 8 text chars + const unsigned int bar_x = 2 + txt_width + 4; // X coord of bar graph #ifdef ENABLE_FEAT_F4HWN - /* - const char empty[] = { - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - 0b00000000, - }; - */ + /* + const char empty[] = { + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + 0b00000000, + }; + */ - unsigned int line; - if (isMainOnly(false)) - { - line = 5; - } - else - { - line = 3; - } + unsigned int line; + if (isMainOnly(false)) + { + line = 5; + } + else + { + line = 3; + } - //char rx[4]; - //sprintf(String, "%d", RxBlink); - //UI_PrintStringSmallBold(String, 80, 0, RxLine); + //char rx[4]; + //sprintf(String, "%d", RxBlink); + //UI_PrintStringSmallBold(String, 80, 0, RxLine); - if(RxLine >= 0 && center_line != CENTER_LINE_IN_USE) - { - switch(RxBlink) - { - case 0: - UI_PrintStringSmallBold("RX", 8, 0, RxLine); - break; - case 1: - UI_PrintStringSmallBold("RX", 8, 0, RxLine); - RxBlink = 2; - break; - case 2: - for (uint8_t i = 8; i < 24; i++) - { - gFrameBuffer[RxLine][i] = 0x00; - } - RxBlink = 1; - break; - } - ST7565_BlitLine(RxLine); - } + if(RxLine >= 0 && center_line != CENTER_LINE_IN_USE) + { + switch(RxBlink) + { + case 0: + UI_PrintStringSmallBold("RX", 8, 0, RxLine); + break; + case 1: + UI_PrintStringSmallBold("RX", 8, 0, RxLine); + RxBlink = 2; + break; + case 2: + for (uint8_t i = 8; i < 24; i++) + { + gFrameBuffer[RxLine][i] = 0x00; + } + RxBlink = 1; + break; + } + ST7565_BlitLine(RxLine); + } #else - const unsigned int line = 3; + const unsigned int line = 3; #endif - uint8_t *p_line = gFrameBuffer[line]; - char str[16]; + uint8_t *p_line = gFrameBuffer[line]; + char str[16]; #ifndef ENABLE_FEAT_F4HWN - const char plus[] = { - 0b00011000, - 0b00011000, - 0b01111110, - 0b01111110, - 0b01111110, - 0b00011000, - 0b00011000, - }; + const char plus[] = { + 0b00011000, + 0b00011000, + 0b01111110, + 0b01111110, + 0b01111110, + 0b00011000, + 0b00011000, + }; #endif - if ((gEeprom.KEY_LOCK && gKeypadLocked > 0) || center_line != CENTER_LINE_RSSI) - return; // display is in use + if ((gEeprom.KEY_LOCK && gKeypadLocked > 0) || center_line != CENTER_LINE_RSSI) + return; // display is in use - if (gCurrentFunction == FUNCTION_TRANSMIT || - gScreenToDisplay != DISPLAY_MAIN + if (gCurrentFunction == FUNCTION_TRANSMIT || + gScreenToDisplay != DISPLAY_MAIN #ifdef ENABLE_DTMF_CALLING - || gDTMF_CallState != DTMF_CALL_STATE_NONE + || gDTMF_CallState != DTMF_CALL_STATE_NONE #endif - ) - return; // display is in use + ) + return; // display is in use - if (now) - memset(p_line, 0, LCD_WIDTH); + if (now) + memset(p_line, 0, LCD_WIDTH); #ifdef ENABLE_FEAT_F4HWN - int16_t rssi_dBm = - BK4819_GetRSSI_dBm() + int16_t rssi_dBm = + BK4819_GetRSSI_dBm() #ifdef ENABLE_AM_FIX - + ((gSetting_AM_fix && gRxVfo->Modulation == MODULATION_AM) ? AM_fix_get_gain_diff() : 0) + + ((gSetting_AM_fix && gRxVfo->Modulation == MODULATION_AM) ? AM_fix_get_gain_diff() : 0) #endif - + dBmCorrTable[gRxVfo->Band]; + + dBmCorrTable[gRxVfo->Band]; - rssi_dBm = -rssi_dBm; + rssi_dBm = -rssi_dBm; - if(rssi_dBm > 141) rssi_dBm = 141; - if(rssi_dBm < 53) rssi_dBm = 53; + if(rssi_dBm > 141) rssi_dBm = 141; + if(rssi_dBm < 53) rssi_dBm = 53; - uint8_t s_level = 0; - uint8_t overS9dBm = 0; - uint8_t overS9Bars = 0; + uint8_t s_level = 0; + uint8_t overS9dBm = 0; + uint8_t overS9Bars = 0; - if(rssi_dBm >= 93) { - s_level = map(rssi_dBm, 141, 93, 1, 9); - } - else { - s_level = 9; - overS9dBm = map(rssi_dBm, 93, 53, 0, 40); - overS9Bars = map(overS9dBm, 0, 40, 0, 4); - } + if(rssi_dBm >= 93) { + s_level = map(rssi_dBm, 141, 93, 1, 9); + } + else { + s_level = 9; + overS9dBm = map(rssi_dBm, 93, 53, 0, 40); + overS9Bars = map(overS9dBm, 0, 40, 0, 4); + } #else - const int16_t s0_dBm = -gEeprom.S0_LEVEL; // S0 .. base level - const int16_t rssi_dBm = - BK4819_GetRSSI_dBm() + const int16_t s0_dBm = -gEeprom.S0_LEVEL; // S0 .. base level + const int16_t rssi_dBm = + BK4819_GetRSSI_dBm() #ifdef ENABLE_AM_FIX - + ((gSetting_AM_fix && gRxVfo->Modulation == MODULATION_AM) ? AM_fix_get_gain_diff() : 0) + + ((gSetting_AM_fix && gRxVfo->Modulation == MODULATION_AM) ? AM_fix_get_gain_diff() : 0) #endif - + dBmCorrTable[gRxVfo->Band]; + + dBmCorrTable[gRxVfo->Band]; - int s0_9 = gEeprom.S0_LEVEL - gEeprom.S9_LEVEL; - const uint8_t s_level = MIN(MAX((int32_t)(rssi_dBm - s0_dBm)*100 / (s0_9*100/9), 0), 9); // S0 - S9 - uint8_t overS9dBm = MIN(MAX(rssi_dBm + gEeprom.S9_LEVEL, 0), 99); - uint8_t overS9Bars = MIN(overS9dBm/10, 4); + int s0_9 = gEeprom.S0_LEVEL - gEeprom.S9_LEVEL; + const uint8_t s_level = MIN(MAX((int32_t)(rssi_dBm - s0_dBm)*100 / (s0_9*100/9), 0), 9); // S0 - S9 + uint8_t overS9dBm = MIN(MAX(rssi_dBm + gEeprom.S9_LEVEL, 0), 99); + uint8_t overS9Bars = MIN(overS9dBm/10, 4); #endif #ifdef ENABLE_FEAT_F4HWN - if (isMainOnly(true)) - { - sprintf(str, "%3d", -rssi_dBm); - UI_PrintStringSmallNormal(str, LCD_WIDTH + 8, 0, line - 1); - } - else - { - sprintf(str, "% 4d %s", -rssi_dBm, "dBm"); - GUI_DisplaySmallest(str, 2, 25, false, true); - } + if (isMainOnly(true)) + { + sprintf(str, "%3d", -rssi_dBm); + UI_PrintStringSmallNormal(str, LCD_WIDTH + 8, 0, line - 1); + } + else + { + sprintf(str, "% 4d %s", -rssi_dBm, "dBm"); + GUI_DisplaySmallest(str, 2, 25, false, true); + } - if(overS9Bars == 0) { - sprintf(str, "S%d", s_level); - } - else { - sprintf(str, "+%02d", overS9dBm); - } + if(overS9Bars == 0) { + sprintf(str, "S%d", s_level); + } + else { + sprintf(str, "+%02d", overS9dBm); + } - UI_PrintStringSmallNormal(str, LCD_WIDTH + 38, 0, line - 1); + UI_PrintStringSmallNormal(str, LCD_WIDTH + 38, 0, line - 1); #else - if(overS9Bars == 0) { - sprintf(str, "% 4d S%d", -rssi_dBm, s_level); - } - else { - sprintf(str, "% 4d %2d", -rssi_dBm, overS9dBm); - memcpy(p_line + 2 + 7*5, &plus, ARRAY_SIZE(plus)); - } + if(overS9Bars == 0) { + sprintf(str, "% 4d S%d", -rssi_dBm, s_level); + } + else { + sprintf(str, "% 4d %2d", -rssi_dBm, overS9dBm); + memcpy(p_line + 2 + 7*5, &plus, ARRAY_SIZE(plus)); + } - UI_PrintStringSmallNormal(str, 2, 0, line); + UI_PrintStringSmallNormal(str, 2, 0, line); #endif - DrawLevelBar(bar_x, line, s_level + overS9Bars); - if (now) - ST7565_BlitLine(line); + DrawLevelBar(bar_x, line, s_level + overS9Bars); + if (now) + ST7565_BlitLine(line); #else - int16_t rssi = BK4819_GetRSSI(); - uint8_t Level; + int16_t rssi = BK4819_GetRSSI(); + uint8_t Level; - if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][3]) { - Level = 6; - } else if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][2]) { - Level = 4; - } else if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][1]) { - Level = 2; - } else if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][0]) { - Level = 1; - } else { - Level = 0; - } + if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][3]) { + Level = 6; + } else if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][2]) { + Level = 4; + } else if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][1]) { + Level = 2; + } else if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][0]) { + Level = 1; + } else { + Level = 0; + } - uint8_t *pLine = (gEeprom.RX_VFO == 0)? gFrameBuffer[2] : gFrameBuffer[6]; - if (now) - memset(pLine, 0, 23); - DrawSmallAntennaAndBars(pLine, Level); - if (now) - ST7565_BlitFullScreen(); + uint8_t *pLine = (gEeprom.RX_VFO == 0)? gFrameBuffer[2] : gFrameBuffer[6]; + if (now) + memset(pLine, 0, 23); + DrawSmallAntennaAndBars(pLine, Level); + if (now) + ST7565_BlitFullScreen(); #endif } @@ -446,1017 +446,1017 @@ void DisplayRSSIBar(const bool now) #ifdef ENABLE_AGC_SHOW_DATA void UI_MAIN_PrintAGC(bool now) { - char buf[20]; - memset(gFrameBuffer[3], 0, 128); - union { - struct { - uint16_t _ : 5; - uint16_t agcSigStrength : 7; - int16_t gainIdx : 3; - uint16_t agcEnab : 1; - }; - uint16_t __raw; - } reg7e; - reg7e.__raw = BK4819_ReadRegister(0x7E); - uint8_t gainAddr = reg7e.gainIdx < 0 ? 0x14 : 0x10 + reg7e.gainIdx; - union { - struct { - uint16_t pga:3; - uint16_t mixer:2; - uint16_t lna:3; - uint16_t lnaS:2; - }; - uint16_t __raw; - } agcGainReg; - agcGainReg.__raw = BK4819_ReadRegister(gainAddr); - int8_t lnaShortTab[] = {-28, -24, -19, 0}; - int8_t lnaTab[] = {-24, -19, -14, -9, -6, -4, -2, 0}; - int8_t mixerTab[] = {-8, -6, -3, 0}; - int8_t pgaTab[] = {-33, -27, -21, -15, -9, -6, -3, 0}; - int16_t agcGain = lnaShortTab[agcGainReg.lnaS] + lnaTab[agcGainReg.lna] + mixerTab[agcGainReg.mixer] + pgaTab[agcGainReg.pga]; + char buf[20]; + memset(gFrameBuffer[3], 0, 128); + union { + struct { + uint16_t _ : 5; + uint16_t agcSigStrength : 7; + int16_t gainIdx : 3; + uint16_t agcEnab : 1; + }; + uint16_t __raw; + } reg7e; + reg7e.__raw = BK4819_ReadRegister(0x7E); + uint8_t gainAddr = reg7e.gainIdx < 0 ? 0x14 : 0x10 + reg7e.gainIdx; + union { + struct { + uint16_t pga:3; + uint16_t mixer:2; + uint16_t lna:3; + uint16_t lnaS:2; + }; + uint16_t __raw; + } agcGainReg; + agcGainReg.__raw = BK4819_ReadRegister(gainAddr); + int8_t lnaShortTab[] = {-28, -24, -19, 0}; + int8_t lnaTab[] = {-24, -19, -14, -9, -6, -4, -2, 0}; + int8_t mixerTab[] = {-8, -6, -3, 0}; + int8_t pgaTab[] = {-33, -27, -21, -15, -9, -6, -3, 0}; + int16_t agcGain = lnaShortTab[agcGainReg.lnaS] + lnaTab[agcGainReg.lna] + mixerTab[agcGainReg.mixer] + pgaTab[agcGainReg.pga]; - sprintf(buf, "%d%2d %2d %2d %3d", reg7e.agcEnab, reg7e.gainIdx, -agcGain, reg7e.agcSigStrength, BK4819_GetRSSI()); - UI_PrintStringSmallNormal(buf, 2, 0, 3); - if(now) - ST7565_BlitLine(3); + sprintf(buf, "%d%2d %2d %2d %3d", reg7e.agcEnab, reg7e.gainIdx, -agcGain, reg7e.agcSigStrength, BK4819_GetRSSI()); + UI_PrintStringSmallNormal(buf, 2, 0, 3); + if(now) + ST7565_BlitLine(3); } #endif void UI_MAIN_TimeSlice500ms(void) { - if(gScreenToDisplay==DISPLAY_MAIN) { + if(gScreenToDisplay==DISPLAY_MAIN) { #ifdef ENABLE_AGC_SHOW_DATA - UI_MAIN_PrintAGC(true); - return; + UI_MAIN_PrintAGC(true); + return; #endif - if(FUNCTION_IsRx()) { - DisplayRSSIBar(true); - } + if(FUNCTION_IsRx()) { + DisplayRSSIBar(true); + } #ifdef ENABLE_FEAT_F4HWN // Blink Green Led for white... - else if(gSetting_set_eot > 0 && RxBlinkLed == 2) - { - if(RxBlinkLedCounter <= 8) - { - if(RxBlinkLedCounter % 2 == 0) - { - if(gSetting_set_eot > 1 ) - { - BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false); - } - } - else - { - if(gSetting_set_eot > 1 ) - { - BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, true); - } + else if(gSetting_set_eot > 0 && RxBlinkLed == 2) + { + if(RxBlinkLedCounter <= 8) + { + if(RxBlinkLedCounter % 2 == 0) + { + if(gSetting_set_eot > 1 ) + { + BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false); + } + } + else + { + if(gSetting_set_eot > 1 ) + { + BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, true); + } - if(gSetting_set_eot == 1 || gSetting_set_eot == 3) - { - switch(RxBlinkLedCounter) - { - case 1: - AUDIO_PlayBeep(BEEP_400HZ_30MS); - break; + if(gSetting_set_eot == 1 || gSetting_set_eot == 3) + { + switch(RxBlinkLedCounter) + { + case 1: + AUDIO_PlayBeep(BEEP_400HZ_30MS); + break; - case 3: - AUDIO_PlayBeep(BEEP_400HZ_30MS); - break; + case 3: + AUDIO_PlayBeep(BEEP_400HZ_30MS); + break; - case 5: - AUDIO_PlayBeep(BEEP_500HZ_30MS); - break; + case 5: + AUDIO_PlayBeep(BEEP_500HZ_30MS); + break; - case 7: - AUDIO_PlayBeep(BEEP_600HZ_30MS); - break; - } - } - } - RxBlinkLedCounter += 1; - } - else - { - RxBlinkLed = 0; - } - } + case 7: + AUDIO_PlayBeep(BEEP_600HZ_30MS); + break; + } + } + } + RxBlinkLedCounter += 1; + } + else + { + RxBlinkLed = 0; + } + } #endif - } + } } // *************************************************************************** void UI_DisplayMain(void) { - char String[22]; + char String[22]; - center_line = CENTER_LINE_NONE; + center_line = CENTER_LINE_NONE; - // clear the screen - UI_DisplayClear(); + // clear the screen + UI_DisplayClear(); - if(gLowBattery && !gLowBatteryConfirmed) { - UI_DisplayPopup("LOW BATTERY"); - ST7565_BlitFullScreen(); - return; - } + if(gLowBattery && !gLowBatteryConfirmed) { + UI_DisplayPopup("LOW BATTERY"); + ST7565_BlitFullScreen(); + return; + } #ifndef ENABLE_FEAT_F4HWN - if (gEeprom.KEY_LOCK && gKeypadLocked > 0) - { // tell user how to unlock the keyboard - UI_PrintString("Long press #", 0, LCD_WIDTH, 1, 8); - UI_PrintString("to unlock", 0, LCD_WIDTH, 3, 8); - ST7565_BlitFullScreen(); - return; - } + if (gEeprom.KEY_LOCK && gKeypadLocked > 0) + { // tell user how to unlock the keyboard + UI_PrintString("Long press #", 0, LCD_WIDTH, 1, 8); + UI_PrintString("to unlock", 0, LCD_WIDTH, 3, 8); + ST7565_BlitFullScreen(); + return; + } #else - if (gEeprom.KEY_LOCK && gKeypadLocked > 0) - { // tell user how to unlock the keyboard - uint8_t shift = 3; + if (gEeprom.KEY_LOCK && gKeypadLocked > 0) + { // tell user how to unlock the keyboard + uint8_t shift = 3; - /* - BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); - SYSTEM_DelayMs(50); - BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false); - SYSTEM_DelayMs(50); - */ + /* + BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); + SYSTEM_DelayMs(50); + BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false); + SYSTEM_DelayMs(50); + */ - if(isMainOnly(false)) - { - shift = 5; - } - //memcpy(gFrameBuffer[shift] + 2, gFontKeyLock, sizeof(gFontKeyLock)); - UI_PrintStringSmallBold("UNLOCK KEYBOARD", 12, 0, shift); - //memcpy(gFrameBuffer[shift] + 120, gFontKeyLock, sizeof(gFontKeyLock)); + if(isMainOnly(false)) + { + shift = 5; + } + //memcpy(gFrameBuffer[shift] + 2, gFontKeyLock, sizeof(gFontKeyLock)); + UI_PrintStringSmallBold("UNLOCK KEYBOARD", 12, 0, shift); + //memcpy(gFrameBuffer[shift] + 120, gFontKeyLock, sizeof(gFontKeyLock)); - /* - for (uint8_t i = 12; i < 116; i++) - { - gFrameBuffer[shift][i] ^= 0xFF; - } - */ - } + /* + for (uint8_t i = 12; i < 116; i++) + { + gFrameBuffer[shift][i] ^= 0xFF; + } + */ + } #endif - unsigned int activeTxVFO = gRxVfoIsActive ? gEeprom.RX_VFO : gEeprom.TX_VFO; + unsigned int activeTxVFO = gRxVfoIsActive ? gEeprom.RX_VFO : gEeprom.TX_VFO; - for (unsigned int vfo_num = 0; vfo_num < 2; vfo_num++) - { + for (unsigned int vfo_num = 0; vfo_num < 2; vfo_num++) + { #ifdef ENABLE_FEAT_F4HWN - const unsigned int line0 = 0; // text screen line - const unsigned int line1 = 4; - unsigned int line; - if (isMainOnly(false)) - { - line = 0; - } - else - { - line = (vfo_num == 0) ? line0 : line1; - } - const bool isMainVFO = (vfo_num == gEeprom.TX_VFO); - uint8_t *p_line0 = gFrameBuffer[line + 0]; - uint8_t *p_line1 = gFrameBuffer[line + 1]; - enum Vfo_txtr_mode mode = VFO_MODE_NONE; + const unsigned int line0 = 0; // text screen line + const unsigned int line1 = 4; + unsigned int line; + if (isMainOnly(false)) + { + line = 0; + } + else + { + line = (vfo_num == 0) ? line0 : line1; + } + const bool isMainVFO = (vfo_num == gEeprom.TX_VFO); + uint8_t *p_line0 = gFrameBuffer[line + 0]; + uint8_t *p_line1 = gFrameBuffer[line + 1]; + enum Vfo_txtr_mode mode = VFO_MODE_NONE; #else - const unsigned int line0 = 0; // text screen line - const unsigned int line1 = 4; - const unsigned int line = (vfo_num == 0) ? line0 : line1; - const bool isMainVFO = (vfo_num == gEeprom.TX_VFO); - uint8_t *p_line0 = gFrameBuffer[line + 0]; - uint8_t *p_line1 = gFrameBuffer[line + 1]; - enum Vfo_txtr_mode mode = VFO_MODE_NONE; + const unsigned int line0 = 0; // text screen line + const unsigned int line1 = 4; + const unsigned int line = (vfo_num == 0) ? line0 : line1; + const bool isMainVFO = (vfo_num == gEeprom.TX_VFO); + uint8_t *p_line0 = gFrameBuffer[line + 0]; + uint8_t *p_line1 = gFrameBuffer[line + 1]; + enum Vfo_txtr_mode mode = VFO_MODE_NONE; #endif #ifdef ENABLE_FEAT_F4HWN - if (isMainOnly(false)) - { - if (activeTxVFO != vfo_num) - { - continue; - } - } + if (isMainOnly(false)) + { + if (activeTxVFO != vfo_num) + { + continue; + } + } #endif #ifdef ENABLE_FEAT_F4HWN - if (activeTxVFO != vfo_num || isMainOnly(false)) + if (activeTxVFO != vfo_num || isMainOnly(false)) #else - if (activeTxVFO != vfo_num) // this is not active TX VFO + if (activeTxVFO != vfo_num) // this is not active TX VFO #endif - { + { #ifdef ENABLE_SCAN_RANGES - if(gScanRangeStart) { + if(gScanRangeStart) { #ifdef ENABLE_FEAT_F4HWN - //if(IS_FREQ_CHANNEL(gEeprom.ScreenChannel[0]) && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[1])) { - if(IS_FREQ_CHANNEL(gEeprom.ScreenChannel[activeTxVFO])) { + //if(IS_FREQ_CHANNEL(gEeprom.ScreenChannel[0]) && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[1])) { + if(IS_FREQ_CHANNEL(gEeprom.ScreenChannel[activeTxVFO])) { - uint8_t shift = 0; + uint8_t shift = 0; - if (isMainOnly(false)) - { - shift = 3; - } + if (isMainOnly(false)) + { + shift = 3; + } - UI_PrintString("ScnRng", 5, 0, line + shift, 8); - sprintf(String, "%3u.%05u", gScanRangeStart / 100000, gScanRangeStart % 100000); - UI_PrintStringSmallNormal(String, 56, 0, line + shift); - sprintf(String, "%3u.%05u", gScanRangeStop / 100000, gScanRangeStop % 100000); - UI_PrintStringSmallNormal(String, 56, 0, line + shift + 1); + UI_PrintString("ScnRng", 5, 0, line + shift, 8); + sprintf(String, "%3u.%05u", gScanRangeStart / 100000, gScanRangeStart % 100000); + UI_PrintStringSmallNormal(String, 56, 0, line + shift); + sprintf(String, "%3u.%05u", gScanRangeStop / 100000, gScanRangeStop % 100000); + UI_PrintStringSmallNormal(String, 56, 0, line + shift + 1); - if (!isMainOnly(false)) - continue; - } - else - { - gScanRangeStart = 0; - } + if (!isMainOnly(false)) + continue; + } + else + { + gScanRangeStart = 0; + } #else - UI_PrintString("ScnRng", 5, 0, line, 8); - sprintf(String, "%3u.%05u", gScanRangeStart / 100000, gScanRangeStart % 100000); - UI_PrintStringSmallNormal(String, 56, 0, line); - sprintf(String, "%3u.%05u", gScanRangeStop / 100000, gScanRangeStop % 100000); - UI_PrintStringSmallNormal(String, 56, 0, line + 1); - continue; + UI_PrintString("ScnRng", 5, 0, line, 8); + sprintf(String, "%3u.%05u", gScanRangeStart / 100000, gScanRangeStart % 100000); + UI_PrintStringSmallNormal(String, 56, 0, line); + sprintf(String, "%3u.%05u", gScanRangeStop / 100000, gScanRangeStop % 100000); + UI_PrintStringSmallNormal(String, 56, 0, line + 1); + continue; #endif - } + } #endif - if (gDTMF_InputMode + if (gDTMF_InputMode #ifdef ENABLE_DTMF_CALLING - || gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_IsTx + || gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_IsTx #endif - ) { - char *pPrintStr = ""; - // show DTMF stuff + ) { + char *pPrintStr = ""; + // show DTMF stuff #ifdef ENABLE_DTMF_CALLING - char Contact[16]; - if (!gDTMF_InputMode) { - if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT) { - pPrintStr = DTMF_FindContact(gDTMF_String, Contact) ? Contact : gDTMF_String; - } else if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED || gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY){ - pPrintStr = DTMF_FindContact(gDTMF_Callee, Contact) ? Contact : gDTMF_Callee; - }else if (gDTMF_IsTx) { - pPrintStr = gDTMF_String; - } - } + char Contact[16]; + if (!gDTMF_InputMode) { + if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT) { + pPrintStr = DTMF_FindContact(gDTMF_String, Contact) ? Contact : gDTMF_String; + } else if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED || gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY){ + pPrintStr = DTMF_FindContact(gDTMF_Callee, Contact) ? Contact : gDTMF_Callee; + }else if (gDTMF_IsTx) { + pPrintStr = gDTMF_String; + } + } - UI_PrintString(pPrintStr, 2, 0, 2 + (vfo_num * 3), 8); + UI_PrintString(pPrintStr, 2, 0, 2 + (vfo_num * 3), 8); - pPrintStr = ""; - if (!gDTMF_InputMode) { - if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT) { - pPrintStr = (gDTMF_State == DTMF_STATE_CALL_OUT_RSP) ? "CALL OUT(RSP)" : "CALL OUT"; - } else if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED || gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY) { - sprintf(String, "CALL FRM:%s", (DTMF_FindContact(gDTMF_Caller, Contact)) ? Contact : gDTMF_Caller); - pPrintStr = String; - } else if (gDTMF_IsTx) { - pPrintStr = (gDTMF_State == DTMF_STATE_TX_SUCC) ? "DTMF TX(SUCC)" : "DTMF TX"; - } - } - else + pPrintStr = ""; + if (!gDTMF_InputMode) { + if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT) { + pPrintStr = (gDTMF_State == DTMF_STATE_CALL_OUT_RSP) ? "CALL OUT(RSP)" : "CALL OUT"; + } else if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED || gDTMF_CallState == DTMF_CALL_STATE_RECEIVED_STAY) { + sprintf(String, "CALL FRM:%s", (DTMF_FindContact(gDTMF_Caller, Contact)) ? Contact : gDTMF_Caller); + pPrintStr = String; + } else if (gDTMF_IsTx) { + pPrintStr = (gDTMF_State == DTMF_STATE_TX_SUCC) ? "DTMF TX(SUCC)" : "DTMF TX"; + } + } + else #endif - { - sprintf(String, ">%s", gDTMF_InputBox); - pPrintStr = String; - } + { + sprintf(String, ">%s", gDTMF_InputBox); + pPrintStr = String; + } #ifdef ENABLE_FEAT_F4HWN - if (isMainOnly(false)) - { - UI_PrintString(pPrintStr, 2, 0, 5, 8); - isMainOnlyInputDTMF = true; - center_line = CENTER_LINE_IN_USE; - } - else - { - UI_PrintString(pPrintStr, 2, 0, 0 + (vfo_num * 3), 8); - isMainOnlyInputDTMF = false; - center_line = CENTER_LINE_IN_USE; - continue; - } + if (isMainOnly(false)) + { + UI_PrintString(pPrintStr, 2, 0, 5, 8); + isMainOnlyInputDTMF = true; + center_line = CENTER_LINE_IN_USE; + } + else + { + UI_PrintString(pPrintStr, 2, 0, 0 + (vfo_num * 3), 8); + isMainOnlyInputDTMF = false; + center_line = CENTER_LINE_IN_USE; + continue; + } #else - UI_PrintString(pPrintStr, 2, 0, 0 + (vfo_num * 3), 8); - center_line = CENTER_LINE_IN_USE; - continue; + UI_PrintString(pPrintStr, 2, 0, 0 + (vfo_num * 3), 8); + center_line = CENTER_LINE_IN_USE; + continue; #endif - } + } - // highlight the selected/used VFO with a marker - if (isMainVFO) - memcpy(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default)); - } - else // active TX VFO - { // highlight the selected/used VFO with a marker - if (isMainVFO) - memcpy(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default)); - else - memcpy(p_line0 + 0, BITMAP_VFO_NotDefault, sizeof(BITMAP_VFO_NotDefault)); - } + // highlight the selected/used VFO with a marker + if (isMainVFO) + memcpy(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default)); + } + else // active TX VFO + { // highlight the selected/used VFO with a marker + if (isMainVFO) + memcpy(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default)); + else + memcpy(p_line0 + 0, BITMAP_VFO_NotDefault, sizeof(BITMAP_VFO_NotDefault)); + } - uint32_t frequency = gEeprom.VfoInfo[vfo_num].pRX->Frequency; + uint32_t frequency = gEeprom.VfoInfo[vfo_num].pRX->Frequency; - if(TX_freq_check(frequency) != 0 && gEeprom.VfoInfo[vfo_num].TX_LOCK == true) - { - if(isMainOnly(false)) - memcpy(p_line0 + 14, BITMAP_VFO_Lock, sizeof(BITMAP_VFO_Lock)); - else - memcpy(p_line0 + 24, BITMAP_VFO_Lock, sizeof(BITMAP_VFO_Lock)); - } + if(TX_freq_check(frequency) != 0 && gEeprom.VfoInfo[vfo_num].TX_LOCK == true) + { + if(isMainOnly(false)) + memcpy(p_line0 + 14, BITMAP_VFO_Lock, sizeof(BITMAP_VFO_Lock)); + else + memcpy(p_line0 + 24, BITMAP_VFO_Lock, sizeof(BITMAP_VFO_Lock)); + } - if (gCurrentFunction == FUNCTION_TRANSMIT) - { // transmitting + if (gCurrentFunction == FUNCTION_TRANSMIT) + { // transmitting #ifdef ENABLE_ALARM - if (gAlarmState == ALARM_STATE_SITE_ALARM) - mode = VFO_MODE_RX; - else + if (gAlarmState == ALARM_STATE_SITE_ALARM) + mode = VFO_MODE_RX; + else #endif - { - if (activeTxVFO == vfo_num) - { // show the TX symbol - mode = VFO_MODE_TX; - UI_PrintStringSmallBold("TX", 8, 0, line); - } - } - } - else - { // receiving .. show the RX symbol - mode = VFO_MODE_RX; - //if (FUNCTION_IsRx() && gEeprom.RX_VFO == vfo_num) { - if (FUNCTION_IsRx() && gEeprom.RX_VFO == vfo_num && VfoState[vfo_num] == VFO_STATE_NORMAL) { + { + if (activeTxVFO == vfo_num) + { // show the TX symbol + mode = VFO_MODE_TX; + UI_PrintStringSmallBold("TX", 8, 0, line); + } + } + } + else + { // receiving .. show the RX symbol + mode = VFO_MODE_RX; + //if (FUNCTION_IsRx() && gEeprom.RX_VFO == vfo_num) { + if (FUNCTION_IsRx() && gEeprom.RX_VFO == vfo_num && VfoState[vfo_num] == VFO_STATE_NORMAL) { #ifdef ENABLE_FEAT_F4HWN - RxBlinkLed = 1; - RxBlinkLedCounter = 0; - RxLine = line; - RxOnVfofrequency = frequency; - if(!isMainVFO) - { - RxBlink = 1; - } - else - { - RxBlink = 0; - } + RxBlinkLed = 1; + RxBlinkLedCounter = 0; + RxLine = line; + RxOnVfofrequency = frequency; + if(!isMainVFO) + { + RxBlink = 1; + } + else + { + RxBlink = 0; + } #else - UI_PrintStringSmallBold("RX", 8, 0, line); + UI_PrintStringSmallBold("RX", 8, 0, line); #endif - } + } #ifdef ENABLE_FEAT_F4HWN - else - { - if(RxOnVfofrequency == frequency && !isMainOnly(false)) - { - UI_PrintStringSmallNormal(">>", 8, 0, line); - //memcpy(p_line0 + 14, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default)); - } + else + { + if(RxOnVfofrequency == frequency && !isMainOnly(false)) + { + UI_PrintStringSmallNormal(">>", 8, 0, line); + //memcpy(p_line0 + 14, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default)); + } - if(RxBlinkLed == 1) - RxBlinkLed = 2; - } + if(RxBlinkLed == 1) + RxBlinkLed = 2; + } #endif - } + } - if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num])) - { // channel mode - const unsigned int x = 2; - const bool inputting = gInputBoxIndex != 0 && gEeprom.TX_VFO == vfo_num; - if (!inputting) - sprintf(String, "M%u", gEeprom.ScreenChannel[vfo_num] + 1); - else - sprintf(String, "M%.3s", INPUTBOX_GetAscii()); // show the input text - UI_PrintStringSmallNormal(String, x, 0, line + 1); - } - else if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num])) - { // frequency mode - // show the frequency band number - const unsigned int x = 2; - char * buf = gEeprom.VfoInfo[vfo_num].pRX->Frequency < _1GHz_in_KHz ? "" : "+"; - sprintf(String, "F%u%s", 1 + gEeprom.ScreenChannel[vfo_num] - FREQ_CHANNEL_FIRST, buf); - UI_PrintStringSmallNormal(String, x, 0, line + 1); - } + if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num])) + { // channel mode + const unsigned int x = 2; + const bool inputting = gInputBoxIndex != 0 && gEeprom.TX_VFO == vfo_num; + if (!inputting) + sprintf(String, "M%u", gEeprom.ScreenChannel[vfo_num] + 1); + else + sprintf(String, "M%.3s", INPUTBOX_GetAscii()); // show the input text + UI_PrintStringSmallNormal(String, x, 0, line + 1); + } + else if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num])) + { // frequency mode + // show the frequency band number + const unsigned int x = 2; + char * buf = gEeprom.VfoInfo[vfo_num].pRX->Frequency < _1GHz_in_KHz ? "" : "+"; + sprintf(String, "F%u%s", 1 + gEeprom.ScreenChannel[vfo_num] - FREQ_CHANNEL_FIRST, buf); + UI_PrintStringSmallNormal(String, x, 0, line + 1); + } #ifdef ENABLE_NOAA - else - { - if (gInputBoxIndex == 0 || gEeprom.TX_VFO != vfo_num) - { // channel number - sprintf(String, "N%u", 1 + gEeprom.ScreenChannel[vfo_num] - NOAA_CHANNEL_FIRST); - } - else - { // user entering channel number - sprintf(String, "N%u%u", '0' + gInputBox[0], '0' + gInputBox[1]); - } - UI_PrintStringSmallNormal(String, 7, 0, line + 1); - } + else + { + if (gInputBoxIndex == 0 || gEeprom.TX_VFO != vfo_num) + { // channel number + sprintf(String, "N%u", 1 + gEeprom.ScreenChannel[vfo_num] - NOAA_CHANNEL_FIRST); + } + else + { // user entering channel number + sprintf(String, "N%u%u", '0' + gInputBox[0], '0' + gInputBox[1]); + } + UI_PrintStringSmallNormal(String, 7, 0, line + 1); + } #endif - // ************ + // ************ - enum VfoState_t state = VfoState[vfo_num]; + enum VfoState_t state = VfoState[vfo_num]; #ifdef ENABLE_ALARM - if (gCurrentFunction == FUNCTION_TRANSMIT && gAlarmState == ALARM_STATE_SITE_ALARM) { - if (activeTxVFO == vfo_num) - state = VFO_STATE_ALARM; - } + if (gCurrentFunction == FUNCTION_TRANSMIT && gAlarmState == ALARM_STATE_SITE_ALARM) { + if (activeTxVFO == vfo_num) + state = VFO_STATE_ALARM; + } #endif - if (state != VFO_STATE_NORMAL) - { - if (state < ARRAY_SIZE(VfoStateStr)) - UI_PrintString(VfoStateStr[state], 31, 0, line, 8); - } - else if (gInputBoxIndex > 0 && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]) && gEeprom.TX_VFO == vfo_num) - { // user entering a frequency - const char * ascii = INPUTBOX_GetAscii(); - bool isGigaF = frequency>=_1GHz_in_KHz; - sprintf(String, "%.*s.%.3s", 3 + isGigaF, ascii, ascii + 3 + isGigaF); + if (state != VFO_STATE_NORMAL) + { + if (state < ARRAY_SIZE(VfoStateStr)) + UI_PrintString(VfoStateStr[state], 31, 0, line, 8); + } + else if (gInputBoxIndex > 0 && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]) && gEeprom.TX_VFO == vfo_num) + { // user entering a frequency + const char * ascii = INPUTBOX_GetAscii(); + bool isGigaF = frequency>=_1GHz_in_KHz; + sprintf(String, "%.*s.%.3s", 3 + isGigaF, ascii, ascii + 3 + isGigaF); #ifdef ENABLE_BIG_FREQ - if(!isGigaF) { - // show the remaining 2 small frequency digits - UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1); - String[7] = 0; - // show the main large frequency digits - UI_DisplayFrequency(String, 32, line, false); - } - else + if(!isGigaF) { + // show the remaining 2 small frequency digits + UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1); + String[7] = 0; + // show the main large frequency digits + UI_DisplayFrequency(String, 32, line, false); + } + else #endif - { - // show the frequency in the main font - UI_PrintString(String, 32, 0, line, 8); - } + { + // show the frequency in the main font + UI_PrintString(String, 32, 0, line, 8); + } - continue; - } - else - { - if (gCurrentFunction == FUNCTION_TRANSMIT) - { // transmitting - if (activeTxVFO == vfo_num) - frequency = gEeprom.VfoInfo[vfo_num].pTX->Frequency; - } + continue; + } + else + { + if (gCurrentFunction == FUNCTION_TRANSMIT) + { // transmitting + if (activeTxVFO == vfo_num) + frequency = gEeprom.VfoInfo[vfo_num].pTX->Frequency; + } - if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num])) - { // it's a channel + if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num])) + { // it's a channel - uint8_t countList = 0; - uint8_t shiftList = 0; + uint8_t countList = 0; + uint8_t shiftList = 0; - if(gMR_ChannelExclude[gEeprom.ScreenChannel[vfo_num]] == false) - { - // show the scan list assigment symbols - const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; + if(gMR_ChannelExclude[gEeprom.ScreenChannel[vfo_num]] == false) + { + // show the scan list assigment symbols + const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; - countList = att.scanlist1 + att.scanlist2 + att.scanlist3; + countList = att.scanlist1 + att.scanlist2 + att.scanlist3; - if(countList == 0) - { - memcpy(p_line0 + 127 - (1 * 6), BITMAP_ScanList0, sizeof(BITMAP_ScanList0)); - } - else - { - shiftList = countList; + if(countList == 0) + { + memcpy(p_line0 + 127 - (1 * 6), BITMAP_ScanList0, sizeof(BITMAP_ScanList0)); + } + else + { + shiftList = countList; - if (att.scanlist1) - { - memcpy(p_line0 + 127 - (shiftList * 6), BITMAP_ScanList1, sizeof(BITMAP_ScanList1)); - shiftList--; - } - if (att.scanlist2) - { - memcpy(p_line0 + 127 - (shiftList * 6), BITMAP_ScanList2, sizeof(BITMAP_ScanList2)); - shiftList--; - } - if (att.scanlist3) - { - memcpy(p_line0 + 127 - (shiftList * 6), BITMAP_ScanList3, sizeof(BITMAP_ScanList3)); - } - } - } - else - { - memcpy(p_line0 + 127 - (1 * 6), BITMAP_ScanListE, sizeof(BITMAP_ScanListE)); - } + if (att.scanlist1) + { + memcpy(p_line0 + 127 - (shiftList * 6), BITMAP_ScanList1, sizeof(BITMAP_ScanList1)); + shiftList--; + } + if (att.scanlist2) + { + memcpy(p_line0 + 127 - (shiftList * 6), BITMAP_ScanList2, sizeof(BITMAP_ScanList2)); + shiftList--; + } + if (att.scanlist3) + { + memcpy(p_line0 + 127 - (shiftList * 6), BITMAP_ScanList3, sizeof(BITMAP_ScanList3)); + } + } + } + else + { + memcpy(p_line0 + 127 - (1 * 6), BITMAP_ScanListE, sizeof(BITMAP_ScanListE)); + } - /* - if (att.scanlist1) - memcpy(p_line0 + 107, BITMAP_ScanList1, sizeof(BITMAP_ScanList1)); - if (att.scanlist2) - memcpy(p_line0 + 114, BITMAP_ScanList2, sizeof(BITMAP_ScanList2)); - if (att.scanlist3) - memcpy(p_line0 + 121, BITMAP_ScanList3, sizeof(BITMAP_ScanList3)); - */ + /* + if (att.scanlist1) + memcpy(p_line0 + 107, BITMAP_ScanList1, sizeof(BITMAP_ScanList1)); + if (att.scanlist2) + memcpy(p_line0 + 114, BITMAP_ScanList2, sizeof(BITMAP_ScanList2)); + if (att.scanlist3) + memcpy(p_line0 + 121, BITMAP_ScanList3, sizeof(BITMAP_ScanList3)); + */ - // compander symbol + // compander symbol #ifndef ENABLE_BIG_FREQ - if (att.compander) - memcpy(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand)); + if (att.compander) + memcpy(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand)); #else - // TODO: // find somewhere else to put the symbol + // TODO: // find somewhere else to put the symbol #endif - switch (gEeprom.CHANNEL_DISPLAY_MODE) - { - case MDF_FREQUENCY: // show the channel frequency - sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000); + switch (gEeprom.CHANNEL_DISPLAY_MODE) + { + case MDF_FREQUENCY: // show the channel frequency + sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000); #ifdef ENABLE_BIG_FREQ - if(frequency < _1GHz_in_KHz) { - // show the remaining 2 small frequency digits - UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1); - String[7] = 0; - // show the main large frequency digits - UI_DisplayFrequency(String, 32, line, false); - } - else + if(frequency < _1GHz_in_KHz) { + // show the remaining 2 small frequency digits + UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1); + String[7] = 0; + // show the main large frequency digits + UI_DisplayFrequency(String, 32, line, false); + } + else #endif - { - // show the frequency in the main font - UI_PrintString(String, 32, 0, line, 8); - } + { + // show the frequency in the main font + UI_PrintString(String, 32, 0, line, 8); + } - break; + break; - case MDF_CHANNEL: // show the channel number - sprintf(String, "CH-%03u", gEeprom.ScreenChannel[vfo_num] + 1); - UI_PrintString(String, 32, 0, line, 8); - break; + case MDF_CHANNEL: // show the channel number + sprintf(String, "CH-%03u", gEeprom.ScreenChannel[vfo_num] + 1); + UI_PrintString(String, 32, 0, line, 8); + break; - case MDF_NAME: // show the channel name - case MDF_NAME_FREQ: // show the channel name and frequency + case MDF_NAME: // show the channel name + case MDF_NAME_FREQ: // show the channel name and frequency - SETTINGS_FetchChannelName(String, gEeprom.ScreenChannel[vfo_num]); - if (String[0] == 0) - { // no channel name, show the channel number instead - sprintf(String, "CH-%03u", gEeprom.ScreenChannel[vfo_num] + 1); - } + SETTINGS_FetchChannelName(String, gEeprom.ScreenChannel[vfo_num]); + if (String[0] == 0) + { // no channel name, show the channel number instead + sprintf(String, "CH-%03u", gEeprom.ScreenChannel[vfo_num] + 1); + } - if (gEeprom.CHANNEL_DISPLAY_MODE == MDF_NAME) { - UI_PrintString(String, 32, 0, line, 8); - } - else { + if (gEeprom.CHANNEL_DISPLAY_MODE == MDF_NAME) { + UI_PrintString(String, 32, 0, line, 8); + } + else { #ifdef ENABLE_FEAT_F4HWN - if (isMainOnly(false)) - { - UI_PrintString(String, 32, 0, line, 8); - } - else - { - if(activeTxVFO == vfo_num) { - UI_PrintStringSmallBold(String, 32 + 4, 0, line); - } - else - { - UI_PrintStringSmallNormal(String, 32 + 4, 0, line); - } - } + if (isMainOnly(false)) + { + UI_PrintString(String, 32, 0, line, 8); + } + else + { + if(activeTxVFO == vfo_num) { + UI_PrintStringSmallBold(String, 32 + 4, 0, line); + } + else + { + UI_PrintStringSmallNormal(String, 32 + 4, 0, line); + } + } #else - UI_PrintStringSmallBold(String, 32 + 4, 0, line); + UI_PrintStringSmallBold(String, 32 + 4, 0, line); #endif #ifdef ENABLE_FEAT_F4HWN - if (isMainOnly(false)) - { - sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000); - if(frequency < _1GHz_in_KHz) { - // show the remaining 2 small frequency digits - UI_PrintStringSmallNormal(String + 7, 113, 0, line + 4); - String[7] = 0; - // show the main large frequency digits - UI_DisplayFrequency(String, 32, line + 3, false); - } - else - { - // show the frequency in the main font - UI_PrintString(String, 32, 0, line + 3, 8); - } - } - else - { - sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000); - UI_PrintStringSmallNormal(String, 32 + 4, 0, line + 1); - } -#else // show the channel frequency below the channel number/name - sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000); - UI_PrintStringSmallNormal(String, 32 + 4, 0, line + 1); + if (isMainOnly(false)) + { + sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000); + if(frequency < _1GHz_in_KHz) { + // show the remaining 2 small frequency digits + UI_PrintStringSmallNormal(String + 7, 113, 0, line + 4); + String[7] = 0; + // show the main large frequency digits + UI_DisplayFrequency(String, 32, line + 3, false); + } + else + { + // show the frequency in the main font + UI_PrintString(String, 32, 0, line + 3, 8); + } + } + else + { + sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000); + UI_PrintStringSmallNormal(String, 32 + 4, 0, line + 1); + } +#else // show the channel frequency below the channel number/name + sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000); + UI_PrintStringSmallNormal(String, 32 + 4, 0, line + 1); #endif - } + } - break; - } - } - else - { // frequency mode - sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000); + break; + } + } + else + { // frequency mode + sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000); #ifdef ENABLE_BIG_FREQ - if(frequency < _1GHz_in_KHz) { - // show the remaining 2 small frequency digits - UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1); - String[7] = 0; - // show the main large frequency digits - UI_DisplayFrequency(String, 32, line, false); - } - else + if(frequency < _1GHz_in_KHz) { + // show the remaining 2 small frequency digits + UI_PrintStringSmallNormal(String + 7, 113, 0, line + 1); + String[7] = 0; + // show the main large frequency digits + UI_DisplayFrequency(String, 32, line, false); + } + else #endif - { - // show the frequency in the main font - UI_PrintString(String, 32, 0, line, 8); - } + { + // show the frequency in the main font + UI_PrintString(String, 32, 0, line, 8); + } - // show the channel symbols - const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; - if (att.compander) + // show the channel symbols + const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; + if (att.compander) #ifdef ENABLE_BIG_FREQ - memcpy(p_line0 + 120, BITMAP_compand, sizeof(BITMAP_compand)); + memcpy(p_line0 + 120, BITMAP_compand, sizeof(BITMAP_compand)); #else - memcpy(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand)); + memcpy(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand)); #endif - } - } + } + } - // ************ + // ************ - { // show the TX/RX level - uint8_t Level = 0; + { // show the TX/RX level + uint8_t Level = 0; - if (mode == VFO_MODE_TX) - { // TX power level - switch (gRxVfo->OUTPUT_POWER) - { - case OUTPUT_POWER_LOW1: Level = 2; break; - case OUTPUT_POWER_LOW2: Level = 2; break; - case OUTPUT_POWER_LOW3: Level = 2; break; - case OUTPUT_POWER_LOW4: Level = 2; break; - case OUTPUT_POWER_LOW5: Level = 2; break; - case OUTPUT_POWER_MID: Level = 4; break; - case OUTPUT_POWER_HIGH: Level = 6; break; - } - } - else - if (mode == VFO_MODE_RX) - { // RX signal level - #ifndef ENABLE_RSSI_BAR - // bar graph - if (gVFO_RSSI_bar_level[vfo_num] > 0) - Level = gVFO_RSSI_bar_level[vfo_num]; - #endif - } - if(Level) - DrawSmallAntennaAndBars(p_line1 + LCD_WIDTH, Level); - } + if (mode == VFO_MODE_TX) + { // TX power level + switch (gRxVfo->OUTPUT_POWER) + { + case OUTPUT_POWER_LOW1: Level = 2; break; + case OUTPUT_POWER_LOW2: Level = 2; break; + case OUTPUT_POWER_LOW3: Level = 2; break; + case OUTPUT_POWER_LOW4: Level = 2; break; + case OUTPUT_POWER_LOW5: Level = 2; break; + case OUTPUT_POWER_MID: Level = 4; break; + case OUTPUT_POWER_HIGH: Level = 6; break; + } + } + else + if (mode == VFO_MODE_RX) + { // RX signal level + #ifndef ENABLE_RSSI_BAR + // bar graph + if (gVFO_RSSI_bar_level[vfo_num] > 0) + Level = gVFO_RSSI_bar_level[vfo_num]; + #endif + } + if(Level) + DrawSmallAntennaAndBars(p_line1 + LCD_WIDTH, Level); + } - // ************ + // ************ - String[0] = '\0'; - const VFO_Info_t *vfoInfo = &gEeprom.VfoInfo[vfo_num]; + String[0] = '\0'; + const VFO_Info_t *vfoInfo = &gEeprom.VfoInfo[vfo_num]; - // show the modulation symbol - const char * s = ""; + // show the modulation symbol + const char * s = ""; #ifdef ENABLE_FEAT_F4HWN - const char * t = ""; + const char * t = ""; #endif - const ModulationMode_t mod = vfoInfo->Modulation; - switch (mod){ - case MODULATION_FM: { - const FREQ_Config_t *pConfig = (mode == VFO_MODE_TX) ? vfoInfo->pTX : vfoInfo->pRX; - const unsigned int code_type = pConfig->CodeType; + const ModulationMode_t mod = vfoInfo->Modulation; + switch (mod){ + case MODULATION_FM: { + const FREQ_Config_t *pConfig = (mode == VFO_MODE_TX) ? vfoInfo->pTX : vfoInfo->pRX; + const unsigned int code_type = pConfig->CodeType; #ifdef ENABLE_FEAT_F4HWN - const char *code_list[] = {"", "CT", "DC", "DC"}; + const char *code_list[] = {"", "CT", "DC", "DC"}; #else - const char *code_list[] = {"", "CT", "DCS", "DCR"}; + const char *code_list[] = {"", "CT", "DCS", "DCR"}; #endif - if (code_type < ARRAY_SIZE(code_list)) - s = code_list[code_type]; + if (code_type < ARRAY_SIZE(code_list)) + s = code_list[code_type]; #ifdef ENABLE_FEAT_F4HWN - if(gCurrentFunction != FUNCTION_TRANSMIT || activeTxVFO != vfo_num) - t = gModulationStr[mod]; + if(gCurrentFunction != FUNCTION_TRANSMIT || activeTxVFO != vfo_num) + t = gModulationStr[mod]; #endif - break; - } - default: - t = gModulationStr[mod]; - break; - } + break; + } + default: + t = gModulationStr[mod]; + break; + } #if ENABLE_FEAT_F4HWN - const FREQ_Config_t *pConfig = (mode == VFO_MODE_TX) ? vfoInfo->pTX : vfoInfo->pRX; - int8_t shift = 0; + const FREQ_Config_t *pConfig = (mode == VFO_MODE_TX) ? vfoInfo->pTX : vfoInfo->pRX; + int8_t shift = 0; - switch((int)pConfig->CodeType) - { - case 1: - sprintf(String, "%u.%u", CTCSS_Options[pConfig->Code] / 10, CTCSS_Options[pConfig->Code] % 10); - break; + switch((int)pConfig->CodeType) + { + case 1: + sprintf(String, "%u.%u", CTCSS_Options[pConfig->Code] / 10, CTCSS_Options[pConfig->Code] % 10); + break; - case 2: - sprintf(String, "%03oN", DCS_Options[pConfig->Code]); - break; + case 2: + sprintf(String, "%03oN", DCS_Options[pConfig->Code]); + break; - case 3: - sprintf(String, "%03oI", DCS_Options[pConfig->Code]); - break; + case 3: + sprintf(String, "%03oI", DCS_Options[pConfig->Code]); + break; - default: - sprintf(String, "%d.%02uK", vfoInfo->StepFrequency / 100, vfoInfo->StepFrequency % 100); - shift = -10; - } + default: + sprintf(String, "%d.%02uK", vfoInfo->StepFrequency / 100, vfoInfo->StepFrequency % 100); + shift = -10; + } - if (isMainOnly(true)) - { - UI_PrintStringSmallNormal(s, LCD_WIDTH + 22, 0, line + 1); - UI_PrintStringSmallNormal(t, LCD_WIDTH + 2, 0, line + 1); + if (isMainOnly(true)) + { + UI_PrintStringSmallNormal(s, LCD_WIDTH + 22, 0, line + 1); + UI_PrintStringSmallNormal(t, LCD_WIDTH + 2, 0, line + 1); - if (isMainOnly(false) && !gDTMF_InputMode) - { - if(shift == 0) - { - UI_PrintStringSmallNormal(String, 2, 0, 6); - } + if (isMainOnly(false) && !gDTMF_InputMode) + { + if(shift == 0) + { + UI_PrintStringSmallNormal(String, 2, 0, 6); + } - if((vfoInfo->StepFrequency / 100) < 100) - { - sprintf(String, "%d.%02uK", vfoInfo->StepFrequency / 100, vfoInfo->StepFrequency % 100); - } - else - { - sprintf(String, "%dK", vfoInfo->StepFrequency / 100); - } - UI_PrintStringSmallNormal(String, 46, 0, 6); - } - } - else - { - if ((s != NULL) && (s[0] != '\0')) { - GUI_DisplaySmallest(s, 58, line == 0 ? 17 : 49, false, true); - } + if((vfoInfo->StepFrequency / 100) < 100) + { + sprintf(String, "%d.%02uK", vfoInfo->StepFrequency / 100, vfoInfo->StepFrequency % 100); + } + else + { + sprintf(String, "%dK", vfoInfo->StepFrequency / 100); + } + UI_PrintStringSmallNormal(String, 46, 0, 6); + } + } + else + { + if ((s != NULL) && (s[0] != '\0')) { + GUI_DisplaySmallest(s, 58, line == 0 ? 17 : 49, false, true); + } - if ((t != NULL) && (t[0] != '\0')) { - GUI_DisplaySmallest(t, 3, line == 0 ? 17 : 49, false, true); - } + if ((t != NULL) && (t[0] != '\0')) { + GUI_DisplaySmallest(t, 3, line == 0 ? 17 : 49, false, true); + } - GUI_DisplaySmallest(String, 68 + shift, line == 0 ? 17 : 49, false, true); + GUI_DisplaySmallest(String, 68 + shift, line == 0 ? 17 : 49, false, true); - //sprintf(String, "%d.%02u", vfoInfo->StepFrequency / 100, vfoInfo->StepFrequency % 100); - //GUI_DisplaySmallest(String, 91, line == 0 ? 2 : 34, false, true); - } + //sprintf(String, "%d.%02u", vfoInfo->StepFrequency / 100, vfoInfo->StepFrequency % 100); + //GUI_DisplaySmallest(String, 91, line == 0 ? 2 : 34, false, true); + } #else - UI_PrintStringSmallNormal(s, LCD_WIDTH + 24, 0, line + 1); + UI_PrintStringSmallNormal(s, LCD_WIDTH + 24, 0, line + 1); #endif - if (state == VFO_STATE_NORMAL || state == VFO_STATE_ALARM) - { // show the TX power - uint8_t currentPower = vfoInfo->OUTPUT_POWER % 8; - uint8_t arrowPos = 19; - bool userPower = false; + if (state == VFO_STATE_NORMAL || state == VFO_STATE_ALARM) + { // show the TX power + uint8_t currentPower = vfoInfo->OUTPUT_POWER % 8; + uint8_t arrowPos = 19; + bool userPower = false; - if(currentPower == OUTPUT_POWER_USER) - { - currentPower = gSetting_set_pwr; - userPower = true; - } - else - { - currentPower--; - userPower = false; - } + if(currentPower == OUTPUT_POWER_USER) + { + currentPower = gSetting_set_pwr; + userPower = true; + } + else + { + currentPower--; + userPower = false; + } - if (isMainOnly(true)) - { - const char pwr_short[][3] = {"L1", "L2", "L3", "L4", "L5", "M", "H"}; - sprintf(String, "%s", pwr_short[currentPower]); - UI_PrintStringSmallNormal(String, LCD_WIDTH + 42, 0, line + 1); - arrowPos = 38; - } - else - { - const char pwr_long[][5] = {"LOW1", "LOW2", "LOW3", "LOW4", "LOW5", "MID", "HIGH"}; - sprintf(String, "%s", pwr_long[currentPower]); - GUI_DisplaySmallest(String, 24, line == 0 ? 17 : 49, false, true); - } + if (isMainOnly(true)) + { + const char pwr_short[][3] = {"L1", "L2", "L3", "L4", "L5", "M", "H"}; + sprintf(String, "%s", pwr_short[currentPower]); + UI_PrintStringSmallNormal(String, LCD_WIDTH + 42, 0, line + 1); + arrowPos = 38; + } + else + { + const char pwr_long[][5] = {"LOW1", "LOW2", "LOW3", "LOW4", "LOW5", "MID", "HIGH"}; + sprintf(String, "%s", pwr_long[currentPower]); + GUI_DisplaySmallest(String, 24, line == 0 ? 17 : 49, false, true); + } - if(userPower == true) - { - memcpy(p_line0 + 256 + arrowPos, BITMAP_PowerUser, sizeof(BITMAP_PowerUser)); - } - } + if(userPower == true) + { + memcpy(p_line0 + 256 + arrowPos, BITMAP_PowerUser, sizeof(BITMAP_PowerUser)); + } + } - if (vfoInfo->freq_config_RX.Frequency != vfoInfo->freq_config_TX.Frequency) - { // show the TX offset symbol - const char dir_list[][2] = {"", "+", "-"}; - int i = vfoInfo->TX_OFFSET_FREQUENCY_DIRECTION % 3; + if (vfoInfo->freq_config_RX.Frequency != vfoInfo->freq_config_TX.Frequency) + { // show the TX offset symbol + const char dir_list[][2] = {"", "+", "-"}; + int i = vfoInfo->TX_OFFSET_FREQUENCY_DIRECTION % 3; #if ENABLE_FEAT_F4HWN - if (isMainOnly(true)) - { - UI_PrintStringSmallNormal(dir_list[i], LCD_WIDTH + 60, 0, line + 1); - } - else - { - UI_PrintStringSmallNormal(dir_list[i], LCD_WIDTH + 41, 0, line + 1); - } + if (isMainOnly(true)) + { + UI_PrintStringSmallNormal(dir_list[i], LCD_WIDTH + 60, 0, line + 1); + } + else + { + UI_PrintStringSmallNormal(dir_list[i], LCD_WIDTH + 41, 0, line + 1); + } #else - UI_PrintStringSmallNormal(dir_list[i], LCD_WIDTH + 54, 0, line + 1); + UI_PrintStringSmallNormal(dir_list[i], LCD_WIDTH + 54, 0, line + 1); #endif - } + } - // show the TX/RX reverse symbol - if (vfoInfo->FrequencyReverse) + // show the TX/RX reverse symbol + if (vfoInfo->FrequencyReverse) #if ENABLE_FEAT_F4HWN - { - if (isMainOnly(true)) - { - UI_PrintStringSmallNormal("R", LCD_WIDTH + 68, 0, line + 1); - } - else - { - GUI_DisplaySmallest("R", 51, line == 0 ? 17 : 49, false, true); - } - } + { + if (isMainOnly(true)) + { + UI_PrintStringSmallNormal("R", LCD_WIDTH + 68, 0, line + 1); + } + else + { + GUI_DisplaySmallest("R", 51, line == 0 ? 17 : 49, false, true); + } + } #else - UI_PrintStringSmallNormal("R", LCD_WIDTH + 62, 0, line + 1); + UI_PrintStringSmallNormal("R", LCD_WIDTH + 62, 0, line + 1); #endif #if ENABLE_FEAT_F4HWN - if (isMainOnly(true)) - { - const char *bandWidthNames[] = {"W", "N"}; - UI_PrintStringSmallNormal(bandWidthNames[vfoInfo->CHANNEL_BANDWIDTH], LCD_WIDTH + 80, 0, line + 1); - } - else - { - const char *bandWidthNames[] = {"WIDE", "NAR"}; - GUI_DisplaySmallest(bandWidthNames[vfoInfo->CHANNEL_BANDWIDTH], 91, line == 0 ? 17 : 49, false, true); - } + if (isMainOnly(true)) + { + const char *bandWidthNames[] = {"W", "N"}; + UI_PrintStringSmallNormal(bandWidthNames[vfoInfo->CHANNEL_BANDWIDTH], LCD_WIDTH + 80, 0, line + 1); + } + else + { + const char *bandWidthNames[] = {"WIDE", "NAR"}; + GUI_DisplaySmallest(bandWidthNames[vfoInfo->CHANNEL_BANDWIDTH], 91, line == 0 ? 17 : 49, false, true); + } #else - if (vfoInfo->CHANNEL_BANDWIDTH == BANDWIDTH_NARROW) - UI_PrintStringSmallNormal("N", LCD_WIDTH + 70, 0, line + 1); + if (vfoInfo->CHANNEL_BANDWIDTH == BANDWIDTH_NARROW) + UI_PrintStringSmallNormal("N", LCD_WIDTH + 70, 0, line + 1); #endif #ifdef ENABLE_DTMF_CALLING - // show the DTMF decoding symbol - if (vfoInfo->DTMF_DECODING_ENABLE || gSetting_KILLED) - UI_PrintStringSmallNormal("DTMF", LCD_WIDTH + 78, 0, line + 1); + // show the DTMF decoding symbol + if (vfoInfo->DTMF_DECODING_ENABLE || gSetting_KILLED) + UI_PrintStringSmallNormal("DTMF", LCD_WIDTH + 78, 0, line + 1); #endif #ifndef ENABLE_FEAT_F4HWN - // show the audio scramble symbol - if (vfoInfo->SCRAMBLING_TYPE > 0 && gSetting_ScrambleEnable) - UI_PrintStringSmallNormal("SCR", LCD_WIDTH + 106, 0, line + 1); + // show the audio scramble symbol + if (vfoInfo->SCRAMBLING_TYPE > 0 && gSetting_ScrambleEnable) + UI_PrintStringSmallNormal("SCR", LCD_WIDTH + 106, 0, line + 1); #endif #ifdef ENABLE_FEAT_F4HWN - if(isMainVFO) - { - if(gMonitor) - { - sprintf(String, "%s", "MONI"); - } - - if (isMainOnly(true)) - { - if(!gMonitor) - { - sprintf(String, "SQL%d", gEeprom.SQUELCH_LEVEL); - } - UI_PrintStringSmallNormal(String, LCD_WIDTH + 98, 0, line + 1); - } - else - { - if(!gMonitor) - { - sprintf(String, "SQL%d", gEeprom.SQUELCH_LEVEL); - } - GUI_DisplaySmallest(String, 110, line == 0 ? 17 : 49, false, true); - } - } + if(isMainVFO) + { + if(gMonitor) + { + sprintf(String, "%s", "MONI"); + } + + if (isMainOnly(true)) + { + if(!gMonitor) + { + sprintf(String, "SQL%d", gEeprom.SQUELCH_LEVEL); + } + UI_PrintStringSmallNormal(String, LCD_WIDTH + 98, 0, line + 1); + } + else + { + if(!gMonitor) + { + sprintf(String, "SQL%d", gEeprom.SQUELCH_LEVEL); + } + GUI_DisplaySmallest(String, 110, line == 0 ? 17 : 49, false, true); + } + } #endif - } + } #ifdef ENABLE_AGC_SHOW_DATA - center_line = CENTER_LINE_IN_USE; - UI_MAIN_PrintAGC(false); + center_line = CENTER_LINE_IN_USE; + UI_MAIN_PrintAGC(false); #endif - if (center_line == CENTER_LINE_NONE) - { // we're free to use the middle line + if (center_line == CENTER_LINE_NONE) + { // we're free to use the middle line - const bool rx = FUNCTION_IsRx(); + const bool rx = FUNCTION_IsRx(); #ifdef ENABLE_AUDIO_BAR - if (gSetting_mic_bar && gCurrentFunction == FUNCTION_TRANSMIT) { - center_line = CENTER_LINE_AUDIO_BAR; - UI_DisplayAudioBar(); - } - else + if (gSetting_mic_bar && gCurrentFunction == FUNCTION_TRANSMIT) { + center_line = CENTER_LINE_AUDIO_BAR; + UI_DisplayAudioBar(); + } + else #endif #if defined(ENABLE_AM_FIX) && defined(ENABLE_AM_FIX_SHOW_DATA) - if (rx && gEeprom.VfoInfo[gEeprom.RX_VFO].Modulation == MODULATION_AM && gSetting_AM_fix) - { - if (gScreenToDisplay != DISPLAY_MAIN + if (rx && gEeprom.VfoInfo[gEeprom.RX_VFO].Modulation == MODULATION_AM && gSetting_AM_fix) + { + if (gScreenToDisplay != DISPLAY_MAIN #ifdef ENABLE_DTMF_CALLING - || gDTMF_CallState != DTMF_CALL_STATE_NONE + || gDTMF_CallState != DTMF_CALL_STATE_NONE #endif - ) - return; + ) + return; - center_line = CENTER_LINE_AM_FIX_DATA; - AM_fix_print_data(gEeprom.RX_VFO, String); - UI_PrintStringSmallNormal(String, 2, 0, 3); - } - else + center_line = CENTER_LINE_AM_FIX_DATA; + AM_fix_print_data(gEeprom.RX_VFO, String); + UI_PrintStringSmallNormal(String, 2, 0, 3); + } + else #endif #ifdef ENABLE_RSSI_BAR - if (rx) { - center_line = CENTER_LINE_RSSI; - DisplayRSSIBar(false); - } - else + if (rx) { + center_line = CENTER_LINE_RSSI; + DisplayRSSIBar(false); + } + else #endif - if (rx || gCurrentFunction == FUNCTION_FOREGROUND || gCurrentFunction == FUNCTION_POWER_SAVE) - { - #if 1 - if (gSetting_live_DTMF_decoder && gDTMF_RX_live[0] != 0) - { // show live DTMF decode - const unsigned int len = strlen(gDTMF_RX_live); - const unsigned int idx = (len > (17 - 5)) ? len - (17 - 5) : 0; // limit to last 'n' chars + if (rx || gCurrentFunction == FUNCTION_FOREGROUND || gCurrentFunction == FUNCTION_POWER_SAVE) + { + #if 1 + if (gSetting_live_DTMF_decoder && gDTMF_RX_live[0] != 0) + { // show live DTMF decode + const unsigned int len = strlen(gDTMF_RX_live); + const unsigned int idx = (len > (17 - 5)) ? len - (17 - 5) : 0; // limit to last 'n' chars - if (gScreenToDisplay != DISPLAY_MAIN + if (gScreenToDisplay != DISPLAY_MAIN #ifdef ENABLE_DTMF_CALLING - || gDTMF_CallState != DTMF_CALL_STATE_NONE + || gDTMF_CallState != DTMF_CALL_STATE_NONE #endif - ) - return; + ) + return; - center_line = CENTER_LINE_DTMF_DEC; + center_line = CENTER_LINE_DTMF_DEC; - sprintf(String, "DTMF %s", gDTMF_RX_live + idx); + sprintf(String, "DTMF %s", gDTMF_RX_live + idx); #ifdef ENABLE_FEAT_F4HWN - if (isMainOnly(false)) - { - UI_PrintStringSmallNormal(String, 2, 0, 5); - } - else - { - UI_PrintStringSmallNormal(String, 2, 0, 3); - } + if (isMainOnly(false)) + { + UI_PrintStringSmallNormal(String, 2, 0, 5); + } + else + { + UI_PrintStringSmallNormal(String, 2, 0, 3); + } #else - UI_PrintStringSmallNormal(String, 2, 0, 3); + UI_PrintStringSmallNormal(String, 2, 0, 3); #endif - } - #else - if (gSetting_live_DTMF_decoder && gDTMF_RX_index > 0) - { // show live DTMF decode - const unsigned int len = gDTMF_RX_index; - const unsigned int idx = (len > (17 - 5)) ? len - (17 - 5) : 0; // limit to last 'n' chars + } + #else + if (gSetting_live_DTMF_decoder && gDTMF_RX_index > 0) + { // show live DTMF decode + const unsigned int len = gDTMF_RX_index; + const unsigned int idx = (len > (17 - 5)) ? len - (17 - 5) : 0; // limit to last 'n' chars - if (gScreenToDisplay != DISPLAY_MAIN || - gDTMF_CallState != DTMF_CALL_STATE_NONE) - return; + if (gScreenToDisplay != DISPLAY_MAIN || + gDTMF_CallState != DTMF_CALL_STATE_NONE) + return; - center_line = CENTER_LINE_DTMF_DEC; + center_line = CENTER_LINE_DTMF_DEC; - sprintf(String, "DTMF %s", gDTMF_RX_live + idx); - UI_PrintStringSmallNormal(String, 2, 0, 3); - } - #endif + sprintf(String, "DTMF %s", gDTMF_RX_live + idx); + UI_PrintStringSmallNormal(String, 2, 0, 3); + } + #endif #ifdef ENABLE_SHOW_CHARGE_LEVEL - else if (gChargingWithTypeC) - { // charging .. show the battery state - if (gScreenToDisplay != DISPLAY_MAIN + else if (gChargingWithTypeC) + { // charging .. show the battery state + if (gScreenToDisplay != DISPLAY_MAIN #ifdef ENABLE_DTMF_CALLING - || gDTMF_CallState != DTMF_CALL_STATE_NONE + || gDTMF_CallState != DTMF_CALL_STATE_NONE #endif - ) - return; + ) + return; - center_line = CENTER_LINE_CHARGE_DATA; + center_line = CENTER_LINE_CHARGE_DATA; - sprintf(String, "Charge %u.%02uV %u%%", - gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100, - BATTERY_VoltsToPercent(gBatteryVoltageAverage)); - UI_PrintStringSmallNormal(String, 2, 0, 3); - } + sprintf(String, "Charge %u.%02uV %u%%", + gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100, + BATTERY_VoltsToPercent(gBatteryVoltageAverage)); + UI_PrintStringSmallNormal(String, 2, 0, 3); + } #endif - } - } + } + } #ifdef ENABLE_FEAT_F4HWN - if (isMainOnly(false) && !gDTMF_InputMode) - { - sprintf(String, "VFO %s", activeTxVFO ? "B" : "A"); - UI_PrintStringSmallBold(String, 92, 0, 6); - for (uint8_t i = 92; i < 128; i++) - { - gFrameBuffer[6][i] ^= 0x7F; - } - } + if (isMainOnly(false) && !gDTMF_InputMode) + { + sprintf(String, "VFO %s", activeTxVFO ? "B" : "A"); + UI_PrintStringSmallBold(String, 92, 0, 6); + for (uint8_t i = 92; i < 128; i++) + { + gFrameBuffer[6][i] ^= 0x7F; + } + } #endif - ST7565_BlitFullScreen(); + ST7565_BlitFullScreen(); } // *************************************************************************** diff --git a/ui/main.h b/ui/main.h index 16a6ec3..92a1cb3 100644 --- a/ui/main.h +++ b/ui/main.h @@ -18,19 +18,19 @@ #define UI_MAIN_H enum center_line_t { - CENTER_LINE_NONE = 0, - CENTER_LINE_IN_USE, - CENTER_LINE_AUDIO_BAR, - CENTER_LINE_RSSI, - CENTER_LINE_AM_FIX_DATA, - CENTER_LINE_DTMF_DEC, - CENTER_LINE_CHARGE_DATA + CENTER_LINE_NONE = 0, + CENTER_LINE_IN_USE, + CENTER_LINE_AUDIO_BAR, + CENTER_LINE_RSSI, + CENTER_LINE_AM_FIX_DATA, + CENTER_LINE_DTMF_DEC, + CENTER_LINE_CHARGE_DATA }; enum Vfo_txtr_mode{ - VFO_MODE_NONE = 0, - VFO_MODE_TX = 1, - VFO_MODE_RX = 2, + VFO_MODE_NONE = 0, + VFO_MODE_TX = 1, + VFO_MODE_RX = 2, }; typedef enum center_line_t center_line_t; diff --git a/ui/menu.c b/ui/menu.c index 6be7848..e2a8b78 100644 --- a/ui/menu.c +++ b/ui/menu.c @@ -40,393 +40,393 @@ const t_menu_item MenuList[] = { // text, menu ID - {"Step", MENU_STEP }, - {"Power", MENU_TXP }, // was "TXP" - {"RxDCS", MENU_R_DCS }, // was "R_DCS" - {"RxCTCS", MENU_R_CTCS }, // was "R_CTCS" - {"TxDCS", MENU_T_DCS }, // was "T_DCS" - {"TxCTCS", MENU_T_CTCS }, // was "T_CTCS" - {"TxODir", MENU_SFT_D }, // was "SFT_D" - {"TxOffs", MENU_OFFSET }, // was "OFFSET" - {"W/N", MENU_W_N }, + {"Step", MENU_STEP }, + {"Power", MENU_TXP }, // was "TXP" + {"RxDCS", MENU_R_DCS }, // was "R_DCS" + {"RxCTCS", MENU_R_CTCS }, // was "R_CTCS" + {"TxDCS", MENU_T_DCS }, // was "T_DCS" + {"TxCTCS", MENU_T_CTCS }, // was "T_CTCS" + {"TxODir", MENU_SFT_D }, // was "SFT_D" + {"TxOffs", MENU_OFFSET }, // was "OFFSET" + {"W/N", MENU_W_N }, #ifndef ENABLE_FEAT_F4HWN - {"Scramb", MENU_SCR }, // was "SCR" + {"Scramb", MENU_SCR }, // was "SCR" #endif - {"BusyCL", MENU_BCL }, // was "BCL" - {"Compnd", MENU_COMPAND }, - {"Mode", MENU_AM }, // was "AM" + {"BusyCL", MENU_BCL }, // was "BCL" + {"Compnd", MENU_COMPAND }, + {"Mode", MENU_AM }, // was "AM" #ifdef ENABLE_FEAT_F4HWN - {"TXLock", MENU_TX_LOCK }, + {"TXLock", MENU_TX_LOCK }, #endif - {"ScAdd1", MENU_S_ADD1 }, - {"ScAdd2", MENU_S_ADD2 }, - {"ScAdd3", MENU_S_ADD3 }, - {"ChSave", MENU_MEM_CH }, // was "MEM-CH" - {"ChDele", MENU_DEL_CH }, // was "DEL-CH" - {"ChName", MENU_MEM_NAME }, + {"ScAdd1", MENU_S_ADD1 }, + {"ScAdd2", MENU_S_ADD2 }, + {"ScAdd3", MENU_S_ADD3 }, + {"ChSave", MENU_MEM_CH }, // was "MEM-CH" + {"ChDele", MENU_DEL_CH }, // was "DEL-CH" + {"ChName", MENU_MEM_NAME }, - {"SList", MENU_S_LIST }, - {"SList1", MENU_SLIST1 }, - {"SList2", MENU_SLIST2 }, - {"SList3", MENU_SLIST3 }, - {"ScnRev", MENU_SC_REV }, + {"SList", MENU_S_LIST }, + {"SList1", MENU_SLIST1 }, + {"SList2", MENU_SLIST2 }, + {"SList3", MENU_SLIST3 }, + {"ScnRev", MENU_SC_REV }, #ifdef ENABLE_NOAA - {"NOAA-S", MENU_NOAA_S }, + {"NOAA-S", MENU_NOAA_S }, #endif - {"F1Shrt", MENU_F1SHRT }, - {"F1Long", MENU_F1LONG }, - {"F2Shrt", MENU_F2SHRT }, - {"F2Long", MENU_F2LONG }, - {"M Long", MENU_MLONG }, + {"F1Shrt", MENU_F1SHRT }, + {"F1Long", MENU_F1LONG }, + {"F2Shrt", MENU_F2SHRT }, + {"F2Long", MENU_F2LONG }, + {"M Long", MENU_MLONG }, - {"KeyLck", MENU_AUTOLK }, // was "AUTOLk" - {"TxTOut", MENU_TOT }, // was "TOT" - {"BatSav", MENU_SAVE }, // was "SAVE" - {"BatTxt", MENU_BAT_TXT }, - {"Mic", MENU_MIC }, + {"KeyLck", MENU_AUTOLK }, // was "AUTOLk" + {"TxTOut", MENU_TOT }, // was "TOT" + {"BatSav", MENU_SAVE }, // was "SAVE" + {"BatTxt", MENU_BAT_TXT }, + {"Mic", MENU_MIC }, #ifdef ENABLE_AUDIO_BAR - {"MicBar", MENU_MIC_BAR }, + {"MicBar", MENU_MIC_BAR }, #endif - {"ChDisp", MENU_MDF }, // was "MDF" - {"POnMsg", MENU_PONMSG }, - {"BLTime", MENU_ABR }, // was "ABR" - {"BLMin", MENU_ABR_MIN }, - {"BLMax", MENU_ABR_MAX }, - {"BLTxRx", MENU_ABR_ON_TX_RX }, - {"Beep", MENU_BEEP }, + {"ChDisp", MENU_MDF }, // was "MDF" + {"POnMsg", MENU_PONMSG }, + {"BLTime", MENU_ABR }, // was "ABR" + {"BLMin", MENU_ABR_MIN }, + {"BLMax", MENU_ABR_MAX }, + {"BLTxRx", MENU_ABR_ON_TX_RX }, + {"Beep", MENU_BEEP }, #ifdef ENABLE_VOICE - {"Voice", MENU_VOICE }, + {"Voice", MENU_VOICE }, #endif - {"Roger", MENU_ROGER }, - {"STE", MENU_STE }, - {"RP STE", MENU_RP_STE }, - {"1 Call", MENU_1_CALL }, + {"Roger", MENU_ROGER }, + {"STE", MENU_STE }, + {"RP STE", MENU_RP_STE }, + {"1 Call", MENU_1_CALL }, #ifdef ENABLE_ALARM - {"AlarmT", MENU_AL_MOD }, + {"AlarmT", MENU_AL_MOD }, #endif #ifdef ENABLE_DTMF_CALLING - {"ANI ID", MENU_ANI_ID }, + {"ANI ID", MENU_ANI_ID }, #endif - {"UPCode", MENU_UPCODE }, - {"DWCode", MENU_DWCODE }, - {"PTT ID", MENU_PTT_ID }, - {"D ST", MENU_D_ST }, + {"UPCode", MENU_UPCODE }, + {"DWCode", MENU_DWCODE }, + {"PTT ID", MENU_PTT_ID }, + {"D ST", MENU_D_ST }, #ifdef ENABLE_DTMF_CALLING - {"D Resp", MENU_D_RSP }, - {"D Hold", MENU_D_HOLD }, + {"D Resp", MENU_D_RSP }, + {"D Hold", MENU_D_HOLD }, #endif - {"D Prel", MENU_D_PRE }, + {"D Prel", MENU_D_PRE }, #ifdef ENABLE_DTMF_CALLING - {"D Decd", MENU_D_DCD }, - {"D List", MENU_D_LIST }, + {"D Decd", MENU_D_DCD }, + {"D List", MENU_D_LIST }, #endif - {"D Live", MENU_D_LIVE_DEC }, // live DTMF decoder + {"D Live", MENU_D_LIVE_DEC }, // live DTMF decoder #ifndef ENABLE_FEAT_F4HWN - #ifdef ENABLE_AM_FIX - {"AM Fix", MENU_AM_FIX }, - #endif + #ifdef ENABLE_AM_FIX + {"AM Fix", MENU_AM_FIX }, + #endif #endif #ifdef ENABLE_VOX - {"VOX", MENU_VOX }, + {"VOX", MENU_VOX }, #endif #ifdef ENABLE_FEAT_F4HWN - {"SysInf", MENU_VOL }, // was "VOL" + {"SysInf", MENU_VOL }, // was "VOL" #else - {"BatVol", MENU_VOL }, // was "VOL" + {"BatVol", MENU_VOL }, // was "VOL" #endif - {"RxMode", MENU_TDR }, - {"Sql", MENU_SQL }, + {"RxMode", MENU_TDR }, + {"Sql", MENU_SQL }, #ifdef ENABLE_FEAT_F4HWN - {"SetPwr", MENU_SET_PWR }, - {"SetPtt", MENU_SET_PTT }, - {"SetTot", MENU_SET_TOT }, - {"SetEot", MENU_SET_EOT }, - {"SetCtr", MENU_SET_CTR }, - {"SetInv", MENU_SET_INV }, - {"SetLck", MENU_SET_LCK }, - {"SetMet", MENU_SET_MET }, - {"SetGui", MENU_SET_GUI }, - {"SetTmr", MENU_SET_TMR }, + {"SetPwr", MENU_SET_PWR }, + {"SetPtt", MENU_SET_PTT }, + {"SetTot", MENU_SET_TOT }, + {"SetEot", MENU_SET_EOT }, + {"SetCtr", MENU_SET_CTR }, + {"SetInv", MENU_SET_INV }, + {"SetLck", MENU_SET_LCK }, + {"SetMet", MENU_SET_MET }, + {"SetGui", MENU_SET_GUI }, + {"SetTmr", MENU_SET_TMR }, #endif - // hidden menu items from here on - // enabled if pressing both the PTT and upper side button at power-on - {"F Lock", MENU_F_LOCK }, - {"Tx 200", MENU_200TX }, // was "200TX" - {"Tx 350", MENU_350TX }, // was "350TX" - {"Tx 500", MENU_500TX }, // was "500TX" - {"350 En", MENU_350EN }, // was "350EN" + // hidden menu items from here on + // enabled if pressing both the PTT and upper side button at power-on + {"F Lock", MENU_F_LOCK }, + {"Tx 200", MENU_200TX }, // was "200TX" + {"Tx 350", MENU_350TX }, // was "350TX" + {"Tx 500", MENU_500TX }, // was "500TX" + {"350 En", MENU_350EN }, // was "350EN" #ifndef ENABLE_FEAT_F4HWN - {"ScraEn", MENU_SCREN }, // was "SCREN" + {"ScraEn", MENU_SCREN }, // was "SCREN" #endif #ifdef ENABLE_F_CAL_MENU - {"FrCali", MENU_F_CALI }, // reference xtal calibration + {"FrCali", MENU_F_CALI }, // reference xtal calibration #endif - {"BatCal", MENU_BATCAL }, // battery voltage calibration - {"BatTyp", MENU_BATTYP }, // battery type 1600/2200mAh - {"Reset", MENU_RESET }, // might be better to move this to the hidden menu items ? + {"BatCal", MENU_BATCAL }, // battery voltage calibration + {"BatTyp", MENU_BATTYP }, // battery type 1600/2200mAh + {"Reset", MENU_RESET }, // might be better to move this to the hidden menu items ? - {"", 0xff } // end of list - DO NOT delete or move this this + {"", 0xff } // end of list - DO NOT delete or move this this }; const uint8_t FIRST_HIDDEN_MENU_ITEM = MENU_F_LOCK; const char gSubMenu_TXP[][6] = { - "USER", - "LOW 1", - "LOW 2", - "LOW 3", - "LOW 4", - "LOW 5", - "MID", - "HIGH" + "USER", + "LOW 1", + "LOW 2", + "LOW 3", + "LOW 4", + "LOW 5", + "MID", + "HIGH" }; const char gSubMenu_SFT_D[][4] = { - "OFF", - "+", - "-" + "OFF", + "+", + "-" }; const char gSubMenu_W_N[][7] = { - "WIDE", - "NARROW" + "WIDE", + "NARROW" }; const char gSubMenu_OFF_ON[][4] = { - "OFF", - "ON" + "OFF", + "ON" }; const char gSubMenu_SAVE[][4] = { - "OFF", - "1:1", - "1:2", - "1:3", - "1:4" + "OFF", + "1:1", + "1:2", + "1:3", + "1:4" }; const char* const gSubMenu_RXMode[] = { - "MAIN\nONLY", // TX and RX on main only - "DUAL RX\nRESPOND", // Watch both and respond - "CROSS\nBAND", // TX on main, RX on secondary - "MAIN TX\nDUAL RX" // always TX on main, but RX on both + "MAIN\nONLY", // TX and RX on main only + "DUAL RX\nRESPOND", // Watch both and respond + "CROSS\nBAND", // TX on main, RX on secondary + "MAIN TX\nDUAL RX" // always TX on main, but RX on both }; #ifdef ENABLE_VOICE - const char gSubMenu_VOICE[][4] = - { - "OFF", - "CHI", - "ENG" - }; + const char gSubMenu_VOICE[][4] = + { + "OFF", + "CHI", + "ENG" + }; #endif const char gSubMenu_SC_REV[][8] = { - "TIMEOUT", - "CARRIER", - "STOP" + "TIMEOUT", + "CARRIER", + "STOP" }; const char* const gSubMenu_MDF[] = { - "FREQ", - "CHANNEL\nNUMBER", - "NAME", - "NAME\n+\nFREQ" + "FREQ", + "CHANNEL\nNUMBER", + "NAME", + "NAME\n+\nFREQ" }; #ifdef ENABLE_ALARM - const char gSubMenu_AL_MOD[][5] = - { - "SITE", - "TONE" - }; + const char gSubMenu_AL_MOD[][5] = + { + "SITE", + "TONE" + }; #endif #ifdef ENABLE_DTMF_CALLING const char gSubMenu_D_RSP[][11] = { - "DO\nNOTHING", - "RING", - "REPLY", - "BOTH" + "DO\nNOTHING", + "RING", + "REPLY", + "BOTH" }; #endif const char* const gSubMenu_PTT_ID[] = { - "OFF", - "UP CODE", - "DOWN CODE", - "UP+DOWN\nCODE", - "APOLLO\nQUINDAR" + "OFF", + "UP CODE", + "DOWN CODE", + "UP+DOWN\nCODE", + "APOLLO\nQUINDAR" }; const char gSubMenu_PONMSG[][8] = { #ifdef ENABLE_FEAT_F4HWN - "ALL", - "SOUND", + "ALL", + "SOUND", #else - "FULL", + "FULL", #endif - "MESSAGE", - "VOLTAGE", - "NONE" + "MESSAGE", + "VOLTAGE", + "NONE" }; const char gSubMenu_ROGER[][6] = { - "OFF", - "ROGER", - "MDC" + "OFF", + "ROGER", + "MDC" }; const char gSubMenu_RESET[][4] = { - "VFO", - "ALL" + "VFO", + "ALL" }; const char * const gSubMenu_F_LOCK[] = { - "DEFAULT+\n137-174\n400-470", - "FCC HAM\n144-148\n420-450", + "DEFAULT+\n137-174\n400-470", + "FCC HAM\n144-148\n420-450", #ifdef ENABLE_FEAT_F4HWN_CA - "CA HAM\n144-148\n430-450", + "CA HAM\n144-148\n430-450", #endif - "CE HAM\n144-146\n430-440", - "GB HAM\n144-148\n430-440", - "137-174\n400-430", - "137-174\n400-438", + "CE HAM\n144-146\n430-440", + "GB HAM\n144-148\n430-440", + "137-174\n400-430", + "137-174\n400-438", #ifdef ENABLE_FEAT_F4HWN_PMR - "PMR 446", + "PMR 446", #endif #ifdef ENABLE_FEAT_F4HWN_GMRS_FRS_MURS - "GMRS\nFRS\nMURS", + "GMRS\nFRS\nMURS", #endif - "DISABLE\nALL", - "UNLOCK\nALL", + "DISABLE\nALL", + "UNLOCK\nALL", }; const char gSubMenu_RX_TX[][6] = { - "OFF", - "TX", - "RX", - "TX/RX" + "OFF", + "TX", + "RX", + "TX/RX" }; const char gSubMenu_BAT_TXT[][8] = { - "NONE", - "VOLTAGE", - "PERCENT" + "NONE", + "VOLTAGE", + "PERCENT" }; const char gSubMenu_BATTYP[][9] = { - "1600mAh", - "2200mAh", - "3500mAh" + "1600mAh", + "2200mAh", + "3500mAh" }; #ifndef ENABLE_FEAT_F4HWN const char gSubMenu_SCRAMBLER[][7] = { - "OFF", - "2600Hz", - "2700Hz", - "2800Hz", - "2900Hz", - "3000Hz", - "3100Hz", - "3200Hz", - "3300Hz", - "3400Hz", - "3500Hz" + "OFF", + "2600Hz", + "2700Hz", + "2800Hz", + "2900Hz", + "3000Hz", + "3100Hz", + "3200Hz", + "3300Hz", + "3400Hz", + "3500Hz" }; #endif #ifdef ENABLE_FEAT_F4HWN - const char gSubMenu_SET_PWR[][6] = - { - "< 20m", - "125m", - "250m", - "500m", - "1", - "2", - "5" - }; + const char gSubMenu_SET_PWR[][6] = + { + "< 20m", + "125m", + "250m", + "500m", + "1", + "2", + "5" + }; - const char gSubMenu_SET_PTT[][8] = - { - "CLASSIC", - "ONEPUSH" - }; + const char gSubMenu_SET_PTT[][8] = + { + "CLASSIC", + "ONEPUSH" + }; - const char gSubMenu_SET_TOT[][7] = // Use by SET_EOT too - { - "OFF", - "SOUND", - "VISUAL", - "ALL" - }; + const char gSubMenu_SET_TOT[][7] = // Use by SET_EOT too + { + "OFF", + "SOUND", + "VISUAL", + "ALL" + }; - const char gSubMenu_SET_LCK[][9] = - { - "KEYS", - "KEYS+PTT" - }; + const char gSubMenu_SET_LCK[][9] = + { + "KEYS", + "KEYS+PTT" + }; - const char gSubMenu_SET_MET[][8] = - { - "TINY", - "CLASSIC" - }; + const char gSubMenu_SET_MET[][8] = + { + "TINY", + "CLASSIC" + }; #endif const t_sidefunction gSubMenu_SIDEFUNCTIONS[] = { - {"NONE", ACTION_OPT_NONE}, + {"NONE", ACTION_OPT_NONE}, #ifdef ENABLE_FLASHLIGHT - {"FLASH\nLIGHT", ACTION_OPT_FLASHLIGHT}, + {"FLASH\nLIGHT", ACTION_OPT_FLASHLIGHT}, #endif - {"POWER", ACTION_OPT_POWER}, - {"MONITOR", ACTION_OPT_MONITOR}, - {"SCAN", ACTION_OPT_SCAN}, + {"POWER", ACTION_OPT_POWER}, + {"MONITOR", ACTION_OPT_MONITOR}, + {"SCAN", ACTION_OPT_SCAN}, #ifdef ENABLE_VOX - {"VOX", ACTION_OPT_VOX}, + {"VOX", ACTION_OPT_VOX}, #endif #ifdef ENABLE_ALARM - {"ALARM", ACTION_OPT_ALARM}, + {"ALARM", ACTION_OPT_ALARM}, #endif #ifdef ENABLE_FMRADIO - {"FM RADIO", ACTION_OPT_FM}, + {"FM RADIO", ACTION_OPT_FM}, #endif #ifdef ENABLE_TX1750 - {"1750Hz", ACTION_OPT_1750}, + {"1750Hz", ACTION_OPT_1750}, #endif - {"LOCK\nKEYPAD", ACTION_OPT_KEYLOCK}, - {"VFO A\nVFO B", ACTION_OPT_A_B}, - {"VFO\nMEM", ACTION_OPT_VFO_MR}, - {"MODE", ACTION_OPT_SWITCH_DEMODUL}, + {"LOCK\nKEYPAD", ACTION_OPT_KEYLOCK}, + {"VFO A\nVFO B", ACTION_OPT_A_B}, + {"VFO\nMEM", ACTION_OPT_VFO_MR}, + {"MODE", ACTION_OPT_SWITCH_DEMODUL}, #ifdef ENABLE_BLMIN_TMP_OFF - {"BLMIN\nTMP OFF", ACTION_OPT_BLMIN_TMP_OFF}, //BackLight Minimum Temporay OFF + {"BLMIN\nTMP OFF", ACTION_OPT_BLMIN_TMP_OFF}, //BackLight Minimum Temporay OFF #endif #ifdef ENABLE_FEAT_F4HWN - {"RX MODE", ACTION_OPT_RXMODE}, - {"MAIN ONLY", ACTION_OPT_MAINONLY}, - {"PTT", ACTION_OPT_PTT}, - {"WIDE\nNARROW", ACTION_OPT_WN}, + {"RX MODE", ACTION_OPT_RXMODE}, + {"MAIN ONLY", ACTION_OPT_MAINONLY}, + {"PTT", ACTION_OPT_PTT}, + {"WIDE\nNARROW", ACTION_OPT_WN}, #endif }; @@ -435,18 +435,18 @@ const uint8_t gSubMenu_SIDEFUNCTIONS_size = ARRAY_SIZE(gSubMenu_SIDEFUNCTIONS); bool gIsInSubMenu; uint8_t gMenuCursor; int UI_MENU_GetCurrentMenuId() { - if(gMenuCursor < ARRAY_SIZE(MenuList)) - return MenuList[gMenuCursor].menu_id; + if(gMenuCursor < ARRAY_SIZE(MenuList)) + return MenuList[gMenuCursor].menu_id; - return MenuList[ARRAY_SIZE(MenuList)-1].menu_id; + return MenuList[ARRAY_SIZE(MenuList)-1].menu_id; } uint8_t UI_MENU_GetMenuIdx(uint8_t id) { - for(uint8_t i = 0; i < ARRAY_SIZE(MenuList); i++) - if(MenuList[i].menu_id == id) - return i; - return 0; + for(uint8_t i = 0; i < ARRAY_SIZE(MenuList); i++) + if(MenuList[i].menu_id == id) + return i; + return 0; } int32_t gSubMenuSelection; @@ -458,712 +458,712 @@ int edit_index; void UI_DisplayMenu(void) { - const unsigned int menu_list_width = 6; // max no. of characters on the menu list (left side) - const unsigned int menu_item_x1 = (8 * menu_list_width) + 2; - const unsigned int menu_item_x2 = LCD_WIDTH - 1; - unsigned int i; - char String[64]; // bigger cuz we can now do multi-line in one string (use '\n' char) + const unsigned int menu_list_width = 6; // max no. of characters on the menu list (left side) + const unsigned int menu_item_x1 = (8 * menu_list_width) + 2; + const unsigned int menu_item_x2 = LCD_WIDTH - 1; + unsigned int i; + char String[64]; // bigger cuz we can now do multi-line in one string (use '\n' char) #ifdef ENABLE_DTMF_CALLING - char Contact[16]; + char Contact[16]; #endif - UI_DisplayClear(); + UI_DisplayClear(); #ifdef ENABLE_FEAT_F4HWN - UI_DrawLineBuffer(gFrameBuffer, 48, 0, 48, 55, 1); // Be ware, status zone = 8 lines, the rest = 56 ->total 64 - //UI_DrawLineDottedBuffer(gFrameBuffer, 0, 46, 50, 46, 1); + UI_DrawLineBuffer(gFrameBuffer, 48, 0, 48, 55, 1); // Be ware, status zone = 8 lines, the rest = 56 ->total 64 + //UI_DrawLineDottedBuffer(gFrameBuffer, 0, 46, 50, 46, 1); - for (uint8_t i = 0; i < 48; i += 2) - { - gFrameBuffer[5][i] = 0x40; - } + for (uint8_t i = 0; i < 48; i += 2) + { + gFrameBuffer[5][i] = 0x40; + } #endif #ifndef ENABLE_CUSTOM_MENU_LAYOUT - // original menu layout - for (i = 0; i < 3; i++) - if (gMenuCursor > 0 || i > 0) - if ((gMenuListCount - 1) != gMenuCursor || i != 2) - UI_PrintString(MenuList[gMenuCursor + i - 1].name, 0, 0, i * 2, 8); + // original menu layout + for (i = 0; i < 3; i++) + if (gMenuCursor > 0 || i > 0) + if ((gMenuListCount - 1) != gMenuCursor || i != 2) + UI_PrintString(MenuList[gMenuCursor + i - 1].name, 0, 0, i * 2, 8); - // invert the current menu list item pixels - for (i = 0; i < (8 * menu_list_width); i++) - { - gFrameBuffer[2][i] ^= 0xFF; - gFrameBuffer[3][i] ^= 0xFF; - } + // invert the current menu list item pixels + for (i = 0; i < (8 * menu_list_width); i++) + { + gFrameBuffer[2][i] ^= 0xFF; + gFrameBuffer[3][i] ^= 0xFF; + } - // draw vertical separating dotted line - for (i = 0; i < 7; i++) - gFrameBuffer[i][(8 * menu_list_width) + 1] = 0xAA; + // draw vertical separating dotted line + for (i = 0; i < 7; i++) + gFrameBuffer[i][(8 * menu_list_width) + 1] = 0xAA; - // draw the little sub-menu triangle marker - if (gIsInSubMenu) - memcpy(gFrameBuffer[0] + (8 * menu_list_width) + 1, BITMAP_CurrentIndicator, sizeof(BITMAP_CurrentIndicator)); + // draw the little sub-menu triangle marker + if (gIsInSubMenu) + memcpy(gFrameBuffer[0] + (8 * menu_list_width) + 1, BITMAP_CurrentIndicator, sizeof(BITMAP_CurrentIndicator)); - // draw the menu index number/count - sprintf(String, "%2u.%u", 1 + gMenuCursor, gMenuListCount); + // draw the menu index number/count + sprintf(String, "%2u.%u", 1 + gMenuCursor, gMenuListCount); - UI_PrintStringSmallNormal(String, 2, 0, 6); + UI_PrintStringSmallNormal(String, 2, 0, 6); #else - { // new menu layout .. experimental & unfinished - const int menu_index = gMenuCursor; // current selected menu item - i = 1; + { // new menu layout .. experimental & unfinished + const int menu_index = gMenuCursor; // current selected menu item + i = 1; - if (!gIsInSubMenu) { - while (i < 2) - { // leading menu items - small text - const int k = menu_index + i - 2; - if (k < 0) - UI_PrintStringSmallNormal(MenuList[gMenuListCount + k].name, 0, 0, i); // wrap-a-round - else if (k >= 0 && k < (int)gMenuListCount) - UI_PrintStringSmallNormal(MenuList[k].name, 0, 0, i); - i++; - } + if (!gIsInSubMenu) { + while (i < 2) + { // leading menu items - small text + const int k = menu_index + i - 2; + if (k < 0) + UI_PrintStringSmallNormal(MenuList[gMenuListCount + k].name, 0, 0, i); // wrap-a-round + else if (k >= 0 && k < (int)gMenuListCount) + UI_PrintStringSmallNormal(MenuList[k].name, 0, 0, i); + i++; + } - // current menu item - keep big n fat - if (menu_index >= 0 && menu_index < (int)gMenuListCount) - UI_PrintString(MenuList[menu_index].name, 0, 0, 2, 8); - i++; + // current menu item - keep big n fat + if (menu_index >= 0 && menu_index < (int)gMenuListCount) + UI_PrintString(MenuList[menu_index].name, 0, 0, 2, 8); + i++; - while (i < 4) - { // trailing menu item - small text - const int k = menu_index + i - 2; - if (k >= 0 && k < (int)gMenuListCount) - UI_PrintStringSmallNormal(MenuList[k].name, 0, 0, 1 + i); - else if (k >= (int)gMenuListCount) - UI_PrintStringSmallNormal(MenuList[gMenuListCount - k].name, 0, 0, 1 + i); // wrap-a-round - i++; - } + while (i < 4) + { // trailing menu item - small text + const int k = menu_index + i - 2; + if (k >= 0 && k < (int)gMenuListCount) + UI_PrintStringSmallNormal(MenuList[k].name, 0, 0, 1 + i); + else if (k >= (int)gMenuListCount) + UI_PrintStringSmallNormal(MenuList[gMenuListCount - k].name, 0, 0, 1 + i); // wrap-a-round + i++; + } - // draw the menu index number/count + // draw the menu index number/count #ifndef ENABLE_FEAT_F4HWN - sprintf(String, "%2u.%u", 1 + gMenuCursor, gMenuListCount); - UI_PrintStringSmallNormal(String, 2, 0, 6); + sprintf(String, "%2u.%u", 1 + gMenuCursor, gMenuListCount); + UI_PrintStringSmallNormal(String, 2, 0, 6); #endif - } - else if (menu_index >= 0 && menu_index < (int)gMenuListCount) - { // current menu item -// strcat(String, ":"); - UI_PrintString(MenuList[menu_index].name, 0, 0, 0, 8); -// UI_PrintStringSmallNormal(String, 0, 0, 0); - } + } + else if (menu_index >= 0 && menu_index < (int)gMenuListCount) + { // current menu item +// strcat(String, ":"); + UI_PrintString(MenuList[menu_index].name, 0, 0, 0, 8); +// UI_PrintStringSmallNormal(String, 0, 0, 0); + } #ifdef ENABLE_FEAT_F4HWN - sprintf(String, "%02u/%u", 1 + gMenuCursor, gMenuListCount); - UI_PrintStringSmallNormal(String, 6, 0, 6); + sprintf(String, "%02u/%u", 1 + gMenuCursor, gMenuListCount); + UI_PrintStringSmallNormal(String, 6, 0, 6); #endif - } + } #endif - // ************** + // ************** - memset(String, 0, sizeof(String)); + memset(String, 0, sizeof(String)); - bool already_printed = false; + bool already_printed = false; - /* Brightness is set to max in some entries of this menu. Return it to the configured brightness - level the "next" time we enter here.I.e., when we move from one menu to another. - It also has to be set back to max when pressing the Exit key. */ + /* Brightness is set to max in some entries of this menu. Return it to the configured brightness + level the "next" time we enter here.I.e., when we move from one menu to another. + It also has to be set back to max when pressing the Exit key. */ - BACKLIGHT_TurnOn(); + BACKLIGHT_TurnOn(); - switch (UI_MENU_GetCurrentMenuId()) - { - case MENU_SQL: - sprintf(String, "%d", gSubMenuSelection); - break; + switch (UI_MENU_GetCurrentMenuId()) + { + case MENU_SQL: + sprintf(String, "%d", gSubMenuSelection); + break; - case MENU_MIC: - { // display the mic gain in actual dB rather than just an index number - const uint8_t mic = gMicGain_dB2[gSubMenuSelection]; - sprintf(String, "+%u.%01udB", mic / 2, mic % 2); - } - break; + case MENU_MIC: + { // display the mic gain in actual dB rather than just an index number + const uint8_t mic = gMicGain_dB2[gSubMenuSelection]; + sprintf(String, "+%u.%01udB", mic / 2, mic % 2); + } + break; - #ifdef ENABLE_AUDIO_BAR - case MENU_MIC_BAR: - strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]); - break; - #endif + #ifdef ENABLE_AUDIO_BAR + case MENU_MIC_BAR: + strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]); + break; + #endif - case MENU_STEP: { - uint16_t step = gStepFrequencyTable[FREQUENCY_GetStepIdxFromSortedIdx(gSubMenuSelection)]; - sprintf(String, "%d.%02ukHz", step / 100, step % 100); - break; - } + case MENU_STEP: { + uint16_t step = gStepFrequencyTable[FREQUENCY_GetStepIdxFromSortedIdx(gSubMenuSelection)]; + sprintf(String, "%d.%02ukHz", step / 100, step % 100); + break; + } - case MENU_TXP: - if(gSubMenuSelection == 0) - { - strcpy(String, gSubMenu_TXP[gSubMenuSelection]); - } - else - { - sprintf(String, "%s\n%sW", gSubMenu_TXP[gSubMenuSelection], gSubMenu_SET_PWR[gSubMenuSelection - 1]); - } - break; + case MENU_TXP: + if(gSubMenuSelection == 0) + { + strcpy(String, gSubMenu_TXP[gSubMenuSelection]); + } + else + { + sprintf(String, "%s\n%sW", gSubMenu_TXP[gSubMenuSelection], gSubMenu_SET_PWR[gSubMenuSelection - 1]); + } + break; - case MENU_R_DCS: - case MENU_T_DCS: - if (gSubMenuSelection == 0) - strcpy(String, "OFF"); - else if (gSubMenuSelection < 105) - sprintf(String, "D%03oN", DCS_Options[gSubMenuSelection - 1]); - else - sprintf(String, "D%03oI", DCS_Options[gSubMenuSelection - 105]); - break; + case MENU_R_DCS: + case MENU_T_DCS: + if (gSubMenuSelection == 0) + strcpy(String, "OFF"); + else if (gSubMenuSelection < 105) + sprintf(String, "D%03oN", DCS_Options[gSubMenuSelection - 1]); + else + sprintf(String, "D%03oI", DCS_Options[gSubMenuSelection - 105]); + break; - case MENU_R_CTCS: - case MENU_T_CTCS: - { - if (gSubMenuSelection == 0) - strcpy(String, "OFF"); - else - sprintf(String, "%u.%uHz", CTCSS_Options[gSubMenuSelection - 1] / 10, CTCSS_Options[gSubMenuSelection - 1] % 10); - break; - } + case MENU_R_CTCS: + case MENU_T_CTCS: + { + if (gSubMenuSelection == 0) + strcpy(String, "OFF"); + else + sprintf(String, "%u.%uHz", CTCSS_Options[gSubMenuSelection - 1] / 10, CTCSS_Options[gSubMenuSelection - 1] % 10); + break; + } - case MENU_SFT_D: - strcpy(String, gSubMenu_SFT_D[gSubMenuSelection]); - break; + case MENU_SFT_D: + strcpy(String, gSubMenu_SFT_D[gSubMenuSelection]); + break; - case MENU_OFFSET: - if (!gIsInSubMenu || gInputBoxIndex == 0) - { - sprintf(String, "%3d.%05u", gSubMenuSelection / 100000, abs(gSubMenuSelection) % 100000); - UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8); - } - else - { - const char * ascii = INPUTBOX_GetAscii(); - sprintf(String, "%.3s.%.3s ",ascii, ascii + 3); - UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8); - } + case MENU_OFFSET: + if (!gIsInSubMenu || gInputBoxIndex == 0) + { + sprintf(String, "%3d.%05u", gSubMenuSelection / 100000, abs(gSubMenuSelection) % 100000); + UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8); + } + else + { + const char * ascii = INPUTBOX_GetAscii(); + sprintf(String, "%.3s.%.3s ",ascii, ascii + 3); + UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8); + } - UI_PrintString("MHz", menu_item_x1, menu_item_x2, 3, 8); + UI_PrintString("MHz", menu_item_x1, menu_item_x2, 3, 8); - already_printed = true; - break; + already_printed = true; + break; - case MENU_W_N: - strcpy(String, gSubMenu_W_N[gSubMenuSelection]); - break; + case MENU_W_N: + strcpy(String, gSubMenu_W_N[gSubMenuSelection]); + break; #ifndef ENABLE_FEAT_F4HWN - case MENU_SCR: - strcpy(String, gSubMenu_SCRAMBLER[gSubMenuSelection]); - #if 1 - if (gSubMenuSelection > 0 && gSetting_ScrambleEnable) - BK4819_EnableScramble(gSubMenuSelection - 1); - else - BK4819_DisableScramble(); - #endif - break; + case MENU_SCR: + strcpy(String, gSubMenu_SCRAMBLER[gSubMenuSelection]); + #if 1 + if (gSubMenuSelection > 0 && gSetting_ScrambleEnable) + BK4819_EnableScramble(gSubMenuSelection - 1); + else + BK4819_DisableScramble(); + #endif + break; #endif - #ifdef ENABLE_VOX - case MENU_VOX: - if (gSubMenuSelection == 0) - strcpy(String, "OFF"); - else - sprintf(String, "%d", gSubMenuSelection); - break; - #endif + #ifdef ENABLE_VOX + case MENU_VOX: + if (gSubMenuSelection == 0) + strcpy(String, "OFF"); + else + sprintf(String, "%d", gSubMenuSelection); + break; + #endif - case MENU_ABR: - if(gSubMenuSelection == 0) - { - sprintf(String, "%s", "OFF"); - } - else if(gSubMenuSelection < 61) - { - sprintf(String, "%02dm:%02ds", (((gSubMenuSelection) * 5) / 60), (((gSubMenuSelection) * 5) % 60)); - } - else - { - sprintf(String, "%s", "ON"); - } + case MENU_ABR: + if(gSubMenuSelection == 0) + { + sprintf(String, "%s", "OFF"); + } + else if(gSubMenuSelection < 61) + { + sprintf(String, "%02dm:%02ds", (((gSubMenuSelection) * 5) / 60), (((gSubMenuSelection) * 5) % 60)); + } + else + { + sprintf(String, "%s", "ON"); + } - if(BACKLIGHT_GetBrightness() < 4) - BACKLIGHT_SetBrightness(4); - break; + if(BACKLIGHT_GetBrightness() < 4) + BACKLIGHT_SetBrightness(4); + break; - case MENU_ABR_MIN: - case MENU_ABR_MAX: - sprintf(String, "%d", gSubMenuSelection); - if(gIsInSubMenu) - BACKLIGHT_SetBrightness(gSubMenuSelection); - else if(BACKLIGHT_GetBrightness() < 4) - BACKLIGHT_SetBrightness(4); - break; + case MENU_ABR_MIN: + case MENU_ABR_MAX: + sprintf(String, "%d", gSubMenuSelection); + if(gIsInSubMenu) + BACKLIGHT_SetBrightness(gSubMenuSelection); + else if(BACKLIGHT_GetBrightness() < 4) + BACKLIGHT_SetBrightness(4); + break; - case MENU_AM: - strcpy(String, gModulationStr[gSubMenuSelection]); - break; + case MENU_AM: + strcpy(String, gModulationStr[gSubMenuSelection]); + break; - case MENU_AUTOLK: - strcpy(String, (gSubMenuSelection == 0) ? "OFF" : "AUTO"); - break; + case MENU_AUTOLK: + strcpy(String, (gSubMenuSelection == 0) ? "OFF" : "AUTO"); + break; - case MENU_COMPAND: - case MENU_ABR_ON_TX_RX: - strcpy(String, gSubMenu_RX_TX[gSubMenuSelection]); - break; + case MENU_COMPAND: + case MENU_ABR_ON_TX_RX: + strcpy(String, gSubMenu_RX_TX[gSubMenuSelection]); + break; - #ifndef ENABLE_FEAT_F4HWN - #ifdef ENABLE_AM_FIX - case MENU_AM_FIX: - #endif - #endif - case MENU_BCL: - case MENU_BEEP: - case MENU_S_ADD1: - case MENU_S_ADD2: - case MENU_S_ADD3: - case MENU_STE: - case MENU_D_ST: + #ifndef ENABLE_FEAT_F4HWN + #ifdef ENABLE_AM_FIX + case MENU_AM_FIX: + #endif + #endif + case MENU_BCL: + case MENU_BEEP: + case MENU_S_ADD1: + case MENU_S_ADD2: + case MENU_S_ADD3: + case MENU_STE: + case MENU_D_ST: #ifdef ENABLE_DTMF_CALLING - case MENU_D_DCD: + case MENU_D_DCD: #endif - case MENU_D_LIVE_DEC: - #ifdef ENABLE_NOAA - case MENU_NOAA_S: - #endif - case MENU_350TX: - case MENU_200TX: - case MENU_500TX: - case MENU_350EN: + case MENU_D_LIVE_DEC: + #ifdef ENABLE_NOAA + case MENU_NOAA_S: + #endif + case MENU_350TX: + case MENU_200TX: + case MENU_500TX: + case MENU_350EN: #ifndef ENABLE_FEAT_F4HWN - case MENU_SCREN: + case MENU_SCREN: #endif #ifdef ENABLE_FEAT_F4HWN - case MENU_SET_TMR: + case MENU_SET_TMR: #endif - strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]); - break; + strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]); + break; - case MENU_MEM_CH: - case MENU_1_CALL: - case MENU_DEL_CH: - { - const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 0); + case MENU_MEM_CH: + case MENU_1_CALL: + case MENU_DEL_CH: + { + const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 0); - UI_GenerateChannelStringEx(String, valid, gSubMenuSelection); - UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8); + UI_GenerateChannelStringEx(String, valid, gSubMenuSelection); + UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8); - if (valid && !gAskForConfirmation) - { // show the frequency so that the user knows the channels frequency - const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection); - sprintf(String, "%u.%05u", frequency / 100000, frequency % 100000); - UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8); - } + if (valid && !gAskForConfirmation) + { // show the frequency so that the user knows the channels frequency + const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection); + sprintf(String, "%u.%05u", frequency / 100000, frequency % 100000); + UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8); + } - SETTINGS_FetchChannelName(String, gSubMenuSelection); - UI_PrintString(String[0] ? String : "--", menu_item_x1, menu_item_x2, 2, 8); - already_printed = true; - break; - } + SETTINGS_FetchChannelName(String, gSubMenuSelection); + UI_PrintString(String[0] ? String : "--", menu_item_x1, menu_item_x2, 2, 8); + already_printed = true; + break; + } - case MENU_MEM_NAME: - { - const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 0); + case MENU_MEM_NAME: + { + const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 0); - UI_GenerateChannelStringEx(String, valid, gSubMenuSelection); - UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8); + UI_GenerateChannelStringEx(String, valid, gSubMenuSelection); + UI_PrintString(String, menu_item_x1, menu_item_x2, 0, 8); - if (valid) - { - const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection); + if (valid) + { + const uint32_t frequency = SETTINGS_FetchChannelFrequency(gSubMenuSelection); - //if (!gIsInSubMenu || edit_index < 0) - if (!gIsInSubMenu) - edit_index = -1; - if (edit_index < 0) - { // show the channel name - SETTINGS_FetchChannelName(String, gSubMenuSelection); - char *pPrintStr = String[0] ? String : "--"; - UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 2, 8); - } - else - { // show the channel name being edited - //UI_PrintString(edit, menu_item_x1, 0, 2, 8); - UI_PrintString(edit, menu_item_x1, menu_item_x2, 2, 8); - if (edit_index < 10) - //UI_PrintString("^", menu_item_x1 + (8 * edit_index), 0, 4, 8); // show the cursor - UI_PrintString("^", menu_item_x1 - 1 + (8 * edit_index),0, 4, 8); // show the cursor - } + //if (!gIsInSubMenu || edit_index < 0) + if (!gIsInSubMenu) + edit_index = -1; + if (edit_index < 0) + { // show the channel name + SETTINGS_FetchChannelName(String, gSubMenuSelection); + char *pPrintStr = String[0] ? String : "--"; + UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 2, 8); + } + else + { // show the channel name being edited + //UI_PrintString(edit, menu_item_x1, 0, 2, 8); + UI_PrintString(edit, menu_item_x1, menu_item_x2, 2, 8); + if (edit_index < 10) + //UI_PrintString("^", menu_item_x1 + (8 * edit_index), 0, 4, 8); // show the cursor + UI_PrintString("^", menu_item_x1 - 1 + (8 * edit_index),0, 4, 8); // show the cursor + } - if (!gAskForConfirmation) - { // show the frequency so that the user knows the channels frequency - sprintf(String, "%u.%05u", frequency / 100000, frequency % 100000); - UI_PrintString(String, menu_item_x1, menu_item_x2, 4 + (gIsInSubMenu && edit_index >= 0), 8); - } - } + if (!gAskForConfirmation) + { // show the frequency so that the user knows the channels frequency + sprintf(String, "%u.%05u", frequency / 100000, frequency % 100000); + UI_PrintString(String, menu_item_x1, menu_item_x2, 4 + (gIsInSubMenu && edit_index >= 0), 8); + } + } - already_printed = true; - break; - } + already_printed = true; + break; + } - case MENU_SAVE: - strcpy(String, gSubMenu_SAVE[gSubMenuSelection]); - break; + case MENU_SAVE: + strcpy(String, gSubMenu_SAVE[gSubMenuSelection]); + break; - case MENU_TDR: - strcpy(String, gSubMenu_RXMode[gSubMenuSelection]); - break; + case MENU_TDR: + strcpy(String, gSubMenu_RXMode[gSubMenuSelection]); + break; - case MENU_TOT: - sprintf(String, "%02dm:%02ds", (((gSubMenuSelection + 1) * 5) / 60), (((gSubMenuSelection + 1) * 5) % 60)); - break; + case MENU_TOT: + sprintf(String, "%02dm:%02ds", (((gSubMenuSelection + 1) * 5) / 60), (((gSubMenuSelection + 1) * 5) % 60)); + break; - #ifdef ENABLE_VOICE - case MENU_VOICE: - strcpy(String, gSubMenu_VOICE[gSubMenuSelection]); - break; - #endif + #ifdef ENABLE_VOICE + case MENU_VOICE: + strcpy(String, gSubMenu_VOICE[gSubMenuSelection]); + break; + #endif - case MENU_SC_REV: - strcpy(String, gSubMenu_SC_REV[gSubMenuSelection]); - break; + case MENU_SC_REV: + strcpy(String, gSubMenu_SC_REV[gSubMenuSelection]); + break; - case MENU_MDF: - strcpy(String, gSubMenu_MDF[gSubMenuSelection]); - break; + case MENU_MDF: + strcpy(String, gSubMenu_MDF[gSubMenuSelection]); + break; - case MENU_RP_STE: - if (gSubMenuSelection == 0) - strcpy(String, "OFF"); - else - sprintf(String, "%d*100ms", gSubMenuSelection); - break; + case MENU_RP_STE: + if (gSubMenuSelection == 0) + strcpy(String, "OFF"); + else + sprintf(String, "%d*100ms", gSubMenuSelection); + break; - case MENU_S_LIST: - if (gSubMenuSelection == 0) - strcpy(String, "LIST [0]\nNO LIST"); - else if (gSubMenuSelection < 4) - sprintf(String, "LIST [%u]", gSubMenuSelection); - else if (gSubMenuSelection == 4) - strcpy(String, "LISTS\n[1, 2, 3]"); - else if (gSubMenuSelection == 5) - strcpy(String, "ALL"); - break; + case MENU_S_LIST: + if (gSubMenuSelection == 0) + strcpy(String, "LIST [0]\nNO LIST"); + else if (gSubMenuSelection < 4) + sprintf(String, "LIST [%u]", gSubMenuSelection); + else if (gSubMenuSelection == 4) + strcpy(String, "LISTS\n[1, 2, 3]"); + else if (gSubMenuSelection == 5) + strcpy(String, "ALL"); + break; - #ifdef ENABLE_ALARM - case MENU_AL_MOD: - sprintf(String, gSubMenu_AL_MOD[gSubMenuSelection]); - break; - #endif + #ifdef ENABLE_ALARM + case MENU_AL_MOD: + sprintf(String, gSubMenu_AL_MOD[gSubMenuSelection]); + break; + #endif #ifdef ENABLE_DTMF_CALLING - case MENU_ANI_ID: - strcpy(String, gEeprom.ANI_DTMF_ID); - break; + case MENU_ANI_ID: + strcpy(String, gEeprom.ANI_DTMF_ID); + break; #endif - case MENU_UPCODE: - sprintf(String, "%.8s\n%.8s", gEeprom.DTMF_UP_CODE, gEeprom.DTMF_UP_CODE + 8); - break; + case MENU_UPCODE: + sprintf(String, "%.8s\n%.8s", gEeprom.DTMF_UP_CODE, gEeprom.DTMF_UP_CODE + 8); + break; - case MENU_DWCODE: - sprintf(String, "%.8s\n%.8s", gEeprom.DTMF_DOWN_CODE, gEeprom.DTMF_DOWN_CODE + 8); - break; + case MENU_DWCODE: + sprintf(String, "%.8s\n%.8s", gEeprom.DTMF_DOWN_CODE, gEeprom.DTMF_DOWN_CODE + 8); + break; #ifdef ENABLE_DTMF_CALLING - case MENU_D_RSP: - strcpy(String, gSubMenu_D_RSP[gSubMenuSelection]); - break; + case MENU_D_RSP: + strcpy(String, gSubMenu_D_RSP[gSubMenuSelection]); + break; - case MENU_D_HOLD: - sprintf(String, "%ds", gSubMenuSelection); - break; + case MENU_D_HOLD: + sprintf(String, "%ds", gSubMenuSelection); + break; #endif - case MENU_D_PRE: - sprintf(String, "%d*10ms", gSubMenuSelection); - break; + case MENU_D_PRE: + sprintf(String, "%d*10ms", gSubMenuSelection); + break; - case MENU_PTT_ID: - strcpy(String, gSubMenu_PTT_ID[gSubMenuSelection]); - break; + case MENU_PTT_ID: + strcpy(String, gSubMenu_PTT_ID[gSubMenuSelection]); + break; - case MENU_BAT_TXT: - strcpy(String, gSubMenu_BAT_TXT[gSubMenuSelection]); - break; + case MENU_BAT_TXT: + strcpy(String, gSubMenu_BAT_TXT[gSubMenuSelection]); + break; #ifdef ENABLE_DTMF_CALLING - case MENU_D_LIST: - gIsDtmfContactValid = DTMF_GetContact((int)gSubMenuSelection - 1, Contact); - if (!gIsDtmfContactValid) - strcpy(String, "NULL"); - else - memcpy(String, Contact, 8); - break; + case MENU_D_LIST: + gIsDtmfContactValid = DTMF_GetContact((int)gSubMenuSelection - 1, Contact); + if (!gIsDtmfContactValid) + strcpy(String, "NULL"); + else + memcpy(String, Contact, 8); + break; #endif - case MENU_PONMSG: - strcpy(String, gSubMenu_PONMSG[gSubMenuSelection]); - break; + case MENU_PONMSG: + strcpy(String, gSubMenu_PONMSG[gSubMenuSelection]); + break; - case MENU_ROGER: - strcpy(String, gSubMenu_ROGER[gSubMenuSelection]); - break; + case MENU_ROGER: + strcpy(String, gSubMenu_ROGER[gSubMenuSelection]); + break; - case MENU_VOL: + case MENU_VOL: #ifdef ENABLE_FEAT_F4HWN - sprintf(String, "%s\n%s", - AUTHOR_STRING_2, - VERSION_STRING_2 - ); + sprintf(String, "%s\n%s", + AUTHOR_STRING_2, + VERSION_STRING_2 + ); #else - sprintf(String, "%u.%02uV\n%u%%", - gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100, - BATTERY_VoltsToPercent(gBatteryVoltageAverage)); + sprintf(String, "%u.%02uV\n%u%%", + gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100, + BATTERY_VoltsToPercent(gBatteryVoltageAverage)); #endif - break; + break; - case MENU_RESET: - strcpy(String, gSubMenu_RESET[gSubMenuSelection]); - break; + case MENU_RESET: + strcpy(String, gSubMenu_RESET[gSubMenuSelection]); + break; - case MENU_F_LOCK: + case MENU_F_LOCK: #ifdef ENABLE_FEAT_F4HWN - if(!gIsInSubMenu && gUnlockAllTxConfCnt>0 && gUnlockAllTxConfCnt<3) + if(!gIsInSubMenu && gUnlockAllTxConfCnt>0 && gUnlockAllTxConfCnt<3) #else - if(!gIsInSubMenu && gUnlockAllTxConfCnt>0 && gUnlockAllTxConfCnt<10) + if(!gIsInSubMenu && gUnlockAllTxConfCnt>0 && gUnlockAllTxConfCnt<10) #endif - strcpy(String, "READ\nMANUAL"); - else - strcpy(String, gSubMenu_F_LOCK[gSubMenuSelection]); - break; + strcpy(String, "READ\nMANUAL"); + else + strcpy(String, gSubMenu_F_LOCK[gSubMenuSelection]); + break; - #ifdef ENABLE_F_CAL_MENU - case MENU_F_CALI: - { - const uint32_t value = 22656 + gSubMenuSelection; - const uint32_t xtal_Hz = (0x4f0000u + value) * 5; + #ifdef ENABLE_F_CAL_MENU + case MENU_F_CALI: + { + const uint32_t value = 22656 + gSubMenuSelection; + const uint32_t xtal_Hz = (0x4f0000u + value) * 5; - writeXtalFreqCal(gSubMenuSelection, false); + writeXtalFreqCal(gSubMenuSelection, false); - sprintf(String, "%d\n%u.%06u\nMHz", - gSubMenuSelection, - xtal_Hz / 1000000, xtal_Hz % 1000000); - } - break; - #endif + sprintf(String, "%d\n%u.%06u\nMHz", + gSubMenuSelection, + xtal_Hz / 1000000, xtal_Hz % 1000000); + } + break; + #endif - case MENU_BATCAL: - { - const uint16_t vol = (uint32_t)gBatteryVoltageAverage * gBatteryCalibration[3] / gSubMenuSelection; - sprintf(String, "%u.%02uV\n%u", vol / 100, vol % 100, gSubMenuSelection); - break; - } + case MENU_BATCAL: + { + const uint16_t vol = (uint32_t)gBatteryVoltageAverage * gBatteryCalibration[3] / gSubMenuSelection; + sprintf(String, "%u.%02uV\n%u", vol / 100, vol % 100, gSubMenuSelection); + break; + } - case MENU_BATTYP: - strcpy(String, gSubMenu_BATTYP[gSubMenuSelection]); - break; + case MENU_BATTYP: + strcpy(String, gSubMenu_BATTYP[gSubMenuSelection]); + break; - case MENU_F1SHRT: - case MENU_F1LONG: - case MENU_F2SHRT: - case MENU_F2LONG: - case MENU_MLONG: - strcpy(String, gSubMenu_SIDEFUNCTIONS[gSubMenuSelection].name); - break; + case MENU_F1SHRT: + case MENU_F1LONG: + case MENU_F2SHRT: + case MENU_F2LONG: + case MENU_MLONG: + strcpy(String, gSubMenu_SIDEFUNCTIONS[gSubMenuSelection].name); + break; #ifdef ENABLE_FEAT_F4HWN - case MENU_SET_PWR: - sprintf(String, "%s\n%sW", gSubMenu_TXP[gSubMenuSelection + 1], gSubMenu_SET_PWR[gSubMenuSelection]); - break; - - case MENU_SET_PTT: - strcpy(String, gSubMenu_SET_PTT[gSubMenuSelection]); - break; + case MENU_SET_PWR: + sprintf(String, "%s\n%sW", gSubMenu_TXP[gSubMenuSelection + 1], gSubMenu_SET_PWR[gSubMenuSelection]); + break; + + case MENU_SET_PTT: + strcpy(String, gSubMenu_SET_PTT[gSubMenuSelection]); + break; - case MENU_SET_TOT: - case MENU_SET_EOT: - strcpy(String, gSubMenu_SET_TOT[gSubMenuSelection]); // Same as SET_TOT - break; + case MENU_SET_TOT: + case MENU_SET_EOT: + strcpy(String, gSubMenu_SET_TOT[gSubMenuSelection]); // Same as SET_TOT + break; - case MENU_SET_CTR: - sprintf(String, "%d", gSubMenuSelection); - gSetting_set_ctr = gSubMenuSelection; - ST7565_ContrastAndInv(); - break; + case MENU_SET_CTR: + sprintf(String, "%d", gSubMenuSelection); + gSetting_set_ctr = gSubMenuSelection; + ST7565_ContrastAndInv(); + break; - case MENU_SET_INV: - strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]); - ST7565_ContrastAndInv(); - break; + case MENU_SET_INV: + strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]); + ST7565_ContrastAndInv(); + break; - case MENU_TX_LOCK: - if(TX_freq_check(gEeprom.VfoInfo[gEeprom.TX_VFO].pRX->Frequency) == 0) - { - strcpy(String, "Inside\nF Lock\nPlan"); - } - else - { - strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]); - } - break; + case MENU_TX_LOCK: + if(TX_freq_check(gEeprom.VfoInfo[gEeprom.TX_VFO].pRX->Frequency) == 0) + { + strcpy(String, "Inside\nF Lock\nPlan"); + } + else + { + strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]); + } + break; - case MENU_SET_LCK: - strcpy(String, gSubMenu_SET_LCK[gSubMenuSelection]); - break; + case MENU_SET_LCK: + strcpy(String, gSubMenu_SET_LCK[gSubMenuSelection]); + break; - case MENU_SET_MET: - case MENU_SET_GUI: - strcpy(String, gSubMenu_SET_MET[gSubMenuSelection]); // Same as SET_MET - break; + case MENU_SET_MET: + case MENU_SET_GUI: + strcpy(String, gSubMenu_SET_MET[gSubMenuSelection]); // Same as SET_MET + break; #endif - } + } - if (!already_printed) - { // we now do multi-line text in a single string + if (!already_printed) + { // we now do multi-line text in a single string - unsigned int y; - unsigned int lines = 1; - unsigned int len = strlen(String); - bool small = false; + unsigned int y; + unsigned int lines = 1; + unsigned int len = strlen(String); + bool small = false; - if (len > 0) - { - // count number of lines - for (i = 0; i < len; i++) - { - if (String[i] == '\n' && i < (len - 1)) - { // found new line char - lines++; - String[i] = 0; // null terminate the line - } - } + if (len > 0) + { + // count number of lines + for (i = 0; i < len; i++) + { + if (String[i] == '\n' && i < (len - 1)) + { // found new line char + lines++; + String[i] = 0; // null terminate the line + } + } - if (lines > 3) - { // use small text - small = true; - if (lines > 7) - lines = 7; - } + if (lines > 3) + { // use small text + small = true; + if (lines > 7) + lines = 7; + } - // center vertically'ish - if (small) - y = 3 - ((lines + 0) / 2); // untested - else - y = 2 - ((lines + 0) / 2); + // center vertically'ish + if (small) + y = 3 - ((lines + 0) / 2); // untested + else + y = 2 - ((lines + 0) / 2); - // only for SysInf - if(UI_MENU_GetCurrentMenuId() == MENU_VOL) - { - sprintf(edit, "%u.%02uV %u%%", - gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100, - BATTERY_VoltsToPercent(gBatteryVoltageAverage) - ); + // only for SysInf + if(UI_MENU_GetCurrentMenuId() == MENU_VOL) + { + sprintf(edit, "%u.%02uV %u%%", + gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100, + BATTERY_VoltsToPercent(gBatteryVoltageAverage) + ); - UI_PrintStringSmallNormal(edit, 54, 127, 1); + UI_PrintStringSmallNormal(edit, 54, 127, 1); - #ifdef ENABLE_SPECTRUM - #ifndef ENABLE_FMRADIO - UI_PrintStringSmallNormal("Bandscope", 54, 127, 6); - #endif - #else - UI_PrintStringSmallNormal("Broadcast", 54, 127, 6); - #endif + #ifdef ENABLE_SPECTRUM + #ifndef ENABLE_FMRADIO + UI_PrintStringSmallNormal("Bandscope", 54, 127, 6); + #endif + #else + UI_PrintStringSmallNormal("Broadcast", 54, 127, 6); + #endif - y = 2; - } + y = 2; + } - // draw the text lines - for (i = 0; i < len && lines > 0; lines--) - { - if (small) - UI_PrintStringSmallNormal(String + i, menu_item_x1, menu_item_x2, y); - else - UI_PrintString(String + i, menu_item_x1, menu_item_x2, y, 8); + // draw the text lines + for (i = 0; i < len && lines > 0; lines--) + { + if (small) + UI_PrintStringSmallNormal(String + i, menu_item_x1, menu_item_x2, y); + else + UI_PrintString(String + i, menu_item_x1, menu_item_x2, y, 8); - // look for start of next line - while (i < len && String[i] >= 32) - i++; + // look for start of next line + while (i < len && String[i] >= 32) + i++; - // hop over the null term char(s) - while (i < len && String[i] < 32) - i++; + // hop over the null term char(s) + while (i < len && String[i] < 32) + i++; - y += small ? 1 : 2; - } - } - } + y += small ? 1 : 2; + } + } + } - if (UI_MENU_GetCurrentMenuId() == MENU_SLIST1 || UI_MENU_GetCurrentMenuId() == MENU_SLIST2 || UI_MENU_GetCurrentMenuId() == MENU_SLIST3) - { - i = UI_MENU_GetCurrentMenuId() - MENU_SLIST1; + if (UI_MENU_GetCurrentMenuId() == MENU_SLIST1 || UI_MENU_GetCurrentMenuId() == MENU_SLIST2 || UI_MENU_GetCurrentMenuId() == MENU_SLIST3) + { + i = UI_MENU_GetCurrentMenuId() - MENU_SLIST1; - char *pPrintStr = String; + char *pPrintStr = String; - if (gSubMenuSelection < 0) { - pPrintStr = "NULL"; - } else { - UI_GenerateChannelStringEx(String, true, gSubMenuSelection); - pPrintStr = String; - } + if (gSubMenuSelection < 0) { + pPrintStr = "NULL"; + } else { + UI_GenerateChannelStringEx(String, true, gSubMenuSelection); + pPrintStr = String; + } - // channel number - UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 0, 8); + // channel number + UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 0, 8); - SETTINGS_FetchChannelName(String, gSubMenuSelection); - pPrintStr = String[0] ? String : "--"; + SETTINGS_FetchChannelName(String, gSubMenuSelection); + pPrintStr = String[0] ? String : "--"; - // channel name and scan-list - if (gSubMenuSelection < 0 || !gEeprom.SCAN_LIST_ENABLED[i]) { - UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 2, 8); - } else { - UI_PrintStringSmallNormal(pPrintStr, menu_item_x1, menu_item_x2, 2); + // channel name and scan-list + if (gSubMenuSelection < 0 || !gEeprom.SCAN_LIST_ENABLED[i]) { + UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 2, 8); + } else { + UI_PrintStringSmallNormal(pPrintStr, menu_item_x1, menu_item_x2, 2); - if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH1[i])) { - sprintf(String, "PRI%d:%u", 1, gEeprom.SCANLIST_PRIORITY_CH1[i] + 1); - UI_PrintString(String, menu_item_x1, menu_item_x2, 3, 8); - } + if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH1[i])) { + sprintf(String, "PRI%d:%u", 1, gEeprom.SCANLIST_PRIORITY_CH1[i] + 1); + UI_PrintString(String, menu_item_x1, menu_item_x2, 3, 8); + } - if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH2[i])) { - sprintf(String, "PRI%d:%u", 2, gEeprom.SCANLIST_PRIORITY_CH2[i] + 1); - UI_PrintString(String, menu_item_x1, menu_item_x2, 5, 8); - } - } - } + if (IS_MR_CHANNEL(gEeprom.SCANLIST_PRIORITY_CH2[i])) { + sprintf(String, "PRI%d:%u", 2, gEeprom.SCANLIST_PRIORITY_CH2[i] + 1); + UI_PrintString(String, menu_item_x1, menu_item_x2, 5, 8); + } + } + } - if ((UI_MENU_GetCurrentMenuId() == MENU_R_CTCS || UI_MENU_GetCurrentMenuId() == MENU_R_DCS) && gCssBackgroundScan) - UI_PrintString("SCAN", menu_item_x1, menu_item_x2, 4, 8); + if ((UI_MENU_GetCurrentMenuId() == MENU_R_CTCS || UI_MENU_GetCurrentMenuId() == MENU_R_DCS) && gCssBackgroundScan) + UI_PrintString("SCAN", menu_item_x1, menu_item_x2, 4, 8); #ifdef ENABLE_DTMF_CALLING - if (UI_MENU_GetCurrentMenuId() == MENU_D_LIST && gIsDtmfContactValid) { - Contact[11] = 0; - memcpy(&gDTMF_ID, Contact + 8, 4); - sprintf(String, "ID:%4s", gDTMF_ID); - UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8); - } + if (UI_MENU_GetCurrentMenuId() == MENU_D_LIST && gIsDtmfContactValid) { + Contact[11] = 0; + memcpy(&gDTMF_ID, Contact + 8, 4); + sprintf(String, "ID:%4s", gDTMF_ID); + UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8); + } #endif - if (UI_MENU_GetCurrentMenuId() == MENU_R_CTCS || - UI_MENU_GetCurrentMenuId() == MENU_T_CTCS || - UI_MENU_GetCurrentMenuId() == MENU_R_DCS || - UI_MENU_GetCurrentMenuId() == MENU_T_DCS + if (UI_MENU_GetCurrentMenuId() == MENU_R_CTCS || + UI_MENU_GetCurrentMenuId() == MENU_T_CTCS || + UI_MENU_GetCurrentMenuId() == MENU_R_DCS || + UI_MENU_GetCurrentMenuId() == MENU_T_DCS #ifdef ENABLE_DTMF_CALLING - || UI_MENU_GetCurrentMenuId() == MENU_D_LIST + || UI_MENU_GetCurrentMenuId() == MENU_D_LIST #endif - ) { - sprintf(String, "%2d", gSubMenuSelection); - UI_PrintStringSmallNormal(String, 105, 0, 0); - } + ) { + sprintf(String, "%2d", gSubMenuSelection); + UI_PrintStringSmallNormal(String, 105, 0, 0); + } - if ((UI_MENU_GetCurrentMenuId() == MENU_RESET || - UI_MENU_GetCurrentMenuId() == MENU_MEM_CH || - UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME || - UI_MENU_GetCurrentMenuId() == MENU_DEL_CH) && gAskForConfirmation) - { // display confirmation - char *pPrintStr = (gAskForConfirmation == 1) ? "SURE?" : "WAIT!"; - UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 5, 8); - } + if ((UI_MENU_GetCurrentMenuId() == MENU_RESET || + UI_MENU_GetCurrentMenuId() == MENU_MEM_CH || + UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME || + UI_MENU_GetCurrentMenuId() == MENU_DEL_CH) && gAskForConfirmation) + { // display confirmation + char *pPrintStr = (gAskForConfirmation == 1) ? "SURE?" : "WAIT!"; + UI_PrintString(pPrintStr, menu_item_x1, menu_item_x2, 5, 8); + } - ST7565_BlitFullScreen(); + ST7565_BlitFullScreen(); } \ No newline at end of file diff --git a/ui/menu.h b/ui/menu.h index 2025cd9..a16df43 100644 --- a/ui/menu.h +++ b/ui/menu.h @@ -24,126 +24,126 @@ #include "settings.h" typedef struct { - const char name[7]; // menu display area only has room for 6 characters - uint8_t menu_id; + const char name[7]; // menu display area only has room for 6 characters + uint8_t menu_id; } t_menu_item; enum { - MENU_SQL = 0, - MENU_STEP, - MENU_TXP, - MENU_R_DCS, - MENU_R_CTCS, - MENU_T_DCS, - MENU_T_CTCS, - MENU_SFT_D, - MENU_OFFSET, - MENU_TOT, - MENU_W_N, + MENU_SQL = 0, + MENU_STEP, + MENU_TXP, + MENU_R_DCS, + MENU_R_CTCS, + MENU_T_DCS, + MENU_T_CTCS, + MENU_SFT_D, + MENU_OFFSET, + MENU_TOT, + MENU_W_N, #ifndef ENABLE_FEAT_F4HWN - MENU_SCR, + MENU_SCR, #endif - MENU_BCL, + MENU_BCL, #ifdef ENABLE_FEAT_F4HWN - MENU_TX_LOCK, + MENU_TX_LOCK, #endif - MENU_MEM_CH, - MENU_DEL_CH, - MENU_MEM_NAME, - MENU_MDF, - MENU_SAVE, + MENU_MEM_CH, + MENU_DEL_CH, + MENU_MEM_NAME, + MENU_MDF, + MENU_SAVE, #ifdef ENABLE_VOX - MENU_VOX, + MENU_VOX, #endif - MENU_ABR, - MENU_ABR_ON_TX_RX, - MENU_ABR_MIN, - MENU_ABR_MAX, - MENU_TDR, - MENU_BEEP, + MENU_ABR, + MENU_ABR_ON_TX_RX, + MENU_ABR_MIN, + MENU_ABR_MAX, + MENU_TDR, + MENU_BEEP, #ifdef ENABLE_VOICE - MENU_VOICE, + MENU_VOICE, #endif - MENU_SC_REV, - MENU_AUTOLK, - MENU_S_ADD1, - MENU_S_ADD2, - MENU_S_ADD3, - MENU_STE, - MENU_RP_STE, - MENU_MIC, + MENU_SC_REV, + MENU_AUTOLK, + MENU_S_ADD1, + MENU_S_ADD2, + MENU_S_ADD3, + MENU_STE, + MENU_RP_STE, + MENU_MIC, #ifdef ENABLE_AUDIO_BAR - MENU_MIC_BAR, + MENU_MIC_BAR, #endif - MENU_COMPAND, - MENU_1_CALL, - MENU_S_LIST, - MENU_SLIST1, - MENU_SLIST2, - MENU_SLIST3, + MENU_COMPAND, + MENU_1_CALL, + MENU_S_LIST, + MENU_SLIST1, + MENU_SLIST2, + MENU_SLIST3, #ifdef ENABLE_ALARM - MENU_AL_MOD, + MENU_AL_MOD, #endif #ifdef ENABLE_DTMF_CALLING - MENU_ANI_ID, + MENU_ANI_ID, #endif - MENU_UPCODE, - MENU_DWCODE, - MENU_PTT_ID, - MENU_D_ST, + MENU_UPCODE, + MENU_DWCODE, + MENU_PTT_ID, + MENU_D_ST, #ifdef ENABLE_DTMF_CALLING - MENU_D_RSP, - MENU_D_HOLD, + MENU_D_RSP, + MENU_D_HOLD, #endif - MENU_D_PRE, -#ifdef ENABLE_DTMF_CALLING - MENU_D_DCD, - MENU_D_LIST, + MENU_D_PRE, +#ifdef ENABLE_DTMF_CALLING + MENU_D_DCD, + MENU_D_LIST, #endif - MENU_D_LIVE_DEC, - MENU_PONMSG, - MENU_ROGER, - MENU_VOL, - MENU_BAT_TXT, - MENU_AM, + MENU_D_LIVE_DEC, + MENU_PONMSG, + MENU_ROGER, + MENU_VOL, + MENU_BAT_TXT, + MENU_AM, #ifdef ENABLE_AM_FIX - MENU_AM_FIX, + MENU_AM_FIX, #endif #ifdef ENABLE_NOAA - MENU_NOAA_S, + MENU_NOAA_S, #endif - MENU_RESET, - MENU_F_LOCK, - MENU_200TX, - MENU_350TX, - MENU_500TX, - MENU_350EN, + MENU_RESET, + MENU_F_LOCK, + MENU_200TX, + MENU_350TX, + MENU_500TX, + MENU_350EN, #ifndef ENABLE_FEAT_F4HWN - MENU_SCREN, + MENU_SCREN, #endif #ifdef ENABLE_F_CAL_MENU - MENU_F_CALI, // reference xtal calibration + MENU_F_CALI, // reference xtal calibration #endif #ifdef ENABLE_FEAT_F4HWN - MENU_SET_PWR, - MENU_SET_PTT, - MENU_SET_TOT, - MENU_SET_EOT, - MENU_SET_CTR, - MENU_SET_INV, - MENU_SET_LCK, - MENU_SET_MET, - MENU_SET_GUI, - MENU_SET_TMR, + MENU_SET_PWR, + MENU_SET_PTT, + MENU_SET_TOT, + MENU_SET_EOT, + MENU_SET_CTR, + MENU_SET_INV, + MENU_SET_LCK, + MENU_SET_MET, + MENU_SET_GUI, + MENU_SET_TMR, #endif - MENU_BATCAL, // battery voltage calibration - MENU_F1SHRT, - MENU_F1LONG, - MENU_F2SHRT, - MENU_F2LONG, - MENU_MLONG, - MENU_BATTYP + MENU_BATCAL, // battery voltage calibration + MENU_F1SHRT, + MENU_F1LONG, + MENU_F2SHRT, + MENU_F2LONG, + MENU_MLONG, + MENU_BATTYP }; extern const uint8_t FIRST_HIDDEN_MENU_ITEM; @@ -158,52 +158,52 @@ extern const char gSubMenu_TOT[11][7]; extern const char* const gSubMenu_RXMode[4]; #ifdef ENABLE_VOICE - extern const char gSubMenu_VOICE[3][4]; + extern const char gSubMenu_VOICE[3][4]; #endif extern const char gSubMenu_SC_REV[3][8]; extern const char* const gSubMenu_MDF[4]; #ifdef ENABLE_ALARM - extern const char gSubMenu_AL_MOD[2][5]; + extern const char gSubMenu_AL_MOD[2][5]; #endif #ifdef ENABLE_DTMF_CALLING extern const char gSubMenu_D_RSP[4][11]; #endif #ifdef ENABLE_FEAT_F4HWN - extern const char gSubMenu_SET_PWR[7][6]; - extern const char gSubMenu_SET_PTT[2][8]; - extern const char gSubMenu_SET_TOT[4][7]; - extern const char gSubMenu_SET_LCK[2][9]; - extern const char gSubMenu_SET_MET[2][8]; + extern const char gSubMenu_SET_PWR[7][6]; + extern const char gSubMenu_SET_PTT[2][8]; + extern const char gSubMenu_SET_TOT[4][7]; + extern const char gSubMenu_SET_LCK[2][9]; + extern const char gSubMenu_SET_MET[2][8]; #endif extern const char* const gSubMenu_PTT_ID[5]; #ifdef ENABLE_FEAT_F4HWN - extern const char gSubMenu_PONMSG[5][8]; + extern const char gSubMenu_PONMSG[5][8]; #else - extern const char gSubMenu_PONMSG[4][8]; + extern const char gSubMenu_PONMSG[4][8]; #endif extern const char gSubMenu_ROGER[3][6]; extern const char gSubMenu_RESET[2][4]; extern const char* const gSubMenu_F_LOCK[F_LOCK_LEN]; extern const char gSubMenu_RX_TX[4][6]; extern const char gSubMenu_BAT_TXT[3][8]; -extern const char gSubMenu_BATTYP[3][9]; +extern const char gSubMenu_BATTYP[3][9]; #ifndef ENABLE_FEAT_F4HWN - extern const char gSubMenu_SCRAMBLER[11][7]; + extern const char gSubMenu_SCRAMBLER[11][7]; #endif typedef struct {char* name; uint8_t id;} t_sidefunction; -extern const uint8_t gSubMenu_SIDEFUNCTIONS_size; +extern const uint8_t gSubMenu_SIDEFUNCTIONS_size; extern const t_sidefunction gSubMenu_SIDEFUNCTIONS[]; - + extern bool gIsInSubMenu; - + extern uint8_t gMenuCursor; extern int32_t gSubMenuSelection; - + extern char edit_original[17]; extern char edit[17]; extern int edit_index; diff --git a/ui/scanner.c b/ui/scanner.c index 6fa7c74..436f820 100644 --- a/ui/scanner.c +++ b/ui/scanner.c @@ -26,58 +26,58 @@ void UI_DisplayScanner(void) { - char String[16] = {0}; - char *pPrintStr = String; - bool bCentered; - uint8_t Start; + char String[16] = {0}; + char *pPrintStr = String; + bool bCentered; + uint8_t Start; - UI_DisplayClear(); + UI_DisplayClear(); - if (gScanSingleFrequency || (gScanCssState != SCAN_CSS_STATE_OFF && gScanCssState != SCAN_CSS_STATE_FAILED)) { - sprintf(String, "FREQ:%u.%05u", gScanFrequency / 100000, gScanFrequency % 100000); - pPrintStr = String; - } else { - pPrintStr = "FREQ:**.*****"; - } + if (gScanSingleFrequency || (gScanCssState != SCAN_CSS_STATE_OFF && gScanCssState != SCAN_CSS_STATE_FAILED)) { + sprintf(String, "FREQ:%u.%05u", gScanFrequency / 100000, gScanFrequency % 100000); + pPrintStr = String; + } else { + pPrintStr = "FREQ:**.*****"; + } - UI_PrintString(pPrintStr, 2, 0, 1, 8); + UI_PrintString(pPrintStr, 2, 0, 1, 8); - if (gScanCssState < SCAN_CSS_STATE_FOUND || !gScanUseCssResult) { - pPrintStr = "CTC:******"; - } else if (gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) { - sprintf(String, "CTC:%u.%uHz", CTCSS_Options[gScanCssResultCode] / 10, CTCSS_Options[gScanCssResultCode] % 10); - pPrintStr = String; - } else { - sprintf(String, "DCS:D%03oN", DCS_Options[gScanCssResultCode]); - pPrintStr = String; - } + if (gScanCssState < SCAN_CSS_STATE_FOUND || !gScanUseCssResult) { + pPrintStr = "CTC:******"; + } else if (gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) { + sprintf(String, "CTC:%u.%uHz", CTCSS_Options[gScanCssResultCode] / 10, CTCSS_Options[gScanCssResultCode] % 10); + pPrintStr = String; + } else { + sprintf(String, "DCS:D%03oN", DCS_Options[gScanCssResultCode]); + pPrintStr = String; + } - UI_PrintString(pPrintStr, 2, 0, 3, 8); - memset(String, 0, sizeof(String)); - if (gScannerSaveState == SCAN_SAVE_CHANNEL) { - pPrintStr = "SAVE?"; - Start = 0; - bCentered = 1; - } else { - Start = 2; - bCentered = 0; + UI_PrintString(pPrintStr, 2, 0, 3, 8); + memset(String, 0, sizeof(String)); + if (gScannerSaveState == SCAN_SAVE_CHANNEL) { + pPrintStr = "SAVE?"; + Start = 0; + bCentered = 1; + } else { + Start = 2; + bCentered = 0; - if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) { - strcpy(String, "SAVE:"); - UI_GenerateChannelStringEx(String + 5, gShowChPrefix, gScanChannel); - pPrintStr = String; - } else if (gScanCssState < SCAN_CSS_STATE_FOUND) { - strcpy(String, "SCAN"); - memset(String + 4, '.', (gScanProgressIndicator & 7) + 1); - pPrintStr = String; - } else if (gScanCssState == SCAN_CSS_STATE_FOUND) { - pPrintStr = "SCAN CMP."; - } else { - pPrintStr = "SCAN FAIL."; - } - } + if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) { + strcpy(String, "SAVE:"); + UI_GenerateChannelStringEx(String + 5, gShowChPrefix, gScanChannel); + pPrintStr = String; + } else if (gScanCssState < SCAN_CSS_STATE_FOUND) { + strcpy(String, "SCAN"); + memset(String + 4, '.', (gScanProgressIndicator & 7) + 1); + pPrintStr = String; + } else if (gScanCssState == SCAN_CSS_STATE_FOUND) { + pPrintStr = "SCAN CMP."; + } else { + pPrintStr = "SCAN FAIL."; + } + } - UI_PrintString(pPrintStr, Start, bCentered ? 127 : 0, 5, 8); + UI_PrintString(pPrintStr, Start, bCentered ? 127 : 0, 5, 8); - ST7565_BlitFullScreen(); + ST7565_BlitFullScreen(); } diff --git a/ui/status.c b/ui/status.c index 32d4e48..f3b1272 100644 --- a/ui/status.c +++ b/ui/status.c @@ -18,7 +18,7 @@ #include "app/chFrScanner.h" #ifdef ENABLE_FMRADIO - #include "app/fm.h" + #include "app/fm.h" #endif #include "app/scanner.h" #include "bitmaps.h" @@ -54,205 +54,205 @@ static void convertTime(uint8_t *line, uint8_t type) void UI_DisplayStatus() { - char str[8] = ""; + char str[8] = ""; - gUpdateStatus = false; - memset(gStatusLine, 0, sizeof(gStatusLine)); + gUpdateStatus = false; + memset(gStatusLine, 0, sizeof(gStatusLine)); - uint8_t *line = gStatusLine; - unsigned int x = 0; - // ************** + uint8_t *line = gStatusLine; + unsigned int x = 0; + // ************** - // POWER-SAVE indicator - if (gCurrentFunction == FUNCTION_POWER_SAVE) { - memcpy(line + x, gFontPowerSave, sizeof(gFontPowerSave)); - } - x += 8; - unsigned int x1 = x; + // POWER-SAVE indicator + if (gCurrentFunction == FUNCTION_POWER_SAVE) { + memcpy(line + x, gFontPowerSave, sizeof(gFontPowerSave)); + } + x += 8; + unsigned int x1 = x; #ifdef ENABLE_NOAA - if (gIsNoaaMode) { // NOASS SCAN indicator - memcpy(line + x, BITMAP_NOAA, sizeof(BITMAP_NOAA)); - x1 = x + sizeof(BITMAP_NOAA); - } - x += sizeof(BITMAP_NOAA); + if (gIsNoaaMode) { // NOASS SCAN indicator + memcpy(line + x, BITMAP_NOAA, sizeof(BITMAP_NOAA)); + x1 = x + sizeof(BITMAP_NOAA); + } + x += sizeof(BITMAP_NOAA); #endif #ifdef ENABLE_DTMF_CALLING - if (gSetting_KILLED) { - memset(line + x, 0xFF, 10); - x1 = x + 10; - } - else + if (gSetting_KILLED) { + memset(line + x, 0xFF, 10); + x1 = x + 10; + } + else #endif - { // SCAN indicator - if (gScanStateDir != SCAN_OFF || SCANNER_IsScanning()) { - if (IS_MR_CHANNEL(gNextMrChannel) && !SCANNER_IsScanning()) { // channel mode - switch(gEeprom.SCAN_LIST_DEFAULT) { - case 0: - memcpy(line + 0, BITMAP_ScanList0, sizeof(BITMAP_ScanList0)); - break; - case 1: - memcpy(line + 0, BITMAP_ScanList1, sizeof(BITMAP_ScanList1)); - break; - case 2: - memcpy(line + 0, BITMAP_ScanList2, sizeof(BITMAP_ScanList2)); - break; - case 3: - memcpy(line + 0, BITMAP_ScanList3, sizeof(BITMAP_ScanList3)); - break; - case 4: - memcpy(line + 0, BITMAP_ScanList123, sizeof(BITMAP_ScanList123)); - break; - case 5: - memcpy(line + 0, BITMAP_ScanListAll, sizeof(BITMAP_ScanListAll)); - break; - } - } - else { // frequency mode - memcpy(line + x + 1, gFontS, sizeof(gFontS)); - //UI_PrintStringSmallBufferNormal("S", line + x + 1); - } - x1 = x + 10; - } - } - x += 10; // font character width + { // SCAN indicator + if (gScanStateDir != SCAN_OFF || SCANNER_IsScanning()) { + if (IS_MR_CHANNEL(gNextMrChannel) && !SCANNER_IsScanning()) { // channel mode + switch(gEeprom.SCAN_LIST_DEFAULT) { + case 0: + memcpy(line + 0, BITMAP_ScanList0, sizeof(BITMAP_ScanList0)); + break; + case 1: + memcpy(line + 0, BITMAP_ScanList1, sizeof(BITMAP_ScanList1)); + break; + case 2: + memcpy(line + 0, BITMAP_ScanList2, sizeof(BITMAP_ScanList2)); + break; + case 3: + memcpy(line + 0, BITMAP_ScanList3, sizeof(BITMAP_ScanList3)); + break; + case 4: + memcpy(line + 0, BITMAP_ScanList123, sizeof(BITMAP_ScanList123)); + break; + case 5: + memcpy(line + 0, BITMAP_ScanListAll, sizeof(BITMAP_ScanListAll)); + break; + } + } + else { // frequency mode + memcpy(line + x + 1, gFontS, sizeof(gFontS)); + //UI_PrintStringSmallBufferNormal("S", line + x + 1); + } + x1 = x + 10; + } + } + x += 10; // font character width - // Only for debug - // Only for debug - // Only for debug - - bool debug = false; - if(debug) - { - sprintf(str, "%d", gDebug); - UI_PrintStringSmallBufferNormal(str, line + x + 1); - x += 16; - } - else - { + // Only for debug + // Only for debug + // Only for debug + + bool debug = false; + if(debug) + { + sprintf(str, "%d", gDebug); + UI_PrintStringSmallBufferNormal(str, line + x + 1); + x += 16; + } + else + { - #ifdef ENABLE_VOICE - // VOICE indicator - if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF){ - memcpy(line + x, BITMAP_VoicePrompt, sizeof(BITMAP_VoicePrompt)); - x1 = x + sizeof(BITMAP_VoicePrompt); - } - x += sizeof(BITMAP_VoicePrompt); - #endif + #ifdef ENABLE_VOICE + // VOICE indicator + if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF){ + memcpy(line + x, BITMAP_VoicePrompt, sizeof(BITMAP_VoicePrompt)); + x1 = x + sizeof(BITMAP_VoicePrompt); + } + x += sizeof(BITMAP_VoicePrompt); + #endif - if(!SCANNER_IsScanning()) { - #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER - if(gCurrentFunction == FUNCTION_TRANSMIT && gSetting_set_tmr == true) - { - convertTime(line, 0); - } - else if(FUNCTION_IsRx() && gSetting_set_tmr == true) - { - convertTime(line, 1); - } - else - #endif - { - uint8_t dw = (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2; - if(dw == 1 || dw == 3) { // DWR - dual watch + respond - if(gDualWatchActive) - memcpy(line + x + (dw==1?0:2), gFontDWR, sizeof(gFontDWR) - (dw==1?0:5)); - else - memcpy(line + x + 3, gFontHold, sizeof(gFontHold)); - } - else if(dw == 2) { // XB - crossband - memcpy(line + x + 2, gFontXB, sizeof(gFontXB)); - } - else - { - memcpy(line + x + 2, gFontMO, sizeof(gFontMO)); - } - } - } - x += sizeof(gFontDWR) + 3; - } + if(!SCANNER_IsScanning()) { + #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER + if(gCurrentFunction == FUNCTION_TRANSMIT && gSetting_set_tmr == true) + { + convertTime(line, 0); + } + else if(FUNCTION_IsRx() && gSetting_set_tmr == true) + { + convertTime(line, 1); + } + else + #endif + { + uint8_t dw = (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2; + if(dw == 1 || dw == 3) { // DWR - dual watch + respond + if(gDualWatchActive) + memcpy(line + x + (dw==1?0:2), gFontDWR, sizeof(gFontDWR) - (dw==1?0:5)); + else + memcpy(line + x + 3, gFontHold, sizeof(gFontHold)); + } + else if(dw == 2) { // XB - crossband + memcpy(line + x + 2, gFontXB, sizeof(gFontXB)); + } + else + { + memcpy(line + x + 2, gFontMO, sizeof(gFontMO)); + } + } + } + x += sizeof(gFontDWR) + 3; + } #ifdef ENABLE_VOX - // VOX indicator - if (gEeprom.VOX_SWITCH) { - memcpy(line + x, gFontVox, sizeof(gFontVox)); - x1 = x + sizeof(gFontVox) + 1; - } - x += sizeof(gFontVox) + 3; + // VOX indicator + if (gEeprom.VOX_SWITCH) { + memcpy(line + x, gFontVox, sizeof(gFontVox)); + x1 = x + sizeof(gFontVox) + 1; + } + x += sizeof(gFontVox) + 3; #endif #ifdef ENABLE_FEAT_F4HWN - // PTT indicator - if (gSetting_set_ptt_session) { - memcpy(line + x, gFontPttOnePush, sizeof(gFontPttOnePush)); - x1 = x + sizeof(gFontPttOnePush) + 1; - } - else - { - memcpy(line + x, gFontPttClassic, sizeof(gFontPttClassic)); - x1 = x + sizeof(gFontPttClassic) + 1; - } - x += sizeof(gFontPttClassic) + 3; + // PTT indicator + if (gSetting_set_ptt_session) { + memcpy(line + x, gFontPttOnePush, sizeof(gFontPttOnePush)); + x1 = x + sizeof(gFontPttOnePush) + 1; + } + else + { + memcpy(line + x, gFontPttClassic, sizeof(gFontPttClassic)); + x1 = x + sizeof(gFontPttClassic) + 1; + } + x += sizeof(gFontPttClassic) + 3; #endif - x = MAX(x1, 70u); + x = MAX(x1, 70u); - // KEY-LOCK indicator - if (gEeprom.KEY_LOCK) { - memcpy(line + x + 1, gFontKeyLock, sizeof(gFontKeyLock)); - } - else if (gWasFKeyPressed) { - memcpy(line + x + 1, gFontF, sizeof(gFontF)); - /* - UI_PrintStringSmallBufferNormal("F", line + x + 1); - - for (uint8_t i = 71; i < 79; i++) - { - gStatusLine[i] ^= 0x7F; - } - */ - } - else if (gBackLight) - { - memcpy(line + x + 1, gFontLight, sizeof(gFontLight)); - } - #ifdef ENABLE_FEAT_F4HWN_CHARGING_C - else if (gChargingWithTypeC) - { - memcpy(line + x + 1, BITMAP_USB_C, sizeof(BITMAP_USB_C)); - } - #endif - - // Battery - unsigned int x2 = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - 0; + // KEY-LOCK indicator + if (gEeprom.KEY_LOCK) { + memcpy(line + x + 1, gFontKeyLock, sizeof(gFontKeyLock)); + } + else if (gWasFKeyPressed) { + memcpy(line + x + 1, gFontF, sizeof(gFontF)); + /* + UI_PrintStringSmallBufferNormal("F", line + x + 1); + + for (uint8_t i = 71; i < 79; i++) + { + gStatusLine[i] ^= 0x7F; + } + */ + } + else if (gBackLight) + { + memcpy(line + x + 1, gFontLight, sizeof(gFontLight)); + } + #ifdef ENABLE_FEAT_F4HWN_CHARGING_C + else if (gChargingWithTypeC) + { + memcpy(line + x + 1, BITMAP_USB_C, sizeof(BITMAP_USB_C)); + } + #endif + + // Battery + unsigned int x2 = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - 0; - UI_DrawBattery(line + x2, gBatteryDisplayLevel, gLowBatteryBlink); + UI_DrawBattery(line + x2, gBatteryDisplayLevel, gLowBatteryBlink); - switch (gSetting_battery_text) { - default: - case 0: - break; + switch (gSetting_battery_text) { + default: + case 0: + break; - case 1: { // voltage - const uint16_t voltage = (gBatteryVoltageAverage <= 999) ? gBatteryVoltageAverage : 999; // limit to 9.99V + case 1: { // voltage + const uint16_t voltage = (gBatteryVoltageAverage <= 999) ? gBatteryVoltageAverage : 999; // limit to 9.99V #ifdef ENABLE_FEAT_F4HWN - sprintf(str, "%u.%02u", voltage / 100, voltage % 100); + sprintf(str, "%u.%02u", voltage / 100, voltage % 100); #else - sprintf(str, "%u.%02uV", voltage / 100, voltage % 100); + sprintf(str, "%u.%02uV", voltage / 100, voltage % 100); #endif - break; - } + break; + } - case 2: // percentage - sprintf(str, "%u%%", BATTERY_VoltsToPercent(gBatteryVoltageAverage)); - break; - } + case 2: // percentage + sprintf(str, "%u%%", BATTERY_VoltsToPercent(gBatteryVoltageAverage)); + break; + } - x2 -= (7 * strlen(str)); - UI_PrintStringSmallBufferNormal(str, line + x2); + x2 -= (7 * strlen(str)); + UI_PrintStringSmallBufferNormal(str, line + x2); - // ************** + // ************** - ST7565_BlitStatusLine(); + ST7565_BlitStatusLine(); } diff --git a/ui/ui.c b/ui/ui.c index 50963aa..a64adc7 100644 --- a/ui/ui.c +++ b/ui/ui.c @@ -20,15 +20,15 @@ #include "app/chFrScanner.h" #include "app/dtmf.h" #ifdef ENABLE_FMRADIO - #include "app/fm.h" + #include "app/fm.h" #endif #include "driver/keyboard.h" #include "misc.h" #ifdef ENABLE_AIRCOPY - #include "ui/aircopy.h" + #include "ui/aircopy.h" #endif #ifdef ENABLE_FMRADIO - #include "ui/fmradio.h" + #include "ui/fmradio.h" #endif #include "ui/inputbox.h" #include "ui/main.h" @@ -46,16 +46,16 @@ bool gAskToDelete; void (*UI_DisplayFunctions[])(void) = { - [DISPLAY_MAIN] = &UI_DisplayMain, - [DISPLAY_MENU] = &UI_DisplayMenu, - [DISPLAY_SCANNER] = &UI_DisplayScanner, + [DISPLAY_MAIN] = &UI_DisplayMain, + [DISPLAY_MENU] = &UI_DisplayMenu, + [DISPLAY_SCANNER] = &UI_DisplayScanner, #ifdef ENABLE_FMRADIO - [DISPLAY_FM] = &UI_DisplayFM, + [DISPLAY_FM] = &UI_DisplayFM, #endif #ifdef ENABLE_AIRCOPY - [DISPLAY_AIRCOPY] = &UI_DisplayAircopy, + [DISPLAY_AIRCOPY] = &UI_DisplayAircopy, #endif }; @@ -63,35 +63,35 @@ static_assert(ARRAY_SIZE(UI_DisplayFunctions) == DISPLAY_N_ELEM); void GUI_DisplayScreen(void) { - if (gScreenToDisplay != DISPLAY_INVALID) { - UI_DisplayFunctions[gScreenToDisplay](); - } + if (gScreenToDisplay != DISPLAY_INVALID) { + UI_DisplayFunctions[gScreenToDisplay](); + } } void GUI_SelectNextDisplay(GUI_DisplayType_t Display) { - if (Display == DISPLAY_INVALID) - return; + if (Display == DISPLAY_INVALID) + return; - if (gScreenToDisplay != Display) - { - DTMF_clear_input_box(); + if (gScreenToDisplay != Display) + { + DTMF_clear_input_box(); - gInputBoxIndex = 0; - gIsInSubMenu = false; - gCssBackgroundScan = false; - gScanStateDir = SCAN_OFF; - #ifdef ENABLE_FMRADIO - gFM_ScanState = FM_SCAN_OFF; - #endif - gAskForConfirmation = 0; - gAskToSave = false; - gAskToDelete = false; - gWasFKeyPressed = false; + gInputBoxIndex = 0; + gIsInSubMenu = false; + gCssBackgroundScan = false; + gScanStateDir = SCAN_OFF; + #ifdef ENABLE_FMRADIO + gFM_ScanState = FM_SCAN_OFF; + #endif + gAskForConfirmation = 0; + gAskToSave = false; + gAskToDelete = false; + gWasFKeyPressed = false; - gUpdateStatus = true; - } + gUpdateStatus = true; + } - gScreenToDisplay = Display; - gUpdateDisplay = true; + gScreenToDisplay = Display; + gUpdateDisplay = true; } diff --git a/ui/ui.h b/ui/ui.h index 97289ae..ce4d35f 100644 --- a/ui/ui.h +++ b/ui/ui.h @@ -22,20 +22,20 @@ enum GUI_DisplayType_t { - DISPLAY_MAIN = 0, - DISPLAY_MENU, - DISPLAY_SCANNER, + DISPLAY_MAIN = 0, + DISPLAY_MENU, + DISPLAY_SCANNER, #ifdef ENABLE_FMRADIO - DISPLAY_FM, + DISPLAY_FM, #endif #ifdef ENABLE_AIRCOPY - DISPLAY_AIRCOPY, + DISPLAY_AIRCOPY, #endif - DISPLAY_N_ELEM, - DISPLAY_INVALID = 0xFFu + DISPLAY_N_ELEM, + DISPLAY_INVALID = 0xFFu }; typedef enum GUI_DisplayType_t GUI_DisplayType_t; diff --git a/ui/welcome.c b/ui/welcome.c index b6a139c..48cd088 100644 --- a/ui/welcome.c +++ b/ui/welcome.c @@ -30,123 +30,123 @@ void UI_DisplayReleaseKeys(void) { - memset(gStatusLine, 0, sizeof(gStatusLine)); + memset(gStatusLine, 0, sizeof(gStatusLine)); #ifdef ENABLE_FEAT_F4HWN - ST7565_ContrastAndInv(); + ST7565_ContrastAndInv(); #endif - UI_DisplayClear(); + UI_DisplayClear(); - UI_PrintString("RELEASE", 0, 127, 1, 10); - UI_PrintString("ALL KEYS", 0, 127, 3, 10); + UI_PrintString("RELEASE", 0, 127, 1, 10); + UI_PrintString("ALL KEYS", 0, 127, 3, 10); - ST7565_BlitStatusLine(); // blank status line - ST7565_BlitFullScreen(); + ST7565_BlitStatusLine(); // blank status line + ST7565_BlitFullScreen(); } void UI_DisplayWelcome(void) { - char WelcomeString0[16]; - char WelcomeString1[16]; - char WelcomeString2[16]; + char WelcomeString0[16]; + char WelcomeString1[16]; + char WelcomeString2[16]; - memset(gStatusLine, 0, sizeof(gStatusLine)); + memset(gStatusLine, 0, sizeof(gStatusLine)); #ifdef ENABLE_FEAT_F4HWN - ST7565_ContrastAndInv(); + ST7565_ContrastAndInv(); #endif - UI_DisplayClear(); + UI_DisplayClear(); #ifdef ENABLE_FEAT_F4HWN - ST7565_BlitStatusLine(); - ST7565_BlitFullScreen(); - - if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_NONE || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_SOUND) { - ST7565_FillScreen(0x00); + ST7565_BlitStatusLine(); + ST7565_BlitFullScreen(); + + if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_NONE || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_SOUND) { + ST7565_FillScreen(0x00); #else - if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_NONE || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_FULL_SCREEN) { - ST7565_FillScreen(0xFF); + if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_NONE || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_FULL_SCREEN) { + ST7565_FillScreen(0xFF); #endif - } else { - memset(WelcomeString0, 0, sizeof(WelcomeString0)); - memset(WelcomeString1, 0, sizeof(WelcomeString1)); + } else { + memset(WelcomeString0, 0, sizeof(WelcomeString0)); + memset(WelcomeString1, 0, sizeof(WelcomeString1)); - EEPROM_ReadBuffer(0x0EB0, WelcomeString0, 16); - EEPROM_ReadBuffer(0x0EC0, WelcomeString1, 16); + EEPROM_ReadBuffer(0x0EB0, WelcomeString0, 16); + EEPROM_ReadBuffer(0x0EC0, WelcomeString1, 16); - sprintf(WelcomeString2, "%u.%02uV %u%%", - gBatteryVoltageAverage / 100, - gBatteryVoltageAverage % 100, - BATTERY_VoltsToPercent(gBatteryVoltageAverage)); + sprintf(WelcomeString2, "%u.%02uV %u%%", + gBatteryVoltageAverage / 100, + gBatteryVoltageAverage % 100, + BATTERY_VoltsToPercent(gBatteryVoltageAverage)); - if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_VOLTAGE) - { - strcpy(WelcomeString0, "VOLTAGE"); - strcpy(WelcomeString1, WelcomeString2); - } - else if(gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_ALL) - { - if(strlen(WelcomeString0) == 0 && strlen(WelcomeString1) == 0) - { - strcpy(WelcomeString0, "WELCOME"); - strcpy(WelcomeString1, WelcomeString2); - } - else if(strlen(WelcomeString0) == 0 || strlen(WelcomeString1) == 0) - { - if(strlen(WelcomeString0) == 0) - { - strcpy(WelcomeString0, WelcomeString1); - } - strcpy(WelcomeString1, WelcomeString2); - } - } - else if(gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_MESSAGE) - { - if(strlen(WelcomeString0) == 0) - { - strcpy(WelcomeString0, "WELCOME"); - } + if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_VOLTAGE) + { + strcpy(WelcomeString0, "VOLTAGE"); + strcpy(WelcomeString1, WelcomeString2); + } + else if(gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_ALL) + { + if(strlen(WelcomeString0) == 0 && strlen(WelcomeString1) == 0) + { + strcpy(WelcomeString0, "WELCOME"); + strcpy(WelcomeString1, WelcomeString2); + } + else if(strlen(WelcomeString0) == 0 || strlen(WelcomeString1) == 0) + { + if(strlen(WelcomeString0) == 0) + { + strcpy(WelcomeString0, WelcomeString1); + } + strcpy(WelcomeString1, WelcomeString2); + } + } + else if(gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_MESSAGE) + { + if(strlen(WelcomeString0) == 0) + { + strcpy(WelcomeString0, "WELCOME"); + } - if(strlen(WelcomeString1) == 0) - { - strcpy(WelcomeString1, "BIENVENUE"); - } - } + if(strlen(WelcomeString1) == 0) + { + strcpy(WelcomeString1, "BIENVENUE"); + } + } - UI_PrintString(WelcomeString0, 0, 127, 0, 10); - UI_PrintString(WelcomeString1, 0, 127, 2, 10); + UI_PrintString(WelcomeString0, 0, 127, 0, 10); + UI_PrintString(WelcomeString1, 0, 127, 2, 10); #ifdef ENABLE_FEAT_F4HWN - UI_PrintStringSmallNormal(Version, 0, 128, 4); + UI_PrintStringSmallNormal(Version, 0, 128, 4); - for (uint8_t i = 0; i < 128; i++) - { - gFrameBuffer[3][i] ^= 0x80; - } + for (uint8_t i = 0; i < 128; i++) + { + gFrameBuffer[3][i] ^= 0x80; + } - for (uint8_t i = 18; i < 110; i++) - { - gFrameBuffer[4][i] ^= 0xFF; - } + for (uint8_t i = 18; i < 110; i++) + { + gFrameBuffer[4][i] ^= 0xFF; + } - #ifdef ENABLE_SPECTRUM - #ifdef ENABLE_FMRADIO - UI_PrintStringSmallNormal(Based, 0, 127, 5); - UI_PrintStringSmallNormal(Credits, 0, 127, 6); - #else - UI_PrintStringSmallNormal("Bandscope ", 0, 127, 5); - memcpy(gFrameBuffer[5] + 95, BITMAP_Ready, sizeof(BITMAP_Ready)); - UI_PrintStringSmallNormal("Broadcast ", 0, 127, 6); - #endif - #else - UI_PrintStringSmallNormal("Bandscope ", 0, 127, 5); - UI_PrintStringSmallNormal("Broadcast ", 0, 127, 6); - memcpy(gFrameBuffer[6] + 95, BITMAP_Ready, sizeof(BITMAP_Ready)); - #endif + #ifdef ENABLE_SPECTRUM + #ifdef ENABLE_FMRADIO + UI_PrintStringSmallNormal(Based, 0, 127, 5); + UI_PrintStringSmallNormal(Credits, 0, 127, 6); + #else + UI_PrintStringSmallNormal("Bandscope ", 0, 127, 5); + memcpy(gFrameBuffer[5] + 95, BITMAP_Ready, sizeof(BITMAP_Ready)); + UI_PrintStringSmallNormal("Broadcast ", 0, 127, 6); + #endif + #else + UI_PrintStringSmallNormal("Bandscope ", 0, 127, 5); + UI_PrintStringSmallNormal("Broadcast ", 0, 127, 6); + memcpy(gFrameBuffer[6] + 95, BITMAP_Ready, sizeof(BITMAP_Ready)); + #endif #else - UI_PrintStringSmallNormal(Version, 0, 127, 6); + UI_PrintStringSmallNormal(Version, 0, 127, 6); #endif - //ST7565_BlitStatusLine(); // blank status line : I think it's useless - ST7565_BlitFullScreen(); - } + //ST7565_BlitStatusLine(); // blank status line : I think it's useless + ST7565_BlitFullScreen(); + } } diff --git a/version.c b/version.c index 30cf86a..f9c28ad 100644 --- a/version.c +++ b/version.c @@ -1,16 +1,16 @@ #ifdef VERSION_STRING - #define VER " "VERSION_STRING + #define VER " "VERSION_STRING #else - #define VER "" + #define VER "" #endif #ifdef ENABLE_FEAT_F4HWN - const char Version[] = AUTHOR_STRING_2 " " VERSION_STRING_2; - const char Based[] = "based on"; - const char Credits[] = AUTHOR_STRING_1 " " VERSION_STRING_1; + const char Version[] = AUTHOR_STRING_2 " " VERSION_STRING_2; + const char Based[] = "based on"; + const char Credits[] = AUTHOR_STRING_1 " " VERSION_STRING_1; #else - const char Version[] = AUTHOR_STRING VER; + const char Version[] = AUTHOR_STRING VER; #endif const char UART_Version[] = "UV-K5 Firmware, " AUTHOR_STRING VER "\r\n"; diff --git a/version.h b/version.h index 8a184df..a19174f 100644 --- a/version.h +++ b/version.h @@ -23,6 +23,6 @@ extern const char UART_Version[]; #endif #ifdef ENABLE_FEAT_F4HWN - extern const char Credits[]; - extern const char Based[]; + extern const char Credits[]; + extern const char Based[]; #endif From e64a615359ee0442390e7513f1d0afd2ab24e367 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Fri, 16 Aug 2024 00:14:26 +0200 Subject: [PATCH 23/30] Check tab only... --- app/main.c | 1294 ++++++++++++++++++++++++++-------------------------- 1 file changed, 647 insertions(+), 647 deletions(-) diff --git a/app/main.c b/app/main.c index 231ec5f..5c5d8d4 100644 --- a/app/main.c +++ b/app/main.c @@ -21,7 +21,7 @@ #include "app/chFrScanner.h" #include "app/common.h" #ifdef ENABLE_FMRADIO - #include "app/fm.h" + #include "app/fm.h" #endif #include "app/generic.h" #include "app/main.h" @@ -44,862 +44,862 @@ #include static void toggle_chan_scanlist(void) -{ // toggle the selected channels scanlist setting +{ // toggle the selected channels scanlist setting - if (SCANNER_IsScanning()) - return; + if (SCANNER_IsScanning()) + return; - if(!IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) { + if(!IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) { #ifdef ENABLE_SCAN_RANGES - gScanRangeStart = gScanRangeStart ? 0 : gTxVfo->pRX->Frequency; - gScanRangeStop = gEeprom.VfoInfo[!gEeprom.TX_VFO].freq_config_RX.Frequency; - if(gScanRangeStart > gScanRangeStop) - SWAP(gScanRangeStart, gScanRangeStop); + gScanRangeStart = gScanRangeStart ? 0 : gTxVfo->pRX->Frequency; + gScanRangeStop = gEeprom.VfoInfo[!gEeprom.TX_VFO].freq_config_RX.Frequency; + if(gScanRangeStart > gScanRangeStop) + SWAP(gScanRangeStart, gScanRangeStop); #endif - return; - } - - // Remove exclude - if(gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] == true) - { - gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] = false; - return; - } + return; + } + + // Remove exclude + if(gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] == true) + { + gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] = false; + return; + } - uint8_t scanTmp = gTxVfo->SCANLIST1_PARTICIPATION | (gTxVfo->SCANLIST2_PARTICIPATION << 1) | (gTxVfo->SCANLIST3_PARTICIPATION << 2); + uint8_t scanTmp = gTxVfo->SCANLIST1_PARTICIPATION | (gTxVfo->SCANLIST2_PARTICIPATION << 1) | (gTxVfo->SCANLIST3_PARTICIPATION << 2); - scanTmp = (scanTmp++ < 7) ? scanTmp: 0; + scanTmp = (scanTmp++ < 7) ? scanTmp: 0; gTxVfo->SCANLIST1_PARTICIPATION = (scanTmp >> 0) & 0x01; gTxVfo->SCANLIST2_PARTICIPATION = (scanTmp >> 1) & 0x01; gTxVfo->SCANLIST3_PARTICIPATION = (scanTmp >> 2) & 0x01; - SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, true, true); + SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true, true, true); - gVfoConfigureMode = VFO_CONFIGURE; - gFlagResetVfos = true; + gVfoConfigureMode = VFO_CONFIGURE; + gFlagResetVfos = true; } static void processFKeyFunction(const KEY_Code_t Key, const bool beep) { - uint8_t Vfo = gEeprom.TX_VFO; + uint8_t Vfo = gEeprom.TX_VFO; - if (gScreenToDisplay == DISPLAY_MENU) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } - - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + if (gScreenToDisplay == DISPLAY_MENU) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } + + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - switch (Key) { - case KEY_0: - #ifdef ENABLE_FMRADIO - ACTION_FM(); - #endif - break; + switch (Key) { + case KEY_0: + #ifdef ENABLE_FMRADIO + ACTION_FM(); + #endif + break; - case KEY_1: - if (!IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) { - gWasFKeyPressed = false; - gUpdateStatus = true; - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + case KEY_1: + if (!IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) { + gWasFKeyPressed = false; + gUpdateStatus = true; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; #ifdef ENABLE_COPY_CHAN_TO_VFO - if (!gEeprom.VFO_OPEN || gCssBackgroundScan) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + if (!gEeprom.VFO_OPEN || gCssBackgroundScan) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } - if (gScanStateDir != SCAN_OFF) { - if (gCurrentFunction != FUNCTION_INCOMING || - gRxReceptionMode == RX_MODE_NONE || - gScanPauseDelayIn_10ms == 0) - { // scan is running (not paused) - return; - } - } + if (gScanStateDir != SCAN_OFF) { + if (gCurrentFunction != FUNCTION_INCOMING || + gRxReceptionMode == RX_MODE_NONE || + gScanPauseDelayIn_10ms == 0) + { // scan is running (not paused) + return; + } + } - const uint8_t vfo = gEeprom.TX_VFO; + const uint8_t vfo = gEeprom.TX_VFO; - if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo])) - { // copy channel to VFO, then swap to the VFO + if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo])) + { // copy channel to VFO, then swap to the VFO - gEeprom.ScreenChannel[vfo] = FREQ_CHANNEL_FIRST + gEeprom.VfoInfo[vfo].Band; - gEeprom.VfoInfo[vfo].CHANNEL_SAVE = gEeprom.ScreenChannel[vfo]; + gEeprom.ScreenChannel[vfo] = FREQ_CHANNEL_FIRST + gEeprom.VfoInfo[vfo].Band; + gEeprom.VfoInfo[vfo].CHANNEL_SAVE = gEeprom.ScreenChannel[vfo]; - RADIO_SelectVfos(); - RADIO_ApplyOffset(gRxVfo); - RADIO_ConfigureSquelchAndOutputPower(gRxVfo); - RADIO_SetupRegisters(true); + RADIO_SelectVfos(); + RADIO_ApplyOffset(gRxVfo); + RADIO_ConfigureSquelchAndOutputPower(gRxVfo); + RADIO_SetupRegisters(true); - //SETTINGS_SaveChannel(channel, gEeprom.RX_VFO, gRxVfo, 1); + //SETTINGS_SaveChannel(channel, gEeprom.RX_VFO, gRxVfo, 1); - gRequestSaveChannel = 1; - gRequestSaveVFO = true; - gUpdateDisplay = true; - } + gRequestSaveChannel = 1; + gRequestSaveVFO = true; + gUpdateDisplay = true; + } #endif - return; - } + return; + } #ifdef ENABLE_WIDE_RX - if(gTxVfo->Band == BAND7_470MHz && gTxVfo->pRX->Frequency < _1GHz_in_KHz) { - gTxVfo->pRX->Frequency = _1GHz_in_KHz; - return; - } + if(gTxVfo->Band == BAND7_470MHz && gTxVfo->pRX->Frequency < _1GHz_in_KHz) { + gTxVfo->pRX->Frequency = _1GHz_in_KHz; + return; + } #endif - gTxVfo->Band += 1; + gTxVfo->Band += 1; - if (gTxVfo->Band == BAND5_350MHz && !gSetting_350EN) { - // skip if not enabled - gTxVfo->Band += 1; - } else if (gTxVfo->Band >= BAND_N_ELEM){ - // go arround if overflowed - gTxVfo->Band = BAND1_50MHz; - } + if (gTxVfo->Band == BAND5_350MHz && !gSetting_350EN) { + // skip if not enabled + gTxVfo->Band += 1; + } else if (gTxVfo->Band >= BAND_N_ELEM){ + // go arround if overflowed + gTxVfo->Band = BAND1_50MHz; + } - gEeprom.ScreenChannel[Vfo] = FREQ_CHANNEL_FIRST + gTxVfo->Band; - gEeprom.FreqChannel[Vfo] = FREQ_CHANNEL_FIRST + gTxVfo->Band; + gEeprom.ScreenChannel[Vfo] = FREQ_CHANNEL_FIRST + gTxVfo->Band; + gEeprom.FreqChannel[Vfo] = FREQ_CHANNEL_FIRST + gTxVfo->Band; - gRequestSaveVFO = true; - gVfoConfigureMode = VFO_CONFIGURE_RELOAD; + gRequestSaveVFO = true; + gVfoConfigureMode = VFO_CONFIGURE_RELOAD; - gRequestDisplayScreen = DISPLAY_MAIN; + gRequestDisplayScreen = DISPLAY_MAIN; - if (beep) - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + if (beep) + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - break; + break; - case KEY_2: - #ifdef ENABLE_FEAT_F4HWN - gVfoConfigureMode = VFO_CONFIGURE; - #endif - COMMON_SwitchVFOs(); - if (beep) - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - break; + case KEY_2: + #ifdef ENABLE_FEAT_F4HWN + gVfoConfigureMode = VFO_CONFIGURE; + #endif + COMMON_SwitchVFOs(); + if (beep) + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + break; - case KEY_3: - #ifdef ENABLE_FEAT_F4HWN - gVfoConfigureMode = VFO_CONFIGURE; - #endif - COMMON_SwitchVFOMode(); - if (beep) - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + case KEY_3: + #ifdef ENABLE_FEAT_F4HWN + gVfoConfigureMode = VFO_CONFIGURE; + #endif + COMMON_SwitchVFOMode(); + if (beep) + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - break; + break; - case KEY_4: - gWasFKeyPressed = false; + case KEY_4: + gWasFKeyPressed = false; - gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX; - gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF; - gUpdateStatus = true; - if (beep) - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gBackup_CROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX; + gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF; + gUpdateStatus = true; + if (beep) + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - SCANNER_Start(false); - gRequestDisplayScreen = DISPLAY_SCANNER; - break; + SCANNER_Start(false); + gRequestDisplayScreen = DISPLAY_SCANNER; + break; - case KEY_5: - if(beep) { + case KEY_5: + if(beep) { #ifdef ENABLE_NOAA - if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) { - gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_VFO]; - } - else { - gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_VFO]; + if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) { + gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_VFO]; + } + else { + gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_VFO]; #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE; + gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE; #endif - } - gRequestSaveVFO = true; - gVfoConfigureMode = VFO_CONFIGURE_RELOAD; + } + gRequestSaveVFO = true; + gVfoConfigureMode = VFO_CONFIGURE_RELOAD; #elif defined(ENABLE_SPECTRUM) - APP_RunSpectrum(); - gRequestDisplayScreen = DISPLAY_MAIN; + APP_RunSpectrum(); + gRequestDisplayScreen = DISPLAY_MAIN; #endif - } - else { - toggle_chan_scanlist(); - } + } + else { + toggle_chan_scanlist(); + } - break; + break; - case KEY_6: - ACTION_Power(); - break; + case KEY_6: + ACTION_Power(); + break; - case KEY_7: + case KEY_7: #ifdef ENABLE_VOX - ACTION_Vox(); + ACTION_Vox(); //#else -// toggle_chan_scanlist(); +// toggle_chan_scanlist(); #endif - break; + break; - case KEY_8: - gTxVfo->FrequencyReverse = gTxVfo->FrequencyReverse == false; - gRequestSaveChannel = 1; - break; + case KEY_8: + gTxVfo->FrequencyReverse = gTxVfo->FrequencyReverse == false; + gRequestSaveChannel = 1; + break; - case KEY_9: - if (RADIO_CheckValidChannel(gEeprom.CHAN_1_CALL, false, 0)) { - gEeprom.MrChannel[Vfo] = gEeprom.CHAN_1_CALL; - gEeprom.ScreenChannel[Vfo] = gEeprom.CHAN_1_CALL; + case KEY_9: + if (RADIO_CheckValidChannel(gEeprom.CHAN_1_CALL, false, 0)) { + gEeprom.MrChannel[Vfo] = gEeprom.CHAN_1_CALL; + gEeprom.ScreenChannel[Vfo] = gEeprom.CHAN_1_CALL; #ifdef ENABLE_VOICE - AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE); - AUDIO_SetDigitVoice(1, gEeprom.CHAN_1_CALL + 1); - gAnotherVoiceID = (VOICE_ID_t)0xFE; + AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE); + AUDIO_SetDigitVoice(1, gEeprom.CHAN_1_CALL + 1); + gAnotherVoiceID = (VOICE_ID_t)0xFE; #endif - gRequestSaveVFO = true; - gVfoConfigureMode = VFO_CONFIGURE_RELOAD; - break; - } + gRequestSaveVFO = true; + gVfoConfigureMode = VFO_CONFIGURE_RELOAD; + break; + } - if (beep) - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - break; + if (beep) + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + break; #ifdef ENABLE_FEAT_F4HWN // Set Squelch F + UP or Down and Step F + SIDE1 or F + SIDE2 - case KEY_UP: - gEeprom.SQUELCH_LEVEL = (gEeprom.SQUELCH_LEVEL < 9) ? gEeprom.SQUELCH_LEVEL + 1: 9; - gVfoConfigureMode = VFO_CONFIGURE; - gWasFKeyPressed = false; - break; - case KEY_DOWN: - gEeprom.SQUELCH_LEVEL = (gEeprom.SQUELCH_LEVEL > 0) ? gEeprom.SQUELCH_LEVEL - 1: 0; - gVfoConfigureMode = VFO_CONFIGURE; - gWasFKeyPressed = false; - break; + case KEY_UP: + gEeprom.SQUELCH_LEVEL = (gEeprom.SQUELCH_LEVEL < 9) ? gEeprom.SQUELCH_LEVEL + 1: 9; + gVfoConfigureMode = VFO_CONFIGURE; + gWasFKeyPressed = false; + break; + case KEY_DOWN: + gEeprom.SQUELCH_LEVEL = (gEeprom.SQUELCH_LEVEL > 0) ? gEeprom.SQUELCH_LEVEL - 1: 0; + gVfoConfigureMode = VFO_CONFIGURE; + gWasFKeyPressed = false; + break; - case KEY_SIDE1: - uint8_t a = FREQUENCY_GetSortedIdxFromStepIdx(gTxVfo->STEP_SETTING); - if (a < STEP_N_ELEM - 1) - { - gTxVfo->STEP_SETTING = FREQUENCY_GetStepIdxFromSortedIdx(a + 1); - } - if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) - { - gRequestSaveChannel = 1; - } - gVfoConfigureMode = VFO_CONFIGURE; - gWasFKeyPressed = false; - break; - case KEY_SIDE2: - uint8_t b = FREQUENCY_GetSortedIdxFromStepIdx(gTxVfo->STEP_SETTING); - if (b > 0) - { - gTxVfo->STEP_SETTING = FREQUENCY_GetStepIdxFromSortedIdx(b - 1); - } - if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) - { - gRequestSaveChannel = 1; - } - gVfoConfigureMode = VFO_CONFIGURE; - gWasFKeyPressed = false; - break; + case KEY_SIDE1: + uint8_t a = FREQUENCY_GetSortedIdxFromStepIdx(gTxVfo->STEP_SETTING); + if (a < STEP_N_ELEM - 1) + { + gTxVfo->STEP_SETTING = FREQUENCY_GetStepIdxFromSortedIdx(a + 1); + } + if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) + { + gRequestSaveChannel = 1; + } + gVfoConfigureMode = VFO_CONFIGURE; + gWasFKeyPressed = false; + break; + case KEY_SIDE2: + uint8_t b = FREQUENCY_GetSortedIdxFromStepIdx(gTxVfo->STEP_SETTING); + if (b > 0) + { + gTxVfo->STEP_SETTING = FREQUENCY_GetStepIdxFromSortedIdx(b - 1); + } + if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) + { + gRequestSaveChannel = 1; + } + gVfoConfigureMode = VFO_CONFIGURE; + gWasFKeyPressed = false; + break; #endif - default: - gUpdateStatus = true; - gWasFKeyPressed = false; + default: + gUpdateStatus = true; + gWasFKeyPressed = false; - if (beep) - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - break; - } + if (beep) + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + break; + } } void channelMove(uint16_t Channel) { - const uint8_t Vfo = gEeprom.TX_VFO; + const uint8_t Vfo = gEeprom.TX_VFO; - if (!RADIO_CheckValidChannel(Channel, false, 0)) { - if (gKeyInputCountdown <= 1) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - } + if (!RADIO_CheckValidChannel(Channel, false, 0)) { + if (gKeyInputCountdown <= 1) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + } - return; - } + return; + } - gBeepToPlay = BEEP_NONE; + gBeepToPlay = BEEP_NONE; - #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; - #endif + #ifdef ENABLE_VOICE + gAnotherVoiceID = (VOICE_ID_t)Key; + #endif - gEeprom.MrChannel[Vfo] = (uint8_t)Channel; - gEeprom.ScreenChannel[Vfo] = (uint8_t)Channel; - //gRequestSaveVFO = true; - gVfoConfigureMode = VFO_CONFIGURE_RELOAD; + gEeprom.MrChannel[Vfo] = (uint8_t)Channel; + gEeprom.ScreenChannel[Vfo] = (uint8_t)Channel; + //gRequestSaveVFO = true; + gVfoConfigureMode = VFO_CONFIGURE_RELOAD; - RADIO_ConfigureChannel(gEeprom.TX_VFO, gVfoConfigureMode); - - return; + RADIO_ConfigureChannel(gEeprom.TX_VFO, gVfoConfigureMode); + + return; } void channelMoveSwitch(void) { - if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) { // user is entering channel number - uint16_t Channel = 0; + if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) { // user is entering channel number + uint16_t Channel = 0; - switch (gInputBoxIndex) - { - case 1: - Channel = gInputBox[0]; - break; - case 2: - Channel = (gInputBox[0] * 10) + gInputBox[1]; - break; - case 3: - Channel = (gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]; - break; - } + switch (gInputBoxIndex) + { + case 1: + Channel = gInputBox[0]; + break; + case 2: + Channel = (gInputBox[0] * 10) + gInputBox[1]; + break; + case 3: + Channel = (gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]; + break; + } - if ((Channel == 0) && (gInputBoxIndex != 3)) { - return; - } + if ((Channel == 0) && (gInputBoxIndex != 3)) { + return; + } - if (gInputBoxIndex == 3) { - gInputBoxIndex = 0; - gKeyInputCountdown = 1; + if (gInputBoxIndex == 3) { + gInputBoxIndex = 0; + gKeyInputCountdown = 1; - channelMove(Channel - 1); - SETTINGS_SaveVfoIndices(); - - return; - } + channelMove(Channel - 1); + SETTINGS_SaveVfoIndices(); + + return; + } - channelMove(Channel - 1); - } + channelMove(Channel - 1); + } } static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { - if (bKeyHeld) { // key held down - if (bKeyPressed) { - if (gScreenToDisplay == DISPLAY_MAIN) { - if (gInputBoxIndex > 0) { // delete any inputted chars - gInputBoxIndex = 0; - gRequestDisplayScreen = DISPLAY_MAIN; - } + if (bKeyHeld) { // key held down + if (bKeyPressed) { + if (gScreenToDisplay == DISPLAY_MAIN) { + if (gInputBoxIndex > 0) { // delete any inputted chars + gInputBoxIndex = 0; + gRequestDisplayScreen = DISPLAY_MAIN; + } - gWasFKeyPressed = false; - gUpdateStatus = true; + gWasFKeyPressed = false; + gUpdateStatus = true; - processFKeyFunction(Key, false); - } - } - return; - } + processFKeyFunction(Key, false); + } + } + return; + } - 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 (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 + if (!gWasFKeyPressed) { // F-key wasn't pressed - if (gScanStateDir != SCAN_OFF){ - switch(Key) { - case KEY_0...KEY_5: - gEeprom.SCAN_LIST_DEFAULT = Key; - break; - default: - break; - } - return; - } + if (gScanStateDir != SCAN_OFF){ + switch(Key) { + case KEY_0...KEY_5: + gEeprom.SCAN_LIST_DEFAULT = Key; + break; + default: + break; + } + return; + } - const uint8_t Vfo = gEeprom.TX_VFO; - INPUTBOX_Append(Key); - gKeyInputCountdown = key_input_timeout_500ms; + const uint8_t Vfo = gEeprom.TX_VFO; + INPUTBOX_Append(Key); + gKeyInputCountdown = key_input_timeout_500ms; - channelMoveSwitch(); + channelMoveSwitch(); - gRequestDisplayScreen = DISPLAY_MAIN; + gRequestDisplayScreen = DISPLAY_MAIN; - if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) { // user is entering channel number + if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE)) { // user is entering channel number - gKeyInputCountdown = (key_input_timeout_500ms / 5); // short time... + gKeyInputCountdown = (key_input_timeout_500ms / 5); // short time... - #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; - #endif - - return; - } + #ifdef ENABLE_VOICE + gAnotherVoiceID = (VOICE_ID_t)Key; + #endif + + return; + } -// #ifdef ENABLE_NOAA -// if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) -// #endif - if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) - { // user is entering a frequency +// #ifdef ENABLE_NOAA +// if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) +// #endif + if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) + { // user is entering a frequency #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; + gAnotherVoiceID = (VOICE_ID_t)Key; #endif - bool isGigaF = gTxVfo->pRX->Frequency >= _1GHz_in_KHz; - if (gInputBoxIndex < 6 + isGigaF) { - return; - } + bool isGigaF = gTxVfo->pRX->Frequency >= _1GHz_in_KHz; + if (gInputBoxIndex < 6 + isGigaF) { + return; + } - gInputBoxIndex = 0; - uint32_t Frequency = StrToUL(INPUTBOX_GetAscii()) * 100; + gInputBoxIndex = 0; + uint32_t Frequency = StrToUL(INPUTBOX_GetAscii()) * 100; - // clamp the frequency entered to some valid value - if (Frequency < frequencyBandTable[0].lower) { - Frequency = frequencyBandTable[0].lower; - } - else if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) { - const uint32_t center = (BX4819_band1.upper + BX4819_band2.lower) / 2; - Frequency = (Frequency < center) ? BX4819_band1.upper : BX4819_band2.lower; - } - else if (Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper) { - Frequency = frequencyBandTable[BAND_N_ELEM - 1].upper; - } + // clamp the frequency entered to some valid value + if (Frequency < frequencyBandTable[0].lower) { + Frequency = frequencyBandTable[0].lower; + } + else if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) { + const uint32_t center = (BX4819_band1.upper + BX4819_band2.lower) / 2; + Frequency = (Frequency < center) ? BX4819_band1.upper : BX4819_band2.lower; + } + else if (Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper) { + Frequency = frequencyBandTable[BAND_N_ELEM - 1].upper; + } - const FREQUENCY_Band_t band = FREQUENCY_GetBand(Frequency); + const FREQUENCY_Band_t band = FREQUENCY_GetBand(Frequency); - if (gTxVfo->Band != band) { - gTxVfo->Band = band; - gEeprom.ScreenChannel[Vfo] = band + FREQ_CHANNEL_FIRST; - gEeprom.FreqChannel[Vfo] = band + FREQ_CHANNEL_FIRST; + if (gTxVfo->Band != band) { + gTxVfo->Band = band; + gEeprom.ScreenChannel[Vfo] = band + FREQ_CHANNEL_FIRST; + gEeprom.FreqChannel[Vfo] = band + FREQ_CHANNEL_FIRST; - SETTINGS_SaveVfoIndices(); + SETTINGS_SaveVfoIndices(); - RADIO_ConfigureChannel(Vfo, VFO_CONFIGURE_RELOAD); - } + RADIO_ConfigureChannel(Vfo, VFO_CONFIGURE_RELOAD); + } - Frequency = FREQUENCY_RoundToStep(Frequency, gTxVfo->StepFrequency); + Frequency = FREQUENCY_RoundToStep(Frequency, gTxVfo->StepFrequency); - if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) - { // clamp the frequency to the limit - const uint32_t center = (BX4819_band1.upper + BX4819_band2.lower) / 2; - Frequency = (Frequency < center) ? BX4819_band1.upper - gTxVfo->StepFrequency : BX4819_band2.lower; - } + if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) + { // clamp the frequency to the limit + const uint32_t center = (BX4819_band1.upper + BX4819_band2.lower) / 2; + Frequency = (Frequency < center) ? BX4819_band1.upper - gTxVfo->StepFrequency : BX4819_band2.lower; + } - gTxVfo->freq_config_RX.Frequency = Frequency; + gTxVfo->freq_config_RX.Frequency = Frequency; - gRequestSaveChannel = 1; - return; + gRequestSaveChannel = 1; + return; - } - #ifdef ENABLE_NOAA - else - if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) - { // user is entering NOAA channel - if (gInputBoxIndex != 2) { - #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; - #endif - gRequestDisplayScreen = DISPLAY_MAIN; - return; - } + } + #ifdef ENABLE_NOAA + else + if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) + { // user is entering NOAA channel + if (gInputBoxIndex != 2) { + #ifdef ENABLE_VOICE + gAnotherVoiceID = (VOICE_ID_t)Key; + #endif + gRequestDisplayScreen = DISPLAY_MAIN; + return; + } - gInputBoxIndex = 0; + gInputBoxIndex = 0; - uint8_t Channel = (gInputBox[0] * 10) + gInputBox[1]; - if (Channel >= 1 && Channel <= ARRAY_SIZE(NoaaFrequencyTable)) { - Channel += NOAA_CHANNEL_FIRST; - #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; - #endif - gEeprom.NoaaChannel[Vfo] = Channel; - gEeprom.ScreenChannel[Vfo] = Channel; - gRequestSaveVFO = true; - gVfoConfigureMode = VFO_CONFIGURE_RELOAD; - return; - } - } - #endif + uint8_t Channel = (gInputBox[0] * 10) + gInputBox[1]; + if (Channel >= 1 && Channel <= ARRAY_SIZE(NoaaFrequencyTable)) { + Channel += NOAA_CHANNEL_FIRST; + #ifdef ENABLE_VOICE + gAnotherVoiceID = (VOICE_ID_t)Key; + #endif + gEeprom.NoaaChannel[Vfo] = Channel; + gEeprom.ScreenChannel[Vfo] = Channel; + gRequestSaveVFO = true; + gVfoConfigureMode = VFO_CONFIGURE_RELOAD; + return; + } + } + #endif - gRequestDisplayScreen = DISPLAY_MAIN; - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + gRequestDisplayScreen = DISPLAY_MAIN; + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } - gWasFKeyPressed = false; - gUpdateStatus = true; + gWasFKeyPressed = false; + gUpdateStatus = true; - if(Key == 8) - { - ACTION_BackLightOnDemand(); - return; - } - else if(Key == 9) - { - ACTION_BackLight(); - return; - } + if(Key == 8) + { + ACTION_BackLightOnDemand(); + return; + } + else if(Key == 9) + { + ACTION_BackLight(); + return; + } - processFKeyFunction(Key, true); + processFKeyFunction(Key, true); } static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld) { - if (!bKeyHeld && bKeyPressed) { // exit key pressed - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + if (!bKeyHeld && bKeyPressed) { // exit key pressed + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; #ifdef ENABLE_DTMF_CALLING - if (gDTMF_CallState != DTMF_CALL_STATE_NONE && gCurrentFunction != FUNCTION_TRANSMIT) - { // clear CALL mode being displayed - gDTMF_CallState = DTMF_CALL_STATE_NONE; - gUpdateDisplay = true; - return; - } + if (gDTMF_CallState != DTMF_CALL_STATE_NONE && gCurrentFunction != FUNCTION_TRANSMIT) + { // clear CALL mode being displayed + gDTMF_CallState = DTMF_CALL_STATE_NONE; + gUpdateDisplay = true; + return; + } #endif #ifdef ENABLE_FMRADIO - if (!gFmRadioMode) + if (!gFmRadioMode) #endif - { - if (gScanStateDir == SCAN_OFF) { - if (gInputBoxIndex == 0) - return; - gInputBox[--gInputBoxIndex] = 10; + { + if (gScanStateDir == SCAN_OFF) { + if (gInputBoxIndex == 0) + return; + gInputBox[--gInputBoxIndex] = 10; - gKeyInputCountdown = key_input_timeout_500ms; + gKeyInputCountdown = key_input_timeout_500ms; #ifdef ENABLE_VOICE - if (gInputBoxIndex == 0) - gAnotherVoiceID = VOICE_ID_CANCEL; + if (gInputBoxIndex == 0) + gAnotherVoiceID = VOICE_ID_CANCEL; #endif - } - else { - gScanKeepResult = false; - CHFRSCANNER_Stop(); + } + else { + gScanKeepResult = false; + CHFRSCANNER_Stop(); #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_SCANNING_STOP; + gAnotherVoiceID = VOICE_ID_SCANNING_STOP; #endif - } + } - gRequestDisplayScreen = DISPLAY_MAIN; - return; - } + gRequestDisplayScreen = DISPLAY_MAIN; + return; + } #ifdef ENABLE_FMRADIO - ACTION_FM(); + ACTION_FM(); #endif - return; - } + return; + } - if (bKeyHeld && bKeyPressed) { // exit key held down - if (gInputBoxIndex > 0 || gDTMF_InputBox_Index > 0 || gDTMF_InputMode) - { // cancel key input mode (channel/frequency entry) - gDTMF_InputMode = false; - gDTMF_InputBox_Index = 0; - memset(gDTMF_String, 0, sizeof(gDTMF_String)); - gInputBoxIndex = 0; - gRequestDisplayScreen = DISPLAY_MAIN; - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - } - } + if (bKeyHeld && bKeyPressed) { // exit key held down + if (gInputBoxIndex > 0 || gDTMF_InputBox_Index > 0 || gDTMF_InputMode) + { // cancel key input mode (channel/frequency entry) + gDTMF_InputMode = false; + gDTMF_InputBox_Index = 0; + memset(gDTMF_String, 0, sizeof(gDTMF_String)); + gInputBoxIndex = 0; + gRequestDisplayScreen = DISPLAY_MAIN; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + } + } } static void MAIN_Key_MENU(bool bKeyPressed, bool bKeyHeld) { - if (bKeyPressed && !bKeyHeld) // menu key pressed - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + if (bKeyPressed && !bKeyHeld) // menu key pressed + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - if (bKeyHeld) { // menu key held down (long press) - if (bKeyPressed) { // long press MENU key + if (bKeyHeld) { // menu key held down (long press) + if (bKeyPressed) { // long press MENU key - #ifdef ENABLE_FEAT_F4HWN - // Exclude work with list 1, 2, 3 or all list - if(gScanStateDir != SCAN_OFF) - { - if(FUNCTION_IsRx()) - { - gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] = true; + #ifdef ENABLE_FEAT_F4HWN + // Exclude work with list 1, 2, 3 or all list + if(gScanStateDir != SCAN_OFF) + { + if(FUNCTION_IsRx()) + { + gMR_ChannelExclude[gTxVfo->CHANNEL_SAVE] = true; - gVfoConfigureMode = VFO_CONFIGURE; - gFlagResetVfos = true; + gVfoConfigureMode = VFO_CONFIGURE; + gFlagResetVfos = true; - lastFoundFrqOrChan = lastFoundFrqOrChanOld; + lastFoundFrqOrChan = lastFoundFrqOrChanOld; - CHFRSCANNER_ContinueScanning(); - } + CHFRSCANNER_ContinueScanning(); + } - return; - } - #endif - - gWasFKeyPressed = false; + return; + } + #endif + + gWasFKeyPressed = false; - if (gScreenToDisplay == DISPLAY_MAIN) { - if (gInputBoxIndex > 0) { // delete any inputted chars - gInputBoxIndex = 0; - gRequestDisplayScreen = DISPLAY_MAIN; - } + if (gScreenToDisplay == DISPLAY_MAIN) { + if (gInputBoxIndex > 0) { // delete any inputted chars + gInputBoxIndex = 0; + gRequestDisplayScreen = DISPLAY_MAIN; + } - gWasFKeyPressed = false; - gUpdateStatus = true; + gWasFKeyPressed = false; + gUpdateStatus = true; - ACTION_Handle(KEY_MENU, bKeyPressed, bKeyHeld); - } - } + ACTION_Handle(KEY_MENU, bKeyPressed, bKeyHeld); + } + } - return; - } + return; + } - if (!bKeyPressed && !gDTMF_InputMode) { // menu key released - const bool bFlag = !gInputBoxIndex; - gInputBoxIndex = 0; + if (!bKeyPressed && !gDTMF_InputMode) { // menu key released + const bool bFlag = !gInputBoxIndex; + gInputBoxIndex = 0; - if (bFlag) { - if (gScanStateDir != SCAN_OFF) { - CHFRSCANNER_Stop(); - return; - } + if (bFlag) { + if (gScanStateDir != SCAN_OFF) { + CHFRSCANNER_Stop(); + return; + } - gFlagRefreshSetting = true; - gRequestDisplayScreen = DISPLAY_MENU; - #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_MENU; - #endif - } - else { - gRequestDisplayScreen = DISPLAY_MAIN; - } - } + gFlagRefreshSetting = true; + gRequestDisplayScreen = DISPLAY_MENU; + #ifdef ENABLE_VOICE + gAnotherVoiceID = VOICE_ID_MENU; + #endif + } + else { + gRequestDisplayScreen = DISPLAY_MAIN; + } + } } static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld) { - if (gCurrentFunction == FUNCTION_TRANSMIT) - return; - - if (gInputBoxIndex) { - if (!bKeyHeld && bKeyPressed) - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + if (gCurrentFunction == FUNCTION_TRANSMIT) + return; + + if (gInputBoxIndex) { + if (!bKeyHeld && bKeyPressed) + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } - if (bKeyHeld && !gWasFKeyPressed){ // long press - if (!bKeyPressed) // released - return; + if (bKeyHeld && !gWasFKeyPressed){ // long press + if (!bKeyPressed) // released + return; - ACTION_Scan(false);// toggle scanning + ACTION_Scan(false);// toggle scanning - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - return; - } + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + return; + } - if (bKeyPressed) { // just pressed - return; - } - - // just released - - if (!gWasFKeyPressed) // pressed without the F-key - { - if (gScanStateDir == SCAN_OFF + if (bKeyPressed) { // just pressed + return; + } + + // just released + + if (!gWasFKeyPressed) // pressed without the F-key + { + if (gScanStateDir == SCAN_OFF #ifdef ENABLE_NOAA - && !IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE) + && !IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE) #endif #ifdef ENABLE_SCAN_RANGES - && gScanRangeStart == 0 -#endif - ) - { // start entering a DTMF string - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - memcpy(gDTMF_InputBox, gDTMF_String, MIN(sizeof(gDTMF_InputBox), sizeof(gDTMF_String) - 1)); - gDTMF_InputBox_Index = 0; - gDTMF_InputMode = true; + && gScanRangeStart == 0 +#endif + ) + { // start entering a DTMF string + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + memcpy(gDTMF_InputBox, gDTMF_String, MIN(sizeof(gDTMF_InputBox), sizeof(gDTMF_String) - 1)); + gDTMF_InputBox_Index = 0; + gDTMF_InputMode = true; - gKeyInputCountdown = key_input_timeout_500ms; + gKeyInputCountdown = key_input_timeout_500ms; - gRequestDisplayScreen = DISPLAY_MAIN; - } - else - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - } - else - { // with the F-key - gWasFKeyPressed = false; + gRequestDisplayScreen = DISPLAY_MAIN; + } + else + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + } + else + { // with the F-key + gWasFKeyPressed = false; #ifdef ENABLE_NOAA - if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE)) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } #endif - // scan the CTCSS/DCS code - 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; Fixed issue #138 - gUpdateStatus = true; + // scan the CTCSS/DCS code + 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; Fixed issue #138 + gUpdateStatus = true; } static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction) { #ifdef ENABLE_FEAT_F4HWN // Set Squelch F + UP or Down - if(gWasFKeyPressed) { - switch(Direction) - { - case 1: - processFKeyFunction(KEY_UP, false); - break; - case -1: - processFKeyFunction(KEY_DOWN, false); - break; - } - return; - } + if(gWasFKeyPressed) { + switch(Direction) + { + case 1: + processFKeyFunction(KEY_UP, false); + break; + case -1: + processFKeyFunction(KEY_DOWN, false); + break; + } + return; + } #endif - uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO]; + uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO]; - if (bKeyHeld || !bKeyPressed) { // key held or released - if (gInputBoxIndex > 0) - return; // leave if input box active + if (bKeyHeld || !bKeyPressed) { // key held or released + if (gInputBoxIndex > 0) + return; // leave if input box active - if (!bKeyPressed) { - if (!bKeyHeld || IS_FREQ_CHANNEL(Channel)) - return; - // if released long button press and not in freq mode + if (!bKeyPressed) { + if (!bKeyHeld || IS_FREQ_CHANNEL(Channel)) + return; + // if released long button press and not in freq mode #ifdef ENABLE_VOICE - AUDIO_SetDigitVoice(0, gTxVfo->CHANNEL_SAVE + 1); // say channel number - gAnotherVoiceID = (VOICE_ID_t)0xFE; + AUDIO_SetDigitVoice(0, gTxVfo->CHANNEL_SAVE + 1); // say channel number + gAnotherVoiceID = (VOICE_ID_t)0xFE; #endif - return; - } - } - else { // short pressed - if (gInputBoxIndex > 0) { - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - } + return; + } + } + else { // short pressed + if (gInputBoxIndex > 0) { + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + } - if (gScanStateDir == SCAN_OFF) { + if (gScanStateDir == SCAN_OFF) { #ifdef ENABLE_NOAA - if (!IS_NOAA_CHANNEL(Channel)) + if (!IS_NOAA_CHANNEL(Channel)) #endif - { - uint8_t Next; - if (IS_FREQ_CHANNEL(Channel)) { // step/down in frequency - const uint32_t frequency = APP_SetFrequencyByStep(gTxVfo, Direction); + { + uint8_t Next; + if (IS_FREQ_CHANNEL(Channel)) { // step/down in frequency + const uint32_t frequency = APP_SetFrequencyByStep(gTxVfo, Direction); - if (RX_freq_check(frequency) < 0) { // frequency not allowed - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } - gTxVfo->freq_config_RX.Frequency = frequency; - BK4819_SetFrequency(frequency); - BK4819_RX_TurnOn(); - gRequestSaveChannel = 1; - return; - } + if (RX_freq_check(frequency) < 0) { // frequency not allowed + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } + gTxVfo->freq_config_RX.Frequency = frequency; + BK4819_SetFrequency(frequency); + BK4819_RX_TurnOn(); + gRequestSaveChannel = 1; + return; + } - Next = RADIO_FindNextChannel(Channel + Direction, Direction, false, 0); - if (Next == 0xFF) - return; - if (Channel == Next) - return; - gEeprom.MrChannel[gEeprom.TX_VFO] = Next; - gEeprom.ScreenChannel[gEeprom.TX_VFO] = Next; + Next = RADIO_FindNextChannel(Channel + Direction, Direction, false, 0); + if (Next == 0xFF) + return; + if (Channel == Next) + return; + gEeprom.MrChannel[gEeprom.TX_VFO] = Next; + gEeprom.ScreenChannel[gEeprom.TX_VFO] = Next; - if (!bKeyHeld) { + if (!bKeyHeld) { #ifdef ENABLE_VOICE - AUDIO_SetDigitVoice(0, Next + 1); - gAnotherVoiceID = (VOICE_ID_t)0xFE; + AUDIO_SetDigitVoice(0, Next + 1); + gAnotherVoiceID = (VOICE_ID_t)0xFE; #endif - } - } + } + } #ifdef ENABLE_NOAA - else { - 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; - } + else { + 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 - gRequestSaveVFO = true; - gVfoConfigureMode = VFO_CONFIGURE_RELOAD; - return; - } + gRequestSaveVFO = true; + gVfoConfigureMode = VFO_CONFIGURE_RELOAD; + return; + } - // jump to the next channel - CHFRSCANNER_Start(false, Direction); - gScanPauseDelayIn_10ms = 1; - gScheduleScanListen = false; + // jump to the next channel + CHFRSCANNER_Start(false, Direction); + gScanPauseDelayIn_10ms = 1; + gScheduleScanListen = false; - gPttWasReleased = true; + gPttWasReleased = true; } void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { #ifdef ENABLE_FMRADIO - if (gFmRadioMode && Key != KEY_PTT && Key != KEY_EXIT) { - if (!bKeyHeld && bKeyPressed) - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - return; - } + if (gFmRadioMode && Key != KEY_PTT && Key != KEY_EXIT) { + if (!bKeyHeld && bKeyPressed) + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } #endif - if (gDTMF_InputMode && bKeyPressed && !bKeyHeld) { - const char Character = DTMF_GetCharacter(Key); - if (Character != 0xFF) - { // add key to DTMF string - DTMF_Append(Character); - gKeyInputCountdown = key_input_timeout_500ms; - gRequestDisplayScreen = DISPLAY_MAIN; - gPttWasReleased = true; - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - return; - } - } + if (gDTMF_InputMode && bKeyPressed && !bKeyHeld) { + const char Character = DTMF_GetCharacter(Key); + if (Character != 0xFF) + { // add key to DTMF string + DTMF_Append(Character); + gKeyInputCountdown = key_input_timeout_500ms; + gRequestDisplayScreen = DISPLAY_MAIN; + gPttWasReleased = true; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + return; + } + } - // TODO: ??? -// if (Key > KEY_PTT) -// { -// Key = KEY_SIDE2; // what's this doing ??? -// } + // TODO: ??? +// if (Key > KEY_PTT) +// { +// Key = KEY_SIDE2; // what's this doing ??? +// } - switch (Key) { + switch (Key) { #ifdef ENABLE_FEAT_F4HWN - case KEY_SIDE1: - case KEY_SIDE2: + case KEY_SIDE1: + case KEY_SIDE2: #endif - case KEY_0...KEY_9: - MAIN_Key_DIGITS(Key, bKeyPressed, bKeyHeld); - break; - case KEY_MENU: - MAIN_Key_MENU(bKeyPressed, bKeyHeld); - break; - case KEY_UP: - MAIN_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1); - break; - case KEY_DOWN: - MAIN_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1); - break; - case KEY_EXIT: - MAIN_Key_EXIT(bKeyPressed, bKeyHeld); - break; - case KEY_STAR: - MAIN_Key_STAR(bKeyPressed, bKeyHeld); - break; - case KEY_F: - GENERIC_Key_F(bKeyPressed, bKeyHeld); - break; - case KEY_PTT: - GENERIC_Key_PTT(bKeyPressed); - break; - default: - if (!bKeyHeld && bKeyPressed) - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; - break; - } + case KEY_0...KEY_9: + MAIN_Key_DIGITS(Key, bKeyPressed, bKeyHeld); + break; + case KEY_MENU: + MAIN_Key_MENU(bKeyPressed, bKeyHeld); + break; + case KEY_UP: + MAIN_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1); + break; + case KEY_DOWN: + MAIN_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1); + break; + case KEY_EXIT: + MAIN_Key_EXIT(bKeyPressed, bKeyHeld); + break; + case KEY_STAR: + MAIN_Key_STAR(bKeyPressed, bKeyHeld); + break; + case KEY_F: + GENERIC_Key_F(bKeyPressed, bKeyHeld); + break; + case KEY_PTT: + GENERIC_Key_PTT(bKeyPressed); + break; + default: + if (!bKeyHeld && bKeyPressed) + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + break; + } } From 17d6b44327fd3da001586146bf4a3bc0d3ed29ac Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Fri, 16 Aug 2024 02:02:21 +0200 Subject: [PATCH 24/30] Add missing tab --- ui/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/main.c b/ui/main.c index 6b9d6f3..d9c1915 100644 --- a/ui/main.c +++ b/ui/main.c @@ -1089,7 +1089,7 @@ void UI_DisplayMain(void) case OUTPUT_POWER_LOW3: Level = 2; break; case OUTPUT_POWER_LOW4: Level = 2; break; case OUTPUT_POWER_LOW5: Level = 2; break; - case OUTPUT_POWER_MID: Level = 4; break; + case OUTPUT_POWER_MID: Level = 4; break; case OUTPUT_POWER_HIGH: Level = 6; break; } } From 9b4e59f77672459844ef1fe88407561b776f6823 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Fri, 16 Aug 2024 02:13:49 +0200 Subject: [PATCH 25/30] Add missing tab --- app/scanner.c | 10 +- app/spectrum.c | 2203 ++++++++++++++++++++++++++---------------------- app/spectrum.h | 139 +-- 3 files changed, 1303 insertions(+), 1049 deletions(-) diff --git a/app/scanner.c b/app/scanner.c index 2d7c523..35059eb 100644 --- a/app/scanner.c +++ b/app/scanner.c @@ -344,14 +344,14 @@ void SCANNER_Start(bool singleFreq) gScanDelay_10ms = scan_delay_10ms; gScanCssResultCode = 0xFF; gScanCssResultType = 0xFF; - scanHitCount = 0; + scanHitCount = 0; gScanUseCssResult = false; g_CxCSS_TAIL_Found = false; g_CDCSS_Lost = false; gCDCSSCodeType = 0; g_CTCSS_Lost = false; #ifdef ENABLE_VOX - g_VOX_Lost = false; + g_VOX_Lost = false; #endif g_SquelchLost = false; gScannerSaveState = SCAN_SAVE_NO_PROMPT; @@ -365,8 +365,8 @@ void SCANNER_Stop(void) gVfoConfigureMode = VFO_CONFIGURE_RELOAD; gFlagResetVfos = true; gUpdateStatus = true; - gCssBackgroundScan = false; - gScanUseCssResult = false; + gCssBackgroundScan = false; + gScanUseCssResult = false; #ifdef ENABLE_VOICE gAnotherVoiceID = VOICE_ID_CANCEL; #endif @@ -414,7 +414,7 @@ void SCANNER_TimeSlice10ms(void) BK4819_SetScanFrequency(gScanFrequency); gScanCssResultCode = 0xFF; gScanCssResultType = 0xFF; - scanHitCount = 0; + scanHitCount = 0; gScanUseCssResult = false; gScanProgressIndicator = 0; gScanCssState = SCAN_CSS_STATE_SCANNING; diff --git a/app/spectrum.c b/app/spectrum.c index 0896c76..64bd619 100644 --- a/app/spectrum.c +++ b/app/spectrum.c @@ -28,17 +28,18 @@ #include "ui/main.h" #ifdef ENABLE_FEAT_F4HWN_SCREENSHOT - #include "screenshot.h" +#include "screenshot.h" #endif #ifdef ENABLE_FEAT_F4HWN_SPECTRUM - #include "driver/eeprom.h" +#include "driver/eeprom.h" #endif -struct FrequencyBandInfo { - uint32_t lower; - uint32_t upper; - uint32_t middle; +struct FrequencyBandInfo +{ + uint32_t lower; + uint32_t upper; + uint32_t middle; }; #define F_MIN frequencyBandTable[0].lower @@ -110,36 +111,36 @@ RegisterSpec registerSpecs[] = { uint16_t statuslineUpdateTimer = 0; #ifdef ENABLE_FEAT_F4HWN_SPECTRUM - static void LoadSettings() - { +static void LoadSettings() +{ uint8_t Data[8] = {0}; // 1FF0..0x1FF7 EEPROM_ReadBuffer(0x1FF0, Data, 8); settings.scanStepIndex = ((Data[4] & 0xF0) >> 4); - if(settings.scanStepIndex > 14) + if (settings.scanStepIndex > 14) { - settings.scanStepIndex = S_STEP_25_0kHz; + settings.scanStepIndex = S_STEP_25_0kHz; } settings.stepsCount = ((Data[4] & 0x0F) & 0b1100) >> 2; - if(settings.stepsCount > 3) + if (settings.stepsCount > 3) { - settings.stepsCount = STEPS_64; + settings.stepsCount = STEPS_64; } settings.listenBw = ((Data[4] & 0x0F) & 0b0011); - if(settings.listenBw > 2) + if (settings.listenBw > 2) { - settings.listenBw = BK4819_FILTER_BW_WIDE; + settings.listenBw = BK4819_FILTER_BW_WIDE; } - } +} - static void SaveSettings() - { +static void SaveSettings() +{ uint8_t Data[8] = {0}; // 1FF0..0x1FF7 EEPROM_ReadBuffer(0x1FF0, Data, 8); @@ -147,187 +148,218 @@ uint16_t statuslineUpdateTimer = 0; Data[4] = (settings.scanStepIndex << 4) | (settings.stepsCount << 2) | settings.listenBw; EEPROM_WriteBuffer(0x1FF0, Data); - } +} #endif -static uint8_t DBm2S(int dbm) { - uint8_t i = 0; - dbm *= -1; - for (i = 0; i < ARRAY_SIZE(U8RssiMap); i++) { - if (dbm >= U8RssiMap[i]) { - return i; +static uint8_t DBm2S(int dbm) +{ + uint8_t i = 0; + dbm *= -1; + for (i = 0; i < ARRAY_SIZE(U8RssiMap); i++) + { + if (dbm >= U8RssiMap[i]) + { + return i; + } } - } - return i; + return i; } -static int Rssi2DBm(uint16_t rssi) { - return (rssi / 2) - 160 + dBmCorrTable[gRxVfo->Band]; +static int Rssi2DBm(uint16_t rssi) +{ + return (rssi / 2) - 160 + dBmCorrTable[gRxVfo->Band]; } -static uint16_t GetRegMenuValue(uint8_t st) { - RegisterSpec s = registerSpecs[st]; - return (BK4819_ReadRegister(s.num) >> s.offset) & s.mask; +static uint16_t GetRegMenuValue(uint8_t st) +{ + RegisterSpec s = registerSpecs[st]; + return (BK4819_ReadRegister(s.num) >> s.offset) & s.mask; } void LockAGC() { - RADIO_SetupAGC(settings.modulationType==MODULATION_AM, lockAGC); - lockAGC = true; + RADIO_SetupAGC(settings.modulationType == MODULATION_AM, lockAGC); + lockAGC = true; } -static void SetRegMenuValue(uint8_t st, bool add) { - uint16_t v = GetRegMenuValue(st); - RegisterSpec s = registerSpecs[st]; +static void SetRegMenuValue(uint8_t st, bool add) +{ + uint16_t v = GetRegMenuValue(st); + RegisterSpec s = registerSpecs[st]; - if(s.num == BK4819_REG_13) - LockAGC(); + if (s.num == BK4819_REG_13) + LockAGC(); - uint16_t reg = BK4819_ReadRegister(s.num); - if (add && v <= s.mask - s.inc) { - v += s.inc; - } else if (!add && v >= 0 + s.inc) { - v -= s.inc; - } - // TODO: use max value for bits count in max value, or reset by additional - // mask in spec - reg &= ~(s.mask << s.offset); - BK4819_WriteRegister(s.num, reg | (v << s.offset)); - redrawScreen = true; + uint16_t reg = BK4819_ReadRegister(s.num); + if (add && v <= s.mask - s.inc) + { + v += s.inc; + } + else if (!add && v >= 0 + s.inc) + { + v -= s.inc; + } + // TODO: use max value for bits count in max value, or reset by additional + // mask in spec + reg &= ~(s.mask << s.offset); + BK4819_WriteRegister(s.num, reg | (v << s.offset)); + redrawScreen = true; } // GUI functions #ifndef ENABLE_FEAT_F4HWN - static void PutPixel(uint8_t x, uint8_t y, bool fill) { +static void PutPixel(uint8_t x, uint8_t y, bool fill) +{ UI_DrawPixelBuffer(gFrameBuffer, x, y, fill); - } - static void PutPixelStatus(uint8_t x, uint8_t y, bool fill) { +} +static void PutPixelStatus(uint8_t x, uint8_t y, bool fill) +{ UI_DrawPixelBuffer(&gStatusLine, x, y, fill); - } +} #endif -static void DrawVLine(int sy, int ey, int nx, bool fill) { - for (int i = sy; i <= ey; i++) { - if (i < 56 && nx < 128) { - PutPixel(nx, i, fill); +static void DrawVLine(int sy, int ey, int nx, bool fill) +{ + for (int i = sy; i <= ey; i++) + { + if (i < 56 && nx < 128) + { + PutPixel(nx, i, fill); + } } - } } #ifndef ENABLE_FEAT_F4HWN - static void GUI_DisplaySmallest(const char *pString, uint8_t x, uint8_t y, - bool statusbar, bool fill) { +static void GUI_DisplaySmallest(const char *pString, uint8_t x, uint8_t y, + bool statusbar, bool fill) +{ uint8_t c; uint8_t pixels; const uint8_t *p = (const uint8_t *)pString; - while ((c = *p++) && c != '\0') { - c -= 0x20; - for (int i = 0; i < 3; ++i) { - pixels = gFont3x5[c][i]; - for (int j = 0; j < 6; ++j) { - if (pixels & 1) { - if (statusbar) - PutPixelStatus(x + i, y + j, fill); - else - PutPixel(x + i, y + j, fill); - } - pixels >>= 1; + while ((c = *p++) && c != '\0') + { + c -= 0x20; + for (int i = 0; i < 3; ++i) + { + pixels = gFont3x5[c][i]; + for (int j = 0; j < 6; ++j) + { + if (pixels & 1) + { + if (statusbar) + PutPixelStatus(x + i, y + j, fill); + else + PutPixel(x + i, y + j, fill); + } + pixels >>= 1; + } } - } - x += 4; + x += 4; } - } +} #endif // Utility functions -KEY_Code_t GetKey() { - KEY_Code_t btn = KEYBOARD_Poll(); - if (btn == KEY_INVALID && !GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT)) { - btn = KEY_PTT; - } - return btn; +KEY_Code_t GetKey() +{ + KEY_Code_t btn = KEYBOARD_Poll(); + if (btn == KEY_INVALID && !GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT)) + { + btn = KEY_PTT; + } + return btn; } -static int clamp(int v, int min, int max) { - return v <= min ? min : (v >= max ? max : v); +static int clamp(int v, int min, int max) +{ + return v <= min ? min : (v >= max ? max : v); } static uint8_t my_abs(signed v) { return v > 0 ? v : -v; } -void SetState(State state) { - previousState = currentState; - currentState = state; - redrawScreen = true; - redrawStatus = true; +void SetState(State state) +{ + previousState = currentState; + currentState = state; + redrawScreen = true; + redrawStatus = true; } // Radio functions -static void ToggleAFBit(bool on) { - uint16_t reg = BK4819_ReadRegister(BK4819_REG_47); - reg &= ~(1 << 8); - if (on) - reg |= on << 8; - BK4819_WriteRegister(BK4819_REG_47, reg); +static void ToggleAFBit(bool on) +{ + uint16_t reg = BK4819_ReadRegister(BK4819_REG_47); + reg &= ~(1 << 8); + if (on) + reg |= on << 8; + BK4819_WriteRegister(BK4819_REG_47, reg); } -static const BK4819_REGISTER_t registers_to_save[] ={ - BK4819_REG_30, - BK4819_REG_37, - BK4819_REG_3D, - BK4819_REG_43, - BK4819_REG_47, - BK4819_REG_48, - BK4819_REG_7E, +static const BK4819_REGISTER_t registers_to_save[] = { + BK4819_REG_30, + BK4819_REG_37, + BK4819_REG_3D, + BK4819_REG_43, + BK4819_REG_47, + BK4819_REG_48, + BK4819_REG_7E, }; -static uint16_t registers_stack [sizeof(registers_to_save)]; +static uint16_t registers_stack[sizeof(registers_to_save)]; -static void BackupRegisters() { - for (uint32_t i = 0; i < ARRAY_SIZE(registers_to_save); i++){ - registers_stack[i] = BK4819_ReadRegister(registers_to_save[i]); - } +static void BackupRegisters() +{ + for (uint32_t i = 0; i < ARRAY_SIZE(registers_to_save); i++) + { + registers_stack[i] = BK4819_ReadRegister(registers_to_save[i]); + } } -static void RestoreRegisters() { +static void RestoreRegisters() +{ - for (uint32_t i = 0; i < ARRAY_SIZE(registers_to_save); i++){ - BK4819_WriteRegister(registers_to_save[i], registers_stack[i]); - } + for (uint32_t i = 0; i < ARRAY_SIZE(registers_to_save); i++) + { + BK4819_WriteRegister(registers_to_save[i], registers_stack[i]); + } #ifdef ENABLE_FEAT_F4HWN - gVfoConfigureMode = VFO_CONFIGURE; + gVfoConfigureMode = VFO_CONFIGURE; #endif } -static void ToggleAFDAC(bool on) { - uint32_t Reg = BK4819_ReadRegister(BK4819_REG_30); - Reg &= ~(1 << 9); - if (on) - Reg |= (1 << 9); - BK4819_WriteRegister(BK4819_REG_30, Reg); +static void ToggleAFDAC(bool on) +{ + uint32_t Reg = BK4819_ReadRegister(BK4819_REG_30); + Reg &= ~(1 << 9); + if (on) + Reg |= (1 << 9); + BK4819_WriteRegister(BK4819_REG_30, Reg); } -static void SetF(uint32_t f) { - fMeasure = f; +static void SetF(uint32_t f) +{ + fMeasure = f; - BK4819_SetFrequency(fMeasure); - BK4819_PickRXFilterPathBasedOnFrequency(fMeasure); - uint16_t reg = BK4819_ReadRegister(BK4819_REG_30); - BK4819_WriteRegister(BK4819_REG_30, 0); - BK4819_WriteRegister(BK4819_REG_30, reg); + BK4819_SetFrequency(fMeasure); + BK4819_PickRXFilterPathBasedOnFrequency(fMeasure); + uint16_t reg = BK4819_ReadRegister(BK4819_REG_30); + BK4819_WriteRegister(BK4819_REG_30, 0); + BK4819_WriteRegister(BK4819_REG_30, reg); } // Spectrum related bool IsPeakOverLevel() { return peak.rssi >= settings.rssiTriggerLevel; } -static void ResetPeak() { - peak.t = 0; - peak.rssi = 0; +static void ResetPeak() +{ + peak.t = 0; + peak.rssi = 0; } bool IsCenterMode() { return settings.scanStepIndex < S_STEP_2_5kHz; } @@ -337,1068 +369,1261 @@ uint16_t GetScanStep() { return scanStepValues[settings.scanStepIndex]; } uint16_t GetStepsCount() { #ifdef ENABLE_SCAN_RANGES - if(gScanRangeStart) { - return (gScanRangeStop - gScanRangeStart) / GetScanStep(); - } + if (gScanRangeStart) + { + return (gScanRangeStop - gScanRangeStart) / GetScanStep(); + } #endif - return 128 >> settings.stepsCount; + return 128 >> settings.stepsCount; } uint32_t GetBW() { return GetStepsCount() * GetScanStep(); } -uint32_t GetFStart() { - return IsCenterMode() ? currentFreq - (GetBW() >> 1) : currentFreq; +uint32_t GetFStart() +{ + return IsCenterMode() ? currentFreq - (GetBW() >> 1) : currentFreq; } uint32_t GetFEnd() { return currentFreq + GetBW(); } -static void TuneToPeak() { - scanInfo.f = peak.f; - scanInfo.rssi = peak.rssi; - scanInfo.i = peak.i; - SetF(scanInfo.f); +static void TuneToPeak() +{ + scanInfo.f = peak.f; + scanInfo.rssi = peak.rssi; + scanInfo.i = peak.i; + SetF(scanInfo.f); } -static void DeInitSpectrum() { - SetF(initialFreq); - RestoreRegisters(); - isInitialized = false; +static void DeInitSpectrum() +{ + SetF(initialFreq); + RestoreRegisters(); + isInitialized = false; } -uint8_t GetBWRegValueForScan() { - return scanStepBWRegValues[settings.scanStepIndex]; +uint8_t GetBWRegValueForScan() +{ + return scanStepBWRegValues[settings.scanStepIndex]; } -uint16_t GetRssi() { - // SYSTICK_DelayUs(800); - // testing autodelay based on Glitch value - while ((BK4819_ReadRegister(0x63) & 0b11111111) >= 255) { - SYSTICK_DelayUs(100); - } - uint16_t rssi = BK4819_GetRSSI(); +uint16_t GetRssi() +{ + // SYSTICK_DelayUs(800); + // testing autodelay based on Glitch value + while ((BK4819_ReadRegister(0x63) & 0b11111111) >= 255) + { + SYSTICK_DelayUs(100); + } + uint16_t rssi = BK4819_GetRSSI(); #ifdef ENABLE_AM_FIX - if(settings.modulationType==MODULATION_AM && gSetting_AM_fix) - rssi += AM_fix_get_gain_diff()*2; + if (settings.modulationType == MODULATION_AM && gSetting_AM_fix) + rssi += AM_fix_get_gain_diff() * 2; #endif - return rssi; + return rssi; } -static void ToggleAudio(bool on) { - if (on == audioState) { - return; - } - audioState = on; - if (on) { - AUDIO_AudioPathOn(); - } else { - AUDIO_AudioPathOff(); - } +static void ToggleAudio(bool on) +{ + if (on == audioState) + { + return; + } + audioState = on; + if (on) + { + AUDIO_AudioPathOn(); + } + else + { + AUDIO_AudioPathOff(); + } } -static void ToggleRX(bool on) { - isListening = on; +static void ToggleRX(bool on) +{ + isListening = on; - RADIO_SetupAGC(on, lockAGC); - BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, on); + RADIO_SetupAGC(on, lockAGC); + BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, on); - ToggleAudio(on); - ToggleAFDAC(on); - ToggleAFBit(on); + ToggleAudio(on); + ToggleAFDAC(on); + ToggleAFBit(on); - if (on) { - listenT = 1000; - BK4819_WriteRegister(0x43, listenBWRegValues[settings.listenBw]); - } else { - BK4819_WriteRegister(0x43, GetBWRegValueForScan()); - } + if (on) + { + listenT = 1000; + BK4819_WriteRegister(0x43, listenBWRegValues[settings.listenBw]); + } + else + { + BK4819_WriteRegister(0x43, GetBWRegValueForScan()); + } } // Scan info -static void ResetScanStats() { - scanInfo.rssi = 0; - scanInfo.rssiMax = 0; - scanInfo.iPeak = 0; - scanInfo.fPeak = 0; +static void ResetScanStats() +{ + scanInfo.rssi = 0; + scanInfo.rssiMax = 0; + scanInfo.iPeak = 0; + scanInfo.fPeak = 0; } -static void InitScan() { - ResetScanStats(); - scanInfo.i = 0; - scanInfo.f = GetFStart(); +static void InitScan() +{ + ResetScanStats(); + scanInfo.i = 0; + scanInfo.f = GetFStart(); - scanInfo.scanStep = GetScanStep(); - scanInfo.measurementsCount = GetStepsCount(); + scanInfo.scanStep = GetScanStep(); + scanInfo.measurementsCount = GetStepsCount(); } -static void ResetBlacklist() { - for (int i = 0; i < 128; ++i) { - if (rssiHistory[i] == RSSI_MAX_VALUE) - rssiHistory[i] = 0; - } +static void ResetBlacklist() +{ + for (int i = 0; i < 128; ++i) + { + if (rssiHistory[i] == RSSI_MAX_VALUE) + rssiHistory[i] = 0; + } #ifdef ENABLE_SCAN_RANGES - memset(blacklistFreqs, 0, sizeof(blacklistFreqs)); - blacklistFreqsIdx = 0; + memset(blacklistFreqs, 0, sizeof(blacklistFreqs)); + blacklistFreqsIdx = 0; #endif } -static void RelaunchScan() { - InitScan(); - ResetPeak(); - ToggleRX(false); +static void RelaunchScan() +{ + InitScan(); + ResetPeak(); + ToggleRX(false); #ifdef SPECTRUM_AUTOMATIC_SQUELCH - settings.rssiTriggerLevel = RSSI_MAX_VALUE; + settings.rssiTriggerLevel = RSSI_MAX_VALUE; #endif - preventKeypress = true; - scanInfo.rssiMin = RSSI_MAX_VALUE; + preventKeypress = true; + scanInfo.rssiMin = RSSI_MAX_VALUE; } -static void UpdateScanInfo() { - if (scanInfo.rssi > scanInfo.rssiMax) { - scanInfo.rssiMax = scanInfo.rssi; - scanInfo.fPeak = scanInfo.f; - scanInfo.iPeak = scanInfo.i; - } +static void UpdateScanInfo() +{ + if (scanInfo.rssi > scanInfo.rssiMax) + { + scanInfo.rssiMax = scanInfo.rssi; + scanInfo.fPeak = scanInfo.f; + scanInfo.iPeak = scanInfo.i; + } - if (scanInfo.rssi < scanInfo.rssiMin) { - scanInfo.rssiMin = scanInfo.rssi; - settings.dbMin = Rssi2DBm(scanInfo.rssiMin); - redrawStatus = true; - } + if (scanInfo.rssi < scanInfo.rssiMin) + { + scanInfo.rssiMin = scanInfo.rssi; + settings.dbMin = Rssi2DBm(scanInfo.rssiMin); + redrawStatus = true; + } } -static void AutoTriggerLevel() { - if (settings.rssiTriggerLevel == RSSI_MAX_VALUE) { - settings.rssiTriggerLevel = clamp(scanInfo.rssiMax + 8, 0, RSSI_MAX_VALUE); - } +static void AutoTriggerLevel() +{ + if (settings.rssiTriggerLevel == RSSI_MAX_VALUE) + { + settings.rssiTriggerLevel = clamp(scanInfo.rssiMax + 8, 0, RSSI_MAX_VALUE); + } } -static void UpdatePeakInfoForce() { - peak.t = 0; - peak.rssi = scanInfo.rssiMax; - peak.f = scanInfo.fPeak; - peak.i = scanInfo.iPeak; - AutoTriggerLevel(); +static void UpdatePeakInfoForce() +{ + peak.t = 0; + peak.rssi = scanInfo.rssiMax; + peak.f = scanInfo.fPeak; + peak.i = scanInfo.iPeak; + AutoTriggerLevel(); } -static void UpdatePeakInfo() { - if (peak.f == 0 || peak.t >= 1024 || peak.rssi < scanInfo.rssiMax) - UpdatePeakInfoForce(); +static void UpdatePeakInfo() +{ + if (peak.f == 0 || peak.t >= 1024 || peak.rssi < scanInfo.rssiMax) + UpdatePeakInfoForce(); } static void SetRssiHistory(uint16_t idx, uint16_t rssi) { #ifdef ENABLE_SCAN_RANGES - if(scanInfo.measurementsCount > 128) { - uint8_t i = (uint32_t)ARRAY_SIZE(rssiHistory) * 1000 / scanInfo.measurementsCount * idx / 1000; - if(rssiHistory[i] < rssi || isListening) - rssiHistory[i] = rssi; - rssiHistory[(i+1)%128] = 0; - return; - } + if (scanInfo.measurementsCount > 128) + { + uint8_t i = (uint32_t)ARRAY_SIZE(rssiHistory) * 1000 / scanInfo.measurementsCount * idx / 1000; + if (rssiHistory[i] < rssi || isListening) + rssiHistory[i] = rssi; + rssiHistory[(i + 1) % 128] = 0; + return; + } #endif - rssiHistory[idx] = rssi; + rssiHistory[idx] = rssi; } static void Measure() { - uint16_t rssi = scanInfo.rssi = GetRssi(); - SetRssiHistory(scanInfo.i, rssi); + uint16_t rssi = scanInfo.rssi = GetRssi(); + SetRssiHistory(scanInfo.i, rssi); } // Update things by keypress -static uint16_t dbm2rssi(int dBm) { - return (dBm + 160 - dBmCorrTable[gRxVfo->Band]) * 2; +static uint16_t dbm2rssi(int dBm) +{ + return (dBm + 160 - dBmCorrTable[gRxVfo->Band]) * 2; } -static void ClampRssiTriggerLevel() { - settings.rssiTriggerLevel = - clamp(settings.rssiTriggerLevel, dbm2rssi(settings.dbMin), - dbm2rssi(settings.dbMax)); +static void ClampRssiTriggerLevel() +{ + settings.rssiTriggerLevel = + clamp(settings.rssiTriggerLevel, dbm2rssi(settings.dbMin), + dbm2rssi(settings.dbMax)); } -static void UpdateRssiTriggerLevel(bool inc) { - if (inc) - settings.rssiTriggerLevel += 2; - else - settings.rssiTriggerLevel -= 2; +static void UpdateRssiTriggerLevel(bool inc) +{ + if (inc) + settings.rssiTriggerLevel += 2; + else + settings.rssiTriggerLevel -= 2; - ClampRssiTriggerLevel(); + ClampRssiTriggerLevel(); - redrawScreen = true; - redrawStatus = true; + redrawScreen = true; + redrawStatus = true; } -static void UpdateDBMax(bool inc) { - if (inc && settings.dbMax < 10) { - settings.dbMax += 1; - } else if (!inc && settings.dbMax > settings.dbMin) { - settings.dbMax -= 1; - } else { - return; - } +static void UpdateDBMax(bool inc) +{ + if (inc && settings.dbMax < 10) + { + settings.dbMax += 1; + } + else if (!inc && settings.dbMax > settings.dbMin) + { + settings.dbMax -= 1; + } + else + { + return; + } - ClampRssiTriggerLevel(); - redrawStatus = true; - redrawScreen = true; - SYSTEM_DelayMs(20); + ClampRssiTriggerLevel(); + redrawStatus = true; + redrawScreen = true; + SYSTEM_DelayMs(20); } -static void UpdateScanStep(bool inc) { - if (inc) { - settings.scanStepIndex = settings.scanStepIndex != S_STEP_100_0kHz ? settings.scanStepIndex + 1 : 0; - } else { - settings.scanStepIndex = settings.scanStepIndex != 0 ? settings.scanStepIndex - 1 : S_STEP_100_0kHz; - } +static void UpdateScanStep(bool inc) +{ + if (inc) + { + settings.scanStepIndex = settings.scanStepIndex != S_STEP_100_0kHz ? settings.scanStepIndex + 1 : 0; + } + else + { + settings.scanStepIndex = settings.scanStepIndex != 0 ? settings.scanStepIndex - 1 : S_STEP_100_0kHz; + } - settings.frequencyChangeStep = GetBW() >> 1; - RelaunchScan(); - ResetBlacklist(); - redrawScreen = true; + settings.frequencyChangeStep = GetBW() >> 1; + RelaunchScan(); + ResetBlacklist(); + redrawScreen = true; } -static void UpdateCurrentFreq(bool inc) { - if (inc && currentFreq < F_MAX) { - currentFreq += settings.frequencyChangeStep; - } else if (!inc && currentFreq > F_MIN) { - currentFreq -= settings.frequencyChangeStep; - } else { - return; - } - RelaunchScan(); - ResetBlacklist(); - redrawScreen = true; +static void UpdateCurrentFreq(bool inc) +{ + if (inc && currentFreq < F_MAX) + { + currentFreq += settings.frequencyChangeStep; + } + else if (!inc && currentFreq > F_MIN) + { + currentFreq -= settings.frequencyChangeStep; + } + else + { + return; + } + RelaunchScan(); + ResetBlacklist(); + redrawScreen = true; } -static void UpdateCurrentFreqStill(bool inc) { - uint8_t offset = modulationTypeTuneSteps[settings.modulationType]; - uint32_t f = fMeasure; - if (inc && f < F_MAX) { - f += offset; - } else if (!inc && f > F_MIN) { - f -= offset; - } - SetF(f); - redrawScreen = true; +static void UpdateCurrentFreqStill(bool inc) +{ + uint8_t offset = modulationTypeTuneSteps[settings.modulationType]; + uint32_t f = fMeasure; + if (inc && f < F_MAX) + { + f += offset; + } + else if (!inc && f > F_MIN) + { + f -= offset; + } + SetF(f); + redrawScreen = true; } -static void UpdateFreqChangeStep(bool inc) { - uint16_t diff = GetScanStep() * 4; - if (inc && settings.frequencyChangeStep < 200000) { - settings.frequencyChangeStep += diff; - } else if (!inc && settings.frequencyChangeStep > 10000) { - settings.frequencyChangeStep -= diff; - } - SYSTEM_DelayMs(100); - redrawScreen = true; +static void UpdateFreqChangeStep(bool inc) +{ + uint16_t diff = GetScanStep() * 4; + if (inc && settings.frequencyChangeStep < 200000) + { + settings.frequencyChangeStep += diff; + } + else if (!inc && settings.frequencyChangeStep > 10000) + { + settings.frequencyChangeStep -= diff; + } + SYSTEM_DelayMs(100); + redrawScreen = true; } -static void ToggleModulation() { - if (settings.modulationType < MODULATION_UKNOWN - 1) { - settings.modulationType++; - } else { - settings.modulationType = MODULATION_FM; - } - RADIO_SetModulation(settings.modulationType); +static void ToggleModulation() +{ + if (settings.modulationType < MODULATION_UKNOWN - 1) + { + settings.modulationType++; + } + else + { + settings.modulationType = MODULATION_FM; + } + RADIO_SetModulation(settings.modulationType); - RelaunchScan(); - redrawScreen = true; + RelaunchScan(); + redrawScreen = true; } -static void ToggleListeningBW() { - if (settings.listenBw == BK4819_FILTER_BW_NARROWER) { - settings.listenBw = BK4819_FILTER_BW_WIDE; - } else { - settings.listenBw++; - } - redrawScreen = true; +static void ToggleListeningBW() +{ + if (settings.listenBw == BK4819_FILTER_BW_NARROWER) + { + settings.listenBw = BK4819_FILTER_BW_WIDE; + } + else + { + settings.listenBw++; + } + redrawScreen = true; } -static void ToggleBacklight() { - settings.backlightState = !settings.backlightState; - if (settings.backlightState) { - BACKLIGHT_TurnOn(); - } else { - BACKLIGHT_TurnOff(); - } - // For screenshot - #ifdef ENABLE_FEAT_F4HWN_SCREENSHOT +static void ToggleBacklight() +{ + settings.backlightState = !settings.backlightState; + if (settings.backlightState) + { + BACKLIGHT_TurnOn(); + } + else + { + BACKLIGHT_TurnOff(); + } +// For screenshot +#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT getScreenShot(); - #endif +#endif } -static void ToggleStepsCount() { - if (settings.stepsCount == STEPS_128) { - settings.stepsCount = STEPS_16; - } else { - settings.stepsCount--; - } - settings.frequencyChangeStep = GetBW() >> 1; - RelaunchScan(); - ResetBlacklist(); - redrawScreen = true; -} - -static void ResetFreqInput() { - tempFreq = 0; - for (int i = 0; i < 10; ++i) { - freqInputString[i] = '-'; - } -} - -static void FreqInput() { - freqInputIndex = 0; - freqInputDotIndex = 0; - ResetFreqInput(); - SetState(FREQ_INPUT); -} - -static void UpdateFreqInput(KEY_Code_t key) { - if (key != KEY_EXIT && freqInputIndex >= 10) { - return; - } - if (key == KEY_STAR) { - if (freqInputIndex == 0 || freqInputDotIndex) { - return; +static void ToggleStepsCount() +{ + if (settings.stepsCount == STEPS_128) + { + settings.stepsCount = STEPS_16; } - freqInputDotIndex = freqInputIndex; - } - if (key == KEY_EXIT) { - freqInputIndex--; - if (freqInputDotIndex == freqInputIndex) - freqInputDotIndex = 0; - } else { - freqInputArr[freqInputIndex++] = key; - } - - ResetFreqInput(); - - uint8_t dotIndex = - freqInputDotIndex == 0 ? freqInputIndex : freqInputDotIndex; - - KEY_Code_t digitKey; - for (int i = 0; i < 10; ++i) { - if (i < freqInputIndex) { - digitKey = freqInputArr[i]; - freqInputString[i] = digitKey <= KEY_9 ? '0' + digitKey - KEY_0 : '.'; - } else { - freqInputString[i] = '-'; + else + { + settings.stepsCount--; } - } - - uint32_t base = 100000; // 1MHz in BK units - for (int i = dotIndex - 1; i >= 0; --i) { - tempFreq += (freqInputArr[i] - KEY_0) * base; - base *= 10; - } - - base = 10000; // 0.1MHz in BK units - if (dotIndex < freqInputIndex) { - for (int i = dotIndex + 1; i < freqInputIndex; ++i) { - tempFreq += (freqInputArr[i] - KEY_0) * base; - base /= 10; - } - } - redrawScreen = true; + settings.frequencyChangeStep = GetBW() >> 1; + RelaunchScan(); + ResetBlacklist(); + redrawScreen = true; } -static void Blacklist() { +static void ResetFreqInput() +{ + tempFreq = 0; + for (int i = 0; i < 10; ++i) + { + freqInputString[i] = '-'; + } +} + +static void FreqInput() +{ + freqInputIndex = 0; + freqInputDotIndex = 0; + ResetFreqInput(); + SetState(FREQ_INPUT); +} + +static void UpdateFreqInput(KEY_Code_t key) +{ + if (key != KEY_EXIT && freqInputIndex >= 10) + { + return; + } + if (key == KEY_STAR) + { + if (freqInputIndex == 0 || freqInputDotIndex) + { + return; + } + freqInputDotIndex = freqInputIndex; + } + if (key == KEY_EXIT) + { + freqInputIndex--; + if (freqInputDotIndex == freqInputIndex) + freqInputDotIndex = 0; + } + else + { + freqInputArr[freqInputIndex++] = key; + } + + ResetFreqInput(); + + uint8_t dotIndex = + freqInputDotIndex == 0 ? freqInputIndex : freqInputDotIndex; + + KEY_Code_t digitKey; + for (int i = 0; i < 10; ++i) + { + if (i < freqInputIndex) + { + digitKey = freqInputArr[i]; + freqInputString[i] = digitKey <= KEY_9 ? '0' + digitKey - KEY_0 : '.'; + } + else + { + freqInputString[i] = '-'; + } + } + + uint32_t base = 100000; // 1MHz in BK units + for (int i = dotIndex - 1; i >= 0; --i) + { + tempFreq += (freqInputArr[i] - KEY_0) * base; + base *= 10; + } + + base = 10000; // 0.1MHz in BK units + if (dotIndex < freqInputIndex) + { + for (int i = dotIndex + 1; i < freqInputIndex; ++i) + { + tempFreq += (freqInputArr[i] - KEY_0) * base; + base /= 10; + } + } + redrawScreen = true; +} + +static void Blacklist() +{ #ifdef ENABLE_SCAN_RANGES - blacklistFreqs[blacklistFreqsIdx++ % ARRAY_SIZE(blacklistFreqs)] = peak.i; + blacklistFreqs[blacklistFreqsIdx++ % ARRAY_SIZE(blacklistFreqs)] = peak.i; #endif - SetRssiHistory(peak.i, RSSI_MAX_VALUE); - ResetPeak(); - ToggleRX(false); - ResetScanStats(); + SetRssiHistory(peak.i, RSSI_MAX_VALUE); + ResetPeak(); + ToggleRX(false); + ResetScanStats(); } #ifdef ENABLE_SCAN_RANGES static bool IsBlacklisted(uint16_t idx) { - if(blacklistFreqsIdx) - for(uint8_t i = 0; i < ARRAY_SIZE(blacklistFreqs); i++) - if(blacklistFreqs[i] == idx) - return true; - return false; + if (blacklistFreqsIdx) + for (uint8_t i = 0; i < ARRAY_SIZE(blacklistFreqs); i++) + if (blacklistFreqs[i] == idx) + return true; + return false; } #endif // Draw things // applied x2 to prevent initial rounding -uint8_t Rssi2PX(uint16_t rssi, uint8_t pxMin, uint8_t pxMax) { - const int DB_MIN = settings.dbMin << 1; - const int DB_MAX = settings.dbMax << 1; - const int DB_RANGE = DB_MAX - DB_MIN; +uint8_t Rssi2PX(uint16_t rssi, uint8_t pxMin, uint8_t pxMax) +{ + const int DB_MIN = settings.dbMin << 1; + const int DB_MAX = settings.dbMax << 1; + const int DB_RANGE = DB_MAX - DB_MIN; - const uint8_t PX_RANGE = pxMax - pxMin; + const uint8_t PX_RANGE = pxMax - pxMin; - int dbm = clamp(Rssi2DBm(rssi) << 1, DB_MIN, DB_MAX); + int dbm = clamp(Rssi2DBm(rssi) << 1, DB_MIN, DB_MAX); - return ((dbm - DB_MIN) * PX_RANGE + DB_RANGE / 2) / DB_RANGE + pxMin; + return ((dbm - DB_MIN) * PX_RANGE + DB_RANGE / 2) / DB_RANGE + pxMin; } -uint8_t Rssi2Y(uint16_t rssi) { - return DrawingEndY - Rssi2PX(rssi, 0, DrawingEndY); +uint8_t Rssi2Y(uint16_t rssi) +{ + return DrawingEndY - Rssi2PX(rssi, 0, DrawingEndY); } -static void DrawSpectrum() { - for (uint8_t x = 0; x < 128; ++x) { - uint16_t rssi = rssiHistory[x >> settings.stepsCount]; - if (rssi != RSSI_MAX_VALUE) { - DrawVLine(Rssi2Y(rssi), DrawingEndY, x, true); +static void DrawSpectrum() +{ + for (uint8_t x = 0; x < 128; ++x) + { + uint16_t rssi = rssiHistory[x >> settings.stepsCount]; + if (rssi != RSSI_MAX_VALUE) + { + DrawVLine(Rssi2Y(rssi), DrawingEndY, x, true); + } } - } } -static void DrawStatus() { +static void DrawStatus() +{ #ifdef SPECTRUM_EXTRA_VALUES - sprintf(String, "%d/%d P:%d T:%d", settings.dbMin, settings.dbMax, - Rssi2DBm(peak.rssi), Rssi2DBm(settings.rssiTriggerLevel)); + sprintf(String, "%d/%d P:%d T:%d", settings.dbMin, settings.dbMax, + Rssi2DBm(peak.rssi), Rssi2DBm(settings.rssiTriggerLevel)); #else - sprintf(String, "%d/%d", settings.dbMin, settings.dbMax); + sprintf(String, "%d/%d", settings.dbMin, settings.dbMax); #endif - GUI_DisplaySmallest(String, 0, 1, true, true); + GUI_DisplaySmallest(String, 0, 1, true, true); - BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryCheckCounter++ % 4], - &gBatteryCurrent); + BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryCheckCounter++ % 4], + &gBatteryCurrent); - uint16_t voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + - gBatteryVoltages[2] + gBatteryVoltages[3]) / - 4 * 760 / gBatteryCalibration[3]; + uint16_t voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + + gBatteryVoltages[2] + gBatteryVoltages[3]) / + 4 * 760 / gBatteryCalibration[3]; - unsigned perc = BATTERY_VoltsToPercent(voltage); + unsigned perc = BATTERY_VoltsToPercent(voltage); - // sprintf(String, "%d %d", voltage, perc); - // GUI_DisplaySmallest(String, 48, 1, true, true); + // sprintf(String, "%d %d", voltage, perc); + // GUI_DisplaySmallest(String, 48, 1, true, true); - gStatusLine[116] = 0b00011100; - gStatusLine[117] = 0b00111110; - for (int i = 118; i <= 126; i++) { - gStatusLine[i] = 0b00100010; - } - - for (unsigned i = 127; i >= 118; i--) { - if (127 - i <= (perc + 5) * 9 / 100) { - gStatusLine[i] = 0b00111110; + gStatusLine[116] = 0b00011100; + gStatusLine[117] = 0b00111110; + for (int i = 118; i <= 126; i++) + { + gStatusLine[i] = 0b00100010; + } + + for (unsigned i = 127; i >= 118; i--) + { + if (127 - i <= (perc + 5) * 9 / 100) + { + gStatusLine[i] = 0b00111110; + } } - } } #ifdef ENABLE_FEAT_F4HWN_SPECTRUM - static void ShowChannelName(uint32_t f) { +static void ShowChannelName(uint32_t f) +{ unsigned int i; memset(String, 0, sizeof(String)); - if ( isListening ) { - for (i = 0; IS_MR_CHANNEL(i); i++) { - if (RADIO_CheckValidChannel(i, false, 0)) { - if (SETTINGS_FetchChannelFrequency(i) == f) { - SETTINGS_FetchChannelName(String, i); - UI_PrintStringSmallBold(String[0] ? String : "--", 8, 127, 1); - break; - } + if (isListening) + { + for (i = 0; IS_MR_CHANNEL(i); i++) + { + if (RADIO_CheckValidChannel(i, false, 0)) + { + if (SETTINGS_FetchChannelFrequency(i) == f) + { + SETTINGS_FetchChannelName(String, i); + UI_PrintStringSmallBold(String[0] ? String : "--", 8, 127, 1); + break; + } + } } - } } - } +} #endif -static void DrawF(uint32_t f) { - sprintf(String, "%u.%05u", f / 100000, f % 100000); - UI_PrintStringSmallNormal(String, 8, 127, 0); +static void DrawF(uint32_t f) +{ + sprintf(String, "%u.%05u", f / 100000, f % 100000); + UI_PrintStringSmallNormal(String, 8, 127, 0); - sprintf(String, "%3s", gModulationStr[settings.modulationType]); - GUI_DisplaySmallest(String, 116, 1, false, true); - sprintf(String, "%4sk", bwOptions[settings.listenBw]); - GUI_DisplaySmallest(String, 108, 7, false, true); + sprintf(String, "%3s", gModulationStr[settings.modulationType]); + GUI_DisplaySmallest(String, 116, 1, false, true); + sprintf(String, "%4sk", bwOptions[settings.listenBw]); + GUI_DisplaySmallest(String, 108, 7, false, true); #ifdef ENABLE_FEAT_F4HWN_SPECTRUM - ShowChannelName(f); + ShowChannelName(f); #endif } -static void DrawNums() { +static void DrawNums() +{ - if (currentState == SPECTRUM) { - sprintf(String, "%ux", GetStepsCount()); - GUI_DisplaySmallest(String, 0, 1, false, true); - sprintf(String, "%u.%02uk", GetScanStep() / 100, GetScanStep() % 100); - GUI_DisplaySmallest(String, 0, 7, false, true); - } - - if (IsCenterMode()) { - sprintf(String, "%u.%05u \x7F%u.%02uk", currentFreq / 100000, - currentFreq % 100000, settings.frequencyChangeStep / 100, - settings.frequencyChangeStep % 100); - GUI_DisplaySmallest(String, 36, 49, false, true); - } else { - sprintf(String, "%u.%05u", GetFStart() / 100000, GetFStart() % 100000); - GUI_DisplaySmallest(String, 0, 49, false, true); - - sprintf(String, "\x7F%u.%02uk", settings.frequencyChangeStep / 100, - settings.frequencyChangeStep % 100); - GUI_DisplaySmallest(String, 48, 49, false, true); - - sprintf(String, "%u.%05u", GetFEnd() / 100000, GetFEnd() % 100000); - GUI_DisplaySmallest(String, 93, 49, false, true); - } -} - -static void DrawRssiTriggerLevel() { - if (settings.rssiTriggerLevel == RSSI_MAX_VALUE || monitorMode) - return; - uint8_t y = Rssi2Y(settings.rssiTriggerLevel); - for (uint8_t x = 0; x < 128; x += 2) { - PutPixel(x, y, true); - } -} - -static void DrawTicks() { - uint32_t f = GetFStart(); - uint32_t span = GetFEnd() - GetFStart(); - uint32_t step = span / 128; - for (uint8_t i = 0; i < 128; i += (1 << settings.stepsCount)) { - f = GetFStart() + span * i / 128; - uint8_t barValue = 0b00000001; - (f % 10000) < step && (barValue |= 0b00000010); - (f % 50000) < step && (barValue |= 0b00000100); - (f % 100000) < step && (barValue |= 0b00011000); - - gFrameBuffer[5][i] |= barValue; - } - - // center - if (IsCenterMode()) { - memset(gFrameBuffer[5] + 62, 0x80, 5); - gFrameBuffer[5][64] = 0xff; - } else { - memset(gFrameBuffer[5] + 1, 0x80, 3); - memset(gFrameBuffer[5] + 124, 0x80, 3); - - gFrameBuffer[5][0] = 0xff; - gFrameBuffer[5][127] = 0xff; - } -} - -static void DrawArrow(uint8_t x) { - for (signed i = -2; i <= 2; ++i) { - signed v = x + i; - if (!(v & 128)) { - gFrameBuffer[5][v] |= (0b01111000 << my_abs(i)) & 0b01111000; + if (currentState == SPECTRUM) + { + sprintf(String, "%ux", GetStepsCount()); + GUI_DisplaySmallest(String, 0, 1, false, true); + sprintf(String, "%u.%02uk", GetScanStep() / 100, GetScanStep() % 100); + GUI_DisplaySmallest(String, 0, 7, false, true); + } + + if (IsCenterMode()) + { + sprintf(String, "%u.%05u \x7F%u.%02uk", currentFreq / 100000, + currentFreq % 100000, settings.frequencyChangeStep / 100, + settings.frequencyChangeStep % 100); + GUI_DisplaySmallest(String, 36, 49, false, true); + } + else + { + sprintf(String, "%u.%05u", GetFStart() / 100000, GetFStart() % 100000); + GUI_DisplaySmallest(String, 0, 49, false, true); + + sprintf(String, "\x7F%u.%02uk", settings.frequencyChangeStep / 100, + settings.frequencyChangeStep % 100); + GUI_DisplaySmallest(String, 48, 49, false, true); + + sprintf(String, "%u.%05u", GetFEnd() / 100000, GetFEnd() % 100000); + GUI_DisplaySmallest(String, 93, 49, false, true); } - } } -static void OnKeyDown(uint8_t key) { - switch (key) { - case KEY_3: - UpdateDBMax(true); - break; - case KEY_9: - UpdateDBMax(false); - break; - case KEY_1: - UpdateScanStep(true); - break; - case KEY_7: - UpdateScanStep(false); - break; - case KEY_2: - UpdateFreqChangeStep(true); - break; - case KEY_8: - UpdateFreqChangeStep(false); - break; - case KEY_UP: +static void DrawRssiTriggerLevel() +{ + if (settings.rssiTriggerLevel == RSSI_MAX_VALUE || monitorMode) + return; + uint8_t y = Rssi2Y(settings.rssiTriggerLevel); + for (uint8_t x = 0; x < 128; x += 2) + { + PutPixel(x, y, true); + } +} + +static void DrawTicks() +{ + uint32_t f = GetFStart(); + uint32_t span = GetFEnd() - GetFStart(); + uint32_t step = span / 128; + for (uint8_t i = 0; i < 128; i += (1 << settings.stepsCount)) + { + f = GetFStart() + span * i / 128; + uint8_t barValue = 0b00000001; + (f % 10000) < step && (barValue |= 0b00000010); + (f % 50000) < step && (barValue |= 0b00000100); + (f % 100000) < step && (barValue |= 0b00011000); + + gFrameBuffer[5][i] |= barValue; + } + + // center + if (IsCenterMode()) + { + memset(gFrameBuffer[5] + 62, 0x80, 5); + gFrameBuffer[5][64] = 0xff; + } + else + { + memset(gFrameBuffer[5] + 1, 0x80, 3); + memset(gFrameBuffer[5] + 124, 0x80, 3); + + gFrameBuffer[5][0] = 0xff; + gFrameBuffer[5][127] = 0xff; + } +} + +static void DrawArrow(uint8_t x) +{ + for (signed i = -2; i <= 2; ++i) + { + signed v = x + i; + if (!(v & 128)) + { + gFrameBuffer[5][v] |= (0b01111000 << my_abs(i)) & 0b01111000; + } + } +} + +static void OnKeyDown(uint8_t key) +{ + switch (key) + { + case KEY_3: + UpdateDBMax(true); + break; + case KEY_9: + UpdateDBMax(false); + break; + case KEY_1: + UpdateScanStep(true); + break; + case KEY_7: + UpdateScanStep(false); + break; + case KEY_2: + UpdateFreqChangeStep(true); + break; + case KEY_8: + UpdateFreqChangeStep(false); + break; + case KEY_UP: #ifdef ENABLE_SCAN_RANGES - if(!gScanRangeStart) + if (!gScanRangeStart) #endif - UpdateCurrentFreq(true); - break; - case KEY_DOWN: + UpdateCurrentFreq(true); + break; + case KEY_DOWN: #ifdef ENABLE_SCAN_RANGES - if(!gScanRangeStart) + if (!gScanRangeStart) #endif - UpdateCurrentFreq(false); - break; - case KEY_SIDE1: - Blacklist(); - break; - case KEY_STAR: - UpdateRssiTriggerLevel(true); - break; - case KEY_F: - UpdateRssiTriggerLevel(false); - break; - case KEY_5: + UpdateCurrentFreq(false); + break; + case KEY_SIDE1: + Blacklist(); + break; + case KEY_STAR: + UpdateRssiTriggerLevel(true); + break; + case KEY_F: + UpdateRssiTriggerLevel(false); + break; + case KEY_5: #ifdef ENABLE_SCAN_RANGES - if(!gScanRangeStart) + if (!gScanRangeStart) #endif - FreqInput(); - break; - case KEY_0: - ToggleModulation(); - break; - case KEY_6: - ToggleListeningBW(); - break; - case KEY_4: + FreqInput(); + break; + case KEY_0: + ToggleModulation(); + break; + case KEY_6: + ToggleListeningBW(); + break; + case KEY_4: #ifdef ENABLE_SCAN_RANGES - if(!gScanRangeStart) + if (!gScanRangeStart) #endif - ToggleStepsCount(); - break; - case KEY_SIDE2: - ToggleBacklight(); - break; - case KEY_PTT: - SetState(STILL); - TuneToPeak(); - break; - case KEY_MENU: - break; - case KEY_EXIT: - if (menuState) { - menuState = 0; - break; + ToggleStepsCount(); + break; + case KEY_SIDE2: + ToggleBacklight(); + break; + case KEY_PTT: + SetState(STILL); + TuneToPeak(); + break; + case KEY_MENU: + break; + case KEY_EXIT: + if (menuState) + { + menuState = 0; + break; + } +#ifdef ENABLE_FEAT_F4HWN_SPECTRUM + SaveSettings(); +#endif + DeInitSpectrum(); + break; + default: + break; } - #ifdef ENABLE_FEAT_F4HWN_SPECTRUM - SaveSettings(); - #endif - DeInitSpectrum(); - break; - default: - break; - } } -static void OnKeyDownFreqInput(uint8_t key) { - switch (key) { - case KEY_0: - case KEY_1: - case KEY_2: - case KEY_3: - case KEY_4: - case KEY_5: - case KEY_6: - case KEY_7: - case KEY_8: - case KEY_9: - case KEY_STAR: - UpdateFreqInput(key); - break; - case KEY_EXIT: - if (freqInputIndex == 0) { - SetState(previousState); - break; +static void OnKeyDownFreqInput(uint8_t key) +{ + switch (key) + { + case KEY_0: + case KEY_1: + case KEY_2: + case KEY_3: + case KEY_4: + case KEY_5: + case KEY_6: + case KEY_7: + case KEY_8: + case KEY_9: + case KEY_STAR: + UpdateFreqInput(key); + break; + case KEY_EXIT: + if (freqInputIndex == 0) + { + SetState(previousState); + break; + } + UpdateFreqInput(key); + break; + case KEY_MENU: + if (tempFreq < F_MIN || tempFreq > F_MAX) + { + break; + } + SetState(previousState); + currentFreq = tempFreq; + if (currentState == SPECTRUM) + { + ResetBlacklist(); + RelaunchScan(); + } + else + { + SetF(currentFreq); + } + break; + default: + break; } - UpdateFreqInput(key); - break; - case KEY_MENU: - if (tempFreq < F_MIN || tempFreq > F_MAX) { - break; - } - SetState(previousState); - currentFreq = tempFreq; - if (currentState == SPECTRUM) { - ResetBlacklist(); - RelaunchScan(); - } else { - SetF(currentFreq); - } - break; - default: - break; - } } -void OnKeyDownStill(KEY_Code_t key) { - switch (key) { - case KEY_3: - UpdateDBMax(true); - break; - case KEY_9: - UpdateDBMax(false); - break; - case KEY_UP: - if (menuState) { - SetRegMenuValue(menuState, true); - break; +void OnKeyDownStill(KEY_Code_t key) +{ + switch (key) + { + case KEY_3: + UpdateDBMax(true); + break; + case KEY_9: + UpdateDBMax(false); + break; + case KEY_UP: + if (menuState) + { + SetRegMenuValue(menuState, true); + break; + } + UpdateCurrentFreqStill(true); + break; + case KEY_DOWN: + if (menuState) + { + SetRegMenuValue(menuState, false); + break; + } + UpdateCurrentFreqStill(false); + break; + case KEY_STAR: + UpdateRssiTriggerLevel(true); + break; + case KEY_F: + UpdateRssiTriggerLevel(false); + break; + case KEY_5: + FreqInput(); + break; + case KEY_0: + ToggleModulation(); + break; + case KEY_6: + ToggleListeningBW(); + break; + case KEY_SIDE1: + monitorMode = !monitorMode; + break; + case KEY_SIDE2: + ToggleBacklight(); + break; + case KEY_PTT: + // TODO: start transmit + /* BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false); + BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); */ + break; + case KEY_MENU: + if (menuState == ARRAY_SIZE(registerSpecs) - 1) + { + menuState = 1; + } + else + { + menuState++; + } + redrawScreen = true; + break; + case KEY_EXIT: + if (!menuState) + { + SetState(SPECTRUM); + lockAGC = false; + monitorMode = false; + RelaunchScan(); + break; + } + menuState = 0; + break; + default: + break; } - UpdateCurrentFreqStill(true); - break; - case KEY_DOWN: - if (menuState) { - SetRegMenuValue(menuState, false); - break; - } - UpdateCurrentFreqStill(false); - break; - case KEY_STAR: - UpdateRssiTriggerLevel(true); - break; - case KEY_F: - UpdateRssiTriggerLevel(false); - break; - case KEY_5: - FreqInput(); - break; - case KEY_0: - ToggleModulation(); - break; - case KEY_6: - ToggleListeningBW(); - break; - case KEY_SIDE1: - monitorMode = !monitorMode; - break; - case KEY_SIDE2: - ToggleBacklight(); - break; - case KEY_PTT: - // TODO: start transmit - /* BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false); - BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); */ - break; - case KEY_MENU: - if (menuState == ARRAY_SIZE(registerSpecs) - 1) { - menuState = 1; - } else { - menuState++; - } - redrawScreen = true; - break; - case KEY_EXIT: - if (!menuState) { - SetState(SPECTRUM); - lockAGC = false; - monitorMode = false; - RelaunchScan(); - break; - } - menuState = 0; - break; - default: - break; - } } static void RenderFreqInput() { UI_PrintString(freqInputString, 2, 127, 0, 8); } -static void RenderStatus() { - memset(gStatusLine, 0, sizeof(gStatusLine)); - DrawStatus(); - ST7565_BlitStatusLine(); +static void RenderStatus() +{ + memset(gStatusLine, 0, sizeof(gStatusLine)); + DrawStatus(); + ST7565_BlitStatusLine(); } -static void RenderSpectrum() { - DrawTicks(); - DrawArrow(128u * peak.i / GetStepsCount()); - DrawSpectrum(); - DrawRssiTriggerLevel(); - DrawF(peak.f); - DrawNums(); +static void RenderSpectrum() +{ + DrawTicks(); + DrawArrow(128u * peak.i / GetStepsCount()); + DrawSpectrum(); + DrawRssiTriggerLevel(); + DrawF(peak.f); + DrawNums(); } -static void RenderStill() { - DrawF(fMeasure); +static void RenderStill() +{ + DrawF(fMeasure); - const uint8_t METER_PAD_LEFT = 3; + const uint8_t METER_PAD_LEFT = 3; - memset(&gFrameBuffer[2][METER_PAD_LEFT], 0b00010000, 121); + memset(&gFrameBuffer[2][METER_PAD_LEFT], 0b00010000, 121); - for (int i = 0; i < 121; i+=5) { - gFrameBuffer[2][i + METER_PAD_LEFT] = 0b00110000; - } - - for (int i = 0; i < 121; i+=10) { - gFrameBuffer[2][i + METER_PAD_LEFT] = 0b01110000; - } - - uint8_t x = Rssi2PX(scanInfo.rssi, 0, 121); - for (int i = 0; i < x; ++i) { - if (i % 5) { - gFrameBuffer[2][i + METER_PAD_LEFT] |= 0b00000111; + for (int i = 0; i < 121; i += 5) + { + gFrameBuffer[2][i + METER_PAD_LEFT] = 0b00110000; } - } - int dbm = Rssi2DBm(scanInfo.rssi); - uint8_t s = DBm2S(dbm); - sprintf(String, "S: %u", s); - GUI_DisplaySmallest(String, 4, 25, false, true); - sprintf(String, "%d dBm", dbm); - GUI_DisplaySmallest(String, 28, 25, false, true); - - if (!monitorMode) { - uint8_t x = Rssi2PX(settings.rssiTriggerLevel, 0, 121); - gFrameBuffer[2][METER_PAD_LEFT + x] = 0b11111111; - } - - const uint8_t PAD_LEFT = 4; - const uint8_t CELL_WIDTH = 30; - uint8_t offset = PAD_LEFT; - uint8_t row = 4; - - for (int i = 0, idx = 1; idx <= 4; ++i, ++idx) { - if (idx == 5) { - row += 2; - i = 0; + for (int i = 0; i < 121; i += 10) + { + gFrameBuffer[2][i + METER_PAD_LEFT] = 0b01110000; } - offset = PAD_LEFT + i * CELL_WIDTH; - if (menuState == idx) { - for (int j = 0; j < CELL_WIDTH; ++j) { - gFrameBuffer[row][j + offset] = 0xFF; - gFrameBuffer[row + 1][j + offset] = 0xFF; - } + + uint8_t x = Rssi2PX(scanInfo.rssi, 0, 121); + for (int i = 0; i < x; ++i) + { + if (i % 5) + { + gFrameBuffer[2][i + METER_PAD_LEFT] |= 0b00000111; + } + } + + int dbm = Rssi2DBm(scanInfo.rssi); + uint8_t s = DBm2S(dbm); + sprintf(String, "S: %u", s); + GUI_DisplaySmallest(String, 4, 25, false, true); + sprintf(String, "%d dBm", dbm); + GUI_DisplaySmallest(String, 28, 25, false, true); + + if (!monitorMode) + { + uint8_t x = Rssi2PX(settings.rssiTriggerLevel, 0, 121); + gFrameBuffer[2][METER_PAD_LEFT + x] = 0b11111111; + } + + const uint8_t PAD_LEFT = 4; + const uint8_t CELL_WIDTH = 30; + uint8_t offset = PAD_LEFT; + uint8_t row = 4; + + for (int i = 0, idx = 1; idx <= 4; ++i, ++idx) + { + if (idx == 5) + { + row += 2; + i = 0; + } + offset = PAD_LEFT + i * CELL_WIDTH; + if (menuState == idx) + { + for (int j = 0; j < CELL_WIDTH; ++j) + { + gFrameBuffer[row][j + offset] = 0xFF; + gFrameBuffer[row + 1][j + offset] = 0xFF; + } + } + sprintf(String, "%s", registerSpecs[idx].name); + GUI_DisplaySmallest(String, offset + 2, row * 8 + 2, false, + menuState != idx); + sprintf(String, "%u", GetRegMenuValue(idx)); + GUI_DisplaySmallest(String, offset + 2, (row + 1) * 8 + 1, false, + menuState != idx); } - sprintf(String, "%s", registerSpecs[idx].name); - GUI_DisplaySmallest(String, offset + 2, row * 8 + 2, false, - menuState != idx); - sprintf(String, "%u", GetRegMenuValue(idx)); - GUI_DisplaySmallest(String, offset + 2, (row + 1) * 8 + 1, false, - menuState != idx); - } } -static void Render() { - UI_DisplayClear(); +static void Render() +{ + UI_DisplayClear(); - switch (currentState) { - case SPECTRUM: - RenderSpectrum(); - break; - case FREQ_INPUT: - RenderFreqInput(); - break; - case STILL: - RenderStill(); - break; - } - - ST7565_BlitFullScreen(); -} - -bool HandleUserInput() { - kbd.prev = kbd.current; - kbd.current = GetKey(); - - if (kbd.current != KEY_INVALID && kbd.current == kbd.prev) { - if (kbd.counter < 16) - kbd.counter++; - else - kbd.counter -= 3; - SYSTEM_DelayMs(20); - } else { - kbd.counter = 0; - } - - if (kbd.counter == 3 || kbd.counter == 16) { - switch (currentState) { + switch (currentState) + { case SPECTRUM: - OnKeyDown(kbd.current); - break; + RenderSpectrum(); + break; case FREQ_INPUT: - OnKeyDownFreqInput(kbd.current); - break; + RenderFreqInput(); + break; case STILL: - OnKeyDownStill(kbd.current); - break; + RenderStill(); + break; } - } - return true; + ST7565_BlitFullScreen(); } -static void Scan() { - if (rssiHistory[scanInfo.i] != RSSI_MAX_VALUE -#ifdef ENABLE_SCAN_RANGES - && !IsBlacklisted(scanInfo.i) -#endif - ) { - SetF(scanInfo.f); - Measure(); - UpdateScanInfo(); - } -} +bool HandleUserInput() +{ + kbd.prev = kbd.current; + kbd.current = GetKey(); -static void NextScanStep() { - ++peak.t; - ++scanInfo.i; - scanInfo.f += scanInfo.scanStep; -} - -static void UpdateScan() { - Scan(); - - if (scanInfo.i < scanInfo.measurementsCount) { - NextScanStep(); - return; - } - - if(scanInfo.measurementsCount < 128) - memset(&rssiHistory[scanInfo.measurementsCount], 0, - sizeof(rssiHistory) - scanInfo.measurementsCount*sizeof(rssiHistory[0])); - - redrawScreen = true; - preventKeypress = false; - - UpdatePeakInfo(); - if (IsPeakOverLevel()) { - ToggleRX(true); - TuneToPeak(); - return; - } - - newScanStart = true; -} - -static void UpdateStill() { - Measure(); - redrawScreen = true; - preventKeypress = false; - - peak.rssi = scanInfo.rssi; - AutoTriggerLevel(); - - ToggleRX(IsPeakOverLevel() || monitorMode); -} - -static void UpdateListening() { - preventKeypress = false; - if (currentState == STILL) { - listenT = 0; - } - if (listenT) { - listenT--; - SYSTEM_DelayMs(1); - return; - } - - if (currentState == SPECTRUM) { - BK4819_WriteRegister(0x43, GetBWRegValueForScan()); - Measure(); - BK4819_WriteRegister(0x43, listenBWRegValues[settings.listenBw]); - } else { - Measure(); - } - - peak.rssi = scanInfo.rssi; - redrawScreen = true; - - if (IsPeakOverLevel() || monitorMode) { - listenT = 1000; - return; - } - - ToggleRX(false); - ResetScanStats(); -} - -static void Tick() { -#ifdef ENABLE_AM_FIX - if (gNextTimeslice) { - gNextTimeslice = false; - if(settings.modulationType == MODULATION_AM && !lockAGC) { - AM_fix_10ms(vfo); //allow AM_Fix to apply its AGC action + if (kbd.current != KEY_INVALID && kbd.current == kbd.prev) + { + if (kbd.counter < 16) + kbd.counter++; + else + kbd.counter -= 3; + SYSTEM_DelayMs(20); + } + else + { + kbd.counter = 0; } - } -#endif + if (kbd.counter == 3 || kbd.counter == 16) + { + switch (currentState) + { + case SPECTRUM: + OnKeyDown(kbd.current); + break; + case FREQ_INPUT: + OnKeyDownFreqInput(kbd.current); + break; + case STILL: + OnKeyDownStill(kbd.current); + break; + } + } + + return true; +} + +static void Scan() +{ + if (rssiHistory[scanInfo.i] != RSSI_MAX_VALUE #ifdef ENABLE_SCAN_RANGES - if (gNextTimeslice_500ms) { - gNextTimeslice_500ms = false; + && !IsBlacklisted(scanInfo.i) +#endif + ) + { + SetF(scanInfo.f); + Measure(); + UpdateScanInfo(); + } +} - // if a lot of steps then it takes long time - // we don't want to wait for whole scan - // listening has it's own timer - if(GetStepsCount()>128 && !isListening) { - UpdatePeakInfo(); - if (IsPeakOverLevel()) { +static void NextScanStep() +{ + ++peak.t; + ++scanInfo.i; + scanInfo.f += scanInfo.scanStep; +} + +static void UpdateScan() +{ + Scan(); + + if (scanInfo.i < scanInfo.measurementsCount) + { + NextScanStep(); + return; + } + + if (scanInfo.measurementsCount < 128) + memset(&rssiHistory[scanInfo.measurementsCount], 0, + sizeof(rssiHistory) - scanInfo.measurementsCount * sizeof(rssiHistory[0])); + + redrawScreen = true; + preventKeypress = false; + + UpdatePeakInfo(); + if (IsPeakOverLevel()) + { ToggleRX(true); TuneToPeak(); return; - } - redrawScreen = true; - preventKeypress = false; } - } -#endif - if (!preventKeypress) { - HandleUserInput(); - } - if (newScanStart) { - InitScan(); - newScanStart = false; - } - if (isListening && currentState != FREQ_INPUT) { - UpdateListening(); - } else { - if (currentState == SPECTRUM) { - UpdateScan(); - } else if (currentState == STILL) { - UpdateStill(); - } - } - if (redrawStatus || ++statuslineUpdateTimer > 4096) { - RenderStatus(); - redrawStatus = false; - statuslineUpdateTimer = 0; - } - if (redrawScreen) { - Render(); - redrawScreen = false; - } + newScanStart = true; } -void APP_RunSpectrum() { - // TX here coz it always? set to active VFO - vfo = gEeprom.TX_VFO; -#ifdef ENABLE_FEAT_F4HWN_SPECTRUM - LoadSettings(); +static void UpdateStill() +{ + Measure(); + redrawScreen = true; + preventKeypress = false; + + peak.rssi = scanInfo.rssi; + AutoTriggerLevel(); + + ToggleRX(IsPeakOverLevel() || monitorMode); +} + +static void UpdateListening() +{ + preventKeypress = false; + if (currentState == STILL) + { + listenT = 0; + } + if (listenT) + { + listenT--; + SYSTEM_DelayMs(1); + return; + } + + if (currentState == SPECTRUM) + { + BK4819_WriteRegister(0x43, GetBWRegValueForScan()); + Measure(); + BK4819_WriteRegister(0x43, listenBWRegValues[settings.listenBw]); + } + else + { + Measure(); + } + + peak.rssi = scanInfo.rssi; + redrawScreen = true; + + if (IsPeakOverLevel() || monitorMode) + { + listenT = 1000; + return; + } + + ToggleRX(false); + ResetScanStats(); +} + +static void Tick() +{ +#ifdef ENABLE_AM_FIX + if (gNextTimeslice) + { + gNextTimeslice = false; + if (settings.modulationType == MODULATION_AM && !lockAGC) + { + AM_fix_10ms(vfo); // allow AM_Fix to apply its AGC action + } + } #endif - // set the current frequency in the middle of the display + #ifdef ENABLE_SCAN_RANGES - if(gScanRangeStart) { - currentFreq = initialFreq = gScanRangeStart; - for(uint8_t i = 0; i < ARRAY_SIZE(scanStepValues); i++) { - if(scanStepValues[i] >= gTxVfo->StepFrequency) { - settings.scanStepIndex = i; - break; - } + if (gNextTimeslice_500ms) + { + gNextTimeslice_500ms = false; + + // if a lot of steps then it takes long time + // we don't want to wait for whole scan + // listening has it's own timer + if (GetStepsCount() > 128 && !isListening) + { + UpdatePeakInfo(); + if (IsPeakOverLevel()) + { + ToggleRX(true); + TuneToPeak(); + return; + } + redrawScreen = true; + preventKeypress = false; + } } - settings.stepsCount = STEPS_128; - } - else #endif - currentFreq = initialFreq = gTxVfo->pRX->Frequency - - ((GetStepsCount() / 2) * GetScanStep()); - BackupRegisters(); - - isListening = true; // to turn off RX later - redrawStatus = true; - redrawScreen = true; - newScanStart = true; - - ToggleRX(true), ToggleRX(false); // hack to prevent noise when squelch off - RADIO_SetModulation(settings.modulationType = gTxVfo->Modulation); - - #ifdef ENABLE_FEAT_F4HWN_SPECTRUM - BK4819_SetFilterBandwidth(settings.listenBw, false); - #else - BK4819_SetFilterBandwidth(settings.listenBw = BK4819_FILTER_BW_WIDE, false); - #endif - - RelaunchScan(); - - memset(rssiHistory, 0, sizeof(rssiHistory)); - - isInitialized = true; - - while (isInitialized) { - Tick(); - } + if (!preventKeypress) + { + HandleUserInput(); + } + if (newScanStart) + { + InitScan(); + newScanStart = false; + } + if (isListening && currentState != FREQ_INPUT) + { + UpdateListening(); + } + else + { + if (currentState == SPECTRUM) + { + UpdateScan(); + } + else if (currentState == STILL) + { + UpdateStill(); + } + } + if (redrawStatus || ++statuslineUpdateTimer > 4096) + { + RenderStatus(); + redrawStatus = false; + statuslineUpdateTimer = 0; + } + if (redrawScreen) + { + Render(); + redrawScreen = false; + } +} + +void APP_RunSpectrum() +{ + // TX here coz it always? set to active VFO + vfo = gEeprom.TX_VFO; +#ifdef ENABLE_FEAT_F4HWN_SPECTRUM + LoadSettings(); +#endif + // set the current frequency in the middle of the display +#ifdef ENABLE_SCAN_RANGES + if (gScanRangeStart) + { + currentFreq = initialFreq = gScanRangeStart; + for (uint8_t i = 0; i < ARRAY_SIZE(scanStepValues); i++) + { + if (scanStepValues[i] >= gTxVfo->StepFrequency) + { + settings.scanStepIndex = i; + break; + } + } + settings.stepsCount = STEPS_128; + } + else +#endif + currentFreq = initialFreq = gTxVfo->pRX->Frequency - + ((GetStepsCount() / 2) * GetScanStep()); + + BackupRegisters(); + + isListening = true; // to turn off RX later + redrawStatus = true; + redrawScreen = true; + newScanStart = true; + + ToggleRX(true), ToggleRX(false); // hack to prevent noise when squelch off + RADIO_SetModulation(settings.modulationType = gTxVfo->Modulation); + +#ifdef ENABLE_FEAT_F4HWN_SPECTRUM + BK4819_SetFilterBandwidth(settings.listenBw, false); +#else + BK4819_SetFilterBandwidth(settings.listenBw = BK4819_FILTER_BW_WIDE, false); +#endif + + RelaunchScan(); + + memset(rssiHistory, 0, sizeof(rssiHistory)); + + isInitialized = true; + + while (isInitialized) + { + Tick(); + } } diff --git a/app/spectrum.h b/app/spectrum.h index 1c1cce5..1f15513 100644 --- a/app/spectrum.h +++ b/app/spectrum.h @@ -41,12 +41,34 @@ static const uint8_t DrawingEndY = 40; static const uint8_t U8RssiMap[] = { - 121, 115, 109, 103, 97, 91, 85, 79, 73, 63, + 121, + 115, + 109, + 103, + 97, + 91, + 85, + 79, + 73, + 63, }; static const uint16_t scanStepValues[] = { - 1, 10, 50, 100, 250, 500, 625, 833, - 1000, 1250, 1500, 2000, 2500, 5000, 10000, + 1, + 10, + 50, + 100, + 250, + 500, + 625, + 833, + 1000, + 1250, + 1500, + 2000, + 2500, + 5000, + 10000, }; static const uint16_t scanStepBWRegValues[] = { @@ -84,71 +106,78 @@ static const uint16_t listenBWRegValues[] = { 0b0100100001011000, // 6.25 }; -typedef enum State { - SPECTRUM, - FREQ_INPUT, - STILL, +typedef enum State +{ + SPECTRUM, + FREQ_INPUT, + STILL, } State; -typedef enum StepsCount { - STEPS_128, - STEPS_64, - STEPS_32, - STEPS_16, +typedef enum StepsCount +{ + STEPS_128, + STEPS_64, + STEPS_32, + STEPS_16, } StepsCount; -typedef enum ScanStep { - S_STEP_0_01kHz, - S_STEP_0_1kHz, - S_STEP_0_5kHz, - S_STEP_1_0kHz, +typedef enum ScanStep +{ + S_STEP_0_01kHz, + S_STEP_0_1kHz, + S_STEP_0_5kHz, + S_STEP_1_0kHz, - S_STEP_2_5kHz, - S_STEP_5_0kHz, - S_STEP_6_25kHz, - S_STEP_8_33kHz, - S_STEP_10_0kHz, - S_STEP_12_5kHz, - S_STEP_15_0kHz, - S_STEP_20_0kHz, - S_STEP_25_0kHz, - S_STEP_50_0kHz, - S_STEP_100_0kHz, + S_STEP_2_5kHz, + S_STEP_5_0kHz, + S_STEP_6_25kHz, + S_STEP_8_33kHz, + S_STEP_10_0kHz, + S_STEP_12_5kHz, + S_STEP_15_0kHz, + S_STEP_20_0kHz, + S_STEP_25_0kHz, + S_STEP_50_0kHz, + S_STEP_100_0kHz, } ScanStep; -typedef struct SpectrumSettings { - uint32_t frequencyChangeStep; - StepsCount stepsCount; - ScanStep scanStepIndex; - uint16_t scanDelay; - uint16_t rssiTriggerLevel; - BK4819_FilterBandwidth_t bw; - BK4819_FilterBandwidth_t listenBw; - int dbMin; - int dbMax; - ModulationMode_t modulationType; - bool backlightState; +typedef struct SpectrumSettings +{ + uint32_t frequencyChangeStep; + StepsCount stepsCount; + ScanStep scanStepIndex; + uint16_t scanDelay; + uint16_t rssiTriggerLevel; + BK4819_FilterBandwidth_t bw; + BK4819_FilterBandwidth_t listenBw; + int dbMin; + int dbMax; + ModulationMode_t modulationType; + bool backlightState; } SpectrumSettings; -typedef struct KeyboardState { - KEY_Code_t current; - KEY_Code_t prev; - uint8_t counter; +typedef struct KeyboardState +{ + KEY_Code_t current; + KEY_Code_t prev; + uint8_t counter; } KeyboardState; -typedef struct ScanInfo { - uint16_t rssi, rssiMin, rssiMax; - uint16_t i, iPeak; - uint32_t f, fPeak; - uint16_t scanStep; - uint16_t measurementsCount; +typedef struct ScanInfo +{ + uint16_t rssi, rssiMin, rssiMax; + uint16_t i, iPeak; + uint32_t f, fPeak; + uint16_t scanStep; + uint16_t measurementsCount; } ScanInfo; -typedef struct PeakInfo { - uint16_t t; - uint16_t rssi; - uint32_t f; - uint16_t i; +typedef struct PeakInfo +{ + uint16_t t; + uint16_t rssi; + uint32_t f; + uint16_t i; } PeakInfo; void APP_RunSpectrum(void); From 195881a5e2b4ed609c754deb8fe8f55d96efe87b Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Fri, 16 Aug 2024 02:19:52 +0200 Subject: [PATCH 26/30] Move spectrum Data[4] to Data[3] --- app/spectrum.c | 8 ++++---- settings.c | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/spectrum.c b/app/spectrum.c index 64bd619..ef05597 100644 --- a/app/spectrum.c +++ b/app/spectrum.c @@ -117,21 +117,21 @@ static void LoadSettings() // 1FF0..0x1FF7 EEPROM_ReadBuffer(0x1FF0, Data, 8); - settings.scanStepIndex = ((Data[4] & 0xF0) >> 4); + settings.scanStepIndex = ((Data[3] & 0xF0) >> 4); if (settings.scanStepIndex > 14) { settings.scanStepIndex = S_STEP_25_0kHz; } - settings.stepsCount = ((Data[4] & 0x0F) & 0b1100) >> 2; + settings.stepsCount = ((Data[3] & 0x0F) & 0b1100) >> 2; if (settings.stepsCount > 3) { settings.stepsCount = STEPS_64; } - settings.listenBw = ((Data[4] & 0x0F) & 0b0011); + settings.listenBw = ((Data[3] & 0x0F) & 0b0011); if (settings.listenBw > 2) { @@ -145,7 +145,7 @@ static void SaveSettings() // 1FF0..0x1FF7 EEPROM_ReadBuffer(0x1FF0, Data, 8); - Data[4] = (settings.scanStepIndex << 4) | (settings.stepsCount << 2) | settings.listenBw; + Data[3] = (settings.scanStepIndex << 4) | (settings.stepsCount << 2) | settings.listenBw; EEPROM_WriteBuffer(0x1FF0, Data); } diff --git a/settings.c b/settings.c index 2211a77..2145b5b 100644 --- a/settings.c +++ b/settings.c @@ -348,6 +348,10 @@ void SETTINGS_InitEEPROM(void) gSetting_set_tmr = Data[4] & 1; + // Warning + // Be aware, Data[3] is use by Spectrum + // Warning + // And set special session settings for actions gSetting_set_ptt_session = gSetting_set_ptt; gEeprom.KEY_LOCK_PTT = gSetting_set_lck; From 533262a6dc211de57930526ffe1edaf11ca1536a Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Fri, 16 Aug 2024 02:39:41 +0200 Subject: [PATCH 27/30] Fix README --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 47c3355..56b32ea 100644 --- a/README.md +++ b/README.md @@ -64,10 +64,11 @@ Special thanks to Jean-Cyrille F6IWW, Fabrice 14RC123, David F4BPP, Olivier 14RC * CTCSS or DCS value, * KeyLock message, * last RX, - * move BatTxt menu from 34/63 to 30/63 (just after BatSave menu 29/63), + * move BatTxt menu from 34/63 to 30/63 (just after BatSave menu 29/63), * rename BackLt to BLTime, * rename BltTRX to BLTxRx, * improve memory channel input, + * add percent and gauge to Air Copy, * and more... * new menu entries and changes: * add SetPwr menu to set User power (<20mW, 125mW, 250mW, 500mW, 1W, 2W or 5W), @@ -80,6 +81,7 @@ Special thanks to Jean-Cyrille F6IWW, Fabrice 14RC123, David F4BPP, Olivier 14RC * add SetLck menu to set what is locked (Keys or Keys + PTT), * add SetGui menu to set font size on the VFO baseline (Classic or Tiny), * add TXLock menu to open TX on channel, + * add SetTmr menu to set RX and TX timers (Off or On) * rename BatVol menu (52/63) to SysInf, which displays the firmware version in addition to the battery status, * improve PonMsg menu, * improve BackLt menu, From 07d89b9eed1417c136da65997941d7bca9686cb4 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Fri, 16 Aug 2024 03:27:05 +0200 Subject: [PATCH 28/30] Add screenshot for Air Copy --- app/aircopy.c | 10 ++++++++++ images/AIR_COPY.png | Bin 0 -> 17085 bytes 2 files changed, 10 insertions(+) create mode 100644 images/AIR_COPY.png diff --git a/app/aircopy.c b/app/aircopy.c index 4f06075..bc844fe 100644 --- a/app/aircopy.c +++ b/app/aircopy.c @@ -32,6 +32,10 @@ #include "ui/inputbox.h" #include "ui/ui.h" +#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT +#include "screenshot.h" +#endif + static const uint16_t Obfuscation[8] = { 0x6C16, 0xE614, 0x912E, 0x400D, 0x3521, 0x40D5, 0x0313, 0x80E9 }; AIRCOPY_State_t gAircopyState; @@ -73,6 +77,9 @@ bool AIRCOPY_SendMessage(void) if (++gAirCopyBlockNumber >= 0x78) { gAircopyState = AIRCOPY_COMPLETE; + #ifdef ENABLE_FEAT_F4HWN_SCREENSHOT + getScreenShot(); + #endif //NVIC_SystemReset(); } @@ -131,6 +138,9 @@ void AIRCOPY_StorePacket(void) if (Offset == 0x1E00) { gAircopyState = AIRCOPY_COMPLETE; + #ifdef ENABLE_FEAT_F4HWN_SCREENSHOT + getScreenShot(); + #endif } gAirCopyBlockNumber++; diff --git a/images/AIR_COPY.png b/images/AIR_COPY.png new file mode 100644 index 0000000000000000000000000000000000000000..ce749a63378a6344009b9fa5a9ef4c76a7de7492 GIT binary patch literal 17085 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 literal 0 HcmV?d00001 From bb7c8121363f3fa05cdf901d184734a4c07e6bc6 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Tue, 20 Aug 2024 05:07:33 +0200 Subject: [PATCH 29/30] Improve audio bar --- ui/main.c | 53 ++++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/ui/main.c b/ui/main.c index d9c1915..321f54a 100644 --- a/ui/main.c +++ b/ui/main.c @@ -112,7 +112,7 @@ static void DrawSmallAntennaAndBars(uint8_t *p, unsigned int level) } #if defined ENABLE_AUDIO_BAR || defined ENABLE_RSSI_BAR -static void DrawLevelBar(uint8_t xpos, uint8_t line, uint8_t level) +static void DrawLevelBar(uint8_t xpos, uint8_t line, uint8_t level, uint8_t bars) { #ifndef ENABLE_FEAT_F4HWN const char hollowBar[] = { @@ -124,7 +124,7 @@ static void DrawLevelBar(uint8_t xpos, uint8_t line, uint8_t level) #endif uint8_t *p_line = gFrameBuffer[line]; - level = MIN(level, 13); + level = MIN(level, bars); for(uint8_t i = 0; i < level; i++) { #ifdef ENABLE_FEAT_F4HWN @@ -137,9 +137,9 @@ static void DrawLevelBar(uint8_t xpos, uint8_t line, uint8_t level) 0b01111111 }; - if(i < 9) { + if(i < bars - 4) { for(uint8_t j = 0; j < 4; j++) - p_line[xpos + i * 5 + j] = (~(0x7F >> (i+1))) & 0x7F; + p_line[xpos + i * 5 + j] = (~(0x7F >> (i + 1))) & 0x7F; } else { memcpy(p_line + (xpos + i * 5), &hollowBar, ARRAY_SIZE(hollowBar)); @@ -161,7 +161,7 @@ static void DrawLevelBar(uint8_t xpos, uint8_t line, uint8_t level) 0b00111110 }; - if(i < 9) { + if(i < bars - 4) { memcpy(p_line + (xpos + i * 5), &simpleBar, ARRAY_SIZE(simpleBar)); } else { @@ -169,7 +169,7 @@ static void DrawLevelBar(uint8_t xpos, uint8_t line, uint8_t level) } } #else - if(i < 9) { + if(i < bars - 4) { for(uint8_t j = 0; j < 4; j++) p_line[xpos + i * 5 + j] = (~(0x7F >> (i+1))) & 0x7F; } @@ -183,21 +183,13 @@ static void DrawLevelBar(uint8_t xpos, uint8_t line, uint8_t level) #ifdef ENABLE_AUDIO_BAR -unsigned int sqrt16(unsigned int value) -{ // return square root of 'value' - unsigned int shift = 16; // number of bits supplied in 'value' .. 2 ~ 32 - unsigned int bit = 1u << --shift; - unsigned int sqrti = 0; - while (bit) - { - const unsigned int temp = ((sqrti << 1) | bit) << shift--; - if (value >= temp) { - value -= temp; - sqrti |= bit; - } - bit >>= 1; +// Approximation of a logarithmic scale using integer arithmetic +uint8_t log2_approx(unsigned int value) { + uint8_t log = 0; + while (value >>= 1) { + log++; } - return sqrti; + return log; } void UI_DisplayAudioBar(void) @@ -238,17 +230,24 @@ void UI_DisplayAudioBar(void) if (gAlarmState != ALARM_STATE_OFF) return; #endif - const unsigned int voice_amp = BK4819_GetVoiceAmplitudeOut(); // 15:0 + static uint8_t barsOld = 0; + const uint8_t thresold = 18; // arbitrary thresold + //const uint8_t barsList[] = {0, 0, 0, 1, 2, 3, 4, 5, 6, 8, 10, 13, 16, 20, 25, 25}; + const uint8_t barsList[] = {0, 0, 0, 1, 2, 3, 5, 7, 9, 12, 15, 18, 21, 25, 25, 25}; + uint8_t logLevel; + uint8_t bars; - // make non-linear to make more sensitive at low values - const unsigned int level = MIN(voice_amp * 8, 65535u); - const unsigned int sqrt_level = MIN(sqrt16(level), 124u); - uint8_t bars = 13 * sqrt_level / 124; + unsigned int voiceLevel = BK4819_GetVoiceAmplitudeOut(); // 15:0 + + voiceLevel = (voiceLevel >= thresold) ? (voiceLevel - thresold) : 0; + logLevel = log2_approx(MIN(voiceLevel * 16, 32768u) + 1); + bars = barsList[logLevel]; + barsOld = (barsOld - bars > 1) ? (barsOld - 1) : bars; uint8_t *p_line = gFrameBuffer[line]; memset(p_line, 0, LCD_WIDTH); - DrawLevelBar(62, line, bars); + DrawLevelBar(2, line, barsOld, 25); if (gCurrentFunction == FUNCTION_TRANSMIT) ST7565_BlitFullScreen(); @@ -414,7 +413,7 @@ void DisplayRSSIBar(const bool now) UI_PrintStringSmallNormal(str, 2, 0, line); #endif - DrawLevelBar(bar_x, line, s_level + overS9Bars); + DrawLevelBar(bar_x, line, s_level + overS9Bars, 13); if (now) ST7565_BlitLine(line); #else From 1b59d509d348187cce4b0c2be77d86303dbc8063 Mon Sep 17 00:00:00 2001 From: Armel FAUVEAU Date: Tue, 20 Aug 2024 18:25:12 +0200 Subject: [PATCH 30/30] Prepare new version --- README.md | 1 + archive/f4hwn.bandscope.packed.v3.3.bin | Bin 0 -> 60706 bytes archive/f4hwn.broadcast.packed.v3.3.bin | Bin 0 -> 58882 bytes archive/f4hwn.voxless.packed.v3.3.bin | Bin 0 -> 61202 bytes 4 files changed, 1 insertion(+) create mode 100644 archive/f4hwn.bandscope.packed.v3.3.bin create mode 100644 archive/f4hwn.broadcast.packed.v3.3.bin create mode 100644 archive/f4hwn.voxless.packed.v3.3.bin diff --git a/README.md b/README.md index 56b32ea..5148af6 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ Special thanks to Jean-Cyrille F6IWW, Fabrice 14RC123, David F4BPP, Olivier 14RC * rename BltTRX to BLTxRx, * improve memory channel input, * add percent and gauge to Air Copy, + * improve audio bar, * and more... * new menu entries and changes: * add SetPwr menu to set User power (<20mW, 125mW, 250mW, 500mW, 1W, 2W or 5W), diff --git a/archive/f4hwn.bandscope.packed.v3.3.bin b/archive/f4hwn.bandscope.packed.v3.3.bin new file mode 100644 index 0000000000000000000000000000000000000000..b54aadf796507298be26868b8eb7c885a4626571 GIT binary patch literal 60706 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 z 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 literal 0 HcmV?d00001 diff --git a/archive/f4hwn.voxless.packed.v3.3.bin b/archive/f4hwn.voxless.packed.v3.3.bin new file mode 100644 index 0000000000000000000000000000000000000000..026486101b25f8b6c12c9a6d894fbb0f975ba4e7 GIT binary patch literal 61202 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 qPBZa5_vP}