diff --git a/Makefile b/Makefile index f194b92..6fe777f 100644 --- a/Makefile +++ b/Makefile @@ -26,8 +26,8 @@ ENABLE_NO_SCAN_TIMEOUT := 1 ENABLE_AM_FIX := 1 ENABLE_AM_FIX_SHOW_DATA := 1 ENABLE_SQUELCH1_LOWER := 0 -ENABLE_RSSI_BAR := 1 -ENABLE_AUDIO_BAR := 1 +ENABLE_RSSI_BAR := 0 +ENABLE_AUDIO_BAR := 0 #ENABLE_COPY_CHAN_TO_VFO := 1 #ENABLE_SINGLE_VFO_CHAN := 1 #ENABLE_BAND_SCOPE := 1 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..42c641f 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; } 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 e2e5f5a..3acd3d6 100644 --- a/app/main.c +++ b/app/main.c @@ -452,9 +452,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 @@ -493,7 +501,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; @@ -509,7 +518,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) { @@ -560,6 +569,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 @@ -577,13 +587,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 db627f6..c19fcd4 100644 --- a/app/menu.c +++ b/app/menu.c @@ -109,11 +109,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; @@ -591,13 +595,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; @@ -1317,9 +1322,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/firmware.bin b/firmware.bin index d0e66df..329b347 100644 Binary files a/firmware.bin and b/firmware.bin differ diff --git a/firmware.packed.bin b/firmware.packed.bin index 7ac0589..7d7b337 100644 Binary files a/firmware.packed.bin and b/firmware.packed.bin differ 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 efb619b..ce567a1 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 @@ -174,7 +174,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 517e28b..a27ba72 100644 --- a/misc.h +++ b/misc.h @@ -238,7 +238,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..d1f7ef8 100644 --- a/radio.c +++ b/radio.c @@ -747,9 +747,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 +757,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 f0dd0f4..47da6cb 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 @@ -180,6 +182,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,8 +291,9 @@ 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; // #else @@ -338,7 +344,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 +686,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); @@ -722,15 +728,26 @@ void UI_DisplayMain(void) if (rx || gCurrentFunction == FUNCTION_FOREGROUND) { - 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 if (gChargingWithTypeC) diff --git a/ui/menu.c b/ui/menu.c index 24d4d09..2399cf6 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