diff --git a/Makefile b/Makefile index f12e011..b13a4c2 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ ENABLE_REVERSE_BAT_SYMBOL := 1 ENABLE_NO_SCAN_TIMEOUT := 1 ENABLE_AM_FIX := 1 ENABLE_AM_FIX_SHOW_DATA := 1 -ENABLE_SQUELCH1_LOWER := 0 +ENABLE_SQUELCH_LOWER := 1 ENABLE_RSSI_BAR := 1 ENABLE_AUDIO_BAR := 1 ENABLE_SPECTRUM := 1 @@ -233,8 +233,8 @@ endif ifeq ($(ENABLE_AM_FIX_TEST1),1) CFLAGS += -DENABLE_AM_FIX_TEST1 endif -ifeq ($(ENABLE_SQUELCH1_LOWER),1) - CFLAGS += -DENABLE_SQUELCH1_LOWER +ifeq ($(ENABLE_SQUELCH_LOWER),1) + CFLAGS += -DENABLE_SQUELCH_LOWER endif ifeq ($(ENABLE_RSSI_BAR),1) CFLAGS += -DENABLE_RSSI_BAR diff --git a/README.md b/README.md index b4280b4..47f953f 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,10 @@ https://github.com/fagci/uv-k5-firmware-fagci-mod/tree/refactor All is a cloned and customized version of DualTachyon's open firmware found here .. -https://github.com/DualTachyon/uv-k5-firmware +https://github.com/DualTachyon/uv-k5-firmware .. a cool achievement ! -A cool achievement +Use this firmware at your own risk (entirely). There is absolutely no guarantee that it will work in any way shape or form on your radio(s), it may even brick your radio(s), in which case, you'd need to buy another radio. +Anyway, have fun. # Radio performance @@ -60,7 +61,7 @@ ENABLE_REVERSE_BAT_SYMBOL := 1 mirror the battery symbol on the status ENABLE_NO_SCAN_TIMEOUT := 1 remove the 32 sec timeout from the CTCSS/DCS scan (press exit butt to end scan) ENABLE_AM_FIX := 1 dynamically adjust the front end gains when in AM mode to helo prevent AM demodulator saturation - ignore the on-screen RSSI (for now) ENABLE_AM_FIX_SHOW_DATA := 1 show debug data for the AM fix -ENABLE_SQUELCH1_LOWER := 0 adjusts squelch setting '1' to be more sensitive - I plan to let user adjust it in the menu +ENABLE_SQUELCH_LOWER := 1 squelch settings more sensitive - plan to let user adjust it in the menu ENABLE_RSSI_BAR := 1 enable a dBm/Sx RSSI bar graph level ENABLE_AUDIO_BAR := 0 experimental, display an audo bar level when TX'ing #ENABLE_COPY_CHAN_TO_VFO := 1 not yet implemented - copy the channel into the VFO diff --git a/app/action.c b/app/action.c index 4ac57b9..5acb8c5 100644 --- a/app/action.c +++ b/app/action.c @@ -14,6 +14,8 @@ * limitations under the License. */ +#include + #include "app/action.h" #include "app/app.h" #include "app/dtmf.h" @@ -167,6 +169,11 @@ void ACTION_Scan(bool bRestart) gMonitor = false; + DTMF_clear_RX(); + + gDTMF_RX_live_timeout = 0; + memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); + RADIO_SelectVfos(); #ifdef ENABLE_NOAA diff --git a/app/app.c b/app/app.c index 4d9c2ab..152f66a 100644 --- a/app/app.c +++ b/app/app.c @@ -73,10 +73,10 @@ static void updateRSSI(const int vfo) if (gEeprom.VfoInfo[vfo].AM_mode && gSetting_AM_fix) rssi -= rssi_gain_diff[vfo]; #endif - + if (gCurrentRSSI[vfo] == rssi) return; // no change - + gCurrentRSSI[vfo] = rssi; UI_UpdateRSSI(rssi, vfo); @@ -119,7 +119,7 @@ static void APP_CheckForIncoming(void) updateRSSI(gEeprom.RX_CHANNEL); gUpdateRSSI = true; } - + return; } @@ -182,6 +182,10 @@ static void APP_HandleIncoming(void) if (!g_SquelchLost) { // squelch is closed + + if (gDTMF_RX_index > 0) + DTMF_clear_RX(); + if (gCurrentFunction != FUNCTION_FOREGROUND) { FUNCTION_Select(FUNCTION_FOREGROUND); @@ -214,12 +218,13 @@ static void APP_HandleIncoming(void) if (!bFlag) return; - DTMF_HandleRequest(); - if (gScanState == SCAN_OFF && gCssScanMode == CSS_SCAN_MODE_OFF) { // not scanning if (gRxVfo->DTMF_DECODING_ENABLE || gSetting_KILLED) - { // DTMF is enabled + { // DTMF DCD is enabled + +// DTMF_HandleRequest(); + if (gDTMF_CallState == DTMF_CALL_STATE_NONE) { if (gRxReceptionMode == RX_MODE_DETECTED) @@ -234,7 +239,6 @@ static void APP_HandleIncoming(void) gUpdateStatus = true; gUpdateDisplay = true; - return; } } @@ -531,7 +535,7 @@ void APP_StartListening(FUNCTION_Type_t Function, const bool reset_am_fix) } // ****************************************** - + // original setting uint8_t lna_short = orig_lna_short; uint8_t lna = orig_lna; @@ -777,34 +781,40 @@ void APP_CheckRadioInterrupts(void) // g_CTCSS_Lost = true; if (interrupt_status_bits & BK4819_REG_02_DTMF_5TONE_FOUND) - { // save the new DTMF RX'ed character - - // fetch the RX'ed char + { // save the RX'ed DTMF character const char c = DTMF_GetCharacter(BK4819_GetDTMF_5TONE_Code()); if (c != 0xff) { - if (gCurrentFunction == FUNCTION_RECEIVE || - gCurrentFunction == FUNCTION_INCOMING || - gCurrentFunction == FUNCTION_MONITOR) + if (gCurrentFunction != FUNCTION_TRANSMIT) { - gDTMF_RequestPending = true; - gDTMF_RecvTimeout = DTMF_RX_timeout_500ms; - // shift the RX buffer down one - if need be - if (gDTMF_WriteIndex >= sizeof(gDTMF_Received)) - memmove(gDTMF_Received, &gDTMF_Received[1], --gDTMF_WriteIndex); - gDTMF_Received[gDTMF_WriteIndex++] = c; + 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; + } - // live DTMF decoder - size_t len = strlen(gDTMF_RX_live); - // shift the RX buffer down one - if need be - if (len >= (sizeof(gDTMF_RX_live) - 1)) - memmove(&gDTMF_RX_live[0], &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 (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; - DTMF_HandleRequest(); + DTMF_HandleRequest(); + } } } } @@ -1257,7 +1267,7 @@ void APP_CheckKeys(void) while (i-- > 0) { SYSTEM_DelayMs(1); - + if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT)) { // PTT pressed if (count > 0) @@ -1666,9 +1676,9 @@ void cancelUserInputModes(void) gKeyInputCountdown = 0; if (gDTMF_InputMode || gInputBoxIndex > 0) { + memset(gDTMF_String, 0, sizeof(gDTMF_String)); gDTMF_InputMode = false; gDTMF_InputIndex = 0; - memset(gDTMF_String, 0, sizeof(gDTMF_String)); gInputBoxIndex = 0; gRequestDisplayScreen = DISPLAY_MAIN; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; @@ -1692,11 +1702,18 @@ void APP_TimeSlice500ms(void) { if (--gDTMF_RX_live_timeout == 0) { - gDTMF_RX_live[0] = 0; - gUpdateDisplay = true; + if (gDTMF_RX_live[0] != 0) + { + memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); + gUpdateDisplay = true; + } } } + if (gDTMF_RX_timeout > 0) + if (--gDTMF_RX_timeout == 0) + DTMF_clear_RX(); + // Skipped authentic device check #ifdef ENABLE_FMRADIO @@ -1711,8 +1728,16 @@ void APP_TimeSlice500ms(void) if (gReducedService) { BOARD_ADC_GetBatteryInfo(&gBatteryCurrentVoltage, &gBatteryCurrent); + if (gBatteryCurrent > 500 || gBatteryCalibration[3] < gBatteryCurrentVoltage) - overlay_FLASH_RebootToBootloader(); + { + #ifdef ENABLE_OVERLAY + overlay_FLASH_RebootToBootloader(); + #else + NVIC_SystemReset(); + #endif + } + return; } @@ -1892,7 +1917,7 @@ void APP_TimeSlice500ms(void) if (gScreenToDisplay == DISPLAY_SCANNER && gScannerEditState == 0 && gScanCssState < SCAN_CSS_STATE_FOUND) { gScanProgressIndicator++; - + #ifndef ENABLE_NO_SCAN_TIMEOUT if (gScanProgressIndicator > 32) { @@ -1900,15 +1925,28 @@ void APP_TimeSlice500ms(void) gScanCssState = SCAN_CSS_STATE_FOUND; else gScanCssState = SCAN_CSS_STATE_FAILED; - + gUpdateStatus = true; } #endif - + gUpdateDisplay = true; } - if (gDTMF_CallState != DTMF_CALL_STATE_NONE && gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_RECEIVE) + 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) { if (gDTMF_AUTO_RESET_TIME > 0) { @@ -1918,15 +1956,6 @@ void APP_TimeSlice500ms(void) gUpdateDisplay = true; } } - - if (gDTMF_DecodeRing && gDTMF_DecodeRingCountdown_500ms > 0) - { - if ((--gDTMF_DecodeRingCountdown_500ms % 3) == 0) - AUDIO_PlayBeep(BEEP_440HZ_500MS); - - if (gDTMF_DecodeRingCountdown_500ms == 0) - gDTMF_DecodeRing = false; - } } if (gDTMF_IsTx && gDTMF_TxStopCountdown_500ms > 0) @@ -1937,15 +1966,6 @@ void APP_TimeSlice500ms(void) gUpdateDisplay = true; } } - - if (gDTMF_RecvTimeout > 0) - { - if (--gDTMF_RecvTimeout == 0) - { - gDTMF_WriteIndex = 0; - memset(gDTMF_Received, 0, sizeof(gDTMF_Received)); - } - } } #ifdef ENABLE_ALARM @@ -2022,9 +2042,13 @@ static void APP_ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) if (Key == KEY_EXIT && bKeyPressed && bKeyHeld && gDTMF_RX_live[0] != 0) { // clear the live DTMF decoder if the EXIT key is held - gDTMF_RX_live_timeout = 0; - gDTMF_RX_live[0] = 0; - gUpdateDisplay = true; + if (gDTMF_RX_live[0] != 0) + { + gDTMF_RX_live_timeout = 0; + memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); + + gUpdateDisplay = true; + } } if (!bKeyPressed) @@ -2065,10 +2089,12 @@ static void APP_ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) BACKLIGHT_TurnOn(); - if (gDTMF_DecodeRing) - { - gDTMF_DecodeRing = false; + if (gDTMF_DecodeRingCountdown_500ms > 0) + { // cancel the ringing + gDTMF_DecodeRingCountdown_500ms = 0; + AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL); + if (Key != KEY_PTT) { gPttWasReleased = true; @@ -2115,7 +2141,8 @@ static void APP_ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) Key != KEY_EXIT && Key != KEY_SIDE1 && Key != KEY_SIDE2 && - Key != KEY_STAR) + Key != KEY_STAR && + Key != KEY_MENU) { if (gScanState != SCAN_OFF || gCssScanMode != CSS_SCAN_MODE_OFF) { // frequency or CTCSS/DCS scanning @@ -2147,7 +2174,8 @@ static void APP_ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) } } - if (gWasFKeyPressed && Key > KEY_9 && Key != KEY_F && Key != KEY_STAR && Key != KEY_MENU) + if (gWasFKeyPressed && Key > KEY_9 && Key != KEY_F && Key != KEY_STAR) +// if (gWasFKeyPressed && Key > KEY_9 && Key != KEY_F && Key != KEY_STAR && Key != KEY_MENU) { gWasFKeyPressed = false; gUpdateStatus = true; @@ -2203,7 +2231,7 @@ static void APP_ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) else { if (gEeprom.DTMF_SIDE_TONE) - { + { // user will here the DTMF tones in speaker GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); gEnableSpeaker = true; } @@ -2416,7 +2444,7 @@ Skip: if (gFlagStartScan) { gMonitor = false; - + #ifdef ENABLE_VOICE AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN); AUDIO_PlaySingleVoice(true); diff --git a/app/dtmf.c b/app/dtmf.c index 415f42e..9e2f334 100644 --- a/app/dtmf.c +++ b/app/dtmf.c @@ -22,6 +22,7 @@ #endif #include "app/scanner.h" #include "bsp/dp32g030/gpio.h" +#include "audio.h" #include "driver/bk4819.h" #include "driver/eeprom.h" #include "driver/gpio.h" @@ -33,12 +34,16 @@ #include "ui/ui.h" char gDTMF_String[15]; -char gDTMF_InputBox[15]; -char gDTMF_Received[16]; -uint8_t gDTMF_WriteIndex = 0; +char gDTMF_InputBox[15]; +uint8_t gDTMF_InputIndex = 0; +bool gDTMF_InputMode = false; uint8_t gDTMF_PreviousIndex = 0; -uint8_t gDTMF_RecvTimeout = 0; + +char gDTMF_RX[17]; +uint8_t gDTMF_RX_index = 0; +uint8_t gDTMF_RX_timeout = 0; +bool gDTMF_RX_pending = false; char gDTMF_RX_live[20]; uint8_t gDTMF_RX_live_timeout = 0; @@ -48,12 +53,9 @@ char gDTMF_ID[4]; char gDTMF_Caller[4]; char gDTMF_Callee[4]; DTMF_State_t gDTMF_State; -bool gDTMF_DecodeRing; uint8_t gDTMF_DecodeRingCountdown_500ms; uint8_t gDTMFChosenContact; uint8_t gDTMF_AUTO_RESET_TIME; -uint8_t gDTMF_InputIndex; -bool gDTMF_InputMode; DTMF_CallState_t gDTMF_CallState; DTMF_ReplyState_t gDTMF_ReplyState; DTMF_CallMode_t gDTMF_CallMode; @@ -61,14 +63,22 @@ bool gDTMF_IsTx; uint8_t gDTMF_TxStopCountdown_500ms; bool gDTMF_IsGroupCall; -bool DTMF_ValidateCodes(char *pCode, uint8_t Size) +void DTMF_clear_RX(void) +{ + gDTMF_RX_timeout = 0; + gDTMF_RX_index = 0; + gDTMF_RX_pending = false; + memset(gDTMF_RX, 0, sizeof(gDTMF_RX)); +} + +bool DTMF_ValidateCodes(char *pCode, const unsigned int size) { unsigned int i; if (pCode[0] == 0xFF || pCode[0] == 0) return false; - for (i = 0; i < Size; i++) + for (i = 0; i < size; i++) { if (pCode[i] == 0xFF || pCode[i] == 0) { @@ -121,16 +131,16 @@ bool DTMF_FindContact(const char *pContact, char *pResult) return false; } -char DTMF_GetCharacter(const uint8_t code) +char DTMF_GetCharacter(const unsigned int code) { const char list[] = "0123456789ABCD*#"; return (code < ARRAY_SIZE(list)) ? list[code] : 0xFF; } -bool DTMF_CompareMessage(const char *pMsg, const char *pTemplate, uint8_t Size, bool bCheckGroup) +bool DTMF_CompareMessage(const char *pMsg, const char *pTemplate, const unsigned int size, const bool bCheckGroup) { unsigned int i; - for (i = 0; i < Size; i++) + for (i = 0; i < size; i++) { if (pMsg[i] != pTemplate[i]) { @@ -140,58 +150,69 @@ bool DTMF_CompareMessage(const char *pMsg, const char *pTemplate, uint8_t Size, } } - return DTMF_CALL_MODE_NOT_GROUP; + return true; } -DTMF_CallMode_t DTMF_CheckGroupCall(const char *pMsg, uint32_t Size) +DTMF_CallMode_t DTMF_CheckGroupCall(const char *pMsg, const unsigned int size) { - uint32_t i; - for (i = 0; i < Size; i++) + unsigned int i; + for (i = 0; i < size; i++) if (pMsg[i] == gEeprom.DTMF_GROUP_CALL_CODE) break; - return (i != Size) ? DTMF_CALL_MODE_GROUP : DTMF_CALL_MODE_NOT_GROUP; + + return (i < size) ? DTMF_CALL_MODE_GROUP : DTMF_CALL_MODE_NOT_GROUP; } -void DTMF_Append(char Code) +void DTMF_Append(const char code) { if (gDTMF_InputIndex == 0) { memset(gDTMF_InputBox, '-', sizeof(gDTMF_InputBox)); gDTMF_InputBox[sizeof(gDTMF_InputBox) - 1] = 0; } - else - if (gDTMF_InputIndex >= sizeof(gDTMF_InputBox)) - return; - gDTMF_InputBox[gDTMF_InputIndex++] = Code; + if (gDTMF_InputIndex < sizeof(gDTMF_InputBox)) + gDTMF_InputBox[gDTMF_InputIndex++] = code; } void DTMF_HandleRequest(void) -{ - char String[20]; - uint8_t Offset; +{ // proccess the RX'ed DTMF characters - if (!gDTMF_RequestPending) - return; + char String[20]; + unsigned int Offset; - gDTMF_RequestPending = false; + if (!gDTMF_RX_pending) + return; // nothing new received if (gScanState != SCAN_OFF || gCssScanMode != CSS_SCAN_MODE_OFF) + { // 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; + } + + gDTMF_RX_pending = false; + + if (gDTMF_RX_index >= 9) + { // look for the KILL code - if (gDTMF_WriteIndex >= 9) - { - Offset = gDTMF_WriteIndex - 9; sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, gEeprom.KILL_CODE); - if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 9, true)) - { + Offset = gDTMF_RX_index - strlen(String); + + if (DTMF_CompareMessage(gDTMF_RX + Offset, String, strlen(String), true)) + { // bugger + if (gEeprom.PERMIT_REMOTE_KILL) { - gSetting_KILLED = true; + gSetting_KILLED = true; // oooerr ! + + DTMF_clear_RX(); SETTINGS_SaveSettings(); @@ -212,82 +233,117 @@ void DTMF_HandleRequest(void) gDTMF_CallState = DTMF_CALL_STATE_NONE; - gUpdateDisplay = true; - gUpdateStatus = true; + gUpdateDisplay = true; + gUpdateStatus = true; return; } - + } + + 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); - if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 9, true)) - { + + Offset = gDTMF_RX_index - strlen(String); + + if (DTMF_CompareMessage(gDTMF_RX + Offset, String, strlen(String), true)) + { // shit, we're back ! + gSetting_KILLED = false; + + DTMF_clear_RX(); + SETTINGS_SaveSettings(); + gDTMF_ReplyState = DTMF_REPLY_AB; gDTMF_CallState = DTMF_CALL_STATE_NONE; + gUpdateDisplay = true; gUpdateStatus = true; return; } } - if (gDTMF_WriteIndex >= 2) - { - if (DTMF_CompareMessage(gDTMF_Received + (gDTMF_WriteIndex - 2), "AB", 2, true)) - { - gDTMF_State = DTMF_STATE_TX_SUCC; - gUpdateDisplay = true; - return; + if (gDTMF_RX_index >= 2) + { // look for ACK reply + + strcpy(String, "AB"); + + Offset = gDTMF_RX_index - strlen(String); + + if (DTMF_CompareMessage(gDTMF_RX + Offset, String, strlen(String), 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_CallState == DTMF_CALL_STATE_CALL_OUT && gDTMF_CallMode == DTMF_CALL_MODE_NOT_GROUP && gDTMF_WriteIndex >= 9) - { - Offset = gDTMF_WriteIndex - 9; - + 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"); - if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 9, false)) - { + Offset = gDTMF_RX_index - strlen(String); + + if (DTMF_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 (gDTMF_WriteIndex >= 7) - { - Offset = gDTMF_WriteIndex - 7; - - sprintf(String, "%s%c", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE); + if (gDTMF_RX_index >= 7) + { // see if we're being called gDTMF_IsGroupCall = false; - if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 4, true)) - { + sprintf(String, "%s%c", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE); + + Offset = gDTMF_RX_index - strlen(String) - 3; + + if (DTMF_CompareMessage(gDTMF_RX + Offset, String, strlen(String), true)) + { // it's for us ! + gDTMF_CallState = DTMF_CALL_STATE_RECEIVED; - memmove(gDTMF_Callee, gDTMF_Received + Offset + 0, 3); - memmove(gDTMF_Caller, gDTMF_Received + Offset + 4, 3); + memset(gDTMF_Callee, 0, sizeof(gDTMF_Callee)); + memset(gDTMF_Caller, 0, sizeof(gDTMF_Caller)); + memmove(gDTMF_Callee, gDTMF_RX + Offset + 0, 3); + memmove(gDTMF_Caller, gDTMF_RX + Offset + 4, 3); + + DTMF_clear_RX(); gUpdateDisplay = true; switch (gEeprom.DTMF_DECODE_RESPONSE) { - case 3: - gDTMF_DecodeRing = true; + case DTMF_DEC_RESPONSE_BOTH: gDTMF_DecodeRingCountdown_500ms = DTMF_decode_ring_countdown_500ms; - // Fallthrough - case 2: + case DTMF_DEC_RESPONSE_REPLY: gDTMF_ReplyState = DTMF_REPLY_AAAAA; break; - case 1: - gDTMF_DecodeRing = true; + case DTMF_DEC_RESPONSE_RING: gDTMF_DecodeRingCountdown_500ms = DTMF_decode_ring_countdown_500ms; break; default: - gDTMF_DecodeRing = false; + case DTMF_DEC_RESPONSE_NONE: + gDTMF_DecodeRingCountdown_500ms = 0; gDTMF_ReplyState = DTMF_REPLY_NONE; break; } @@ -346,12 +402,14 @@ void DTMF_Reply(void) return; Delay = gEeprom.DTMF_PRELOAD_TIME; + if (gEeprom.DTMF_SIDE_TONE) - { + { // the will also hear the transmitted tones GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); gEnableSpeaker = true; Delay = (gEeprom.DTMF_PRELOAD_TIME < 60) ? 60 : gEeprom.DTMF_PRELOAD_TIME; } + SYSTEM_DelayMs(Delay); BK4819_EnterDTMF_TX(gEeprom.DTMF_SIDE_TONE); diff --git a/app/dtmf.h b/app/dtmf.h index 3b4b425..281fae9 100644 --- a/app/dtmf.h +++ b/app/dtmf.h @@ -36,6 +36,13 @@ enum DTMF_CallState_t { DTMF_CALL_STATE_RECEIVED }; +enum DTMF_DecodeResponse_t { + 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 { @@ -56,12 +63,16 @@ enum DTMF_CallMode_t { typedef enum DTMF_CallMode_t DTMF_CallMode_t; extern char gDTMF_String[15]; -extern char gDTMF_InputBox[15]; -extern char gDTMF_Received[16]; -extern uint8_t gDTMF_WriteIndex; +extern char gDTMF_InputBox[15]; +extern uint8_t gDTMF_InputIndex; +extern bool gDTMF_InputMode; extern uint8_t gDTMF_PreviousIndex; -extern uint8_t gDTMF_RecvTimeout; + +extern char gDTMF_RX[17]; +extern uint8_t gDTMF_RX_index; +extern uint8_t gDTMF_RX_timeout; +extern bool gDTMF_RX_pending; extern char gDTMF_RX_live[20]; extern uint8_t gDTMF_RX_live_timeout; @@ -71,25 +82,23 @@ extern char gDTMF_ID[4]; extern char gDTMF_Caller[4]; extern char gDTMF_Callee[4]; extern DTMF_State_t gDTMF_State; -extern bool gDTMF_DecodeRing; extern uint8_t gDTMF_DecodeRingCountdown_500ms; extern uint8_t gDTMFChosenContact; extern uint8_t gDTMF_AUTO_RESET_TIME; -extern uint8_t gDTMF_InputIndex; -extern bool gDTMF_InputMode; extern DTMF_CallState_t gDTMF_CallState; extern DTMF_ReplyState_t gDTMF_ReplyState; extern DTMF_CallMode_t gDTMF_CallMode; extern bool gDTMF_IsTx; extern uint8_t gDTMF_TxStopCountdown_500ms; -bool DTMF_ValidateCodes(char *pCode, uint8_t Size); +void DTMF_clear_RX(void); +bool DTMF_ValidateCodes(char *pCode, const unsigned int size); bool DTMF_GetContact(const int Index, char *pContact); bool DTMF_FindContact(const char *pContact, char *pResult); -char DTMF_GetCharacter(const uint8_t code); -bool DTMF_CompareMessage(const char *pDTMF, const char *pTemplate, uint8_t Size, bool bFlag); -DTMF_CallMode_t DTMF_CheckGroupCall(const char *pDTMF, uint32_t Size); -void DTMF_Append(char Code); +char DTMF_GetCharacter(const unsigned int code); +bool DTMF_CompareMessage(const char *pDTMF, const char *pTemplate, const unsigned int size, const bool bFlag); +DTMF_CallMode_t DTMF_CheckGroupCall(const char *pDTMF, const unsigned int size); +void DTMF_Append(const char vode); void DTMF_HandleRequest(void); void DTMF_Reply(void); diff --git a/app/main.c b/app/main.c index 715efcc..b3a9325 100644 --- a/app/main.c +++ b/app/main.c @@ -458,9 +458,17 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld) { if (!bKeyHeld && bKeyPressed) - { + { // exit key pressed + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + if (gDTMF_CallState != DTMF_CALL_STATE_NONE && gCurrentFunction != FUNCTION_TRANSMIT) + { // clear CALL mode being displayed + gDTMF_CallState = DTMF_CALL_STATE_NONE; + gUpdateDisplay = true; + return; + } + #ifdef ENABLE_FMRADIO if (!gFmRadioMode) #endif @@ -499,7 +507,8 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld) } if (bKeyHeld && bKeyPressed) - { + { // exit key held down + if (gInputBoxIndex > 0) { // cancel key input mode (channel/frequency entry) gDTMF_InputMode = false; @@ -515,7 +524,7 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld) static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld) { if (bKeyHeld) - { // key held down (long press) + { // menu key held down (long press) if (bKeyPressed) { @@ -566,6 +575,7 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld) gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + // TODO: finish this //gEeprom.RX_CHANNEL = () & 1; // swap to the VFO @@ -583,13 +593,13 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld) return; } - if (!bKeyPressed) - { - bool bFlag; + if (!bKeyPressed && !gDTMF_InputMode) + { // menu key released + const bool bFlag = (gInputBoxIndex == 0); + gInputBoxIndex = 0; - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - bFlag = (gInputBoxIndex == 0); - gInputBoxIndex = 0; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + if (bFlag) { gFlagRefreshSetting = true; diff --git a/app/menu.c b/app/menu.c index 70ac672..9a7511a 100644 --- a/app/menu.c +++ b/app/menu.c @@ -110,11 +110,15 @@ int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax) break; case MENU_TDR: - case MENU_XB: *pMin = 0; *pMax = ARRAY_SIZE(gSubMenu_CHAN) - 1; break; + case MENU_XB: + *pMin = 0; + *pMax = ARRAY_SIZE(gSubMenu_XB) - 1; + break; + #ifdef ENABLE_VOICE case MENU_VOICE: *pMin = 0; @@ -603,13 +607,14 @@ void MENU_AcceptSetting(void) case MENU_D_DCD: gTxVfo->DTMF_DECODING_ENABLE = gSubMenuSelection; - gRequestSaveChannel = 1; + DTMF_clear_RX(); + gRequestSaveChannel = 1; return; case MENU_D_LIVE_DEC: - gDTMF_RX_live_timeout = 0; - gDTMF_RX_live[0] = '\0'; 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; @@ -1333,9 +1338,13 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld) gAskForConfirmation = 0; gIsInSubMenu = true; - gInputBoxIndex = 0; - edit_index = -1; - + +// if (gMenuCursor != MENU_D_LIST) + { + gInputBoxIndex = 0; + edit_index = -1; + } + return; } diff --git a/app/scanner.c b/app/scanner.c index cc52d65..4002e38 100644 --- a/app/scanner.c +++ b/app/scanner.c @@ -14,6 +14,7 @@ * limitations under the License. */ +#include "app/dtmf.h" #include "app/generic.h" #include "app/scanner.h" #include "audio.h" @@ -399,12 +400,13 @@ void SCANNER_Start(void) gUpdateStatus = true; } + DTMF_clear_RX(); + gScanDelay_10ms = scan_delay_10ms; gScanCssResultCode = 0xFF; gScanCssResultType = 0xFF; gScanHitCount = 0; gScanUseCssResult = false; - gDTMF_RequestPending = false; g_CxCSS_TAIL_Found = false; g_CDCSS_Lost = false; gCDCSSCodeType = 0; diff --git a/audio.c b/audio.c index 14de43d..94d54d6 100644 --- a/audio.c +++ b/audio.c @@ -76,7 +76,12 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep) uint16_t ToneFrequency; uint16_t Duration; - if (Beep != BEEP_880HZ_60MS_TRIPLE_BEEP && Beep != BEEP_500HZ_60MS_DOUBLE_BEEP && Beep != BEEP_440HZ_500MS && !gEeprom.BEEP_CONTROL) + if (Beep != BEEP_880HZ_60MS_TRIPLE_BEEP && + Beep != BEEP_500HZ_60MS_DOUBLE_BEEP && + Beep != BEEP_440HZ_500MS && + Beep != BEEP_880HZ_200MS && + Beep != BEEP_880HZ_500MS && + !gEeprom.BEEP_CONTROL) return; #ifdef ENABLE_AIRCOPY @@ -123,6 +128,8 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep) break; case BEEP_880HZ_40MS_OPTIONAL: case BEEP_880HZ_60MS_TRIPLE_BEEP: + case BEEP_880HZ_200MS: + case BEEP_880HZ_500MS: ToneFrequency = 880; break; } @@ -161,7 +168,13 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep) Duration = 40; break; + case BEEP_880HZ_200MS: + BK4819_ExitTxMute(); + Duration = 200; + break; + case BEEP_440HZ_500MS: + case BEEP_880HZ_500MS: default: BK4819_ExitTxMute(); Duration = 500; diff --git a/audio.h b/audio.h index 65c2ca6..86b5928 100644 --- a/audio.h +++ b/audio.h @@ -26,6 +26,8 @@ enum BEEP_Type_t BEEP_1KHZ_60MS_OPTIONAL, BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL, BEEP_440HZ_500MS, + BEEP_880HZ_200MS, + BEEP_880HZ_500MS, BEEP_500HZ_60MS_DOUBLE_BEEP, BEEP_440HZ_40MS_OPTIONAL, BEEP_880HZ_40MS_OPTIONAL, diff --git a/driver/bk4819.c b/driver/bk4819.c index 91177b1..49ac4dc 100644 --- a/driver/bk4819.c +++ b/driver/bk4819.c @@ -891,7 +891,7 @@ void BK4819_EnableDTMF(void) // REG_24 <3:0> 14 Max symbol number for SelCall detection // const uint16_t threshold = 24; // doesn't decode non-QS radios - const uint16_t threshold = 200; // but 128 ~ 247 does + const uint16_t threshold = 140; // 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 diff --git a/functions.c b/functions.c index 6f35bf4..5394fde 100644 --- a/functions.c +++ b/functions.c @@ -53,15 +53,8 @@ void FUNCTION_Init(void) gCurrentCodeType = CODE_TYPE_CONTINUOUS_TONE; #endif - gDTMF_RequestPending = false; - - gDTMF_RecvTimeout = 0; - gDTMF_WriteIndex = 0; - memset(gDTMF_Received, 0, sizeof(gDTMF_Received)); - -// gDTMF_RX_timeout_live = 0; -// gDTMF_RX_timeout_live[0] = '\0'; - + DTMF_clear_RX(); + g_CxCSS_TAIL_Found = false; g_CDCSS_Lost = false; g_CTCSS_Lost = false; @@ -152,8 +145,13 @@ void FUNCTION_Select(FUNCTION_Type_t Function) // if DTMF is enabled when TX'ing, it changes the TX audio filtering !! .. 1of11 BK4819_DisableDTMF(); + // clear the DTMF RX buffer + DTMF_clear_RX(); + + // clear the DTMF RX live decoder buffer gDTMF_RX_live_timeout = 0; - gDTMF_RX_live[0] = 0; + gDTMF_RX_live_timeout = 0; + memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live)); #if defined(ENABLE_FMRADIO) if (gFmRadioMode) @@ -189,7 +187,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function) RADIO_SetTxParameters(); - // turn the LED on RED + // turn the RED LED on BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, true); DTMF_Reply(); diff --git a/misc.c b/misc.c index c6d1a12..3b129ac 100644 --- a/misc.c +++ b/misc.c @@ -28,7 +28,7 @@ const uint8_t menu_timeout_500ms = 20000 / 500; // 20 seconds const uint8_t DTMF_RX_live_timeout_500ms = 6000 / 500; // 6 seconds live decoder on screen const uint8_t DTMF_RX_timeout_500ms = 10000 / 500; // 10 seconds till we wipe the DTMF receiver -const uint8_t DTMF_decode_ring_countdown_500ms = 15000 / 500; // 15 seconds +const uint8_t DTMF_decode_ring_countdown_500ms = 15000 / 500; // 15 seconds .. time we sound the ringing for const uint8_t DTMF_txstop_countdown_500ms = 3000 / 500; // 6 seconds const uint8_t key_input_timeout_500ms = 8000 / 500; // 8 seconds @@ -171,7 +171,6 @@ bool gFlagSaveChannel; #ifdef ENABLE_FMRADIO bool gFlagSaveFM; #endif -uint8_t gDTMF_RequestPending; bool g_CDCSS_Lost; uint8_t gCDCSSCodeType; bool g_CTCSS_Lost; diff --git a/misc.h b/misc.h index b8ab28e..bee352d 100644 --- a/misc.h +++ b/misc.h @@ -235,7 +235,6 @@ extern bool gFlagSaveChannel; #ifdef ENABLE_FMRADIO extern bool gFlagSaveFM; #endif -extern uint8_t gDTMF_RequestPending; extern bool g_CDCSS_Lost; extern uint8_t gCDCSSCodeType; extern bool g_CTCSS_Lost; diff --git a/radio.c b/radio.c index 9356b0b..175807b 100644 --- a/radio.c +++ b/radio.c @@ -436,7 +436,7 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo) uint16_t Base = (Band < BAND4_174MHz) ? 0x1E60 : 0x1E00; if (gEeprom.SQUELCH_LEVEL == 0) - { + { // squelch == 0 (off) pInfo->SquelchOpenRSSIThresh = 0; pInfo->SquelchOpenNoiseThresh = 127; pInfo->SquelchCloseGlitchThresh = 255; @@ -446,9 +446,8 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo) pInfo->SquelchOpenGlitchThresh = 255; } else - { - Base += gEeprom.SQUELCH_LEVEL; - // my squelch-1 + { // squelch >= 1 + Base += gEeprom.SQUELCH_LEVEL; // my squelch-1 // VHF UHF EEPROM_ReadBuffer(Base + 0x00, &pInfo->SquelchOpenRSSIThresh, 1); // 50 10 EEPROM_ReadBuffer(Base + 0x10, &pInfo->SquelchCloseRSSIThresh, 1); // 40 5 @@ -459,37 +458,22 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo) EEPROM_ReadBuffer(Base + 0x40, &pInfo->SquelchCloseGlitchThresh, 1); // 90 90 EEPROM_ReadBuffer(Base + 0x50, &pInfo->SquelchOpenGlitchThresh, 1); // 100 100 - #if ENABLE_SQUELCH1_LOWER - // make squelch-1 more sensitive - if (gEeprom.SQUELCH_LEVEL == 1) - { - if (Band < BAND4_174MHz) - { - pInfo->SquelchOpenRSSIThresh = ((uint16_t)pInfo->SquelchOpenRSSIThresh * 11) / 12; - pInfo->SquelchCloseRSSIThresh = ((uint16_t)pInfo->SquelchOpenRSSIThresh * 9) / 10; + #if ENABLE_SQUELCH_LOWER + // make squelch more sensitive - pInfo->SquelchOpenNoiseThresh = ((uint16_t)pInfo->SquelchOpenNoiseThresh * 9) / 8; - pInfo->SquelchCloseNoiseThresh = ((uint16_t)pInfo->SquelchOpenNoiseThresh * 10) / 9; + pInfo->SquelchOpenRSSIThresh = ((uint16_t)pInfo->SquelchOpenRSSIThresh * 8) / 9; + pInfo->SquelchCloseRSSIThresh = ((uint16_t)pInfo->SquelchOpenRSSIThresh * 7) / 8; - pInfo->SquelchOpenGlitchThresh = ((uint16_t)pInfo->SquelchOpenGlitchThresh * 9) / 8; - pInfo->SquelchCloseGlitchThresh = ((uint16_t)pInfo->SquelchOpenGlitchThresh * 10) / 9; - } - else - { - pInfo->SquelchOpenRSSIThresh = ((uint16_t)pInfo->SquelchOpenRSSIThresh * 3) / 4; - pInfo->SquelchCloseRSSIThresh = ((uint16_t)pInfo->SquelchOpenRSSIThresh * 9) / 10; + pInfo->SquelchOpenNoiseThresh = ((uint16_t)pInfo->SquelchOpenNoiseThresh * 8) / 7; + pInfo->SquelchCloseNoiseThresh = ((uint16_t)pInfo->SquelchOpenNoiseThresh * 9) / 8; - pInfo->SquelchOpenNoiseThresh = ((uint16_t)pInfo->SquelchOpenNoiseThresh * 4) / 3; - pInfo->SquelchCloseNoiseThresh = ((uint16_t)pInfo->SquelchOpenNoiseThresh * 10) / 9; - - pInfo->SquelchOpenGlitchThresh = ((uint16_t)pInfo->SquelchOpenGlitchThresh * 4) / 3; - pInfo->SquelchCloseGlitchThresh = ((uint16_t)pInfo->SquelchOpenGlitchThresh * 10) / 9; - } - } + pInfo->SquelchOpenGlitchThresh = ((uint16_t)pInfo->SquelchOpenGlitchThresh * 8) / 7; + pInfo->SquelchCloseGlitchThresh = ((uint16_t)pInfo->SquelchOpenGlitchThresh * 9) / 8; #endif if (pInfo->SquelchOpenNoiseThresh > 127) pInfo->SquelchOpenNoiseThresh = 127; + if (pInfo->SquelchCloseNoiseThresh > 127) pInfo->SquelchCloseNoiseThresh = 127; } @@ -747,9 +731,6 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0) #endif #if 0 - // there's no reason the DTMF decoder can't be used in AM RX mode too - // aircraft comms use it on HF (AM and SSB) -// if (gRxVfo->AM_mode || (!gRxVfo->DTMF_DECODING_ENABLE && !gSetting_KILLED)) if (!gRxVfo->DTMF_DECODING_ENABLE && !gSetting_KILLED) { BK4819_DisableDTMF(); @@ -760,7 +741,7 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0) InterruptMask |= BK4819_REG_3F_DTMF_5TONE_FOUND; } #else - if (gCurrentFunction != FUNCTION_TRANSMIT && gSetting_live_DTMF_decoder) + if (gCurrentFunction != FUNCTION_TRANSMIT) { BK4819_EnableDTMF(); InterruptMask |= BK4819_REG_3F_DTMF_5TONE_FOUND; diff --git a/settings.c b/settings.c index e0203a7..649eca4 100644 --- a/settings.c +++ b/settings.c @@ -214,7 +214,7 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, | (pVFO->OUTPUT_POWER << 2) | (pVFO->CHANNEL_BANDWIDTH << 1) | (pVFO->FrequencyReverse << 0); - State[5] = (pVFO->DTMF_PTT_ID_TX_MODE << 1) | (pVFO->DTMF_DECODING_ENABLE < 0); + State[5] = (pVFO->DTMF_PTT_ID_TX_MODE << 1) | (pVFO->DTMF_DECODING_ENABLE << 0); State[6] = pVFO->STEP_SETTING; State[7] = pVFO->SCRAMBLING_TYPE; EEPROM_WriteBuffer(OffsetVFO + 8, State); diff --git a/ui/main.c b/ui/main.c index 6b41e2c..32f9df1 100644 --- a/ui/main.c +++ b/ui/main.c @@ -36,6 +36,8 @@ #include "ui/main.h" #include "ui/ui.h" +bool center_line_is_free = true; + // *************************************************************************** #ifdef ENABLE_AUDIO_BAR @@ -117,11 +119,12 @@ #if defined(ENABLE_RSSI_BAR) void UI_DisplayRSSIBar(const int16_t rssi, const bool now) { - const int16_t s9_dBm = -73; // S9 - const int16_t s0_dBm = -127; // S0 +// const int16_t s0_dBm = -127; // S0 .. base level + const int16_t s0_dBm = -147; // S0 .. base level + const int16_t s9_dBm = s0_dBm + (6 * 9); // S9 .. 6dB/S-Point const int16_t bar_max_dBm = s9_dBm + 30; // S9+30dB - const int16_t bar_min_dBm = s0_dBm; // S0 + const int16_t bar_min_dBm = s0_dBm + (6 * 4); // S4 // ************ @@ -129,8 +132,8 @@ const unsigned int bar_x = 2 + txt_width + 4; // X coord of bar graph const unsigned int bar_width = LCD_WIDTH - 1 - bar_x; - const int16_t dBm = (rssi / 2) - 160; - const int16_t clamped_dBm = (dBm <= bar_min_dBm) ? bar_min_dBm : (dBm >= bar_max_dBm) ? bar_max_dBm : dBm; + const int16_t rssi_dBm = (rssi / 2) - 160; + const int16_t clamped_dBm = (rssi_dBm <= bar_min_dBm) ? bar_min_dBm : (rssi_dBm >= bar_max_dBm) ? bar_max_dBm : rssi_dBm; const unsigned int bar_range_dB = bar_max_dBm - bar_min_dBm; const unsigned int len = ((clamped_dBm - bar_min_dBm) * bar_width) / bar_range_dB; @@ -139,26 +142,26 @@ char s[16]; unsigned int i; - unsigned int s_level = 0; // S0 if (gEeprom.KEY_LOCK && gKeypadLocked > 0) return; // display is in use if (gCurrentFunction == FUNCTION_TRANSMIT || gScreenToDisplay != DISPLAY_MAIN) return; // display is in use - if (dBm >= (s9_dBm + 10)) // S9+10dB - s_level = ((dBm - s9_dBm) / 10) * 10; - else - if (dBm >= s0_dBm) // S0 - s_level = (dBm - s0_dBm) / 6; // 6dB per S point - if (now) memset(pLine, 0, LCD_WIDTH); - if (s_level < 10) - sprintf(s, "%-4d S%u ", dBm, s_level); // S0 ~ S9 + if (rssi_dBm >= (s9_dBm + 6)) + { // S9+XXdB, 1dB increment + const char *fmt[] = {"%-4d +%u ", "%-4d +%u "}; + const unsigned int dB = rssi_dBm - s9_dBm; + sprintf(s, (dB < 10) ? fmt[0] : fmt[1], rssi_dBm, dB); + } else - sprintf(s, "%-4d +%2u", dBm, s_level); // S9+XX + { // S0 ~ S9, 6dB per S-point + const unsigned int s_level = (rssi_dBm >= s0_dBm) ? (rssi_dBm - s0_dBm) / 6 : 0; + sprintf(s, "%-4d S%u ", rssi_dBm, s_level); + } UI_PrintStringSmall(s, 2, 0, line); #if 1 @@ -180,6 +183,9 @@ void UI_UpdateRSSI(const int16_t rssi, const int vfo) { #ifdef ENABLE_RSSI_BAR + if (!center_line_is_free) + return; + const bool rx = (gCurrentFunction == FUNCTION_RECEIVE || gCurrentFunction == FUNCTION_MONITOR || gCurrentFunction == FUNCTION_INCOMING); @@ -286,7 +292,8 @@ void UI_DisplayMain(void) { char String[16]; unsigned int vfo_num; - bool center_line_is_free = true; + + center_line_is_free = true; // #ifdef SINGLE_VFO_CHAN // const bool single_vfo = (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? true : false; @@ -338,7 +345,7 @@ void UI_DisplayMain(void) strcpy(String, (gDTMF_State == DTMF_STATE_CALL_OUT_RSP) ? "CALL OUT(RSP)" : "CALL OUT"); else if (gDTMF_CallState == DTMF_CALL_STATE_RECEIVED) - sprintf(String, "CALL:%s", (DTMF_FindContact(gDTMF_Caller, Contact)) ? Contact : gDTMF_Caller); + sprintf(String, "CALL FRM:%s", (DTMF_FindContact(gDTMF_Caller, Contact)) ? Contact : gDTMF_Caller); else if (gDTMF_IsTx) strcpy(String, (gDTMF_State == DTMF_STATE_TX_SUCC) ? "DTMF TX(SUCC)" : "DTMF TX"); @@ -680,7 +687,7 @@ void UI_DisplayMain(void) UI_PrintStringSmall(String, LCD_WIDTH + 70, 0, Line + 1); } - // show the DTMF decoding symbol( + // show the DTMF decoding symbol if (gEeprom.VfoInfo[vfo_num].DTMF_DECODING_ENABLE || gSetting_KILLED) UI_PrintStringSmall("DTMF", LCD_WIDTH + 78, 0, Line + 1); @@ -719,14 +726,25 @@ void UI_DisplayMain(void) if (rx || gCurrentFunction == FUNCTION_FOREGROUND || gCurrentFunction == FUNCTION_POWER_SAVE) { - if (gSetting_live_DTMF_decoder && gDTMF_RX_live[0] >= 32) - { // 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 - strcpy(String, "DTMF "); - strcat(String, gDTMF_RX_live + idx); - UI_PrintStringSmall(String, 2, 0, 3); - } + #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 + strcpy(String, "DTMF "); + strcat(String, gDTMF_RX_live + idx); + UI_PrintStringSmall(String, 2, 0, 3); + } + #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 + strcpy(String, "DTMF "); + strcat(String, gDTMF_RX + idx); + UI_PrintStringSmall(String, 2, 0, 3); + } + #endif #ifdef ENABLE_SHOW_CHARGE_LEVEL else diff --git a/ui/menu.c b/ui/menu.c index 3af00c9..3c6dc47 100644 --- a/ui/menu.c +++ b/ui/menu.c @@ -184,8 +184,15 @@ const char gSubMenu_TOT[11][7] = const char gSubMenu_CHAN[3][7] = { "OFF", - "CHAN_A", - "CHAN_B" + "CHAN A", + "CHAN B" +}; + +const char gSubMenu_XB[3][7] = +{ + "SAME", + "CHAN A", + "CHAN B" }; #ifdef ENABLE_VOICE @@ -575,10 +582,13 @@ void UI_DisplayMenu(void) break; case MENU_TDR: - case MENU_XB: strcpy(String, gSubMenu_CHAN[gSubMenuSelection]); break; + case MENU_XB: + strcpy(String, gSubMenu_XB[gSubMenuSelection]); + break; + case MENU_TOT: strcpy(String, gSubMenu_TOT[gSubMenuSelection]); break; diff --git a/ui/menu.h b/ui/menu.h index 3cd187e..1356510 100644 --- a/ui/menu.h +++ b/ui/menu.h @@ -125,6 +125,7 @@ extern const char gSubMenu_OFF_ON[2][4]; extern const char gSubMenu_SAVE[5][4]; extern const char gSubMenu_TOT[11][7]; extern const char gSubMenu_CHAN[3][7]; +extern const char gSubMenu_XB[3][7]; #ifdef ENABLE_VOICE extern const char gSubMenu_VOICE[3][4]; #endif