diff --git a/Makefile b/Makefile index 427efbb..78a246d 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,7 @@ 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 := 0 #ENABLE_COPY_CHAN_TO_VFO := 1 #ENABLE_SINGLE_VFO_CHAN := 1 @@ -117,7 +118,6 @@ OBJS += ui/inputbox.o OBJS += ui/lock.o OBJS += ui/main.o OBJS += ui/menu.o -OBJS += ui/rssi.o OBJS += ui/scanner.o OBJS += ui/status.o OBJS += ui/ui.o @@ -224,6 +224,9 @@ endif ifeq ($(ENABLE_SQUELCH1_LOWER),1) CFLAGS += -DENABLE_SQUELCH1_LOWER endif +ifeq ($(ENABLE_RSSI_BAR),1) + CFLAGS += -DENABLE_RSSI_BAR +endif ifeq ($(ENABLE_AUDIO_BAR),1) CFLAGS += -DENABLE_AUDIO_BAR endif diff --git a/README.md b/README.md index f183076..961582c 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ ENABLE_NO_SCAN_TIMEOUT := 1 remove the 32 sec timeout from the CTCS 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_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 #ENABLE_SINGLE_VFO_CHAN := 1 not yet implemented - single VFO on display when possible diff --git a/am_fix.c b/am_fix.c index 1b61e84..619d12d 100644 --- a/am_fix.c +++ b/am_fix.c @@ -29,7 +29,6 @@ #include "frequencies.h" #include "functions.h" #include "misc.h" -#include "ui/rssi.h" // original QS front end register settings const uint8_t orig_lna_short = 3; // 0dB diff --git a/app/app.c b/app/app.c index b6f95d2..f89a649 100644 --- a/app/app.c +++ b/app/app.c @@ -59,7 +59,6 @@ #include "ui/inputbox.h" #include "ui/main.h" #include "ui/menu.h" -#include "ui/rssi.h" #include "ui/status.h" #include "ui/ui.h" @@ -79,6 +78,7 @@ static void updateRSSI(const int vfo) return; // no change gCurrentRSSI[vfo] = rssi; +// gCurrentRSSI[vfo] = (gCurrentRSSI[vfo] + rssi) / 2; UI_UpdateRSSI(rssi, vfo); } @@ -2305,7 +2305,7 @@ Skip: { SETTINGS_SaveChannel(gTxVfo->CHANNEL_SAVE, gEeprom.TX_CHANNEL, gTxVfo, gRequestSaveChannel); if (gScreenToDisplay != DISPLAY_SCANNER) - if (gVfoConfigureMode == VFO_CONFIGURE_NONE) + if (gVfoConfigureMode == VFO_CONFIGURE_NONE) // 'if' is so as we don't wipe out previously setting this variable elsewhere gVfoConfigureMode = VFO_CONFIGURE; } else diff --git a/app/dtmf.c b/app/dtmf.c index 7973787..146e75c 100644 --- a/app/dtmf.c +++ b/app/dtmf.c @@ -40,7 +40,7 @@ uint8_t gDTMF_WriteIndex = 0; uint8_t gDTMF_PreviousIndex = 0; uint8_t gDTMF_RecvTimeout = 0; -char gDTMF_ReceivedSaved[17]; +char gDTMF_ReceivedSaved[20]; uint8_t gDTMF_RecvTimeoutSaved = 0; bool gIsDtmfContactValid; diff --git a/app/dtmf.h b/app/dtmf.h index 5b7549a..141aec5 100644 --- a/app/dtmf.h +++ b/app/dtmf.h @@ -63,7 +63,7 @@ extern uint8_t gDTMF_WriteIndex; extern uint8_t gDTMF_PreviousIndex; extern uint8_t gDTMF_RecvTimeout; -extern char gDTMF_ReceivedSaved[17]; +extern char gDTMF_ReceivedSaved[20]; extern uint8_t gDTMF_RecvTimeoutSaved; extern bool gIsDtmfContactValid; diff --git a/app/menu.c b/app/menu.c index a22f6fe..0d85e73 100644 --- a/app/menu.c +++ b/app/menu.c @@ -432,7 +432,7 @@ void MENU_AcceptSetting(void) { // trailing trim for (int i = 9; i >= 0; i--) { - if (edit[i] != ' ' && edit[i] != '_' && edit[i] != 0 && edit[i] != 0xff) + if (edit[i] != ' ' && edit[i] != '_' && edit[i] != 0x00 && edit[i] != 0xff) break; edit[i] = ' '; } @@ -455,7 +455,7 @@ void MENU_AcceptSetting(void) gEeprom.VOX_LEVEL = gSubMenuSelection - 1; BOARD_EEPROM_LoadMoreSettings(); gFlagReconfigureVfos = true; - gUpdateStatus = true; + gUpdateStatus = true; break; case MENU_ABR: diff --git a/firmware.bin b/firmware.bin index 369d702..703bf6d 100644 Binary files a/firmware.bin and b/firmware.bin differ diff --git a/firmware.packed.bin b/firmware.packed.bin index 45d7935..11d02b7 100644 Binary files a/firmware.packed.bin and b/firmware.packed.bin differ diff --git a/ui/main.c b/ui/main.c index 5259389..bb0dcca 100644 --- a/ui/main.c +++ b/ui/main.c @@ -36,21 +36,25 @@ #include "ui/main.h" #include "ui/ui.h" +// *************************************************************************** + #ifdef ENABLE_AUDIO_BAR unsigned int sqrt16(unsigned int value) { // return square root of 'value' - unsigned int shift = 15; - unsigned int bit = 1u << shift; + unsigned int shift = 16; // number of bits supplied in 'value' .. 2 ~ 32 + unsigned int bit = 1u << --shift; unsigned int sqrti = 0; - do { + while (bit) + { const unsigned int temp = ((sqrti << 1) | bit) << shift--; if (value >= temp) { value -= temp; sqrti |= bit; } - } while (bit >>= 1); + bit >>= 1; + } return sqrti; } @@ -105,6 +109,152 @@ } #endif +#if defined(ENABLE_RSSI_BAR) + void UI_DisplayRSSIBar(const int16_t rssi, const bool now) + { + char s[16]; + unsigned int i; + + const unsigned int max_dB = -33; + const unsigned int min_dB = -127; + + const unsigned int txt_width = 7 * 10; // 10 chars + const unsigned int bar_x = txt_width + 4; + const unsigned int bar_width = LCD_WIDTH - 1 - bar_x; + + const int16_t dBm = (rssi / 2) - 160; + const unsigned int clamped_dBm = (dBm < min_dB) ? min_dB : (dBm > max_dB) ? max_dB : dBm; + const unsigned int width = max_dB - min_dB; + const unsigned int len = (((clamped_dBm - min_dB) * bar_width) + (width / 2)) / width; + + const unsigned int line = 3; + uint8_t *pLine = gFrameBuffer[line]; + + unsigned int s_level = 0; + + 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 >= -63) // S9+10dB + s_level = 10 + (((dBm - -63) / 10) * 10); + else + if (clamped_dBm >= -127) // S0 + s_level = (clamped_dBm - -127) / 6; + + if (now) + memset(pLine, 0, LCD_WIDTH); + + if (s_level < 10) + sprintf(s, "%-4d S%u ", dBm, s_level); // S0 ~ S9 + else + sprintf(s, "%-4d S9+%u", dBm, s_level); // S9+ + UI_PrintStringSmall(s, 2, 0, line); + + for (i = 0; i < bar_width; i += 2) + pLine[bar_x + i] = ((i & 1) == 0 && i <= len) ? 0x7f : 0x41; + + if (now) + ST7565_BlitFullScreen(); + } +#endif + +void UI_UpdateRSSI(const int16_t rssi, const int vfo) +{ + #ifdef ENABLE_RSSI_BAR + + const bool rx = (gCurrentFunction == FUNCTION_RECEIVE || + gCurrentFunction == FUNCTION_MONITOR || + gCurrentFunction == FUNCTION_INCOMING); + + if (rx) + UI_DisplayRSSIBar(rssi, true); + + #else + + const uint8_t Line = (vfo == 0) ? 3 : 7; + uint8_t *pLine = gFrameBuffer[Line - 1]; +// const int16_t dBm = (rssi / 2) - 160; + + #if 0 + //const unsigned int band = gRxVfo->Band; + const unsigned int band = 0; + const int16_t level0 = gEEPROM_RSSI_CALIB[band][0]; + const int16_t level1 = gEEPROM_RSSI_CALIB[band][1]; + const int16_t level2 = gEEPROM_RSSI_CALIB[band][2]; + const int16_t level3 = gEEPROM_RSSI_CALIB[band][3]; + #else + const int16_t level0 = (-115 + 160) * 2; // dB + const int16_t level1 = ( -89 + 160) * 2; // dB + const int16_t level2 = ( -64 + 160) * 2; // dB + const int16_t level3 = ( -39 + 160) * 2; // dB + #endif + const int16_t level01 = (level0 + level1) / 2; + const int16_t level12 = (level1 + level2) / 2; + const int16_t level23 = (level2 + level3) / 2; + + gVFO_RSSI[vfo] = rssi; + + uint8_t rssi_level = 0; + + if (rssi >= level3) rssi_level = 7; + else + if (rssi >= level23) rssi_level = 6; + else + if (rssi >= level2) rssi_level = 5; + else + if (rssi >= level12) rssi_level = 4; + else + if (rssi >= level1) rssi_level = 3; + else + if (rssi >= level01) rssi_level = 2; + else + if (rssi >= level0) rssi_level = 1; + + if (gVFO_RSSI_bar_level[vfo] == rssi_level) + return; + + gVFO_RSSI_bar_level[vfo] = rssi_level; + + // ********************************************************** + + if (gEeprom.KEY_LOCK && gKeypadLocked > 0) + return; // display is in use + + if (gCurrentFunction == FUNCTION_TRANSMIT || gScreenToDisplay != DISPLAY_MAIN) + return; // display is in use + + pLine = gFrameBuffer[Line - 1]; + + memset(pLine, 0, 23); + + if (rssi_level > 0) + { + //if (rssi_level >= 1) + memmove(pLine, BITMAP_Antenna, 5); + if (rssi_level >= 2) + memmove(pLine + 5, BITMAP_AntennaLevel1, sizeof(BITMAP_AntennaLevel1)); + if (rssi_level >= 3) + memmove(pLine + 8, BITMAP_AntennaLevel2, sizeof(BITMAP_AntennaLevel2)); + if (rssi_level >= 4) + memmove(pLine + 11, BITMAP_AntennaLevel3, sizeof(BITMAP_AntennaLevel3)); + if (rssi_level >= 5) + memmove(pLine + 14, BITMAP_AntennaLevel4, sizeof(BITMAP_AntennaLevel4)); + if (rssi_level >= 6) + memmove(pLine + 17, BITMAP_AntennaLevel5, sizeof(BITMAP_AntennaLevel5)); + if (rssi_level >= 7) + memmove(pLine + 20, BITMAP_AntennaLevel6, sizeof(BITMAP_AntennaLevel6)); + } + else + pLine = NULL; + + ST7565_DrawLine(0, Line, 23, pLine); + #endif +} + +// *************************************************************************** + void UI_DisplayMain(void) { char String[16]; @@ -428,17 +578,7 @@ void UI_DisplayMain(void) else if (duff_beer == 2) { // RX signal level - #ifdef ENABLE_DBM - // dBm - // - // this doesn't yet quite fit into the available screen space - // I suppose the '-' sign could be dropped - // - const int16_t dBm = (gVFO_RSSI[vfo_num] / 2) - 160; - sprintf(String, "%-3d", dBm); - //sprintf(String, "%3d", abs(dBm)); - UI_PrintStringSmall(String, 2, 0, Line + 2); - #else + #ifndef ENABLE_RSSI_BAR // bar graph if (gVFO_RSSI_bar_level[vfo_num] > 0) Level = gVFO_RSSI_bar_level[vfo_num]; @@ -523,42 +663,44 @@ void UI_DisplayMain(void) } if (center_line_is_free) - { // we're free to use the middle empty line for something + { // we're free to use the middle line + + const bool rx = (gCurrentFunction == FUNCTION_RECEIVE || + gCurrentFunction == FUNCTION_MONITOR || + gCurrentFunction == FUNCTION_INCOMING); #if defined(ENABLE_AM_FIX) && defined(ENABLE_AM_FIX_SHOW_DATA) - if (gSetting_AM_fix && gEeprom.VfoInfo[gEeprom.RX_CHANNEL].AM_mode) + if (rx && gEeprom.VfoInfo[gEeprom.RX_CHANNEL].AM_mode && gSetting_AM_fix) { - switch (gCurrentFunction) - { - case FUNCTION_TRANSMIT: - case FUNCTION_BAND_SCOPE: - case FUNCTION_POWER_SAVE: - break; - - case FUNCTION_FOREGROUND: - break; - - case FUNCTION_RECEIVE: - case FUNCTION_MONITOR: - case FUNCTION_INCOMING: - AM_fix_print_data(gEeprom.RX_CHANNEL, String); - UI_PrintStringSmall(String, 0, 0, 3); - break; - } + AM_fix_print_data(gEeprom.RX_CHANNEL, String); + UI_PrintStringSmall(String, 0, 0, 3); } else #endif + + #ifdef ENABLE_RSSI_BAR + if (rx) + UI_DisplayRSSIBar(gCurrentRSSI[gEeprom.RX_CHANNEL], false); + else + #endif + { #ifdef ENABLE_AUDIO_BAR UI_DisplayAudioBar(); // if (!gSetting_mic_bar) #endif - if (gCurrentFunction != FUNCTION_TRANSMIT) + if (rx || gCurrentFunction == FUNCTION_FOREGROUND) { if (gSetting_live_DTMF_decoder && gDTMF_ReceivedSaved[0] >= 32) { // show live DTMF decode - UI_PrintStringSmall(gDTMF_ReceivedSaved, 8, 0, 3); + const unsigned int len = strlen(gDTMF_ReceivedSaved); + unsigned int idx = 0; + while ((len - idx) > (17 - 5)) // display the last 'n' on-screen fittable chars + idx++; + strcpy(String, "DTMF "); + strcat(String, gDTMF_ReceivedSaved + idx); + UI_PrintStringSmall(String, 2, 0, 3); } else if (gChargingWithTypeC) @@ -576,3 +718,5 @@ void UI_DisplayMain(void) ST7565_BlitFullScreen(); } + +// *************************************************************************** diff --git a/ui/main.h b/ui/main.h index 347b9f4..3c5b27d 100644 --- a/ui/main.h +++ b/ui/main.h @@ -18,6 +18,7 @@ #define UI_MAIN_H void UI_DisplayAudioBar(void); +void UI_UpdateRSSI(const int16_t rssi, const int vfo); void UI_DisplayMain(void); #endif diff --git a/ui/rssi.c b/ui/rssi.c deleted file mode 100644 index fd29c6b..0000000 --- a/ui/rssi.c +++ /dev/null @@ -1,157 +0,0 @@ -/* Copyright 2023 Dual Tachyon - * https://github.com/DualTachyon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include // abs() - -#include "bitmaps.h" -#include "driver/st7565.h" -#include "external/printf/printf.h" -#include "functions.h" -#include "misc.h" -#include "settings.h" -#include "ui/helper.h" -#include "ui/rssi.h" -#include "ui/ui.h" - -#ifdef ENABLE_DBM - -void UI_UpdateRSSI(const int16_t rssi, const int vfo) -{ - // dBm - // - // this doesn't yet quite fit into the available screen space - // I suppose the '-' sign could be dropped - - char s[8]; - const uint8_t line = (vfo == 0) ? 3 : 7; - - if (gEeprom.KEY_LOCK && gKeypadLocked > 0) - return; // the screen is currently in use - - gVFO_RSSI[vfo] = rssi; - gVFO_RSSI_bar_level[vfo] = 0; - - { // drop the '.5' bit - const int16_t dBm = (rssi / 2) - 160; - sprintf(s, "%-3d", dBm); -// sprintf(s, "%3d", abs(dBm)); - } - else - strcpy(s, " "); - - UI_PrintStringSmall(s, 2, 0, line); -} - -#else - -void render(const int16_t rssi, const uint8_t rssi_level, const int vfo) -{ // bar graph - - uint8_t *pLine; - uint8_t Line; - - if (gEeprom.KEY_LOCK && gKeypadLocked > 0) - return; // the screen is currently in use - - if (gCurrentFunction == FUNCTION_TRANSMIT || gScreenToDisplay != DISPLAY_MAIN) - return; // it's still in use - - if (vfo == 0) - { - pLine = gFrameBuffer[2]; - Line = 3; - } - else - { - pLine = gFrameBuffer[6]; - Line = 7; - } - - memset(pLine, 0, 23); - - if (rssi_level == 0) - { - pLine = NULL; - } - else - { - //if (rssi_level >= 1) - memmove(pLine, BITMAP_Antenna, 5); - if (rssi_level >= 2) - memmove(pLine + 5, BITMAP_AntennaLevel1, sizeof(BITMAP_AntennaLevel1)); - if (rssi_level >= 3) - memmove(pLine + 8, BITMAP_AntennaLevel2, sizeof(BITMAP_AntennaLevel2)); - if (rssi_level >= 4) - memmove(pLine + 11, BITMAP_AntennaLevel3, sizeof(BITMAP_AntennaLevel3)); - if (rssi_level >= 5) - memmove(pLine + 14, BITMAP_AntennaLevel4, sizeof(BITMAP_AntennaLevel4)); - if (rssi_level >= 6) - memmove(pLine + 17, BITMAP_AntennaLevel5, sizeof(BITMAP_AntennaLevel5)); - if (rssi_level >= 7) - memmove(pLine + 20, BITMAP_AntennaLevel6, sizeof(BITMAP_AntennaLevel6)); - } - - ST7565_DrawLine(0, Line, 23, pLine); -} - -void UI_UpdateRSSI(const int16_t rssi, const int vfo) -{ - gVFO_RSSI[vfo] = rssi; - - //const int16_t dBm = (rssi / 2) - 160; - - #if 0 - //const unsigned int band = gRxVfo->Band; - const unsigned int band = 0; - const int16_t level0 = gEEPROM_RSSI_CALIB[band][0]; - const int16_t level1 = gEEPROM_RSSI_CALIB[band][1]; - const int16_t level2 = gEEPROM_RSSI_CALIB[band][2]; - const int16_t level3 = gEEPROM_RSSI_CALIB[band][3]; - #else - const int16_t level0 = (-115 + 160) * 2; // dB - const int16_t level1 = ( -89 + 160) * 2; // dB - const int16_t level2 = ( -64 + 160) * 2; // dB - const int16_t level3 = ( -39 + 160) * 2; // dB - #endif - const int16_t level01 = (level0 + level1) / 2; - const int16_t level12 = (level1 + level2) / 2; - const int16_t level23 = (level2 + level3) / 2; - - uint8_t Level = 0; - - if (rssi >= level3) Level = 7; - else - if (rssi >= level23) Level = 6; - else - if (rssi >= level2) Level = 5; - else - if (rssi >= level12) Level = 4; - else - if (rssi >= level1) Level = 3; - else - if (rssi >= level01) Level = 2; - else - if (rssi >= level0) Level = 1; - - if (gVFO_RSSI_bar_level[vfo] != Level) - { - gVFO_RSSI_bar_level[vfo] = Level; - render(rssi, Level, vfo); - } -} - -#endif diff --git a/ui/rssi.h b/ui/rssi.h deleted file mode 100644 index e0bf246..0000000 --- a/ui/rssi.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright 2023 Dual Tachyon - * https://github.com/DualTachyon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef UI_RSSI_H -#define UI_RSSI_H - -void UI_UpdateRSSI(const int16_t RSSI, const int vfo); - -#endif - diff --git a/version.c b/version.c index 7615aa5..c257f1f 100644 --- a/version.c +++ b/version.c @@ -2,7 +2,7 @@ #ifdef GIT_HASH #define VER GIT_HASH #else - #define VER "230925" + #define VER "230930" #endif const char Version[] = "OEFW-"VER;