diff --git a/app/dtmf.c b/app/dtmf.c index fc70b0c..8c9a9c1 100644 --- a/app/dtmf.c +++ b/app/dtmf.c @@ -86,7 +86,7 @@ bool DTMF_ValidateCodes(char *pCode, uint8_t Size) bool DTMF_GetContact(const int Index, char *pContact) { int i = -1; - if (Index >= 0 && Index < 16 && pContact != NULL) // max 16 DTMF contacts + if (Index >= 0 && Index < MAX_DTMF_CONTACTS && pContact != NULL) { EEPROM_ReadBuffer(0x1C00 + (Index * 16), pContact, 16); i = (int)pContact[0] - ' '; @@ -96,10 +96,10 @@ bool DTMF_GetContact(const int Index, char *pContact) bool DTMF_FindContact(const char *pContact, char *pResult) { - char Contact [16]; + char Contact[16]; unsigned int i; - for (i = 0; i < 16; i++) + for (i = 0; i < MAX_DTMF_CONTACTS; i++) { unsigned int j; @@ -130,7 +130,6 @@ char DTMF_GetCharacter(const uint8_t code) bool DTMF_CompareMessage(const char *pMsg, const char *pTemplate, uint8_t Size, bool bCheckGroup) { unsigned int i; - for (i = 0; i < Size; i++) { if (pMsg[i] != pTemplate[i]) @@ -147,7 +146,6 @@ bool DTMF_CompareMessage(const char *pMsg, const char *pTemplate, uint8_t Size, bool DTMF_CheckGroupCall(const char *pMsg, uint32_t Size) { uint32_t i; - for (i = 0; i < Size; i++) if (pMsg[i] == gEeprom.DTMF_GROUP_CALL_CODE) break; @@ -189,12 +187,15 @@ void DTMF_HandleRequest(void) { 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)) { if (gEeprom.PERMIT_REMOTE_KILL) { gSetting_KILLED = true; + SETTINGS_SaveSettings(); + gDTMF_ReplyState = DTMF_REPLY_AB; #ifdef ENABLE_FMRADIO @@ -220,12 +221,12 @@ void DTMF_HandleRequest(void) 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)) { - gSetting_KILLED = false; + gSetting_KILLED = false; SETTINGS_SaveSettings(); gDTMF_ReplyState = DTMF_REPLY_AB; - gDTMF_CallState = DTMF_CALL_STATE_NONE; - gUpdateDisplay = true; - gUpdateStatus = true; + gDTMF_CallState = DTMF_CALL_STATE_NONE; + gUpdateDisplay = true; + gUpdateStatus = true; return; } } @@ -234,7 +235,7 @@ void DTMF_HandleRequest(void) { if (DTMF_CompareMessage(gDTMF_Received + (gDTMF_WriteIndex - 2), "AB", 2, true)) { - gDTMF_State = DTMF_STATE_TX_SUCC; + gDTMF_State = DTMF_STATE_TX_SUCC; gUpdateDisplay = true; return; } @@ -243,10 +244,12 @@ void DTMF_HandleRequest(void) if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT && gDTMF_CallMode == DTMF_CALL_MODE_NOT_GROUP && gDTMF_WriteIndex >= 9) { Offset = gDTMF_WriteIndex - 9; + sprintf(String, "%s%c%s", gDTMF_String, gEeprom.DTMF_SEPARATE_CODE, "AAAAA"); + if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 9, false)) { - gDTMF_State = DTMF_STATE_CALL_OUT_RSP; + gDTMF_State = DTMF_STATE_CALL_OUT_RSP; gUpdateDisplay = true; } } @@ -257,12 +260,16 @@ void DTMF_HandleRequest(void) if (gDTMF_WriteIndex >= 7) { Offset = gDTMF_WriteIndex - 7; + sprintf(String, "%s%c", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE); + gDTMF_IsGroupCall = false; + if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 4, true)) { gDTMF_CallState = DTMF_CALL_STATE_RECEIVED; - memmove(gDTMF_Callee, gDTMF_Received + Offset, 3); + + memmove(gDTMF_Callee, gDTMF_Received + Offset + 0, 3); memmove(gDTMF_Caller, gDTMF_Received + Offset + 4, 3); gUpdateDisplay = true; @@ -364,4 +371,3 @@ void DTMF_Reply(void) BK4819_ExitDTMF_TX(false); } - diff --git a/app/dtmf.h b/app/dtmf.h index fdcf614..1ffd8b3 100644 --- a/app/dtmf.h +++ b/app/dtmf.h @@ -20,6 +20,8 @@ #include #include +#define MAX_DTMF_CONTACTS 16 + enum DTMF_State_t { DTMF_STATE_0 = 0, DTMF_STATE_TX_SUCC, diff --git a/app/fm.c b/app/fm.c index 1573ab9..39e6a53 100644 --- a/app/fm.c +++ b/app/fm.c @@ -59,7 +59,11 @@ uint8_t FM_FindNextChannel(uint8_t Channel, uint8_t Direction) for (i = 0; i < ARRAY_SIZE(gFM_Channels); i++) { - Channel %= ARRAY_SIZE(gFM_Channels); + 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; @@ -182,7 +186,7 @@ int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit) 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) { - // if (Deviation > -281 && Deviation < 280) + //if (Deviation > -281 && Deviation < 280) if (Deviation < 280 || Deviation > 3815) { // not BLE(less than or equal) diff --git a/app/main.c b/app/main.c index 3cbe149..5a9b0ec 100644 --- a/app/main.c +++ b/app/main.c @@ -314,6 +314,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) gInputBoxIndex = 0; Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1; + if (!RADIO_CheckValidChannel(Channel, false, 0)) { gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; @@ -398,7 +399,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) gInputBoxIndex = 0; Channel = (gInputBox[0] * 10) + gInputBox[1]; - if (Channel >= 1 && Channel <= 10) + if (Channel >= 1 && Channel <= ARRAY_SIZE(NoaaFrequencyTable)) { Channel += NOAA_CHANNEL_FIRST; #ifdef ENABLE_VOICE diff --git a/app/menu.c b/app/menu.c index 46552c5..02bdb9e 100644 --- a/app/menu.c +++ b/app/menu.c @@ -39,6 +39,7 @@ #endif #include "ui/inputbox.h" #include "ui/menu.h" +#include "ui/menu.h" #include "ui/ui.h" #ifndef ARRAY_SIZE @@ -64,15 +65,16 @@ VOICE_ID_BUSY_LOCKOUT, // BUSYCL VOICE_ID_MEMORY_CHANNEL, // CH-SAV VOICE_ID_DELETE_CHANNEL, // CH-DEL + VOICE_ID_INVALID, // CH-EDIT VOICE_ID_INVALID, // CH-DIS VOICE_ID_SAVE_MODE, // BATSAV VOICE_ID_VOX, // VOX VOICE_ID_INVALID, // BACKLT VOICE_ID_DUAL_STANDBY, // DUALRX VOICE_ID_BEEP_PROMPT, // BEEP - #ifdef ENABLE_VOICE + #ifdef ENABLE_VOICE VOICE_ID_VOICE_PROMPT, // VOICE - #endif + #endif VOICE_ID_INVALID, // SC-REV VOICE_ID_INVALID, // KEYLOC VOICE_ID_INVALID, // S-ADD1 @@ -285,17 +287,16 @@ int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax) case MENU_MEM_CH: case MENU_1_CALL: -// case MENU_SLIST1: -// case MENU_SLIST2: case MENU_DEL_CH: + case MENU_MEM_NAME: *pMin = 0; - *pMax = 199; + *pMax = MR_CHANNEL_LAST; break; case MENU_SLIST1: case MENU_SLIST2: *pMin = -1; - *pMax = 199; + *pMax = MR_CHANNEL_LAST; break; case MENU_SAVE: @@ -344,8 +345,8 @@ int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax) break; case MENU_F_CALI: - *pMin = -1000; - *pMax = +1000; + *pMin = -50; + *pMax = +50; break; default: @@ -373,7 +374,7 @@ void MENU_AcceptSetting(void) { default: return; - + case MENU_SQL: gEeprom.SQUELCH_LEVEL = gSubMenuSelection; gVfoConfigureMode = VFO_CONFIGURE_1; @@ -479,7 +480,28 @@ void MENU_AcceptSetting(void) case MENU_MEM_CH: gTxVfo->CHANNEL_SAVE = gSubMenuSelection; gRequestSaveChannel = 2; - gEeprom.MrChannel[0] = gSubMenuSelection; + #if 0 + gEeprom.MrChannel[0] = gSubMenuSelection; + #else + gEeprom.MrChannel[gEeprom.TX_CHANNEL] = gSubMenuSelection; + #endif + return; + + case MENU_MEM_NAME: + { // trailing trim + for (int i = 9; i >= 0; i--) + { + if (edit[i] != ' ' && edit[i] != '_' && edit[i] != 0 && edit[i] != 0xff) + break; + edit[i] = ' '; + } + } + + // save the channel name + memset(gTxVfo->Name, 0xff, sizeof(gTxVfo->Name)); + memmove(gTxVfo->Name, edit, 10); + SETTINGS_SaveChannel(gSubMenuSelection, gEeprom.TX_CHANNEL, gTxVfo, 2); + gFlagReconfigureVfos = true; return; case MENU_SAVE: @@ -623,13 +645,15 @@ void MENU_AcceptSetting(void) case MENU_BAT_TXT: gSetting_battery_text = gSubMenuSelection; break; - + case MENU_D_DCD: gTxVfo->DTMF_DECODING_ENABLE = gSubMenuSelection; gRequestSaveChannel = 1; return; case MENU_D_LIVE_DEC: + gDTMF_RecvTimeoutSaved = 0; + gDTMF_ReceivedSaved[0] = '\0'; gSetting_live_DTMF_decoder = gSubMenuSelection; break; @@ -873,6 +897,10 @@ void MENU_ShowCurrentSetting(void) #endif break; + case MENU_MEM_NAME: + gSubMenuSelection = gEeprom.MrChannel[gEeprom.TX_CHANNEL]; + break; + case MENU_SAVE: gSubMenuSelection = gEeprom.BATTERY_SAVE; break; @@ -990,7 +1018,7 @@ void MENU_ShowCurrentSetting(void) case MENU_BAT_TXT: gSubMenuSelection = gSetting_battery_text; return; - + case MENU_D_DCD: gSubMenuSelection = gTxVfo->DTMF_DECODING_ENABLE; break; @@ -1065,12 +1093,12 @@ void MENU_ShowCurrentSetting(void) static void MENU_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) { + uint8_t Offset; + int32_t Min; + int32_t Max; uint16_t Value = 0; - if (bKeyHeld) - return; - - if (!bKeyPressed) + if (bKeyHeld || !bKeyPressed) return; gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; @@ -1106,89 +1134,92 @@ static void MENU_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) } gInputBoxIndex = 0; + + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; } - else + + if (gMenuCursor == MENU_OFFSET) { - if (gMenuCursor == MENU_OFFSET) - { - uint32_t Frequency; + uint32_t Frequency; - if (gInputBoxIndex < 6) - { - #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; - #endif - return; - } - - gInputBoxIndex = 0; - NUMBER_Get(gInputBox, &Frequency); - Frequency += 75; + if (gInputBoxIndex < 6) + { // invalid frequency #ifdef ENABLE_VOICE gAnotherVoiceID = (VOICE_ID_t)Key; #endif - gSubMenuSelection = FREQUENCY_FloorToStep(Frequency, gTxVfo->StepFrequency, 0); return; } - if (gMenuCursor == MENU_MEM_CH || gMenuCursor == MENU_DEL_CH || gMenuCursor == MENU_1_CALL) + #ifdef ENABLE_VOICE + gAnotherVoiceID = (VOICE_ID_t)Key; + #endif + + NUMBER_Get(gInputBox, &Frequency); + gSubMenuSelection = FREQUENCY_FloorToStep(Frequency + 62, gTxVfo->StepFrequency, 0); + + gInputBoxIndex = 0; + return; + } + + if (gMenuCursor == MENU_MEM_CH || gMenuCursor == MENU_DEL_CH || gMenuCursor == MENU_1_CALL || gMenuCursor == MENU_MEM_NAME) + { // enter 3-digit channel number + + if (gInputBoxIndex < 3) { - if (gInputBoxIndex < 3) - { - #ifdef ENABLE_VOICE - gAnotherVoiceID = (VOICE_ID_t)Key; - #endif - gRequestDisplayScreen = DISPLAY_MENU; - return; - } - - gInputBoxIndex = 0; - - 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; - } + #ifdef ENABLE_VOICE + gAnotherVoiceID = (VOICE_ID_t)Key; + #endif + gRequestDisplayScreen = DISPLAY_MENU; + return; } - else + + gInputBoxIndex = 0; + + Value = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1; + + if (IS_MR_CHANNEL(Value)) { - int32_t Min; - int32_t Max; - - if (!MENU_GetLimits(gMenuCursor, &Min, &Max)) - { - const uint8_t 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; - } - - if (Offset == gInputBoxIndex) - gInputBoxIndex = 0; - - if (Value <= Max) - { - gSubMenuSelection = Value; - return; - } - } - else - gInputBoxIndex = 0; + #ifdef ENABLE_VOICE + gAnotherVoiceID = (VOICE_ID_t)Key; + #endif + gSubMenuSelection = Value; + return; } + + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } + + if (MENU_GetLimits(gMenuCursor, &Min, &Max)) + { + gInputBoxIndex = 0; + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + return; + } + + 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; + } + + if (Offset == gInputBoxIndex) + gInputBoxIndex = 0; + + if (Value <= Max) + { + gSubMenuSelection = Value; + return; } gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; @@ -1196,162 +1227,213 @@ static void MENU_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) static void MENU_Key_EXIT(bool bKeyPressed, bool bKeyHeld) { - if (!bKeyHeld && bKeyPressed) + if (bKeyHeld || !bKeyPressed) + return; + + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + + if (gCssScanMode == CSS_SCAN_MODE_OFF) { - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - - if (gCssScanMode == CSS_SCAN_MODE_OFF) + if (gIsInSubMenu) { - if (gIsInSubMenu) + if (gInputBoxIndex == 0 || gMenuCursor != MENU_OFFSET) { - if (gInputBoxIndex == 0 || gMenuCursor != MENU_OFFSET) - { - gAskForConfirmation = 0; // fix bug - gIsInSubMenu = false; - gInputBoxIndex = 0; - gFlagRefreshSetting = true; - #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_CANCEL; - #endif - } - else - gInputBox[--gInputBoxIndex] = 10; + gAskForConfirmation = 0; + gIsInSubMenu = false; + gInputBoxIndex = 0; + gFlagRefreshSetting = true; - gRequestDisplayScreen = DISPLAY_MENU; - return; - } - - #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_CANCEL; - #endif - gRequestDisplayScreen = DISPLAY_MAIN; - } - else - { - MENU_StopCssScan(); - #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_SCANNING_STOP; - #endif - gRequestDisplayScreen = DISPLAY_MENU; - } - - gPttWasReleased = true; - } -} - -static void MENU_Key_MENU(bool bKeyPressed, bool bKeyHeld) -{ - if (!bKeyHeld && bKeyPressed) - { - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - gRequestDisplayScreen = DISPLAY_MENU; - - if (!gIsInSubMenu) - { - #ifdef ENABLE_VOICE - if (gMenuCursor != MENU_SCR) - gAnotherVoiceID = MenuVoices[gMenuCursor]; - #endif - - gAskForConfirmation = 0; - gIsInSubMenu = true; - } - else - { - if (gMenuCursor == MENU_RESET || gMenuCursor == MENU_MEM_CH || gMenuCursor == MENU_DEL_CH) - { - switch (gAskForConfirmation) - { - case 0: - gAskForConfirmation = 1; - break; - case 1: - gAskForConfirmation = 2; - - UI_DisplayMenu(); - - if (gMenuCursor == MENU_RESET) - { - #ifdef ENABLE_VOICE - AUDIO_SetVoiceID(0, VOICE_ID_CONFIRM); - AUDIO_PlaySingleVoice(true); - #endif - MENU_AcceptSetting(); - - #if defined(ENABLE_OVERLAY) - overlay_FLASH_RebootToBootloader(); - #else - NVIC_SystemReset(); - #endif - } - - gFlagAcceptSetting = true; - gIsInSubMenu = false; - gAskForConfirmation = 0; - } + #ifdef ENABLE_VOICE + gAnotherVoiceID = VOICE_ID_CANCEL; + #endif } else - { - gFlagAcceptSetting = true; - gIsInSubMenu = false; - } + gInputBox[--gInputBoxIndex] = 10; - gCssScanMode = CSS_SCAN_MODE_OFF; - gUpdateStatus = true; - - #ifdef ENABLE_VOICE - if (gMenuCursor == MENU_SCR) - gAnotherVoiceID = (gSubMenuSelection == 0) ? VOICE_ID_SCRAMBLER_OFF : VOICE_ID_SCRAMBLER_ON; - else - gAnotherVoiceID = VOICE_ID_CONFIRM; - #endif - } - - gInputBoxIndex = 0; - } -} - -static void MENU_Key_STAR(bool bKeyPressed, bool bKeyHeld) -{ - if (!bKeyHeld && bKeyPressed) - { - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; - - RADIO_SelectVfos(); - - #ifdef ENABLE_NOAA - if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && !gRxVfo->IsAM) - #else - if (!gRxVfo->IsAM) - #endif - { - if (gMenuCursor == MENU_R_CTCS || gMenuCursor == MENU_R_DCS) - { - if (gCssScanMode == CSS_SCAN_MODE_OFF) - { - MENU_StartCssScan(1); - gRequestDisplayScreen = DISPLAY_MENU; - #ifdef ENABLE_VOICE - AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN); - AUDIO_PlaySingleVoice(1); - #endif - } - else - { - MENU_StopCssScan(); - gRequestDisplayScreen = DISPLAY_MENU; - #ifdef ENABLE_VOICE - gAnotherVoiceID = VOICE_ID_SCANNING_STOP; - #endif - } - } - - gPttWasReleased = true; + gRequestDisplayScreen = DISPLAY_MENU; return; } - gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; + #ifdef ENABLE_VOICE + gAnotherVoiceID = VOICE_ID_CANCEL; + #endif + + gRequestDisplayScreen = DISPLAY_MAIN; } + else + { + MENU_StopCssScan(); + + #ifdef ENABLE_VOICE + gAnotherVoiceID = VOICE_ID_SCANNING_STOP; + #endif + + gRequestDisplayScreen = DISPLAY_MENU; + } + + gPttWasReleased = true; +} + +static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld) +{ + if (bKeyHeld || !bKeyPressed) + return; + + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gRequestDisplayScreen = DISPLAY_MENU; + + if (!gIsInSubMenu) + { + #ifdef ENABLE_VOICE + if (gMenuCursor != MENU_SCR) + gAnotherVoiceID = MenuVoices[gMenuCursor]; + #endif + + #if 1 + if (gMenuCursor == MENU_DEL_CH || gMenuCursor == MENU_MEM_NAME) + if (!RADIO_CheckValidChannel(gSubMenuSelection, false, 0)) + return; // invalid channel + #endif + + gAskForConfirmation = 0; + gIsInSubMenu = true; + gInputBoxIndex = 0; + edit_index = -1; + + return; + } + + if (gMenuCursor == MENU_MEM_NAME) + { + if (edit_index < 0) + { // enter channel name edit mode + if (!RADIO_CheckValidChannel(gSubMenuSelection, false, 0)) + { + return; + } + + BOARD_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 + + return; + } + else + if (edit_index >= 0 && edit_index < 10) + { // editing the channel name characters + + if (++edit_index < 10) + return; // next char + + // exit + gFlagAcceptSetting = false; + gAskForConfirmation = 0; + } + } + + if (gMenuCursor == MENU_RESET || + gMenuCursor == MENU_MEM_CH || + gMenuCursor == MENU_DEL_CH || + gMenuCursor == MENU_MEM_NAME) + { + switch (gAskForConfirmation) + { + case 0: + gAskForConfirmation = 1; + break; + + case 1: + gAskForConfirmation = 2; + + UI_DisplayMenu(); + + if (gMenuCursor == MENU_RESET) + { + #ifdef ENABLE_VOICE + AUDIO_SetVoiceID(0, VOICE_ID_CONFIRM); + AUDIO_PlaySingleVoice(true); + #endif + + MENU_AcceptSetting(); + + #if defined(ENABLE_OVERLAY) + overlay_FLASH_RebootToBootloader(); + #else + NVIC_SystemReset(); + #endif + } + + gFlagAcceptSetting = true; + gIsInSubMenu = false; + gAskForConfirmation = 0; + } + } + else + { + gFlagAcceptSetting = true; + gIsInSubMenu = false; + } + + gCssScanMode = CSS_SCAN_MODE_OFF; + gUpdateStatus = true; + + #ifdef ENABLE_VOICE + if (gMenuCursor == MENU_SCR) + gAnotherVoiceID = (gSubMenuSelection == 0) ? VOICE_ID_SCRAMBLER_OFF : VOICE_ID_SCRAMBLER_ON; + else + gAnotherVoiceID = VOICE_ID_CONFIRM; + #endif + + gInputBoxIndex = 0; +} + +static void MENU_Key_STAR(const bool bKeyPressed, const bool bKeyHeld) +{ + if (bKeyHeld || !bKeyPressed) + return; + + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + + RADIO_SelectVfos(); + + #ifdef ENABLE_NOAA + if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && !gRxVfo->IsAM) + #else + if (!gRxVfo->IsAM) + #endif + { + if (gMenuCursor == MENU_R_CTCS || gMenuCursor == MENU_R_DCS) + { // scan CTCSS or DCS to find the tone/code of the incoming signal + + if (gCssScanMode == CSS_SCAN_MODE_OFF) + { + MENU_StartCssScan(1); + gRequestDisplayScreen = DISPLAY_MENU; + #ifdef ENABLE_VOICE + AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN); + AUDIO_PlaySingleVoice(1); + #endif + } + else + { + MENU_StopCssScan(); + gRequestDisplayScreen = DISPLAY_MENU; + #ifdef ENABLE_VOICE + gAnotherVoiceID = VOICE_ID_SCANNING_STOP; + #endif + } + } + + gPttWasReleased = true; + return; + } + + gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; } static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction) @@ -1360,12 +1442,76 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction) uint8_t Channel; bool bCheckScanList; + if (gMenuCursor == MENU_MEM_NAME && gIsInSubMenu && edit_index >= 0) + { // change the character + if (bKeyPressed && edit_index < 10) + { + #if 0 + char c1 = edit[edit_index]; + char c2 = 0; + + if (Direction == 0) + return; + + if (Direction < 0) + { + switch (c1) + { + case 'a': c2 = 'Z'; break; + case 'A': c2 = '9'; break; + case '0': c2 = '.'; break; + case '.': c2 = '-'; break; + case '-': c2 = '_'; break; + case '_': c2 = ' '; break; + case ' ': c2 = 'z'; break; + } + } + else + { + switch (c1) + { + case ' ': c2 = '_'; break; + case '_': c2 = '-'; break; + case '-': c2 = '.'; break; + case '.': c2 = '0'; break; + case '9': c2 = 'A'; break; + case 'Z': c2 = 'a'; break; + case 'z': c2 = ' '; break; + } + } + + if (c2 == 0) + { + if ((c1 >= '0' && c1 <= '9') || + (c1 >= 'A' && c1 <= 'Z') || + (c1 >= 'a' && c1 <= 'z')) + { + c2 = c1 + Direction; + } + else + { + c2 = 'A'; + } + } + + edit[edit_index] = c2; + #else + const char c = edit[edit_index] + Direction; + edit[edit_index] = (c < 32) ? 126 : (c > 126) ? 32 : c; + #endif + + gRequestDisplayScreen = DISPLAY_MENU; + } + return; + } + if (!bKeyHeld) { if (!bKeyPressed) return; - gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; + gInputBoxIndex = 0; } else @@ -1375,6 +1521,7 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction) if (gCssScanMode != CSS_SCAN_MODE_OFF) { MENU_StartCssScan(Direction); + gPttWasReleased = true; gRequestDisplayScreen = DISPLAY_MENU; return; @@ -1410,14 +1557,12 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction) { case MENU_DEL_CH: case MENU_1_CALL: + case MENU_MEM_NAME: bCheckScanList = false; break; case MENU_SLIST2: VFO = 1; - - // Fallthrough - case MENU_SLIST1: bCheckScanList = true; break; diff --git a/app/scanner.c b/app/scanner.c index 862b716..17a925b 100644 --- a/app/scanner.c +++ b/app/scanner.c @@ -300,7 +300,7 @@ static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Directio if (gScannerEditState == 1) { - gScanChannel = NUMBER_AddWithWraparound(gScanChannel, Direction, 0, 199); + gScanChannel = NUMBER_AddWithWraparound(gScanChannel, Direction, 0, MR_CHANNEL_LAST); gShowChPrefix = RADIO_CheckValidChannel(gScanChannel, false, 0); gRequestDisplayScreen = DISPLAY_SCANNER; } diff --git a/board.c b/board.c index a6c73f2..46d6650 100644 --- a/board.c +++ b/board.c @@ -595,11 +595,8 @@ void BOARD_EEPROM_Init(void) 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_FLASHLIGHT; gEeprom.KEY_2_SHORT_PRESS_ACTION = (Data[3] < ACTION_OPT_LEN) ? Data[3] : ACTION_OPT_SCAN; - #ifdef ENABLE_FMRADIO - gEeprom.KEY_2_LONG_PRESS_ACTION = (Data[4] < ACTION_OPT_LEN) ? Data[4] : ACTION_OPT_NONE; - #else - gEeprom.SCAN_RESUME_MODE = (Data[5] < 3) ? Data[5] : SCAN_RESUME_CO; - #endif + 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; gEeprom.POWER_ON_DISPLAY_MODE = (Data[7] < 4) ? Data[7] : POWER_ON_DISPLAY_MODE_VOLTAGE; @@ -791,6 +788,35 @@ void BOARD_EEPROM_LoadMoreSettings(void) } } +void BOARD_fetchChannelName(char *s, const int channel) +{ + int i; + + if (s == NULL) + return; + + memset(s, 0, 11); // 's' had better be large enough ! + + if (channel < 0) + return; + + if (!RADIO_CheckValidChannel(channel, false, 0)) + return; + + + EEPROM_ReadBuffer(0x0F50 + (channel * 16), s + 0, 8); + EEPROM_ReadBuffer(0x0F58 + (channel * 16), s + 8, 2); + + for (i = 0; i < 10; i++) + if (s[i] < 32 || s[i] > 127) + break; // invalid char + + s[i--] = 0; // null term + + while (i >= 0 && s[i] == 32) // trim trailing spaces + s[i--] = 0; // null term +} + void BOARD_FactoryReset(bool bIsAll) { uint16_t i; diff --git a/board.h b/board.h index 0d6405f..e5dcef6 100644 --- a/board.h +++ b/board.h @@ -27,6 +27,7 @@ void BOARD_ADC_GetBatteryInfo(uint16_t *pVoltage, uint16_t *pCurrent); void BOARD_Init(void); void BOARD_EEPROM_Init(void); void BOARD_EEPROM_LoadMoreSettings(void); +void BOARD_fetchChannelName(char *s, const int channel); void BOARD_FactoryReset(bool bIsAll); #endif diff --git a/driver/st7565.c b/driver/st7565.c index 0c1e4aa..03f802d 100644 --- a/driver/st7565.c +++ b/driver/st7565.c @@ -22,6 +22,7 @@ #include "driver/spi.h" #include "driver/st7565.h" #include "driver/system.h" +#include "misc.h" uint8_t gStatusLine[128]; uint8_t gFrameBuffer[7][128]; @@ -66,12 +67,12 @@ void ST7565_BlitFullScreen(void) ST7565_WriteByte(0x40); - for (Line = 0; Line < 7; Line++) + for (Line = 0; Line < ARRAY_SIZE(gFrameBuffer); Line++) { unsigned int Column; ST7565_SelectColumnAndLine(4, Line + 1); GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0); - for (Column = 0; Column < 128; Column++) + for (Column = 0; Column < ARRAY_SIZE(gFrameBuffer[0]); Column++) { while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} SPI0->WDR = gFrameBuffer[Line][Column]; @@ -102,7 +103,7 @@ void ST7565_BlitStatusLine(void) GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0); - for (i = 0; i < sizeof(gStatusLine); i++) + for (i = 0; i < ARRAY_SIZE(gStatusLine); i++) { while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {} SPI0->WDR = gStatusLine[i]; diff --git a/firmware b/firmware index 026e5df..1d6ce71 100644 Binary files a/firmware and b/firmware differ diff --git a/firmware.bin b/firmware.bin index 28c0f29..d56a706 100644 Binary files a/firmware.bin and b/firmware.bin differ diff --git a/firmware.packed.bin b/firmware.packed.bin index ea1e285..02552f0 100644 Binary files a/firmware.packed.bin and b/firmware.packed.bin differ diff --git a/frequencies.c b/frequencies.c index 92ad4e0..3fb5122 100644 --- a/frequencies.c +++ b/frequencies.c @@ -174,7 +174,7 @@ int FREQUENCY_Check(VFO_Info_t *pInfo) const uint32_t Frequency = pInfo->pTX->Frequency; #ifdef ENABLE_NOAA - if (pInfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST) + if (pInfo->CHANNEL_SAVE > FREQ_CHANNEL_LAST) return -1; #endif diff --git a/helper/boot.c b/helper/boot.c index eb2314d..c6f6c43 100644 --- a/helper/boot.c +++ b/helper/boot.c @@ -90,7 +90,7 @@ void BOOT_ProcessMode(BOOT_Mode_t Mode) gEeprom.KEY_2_SHORT_PRESS_ACTION = 0; gEeprom.KEY_2_LONG_PRESS_ACTION = 0; - RADIO_InitInfo(gRxVfo, 205, 5, 41002500); + RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_LAST - 1, 5, 41002500); gRxVfo->CHANNEL_BANDWIDTH = BANDWIDTH_NARROW; gRxVfo->OUTPUT_POWER = 0; diff --git a/misc.c b/misc.c index 2e134d1..a1aa6d5 100644 --- a/misc.c +++ b/misc.c @@ -83,7 +83,7 @@ uint16_t gEEPROM_RSSI_CALIB[3][4]; uint16_t gEEPROM_1F8A; uint16_t gEEPROM_1F8C; -uint8_t gMR_ChannelAttributes[207]; +uint8_t gMR_ChannelAttributes[FREQ_CHANNEL_LAST + 1]; volatile uint16_t gBatterySaveCountdown_10ms = battery_save_count_10ms; volatile bool gBatterySaveCountdownExpired; diff --git a/misc.h b/misc.h index 7566e4e..fc3b3cc 100644 --- a/misc.h +++ b/misc.h @@ -22,10 +22,12 @@ #define IS_MR_CHANNEL(x) ((x) >= MR_CHANNEL_FIRST && (x) <= MR_CHANNEL_LAST) #define IS_FREQ_CHANNEL(x) ((x) >= FREQ_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST) -#define IS_VALID_CHANNEL(x) ((x) <= NOAA_CHANNEL_LAST) +#define IS_VALID_CHANNEL(x) ((x) < LAST_CHANNEL) -#define IS_NOAA_CHANNEL(x) ((x) >= NOAA_CHANNEL_FIRST && (x) <= NOAA_CHANNEL_LAST) -#define IS_NOT_NOAA_CHANNEL(x) ((x) >= MR_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST) +#ifdef ENABLE_NOAA + #define IS_NOAA_CHANNEL(x) ((x) >= NOAA_CHANNEL_FIRST && (x) <= NOAA_CHANNEL_LAST) + #define IS_NOT_NOAA_CHANNEL(x) ((x) >= MR_CHANNEL_FIRST && (x) <= FREQ_CHANNEL_LAST) +#endif #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) @@ -36,8 +38,11 @@ enum { MR_CHANNEL_LAST = 199u, FREQ_CHANNEL_FIRST = 200u, FREQ_CHANNEL_LAST = 206u, - NOAA_CHANNEL_FIRST = 207u, - NOAA_CHANNEL_LAST = 216u + #ifdef ENABLE_NOAA + NOAA_CHANNEL_FIRST = 207u, + NOAA_CHANNEL_LAST = 216u + #endif + LAST_CHANNEL }; enum { diff --git a/radio.c b/radio.c index ceba43c..b110374 100644 --- a/radio.c +++ b/radio.c @@ -100,7 +100,7 @@ uint8_t RADIO_FindNextChannel(uint8_t Channel, int8_t Direction, bool bCheckScan { unsigned int i; - for (i = 0; i < 200; i++) + for (i = 0; i <= MR_CHANNEL_LAST; i++) { if (Channel == 0xFF) Channel = MR_CHANNEL_LAST; @@ -159,11 +159,11 @@ void RADIO_ConfigureChannel(uint8_t VFO, uint32_t Arg) if (!gSetting_350EN) { - if (gEeprom.FreqChannel[VFO] == 204) - gEeprom.FreqChannel[VFO]++; + if (gEeprom.FreqChannel[VFO] == (FREQ_CHANNEL_LAST - 2)) + gEeprom.FreqChannel[VFO] = FREQ_CHANNEL_LAST - 1; - if (gEeprom.ScreenChannel[VFO] == 204) - gEeprom.ScreenChannel[VFO]++; + if (gEeprom.ScreenChannel[VFO] == (FREQ_CHANNEL_LAST - 2)) + gEeprom.ScreenChannel[VFO] = FREQ_CHANNEL_LAST - 1; } Channel = gEeprom.ScreenChannel[VFO]; @@ -201,7 +201,7 @@ void RADIO_ConfigureChannel(uint8_t VFO, uint32_t Arg) } } else - Channel = 205; + Channel = FREQ_CHANNEL_LAST - 1; Attributes = gMR_ChannelAttributes[Channel]; if (Attributes == 0xFF) diff --git a/settings.c b/settings.c index dc8c083..7837e1e 100644 --- a/settings.c +++ b/settings.c @@ -39,8 +39,6 @@ EEPROM_Config_t gEeprom; uint8_t Padding[4]; } State; - UART_LogSend("sFm\r\n", 5); - memset(&State, 0xFF, sizeof(State)); State.Channel = gEeprom.FM_SelectedChannel; State.Frequency = gEeprom.FM_SelectedFrequency; @@ -56,8 +54,10 @@ void SETTINGS_SaveVfoIndices(void) { uint8_t State[8]; - UART_LogSend("sidx\r\n", 6); - + #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]; @@ -67,9 +67,6 @@ void SETTINGS_SaveVfoIndices(void) #ifdef ENABLE_NOAA State[6] = gEeprom.NoaaChannel[0]; State[7] = gEeprom.NoaaChannel[1]; - #else - State[6] = NOAA_CHANNEL_FIRST; - State[7] = NOAA_CHANNEL_FIRST; #endif EEPROM_WriteBuffer(0x0E80, State); @@ -80,8 +77,6 @@ void SETTINGS_SaveSettings(void) uint8_t State[8]; uint32_t Password[2]; - UART_LogSend("spub\r\n", 6); - State[0] = gEeprom.CHAN_1_CALL; State[1] = gEeprom.SQUELCH_LEVEL; State[2] = gEeprom.TX_TIMEOUT_TIMER; @@ -178,8 +173,6 @@ void SETTINGS_SaveSettings(void) void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode) { - UART_LogSend("schn\r\n", 6); - #ifdef ENABLE_NOAA if (IS_NOT_NOAA_CHANNEL(Channel)) #endif @@ -218,22 +211,28 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, SETTINGS_UpdateChannel(Channel, pVFO, true); - #ifndef KEEP_MEM_NAME - if (IS_MR_CHANNEL(Channel)) - { // clear/reset the channel name + if (IS_MR_CHANNEL(Channel)) + { + #ifndef KEEP_MEM_NAME + // clear/reset the channel name memset(&State8, 0xFF, sizeof(State8)); EEPROM_WriteBuffer(0x0F50 + OffsetMR, State8); EEPROM_WriteBuffer(0x0F58 + OffsetMR, State8); - } - #endif + #else + // save the channel name + memmove(State8, pVFO->Name + 0, 8); + EEPROM_WriteBuffer(0x0F50 + OffsetMR, State8); + memset(State8, 0xFF, sizeof(State8)); + memmove(State8, pVFO->Name + 8, 2); + EEPROM_WriteBuffer(0x0F58 + OffsetMR, State8); + #endif + } } } } void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep) { - UART_LogSend("svalid\r\n", 8); - #ifdef ENABLE_NOAA if (IS_NOT_NOAA_CHANNEL(Channel)) #endif @@ -265,12 +264,23 @@ void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep) gMR_ChannelAttributes[Channel] = Attributes; // #ifndef KEEP_MEM_NAME - if (IS_MR_CHANNEL(Channel) && !keep) - { // clear/reset the channel name + if (IS_MR_CHANNEL(Channel)) + { const uint16_t OffsetMR = Channel * 16; - memset(&State, 0xFF, sizeof(State)); - EEPROM_WriteBuffer(0x0F50 + OffsetMR, State); - EEPROM_WriteBuffer(0x0F58 + OffsetMR, State); + if (!keep) + { // clear/reset the channel name + memset(&State, 0xFF, sizeof(State)); + EEPROM_WriteBuffer(0x0F50 + OffsetMR, State); + EEPROM_WriteBuffer(0x0F58 + OffsetMR, State); + } +// else +// { // update the channel name +// memmove(State, pVFO->Name + 0, 8); +// EEPROM_WriteBuffer(0x0F50 + OffsetMR, State); +// memset(State, 0xFF, sizeof(State)); +// memmove(State, pVFO->Name + 8, 2); +// EEPROM_WriteBuffer(0x0F58 + OffsetMR, State); +// } } // #endif } diff --git a/ui/main.c b/ui/main.c index eeb110e..f8e5429 100644 --- a/ui/main.c +++ b/ui/main.c @@ -18,6 +18,7 @@ #include "app/dtmf.h" #include "bitmaps.h" +#include "board.h" #include "driver/st7565.h" #include "external/printf/printf.h" #include "functions.h" @@ -150,9 +151,7 @@ void UI_DisplayMain(void) #ifdef ENABLE_ALARM if (gAlarmState == ALARM_STATE_ALARM) - { duff_beer = 2; - } else #endif { @@ -227,7 +226,7 @@ void UI_DisplayMain(void) else if (gInputBoxIndex > 0 && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]) && gEeprom.TX_CHANNEL == vfo_num) { // user entering a frequency - UI_DisplayFrequency(gInputBox, 31, Line, true, false); + UI_DisplayFrequency(gInputBox, 32, Line, true, false); center_line_is_free = false; } @@ -263,9 +262,9 @@ void UI_DisplayMain(void) #ifdef ENABLE_BIG_FREQ NUMBER_ToDigits(frequency, String); // show the main large frequency digits - UI_DisplayFrequency(String, 31, Line, false, false); + UI_DisplayFrequency(String, 32, Line, false, false); // show the remaining 2 small frequency digits - UI_DisplaySmallDigits(2, String + 7, 112, Line + 1, true); + UI_DisplaySmallDigits(2, String + 7, 113, Line + 1, true); #else // show the frequency in the main font sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000); @@ -276,38 +275,26 @@ void UI_DisplayMain(void) case MDF_CHANNEL: // show the channel number sprintf(String, "CH-%03u", gEeprom.ScreenChannel[vfo_num] + 1); UI_PrintString(String, 32, 0, Line, 8); - frequency = 0; break; case MDF_NAME: // show the channel name - if (gEeprom.VfoInfo[vfo_num].Name[0] <= 32 || gEeprom.VfoInfo[vfo_num].Name[0] >= 127) + case MDF_NAME_FREQ: // show the channel name and frequency + BOARD_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); } - else - { // channel name - memset(String, 0, sizeof(String)); - memmove(String, gEeprom.VfoInfo[vfo_num].Name, 10); - } -// UI_PrintString(String, 32, 112, Line, 8); - UI_PrintString(String, 32, 0, Line, 8); - break; - - case MDF_NAME_FREQ: // show the channel name and frequency - if (gEeprom.VfoInfo[vfo_num].Name[0] <= 32 || gEeprom.VfoInfo[vfo_num].Name[0] >= 127) - { // no channel name, show 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 - { // channel name - memset(String, 0, sizeof(String)); - memmove(String, gEeprom.VfoInfo[vfo_num].Name, 10); + { + UI_PrintStringSmall(String, 32 + 4, 0, Line); + // show the channel frequency below the channel number/name + sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000); + UI_PrintStringSmall(String, 32 + 4, 0, Line + 1); } - UI_PrintStringSmall(String, 32 + 4, 0, Line); - - // show the channel frequency below the channel number/name - sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000); - UI_PrintStringSmall(String, 32 + 4, 0, Line + 1); break; } } @@ -318,26 +305,22 @@ void UI_DisplayMain(void) // show the main large frequency digits UI_DisplayFrequency(String, 32, Line, false, false); // show the remaining 2 small frequency digits - UI_DisplaySmallDigits(2, String + 7, 112, Line + 1, true); + UI_DisplaySmallDigits(2, String + 7, 113, Line + 1, true); #else // show the frequency in the main font sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000); UI_PrintString(String, 32, 0, Line, 8); #endif - // show the channel symbols - const uint8_t attributes = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; - (void)attributes; // stop compiler warning/error - #ifdef ENABLE_BIG_FREQ - #ifdef ENABLE_COMPANDER - if ((attributes & MR_CH_COMPAND) > 0) + #ifdef ENABLE_COMPANDER + // show the channel symbols + const uint8_t attributes = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; + if ((attributes & MR_CH_COMPAND) > 0) + #ifdef ENABLE_BIG_FREQ memmove(pLine0 + 120, BITMAP_compand, sizeof(BITMAP_compand)); - #endif - #else - #ifdef ENABLE_COMPANDER - if ((attributes & MR_CH_COMPAND) > 0) + #else memmove(pLine0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand)); - #endif + #endif #endif } } @@ -423,12 +406,9 @@ void UI_DisplayMain(void) if (gEeprom.VfoInfo[vfo_num].ConfigRX.Frequency != gEeprom.VfoInfo[vfo_num].ConfigTX.Frequency) { // show the TX offset symbol - String[0] = '\0'; - switch (gEeprom.VfoInfo[vfo_num].TX_OFFSET_FREQUENCY_DIRECTION) - { - case TX_OFFSET_FREQUENCY_DIRECTION_ADD: String[0] = '+'; break; - case TX_OFFSET_FREQUENCY_DIRECTION_SUB: String[0] = '-'; break; - } + const char dir_list[] = "\0+-"; + const unsigned int i = gEeprom.VfoInfo[vfo_num].TX_OFFSET_FREQUENCY_DIRECTION; + String[0] = (i < sizeof(dir_list)) ? dir_list[i] : '?'; String[1] = '\0'; UI_PrintStringSmall(String, LCD_WIDTH + 54, 0, Line + 1); } diff --git a/ui/menu.c b/ui/menu.c index 7449440..de8dd1c 100644 --- a/ui/menu.c +++ b/ui/menu.c @@ -19,6 +19,7 @@ #include "app/dtmf.h" #include "bitmaps.h" +#include "board.h" #include "dcs.h" #include "driver/bk4819.h" #include "driver/eeprom.h" // EEPROM_ReadBuffer() @@ -55,6 +56,7 @@ const char MenuList[][7] = "BUSYCL", // was "BCL" "CH-SAV", // was "MEM-CH" "CH-DEL", // was "DEL-CH" + "CH-NAM", "CH-DIS", // was "MDF" "BATSAV", // was "SAVE" "VOX", @@ -261,6 +263,10 @@ uint8_t gMenuCursor; int8_t gMenuScrollDirection; int32_t gSubMenuSelection; +// edit box +char edit[17]; +int edit_index; + void UI_DisplayMenu(void) { unsigned int i; @@ -281,26 +287,11 @@ void UI_DisplayMenu(void) } // draw vertical separating line - #if 0 - // original thick line - for (i = 0; i < 7; i++) - { - gFrameBuffer[i][48] = 0xFF; - gFrameBuffer[i][49] = 0xFF; - } - #else - // a less intense thinner dotted line - for (i = 0; i < 6; i++) - gFrameBuffer[i][49] = 0xAA; - #endif + for (i = 0; i < 6; i++) + gFrameBuffer[i][49] = 0xAA; - #if 0 - NUMBER_ToDigits(1 + gMenuCursor, String); - UI_DisplaySmallDigits(2, String + 6, 33, 6, false); - #else - sprintf(String, "%2u.%u", 1 + gMenuCursor, gMenuListCount); - UI_PrintStringSmall(String, 8, 0, 6); - #endif + sprintf(String, "%2u.%u", 1 + gMenuCursor, gMenuListCount); + UI_PrintStringSmall(String, 8, 0, 6); if (gIsInSubMenu) memmove(gFrameBuffer[0] + 50, BITMAP_CurrentIndicator, sizeof(BITMAP_CurrentIndicator)); @@ -451,11 +442,76 @@ void UI_DisplayMenu(void) case MENU_MEM_CH: case MENU_1_CALL: case MENU_DEL_CH: - UI_GenerateChannelStringEx(String, RADIO_CheckValidChannel(gSubMenuSelection, false, 0), gSubMenuSelection); + { + const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 0); + + UI_GenerateChannelStringEx(String, valid, gSubMenuSelection); UI_PrintString(String, 50, 127, 0, 8); + + if (valid && !gAskForConfirmation) + { // show the frequency so that the user knows the channels frequency + struct + { + uint32_t Frequency; + uint32_t Offset; + } __attribute__((packed)) Info; + EEPROM_ReadBuffer(gSubMenuSelection * 16, &Info, sizeof(Info)); + + sprintf(String, "%03u.%05u", Info.Frequency / 100000, Info.Frequency % 100000); +// UI_PrintStringSmall(String, 50, 127, 5); + UI_PrintString(String, 50, 127, 4, 8); + } + already_printed = true; break; + } + + case MENU_MEM_NAME: + { + const bool valid = RADIO_CheckValidChannel(gSubMenuSelection, false, 0); + + UI_GenerateChannelStringEx(String, valid, gSubMenuSelection); + UI_PrintString(String, 50, 127, 0, 8); + + if (valid) + { + struct + { + uint32_t Frequency; + uint32_t Offset; + } __attribute__((packed)) Info; + EEPROM_ReadBuffer(gSubMenuSelection * 16, &Info, sizeof(Info)); + + if (!gIsInSubMenu || edit_index < 0) + { // show the channel name + BOARD_fetchChannelName(String, gSubMenuSelection); + if (String[0] == 0) + strcpy(String, "--"); + UI_PrintString(String, 50, 127, 2, 8); + } + else + { // show the channel name being edited + UI_PrintString(edit, 50, 0, 2, 8); + if (edit_index < 10) +// UI_PrintString("^", 50 + (8 * edit_index), 0, 4, 8); // show the cursor + UI_PrintStringSmall("^", 50 + (8 * edit_index), 0, 4); + } + + if (!gAskForConfirmation) + { // show the frequency so that the user knows the channels frequency + sprintf(String, "%03u.%05u", Info.Frequency / 100000, Info.Frequency % 100000); + if (!gIsInSubMenu || edit_index < 0) + UI_PrintString(String, 50, 127, 4, 8); + else + UI_PrintString(String, 50, 127, 5, 8); +// UI_PrintStringSmall(String, 50, 127, 5); + } + } + already_printed = true; + break; + } + case MENU_SAVE: strcpy(String, gSubMenu_SAVE[gSubMenuSelection]); break; @@ -635,41 +691,17 @@ void UI_DisplayMenu(void) } } - if (gMenuCursor == MENU_MEM_CH || - gMenuCursor == MENU_DEL_CH || - gMenuCursor == MENU_1_CALL || - gMenuCursor == MENU_SLIST1 || + if (gMenuCursor == MENU_MEM_CH || + gMenuCursor == MENU_DEL_CH || + gMenuCursor == MENU_1_CALL || + gMenuCursor == MENU_SLIST1 || gMenuCursor == MENU_SLIST2) { // display the channel name - if (gSubMenuSelection >= 0) - { - const uint16_t channel = (uint16_t)gSubMenuSelection; - const bool valid = RADIO_CheckValidChannel(channel, false, 0); - if (valid) - { // 16 bytes allocated to the channel name but only 12 used - char s[17] = {0}; - EEPROM_ReadBuffer(0x0F50 + (channel * 16), s + 0, 8); - EEPROM_ReadBuffer(0x0F58 + (channel * 16), s + 8, 2); - { // make invalid chars '0' - i = 0; - while (i < sizeof(s)) - { - if (s[i] < 32 || s[i] >= 128) - break; - i++; - } - while (i < sizeof(s)) - s[i++] = 0; - while (--i > 0) - { - if (s[i] != 0 && s[i] != 32) - break; - s[i] = 0; - } - } - UI_PrintString(s, 50, 127, 2, 8); - } - } + char s[11]; + BOARD_fetchChannelName(s, gSubMenuSelection); + if (s[0] == 0) + strcpy(s, "--"); + UI_PrintString(s, 50, 127, 2, 8); } if ((gMenuCursor == MENU_R_CTCS || gMenuCursor == MENU_R_DCS) && gCssScanMode != CSS_SCAN_MODE_OFF) @@ -703,7 +735,10 @@ void UI_DisplayMenu(void) UI_DisplaySmallDigits(Offset, String + (8 - Offset), 105, 0, false); } - if ((gMenuCursor == MENU_RESET || gMenuCursor == MENU_MEM_CH || gMenuCursor == MENU_DEL_CH) && gAskForConfirmation) + if ((gMenuCursor == MENU_RESET || + gMenuCursor == MENU_MEM_CH || + gMenuCursor == MENU_MEM_NAME || + gMenuCursor == MENU_DEL_CH) && gAskForConfirmation) { // display confirmation strcpy(String, (gAskForConfirmation == 1) ? "SURE?" : "WAIT!"); UI_PrintString(String, 50, 127, 5, 8); diff --git a/ui/menu.h b/ui/menu.h index 2a12275..1b0cac8 100644 --- a/ui/menu.h +++ b/ui/menu.h @@ -38,6 +38,7 @@ enum MENU_BCL, MENU_MEM_CH, MENU_DEL_CH, + MENU_MEM_NAME, MENU_MDF, MENU_SAVE, MENU_VOX, @@ -131,6 +132,9 @@ extern uint8_t gMenuCursor; extern int8_t gMenuScrollDirection; extern int32_t gSubMenuSelection; +extern char edit[17]; +extern int edit_index; + void UI_DisplayMenu(void); #endif diff --git a/version.c b/version.c index aea9735..2cbe055 100644 --- a/version.c +++ b/version.c @@ -2,7 +2,7 @@ #ifdef GIT_HASH #define VER GIT_HASH #else - #define VER "230919" + #define VER "230920" #endif const char Version[] = "OEFW-"VER; diff --git a/win_make.bat b/win_make.bat index cbd5692..1dc179a 100644 --- a/win_make.bat +++ b/win_make.bat @@ -21,7 +21,7 @@ del /S /Q *.d >nul 2>nul :: https://github.com/OneOfEleven/k5prog-win :: ::python -m pip install --upgrade pip crcmod -fw-pack.py firmware.bin 230919 firmware.packed.bin +fw-pack.py firmware.bin 230920 firmware.packed.bin ::arm-none-eabi-size firmware