75 Commits
v0.10 ... v0.15

Author SHA1 Message Date
Krzysiek Egzmont
140b5f4b4a Added second discharge curve for 2200mAh type battery and hidden BatTyp menu entry 2023-10-31 00:41:53 +01:00
Krzysiek Egzmont
3e0ea6f7de Backlight setting 1 was fully off for some reason on higher freq PWM 2023-10-30 18:57:35 +01:00
Krzysiek Egzmont
ed64c7fb49 Mid, low power reduction mod from 1o11 2023-10-30 18:17:54 +01:00
Krzysiek Egzmont
d70fa1b7b4 Refactor 2023-10-30 16:39:18 +01:00
Krzysiek Egzmont
a41628410e FIX #65: code refactoring 2023-10-30 13:26:16 +01:00
Krzysiek Egzmont
f7c25b482d FIX #55: Broken DTMF calling (D Decd) 2023-10-29 22:26:48 +01:00
Krzysiek Egzmont
ac3cd08163 serial debugging helper 2023-10-28 23:11:52 +02:00
Krzysiek Egzmont
c1657a37f2 Refactor 2023-10-28 22:50:42 +02:00
Krzysiek Egzmont
a2580d5d8d Increase backlight PWM frequency to reduce flicker 2023-10-28 16:10:37 +02:00
Krzysiek Egzmont
5d4f7529ed Refactor 2023-10-28 16:09:49 +02:00
Krzysiek Egzmont
20a3e3b605 Fix STE not working when TX CTCSS/DCS is off
Reverts:
fde690a74a: app.c
50a55e34ab: radio.c
2023-10-28 14:41:47 +02:00
Krzysiek Egzmont
f3cc0f5acf Comments, refactor 2023-10-28 14:39:13 +02:00
Krzysiek Egzmont
2086bd6aaa Comments, refactor 2023-10-28 10:53:07 +02:00
Krzysiek Egzmont
3b3db88e5e Fix s-meter displaying for overpowering signals 2023-10-28 10:50:51 +02:00
Krzysiek Egzmont
f6791395cc Modified displaying of little sbar 2023-10-28 10:45:56 +02:00
Krzysiek Egzmont
8739996668 Changed little sbar back to factory 2023-10-27 15:32:14 +02:00
Krzysiek Egzmont
1740583ccc Set the backlight to minimum on reboot 2023-10-27 11:08:28 +02:00
Krzysiek Egzmont
b12244e352 Fix the RX buzzing problem after reboot 2023-10-27 10:53:22 +02:00
Krzysiek Egzmont
e6ac0d1d8d Import bk4819 changes 2023-10-26 18:30:35 +02:00
Krzysiek Egzmont
eda199d47a Back-light PWM 2023-10-26 18:20:28 +02:00
Krzysiek Egzmont
012c375f2e Fix build error 2023-10-26 10:55:33 +02:00
Krzysiek Egzmont
4a96dfa6ce AM fix gains adjusted 2023-10-25 23:24:45 +02:00
Krzysiek Egzmont
ec10aec0c4 Fix monitor listens on the opposite VFO when XB with DW is active at the same time 2023-10-25 21:35:34 +02:00
Krzysiek Egzmont
49c2c6b405 Refactor 2023-10-25 20:56:03 +02:00
Krzysiek Egzmont
38b1e5cbaa #45 piotr022 style S-meter 2023-10-25 14:39:21 +02:00
Krzysiek Egzmont
9a64a18010 #44 Channel/frequency scanner remember last found channel 2023-10-25 02:34:52 +02:00
Krzysiek Egzmont
72eddd009b Refactor 2023-10-25 01:26:14 +02:00
Krzysiek Egzmont
77d58eb8f5 Stop scan with MENU button and accept scan result 2023-10-24 04:09:46 +02:00
Krzysiek Egzmont
856dbe083d Increase DTMF string buffers size 2023-10-24 03:43:48 +02:00
Krzysiek Egzmont
50cc34ad9b Refactor 2023-10-24 03:42:34 +02:00
Krzysiek Egzmont
c996577a0b Fix frequency wraparound over band limit 2023-10-24 03:31:43 +02:00
Krzysiek Egzmont
e877820594 Change upper limit of airband to 137MHz 2023-10-24 03:29:50 +02:00
Krzysiek Egzmont
8ab123c927 Add new "VFO/MR" configurable button function 2023-10-24 02:34:29 +02:00
Krzysiek Egzmont
a510b89c6a Refactor frequency rounding 2023-10-24 02:25:01 +02:00
Krzysiek Egzmont
8b41a1fa66 Fix offset display in menu 2023-10-24 01:56:27 +02:00
Krzysiek Egzmont
99fc8a8311 FIX #43: frequent offset menu is not working properly 2023-10-24 01:54:57 +02:00
Krzysiek Egzmont
5c3eea2fcb Restart dual watch after VFO switched 2023-10-22 02:24:04 +02:00
Krzysiek Egzmont
ffb26a1f86 Refactoring 2023-10-22 02:23:16 +02:00
Krzysiek Egzmont
a8ae1b7739 Add menu configurable long-press function for MENU button 2023-10-22 02:11:26 +02:00
Krzysiek Egzmont
b59df11bd6 Refactoring 2023-10-21 06:12:59 +02:00
Krzysiek Egzmont
146c8dede4 Move copy channel to frequency mode from long press M to 1/BAND 2023-10-21 06:11:28 +02:00
Krzysiek Egzmont
c2090676d8 Side-key functions added: key lock, switch VFOs 2023-10-21 06:11:02 +02:00
Krzysiek Egzmont
b29bae88f1 Change SC_REV menu items names 2023-10-20 19:11:30 +02:00
Krzysiek Egzmont
c55a40481d Spectrum refactoring 2023-10-20 17:23:45 +02:00
Krzysiek Egzmont
a37a1ca6ef Fonts trimmed to save quite a bit of space 2023-10-20 16:52:15 +02:00
Krzysiek Egzmont
8629b1b867 Refactoring 2023-10-20 16:49:53 +02:00
Krzysiek Egzmont
f7c0d4149b Reduce EEPROM wear, don't check if changed before write. 2023-10-20 12:01:06 +02:00
Krzysiek Egzmont
87fd5c19d0 README.md updated 2023-10-20 01:35:11 +02:00
Krzysiek Egzmont
d132969c91 Support for >1GHz frequencies input 2023-10-20 00:15:11 +02:00
Krzysiek Egzmont
a5fa0b1e4b Refactoring, cleanup, comments 2023-10-19 21:42:56 +02:00
Krzysiek Egzmont
a21c8a62ac Small changes 2023-10-19 21:29:54 +02:00
Krzysiek Egzmont
9fd3701f46 Don't activate RX VFO when crossband is active 2023-10-19 17:00:22 +02:00
Krzysiek Egzmont
1d95737088 Refactoring, cleanup, comments 2023-10-19 16:58:12 +02:00
Krzysiek Egzmont
2f7042056a Display frequencies >=1GHz 2023-10-19 02:35:34 +02:00
Krzysiek Egzmont
13b41abce6 REFACTORING: Fixed correct BK4819 GPIO pin names 2023-10-18 17:27:18 +02:00
Krzysiek Egzmont
b9f9566158 Additional fix for RSSI calibration 2023-10-18 17:02:49 +02:00
Krzysiek Egzmont
710a417e12 FIX #31: Disable ENABLE_CTCSS_TAIL_PHASE_SHIFT that causes STE not to work 2023-10-18 00:29:20 +02:00
Krzysiek Egzmont
f11d0fbcda Code refactoring 2023-10-17 21:47:39 +02:00
Krzysiek Egzmont
96144af9e9 Added function buttons configuration to menu 2023-10-17 20:16:56 +02:00
Krzysiek Egzmont
4dd2445833 Menu items reordered 2023-10-17 13:34:18 +02:00
Krzysiek Egzmont
6172d942be Fix scanning on opposite VFO, ignore scan result on EXIT button, changed status bar while scanning 2023-10-17 02:57:55 +02:00
Krzysiek Egzmont
0c0cbb232c Refactoring 2023-10-17 02:26:20 +02:00
Krzysiek Egzmont
298ff29cf4 Fix restore VFO settings after scan 2023-10-16 22:59:17 +02:00
Krzysiek Egzmont
f70707e17f Fix copy channel to VFO function copying wrong VFO, clean VFO setup 2023-10-16 18:39:20 +02:00
Krzysiek Egzmont
f1fc04591c Fix compiler errors 2023-10-16 17:17:17 +02:00
Krzysiek Egzmont
a26c397417 Remove fall-through pragmas 2023-10-16 16:52:32 +02:00
Krzysiek Egzmont
d3a2a7bee9 Menu id fix 2023-10-16 16:02:39 +02:00
Krzysiek Egzmont
d817ff7e6a Fixed RSSI calibration 2023-10-16 13:01:24 +02:00
Krzysiek Egzmont
ec4bec5b1f Flashlight SOS function 2023-10-16 00:15:04 +02:00
Krzysiek Egzmont
d7c458839c Change menu items names 2023-10-15 22:07:55 +02:00
Krzysiek Egzmont
cff2f25e56 Consolidate "T VFO" and "DUALRX" into one "RXMODE" 2023-10-15 21:52:42 +02:00
Krzysiek Egzmont
63ac84883e add execute rights to compile-with-docker.sh 2023-10-15 21:12:06 +02:00
wrobepio
f8252df281 fixed: "compiled-firmware" folder missing under linux - fixed shell variable $PWD 2023-10-14 20:26:29 +02:00
Krzysiek Egzmont
be00bb99ad FIX #28: After entering item 51(BATVOL) of the menu, the automatic lock screen cannot be unlocked 2023-10-12 20:45:26 +02:00
Krzysiek Egzmont
7e6a78ab6c FIX #26: vfo state (TX DISABLE label) update issue when FM radio disabled in Makefile 2023-10-12 00:44:52 +02:00
66 changed files with 2848 additions and 2732 deletions

View File

@@ -22,7 +22,7 @@ ENABLE_KEEP_MEM_NAME := 1
ENABLE_WIDE_RX := 1
ENABLE_TX_WHEN_AM := 0
ENABLE_F_CAL_MENU := 0
ENABLE_CTCSS_TAIL_PHASE_SHIFT := 1
ENABLE_CTCSS_TAIL_PHASE_SHIFT := 0
ENABLE_BOOT_BEEPS := 0
ENABLE_SHOW_CHARGE_LEVEL := 1
ENABLE_REVERSE_BAT_SYMBOL := 0
@@ -35,8 +35,7 @@ ENABLE_RSSI_BAR := 1
ENABLE_AUDIO_BAR := 1
ENABLE_COPY_CHAN_TO_VFO := 1
ENABLE_SPECTRUM := 1
#ENABLE_SINGLE_VFO_CHAN := 1
#ENABLE_BAND_SCOPE := 1
ENABLE_REDUCE_LOW_MID_TX_POWER:= 0
#############################################################
@@ -104,6 +103,7 @@ ifeq ($(ENABLE_FMRADIO),1)
OBJS += app/fm.o
endif
OBJS += app/generic.o
OBJS += app/common.o
OBJS += app/main.o
OBJS += app/menu.o
ifeq ($(ENABLE_SPECTRUM), 1)
@@ -209,7 +209,8 @@ endif
#CFLAGS += -Wpadded
# catch any and all warnings
#CFLAGS += -Wextra
CFLAGS += -Wextra
#CFLAGS += -Wpedantic
CFLAGS += -DPRINTF_INCLUDE_CONFIG_H
CFLAGS += -DGIT_HASH=\"$(GIT_HASH)\"
@@ -316,6 +317,9 @@ endif
ifeq ($(ENABLE_BAND_SCOPE),1)
CFLAGS += -DENABLE_BAND_SCOPE
endif
ifeq ($(ENABLE_REDUCE_LOW_MID_TX_POWER),1)
CFLAGS += -DENABLE_REDUCE_LOW_MID_TX_POWER
endif
LDFLAGS =
ifeq ($(ENABLE_CLANG),0)

View File

@@ -1,8 +1,9 @@
# Main features:
- OneOfEleven mods, including AM fix
- many of OneOfEleven mods, including AM fix
- fagci spectrum analyzer (**F+5** to turn on)
- better battery percentage calculation (based on real measurement, battery calibration recommended)
- battery calibration option available available in the menu (instructions below)
- some other smaller mods introduced by me
Go to [Wiki](https://github.com/egzumer/uv-k5-firmware-custom/wiki) to learn more.
<img src="images/main.jpg" width=300 /><img src="images/spectrum.jpg" width=300 /><img src="images/audiobar.jpg" width=300 /><img src="images/rssibar.jpg" width=300 />

View File

@@ -51,10 +51,10 @@
// <7:5> = LNA Gain
// 7 = 0dB
// 6 = -2dB
// 5 = -4dB
// 5 = -4dB < original value
// 4 = -6dB
// 3 = -9dB
// 2 = -14dB < original value
// 2 = -14dB
// 1 = -19dB
// 0 = -24dB
//
@@ -192,26 +192,26 @@
{0x03D3, -20}, // 77 .. 3 6 2 3 .. 0dB -2dB -3dB -15dB .. -20dB
{0x03BB, -19}, // 78 .. 3 5 3 3 .. 0dB -4dB 0dB -15dB .. -19dB
{0x037C, -18}, // 79 .. 3 3 3 4 .. 0dB -9dB 0dB -9dB .. -18dB
{0x035E, -17}, // 80 .. 3 2 3 6 .. 0dB -14dB 0dB -3dB .. -17dB original
{0x03CC, -17}, // 80 .. 3 6 1 4 .. 0dB -2dB -6dB -9dB .. -17dB
{0x03C5, -16}, // 81 .. 3 6 0 5 .. 0dB -2dB -8dB -6dB .. -16dB
{0x03EC, -15}, // 82 .. 3 7 1 4 .. 0dB 0dB -6dB -9dB .. -15dB
{0x035F, -14}, // 83 .. 3 2 3 7 .. 0dB -14dB 0dB 0dB .. -14dB
{0x03C6, -13}, // 84 .. 3 6 0 6 .. 0dB -2dB -8dB -3dB .. -13dB
{0x0377, -12}, // 85 .. 3 3 2 7 .. 0dB -9dB -3dB 0dB .. -12dB
{0x03BC, -13}, // 84 .. 3 5 3 4 .. 0dB -4dB 0dB -9dB .. -13dB
{0x038F, -12}, // 85 .. 3 4 1 7 .. 0dB -6dB -6dB 0dB .. -12dB
{0x03E6, -11}, // 86 .. 3 7 0 6 .. 0dB 0dB -8dB -3dB .. -11dB
{0x03BD, -10}, // 87 .. 3 5 3 5 .. 0dB -4dB 0dB -6dB .. -10dB
{0x03F5, -9}, // 88 .. 3 7 2 5 .. 0dB 0dB -3dB -6dB .. -9dB
{0x03DD, -8}, // 89 .. 3 6 3 5 .. 0dB -2dB 0dB -6dB .. -8dB
{0x03B7, -7}, // 90 .. 3 5 2 7 .. 0dB -4dB -3dB 0dB .. -7dB
{0x03F6, -6}, // 91 .. 3 7 2 6 .. 0dB 0dB -3dB -3dB .. -6dB
{0x03D7, -5}, // 92 .. 3 6 2 7 .. 0dB -2dB -3dB 0dB .. -5dB
{0x03BF, -4}, // 93 .. 3 5 3 7 .. 0dB -4dB 0dB 0dB .. -4dB
{0x03F7, -3}, // 94 .. 3 7 2 7 .. 0dB 0dB -3dB 0dB .. -3dB
{0x03DF, -2}, // 95 .. 3 6 3 7 .. 0dB -2dB 0dB 0dB .. -2dB
{0x03FF, 0} // 96 .. 3 7 3 7 .. 0dB 0dB 0dB 0dB .. 0dB
{0x03AF, -10}, // 87 .. 3 5 1 7 .. 0dB -4dB -6dB 0dB .. -10dB
{0x03F5, -9 }, // 88 .. 3 7 2 5 .. 0dB 0dB -3dB -6dB .. -9dB
{0x03D6, -8 }, // 89 .. 3 6 2 6 .. 0dB -2dB -3dB -3dB .. -8dB
{0x03BE, -7 }, // 90 .. 3 5 3 6 .. 0dB -4dB 0dB -3dB .. -7dB original
{0x03F6, -6 }, // 91 .. 3 7 2 6 .. 0dB 0dB -3dB -3dB .. -6dB
{0x03DE, -5 }, // 92 .. 3 6 3 6 .. 0dB -2dB 0dB -3dB .. -5dB
{0x03BF, -4 }, // 93 .. 3 5 3 7 .. 0dB -4dB 0dB 0dB .. -4dB
{0x03F7, -3 }, // 94 .. 3 7 2 7 .. 0dB 0dB -3dB 0dB .. -3dB
{0x03DF, -2 }, // 95 .. 3 6 3 7 .. 0dB -2dB 0dB 0dB .. -2dB
{0x03FF, 0 }, // 96 .. 3 7 3 7 .. 0dB 0dB 0dB 0dB .. 0dB
};
static const unsigned int original_index = 80;
static const unsigned int original_index = 90;
#endif

View File

@@ -18,6 +18,7 @@
#include "app/action.h"
#include "app/app.h"
#include "app/common.h"
#include "app/dtmf.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
@@ -45,6 +46,7 @@ static void ACTION_FlashLight(void)
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
break;
case 1:
case 2:
gFlashLightState++;
break;
default:
@@ -114,55 +116,53 @@ void ACTION_Monitor(void)
void ACTION_Scan(bool bRestart)
{
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
{
if (gCurrentFunction != FUNCTION_RECEIVE &&
gCurrentFunction != FUNCTION_MONITOR &&
gCurrentFunction != FUNCTION_TRANSMIT)
{
if (gCurrentFunction != FUNCTION_RECEIVE &&
gCurrentFunction != FUNCTION_MONITOR &&
gCurrentFunction != FUNCTION_TRANSMIT)
GUI_SelectNextDisplay(DISPLAY_FM);
gMonitor = false;
if (gFM_ScanState != FM_SCAN_OFF)
{
GUI_SelectNextDisplay(DISPLAY_FM);
FM_PlayAndUpdate();
gMonitor = false;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
else
{
uint16_t Frequency;
if (gFM_ScanState != FM_SCAN_OFF)
if (bRestart)
{
FM_PlayAndUpdate();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
gFM_AutoScan = true;
gFM_ChannelPosition = 0;
FM_EraseChannels();
Frequency = gEeprom.FM_LowerLimit;
}
else
{
uint16_t Frequency;
if (bRestart)
{
gFM_AutoScan = true;
gFM_ChannelPosition = 0;
FM_EraseChannels();
Frequency = gEeprom.FM_LowerLimit;
}
else
{
gFM_AutoScan = false;
gFM_ChannelPosition = 0;
Frequency = gEeprom.FM_FrequencyPlaying;
}
BK1080_GetFrequencyDeviation(Frequency);
FM_Tune(Frequency, 1, bRestart);
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;
#endif
gFM_AutoScan = false;
gFM_ChannelPosition = 0;
Frequency = gEeprom.FM_FrequencyPlaying;
}
}
return;
BK1080_GetFrequencyDeviation(Frequency);
FM_Tune(Frequency, 1, bRestart);
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;
#endif
}
}
#endif
return;
}
#endif
if (gScreenToDisplay != DISPLAY_SCANNER)
{ // not scanning
@@ -176,23 +176,23 @@ void ACTION_Scan(bool bRestart)
RADIO_SelectVfos();
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif
#ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif
{
GUI_SelectNextDisplay(DISPLAY_MAIN);
if (gScanStateDir != SCAN_OFF)
{ // already scanning
if (gNextMrChannel <= MR_CHANNEL_LAST)
if (IS_MR_CHANNEL(gNextMrChannel))
{ // channel mode
// keep scanning but toggle between scan lists
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3;
// jump to the next channel
CHANNEL_Next(true, gScanStateDir);
SCANNER_ScanChannels(false, gScanStateDir);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;
@@ -211,7 +211,7 @@ void ACTION_Scan(bool bRestart)
else
{ // start scanning
CHANNEL_Next(true, SCAN_FWD);
SCANNER_ScanChannels(true, SCAN_FWD);
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN);
@@ -229,12 +229,12 @@ void ACTION_Scan(bool bRestart)
}
else
// if (!bRestart)
if (!bRestart && gNextMrChannel <= MR_CHANNEL_LAST)
if (!bRestart && IS_MR_CHANNEL(gNextMrChannel))
{ // channel mode, keep scanning but toggle between scan lists
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3;
// jump to the next channel
CHANNEL_Next(true, gScanStateDir);
SCANNER_ScanChannels(false, gScanStateDir);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;
@@ -325,18 +325,15 @@ void ACTION_Scan(bool bRestart)
void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
uint8_t Short = ACTION_OPT_NONE;
uint8_t Long = ACTION_OPT_NONE;
if (gScreenToDisplay == DISPLAY_MAIN && gDTMF_InputMode)
if (gScreenToDisplay == DISPLAY_MAIN && gDTMF_InputMode) // entering DTMF code
{
if (Key == KEY_SIDE1 && !bKeyHeld && bKeyPressed)
if (Key == KEY_SIDE1 && !bKeyHeld && bKeyPressed) // side1 btn pressed
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gDTMF_InputBox_Index > 0)
if (gDTMF_InputBox_Index > 0) // DTMF codes are in the input box
{
gDTMF_InputBox[--gDTMF_InputBox_Index] = '-';
gDTMF_InputBox[--gDTMF_InputBox_Index] = '-'; // delete one code
if (gDTMF_InputBox_Index > 0)
{
gPttWasReleased = true;
@@ -350,43 +347,52 @@ void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
#endif
gRequestDisplayScreen = DISPLAY_MAIN;
gDTMF_InputMode = false;
gDTMF_InputMode = false; // turn off DTMF input box if no codes left
}
gPttWasReleased = true;
return;
}
if (Key == KEY_SIDE1)
{
Short = gEeprom.KEY_1_SHORT_PRESS_ACTION;
Long = gEeprom.KEY_1_LONG_PRESS_ACTION;
}
else
if (Key == KEY_SIDE2)
{
Short = gEeprom.KEY_2_SHORT_PRESS_ACTION;
Long = gEeprom.KEY_2_LONG_PRESS_ACTION;
uint8_t funcShort = ACTION_OPT_NONE;
uint8_t funcLong = ACTION_OPT_NONE;
switch(Key) {
case KEY_SIDE1:
funcShort = gEeprom.KEY_1_SHORT_PRESS_ACTION;
funcLong = gEeprom.KEY_1_LONG_PRESS_ACTION;
break;
case KEY_SIDE2:
funcShort = gEeprom.KEY_2_SHORT_PRESS_ACTION;
funcLong = gEeprom.KEY_2_LONG_PRESS_ACTION;
break;
case KEY_MENU:
funcLong = gEeprom.KEY_M_LONG_PRESS_ACTION;
break;
default:
break;
}
if (!bKeyHeld && bKeyPressed)
if (!bKeyHeld && bKeyPressed) // button pushed
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
if (bKeyHeld || bKeyPressed)
// held or released beyond this point
if(!(bKeyHeld && !bKeyPressed)) // don't beep on released after hold
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (bKeyHeld || bKeyPressed) // held
{
if (!bKeyHeld)
return;
funcShort = funcLong;
Short = Long;
if (!bKeyPressed)
if (!bKeyPressed) //ignore release if held
return;
}
switch (Short)
// held or released after short press beyond this point
switch (funcShort)
{
default:
case ACTION_OPT_NONE:
@@ -404,24 +410,33 @@ void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
ACTION_Scan(true);
break;
case ACTION_OPT_VOX:
#ifdef ENABLE_VOX
ACTION_Vox();
#endif
#ifdef ENABLE_VOX
ACTION_Vox();
#endif
break;
case ACTION_OPT_ALARM:
#ifdef ENABLE_ALARM
ACTION_AlarmOr1750(false);
#endif
#ifdef ENABLE_ALARM
ACTION_AlarmOr1750(false);
#endif
break;
#ifdef ENABLE_FMRADIO
case ACTION_OPT_FM:
ACTION_FM();
break;
#endif
#ifdef ENABLE_FMRADIO
case ACTION_OPT_FM:
ACTION_FM();
break;
#endif
case ACTION_OPT_1750:
#ifdef ENABLE_TX1750
ACTION_AlarmOr1750(true);
#endif
break;
case ACTION_OPT_KEYLOCK:
COMMON_KeypadLockToggle();
break;
case ACTION_OPT_A_B:
COMMON_SwitchVFOs();
break;
case ACTION_OPT_VFO_MR:
COMMON_SwitchVFOMode();
break;
}
}

View File

@@ -22,7 +22,7 @@
//static void ACTION_FlashLight(void)
void ACTION_Power(void);
void ACTION_Monitor(void);
void ACTION_Scan(bool bFlag);
void ACTION_Scan(bool bRestart);
#ifdef ENABLE_VOX
void ACTION_Vox(void);
#endif

View File

@@ -57,7 +57,7 @@ void AIRCOPY_SendMessage(void)
BK4819_SendFSKData(g_FSK_Buffer);
BK4819_SetupPowerAmplifier(0, 0);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, false);
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
gAircopySendCountdown = 30;
}
@@ -131,8 +131,7 @@ static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
}
gInputBoxIndex = 0;
NUMBER_Get(gInputBox, &Frequency);
Frequency = StrToUL(INPUTBOX_GetAscii()) * 100;
for (i = 0; i < ARRAY_SIZE(frequencyBandTable); i++)
{
@@ -142,8 +141,7 @@ static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gRxVfo->Band = i;
Frequency += 75;
Frequency = FREQUENCY_FloorToStep(Frequency, gRxVfo->StepFrequency, 0);
Frequency = FREQUENCY_RoundToStep(Frequency, gRxVfo->StepFrequency);
gRxVfo->freq_config_RX.Frequency = Frequency;
gRxVfo->freq_config_TX.Frequency = Frequency;
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);

797
app/app.c

File diff suppressed because it is too large Load Diff

View File

@@ -23,15 +23,9 @@
#include "frequencies.h"
#include "radio.h"
extern const uint8_t orig_lna_short;
extern const uint8_t orig_lna;
extern const uint8_t orig_mixer;
extern const uint8_t orig_pga;
void APP_EndTransmission(void);
void CHANNEL_Next(const bool bFlag, const int8_t scan_direction);
void APP_StartListening(FUNCTION_Type_t Function, const bool reset_am_fix);
uint32_t APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t Step);
uint32_t APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t direction);
void APP_Update(void);
void APP_TimeSlice10ms(void);
void APP_TimeSlice500ms(void);

73
app/common.c Normal file
View File

@@ -0,0 +1,73 @@
#include "audio.h"
#include "functions.h"
#include "misc.h"
#include "settings.h"
#include "ui/ui.h"
void COMMON_KeypadLockToggle()
{
if (gScreenToDisplay != DISPLAY_MENU &&
gCurrentFunction != FUNCTION_TRANSMIT)
{ // toggle the keyboad lock
#ifdef ENABLE_VOICE
gAnotherVoiceID = gEeprom.KEY_LOCK ? VOICE_ID_UNLOCK : VOICE_ID_LOCK;
#endif
gEeprom.KEY_LOCK = !gEeprom.KEY_LOCK;
gRequestSaveSettings = true;
}
}
void COMMON_SwitchVFOs()
{
gEeprom.TX_VFO ^= 1;
if (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF)
gEeprom.CROSS_BAND_RX_TX = gEeprom.TX_VFO + 1;
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
gEeprom.DUAL_WATCH = gEeprom.TX_VFO + 1;
gRequestSaveSettings = 1;
gFlagReconfigureVfos = true;
gScheduleDualWatch = true;
gRequestDisplayScreen = DISPLAY_MAIN;
}
void COMMON_SwitchVFOMode()
{
#ifdef ENABLE_NOAA
if (gEeprom.VFO_OPEN && !IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
#else
if (gEeprom.VFO_OPEN)
#endif
{
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // swap to frequency mode
gEeprom.ScreenChannel[gEeprom.TX_VFO] = gEeprom.FreqChannel[gEeprom.TX_VFO];
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
return;
}
uint8_t Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 0);
if (Channel != 0xFF)
{ // swap to channel mode
gEeprom.ScreenChannel[gEeprom.TX_VFO] = Channel;
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
AUDIO_SetDigitVoice(1, Channel + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
return;
}
}
}

13
app/common.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef APP_COMMON_H
#define APP_COMMON_H
#include "functions.h"
#include "settings.h"
#include "ui/ui.h"
void COMMON_KeypadLockToggle();
void COMMON_SwitchVFOs();
void COMMON_SwitchVFOMode();
#endif

View File

@@ -203,7 +203,7 @@ void DTMF_Append(const char code)
void DTMF_HandleRequest(void)
{ // proccess the RX'ed DTMF characters
char String[20];
char String[21];
unsigned int Offset;
if (!gDTMF_RX_pending)
@@ -356,13 +356,11 @@ void DTMF_HandleRequest(void)
gUpdateDisplay = true;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (gEeprom.DTMF_DECODE_RESPONSE)
{
case DTMF_DEC_RESPONSE_BOTH:
gDTMF_DecodeRingCountdown_500ms = DTMF_decode_ring_countdown_500ms;
[[fallthrough]];
case DTMF_DEC_RESPONSE_REPLY:
gDTMF_ReplyState = DTMF_REPLY_AAAAA;
break;
@@ -376,8 +374,6 @@ void DTMF_HandleRequest(void)
break;
}
#pragma GCC diagnostic pop
if (gDTMF_IsGroupCall)
gDTMF_ReplyState = DTMF_REPLY_NONE;
}
@@ -387,7 +383,7 @@ void DTMF_HandleRequest(void)
void DTMF_Reply(void)
{
uint16_t Delay;
char String[20];
char String[23];
const char *pString = NULL;
switch (gDTMF_ReplyState)
@@ -438,7 +434,7 @@ void DTMF_Reply(void)
if (gEeprom.DTMF_SIDE_TONE)
{ // the user will also hear the transmitted tones
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
gEnableSpeaker = true;
}
@@ -454,7 +450,7 @@ void DTMF_Reply(void)
gEeprom.DTMF_CODE_PERSIST_TIME,
gEeprom.DTMF_CODE_INTERVAL_TIME);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
gEnableSpeaker = false;

View File

@@ -45,7 +45,6 @@ bool gFM_AutoScan;
uint8_t gFM_ChannelPosition;
bool gFM_FoundFrequency;
bool gFM_AutoScan;
uint8_t gFM_ResumeCountdown_500ms;
uint16_t gFM_RestoreCountdown_10ms;
bool FM_CheckValidChannel(uint8_t Channel)
@@ -97,7 +96,7 @@ void FM_TurnOff(void)
gFM_ScanState = FM_SCAN_OFF;
gFM_RestoreCountdown_10ms = 0;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
gEnableSpeaker = false;
@@ -120,7 +119,7 @@ void FM_EraseChannels(void)
void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag)
{
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
gEnableSpeaker = false;
@@ -167,7 +166,7 @@ void FM_PlayAndUpdate(void)
gScheduleFM = false;
gAskToSave = false;
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
gEnableSpeaker = true;
}
@@ -278,8 +277,7 @@ static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
uint32_t Frequency;
gInputBoxIndex = 0;
NUMBER_Get(gInputBox, &Frequency);
Frequency /= 10000;
Frequency = StrToUL(INPUTBOX_GetAscii());
if (Frequency < gEeprom.FM_LowerLimit || gEeprom.FM_UpperLimit < Frequency)
{
@@ -627,7 +625,7 @@ void FM_Play(void)
if (!gEeprom.FM_IsMrMode)
gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying;
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
gEnableSpeaker = true;
GUI_SelectNextDisplay(DISPLAY_FM);
@@ -661,7 +659,7 @@ void FM_Start(void)
BK1080_Init(gEeprom.FM_FrequencyPlaying, true);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
gEnableSpeaker = true;
gUpdateStatus = true;

View File

@@ -39,7 +39,6 @@ extern uint8_t gFM_ChannelPosition;
extern uint16_t gFM_FrequencyDeviation;
extern bool gFM_FoundFrequency;
extern bool gFM_AutoScan;
extern uint8_t gFM_ResumeCountdown_500ms;
extern uint16_t gFM_RestoreCountdown_10ms;
bool FM_CheckValidChannel(uint8_t Channel);

View File

@@ -17,9 +17,12 @@
#include <string.h>
#include "app/app.h"
#include "app/common.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif
#include "app/generic.h"
#include "app/menu.h"
#include "app/scanner.h"
@@ -52,18 +55,7 @@ void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
if (!bKeyPressed) // won't ever pass
return;
if (gScreenToDisplay != DISPLAY_MENU &&
gCurrentFunction != FUNCTION_TRANSMIT)
{ // toggle the keyboad lock
#ifdef ENABLE_VOICE
gAnotherVoiceID = gEeprom.KEY_LOCK ? VOICE_ID_UNLOCK : VOICE_ID_LOCK;
#endif
gEeprom.KEY_LOCK = !gEeprom.KEY_LOCK;
gRequestSaveSettings = true;
}
COMMON_KeypadLockToggle();
}
else // released
{
@@ -220,21 +212,12 @@ void GENERIC_Key_PTT(bool bKeyPressed)
if (gDTMF_InputBox_Index < sizeof(gDTMF_InputBox))
gDTMF_InputBox[gDTMF_InputBox_Index] = 0; // NULL term the string
#if 0
// append our DTMF ID to the inputted DTMF code -
// IF the user inputted code is exactly 3 digits long
if (gDTMF_InputBox_Index == 3)
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
else
gDTMF_CallMode = DTMF_CALL_MODE_DTMF;
#else
// append our DTMF ID to the inputted DTMF code -
// IF the user inputted code is exactly 3 digits long and D-DCD is enabled
if (gDTMF_InputBox_Index == 3 && gTxVfo->DTMF_DECODING_ENABLE > 0)
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
else
gDTMF_CallMode = DTMF_CALL_MODE_DTMF;
#endif
// append our DTMF ID to the inputted DTMF code -
// IF the user inputted code is exactly 3 digits long and D-DCD is enabled
if (gDTMF_InputBox_Index == 3 && gTxVfo->DTMF_DECODING_ENABLE > 0)
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
else
gDTMF_CallMode = DTMF_CALL_MODE_DTMF;
// remember the DTMF string
gDTMF_PreviousIndex = gDTMF_InputBox_Index;

View File

@@ -18,15 +18,18 @@
#include "app/action.h"
#include "app/app.h"
#include "app/common.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#endif
#include "app/generic.h"
#include "app/main.h"
#include "app/scanner.h"
#ifdef ENABLE_SPECTRUM
#include "app/spectrum.h"
#endif
#include "audio.h"
#include "board.h"
#include "driver/bk4819.h"
@@ -37,9 +40,7 @@
#include "settings.h"
#include "ui/inputbox.h"
#include "ui/ui.h"
#ifdef ENABLE_SPECTRUM
// #include "app/spectrum.h"
#endif
#include <stdlib.h>
void toggle_chan_scanlist(void)
{ // toggle the selected channels scanlist setting
@@ -98,26 +99,71 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break;
case KEY_1:
if (!IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
if (!IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE)) {
gWasFKeyPressed = false;
gUpdateStatus = true;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
#ifdef ENABLE_COPY_CHAN_TO_VFO
if (gEeprom.VFO_OPEN && gCssScanMode == CSS_SCAN_MODE_OFF)
{
if (gScanStateDir != SCAN_OFF)
{
if (gCurrentFunction != FUNCTION_INCOMING ||
gRxReceptionMode == RX_MODE_NONE ||
gScanPauseDelayIn_10ms == 0)
{ // scan is running (not paused)
return;
}
}
const uint8_t vfo = gEeprom.TX_VFO;
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo]))
{ // copy channel to VFO, then swap to the VFO
const unsigned int channel = FREQ_CHANNEL_FIRST + gEeprom.VfoInfo[vfo].Band;
gEeprom.ScreenChannel[vfo] = channel;
gEeprom.VfoInfo[vfo].CHANNEL_SAVE = channel;
RADIO_SelectVfos();
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
RADIO_SetupRegisters(true);
//SETTINGS_SaveChannel(channel, gEeprom.RX_VFO, gRxVfo, 1);
gUpdateDisplay = true;
}
}
else
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
#endif
return;
}
Band = gTxVfo->Band + 1;
if (gSetting_350EN || Band != BAND5_350MHz)
{
if (Band > BAND7_470MHz)
Band = BAND1_50MHz;
if(gTxVfo->Band == 6 && gTxVfo->pRX->Frequency < 100000000) {
gTxVfo->pRX->Frequency = 100000000;
return;
}
else
Band = BAND6_400MHz;
gTxVfo->Band = Band;
else {
Band = gTxVfo->Band + 1;
if (gSetting_350EN || Band != BAND5_350MHz) {
if (Band > BAND7_470MHz)
Band = BAND1_50MHz;
}
else
Band = BAND6_400MHz;
gEeprom.ScreenChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
gEeprom.FreqChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
gTxVfo->Band = Band;
gEeprom.ScreenChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
gEeprom.FreqChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
}
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
@@ -130,64 +176,14 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break;
case KEY_2:
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_A)
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_CHAN_B;
else
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_B)
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_CHAN_A;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A)
gEeprom.DUAL_WATCH = DUAL_WATCH_CHAN_B;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B)
gEeprom.DUAL_WATCH = DUAL_WATCH_CHAN_A;
else
gEeprom.TX_VFO = (Vfo + 1) & 1u;
gRequestSaveSettings = 1;
gFlagReconfigureVfos = true;
gRequestDisplayScreen = DISPLAY_MAIN;
COMMON_SwitchVFOs();
if (beep)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
break;
case KEY_3:
#ifdef ENABLE_NOAA
if (gEeprom.VFO_OPEN && IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
#else
if (gEeprom.VFO_OPEN)
#endif
{
uint8_t Channel;
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // swap to frequency mode
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_VFO];
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
break;
}
Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_VFO], 1, false, 0);
if (Channel != 0xFF)
{ // swap to channel mode
gEeprom.ScreenChannel[Vfo] = Channel;
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
AUDIO_SetDigitVoice(1, Channel + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
break;
}
}
COMMON_SwitchVFOMode();
if (beep)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
@@ -209,18 +205,18 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
case KEY_5:
if(beep) {
#ifdef ENABLE_NOAA
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_VFO];
}
else
{
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_VFO];
#ifdef ENABLE_VOICE
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif
#endif
}
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
@@ -230,9 +226,9 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
#endif
}
else {
#ifdef ENABLE_VOX
#ifdef ENABLE_VOX
toggle_chan_scanlist();
#endif
#endif
}
break;
@@ -242,11 +238,11 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
break;
case KEY_7:
#ifdef ENABLE_VOX
ACTION_Vox();
#else
toggle_chan_scanlist();
#endif
#ifdef ENABLE_VOX
ACTION_Vox();
#else
toggle_chan_scanlist();
#endif
break;
case KEY_8:
@@ -259,11 +255,11 @@ static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
{
gEeprom.MrChannel[Vfo] = gEeprom.CHAN_1_CALL;
gEeprom.ScreenChannel[Vfo] = gEeprom.CHAN_1_CALL;
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
AUDIO_SetDigitVoice(1, gEeprom.CHAN_1_CALL + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
AUDIO_SetDigitVoice(1, gEeprom.CHAN_1_CALL + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
break;
@@ -362,14 +358,14 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
}
// #ifdef ENABLE_NOAA
// if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
// if (!IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
// #endif
if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
{ // user is entering a frequency
uint32_t Frequency;
if (gInputBoxIndex < 6)
bool isGigaF = gTxVfo->pRX->Frequency >= 100000000;
if (gInputBoxIndex < 6 + isGigaF)
{
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
@@ -379,8 +375,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
}
gInputBoxIndex = 0;
NUMBER_Get(gInputBox, &Frequency);
Frequency = StrToUL(INPUTBOX_GetAscii()) * 100;
// clamp the frequency entered to some valid value
if (Frequency < frequencyBandTable[0].lower)
@@ -417,10 +412,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
RADIO_ConfigureChannel(Vfo, VFO_CONFIGURE_RELOAD);
}
// Frequency += 75; // is this meant to be rounding ?
Frequency += gTxVfo->StepFrequency / 2; // no idea, but this is
Frequency = FREQUENCY_FloorToStep(Frequency, gTxVfo->StepFrequency, frequencyBandTable[gTxVfo->Band].lower);
Frequency = FREQUENCY_RoundToStep(Frequency, gTxVfo->StepFrequency);
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
{ // clamp the frequency to the limit
@@ -513,6 +505,7 @@ static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
}
else
{
gScanKeepResult = false;
SCANNER_Stop();
#ifdef ENABLE_VOICE
@@ -571,51 +564,7 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
gWasFKeyPressed = false;
gUpdateStatus = true;
#ifdef ENABLE_COPY_CHAN_TO_VFO
if (gEeprom.VFO_OPEN && gCssScanMode == CSS_SCAN_MODE_OFF)
{
if (gScanStateDir != SCAN_OFF)
{
if (gCurrentFunction != FUNCTION_INCOMING ||
gRxReceptionMode == RX_MODE_NONE ||
gScanPauseDelayIn_10ms == 0)
{ // scan is running (not paused)
return;
}
}
const unsigned int vfo = get_rx_VFO();
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo]))
{ // copy channel to VFO, then swap to the VFO
const unsigned int channel = FREQ_CHANNEL_FIRST + gEeprom.VfoInfo[vfo].Band;
gEeprom.ScreenChannel[vfo] = channel;
gEeprom.VfoInfo[vfo].CHANNEL_SAVE = channel;
gEeprom.TX_VFO = vfo;
RADIO_SelectVfos();
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
RADIO_SetupRegisters(true);
//SETTINGS_SaveChannel(channel, gEeprom.RX_VFO, gRxVfo, 1);
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gUpdateStatus = true;
gUpdateDisplay = true;
}
}
else
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
#endif
ACTION_Handle(KEY_MENU, bKeyPressed, bKeyHeld);
}
}
@@ -629,6 +578,11 @@ static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
if (bFlag)
{
if (gScanStateDir != SCAN_OFF) {
SCANNER_Stop();
return;
}
gFlagRefreshSetting = true;
gRequestDisplayScreen = DISPLAY_MENU;
#ifdef ENABLE_VOICE
@@ -654,31 +608,31 @@ static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
return;
}
if (bKeyHeld && !gWasFKeyPressed)
{ // long press .. toggle scanning
if (!bKeyPressed)
return; // released
if (bKeyHeld && !gWasFKeyPressed) // long press
{
if (!bKeyPressed) // released
return;
ACTION_Scan(false);
ACTION_Scan(false);// toggle scanning
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
if (bKeyPressed)
{ // just pressed
// gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (bKeyPressed) // just pressed
{
// gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gBeepToPlay = BEEP_880HZ_40MS_OPTIONAL;
return;
}
// just released
if (!gWasFKeyPressed)
{ // pressed without the F-key
if (!gWasFKeyPressed) // pressed without the F-key
{
#ifdef ENABLE_NOAA
if (gScanStateDir == SCAN_OFF && IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
if (gScanStateDir == SCAN_OFF && !IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
#else
if (gScanStateDir == SCAN_OFF)
#endif
@@ -756,7 +710,7 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
if (gScanStateDir == SCAN_OFF)
{
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(Channel))
if (!IS_NOAA_CHANNEL(Channel))
#endif
{
uint8_t Next;
@@ -810,7 +764,7 @@ static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
}
// jump to the next channel
CHANNEL_Next(false, Direction);
SCANNER_ScanChannels(false, Direction);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;

View File

@@ -98,9 +98,9 @@ void MENU_StopCssScan(void)
RADIO_SetupRegisters(true);
}
int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax)
int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
{
switch (Cursor)
switch (menu_id)
{
case MENU_SQL:
*pMin = 0;
@@ -117,6 +117,16 @@ int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax)
*pMax = ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1;
break;
case MENU_ABR_MIN:
*pMin = 0;
*pMax = 9;
break;
case MENU_ABR_MAX:
*pMin = 1;
*pMax = 10;
break;
case MENU_F_LOCK:
*pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_F_LOCK) - 1;
@@ -139,12 +149,7 @@ int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax)
case MENU_TDR:
*pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_CHAN) - 1;
break;
case MENU_XB:
*pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_XB) - 1;
*pMax = ARRAY_SIZE(gSubMenu_RXMode) - 1;
break;
#ifdef ENABLE_VOICE
@@ -285,7 +290,6 @@ int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax)
case MENU_S_LIST:
*pMin = 0;
// *pMax = 1;
*pMax = 2;
break;
@@ -327,8 +331,22 @@ int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax)
#endif
case MENU_BATCAL:
*pMin = 1600; // 0
*pMax = 2200; // 2300
*pMin = 1600;
*pMax = 2200;
break;
case MENU_BATTYP:
*pMin = 0;
*pMax = 1;
break;
case MENU_F1SHRT:
case MENU_F1LONG:
case MENU_F2SHRT:
case MENU_F2LONG:
case MENU_MLONG:
*pMin = 0;
*pMax = gSubMenu_SIDEFUNCTIONS_size-1;
break;
default:
@@ -345,14 +363,14 @@ void MENU_AcceptSetting(void)
uint8_t Code;
FREQ_Config_t *pConfig = &gTxVfo->freq_config_RX;
if (!MENU_GetLimits(gMenuCursor, &Min, &Max))
if (!MENU_GetLimits(GetCurrentMenuId(), &Min, &Max))
{
if (gSubMenuSelection < Min) gSubMenuSelection = Min;
else
if (gSubMenuSelection > Max) gSubMenuSelection = Max;
}
switch (gMenuCursor)
switch (GetCurrentMenuId())
{
default:
return;
@@ -408,11 +426,9 @@ void MENU_AcceptSetting(void)
gRequestSaveChannel = 1;
return;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
case MENU_T_CTCS:
pConfig = &gTxVfo->freq_config_TX;
[[fallthrough]];
case MENU_R_CTCS:
if (gSubMenuSelection == 0)
{
@@ -439,8 +455,6 @@ void MENU_AcceptSetting(void)
gRequestSaveChannel = 1;
return;
#pragma GCC diagnostic pop
case MENU_SFT_D:
gTxVfo->TX_OFFSET_FREQUENCY_DIRECTION = gSubMenuSelection;
gRequestSaveChannel = 1;
@@ -510,39 +524,38 @@ void MENU_AcceptSetting(void)
gEeprom.VOX_SWITCH = gSubMenuSelection != 0;
if (gEeprom.VOX_SWITCH)
gEeprom.VOX_LEVEL = gSubMenuSelection - 1;
BOARD_EEPROM_LoadMoreSettings();
BOARD_EEPROM_LoadCalibration();
gFlagReconfigureVfos = true;
gUpdateStatus = true;
break;
#endif
case MENU_ABR:
gEeprom.BACKLIGHT = gSubMenuSelection;
gEeprom.BACKLIGHT_TIME = gSubMenuSelection;
break;
case MENU_ABR_MIN:
gEeprom.BACKLIGHT_MIN = gSubMenuSelection;
gEeprom.BACKLIGHT_MAX = MAX(gSubMenuSelection + 1 , gEeprom.BACKLIGHT_MAX);
break;
case MENU_ABR_MAX:
gEeprom.BACKLIGHT_MAX = gSubMenuSelection;
gEeprom.BACKLIGHT_MIN = MIN(gSubMenuSelection - 1, gEeprom.BACKLIGHT_MIN);
break;
case MENU_ABR_ON_TX_RX:
gSetting_backlight_on_tx_rx = gSubMenuSelection;
break;
case MENU_TDR:
gEeprom.DUAL_WATCH = gSubMenuSelection;
gEeprom.DUAL_WATCH = (gEeprom.TX_VFO + 1) * (gSubMenuSelection & 1);
gEeprom.CROSS_BAND_RX_TX = (gEeprom.TX_VFO + 1) * ((gSubMenuSelection & 2) > 0);
gFlagReconfigureVfos = true;
gUpdateStatus = true;
break;
case MENU_XB:
#ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(gEeprom.ScreenChannel[0]))
return;
if (IS_NOAA_CHANNEL(gEeprom.ScreenChannel[1]))
return;
#endif
gEeprom.CROSS_BAND_RX_TX = gSubMenuSelection;
gFlagReconfigureVfos = true;
gUpdateStatus = true;
break;
case MENU_BEEP:
gEeprom.BEEP_CONTROL = gSubMenuSelection;
break;
@@ -586,7 +599,7 @@ void MENU_AcceptSetting(void)
return;
case MENU_STE:
gEeprom.TAIL_NOTE_ELIMINATION = gSubMenuSelection;
gEeprom.TAIL_TONE_ELIMINATION = gSubMenuSelection;
break;
case MENU_RP_STE:
@@ -595,7 +608,7 @@ void MENU_AcceptSetting(void)
case MENU_MIC:
gEeprom.MIC_SENSITIVITY = gSubMenuSelection;
BOARD_EEPROM_LoadMoreSettings();
BOARD_EEPROM_LoadCalibration();
gFlagReconfigureVfos = true;
break;
@@ -764,24 +777,37 @@ void MENU_AcceptSetting(void)
#endif
case MENU_BATCAL:
{
uint16_t buf[4];
{ // voltages are averages between discharge curves of 1600 and 2200 mAh
gBatteryCalibration[0] = (520ul * gSubMenuSelection) / 760; // 5.20V empty, blinking above this value, reduced functionality below
gBatteryCalibration[1] = (700ul * gSubMenuSelection) / 760; // 7.00V, ~5%, 1 bars above this value
gBatteryCalibration[2] = (745ul * gSubMenuSelection) / 760; // 7.45V, ~17%, 2 bars above this value
gBatteryCalibration[1] = (689ul * gSubMenuSelection) / 760; // 6.89V, ~5%, 1 bars above this value
gBatteryCalibration[2] = (724ul * gSubMenuSelection) / 760; // 7.24V, ~17%, 2 bars above this value
gBatteryCalibration[3] = gSubMenuSelection; // 7.6V, ~29%, 3 bars above this value
gBatteryCalibration[4] = (788ul * gSubMenuSelection) / 760; // 7.88V, ~65%, 4 bars above this value
gBatteryCalibration[4] = (771ul * gSubMenuSelection) / 760; // 7.71V, ~65%, 4 bars above this value
gBatteryCalibration[5] = 2300;
EEPROM_WriteBuffer(0x1F40, gBatteryCalibration);
EEPROM_ReadBuffer( 0x1F48, buf, sizeof(buf));
buf[0] = gBatteryCalibration[4];
buf[1] = gBatteryCalibration[5];
EEPROM_WriteBuffer(0x1F48, buf);
break;
SETTINGS_SaveBatteryCalibration(gBatteryCalibration);
return;
}
case MENU_BATTYP:
gEeprom.BATTERY_TYPE = gSubMenuSelection;
break;
case MENU_F1SHRT:
case MENU_F1LONG:
case MENU_F2SHRT:
case MENU_F2LONG:
case MENU_MLONG:
{
uint8_t * fun[]= {
&gEeprom.KEY_1_SHORT_PRESS_ACTION,
&gEeprom.KEY_1_LONG_PRESS_ACTION,
&gEeprom.KEY_2_SHORT_PRESS_ACTION,
&gEeprom.KEY_2_LONG_PRESS_ACTION,
&gEeprom.KEY_M_LONG_PRESS_ACTION};
*fun[GetCurrentMenuId()-MENU_F1SHRT] = gSubMenu_SIDEFUNCTIONS[gSubMenuSelection].id;
}
break;
}
gRequestSaveSettings = true;
@@ -791,18 +817,17 @@ void MENU_SelectNextCode(void)
{
int32_t UpperLimit;
if (gMenuCursor == MENU_R_DCS)
if (GetCurrentMenuId() == MENU_R_DCS)
UpperLimit = 208;
//UpperLimit = ARRAY_SIZE(DCS_Options);
else
if (gMenuCursor == MENU_R_CTCS)
else if (GetCurrentMenuId() == MENU_R_CTCS)
UpperLimit = ARRAY_SIZE(CTCSS_Options) - 1;
else
return;
gSubMenuSelection = NUMBER_AddWithWraparound(gSubMenuSelection, gMenuScrollDirection, 1, UpperLimit);
if (gMenuCursor == MENU_R_DCS)
if (GetCurrentMenuId() == MENU_R_DCS)
{
if (gSubMenuSelection > 104)
{
@@ -834,7 +859,7 @@ static void MENU_ClampSelection(int8_t Direction)
int32_t Min;
int32_t Max;
if (!MENU_GetLimits(gMenuCursor, &Min, &Max))
if (!MENU_GetLimits(GetCurrentMenuId(), &Min, &Max))
{
int32_t Selection = gSubMenuSelection;
if (Selection < Min) Selection = Min;
@@ -846,7 +871,7 @@ static void MENU_ClampSelection(int8_t Direction)
void MENU_ShowCurrentSetting(void)
{
switch (gMenuCursor)
switch (GetCurrentMenuId())
{
case MENU_SQL:
gSubMenuSelection = gEeprom.SQUELCH_LEVEL;
@@ -938,29 +963,30 @@ void MENU_ShowCurrentSetting(void)
gSubMenuSelection = gEeprom.BATTERY_SAVE;
break;
#ifdef ENABLE_VOX
case MENU_VOX:
gSubMenuSelection = gEeprom.VOX_SWITCH ? gEeprom.VOX_LEVEL + 1 : 0;
break;
#endif
#ifdef ENABLE_VOX
case MENU_VOX:
gSubMenuSelection = gEeprom.VOX_SWITCH ? gEeprom.VOX_LEVEL + 1 : 0;
break;
#endif
case MENU_ABR:
gSubMenuSelection = gEeprom.BACKLIGHT;
gBacklightCountdown = 0;
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight ON while in backlight menu
gSubMenuSelection = gEeprom.BACKLIGHT_TIME;
break;
case MENU_ABR_MIN:
gSubMenuSelection = gEeprom.BACKLIGHT_MIN;
break;
case MENU_ABR_MAX:
gSubMenuSelection = gEeprom.BACKLIGHT_MAX;
break;
case MENU_ABR_ON_TX_RX:
gSubMenuSelection = gSetting_backlight_on_tx_rx;
break;
case MENU_TDR:
gSubMenuSelection = gEeprom.DUAL_WATCH;
break;
case MENU_XB:
gSubMenuSelection = gEeprom.CROSS_BAND_RX_TX;
gSubMenuSelection = (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2;
break;
case MENU_BEEP:
@@ -971,11 +997,11 @@ void MENU_ShowCurrentSetting(void)
gSubMenuSelection = gEeprom.TX_TIMEOUT_TIMER;
break;
#ifdef ENABLE_VOICE
case MENU_VOICE:
gSubMenuSelection = gEeprom.VOICE_PROMPT;
break;
#endif
#ifdef ENABLE_VOICE
case MENU_VOICE:
gSubMenuSelection = gEeprom.VOICE_PROMPT;
break;
#endif
case MENU_SC_REV:
gSubMenuSelection = gEeprom.SCAN_RESUME_MODE;
@@ -998,7 +1024,7 @@ void MENU_ShowCurrentSetting(void)
break;
case MENU_STE:
gSubMenuSelection = gEeprom.TAIL_NOTE_ELIMINATION;
gSubMenuSelection = gEeprom.TAIL_TONE_ELIMINATION;
break;
case MENU_RP_STE:
@@ -1009,11 +1035,11 @@ void MENU_ShowCurrentSetting(void)
gSubMenuSelection = gEeprom.MIC_SENSITIVITY;
break;
#ifdef ENABLE_AUDIO_BAR
case MENU_MIC_BAR:
gSubMenuSelection = gSetting_mic_bar;
break;
#endif
#ifdef ENABLE_AUDIO_BAR
case MENU_MIC_BAR:
gSubMenuSelection = gSetting_mic_bar;
break;
#endif
case MENU_COMPAND:
gSubMenuSelection = gTxVfo->Compander;
@@ -1089,11 +1115,11 @@ void MENU_ShowCurrentSetting(void)
gSubMenuSelection = gTxVfo->AM_mode;
break;
#ifdef ENABLE_AM_FIX
case MENU_AM_FIX:
gSubMenuSelection = gSetting_AM_fix;
break;
#endif
#ifdef ENABLE_AM_FIX
case MENU_AM_FIX:
gSubMenuSelection = gSetting_AM_fix;
break;
#endif
#ifdef ENABLE_AM_FIX_TEST1
case MENU_AM_FIX_TEST1:
@@ -1153,6 +1179,34 @@ void MENU_ShowCurrentSetting(void)
gSubMenuSelection = gBatteryCalibration[3];
break;
case MENU_BATTYP:
gSubMenuSelection = gEeprom.BATTERY_TYPE;
break;
case MENU_F1SHRT:
case MENU_F1LONG:
case MENU_F2SHRT:
case MENU_F2LONG:
case MENU_MLONG:
{
uint8_t * fun[]= {
&gEeprom.KEY_1_SHORT_PRESS_ACTION,
&gEeprom.KEY_1_LONG_PRESS_ACTION,
&gEeprom.KEY_2_SHORT_PRESS_ACTION,
&gEeprom.KEY_2_LONG_PRESS_ACTION,
&gEeprom.KEY_M_LONG_PRESS_ACTION};
uint8_t id = *fun[GetCurrentMenuId()-MENU_F1SHRT];
for(int i = 0; i < gSubMenu_SIDEFUNCTIONS_size; i++) {
if(gSubMenu_SIDEFUNCTIONS[i].id==id) {
gSubMenuSelection = i;
break;
}
}
break;
}
default:
return;
}
@@ -1170,12 +1224,12 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gMenuCursor == MENU_MEM_NAME && edit_index >= 0)
if (GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0)
{ // currently editing the channel name
if (edit_index < 10)
{
if (Key >= KEY_0 && Key <= KEY_9)
if (Key <= KEY_9)
{
edit[edit_index] = '0' + Key - KEY_0;
@@ -1198,9 +1252,6 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
if (!gIsInSubMenu)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (gInputBoxIndex)
{
case 2:
@@ -1220,7 +1271,7 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gInputBox[0] = gInputBox[1];
gInputBoxIndex = 1;
[[fallthrough]];
case 1:
Value = gInputBox[0];
if (Value > 0 && Value <= gMenuListCount)
@@ -1232,15 +1283,13 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
break;
}
#pragma GCC diagnostic pop
gInputBoxIndex = 0;
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gMenuCursor == MENU_OFFSET)
if (GetCurrentMenuId() == MENU_OFFSET)
{
uint32_t Frequency;
@@ -1255,15 +1304,18 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
NUMBER_Get(gInputBox, &Frequency);
gSubMenuSelection = FREQUENCY_FloorToStep(Frequency + 75, gTxVfo->StepFrequency, 0);
Frequency = StrToUL(INPUTBOX_GetAscii())*100;
gSubMenuSelection = FREQUENCY_RoundToStep(Frequency, gTxVfo->StepFrequency);
gInputBoxIndex = 0;
return;
}
if (gMenuCursor == MENU_MEM_CH || gMenuCursor == MENU_DEL_CH || gMenuCursor == MENU_1_CALL || gMenuCursor == MENU_MEM_NAME)
if (GetCurrentMenuId() == MENU_MEM_CH ||
GetCurrentMenuId() == MENU_DEL_CH ||
GetCurrentMenuId() == MENU_1_CALL ||
GetCurrentMenuId() == MENU_MEM_NAME)
{ // enter 3-digit channel number
if (gInputBoxIndex < 3)
@@ -1279,7 +1331,7 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
Value = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
if (Value <= MR_CHANNEL_LAST)
if (IS_MR_CHANNEL(Value))
{
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
@@ -1292,7 +1344,7 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
return;
}
if (MENU_GetLimits(gMenuCursor, &Min, &Max))
if (MENU_GetLimits(GetCurrentMenuId(), &Min, &Max))
{
gInputBoxIndex = 0;
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
@@ -1337,7 +1389,7 @@ static void MENU_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
{
if (gIsInSubMenu)
{
if (gInputBoxIndex == 0 || gMenuCursor != MENU_OFFSET)
if (gInputBoxIndex == 0 || GetCurrentMenuId() != MENU_OFFSET)
{
gAskForConfirmation = 0;
gIsInSubMenu = false;
@@ -1363,10 +1415,9 @@ static void MENU_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
gRequestDisplayScreen = DISPLAY_MAIN;
if (gEeprom.BACKLIGHT == 0)
if (gEeprom.BACKLIGHT_TIME == 0) // backlight set to always off
{
gBacklightCountdown = 0;
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight OFF
BACKLIGHT_TurnOff(); // turn the backlight OFF
}
}
else
@@ -1394,12 +1445,12 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
if (!gIsInSubMenu)
{
#ifdef ENABLE_VOICE
if (gMenuCursor != MENU_SCR)
if (GetCurrentMenuId() != MENU_SCR)
gAnotherVoiceID = MenuList[gMenuCursor].voice_id;
#endif
#if 1
if (gMenuCursor == MENU_DEL_CH || gMenuCursor == MENU_MEM_NAME)
if (GetCurrentMenuId() == MENU_DEL_CH || GetCurrentMenuId() == MENU_MEM_NAME)
if (!RADIO_CheckValidChannel(gSubMenuSelection, false, 0))
return; // invalid channel
#endif
@@ -1407,7 +1458,7 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
gAskForConfirmation = 0;
gIsInSubMenu = true;
// if (gMenuCursor != MENU_D_LIST)
// if (GetCurrentMenuId() != MENU_D_LIST)
{
gInputBoxIndex = 0;
edit_index = -1;
@@ -1416,7 +1467,7 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
return;
}
if (gMenuCursor == MENU_MEM_NAME)
if (GetCurrentMenuId() == MENU_MEM_NAME)
{
if (edit_index < 0)
{ // enter channel name edit mode
@@ -1463,10 +1514,10 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
if (gIsInSubMenu)
{
if (gMenuCursor == MENU_RESET ||
gMenuCursor == MENU_MEM_CH ||
gMenuCursor == MENU_DEL_CH ||
gMenuCursor == MENU_MEM_NAME)
if (GetCurrentMenuId() == MENU_RESET ||
GetCurrentMenuId() == MENU_MEM_CH ||
GetCurrentMenuId() == MENU_DEL_CH ||
GetCurrentMenuId() == MENU_MEM_NAME)
{
switch (gAskForConfirmation)
{
@@ -1479,7 +1530,7 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
UI_DisplayMenu();
if (gMenuCursor == MENU_RESET)
if (GetCurrentMenuId() == MENU_RESET)
{
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_CONFIRM);
@@ -1514,7 +1565,7 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
}
#ifdef ENABLE_VOICE
if (gMenuCursor == MENU_SCR)
if (GetCurrentMenuId() == MENU_SCR)
gAnotherVoiceID = (gSubMenuSelection == 0) ? VOICE_ID_SCRAMBLER_OFF : VOICE_ID_SCRAMBLER_ON;
else
gAnotherVoiceID = VOICE_ID_CONFIRM;
@@ -1530,7 +1581,7 @@ static void MENU_Key_STAR(const bool bKeyPressed, const bool bKeyHeld)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gMenuCursor == MENU_MEM_NAME && edit_index >= 0)
if (GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0)
{ // currently editing the channel name
if (edit_index < 10)
@@ -1552,12 +1603,12 @@ static void MENU_Key_STAR(const bool bKeyPressed, const bool bKeyHeld)
RADIO_SelectVfos();
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gRxVfo->AM_mode == 0)
if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gRxVfo->AM_mode == 0)
#else
if (gRxVfo->AM_mode == 0)
#endif
{
if (gMenuCursor == MENU_R_CTCS || gMenuCursor == MENU_R_DCS)
if (GetCurrentMenuId() == MENU_R_CTCS || GetCurrentMenuId() == MENU_R_DCS)
{ // scan CTCSS or DCS to find the tone/code of the incoming signal
if (gCssScanMode == CSS_SCAN_MODE_OFF)
@@ -1592,7 +1643,7 @@ 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)
if (GetCurrentMenuId() == MENU_MEM_NAME && gIsInSubMenu && edit_index >= 0)
{ // change the character
if (bKeyPressed && edit_index < 10 && Direction != 0)
{
@@ -1644,16 +1695,15 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
gRequestDisplayScreen = DISPLAY_MENU;
if (gMenuCursor != MENU_ABR && gEeprom.BACKLIGHT == 0)
if (GetCurrentMenuId() != MENU_ABR && gEeprom.BACKLIGHT_TIME == 0) // backlight always off and not in the backlight menu
{
gBacklightCountdown = 0;
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight OFF
BACKLIGHT_TurnOff();
}
return;
}
if (gMenuCursor == MENU_OFFSET)
if (GetCurrentMenuId() == MENU_OFFSET)
{
int32_t Offset = (Direction * gTxVfo->StepFrequency) + gSubMenuSelection;
if (Offset < 99999990)
@@ -1664,17 +1714,14 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
else
Offset = 0;
gSubMenuSelection = FREQUENCY_FloorToStep(Offset, gTxVfo->StepFrequency, 0);
gSubMenuSelection = FREQUENCY_RoundToStep(Offset, gTxVfo->StepFrequency);
gRequestDisplayScreen = DISPLAY_MENU;
return;
}
VFO = 0;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (gMenuCursor)
switch (GetCurrentMenuId())
{
case MENU_DEL_CH:
case MENU_1_CALL:
@@ -1684,6 +1731,7 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
case MENU_SLIST2:
VFO = 1;
[[fallthrough]];
case MENU_SLIST1:
bCheckScanList = true;
break;
@@ -1694,8 +1742,6 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
return;
}
#pragma GCC diagnostic pop
Channel = RADIO_FindNextChannel(gSubMenuSelection + Direction, Direction, bCheckScanList, VFO);
if (Channel != 0xFF)
gSubMenuSelection = Channel;
@@ -1735,7 +1781,7 @@ void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
MENU_Key_STAR(bKeyPressed, bKeyHeld);
break;
case KEY_F:
if (gMenuCursor == MENU_MEM_NAME && edit_index >= 0)
if (GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0)
{ // currently editing the channel name
if (!bKeyHeld && bKeyPressed)
{
@@ -1767,11 +1813,11 @@ void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
if (gScreenToDisplay == DISPLAY_MENU)
{
if (gMenuCursor == MENU_VOL ||
if (GetCurrentMenuId() == MENU_VOL ||
#ifdef ENABLE_F_CAL_MENU
gMenuCursor == MENU_F_CALI ||
GetCurrentMenuId() == MENU_F_CALI ||
#endif
gMenuCursor == MENU_BATCAL)
GetCurrentMenuId() == MENU_BATCAL)
{
gMenuCountdown = menu_timeout_long_500ms;
}

View File

@@ -23,7 +23,7 @@
void writeXtalFreqCal(const int32_t value, const bool update_eeprom);
#endif
int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax);
int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax);
void MENU_AcceptSetting(void);
void MENU_SelectNextCode(void);
void MENU_ShowCurrentSetting(void);

View File

@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include "app/app.h"
#include "app/dtmf.h"
#include "app/generic.h"
#include "app/scanner.h"
@@ -42,7 +43,21 @@ uint8_t gScanProgressIndicator;
uint8_t gScanHitCount;
bool gScanUseCssResult;
int8_t gScanStateDir;
bool bScanKeepFrequency;
bool gScanKeepResult;
typedef enum {
SCAN_NEXT_CHAN_SCANLIST1 = 0,
SCAN_NEXT_CHAN_SCANLIST2,
SCAN_NEXT_CHAN_DUAL_WATCH,
SCAN_NEXT_CHAN_MR,
SCAN_NEXT_NUM
} scan_next_chan_t;
scan_next_chan_t currentScanList;
uint32_t initialFrqOrChan;
uint8_t initialCROSS_BAND_RX_TX;
uint32_t lastFoundFrqOrChan;
static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
@@ -69,7 +84,7 @@ static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gInputBoxIndex = 0;
Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
if (Channel <= MR_CHANNEL_LAST)
if (IS_MR_CHANNEL(Channel))
{
#ifdef ENABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
@@ -164,38 +179,23 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
case 0:
if (!gScanSingleFrequency)
{
int16_t Delta625;
uint32_t Freq250 = FREQUENCY_FloorToStep(gScanFrequency, 250, 0);
uint32_t Freq625 = FREQUENCY_FloorToStep(gScanFrequency, 625, 0);
int16_t Delta250 = (int16_t)gScanFrequency - (int16_t)Freq250;
uint32_t freq250 = FREQUENCY_RoundToStep(gScanFrequency, 250);
uint32_t freq625 = FREQUENCY_RoundToStep(gScanFrequency, 625);
if (125 < Delta250)
{
Delta250 = 250 - Delta250;
Freq250 += 250;
}
uint32_t diff250 = gScanFrequency > freq250 ? gScanFrequency - freq250 : freq250 - gScanFrequency;
uint32_t diff625 = gScanFrequency > freq625 ? gScanFrequency - freq625 : freq625 - gScanFrequency;
Delta625 = (int16_t)gScanFrequency - (int16_t)Freq625;
if (312 < Delta625)
{
Delta625 = 625 - Delta625;
Freq625 += 625;
}
if (Delta625 < Delta250)
{
if(diff250 > diff625) {
gStepSetting = STEP_6_25kHz;
gScanFrequency = Freq625;
gScanFrequency = freq625;
}
else
{
else {
gStepSetting = STEP_2_5kHz;
gScanFrequency = Freq250;
gScanFrequency = freq250;
}
}
if (gTxVfo->CHANNEL_SAVE <= MR_CHANNEL_LAST)
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gScannerEditState = 1;
gScanChannel = gTxVfo->CHANNEL_SAVE;
@@ -249,7 +249,7 @@ static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
gTxVfo->freq_config_TX.Code = gScanCssResultCode;
}
if (gTxVfo->CHANNEL_SAVE <= MR_CHANNEL_LAST)
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
Channel = gScanChannel;
gEeprom.MrChannel[gEeprom.TX_VFO] = Channel;
@@ -362,10 +362,10 @@ void SCANNER_Start(void)
RADIO_SelectVfos();
#ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + BAND6_400MHz;
#endif
#ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + BAND6_400MHz;
#endif
BackupStep = gRxVfo->STEP_SETTING;
BackupFrequency = gRxVfo->StepFrequency;
@@ -377,9 +377,9 @@ void SCANNER_Start(void)
RADIO_SetupRegisters(true);
#ifdef ENABLE_NOAA
gIsNoaaMode = false;
#endif
#ifdef ENABLE_NOAA
gIsNoaaMode = false;
#endif
if (gScanSingleFrequency)
{
@@ -414,49 +414,246 @@ void SCANNER_Start(void)
g_CDCSS_Lost = false;
gCDCSSCodeType = 0;
g_CTCSS_Lost = false;
#ifdef ENABLE_VOX
g_VOX_Lost = false;
#endif
#ifdef ENABLE_VOX
g_VOX_Lost = false;
#endif
g_SquelchLost = false;
gScannerEditState = 0;
gScanProgressIndicator = 0;
}
void SCANNER_Found()
{
switch (gEeprom.SCAN_RESUME_MODE)
{
case SCAN_RESUME_TO:
if (!gScanPauseMode)
{
gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms;
gScheduleScanListen = false;
gScanPauseMode = true;
}
break;
case SCAN_RESUME_CO:
case SCAN_RESUME_SE:
gScanPauseDelayIn_10ms = 0;
gScheduleScanListen = false;
break;
}
if (IS_MR_CHANNEL(gRxVfo->CHANNEL_SAVE)) { //memory scan
lastFoundFrqOrChan = gRxVfo->CHANNEL_SAVE;
}
else { // frequency scan
lastFoundFrqOrChan = gRxVfo->freq_config_RX.Frequency;
}
gScanKeepResult = true;
}
void SCANNER_Stop(void)
{
const uint8_t Previous = gRestoreMrChannel;
if(initialCROSS_BAND_RX_TX != CROSS_BAND_OFF) {
gEeprom.CROSS_BAND_RX_TX = initialCROSS_BAND_RX_TX;
initialCROSS_BAND_RX_TX = CROSS_BAND_OFF;
}
gScanStateDir = SCAN_OFF;
if (!bScanKeepFrequency)
{
if (gNextMrChannel <= MR_CHANNEL_LAST)
{
gEeprom.MrChannel[gEeprom.RX_VFO] = gRestoreMrChannel;
gEeprom.ScreenChannel[gEeprom.RX_VFO] = Previous;
const uint32_t chFr = gScanKeepResult ? lastFoundFrqOrChan : initialFrqOrChan;
const bool channelChanged = chFr != initialFrqOrChan;
if (IS_MR_CHANNEL(gNextMrChannel)) {
gEeprom.MrChannel[gEeprom.RX_VFO] = chFr;
gEeprom.ScreenChannel[gEeprom.RX_VFO] = chFr;
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
if(channelChanged) {
SETTINGS_SaveVfoIndices();
gUpdateStatus = true;
}
else
{
gRxVfo->freq_config_RX.Frequency = gRestoreFrequency;
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
}
RADIO_SetupRegisters(true);
gUpdateDisplay = true;
return;
}
if (gRxVfo->CHANNEL_SAVE > MR_CHANNEL_LAST)
{
else {
gRxVfo->freq_config_RX.Frequency = chFr;
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_VFO, gRxVfo, 1);
return;
if(channelChanged) {
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_VFO, gRxVfo, 1);
}
}
SETTINGS_SaveVfoIndices();
gUpdateStatus = true;
RADIO_SetupRegisters(true);
gUpdateDisplay = true;
}
static void NextFreqChannel(void)
{
gRxVfo->freq_config_RX.Frequency = APP_SetFrequencyByStep(gRxVfo, gScanStateDir);
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
RADIO_SetupRegisters(true);
#ifdef ENABLE_FASTER_CHANNEL_SCAN
gScanPauseDelayIn_10ms = 9; // 90ms
#else
gScanPauseDelayIn_10ms = scan_pause_delay_in_6_10ms;
#endif
gUpdateDisplay = true;
}
static void NextMemChannel(void)
{
static unsigned int prev_mr_chan = 0;
const bool enabled = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCAN_LIST_ENABLED[gEeprom.SCAN_LIST_DEFAULT] : true;
const int chan1 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH1[gEeprom.SCAN_LIST_DEFAULT] : -1;
const int chan2 = (gEeprom.SCAN_LIST_DEFAULT < 2) ? gEeprom.SCANLIST_PRIORITY_CH2[gEeprom.SCAN_LIST_DEFAULT] : -1;
const unsigned int prev_chan = gNextMrChannel;
unsigned int chan = 0;
if (enabled)
{
switch (currentScanList)
{
case SCAN_NEXT_CHAN_SCANLIST1:
prev_mr_chan = gNextMrChannel;
if (chan1 >= 0)
{
if (RADIO_CheckValidChannel(chan1, false, 0))
{
currentScanList = SCAN_NEXT_CHAN_SCANLIST1;
gNextMrChannel = chan1;
break;
}
}
[[fallthrough]];
case SCAN_NEXT_CHAN_SCANLIST2:
if (chan2 >= 0)
{
if (RADIO_CheckValidChannel(chan2, false, 0))
{
currentScanList = SCAN_NEXT_CHAN_SCANLIST2;
gNextMrChannel = chan2;
break;
}
}
[[fallthrough]];
// this bit doesn't yet work if the other VFO is a frequency
case SCAN_NEXT_CHAN_DUAL_WATCH:
// dual watch is enabled - include the other VFO in the scan
// if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
// {
// chan = (gEeprom.RX_VFO + 1) & 1u;
// chan = gEeprom.ScreenChannel[chan];
// if (IS_MR_CHANNEL(chan))
// {
// currentScanList = SCAN_NEXT_CHAN_DUAL_WATCH;
// gNextMrChannel = chan;
// break;
// }
// }
default:
case SCAN_NEXT_CHAN_MR:
currentScanList = SCAN_NEXT_CHAN_MR;
gNextMrChannel = prev_mr_chan;
chan = 0xff;
break;
}
}
if (!enabled || chan == 0xff)
{
chan = RADIO_FindNextChannel(gNextMrChannel + gScanStateDir, gScanStateDir, (gEeprom.SCAN_LIST_DEFAULT < 2) ? true : false, gEeprom.SCAN_LIST_DEFAULT);
if (chan == 0xFF)
{ // no valid channel found
chan = MR_CHANNEL_FIRST;
}
gNextMrChannel = chan;
}
if (gNextMrChannel != prev_chan)
{
gEeprom.MrChannel[ gEeprom.RX_VFO] = gNextMrChannel;
gEeprom.ScreenChannel[gEeprom.RX_VFO] = gNextMrChannel;
RADIO_ConfigureChannel(gEeprom.RX_VFO, VFO_CONFIGURE_RELOAD);
RADIO_SetupRegisters(true);
gUpdateDisplay = true;
}
#ifdef ENABLE_FASTER_CHANNEL_SCAN
gScanPauseDelayIn_10ms = 9; // 90ms .. <= ~60ms it misses signals (squelch response and/or PLL lock time) ?
#else
gScanPauseDelayIn_10ms = scan_pause_delay_in_3_10ms;
#endif
if (enabled)
if (++currentScanList >= SCAN_NEXT_NUM)
currentScanList = SCAN_NEXT_CHAN_SCANLIST1; // back round we go
}
void SCANNER_ScanChannels(const bool storeBackupSettings, const int8_t scan_direction)
{
if (storeBackupSettings) {
initialCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gScanKeepResult = false;
}
RADIO_SelectVfos();
gNextMrChannel = gRxVfo->CHANNEL_SAVE;
currentScanList = SCAN_NEXT_CHAN_SCANLIST1;
gScanStateDir = scan_direction;
if (IS_MR_CHANNEL(gNextMrChannel))
{ // channel mode
if (storeBackupSettings) {
initialFrqOrChan = gRxVfo->CHANNEL_SAVE;
lastFoundFrqOrChan = initialFrqOrChan;
}
NextMemChannel();
}
else
{ // frequency mode
if (storeBackupSettings) {
initialFrqOrChan = gRxVfo->freq_config_RX.Frequency;
lastFoundFrqOrChan = initialFrqOrChan;
}
NextFreqChannel();
}
gScanPauseDelayIn_10ms = scan_pause_delay_in_2_10ms;
gScheduleScanListen = false;
gRxReceptionMode = RX_MODE_NONE;
gScanPauseMode = false;
}
void SCANNER_ContinueScanning()
{
if (IS_FREQ_CHANNEL(gNextMrChannel))
{
if (gCurrentFunction == FUNCTION_INCOMING)
APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE, true);
else
NextFreqChannel(); // switch to next frequency
}
else
{
if (gCurrentCodeType == CODE_TYPE_OFF && gCurrentFunction == FUNCTION_INCOMING)
APP_StartListening(gMonitor ? FUNCTION_MONITOR : FUNCTION_RECEIVE, true);
else
NextMemChannel(); // switch to next channel
}
gScanPauseMode = false;
gRxReceptionMode = RX_MODE_NONE;
gScheduleScanListen = false;
}

View File

@@ -52,12 +52,18 @@ extern volatile uint16_t gScanPauseDelayIn_10ms;
extern uint8_t gScanProgressIndicator;
extern uint8_t gScanHitCount;
extern bool gScanUseCssResult;
// scan direction, if not equal SCAN_OFF indicates
// that we are in a process of scanning channels/frequencies
extern int8_t gScanStateDir;
extern bool bScanKeepFrequency;
extern bool gScanKeepResult;
void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
void SCANNER_Start(void);
void SCANNER_Found();
void SCANNER_Stop(void);
void SCANNER_ScanChannels(const bool storeBackupSettings, const int8_t scan_direction);
void SCANNER_ContinueScanning();
#endif

View File

@@ -14,7 +14,9 @@
* limitations under the License.
*/
#include "../app/spectrum.h"
#include "app/spectrum.h"
#include "driver/backlight.h"
#include "audio.h"
struct FrequencyBandInfo {
uint32_t lower;
@@ -22,19 +24,8 @@ struct FrequencyBandInfo {
uint32_t middle;
};
const struct FrequencyBandInfo FrequencyBandTable[7] = {
[BAND1_50MHz ] = {.lower = 1600000, .middle = 6500000, .upper = 7600000},
[BAND2_108MHz] = {.lower = 10800000, .middle = 12200000, .upper = 13599990},
[BAND3_136MHz] = {.lower = 13600000, .middle = 15000000, .upper = 17399990},
[BAND4_174MHz] = {.lower = 17400000, .middle = 26000000, .upper = 34999990},
[BAND5_350MHz] = {.lower = 35000000, .middle = 37000000, .upper = 39999990},
[BAND6_400MHz] = {.lower = 40000000, .middle = 43500000, .upper = 46999990},
[BAND7_470MHz] = {.lower = 47000000, .middle = 55000000, .upper = 130000000},
};
#define F_MIN FrequencyBandTable[0].lower
#define F_MAX FrequencyBandTable[ARRAY_SIZE(FrequencyBandTable) - 1].upper
#define F_MIN frequencyBandTable[0].lower
#define F_MAX frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper
const uint16_t RSSI_MAX_VALUE = 65535;
@@ -76,22 +67,22 @@ SpectrumSettings settings = {stepsCount: STEPS_64,
uint32_t fMeasure = 0;
uint32_t currentFreq, tempFreq;
uint16_t rssiHistory[128] = {};
uint16_t rssiHistory[128];
uint8_t freqInputIndex = 0;
uint8_t freqInputDotIndex = 0;
KEY_Code_t freqInputArr[10];
char freqInputString[11] = "----------\0"; // XXXX.XXXXX\0
char freqInputString[11];
uint8_t menuState = 0;
uint16_t listenT = 0;
RegisterSpec registerSpecs[] = {
{},
{"LNAs", 0x13, 8, 0b11, 1},
{"LNA", 0x13, 5, 0b111, 1},
{"PGA", 0x13, 0, 0b111, 1},
{"IF", 0x3D, 0, 0xFFFF, 0x2aaa},
{"LNAs", BK4819_REG_13, 8, 0b11, 1},
{"LNA", BK4819_REG_13, 5, 0b111, 1},
{"PGA", BK4819_REG_13, 0, 0b111, 1},
{"IF", BK4819_REG_3D, 0, 0xFFFF, 0x2aaa},
// {"MIX", 0x13, 3, 0b11, 1}, // TODO: hidden
};
@@ -215,23 +206,23 @@ static void ToggleAFBit(bool on) {
}
static void BackupRegisters() {
R30 = BK4819_ReadRegister(0x30);
R37 = BK4819_ReadRegister(0x37);
R3D = BK4819_ReadRegister(0x3D);
R43 = BK4819_ReadRegister(0x43);
R47 = BK4819_ReadRegister(0x47);
R48 = BK4819_ReadRegister(0x48);
R7E = BK4819_ReadRegister(0x7E);
R30 = BK4819_ReadRegister(BK4819_REG_30);
R37 = BK4819_ReadRegister(BK4819_REG_37);
R3D = BK4819_ReadRegister(BK4819_REG_3D);
R43 = BK4819_ReadRegister(BK4819_REG_43);
R47 = BK4819_ReadRegister(BK4819_REG_47);
R48 = BK4819_ReadRegister(BK4819_REG_48);
R7E = BK4819_ReadRegister(BK4819_REG_7E);
}
static void RestoreRegisters() {
BK4819_WriteRegister(0x30, R30);
BK4819_WriteRegister(0x37, R37);
BK4819_WriteRegister(0x3D, R3D);
BK4819_WriteRegister(0x43, R43);
BK4819_WriteRegister(0x47, R47);
BK4819_WriteRegister(0x48, R48);
BK4819_WriteRegister(0x7E, R7E);
BK4819_WriteRegister(BK4819_REG_30, R30);
BK4819_WriteRegister(BK4819_REG_37, R37);
BK4819_WriteRegister(BK4819_REG_3D, R3D);
BK4819_WriteRegister(BK4819_REG_43, R43);
BK4819_WriteRegister(BK4819_REG_47, R47);
BK4819_WriteRegister(BK4819_REG_48, R48);
BK4819_WriteRegister(BK4819_REG_7E, R7E);
}
static void SetModulation(ModulationType type) {
@@ -240,9 +231,9 @@ static void SetModulation(ModulationType type) {
reg &= ~(0b111 << 8);
BK4819_WriteRegister(BK4819_REG_47, reg | (modTypeReg47Values[type] << 8));
if (type == MOD_USB) {
BK4819_WriteRegister(0x3D, 0b0010101101000101);
BK4819_WriteRegister(BK4819_REG_3D, 0b0010101101000101);
BK4819_WriteRegister(BK4819_REG_37, 0x160F);
BK4819_WriteRegister(0x48, 0b0000001110101000);
BK4819_WriteRegister(BK4819_REG_48, 0b0000001110101000);
}
}
@@ -314,16 +305,16 @@ static void ToggleAudio(bool on) {
}
audioState = on;
if (on) {
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
} else {
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
}
}
static void ToggleRX(bool on) {
isListening = on;
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, on);
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, on);
ToggleAudio(on);
ToggleAFDAC(on);
@@ -504,9 +495,9 @@ static void ToggleListeningBW() {
static void ToggleBacklight() {
settings.backlightState = !settings.backlightState;
if (settings.backlightState) {
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
BACKLIGHT_TurnOn();
} else {
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
BACKLIGHT_TurnOff();
}
}
@@ -638,19 +629,12 @@ static void DrawStatus() {
gBatteryVoltages[3]) /
4;
if (gBatteryCalibration[5] < Voltage) {
v = 5;
} else if (gBatteryCalibration[4] < Voltage) {
v = 5;
} else if (gBatteryCalibration[3] < Voltage) {
v = 4;
} else if (gBatteryCalibration[2] < Voltage) {
v = 3;
} else if (gBatteryCalibration[1] < Voltage) {
v = 2;
} else if (gBatteryCalibration[0] < Voltage) {
v = 1;
for(uint8_t i = 5; i > 0; i--) {
if(Voltage > gBatteryCalibration[i - 1]) {
v = i;
break;
}
}
gStatusLine[127] = 0b01111110;
for (int i = 126; i >= 116; i--) {
@@ -686,7 +670,7 @@ static void DrawNums() {
}
if (IsCenterMode()) {
sprintf(String, "%u.%05u \xB1%u.%02uk", currentFreq / 100000,
sprintf(String, "%u.%05u \x7F%u.%02uk", currentFreq / 100000,
currentFreq % 100000, settings.frequencyChangeStep / 100,
settings.frequencyChangeStep % 100);
GUI_DisplaySmallest(String, 36, 49, false, true);
@@ -694,7 +678,7 @@ static void DrawNums() {
sprintf(String, "%u.%05u", GetFStart() / 100000, GetFStart() % 100000);
GUI_DisplaySmallest(String, 0, 49, false, true);
sprintf(String, "\xB1%u.%02uk", settings.frequencyChangeStep / 100,
sprintf(String, "\x7F%u.%02uk", settings.frequencyChangeStep / 100,
settings.frequencyChangeStep % 100);
GUI_DisplaySmallest(String, 48, 49, false, true);
@@ -905,8 +889,8 @@ void OnKeyDownStill(KEY_Code_t key) {
break;
case KEY_PTT:
// TODO: start transmit
/* BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, false);
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, true); */
/* BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true); */
break;
case KEY_MENU:
if (menuState == ARRAY_SIZE(registerSpecs) - 1) {

View File

@@ -27,6 +27,7 @@
#include "bsp/dp32g030/dma.h"
#include "bsp/dp32g030/gpio.h"
#include "driver/aes.h"
#include "driver/backlight.h"
#include "driver/bk4819.h"
#include "driver/crc.h"
#include "driver/eeprom.h"
@@ -238,7 +239,7 @@ static void CMD_0514(const uint8_t *pBuffer)
gSerialConfigCountDown_500ms = 12; // 6 sec
// turn the LCD backlight off
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
BACKLIGHT_TurnOff();
SendVersion();
}
@@ -413,7 +414,7 @@ static void CMD_052F(const uint8_t *pBuffer)
Timestamp = pCmd->Timestamp;
// turn the LCD backlight off
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
BACKLIGHT_TurnOff();
SendVersion();
}

24
audio.c
View File

@@ -97,7 +97,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
ToneConfig = BK4819_ReadRegister(BK4819_REG_71);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode)
BK4819_RX_TurnOn();
@@ -138,13 +138,10 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
SYSTEM_DelayMs(2);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
SYSTEM_DelayMs(60);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (Beep)
{
case BEEP_880HZ_60MS_TRIPLE_BEEP:
@@ -152,14 +149,14 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
SYSTEM_DelayMs(60);
BK4819_EnterTxMute();
SYSTEM_DelayMs(20);
[[fallthrough]];
case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL:
case BEEP_500HZ_60MS_DOUBLE_BEEP:
BK4819_ExitTxMute();
SYSTEM_DelayMs(60);
BK4819_EnterTxMute();
SYSTEM_DelayMs(20);
[[fallthrough]];
case BEEP_1KHZ_60MS_OPTIONAL:
BK4819_ExitTxMute();
Duration = 60;
@@ -184,13 +181,11 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
break;
}
#pragma GCC diagnostic pop
SYSTEM_DelayMs(Duration);
BK4819_EnterTxMute();
SYSTEM_DelayMs(20);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
@@ -202,7 +197,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
BK4819_WriteRegister(BK4819_REG_71, ToneConfig);
if (gEnableSpeaker)
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
@@ -275,7 +270,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
BK1080_Mute(true);
#endif
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
#ifdef ENABLE_VOX
gVoxResumeCountdown = 2000;
@@ -302,7 +297,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
#endif
if (!gEnableSpeaker)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
@@ -443,7 +438,7 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
#endif
if (!gEnableSpeaker)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
@@ -454,3 +449,4 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
}
#endif

11
audio.h
View File

@@ -20,6 +20,9 @@
#include <stdbool.h>
#include <stdint.h>
#include "bsp/dp32g030/gpio.h"
#include "driver/gpio.h"
enum BEEP_Type_t
{
BEEP_NONE = 0,
@@ -130,6 +133,14 @@ enum VOICE_ID_t
typedef enum VOICE_ID_t VOICE_ID_t;
static inline void AUDIO_AudioPathOn(void) {
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
}
static inline void AUDIO_AudioPathOff(void) {
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
}
#ifdef ENABLE_VOICE
extern VOICE_ID_t gVoiceID[8];
extern uint8_t gVoiceReadIndex;

View File

@@ -197,26 +197,27 @@ const uint8_t BITMAP_F_Key[6] =
};
#endif
const uint8_t BITMAP_TDR1[12] =
{ // "DW"
0b00000000,
const uint8_t BITMAP_TDR1[15] =
{ // "DWR"
0b01111111,
0b01000001,
0b01000001,
0b01000001,
0b00111110,
0b00000000,
0b01111111,
0b00100000,
0b00011000,
0b00100000,
0b01111111
0b01111111,
0b00000000,
0b01111111,
0b00011001,
0b00101001,
0b01000110
};
const uint8_t BITMAP_TDR2[12] =
const uint8_t BITMAP_TDR2[9] =
{ // "><" .. DW on hold
0b00000000,
0b00000000,
0b00100010,
0b00110110,
0b00011100,
@@ -226,7 +227,6 @@ const uint8_t BITMAP_TDR2[12] =
0b00011100,
0b00110110,
0b00100010,
0b00000000
};
#ifdef ENABLE_VOICE
@@ -244,27 +244,8 @@ const uint8_t BITMAP_TDR2[12] =
};
#endif
#ifdef ENABLE_FMRADIO
const uint8_t BITMAP_FM[12] =
{ // "FM"
0b00000000,
0b01111111,
0b00001001,
0b00001001,
0b00001001,
0b00000001,
0b00000000,
0b01111111,
0b00000010,
0b00001100,
0b00000010,
0b01111111
};
#endif
#ifdef ENABLE_NOAA
const uint8_t BITMAP_NOAA[12] =
const uint8_t BITMAP_NOAA[11] =
{ // "NS"
0b00000000,
0b01111111,
@@ -272,12 +253,10 @@ const uint8_t BITMAP_TDR2[12] =
0b00001000,
0b00010000,
0b01111111,
0b00000000,
0b01000110,
0b01001001,
0b01001001,
0b01001001,
0b00110001
};
#endif
@@ -291,48 +270,6 @@ const uint8_t BITMAP_Antenna[5] =
0b00000011
};
const uint8_t BITMAP_AntennaLevel1[3] =
{
0b01100000,
0b01100000,
0b00000000
};
const uint8_t BITMAP_AntennaLevel2[3] =
{
0b01110000,
0b01110000,
0b00000000
};
const uint8_t BITMAP_AntennaLevel3[3] =
{
0b01111000,
0b01111000,
0b00000000
};
const uint8_t BITMAP_AntennaLevel4[3] =
{
0b01111100,
0b01111100,
0b00000000
};
const uint8_t BITMAP_AntennaLevel5[3] =
{
0b01111110,
0b01111110,
0b00000000
};
const uint8_t BITMAP_AntennaLevel6[3] =
{
0b01111111,
0b01111111,
0b00000000
};
const uint8_t BITMAP_MARKER[8] =
{
0b11111111,

View File

@@ -25,34 +25,20 @@ extern const uint8_t BITMAP_F_Key[6];
extern const uint8_t BITMAP_VOX[18];
#endif
#if 0
extern const uint8_t BITMAP_WX[12];
#else
extern const uint8_t BITMAP_XB[12];
#endif
extern const uint8_t BITMAP_XB[12];
extern const uint8_t BITMAP_TDR1[12];
extern const uint8_t BITMAP_TDR2[12];
extern const uint8_t BITMAP_TDR1[15];
extern const uint8_t BITMAP_TDR2[9];
#ifdef ENABLE_VOICE
extern const uint8_t BITMAP_VoicePrompt[9];
#endif
#ifdef ENABLE_FMRADIO
extern const uint8_t BITMAP_FM[12];
#endif
#ifdef ENABLE_NOAA
extern const uint8_t BITMAP_NOAA[12];
extern const uint8_t BITMAP_NOAA[11];
#endif
extern const uint8_t BITMAP_Antenna[5];
extern const uint8_t BITMAP_AntennaLevel1[3];
extern const uint8_t BITMAP_AntennaLevel2[3];
extern const uint8_t BITMAP_AntennaLevel3[3];
extern const uint8_t BITMAP_AntennaLevel4[3];
extern const uint8_t BITMAP_AntennaLevel5[3];
extern const uint8_t BITMAP_AntennaLevel6[3];
extern const uint8_t BITMAP_MARKER[8];

37
board.c
View File

@@ -26,7 +26,7 @@
#include "bsp/dp32g030/saradc.h"
#include "bsp/dp32g030/syscon.h"
#include "driver/adc.h"
//#include "driver/backlight.h"
#include "driver/backlight.h"
#ifdef ENABLE_FMRADIO
#include "driver/bk1080.h"
#endif
@@ -94,8 +94,6 @@ void BOARD_GPIO_Init(void)
| GPIO_DIR_6_MASK // INPUT
);
GPIOB->DIR |= 0
// Back light
| GPIO_DIR_6_BITS_OUTPUT
// ST7565
| GPIO_DIR_9_BITS_OUTPUT
// ST7565 + SWD IO
@@ -183,14 +181,10 @@ void BOARD_PORTCON_Init(void)
// PORT B pin selection
PORTCON_PORTB_SEL0 &= ~(0
// Back light
| PORTCON_PORTB_SEL0_B6_MASK
// SPI0 SSN
| PORTCON_PORTB_SEL0_B7_MASK
);
PORTCON_PORTB_SEL0 |= 0
// Back light
| PORTCON_PORTB_SEL0_B6_BITS_GPIOB6
// SPI0 SSN
| PORTCON_PORTB_SEL0_B7_BITS_SPI0_SSN
;
@@ -508,6 +502,7 @@ void BOARD_Init(void)
{
BOARD_PORTCON_Init();
BOARD_GPIO_Init();
BACKLIGHT_InitHardware();
BOARD_ADC_Init();
ST7565_Init(true);
#ifdef ENABLE_FMRADIO
@@ -540,12 +535,14 @@ void BOARD_EEPROM_Init(void)
// 0E78..0E7F
EEPROM_ReadBuffer(0x0E78, Data, 8);
gEeprom.BACKLIGHT_MAX = (Data[0] & 0xF) <= 10 ? (Data[0] & 0xF) : 10;
gEeprom.BACKLIGHT_MIN = (Data[0] >> 4) < gEeprom.BACKLIGHT_MAX ? (Data[0] >> 4) : 0;
gEeprom.CHANNEL_DISPLAY_MODE = (Data[1] < 4) ? Data[1] : MDF_FREQUENCY; // 4 instead of 3 - extra display mode
gEeprom.CROSS_BAND_RX_TX = (Data[2] < 3) ? Data[2] : CROSS_BAND_OFF;
gEeprom.BATTERY_SAVE = (Data[3] < 5) ? Data[3] : 4;
gEeprom.DUAL_WATCH = (Data[4] < 3) ? Data[4] : DUAL_WATCH_CHAN_A;
gEeprom.BACKLIGHT = (Data[5] < ARRAY_SIZE(gSubMenu_BACKLIGHT)) ? Data[5] : 3;
gEeprom.TAIL_NOTE_ELIMINATION = (Data[6] < 2) ? Data[6] : false;
gEeprom.BACKLIGHT_TIME = (Data[5] < ARRAY_SIZE(gSubMenu_BACKLIGHT)) ? Data[5] : 3;
gEeprom.TAIL_TONE_ELIMINATION = (Data[6] < 2) ? Data[6] : false;
gEeprom.VFO_OPEN = (Data[7] < 2) ? Data[7] : true;
// 0E80..0E87
@@ -590,7 +587,8 @@ void BOARD_EEPROM_Init(void)
// 0E90..0E97
EEPROM_ReadBuffer(0x0E90, Data, 8);
gEeprom.BEEP_CONTROL = (Data[0] < 2) ? Data[0] : true;
gEeprom.BEEP_CONTROL = Data[0] & 1;
gEeprom.KEY_M_LONG_PRESS_ACTION = ((Data[0] >> 1) < ACTION_OPT_LEN) ? (Data[0] >> 1) : ACTION_OPT_NONE;
gEeprom.KEY_1_SHORT_PRESS_ACTION = (Data[1] < ACTION_OPT_LEN) ? Data[1] : ACTION_OPT_MONITOR;
gEeprom.KEY_1_LONG_PRESS_ACTION = (Data[2] < ACTION_OPT_LEN) ? Data[2] : ACTION_OPT_FLASHLIGHT;
gEeprom.KEY_2_SHORT_PRESS_ACTION = (Data[3] < ACTION_OPT_LEN) ? Data[3] : ACTION_OPT_SCAN;
@@ -616,7 +614,8 @@ void BOARD_EEPROM_Init(void)
#endif
gEeprom.ROGER = (Data[1] < 3) ? Data[1] : ROGER_MODE_OFF;
gEeprom.REPEATER_TAIL_TONE_ELIMINATION = (Data[2] < 11) ? Data[2] : 0;
gEeprom.TX_VFO = (Data[3] < 2) ? Data[3] : 0;
gEeprom.TX_VFO = (Data[3] < 2) ? Data[3] : 0;
gEeprom.BATTERY_TYPE = (Data[4] < BATTERY_TYPE_UNKNOWN) ? Data[4] : BATTERY_TYPE_1600_MAH;
// 0ED0..0ED7
EEPROM_ReadBuffer(0x0ED0, Data, 8);
@@ -739,18 +738,18 @@ void BOARD_EEPROM_Init(void)
}
}
void BOARD_EEPROM_LoadMoreSettings(void)
void BOARD_EEPROM_LoadCalibration(void)
{
// uint8_t Mic;
EEPROM_ReadBuffer(0x1EC0, gEEPROM_1EC0_0, 8);
memmove(gEEPROM_1EC0_1, gEEPROM_1EC0_0, 8);
memmove(gEEPROM_1EC0_2, gEEPROM_1EC0_0, 8);
memmove(gEEPROM_1EC0_3, gEEPROM_1EC0_0, 8);
EEPROM_ReadBuffer(0x1EC0, gEEPROM_RSSI_CALIB[3], 8);
memcpy(gEEPROM_RSSI_CALIB[4], gEEPROM_RSSI_CALIB[3], 8);
memcpy(gEEPROM_RSSI_CALIB[5], gEEPROM_RSSI_CALIB[3], 8);
memcpy(gEEPROM_RSSI_CALIB[6], gEEPROM_RSSI_CALIB[3], 8);
// 8 * 16-bit values
EEPROM_ReadBuffer(0x1EC0, gEEPROM_RSSI_CALIB[0], 8);
EEPROM_ReadBuffer(0x1EC8, gEEPROM_RSSI_CALIB[1], 8);
EEPROM_ReadBuffer(0x1EC8, gEEPROM_RSSI_CALIB[0], 8);
memcpy(gEEPROM_RSSI_CALIB[1], gEEPROM_RSSI_CALIB[0], 8);
memcpy(gEEPROM_RSSI_CALIB[2], gEEPROM_RSSI_CALIB[0], 8);
EEPROM_ReadBuffer(0x1F40, gBatteryCalibration, 12);
if (gBatteryCalibration[0] >= 5000)

View File

@@ -27,7 +27,7 @@ void BOARD_ADC_Init(void);
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_EEPROM_LoadCalibration(void);
uint32_t BOARD_fetchChannelFrequency(const int channel);
void BOARD_fetchChannelName(char *s, const int channel);
void BOARD_FactoryReset(bool bIsAll);

146
bsp/dp32g030/pwmplus.h Normal file
View File

@@ -0,0 +1,146 @@
#ifndef HARDWARE_DP32G030_PWMPLUS_H
#define HARDWARE_DP32G030_PWMPLUS_H
#define PWM_PLUS0_BASE_ADDR 0x400B4000U
//---------------
#define PWMPLUS_CFG 0x00U
#define PWMPLUS_CFG_COUNTER_EN_SHIFT 0U
#define PWMPLUS_CFG_COUNTER_EN_WIDTH 1U
#define PWMPLUS_CFG_COUNTER_EN_MASK (((1U << PWMPLUS_CFG_COUNTER_EN_WIDTH) - 1U) << PWMPLUS_CFG_COUNTER_EN_SHIFT)
#define PWMPLUS_CFG_COUNTER_EN_VALUE_ENABLE 1U
#define PWMPLUS_CFG_COUNTER_EN_BITS_ENABLE (PWMPLUS_CFG_COUNTER_EN_VALUE_ENABLE << PWMPLUS_CFG_COUNTER_EN_SHIFT)
#define PWMPLUS_CFG_CNT_TYPE_SHIFT 1U
#define PWMPLUS_CFG_CNT_REP_SHIFT 2U
#define PWMPLUS_CFG_CNT_REP_WIDTH 1U
#define PWMPLUS_CFG_CNT_REP_VALUE_ENABLE 1U
#define PWMPLUS_CFG_CNT_REP_BITS_ENABLE (PWMPLUS_CFG_CNT_REP_VALUE_ENABLE << PWMPLUS_CFG_CNT_REP_SHIFT)
#define PWMPLUS_CFG_OUT_MODE_SHIFT 3U
#define PWMPLUS_CFG_OUT_MODE_VALUE_ENABLE 1U
#define PWMPLUS_CFG_OUT_MODE_BITS_ENABLE (PWMPLUS_CFG_OUT_MODE_VALUE_ENABLE << PWMPLUS_CFG_OUT_MODE_SHIFT)
#define PWMPLUS_CFG_AUTO_RELOAD_SHIFT 8U
//---------------
#define PWMPLUS_GEN 0x04U
#define PWMPLUS_GEN_CH0_OE_SHIFT 24U
#define PWMPLUS_GEN_CH0_OE_WIDTH 1U
#define PWMPLUS_GEN_CH0_OE_VALUE_ENABLE 1U
#define PWMPLUS_GEN_CH0_OE_BITS_ENABLE (PWMPLUS_GEN_CH0_OE_VALUE_ENABLE << PWMPLUS_GEN_CH0_OE_SHIFT)
#define PWMPLUS_GEN_CH0_OUTINV_SHIFT 16U
#define PWMPLUS_GEN_CH0_OUTINV_WIDTH 1U
#define PWMPLUS_GEN_CH0_OUTINV_VALUE_ENABLE 1U
#define PWMPLUS_GEN_CH0_OUTINV_BITS_ENABLE (PWMPLUS_GEN_CH0_OUTINV_VALUE_ENABLE << PWMPLUS_GEN_CH0_OUTINV_SHIFT)
#define PWMPLUS_GEN_CH0_START_SHIFT 8U
#define PWMPLUS_GEN_CH0_START_WIDTH 1U
#define PWMPLUS_GEN_CH0_START_VALUE_ENABLE 1U
#define PWMPLUS_GEN_CH0_START_BITS_ENABLE (PWMPLUS_GEN_CH0_START_VALUE_ENABLE << PWMPLUS_GEN_CH0_START_SHIFT)
#define PWMPLUS_GEN_CH0_IDLE_SHIFT 0U
#define PWMPLUS_GEN_CH0_IDLE_WIDTH 1U
#define PWMPLUS_GEN_CH0_IDLE_VALUE_ENABLE 1U
#define PWMPLUS_GEN_CH0_IDLE_BITS_ENABLE (PWMPLUS_GEN_CH0_IDLE_VALUE_ENABLE << PWMPLUS_GEN_CH0_IDLE_SHIFT)
//---------------
#define PWMPLUS_CLKSRC 0x08U
#define PWMPLUS_BRAKE_CFG 0x0CU
#define PWMPLUS_MASK_LEV 0x10U
#define PWMPLUS_PERIOD 0x1CU
#define PWMPLUS_CH0_COMP 0x20U
#define PWMPLUS_CH1_COMP 0x24U
#define PWMPLUS_CH2_COMP 0x28U
#define PWMPLUS_CH0_DT 0x30U
#define PWMPLUS_CH1_DT 0x34U
#define PWMPLUS_CH2_DT 0x38U
#define PWMPLUS_TRIG_COMP 0x40U
#define PWMPLUS_TRIG_CFG 0x44U
#define PWMPLUS_IE 0x60U
#define PWMPLUS_IF 0x64U
#define PWMPLUS_SWLOAD 0x84U
#define PWMPLUS_MASK_EN 0x88
#define PWMPLUS_CNT_ST 0xE0
#define PWMPLUS_BRAKE_ST 0xE4
#define PWM_PLUS0_CFG_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CFG)
#define PWM_PLUS0_CFG (*(volatile uint32_t *)PWM_PLUS0_CFG_ADDR)
#define PWM_PLUS0_GEN_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_GEN)
#define PWM_PLUS0_GEN (*(volatile uint32_t *)PWM_PLUS0_GEN_ADDR)
#define PWM_PLUS0_CLKSRC_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CLKSRC)
#define PWM_PLUS0_CLKSRC (*(volatile uint32_t *)PWM_PLUS0_CLKSRC_ADDR)
#define PWM_PLUS0_BRAKE_CFG_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_BRAKE_CFG)
#define PWM_PLUS0_BRAKE_CFG (*(volatile uint32_t *)PWM_PLUS0_BRAKE_CFG_ADDR)
#define PWM_PLUS0_MASK_LEV_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_MASK_LEV)
#define PWM_PLUS0_MASK_LEV (*(volatile uint32_t *)PWM_PLUS0_MASK_LEV_ADDR)
#define PWM_PLUS0_PERIOD_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_PERIOD)
#define PWM_PLUS0_PERIOD (*(volatile uint32_t *)PWM_PLUS0_PERIOD_ADDR)
#define PWM_PLUS0_CH0_COMP_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH0_COMP)
#define PWM_PLUS0_CH0_COMP (*(volatile uint32_t *)PWM_PLUS0_CH0_COMP_ADDR)
#define PWM_PLUS0_CH1_COMP_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH1_COMP)
#define PWM_PLUS0_CH1_COMP (*(volatile uint32_t *)PWM_PLUS0_CH1_COMP_ADDR)
#define PWM_PLUS0_CH2_COMP_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH2_COMP)
#define PWM_PLUS0_CH2_COMP (*(volatile uint32_t *)PWM_PLUS0_CH2_COMP_ADDR)
#define PWM_PLUS0_CH0_DT_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH0_DT)
#define PWM_PLUS0_CH0_DT (*(volatile uint32_t *)PWM_PLUS0_CH0_DT_ADDR)
#define PWM_PLUS0_CH1_DT_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH1_DT)
#define PWM_PLUS0_CH1_DT (*(volatile uint32_t *)PWM_PLUS0_CH1_DT_ADDR)
#define PWM_PLUS0_CH2_DT_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CH2_DT)
#define PWM_PLUS0_CH2_DT (*(volatile uint32_t *)PWM_PLUS0_CH2_DT_ADDR)
#define PWM_PLUS0_TRIG_COMP_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_TRIG_COMP)
#define PWM_PLUS0_TRIG_COMP (*(volatile uint32_t *)PWM_PLUS0_TRIG_COMP_ADDR)
#define PWM_PLUS0_TRIG_CFG_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_TRIG_CFG)
#define PWM_PLUS0_TRIG_CFG (*(volatile uint32_t *)PWM_PLUS0_TRIG_CFG_ADDR)
#define PWM_PLUS0_IE_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_IE)
#define PWM_PLUS0_IE (*(volatile uint32_t *)PWM_PLUS0_IE_ADDR)
#define PWM_PLUS0_IF_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_IF)
#define PWM_PLUS0_IF (*(volatile uint32_t *)PWM_PLUS0_IF_ADDR)
#define PWM_PLUS0_SWLOAD_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_SWLOAD)
#define PWM_PLUS0_SWLOAD (*(volatile uint32_t *)PWM_PLUS0_SWLOAD_ADDR)
#define PWM_PLUS0_MASK_EN_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_MASK_EN)
#define PWM_PLUS0_MASK_EN (*(volatile uint32_t *)PWM_PLUS0_MASK_EN_ADDR)
#define PWM_PLUS0_CNT_ST_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_CNT_ST)
#define PWM_PLUS0_CNT_ST (*(volatile uint32_t *)PWM_PLUS0_CNT_ST_ADDR)
#define PWM_PLUS0_BRAKE_ST_ADDR (PWM_PLUS0_BASE_ADDR + PWMPLUS_BRAKE_ST)
#define PWM_PLUS0_BRAKE_ST (*(volatile uint32_t *)PWM_PLUS0_BRAKE_ST_ADDR)
#endif

2
compile-with-docker.sh Normal file → Executable file
View File

@@ -1,3 +1,3 @@
#!/bin/sh
docker build -t uvk5 .
docker run -v $(PWD)/compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make && cp firmware* compiled-firmware/"
docker run -v ${PWD}/compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make && cp firmware* compiled-firmware/"

18
debugging.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef DEBUGGING_H
#define DEBUGGING_H
#include "driver/uart.h"
#include "string.h"
#include "external/printf/printf.h"
static inline void LogUart(char * str)
{
UART_Send(str, strlen(str));
}
#endif

View File

@@ -16,21 +16,54 @@
#include "backlight.h"
#include "bsp/dp32g030/gpio.h"
#include "bsp/dp32g030/pwmplus.h"
#include "bsp/dp32g030/portcon.h"
#include "driver/gpio.h"
#include "settings.h"
// this is decremented once every 500ms
uint16_t gBacklightCountdown = 0;
bool backlightOn;
void BACKLIGHT_InitHardware()
{
// 48MHz / 94 / 1024 ~ 500Hz
const uint32_t PWM_FREQUENCY_HZ = 1000;
PWM_PLUS0_CLKSRC |= ((48000000 / 1024 / PWM_FREQUENCY_HZ) << 16);
PWM_PLUS0_PERIOD = 1023;
PORTCON_PORTB_SEL0 &= ~(0
// Back light
| PORTCON_PORTB_SEL0_B6_MASK
);
PORTCON_PORTB_SEL0 |= 0
// Back light PWM
| PORTCON_PORTB_SEL0_B6_BITS_PWMP0_CH0
;
PWM_PLUS0_GEN =
PWMPLUS_GEN_CH0_OE_BITS_ENABLE |
PWMPLUS_GEN_CH0_OUTINV_BITS_ENABLE |
0;
PWM_PLUS0_CFG =
PWMPLUS_CFG_CNT_REP_BITS_ENABLE |
PWMPLUS_CFG_COUNTER_EN_BITS_ENABLE |
0;
}
void BACKLIGHT_TurnOn(void)
{
if (gEeprom.BACKLIGHT == 0)
if (gEeprom.BACKLIGHT_TIME != 0) {
backlightOn = true;
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MAX);
}
else {
BACKLIGHT_TurnOff();
return;
// turn the backlight ON
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
}
switch (gEeprom.BACKLIGHT)
switch (gEeprom.BACKLIGHT_TIME)
{
default:
case 1: // 5 sec
@@ -58,3 +91,21 @@ void BACKLIGHT_TurnOn(void)
gBacklightCountdown *= 2;
}
void BACKLIGHT_TurnOff()
{
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MIN);
gBacklightCountdown = 0;
backlightOn = false;
}
bool BACKLIGHT_IsOn()
{
return backlightOn;
}
void BACKLIGHT_SetBrightness(uint8_t brigtness)
{
PWM_PLUS0_CH0_COMP = (1 << brigtness) - 1;
//PWM_PLUS0_SWLOAD = 1;
}

View File

@@ -18,10 +18,16 @@
#define DRIVER_BACKLIGHT_H
#include <stdint.h>
#include <stdbool.h>
extern uint16_t gBacklightCountdown;
extern uint8_t gBacklightBrightness;
void BACKLIGHT_TurnOn(void);
void BACKLIGHT_InitHardware();
void BACKLIGHT_TurnOn();
void BACKLIGHT_TurnOff();
bool BACKLIGHT_IsOn();
void BACKLIGHT_SetBrightness(uint8_t brigtness);
#endif

View File

@@ -52,6 +52,7 @@ enum BK4819_REGISTER_t {
BK4819_REG_3A = 0x3AU,
BK4819_REG_3B = 0x3BU,
BK4819_REG_3C = 0x3CU,
BK4819_REG_3D = 0x3DU,
BK4819_REG_3E = 0x3EU,
BK4819_REG_3F = 0x3FU,
BK4819_REG_43 = 0x43U,
@@ -95,13 +96,12 @@ enum BK4819_REGISTER_t {
typedef enum BK4819_REGISTER_t BK4819_REGISTER_t;
enum BK4819_GPIO_PIN_t {
BK4819_GPIO6_PIN2 = 0,
BK4819_GPIO5_PIN1 = 1,
BK4819_GPIO4_PIN32 = 2,
BK4819_GPIO3_PIN31 = 3,
BK4819_GPIO2_PIN30 = 4,
BK4819_GPIO1_PIN29_RED = 5,
BK4819_GPIO0_PIN28_GREEN = 6,
BK4819_GPIO0_PIN28_RX_ENABLE = 0,
BK4819_GPIO1_PIN29_PA_ENABLE = 1,
BK4819_GPIO3_PIN31_UHF_LNA = 3,
BK4819_GPIO4_PIN32_VHF_LNA = 4,
BK4819_GPIO5_PIN1_RED = 5,
BK4819_GPIO6_PIN2_GREEN = 6,
};
typedef enum BK4819_GPIO_PIN_t BK4819_GPIO_PIN_t;

View File

@@ -16,6 +16,7 @@
#include <stdio.h> // NULL
#include "audio.h"
#include "bk4819.h"
#include "bsp/dp32g030/gpio.h"
#include "bsp/dp32g030/portcon.h"
@@ -51,8 +52,8 @@ void BK4819_Init(void)
BK4819_WriteRegister(BK4819_REG_37, 0x1D0F);
BK4819_WriteRegister(BK4819_REG_36, 0x0022);
BK4819_SetAGC(0);
// BK4819_SetAGC(1);
BK4819_DisableAGC();
// BK4819_EnableAGC();
BK4819_WriteRegister(BK4819_REG_19, 0b0001000001000001); // <15> MIC AGC 1 = disable 0 = enable
@@ -232,118 +233,113 @@ void BK4819_WriteU16(uint16_t Data)
}
}
void BK4819_SetAGC(uint8_t Value)
void BK4819_DisableAGC()
{
if (Value == 0)
{
// REG_10
//
// 0x0038 Rx AGC Gain Table[0]. (Index Max->Min is 3,2,1,0,-1)
//
// <15:10> ???
//
// <9:8> LNA Gain Short
// 3 = 0dB <<<
// 2 = -24dB // was -11
// 1 = -30dB // was -16
// 0 = -33dB // was -19
//
// <7:5> LNA Gain
// 7 = 0dB
// 6 = -2dB
// 5 = -4dB
// 4 = -6dB
// 3 = -9dB
// 2 = -14dB <<<
// 1 = -19dB
// 0 = -24dB
//
// <4:3> MIXER Gain
// 3 = 0dB <<<
// 2 = -3dB
// 1 = -6dB
// 0 = -8dB
//
// <2:0> PGA Gain
// 7 = 0dB
// 6 = -3dB <<<
// 5 = -6dB
// 4 = -9dB
// 3 = -15dB
// 2 = -21dB
// 1 = -27dB
// 0 = -33dB
//
BK4819_WriteRegister(BK4819_REG_13, (3u << 8) | (2u << 5) | (3u << 3) | (6u << 0)); // 000000 11 101 11 110
// REG_10
//
// 0x0038 Rx AGC Gain Table[0]. (Index Max->Min is 3,2,1,0,-1)
//
// <15:10> ???
//
// <9:8> LNA Gain Short
// 3 = 0dB <<<
// 2 = -24dB // was -11
// 1 = -30dB // was -16
// 0 = -33dB // was -19
//
// <7:5> LNA Gain
// 7 = 0dB
// 6 = -2dB
// 5 = -4dB
// 4 = -6dB
// 3 = -9dB
// 2 = -14dB <<<
// 1 = -19dB
// 0 = -24dB
//
// <4:3> MIXER Gain
// 3 = 0dB <<<
// 2 = -3dB
// 1 = -6dB
// 0 = -8dB
//
// <2:0> PGA Gain
// 7 = 0dB
// 6 = -3dB <<<
// 5 = -6dB
// 4 = -9dB
// 3 = -15dB
// 2 = -21dB
// 1 = -27dB
// 0 = -33dB
//
BK4819_WriteRegister(BK4819_REG_13, (3u << 8) | (5u << 5) | (3u << 3) | (6u << 0)); // 000000 11 101 11 110
BK4819_WriteRegister(BK4819_REG_12, 0x037B); // 000000 11 011 11 011
BK4819_WriteRegister(BK4819_REG_11, 0x027B); // 000000 10 011 11 011
BK4819_WriteRegister(BK4819_REG_10, 0x007A); // 000000 00 011 11 010
BK4819_WriteRegister(BK4819_REG_14, 0x0019); // 000000 00 000 11 001
BK4819_WriteRegister(BK4819_REG_12, 0x037B); // 000000 11 011 11 011
BK4819_WriteRegister(BK4819_REG_11, 0x027B); // 000000 10 011 11 011
BK4819_WriteRegister(BK4819_REG_10, 0x007A); // 000000 00 011 11 010
BK4819_WriteRegister(BK4819_REG_14, 0x0019); // 000000 00 000 11 001
BK4819_WriteRegister(BK4819_REG_49, 0x2A38);
BK4819_WriteRegister(BK4819_REG_7B, 0x8420);
}
else
if (Value == 1)
{ // what does this do ???
BK4819_WriteRegister(BK4819_REG_49, 0x2A38);
BK4819_WriteRegister(BK4819_REG_7B, 0x8420);
}
unsigned int i;
void BK4819_EnableAGC()
{
// REG_10
//
// 0x0038 Rx AGC Gain Table[0]. (Index Max->Min is 3,2,1,0,-1)
//
// (15:10> ???
//
// <9:8> LNA Gain Short
// 3 = 0dB << original
// 2 = -24dB // was -11
// 1 = -30dB // was -16
// 0 = -33dB // was -19
//
// <7:5> LNA Gain
// 7 = 0dB
// 6 = -2dB
// 5 = -4dB
// 4 = -6dB
// 3 = -9dB
// 2 = -14dB << original
// 1 = -19dB
// 0 = -24dB
//
// <4:3> MIXER Gain
// 3 = 0dB << original
// 2 = -3dB
// 1 = -6dB
// 0 = -8dB
//
// <2:0> PGA Gain
// 7 = 0dB
// 6 = -3dB << original
// 5 = -6dB
// 4 = -9dB
// 3 = -15dB
// 2 = -21dB
// 1 = -27dB
// 0 = -33dB
//
BK4819_WriteRegister(BK4819_REG_13, (3u << 8) | (5u << 5) | (3u << 3) | (6u << 0));
// REG_10
//
// 0x0038 Rx AGC Gain Table[0]. (Index Max->Min is 3,2,1,0,-1)
//
// (15:10> ???
//
// <9:8> LNA Gain Short
// 3 = 0dB << original
// 2 = -24dB // was -11
// 1 = -30dB // was -16
// 0 = -33dB // was -19
//
// <7:5> LNA Gain
// 7 = 0dB
// 6 = -2dB
// 5 = -4dB
// 4 = -6dB
// 3 = -9dB
// 2 = -14dB << original
// 1 = -19dB
// 0 = -24dB
//
// <4:3> MIXER Gain
// 3 = 0dB << original
// 2 = -3dB
// 1 = -6dB
// 0 = -8dB
//
// <2:0> PGA Gain
// 7 = 0dB
// 6 = -3dB << original
// 5 = -6dB
// 4 = -9dB
// 3 = -15dB
// 2 = -21dB
// 1 = -27dB
// 0 = -33dB
//
BK4819_WriteRegister(BK4819_REG_13, (3u << 8) | (2u << 5) | (3u << 3) | (6u << 0));
BK4819_WriteRegister(BK4819_REG_12, 0x037C); // 000000 11 011 11 100
BK4819_WriteRegister(BK4819_REG_11, 0x027B); // 000000 10 011 11 011
BK4819_WriteRegister(BK4819_REG_10, 0x007A); // 000000 00 011 11 010
BK4819_WriteRegister(BK4819_REG_14, 0x0018); // 000000 00 000 11 000
BK4819_WriteRegister(BK4819_REG_12, 0x037C); // 000000 11 011 11 100
BK4819_WriteRegister(BK4819_REG_11, 0x027B); // 000000 10 011 11 011
BK4819_WriteRegister(BK4819_REG_10, 0x007A); // 000000 00 011 11 010
BK4819_WriteRegister(BK4819_REG_14, 0x0018); // 000000 00 000 11 000
BK4819_WriteRegister(BK4819_REG_49, 0x2A38);
BK4819_WriteRegister(BK4819_REG_7B, 0x318C);
BK4819_WriteRegister(BK4819_REG_49, 0x2A38);
BK4819_WriteRegister(BK4819_REG_7B, 0x318C);
BK4819_WriteRegister(BK4819_REG_7C, 0x595E);
BK4819_WriteRegister(BK4819_REG_20, 0x8DEF);
BK4819_WriteRegister(BK4819_REG_7C, 0x595E);
BK4819_WriteRegister(BK4819_REG_20, 0x8DEF);
for (i = 0; i < 8; i++)
// Bug? The bit 0x2000 below overwrites the (i << 13)
BK4819_WriteRegister(BK4819_REG_06, ((i << 13) | 0x2500u) + 0x036u);
for (uint8_t i = 0; i < 8; i++) {
//BK4819_WriteRegister(BK4819_REG_06, ((i << 13) | 0x2500u) + 0x036u);
BK4819_WriteRegister(BK4819_REG_06, (i & 7) << 13 | 0x4A << 7 | 0x36);
}
}
@@ -760,19 +756,13 @@ void BK4819_SetupSquelch(
// 0 ~ 255
//
BK4819_WriteRegister(BK4819_REG_4E, // 01 101 11 1 00000000
#ifndef ENABLE_FASTER_CHANNEL_SCAN
// original (*)
(1u << 14) | // 1 ???
(3u << 11) | // *5 squelch = open delay .. 0 ~ 7
(2u << 9) | // *3 squelch = close delay .. 0 ~ 3
SquelchOpenGlitchThresh); // 0 ~ 255
#else
// faster (but twitchier)
(1u << 14) | // 1 ???
(2u << 11) | // *5 squelch = open delay .. 0 ~ 7
(1u << 9) | // *3 squelch = close delay .. 0 ~ 3
SquelchOpenGlitchThresh); // 0 ~ 255
#endif
(1u << 14) | // 1 ???
(5u << 11) | // *5 squelch = open delay .. 0 ~ 7
(6u << 9) | // *3 squelch = close delay .. 0 ~ 3
SquelchOpenGlitchThresh); // 0 ~ 255
// REG_4F
//
@@ -804,7 +794,8 @@ void BK4819_SetAF(BK4819_AF_Type_t AF)
// AF Output Inverse Mode = Inverse
// Undocumented bits 0x2040
//
BK4819_WriteRegister(BK4819_REG_47, 0x6040 | (AF << 8));
// BK4819_WriteRegister(BK4819_REG_47, 0x6040 | (AF << 8));
BK4819_WriteRegister(BK4819_REG_47, (6u << 12) | (AF << 8) | (1u << 6));
}
void BK4819_RX_TurnOn(void)
@@ -843,20 +834,20 @@ void BK4819_RX_TurnOn(void)
void BK4819_PickRXFilterPathBasedOnFrequency(uint32_t Frequency)
{
if (Frequency < 28000000)
{
BK4819_ToggleGpioOut(BK4819_GPIO2_PIN30, true);
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31, false);
{ // VHF
BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, true);
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, false);
}
else
if (Frequency == 0xFFFFFFFF)
{
BK4819_ToggleGpioOut(BK4819_GPIO2_PIN30, false);
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31, false);
{ // OFF
BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, false);
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, false);
}
else
{
BK4819_ToggleGpioOut(BK4819_GPIO2_PIN30, false);
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31, true);
{ // UHF
BK4819_ToggleGpioOut(BK4819_GPIO4_PIN32_VHF_LNA, false);
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31_UHF_LNA, true);
}
}
@@ -975,14 +966,14 @@ void BK4819_EnableDTMF(void)
// <3:0> 14 Max symbol number for SelCall detection
//
// const uint16_t threshold = 24; // default, but doesn't decode non-QS radios
const uint16_t threshold = 160; // but 128 ~ 247 does
const uint16_t threshold = 130; // but 128 ~ 247 does
BK4819_WriteRegister(BK4819_REG_24, // 1 00011000 1 1 1 1110
(1u << BK4819_REG_24_SHIFT_UNKNOWN_15) |
(threshold << BK4819_REG_24_SHIFT_THRESHOLD) | // 0 ~ 255
(1u << BK4819_REG_24_SHIFT_UNKNOWN_6) |
BK4819_REG_24_ENABLE |
BK4819_REG_24_SELECT_DTMF |
(14u << BK4819_REG_24_SHIFT_MAX_SYMBOLS)); // 0 ~ 15
(15u << BK4819_REG_24_SHIFT_MAX_SYMBOLS)); // 0 ~ 15
}
void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch)
@@ -1010,7 +1001,7 @@ void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay,
if (play_speaker)
{
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
BK4819_SetAF(BK4819_AF_BEEP);
}
else
@@ -1032,7 +1023,7 @@ void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay,
if (play_speaker)
{
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
BK4819_SetAF(BK4819_AF_MUTE);
}
@@ -1198,7 +1189,7 @@ void BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable(void)
{
if (gRxIdleMode)
{
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, true);
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, true);
BK4819_RX_TurnOn();
}
}
@@ -1249,30 +1240,30 @@ void BK4819_PlayDTMF(char Code)
uint16_t tone1 = 0;
uint16_t tone2 = 0;
switch (Code) // Hz Hz
{ //
case '0': tone1 = 9715; tone2 = 13793; break; // 941 1336
case '1': tone1 = 7196; tone2 = 12482; break; // 679 1209
case '2': tone1 = 7196; tone2 = 13793; break; // 697 1336
case '3': tone1 = 7196; tone2 = 15249; break; // 679 1477
case '4': tone1 = 7950; tone2 = 12482; break; // 770 1209
case '5': tone1 = 7950; tone2 = 13793; break; // 770 1336
case '6': tone1 = 7950; tone2 = 15249; break; // 770 1477
case '7': tone1 = 8796; tone2 = 12482; break; // 852 1209
case '8': tone1 = 8796; tone2 = 13793; break; // 852 1336
case '9': tone1 = 8796; tone2 = 15249; break; // 852 1477
case 'A': tone1 = 7196; tone2 = 16860; break; // 679 1633
case 'B': tone1 = 7950; tone2 = 16860; break; // 770 1633
case 'C': tone1 = 8796; tone2 = 16860; break; // 852 1633
case 'D': tone1 = 9715; tone2 = 16860; break; // 941 1633
case '*': tone1 = 9715; tone2 = 12482; break; // 941 1209
case '#': tone1 = 9715; tone2 = 15249; break; // 941 1477
switch (Code)
{
case '0': tone1 = 941; tone2 = 1336; break;
case '1': tone1 = 679; tone2 = 1209; break;
case '2': tone1 = 697; tone2 = 1336; break;
case '3': tone1 = 679; tone2 = 1477; break;
case '4': tone1 = 770; tone2 = 1209; break;
case '5': tone1 = 770; tone2 = 1336; break;
case '6': tone1 = 770; tone2 = 1477; break;
case '7': tone1 = 852; tone2 = 1209; break;
case '8': tone1 = 852; tone2 = 1336; break;
case '9': tone1 = 852; tone2 = 1477; break;
case 'A': tone1 = 679; tone2 = 1633; break;
case 'B': tone1 = 770; tone2 = 1633; break;
case 'C': tone1 = 852; tone2 = 1633; break;
case 'D': tone1 = 941; tone2 = 1633; break;
case '*': tone1 = 941; tone2 = 1209; break;
case '#': tone1 = 941; tone2 = 1477; break;
}
if (tone1 > 0)
BK4819_WriteRegister(BK4819_REG_71, tone1);
BK4819_WriteRegister(BK4819_REG_71, (((uint32_t)tone1 * 103244) + 5000) / 10000); // with rounding
if (tone2 > 0)
BK4819_WriteRegister(BK4819_REG_72, tone2);
BK4819_WriteRegister(BK4819_REG_72, (((uint32_t)tone2 * 103244) + 5000) / 10000); // with rounding
}
void BK4819_PlayDTMFString(const char *pString, bool bDelayFirst, uint16_t FirstCodePersistTime, uint16_t HashCodePersistTime, uint16_t CodePersistTime, uint16_t CodeInternalTime)
@@ -1513,12 +1504,46 @@ BK4819_CssScanResult_t BK4819_GetCxCSSScanResult(uint32_t *pCdcssFreq, uint16_t
void BK4819_DisableFrequencyScan(void)
{
BK4819_WriteRegister(BK4819_REG_32, 0x0244);
// REG_32
//
// <15:14> 0 frequency scan time
// 0 = 0.2 sec
// 1 = 0.4 sec
// 2 = 0.8 sec
// 3 = 1.6 sec
//
// <13:1> ???
//
// <0> 0 frequency scan enable
// 1 = enable
// 0 = disable
//
BK4819_WriteRegister(BK4819_REG_32, // 0x0244); // 00 0000100100010 0
( 0u << 14) | // 0 frequency scan Time
(290u << 1) | // ???
( 0u << 0)); // 0 frequency scan enable
}
void BK4819_EnableFrequencyScan(void)
{
BK4819_WriteRegister(BK4819_REG_32, 0x0245); // 00 0000100100010 1
// REG_32
//
// <15:14> 0 frequency scan time
// 0 = 0.2 sec
// 1 = 0.4 sec
// 2 = 0.8 sec
// 3 = 1.6 sec
//
// <13:1> ???
//
// <0> 0 frequency scan enable
// 1 = enable
// 0 = disable
//
BK4819_WriteRegister(BK4819_REG_32, // 0x0245); // 00 0000100100010 1
( 0u << 14) | // 0 frequency scan time
(290u << 1) | // ???
( 1u << 0)); // 1 frequency scan enable
}
void BK4819_SetScanFrequency(uint32_t Frequency)

View File

@@ -62,6 +62,7 @@ enum BK4819_CssScanResult_t
typedef enum BK4819_CssScanResult_t BK4819_CssScanResult_t;
// radio is asleep, not listening
extern bool gRxIdleMode;
void BK4819_Init(void);
@@ -70,7 +71,8 @@ void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data);
void BK4819_WriteU8(uint8_t Data);
void BK4819_WriteU16(uint16_t Data);
void BK4819_SetAGC(uint8_t Value);
void BK4819_EnableAGC();
void BK4819_DisableAGC();
void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet);

View File

@@ -14,6 +14,9 @@
* limitations under the License.
*/
#include <stddef.h>
#include <string.h>
#include "driver/eeprom.h"
#include "driver/i2c.h"
#include "driver/system.h"
@@ -38,16 +41,22 @@ void EEPROM_ReadBuffer(uint16_t Address, void *pBuffer, uint8_t Size)
void EEPROM_WriteBuffer(uint16_t Address, const void *pBuffer)
{
I2C_Start();
if (pBuffer == NULL || Address >= 0x2000)
return;
I2C_Write(0xA0);
I2C_Write((Address >> 8) & 0xFF);
I2C_Write((Address >> 0) & 0xFF);
uint8_t buffer[8];
EEPROM_ReadBuffer(Address, buffer, 8);
if (memcmp(pBuffer, buffer, 8) != 0)
{
I2C_Start();
I2C_Write(0xA0);
I2C_Write((Address >> 8) & 0xFF);
I2C_Write((Address >> 0) & 0xFF);
I2C_WriteBuffer(pBuffer, 8);
I2C_Stop();
}
I2C_WriteBuffer(pBuffer, 8);
I2C_Stop();
SYSTEM_DelayMs(10);
// give the EEPROM time to burn the data in (apparently takes 5ms)
SYSTEM_DelayMs(8);
}

View File

@@ -14,25 +14,5 @@
* limitations under the License.
*/
#include "driver/gpio.h"
void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit)
{
*pReg &= ~(1U << Bit);
}
uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit)
{
return (*pReg >> Bit) & 1U;
}
void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit)
{
*pReg ^= 1U << Bit;
}
void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit)
{
*pReg |= 1U << Bit;
}

View File

@@ -58,10 +58,21 @@ enum GPIOC_PINS {
GPIOC_PIN_PTT = 5
};
void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit);
uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit);
void GPIO_FlipBit( volatile uint32_t *pReg, uint8_t Bit);
void GPIO_SetBit( volatile uint32_t *pReg, uint8_t Bit);
static inline void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit) {
*pReg &= ~(1U << Bit);
}
static inline uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit) {
return (*pReg >> Bit) & 1U;
}
static inline void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit) {
*pReg ^= 1U << Bit;
}
static inline void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit) {
*pReg |= 1U << Bit;
}
#endif

580
font.c
View File

@@ -16,201 +16,202 @@
#include "font.h"
//const uint8_t gFontBig[95][16] =
const uint8_t gFontBig[95][15] =
// removed last and middle column which was all 0x00
// also the space char is not needed
const uint8_t gFontBig[95 - 1][16 - 2] =
{
#if 0
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // ' '
{0x00, 0x00, 0x70, 0xF8, 0xF8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '!'
{0x00, 0x1E, 0x3E, 0x00, 0x00, 0x3E, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '"'
{0x40, 0xF0, 0xF0, 0x40, 0xF0, 0xF0, 0x40, 0x00, 0x04, 0x1F, 0x1F, 0x04, 0x1F, 0x1F, 0x04}, // , 0x00}, // '#'
{0x70, 0xF8, 0x88, 0x8F, 0x8F, 0x98, 0x30, 0x00, 0x06, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // , 0x00}, // '$'
{0x60, 0x60, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x00, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x18, 0x18}, // , 0x00}, // '%'
{0x00, 0xB0, 0xF8, 0xC8, 0x78, 0xB0, 0x80, 0x00, 0x0F, 0x1F, 0x10, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // '&'
{0x00, 0x20, 0x3E, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '''
{0x00, 0x00, 0xE0, 0xF0, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x00}, // , 0x00}, // '('
{0x00, 0x00, 0x08, 0x18, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x0F, 0x07, 0x00}, // , 0x00}, // ')'
{0x00, 0x40, 0xC0, 0x80, 0x80, 0xC0, 0x40, 0x00, 0x01, 0x05, 0x07, 0x03, 0x03, 0x07, 0x05}, // , 0x01}, // '*'
{0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x07, 0x07, 0x01, 0x01}, // , 0x00}, // '+'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x1C, 0x00, 0x00}, // , 0x00}, // ','
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, // , 0x00}, // '-'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, // , 0x00}, // '.'
{0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x00, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00}, // , 0x00}, // '/'
{0xF0, 0xF8, 0x08, 0x88, 0x48, 0xF8, 0xF0, 0x00, 0x0F, 0x1F, 0x12, 0x11, 0x10, 0x1F, 0x0F}, // , 0x00}, // '0'
{0x00, 0x20, 0x30, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10}, // , 0x00}, // '1'
{0x10, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x30, 0x00, 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x18}, // , 0x00}, // '2'
{0x10, 0x18, 0x88, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x08, 0x18, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '3'
{0x80, 0xC0, 0x60, 0x30, 0xF8, 0xF8, 0x00, 0x00, 0x01, 0x01, 0x01, 0x11, 0x1F, 0x1F, 0x11}, // , 0x00}, // '4'
{0xF8, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x08, 0x00, 0x08, 0x18, 0x10, 0x10, 0x11, 0x1F, 0x0F}, // , 0x00}, // '5'
{0xE0, 0xF0, 0x98, 0x88, 0x88, 0x80, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '6'
{0x18, 0x18, 0x08, 0x08, 0x88, 0xF8, 0x78, 0x00, 0x00, 0x00, 0x1E, 0x1F, 0x01, 0x00, 0x00}, // , 0x00}, // '7'
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '8'
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0xF0, 0x00, 0x00, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // '9'
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // , 0x00}, // ':'
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1C, 0x0C, 0x00, 0x00}, // , 0x00}, // ';'
{0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x10, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18, 0x10}, // , 0x00}, // '<'
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, // , 0x00}, // '='
{0x00, 0x10, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x10, 0x18, 0x0C, 0x06, 0x03, 0x01}, // , 0x00}, // '>'
{0x30, 0x38, 0x08, 0x88, 0xC8, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '?'
{0xE0, 0xF0, 0x10, 0x90, 0x90, 0xF0, 0xE0, 0x00, 0x0F, 0x1F, 0x10, 0x17, 0x17, 0x17, 0x03}, // , 0x00}, // '@'
{0xC0, 0xE0, 0x30, 0x18, 0x30, 0xE0, 0xC0, 0x00, 0x1F, 0x1F, 0x01, 0x01, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'A'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'B'
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x10, 0x18, 0x0C}, // , 0x00}, // 'C'
{0x08, 0xF8, 0xF8, 0x08, 0x18, 0xF0, 0xE0, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'D'
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x11, 0x18, 0x1C}, // , 0x00}, // 'E'
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x01, 0x00, 0x00}, // , 0x00}, // 'F'
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, 0x00, 0x07, 0x0F, 0x18, 0x11, 0x11, 0x0F, 0x1F}, // , 0x00}, // 'G'
{0xF8, 0xF8, 0x80, 0x80, 0x80, 0xF8, 0xF8, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'H'
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'I'
{0x00, 0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, 0x00, 0x0E, 0x1E, 0x10, 0x10, 0x1F, 0x0F, 0x00}, // , 0x00}, // 'J'
{0x08, 0xF8, 0xF8, 0x80, 0xE0, 0x78, 0x18, 0x00, 0x10, 0x1F, 0x1F, 0x01, 0x03, 0x1E, 0x1C}, // , 0x00}, // 'K'
{0x08, 0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x18, 0x1C}, // , 0x00}, // 'L'
{0xF8, 0xF8, 0x70, 0xE0, 0x70, 0xF8, 0xF8, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'M'
{0xF8, 0xF8, 0x70, 0xE0, 0xC0, 0xF8, 0xF8, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'N'
{0xE0, 0xF0, 0x18, 0x08, 0x18, 0xF0, 0xE0, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'O'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'P'
{0xF0, 0xF8, 0x08, 0x08, 0x08, 0xF8, 0xF0, 0x00, 0x0F, 0x1F, 0x10, 0x1C, 0x78, 0x7F, 0x4F}, // , 0x00}, // 'Q'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, 0x00, 0x10, 0x1F, 0x1F, 0x00, 0x01, 0x1F, 0x1E}, // , 0x00}, // 'R'
{0x30, 0x78, 0xC8, 0x88, 0x88, 0x38, 0x30, 0x00, 0x0C, 0x1C, 0x10, 0x10, 0x11, 0x1F, 0x0E}, // , 0x00}, // 'S'
{0x00, 0x38, 0x18, 0xF8, 0xF8, 0x18, 0x38, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'T'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'U'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x03, 0x07, 0x0C, 0x18, 0x0C, 0x07, 0x03}, // , 0x00}, // 'V'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x07, 0x1F, 0x1C, 0x07, 0x1C, 0x1F, 0x07}, // , 0x00}, // 'W'
{0x18, 0x78, 0xE0, 0x80, 0xE0, 0x78, 0x18, 0x00, 0x18, 0x1E, 0x07, 0x01, 0x07, 0x1E, 0x18}, // , 0x00}, // 'X'
{0x00, 0x78, 0xF8, 0x80, 0x80, 0xF8, 0x78, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'Y'
{0x38, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x38, 0x00, 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x1C}, // , 0x00}, // 'Z'
{0x00, 0x00, 0xF8, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x00}, // , 0x00}, // '['
{0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x1C}, // , 0x00}, // '"\'
{0x00, 0x00, 0x08, 0x08, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x00}, // , 0x00}, // ']'
{0x10, 0x18, 0x0E, 0x07, 0x0E, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '^'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, // , 0x40}, // '_'
{0x00, 0x00, 0x07, 0x0F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '`'
{0x00, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x00, 0x0E, 0x1F, 0x11, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'a'
{0x08, 0xF8, 0xF8, 0x40, 0xC0, 0x80, 0x00, 0x00, 0x10, 0x1F, 0x0F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'b'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x18, 0x08}, // , 0x00}, // 'c'
{0x00, 0x80, 0xC0, 0x48, 0xF8, 0xF8, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'd'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x0F, 0x1F, 0x11, 0x11, 0x11, 0x19, 0x09}, // , 0x00}, // 'e'
{0x80, 0xF0, 0xF8, 0x88, 0x18, 0x30, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'f'
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, 0x00, 0x4F, 0xDF, 0x90, 0x90, 0xFF, 0x7F, 0x00}, // , 0x00}, // 'g'
{0x08, 0xF8, 0xF8, 0x80, 0x40, 0xC0, 0x80, 0x00, 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'h'
{0x00, 0x00, 0x40, 0xD8, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'i'
{0x00, 0x00, 0x00, 0x00, 0x40, 0xD8, 0xD8, 0x00, 0x00, 0x60, 0xE0, 0x80, 0x80, 0xFF, 0x7F}, // , 0x00}, // 'j'
{0x08, 0xF8, 0xF8, 0x00, 0x80, 0xC0, 0x40, 0x00, 0x10, 0x1F, 0x1F, 0x03, 0x07, 0x1C, 0x18}, // , 0x00}, // 'k'
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'l'
{0xC0, 0xC0, 0xC0, 0x80, 0xC0, 0xC0, 0x80, 0x00, 0x1F, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'm'
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'n'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'o'
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x80, 0xFF, 0xFF, 0x90, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'p'
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, 0x00, 0x0F, 0x1F, 0x10, 0x90, 0xFF, 0xFF, 0x80}, // , 0x00}, // 'q'
{0x40, 0xC0, 0x80, 0xC0, 0x40, 0xC0, 0x80, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x01}, // , 0x00}, // 'r'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x08, 0x19, 0x13, 0x12, 0x16, 0x1C, 0x08}, // , 0x00}, // 's'
{0x40, 0x40, 0xF0, 0xF8, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x18, 0x08}, // , 0x00}, // 't'
{0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'u'
{0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x07, 0x0F, 0x18, 0x18, 0x0F, 0x07}, // , 0x00}, // 'v'
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x0F, 0x1F, 0x18, 0x0E, 0x18, 0x1F, 0x0F}, // , 0x00}, // 'w'
{0x40, 0xC0, 0x80, 0x00, 0x80, 0xC0, 0x40, 0x00, 0x10, 0x18, 0x0F, 0x07, 0x0F, 0x18, 0x10}, // , 0x00}, // 'x'
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x8F, 0x9F, 0x90, 0x90, 0xD0, 0x7F, 0x3F}, // , 0x00}, // 'y'
{0xC0, 0xC0, 0x40, 0x40, 0xC0, 0xC0, 0x40, 0x00, 0x18, 0x1C, 0x16, 0x13, 0x11, 0x18, 0x18}, // , 0x00}, // 'z'
{0x00, 0x80, 0x80, 0xF0, 0x78, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10}, // , 0x00}, // '{'
{0x00, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00}, // , 0x00}, // '|'
{0x00, 0x08, 0x08, 0x78, 0xF0, 0x80, 0x80, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x0F, 0x00, 0x00}, // , 0x00}, // '}'
{0x10, 0x18, 0x08, 0x18, 0x10, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // , 0x00} // '->'
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // ' '
{0x00, 0x00, 0x70, 0xF8, 0xF8, 0x70, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '!'
{0x00, 0x1E, 0x3E, 0x00, 0x00, 0x3E, 0x1E, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '"'
{0x40, 0xF0, 0xF0, 0x40, 0xF0, 0xF0, 0x40, /*0x00,*/ 0x04, 0x1F, 0x1F, 0x04, 0x1F, 0x1F, 0x04}, // , 0x00}, // '#'
{0x70, 0xF8, 0x88, 0x8F, 0x8F, 0x98, 0x30, /*0x00,*/ 0x06, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // , 0x00}, // '$'
{0x60, 0x60, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x18, 0x18}, // , 0x00}, // '%'
{0x00, 0xB0, 0xF8, 0xC8, 0x78, 0xB0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // '&'
{0x00, 0x20, 0x3E, 0x1E, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '''
{0x00, 0x00, 0xE0, 0xF0, 0x18, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x18, 0x10, 0x00}, // , 0x00}, // '('
{0x00, 0x00, 0x08, 0x18, 0xF0, 0xE0, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x18, 0x0F, 0x07, 0x00}, // , 0x00}, // ')'
{0x00, 0x40, 0xC0, 0x80, 0x80, 0xC0, 0x40, /*0x00,*/ 0x01, 0x05, 0x07, 0x03, 0x03, 0x07, 0x05}, // , 0x01}, // '*'
{0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, /*0x00,*/ 0x00, 0x01, 0x01, 0x07, 0x07, 0x01, 0x01}, // , 0x00}, // '+'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x20, 0x3C, 0x1C, 0x00, 0x00}, // , 0x00}, // ','
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, // , 0x00}, // '-'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, // , 0x00}, // '.'
{0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, /*0x00,*/ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00}, // , 0x00}, // '/'
{0xF0, 0xF8, 0x08, 0x88, 0x48, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x12, 0x11, 0x10, 0x1F, 0x0F}, // , 0x00}, // '0'
{0x00, 0x20, 0x30, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10}, // , 0x00}, // '1'
{0x10, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x18}, // , 0x00}, // '2'
{0x10, 0x18, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '3'
{0x80, 0xC0, 0x60, 0x30, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x01, 0x01, 0x01, 0x11, 0x1F, 0x1F, 0x11}, // , 0x00}, // '4'
{0xF8, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x08, /*0x00,*/ 0x08, 0x18, 0x10, 0x10, 0x11, 0x1F, 0x0F}, // , 0x00}, // '5'
{0xE0, 0xF0, 0x98, 0x88, 0x88, 0x80, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '6'
{0x18, 0x18, 0x08, 0x08, 0x88, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x1E, 0x1F, 0x01, 0x00, 0x00}, // , 0x00}, // '7'
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // '8'
{0x70, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0xF0, /*0x00,*/ 0x00, 0x10, 0x10, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // '9'
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // , 0x00}, // ':'
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1C, 0x0C, 0x00, 0x00}, // , 0x00}, // ';'
{0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x10, /*0x00,*/ 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18, 0x10}, // , 0x00}, // '<'
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, // , 0x00}, // '='
{0x00, 0x10, 0x30, 0x60, 0xC0, 0x80, 0x00, /*0x00,*/ 0x00, 0x10, 0x18, 0x0C, 0x06, 0x03, 0x01}, // , 0x00}, // '>'
{0x30, 0x38, 0x08, 0x88, 0xC8, 0x78, 0x30, /*0x00,*/ 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x00, 0x00}, // , 0x00}, // '?'
{0xE0, 0xF0, 0x10, 0x90, 0x90, 0xF0, 0xE0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x17, 0x17, 0x17, 0x03}, // , 0x00}, // '@'
{0xC0, 0xE0, 0x30, 0x18, 0x30, 0xE0, 0xC0, /*0x00,*/ 0x1F, 0x1F, 0x01, 0x01, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'A'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'B'
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x10, 0x18, 0x0C}, // , 0x00}, // 'C'
{0x08, 0xF8, 0xF8, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'D'
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x11, 0x18, 0x1C}, // , 0x00}, // 'E'
{0x08, 0xF8, 0xF8, 0x88, 0xC8, 0x18, 0x38, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x01, 0x00, 0x00}, // , 0x00}, // 'F'
{0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0x30, /*0x00,*/ 0x07, 0x0F, 0x18, 0x11, 0x11, 0x0F, 0x1F}, // , 0x00}, // 'G'
{0xF8, 0xF8, 0x80, 0x80, 0x80, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'H'
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'I'
{0x00, 0x00, 0x00, 0x08, 0xF8, 0xF8, 0x08, /*0x00,*/ 0x0E, 0x1E, 0x10, 0x10, 0x1F, 0x0F, 0x00}, // , 0x00}, // 'J'
{0x08, 0xF8, 0xF8, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x01, 0x03, 0x1E, 0x1C}, // , 0x00}, // 'K'
{0x08, 0xF8, 0xF8, 0x08, 0x00, 0x00, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x18, 0x1C}, // , 0x00}, // 'L'
{0xF8, 0xF8, 0x70, 0xE0, 0x70, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'M'
{0xF8, 0xF8, 0x70, 0xE0, 0xC0, 0xF8, 0xF8, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x00, 0x01, 0x1F, 0x1F}, // , 0x00}, // 'N'
{0xE0, 0xF0, 0x18, 0x08, 0x18, 0xF0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x18, 0x10, 0x18, 0x0F, 0x07}, // , 0x00}, // 'O'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'P'
{0xF0, 0xF8, 0x08, 0x08, 0x08, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x1C, 0x78, 0x7F, 0x4F}, // , 0x00}, // 'Q'
{0x08, 0xF8, 0xF8, 0x88, 0x88, 0xF8, 0x70, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x01, 0x1F, 0x1E}, // , 0x00}, // 'R'
{0x30, 0x78, 0xC8, 0x88, 0x88, 0x38, 0x30, /*0x00,*/ 0x0C, 0x1C, 0x10, 0x10, 0x11, 0x1F, 0x0E}, // , 0x00}, // 'S'
{0x00, 0x38, 0x18, 0xF8, 0xF8, 0x18, 0x38, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'T'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'U'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x03, 0x07, 0x0C, 0x18, 0x0C, 0x07, 0x03}, // , 0x00}, // 'V'
{0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, /*0x00,*/ 0x07, 0x1F, 0x1C, 0x07, 0x1C, 0x1F, 0x07}, // , 0x00}, // 'W'
{0x18, 0x78, 0xE0, 0x80, 0xE0, 0x78, 0x18, /*0x00,*/ 0x18, 0x1E, 0x07, 0x01, 0x07, 0x1E, 0x18}, // , 0x00}, // 'X'
{0x00, 0x78, 0xF8, 0x80, 0x80, 0xF8, 0x78, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'Y'
{0x38, 0x18, 0x08, 0x88, 0xC8, 0x78, 0x38, /*0x00,*/ 0x1C, 0x1E, 0x13, 0x11, 0x10, 0x18, 0x1C}, // , 0x00}, // 'Z'
{0x00, 0x00, 0xF8, 0xF8, 0x08, 0x08, 0x00, /*0x00,*/ 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x00}, // , 0x00}, // '['
{0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x1C}, // , 0x00}, // '"\'
{0x00, 0x00, 0x08, 0x08, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x00}, // , 0x00}, // ']'
{0x10, 0x18, 0x0E, 0x07, 0x0E, 0x18, 0x10, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '^'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, // , 0x40}, // '_'
{0x00, 0x00, 0x07, 0x0F, 0x08, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // , 0x00}, // '`'
{0x00, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x0E, 0x1F, 0x11, 0x11, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'a'
{0x08, 0xF8, 0xF8, 0x40, 0xC0, 0x80, 0x00, /*0x00,*/ 0x10, 0x1F, 0x0F, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'b'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x18, 0x08}, // , 0x00}, // 'c'
{0x00, 0x80, 0xC0, 0x48, 0xF8, 0xF8, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'd'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x11, 0x11, 0x11, 0x19, 0x09}, // , 0x00}, // 'e'
{0x80, 0xF0, 0xF8, 0x88, 0x18, 0x30, 0x00, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x00}, // , 0x00}, // 'f'
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x4F, 0xDF, 0x90, 0x90, 0xFF, 0x7F, 0x00}, // , 0x00}, // 'g'
{0x08, 0xF8, 0xF8, 0x80, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'h'
{0x00, 0x00, 0x40, 0xD8, 0xD8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'i'
{0x00, 0x00, 0x00, 0x00, 0x40, 0xD8, 0xD8, /*0x00,*/ 0x00, 0x60, 0xE0, 0x80, 0x80, 0xFF, 0x7F}, // , 0x00}, // 'j'
{0x08, 0xF8, 0xF8, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x03, 0x07, 0x1C, 0x18}, // , 0x00}, // 'k'
{0x00, 0x00, 0x08, 0xF8, 0xF8, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1F, 0x1F, 0x10, 0x00}, // , 0x00}, // 'l'
{0xC0, 0xC0, 0xC0, 0x80, 0xC0, 0xC0, 0x80, /*0x00,*/ 0x1F, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'm'
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F}, // , 0x00}, // 'n'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'o'
{0x40, 0xC0, 0x80, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x80, 0xFF, 0xFF, 0x90, 0x10, 0x1F, 0x0F}, // , 0x00}, // 'p'
{0x80, 0xC0, 0x40, 0x40, 0x80, 0xC0, 0x40, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x90, 0xFF, 0xFF, 0x80}, // , 0x00}, // 'q'
{0x40, 0xC0, 0x80, 0xC0, 0x40, 0xC0, 0x80, /*0x00,*/ 0x10, 0x1F, 0x1F, 0x10, 0x00, 0x00, 0x01}, // , 0x00}, // 'r'
{0x80, 0xC0, 0x40, 0x40, 0x40, 0xC0, 0x80, /*0x00,*/ 0x08, 0x19, 0x13, 0x12, 0x16, 0x1C, 0x08}, // , 0x00}, // 's'
{0x40, 0x40, 0xF0, 0xF8, 0x40, 0x40, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x18, 0x08}, // , 0x00}, // 't'
{0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, /*0x00,*/ 0x0F, 0x1F, 0x10, 0x10, 0x0F, 0x1F, 0x10}, // , 0x00}, // 'u'
{0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x00, 0x07, 0x0F, 0x18, 0x18, 0x0F, 0x07}, // , 0x00}, // 'v'
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x0F, 0x1F, 0x18, 0x0E, 0x18, 0x1F, 0x0F}, // , 0x00}, // 'w'
{0x40, 0xC0, 0x80, 0x00, 0x80, 0xC0, 0x40, /*0x00,*/ 0x10, 0x18, 0x0F, 0x07, 0x0F, 0x18, 0x10}, // , 0x00}, // 'x'
{0xC0, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xC0, /*0x00,*/ 0x8F, 0x9F, 0x90, 0x90, 0xD0, 0x7F, 0x3F}, // , 0x00}, // 'y'
{0xC0, 0xC0, 0x40, 0x40, 0xC0, 0xC0, 0x40, /*0x00,*/ 0x18, 0x1C, 0x16, 0x13, 0x11, 0x18, 0x18}, // , 0x00}, // 'z'
{0x00, 0x80, 0x80, 0xF0, 0x78, 0x08, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x10, 0x10}, // , 0x00}, // '{'
{0x00, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00}, // , 0x00}, // '|'
{0x00, 0x08, 0x08, 0x78, 0xF0, 0x80, 0x80, /*0x00,*/ 0x00, 0x10, 0x10, 0x1F, 0x0F, 0x00, 0x00}, // , 0x00}, // '}'
{0x10, 0x18, 0x08, 0x18, 0x10, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // , 0x00} // '->'
#else
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00},
{0x00, 0x0F, 0x1F, 0x00, 0x00, 0x1F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x20, 0xF8, 0xF8, 0x20, 0xF8, 0xF8, 0x20, 0x00, 0x02, 0x0F, 0x0F, 0x02, 0x0F, 0x0F, 0x02},
{0x70, 0xF8, 0x88, 0x8E, 0x8E, 0x98, 0x10, 0x00, 0x04, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07},
{0x30, 0x30, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x00, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x0C, 0x0C},
{0x80, 0xD8, 0x7C, 0xE4, 0xBC, 0xD8, 0x40, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x07, 0x0F, 0x08},
{0x00, 0x10, 0x1F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xF0, 0xF8, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0C, 0x08, 0x00},
{0x00, 0x00, 0x04, 0x0C, 0xF8, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0C, 0x07, 0x03, 0x00},
{0x00, 0x80, 0xA0, 0xE0, 0xC0, 0xE0, 0xA0, 0x80, 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x02},
{0x00, 0x80, 0x80, 0xE0, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x1E, 0x0E, 0x00, 0x00},
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x00, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00},
{0xF8, 0xFC, 0x84, 0xC4, 0x64, 0xFC, 0xF8, 0x00, 0x07, 0x0F, 0x09, 0x08, 0x08, 0x0F, 0x07},
{0x00, 0x10, 0x18, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08},
{0x18, 0x1C, 0x04, 0x84, 0xC4, 0x7C, 0x38, 0x00, 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08},
{0x18, 0x1C, 0x44, 0x44, 0x44, 0xFC, 0xB8, 0x00, 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07},
{0x80, 0xC0, 0x60, 0x30, 0x18, 0xFC, 0xFC, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x0F},
{0x7C, 0x7C, 0x44, 0x44, 0x44, 0xC4, 0x84, 0x00, 0x04, 0x0C, 0x08, 0x08, 0x08, 0x0F, 0x07},
{0xF0, 0xF8, 0x4C, 0x44, 0x44, 0xC4, 0x80, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
{0x04, 0x04, 0x04, 0x84, 0xE4, 0x7C, 0x1C, 0x00, 0x00, 0x00, 0x0E, 0x0F, 0x01, 0x00, 0x00},
{0xB8, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
{0x78, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, 0x00, 0x00, 0x08, 0x08, 0x08, 0x0C, 0x07, 0x03},
{0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 0x06, 0x00, 0x00},
{0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x08},
{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02},
{0x00, 0x08, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x08, 0x0C, 0x06, 0x03, 0x01, 0x00},
{0x38, 0x3C, 0x04, 0x84, 0xC4, 0x7C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00},
{0xF0, 0xF8, 0x08, 0xC8, 0xC8, 0xF8, 0xF0, 0x00, 0x07, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x01},
{0xF8, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F},
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0x1C, 0x18, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0E, 0x06},
{0xFC, 0xFC, 0x04, 0x04, 0x0C, 0xF8, 0xF0, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x0C, 0x07, 0x03},
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08},
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xF8, 0xFC, 0x04, 0x84, 0x84, 0x9C, 0x98, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
{0xFC, 0xFC, 0x40, 0x40, 0x40, 0xFC, 0xFC, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F},
{0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00},
{0x00, 0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, 0x00, 0x06, 0x0E, 0x08, 0x08, 0x0F, 0x07, 0x00},
{0xFC, 0xFC, 0xE0, 0x30, 0x18, 0x0C, 0x04, 0x00, 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08},
{0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08},
{0xFC, 0xFC, 0x18, 0x70, 0x18, 0xFC, 0xFC, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F},
{0xFC, 0xFC, 0x60, 0xC0, 0x80, 0xFC, 0xFC, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0F},
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
{0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, 0x00, 0x07, 0x0F, 0x08, 0x0C, 0x0C, 0x1F, 0x17},
{0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, 0x00, 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08},
{0x38, 0x7C, 0x44, 0x44, 0x44, 0xCC, 0x88, 0x00, 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07},
{0x00, 0x04, 0x04, 0xFC, 0xFC, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00},
{0xFC, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
{0x7C, 0xFC, 0x80, 0x00, 0x80, 0xFC, 0x7C, 0x00, 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00},
{0xFC, 0xFC, 0x00, 0x80, 0x00, 0xFC, 0xFC, 0x00, 0x0F, 0x0F, 0x06, 0x03, 0x06, 0x0F, 0x0F},
{0x0C, 0x3C, 0xF0, 0xC0, 0xF0, 0x3C, 0x0C, 0x00, 0x0C, 0x0F, 0x03, 0x00, 0x03, 0x0F, 0x0C},
{0x00, 0x3C, 0x7C, 0xC0, 0xC0, 0x7C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00},
{0x04, 0x04, 0x84, 0xC4, 0x64, 0x3C, 0x1C, 0x00, 0x0E, 0x0F, 0x09, 0x08, 0x08, 0x08, 0x08},
{0x00, 0x00, 0xFC, 0xFC, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x00},
{0x38, 0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E},
{0x00, 0x00, 0x04, 0x04, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x00},
{0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20},
{0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, 0xC0, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F},
{0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0x60, 0x40, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0C, 0x04},
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xFC, 0xFC, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F},
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x07, 0x0F, 0x09, 0x09, 0x09, 0x09, 0x01},
{0x20, 0x20, 0xF8, 0xFC, 0x24, 0x24, 0x04, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00},
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, 0x00, 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F},
{0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F},
{0x00, 0x00, 0x20, 0xEC, 0xEC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x20, 0xEC, 0xEC, 0x00, 0x00, 0x30, 0x70, 0x40, 0x40, 0x7F, 0x3F},
{0xFC, 0xFC, 0x00, 0x80, 0xC0, 0x60, 0x20, 0x00, 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08},
{0x00, 0x00, 0x04, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00},
{0xE0, 0xE0, 0x20, 0xE0, 0x20, 0xE0, 0xC0, 0x00, 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x0F},
{0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F},
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07},
{0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, 0x00, 0x7F, 0x7F, 0x08, 0x08, 0x08, 0x0F, 0x07},
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x7F, 0x7F},
{0xE0, 0xE0, 0x60, 0x20, 0x20, 0x20, 0x20, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x08, 0x09, 0x09, 0x09, 0x09, 0x0F, 0x06},
{0x20, 0x20, 0xFC, 0xFC, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08},
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F},
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x00, 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00},
{0xE0, 0xE0, 0x00, 0x80, 0x00, 0xE0, 0xE0, 0x00, 0x07, 0x0F, 0x08, 0x0F, 0x08, 0x0F, 0x07},
{0x60, 0xE0, 0x80, 0x00, 0x80, 0xE0, 0x60, 0x00, 0x0C, 0x0E, 0x03, 0x01, 0x03, 0x0E, 0x0C},
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x00, 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F},
{0x20, 0x20, 0x20, 0xA0, 0xE0, 0x60, 0x20, 0x00, 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08},
{0x00, 0x00, 0x40, 0xF8, 0xBC, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08},
{0x00, 0x00, 0x00, 0xBC, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00},
{0x00, 0x04, 0x04, 0xBC, 0xF8, 0x40, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0F, 0x07, 0x00, 0x00},
{0x08, 0x0C, 0x04, 0x0C, 0x08, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' '
{0x00, 0x00, 0x00, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '!'
{0x00, 0x0F, 0x1F, 0x00, 0x00, 0x1F, 0x0F, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '"'
{0x20, 0xF8, 0xF8, 0x20, 0xF8, 0xF8, 0x20, /*0x00,*/ 0x02, 0x0F, 0x0F, 0x02, 0x0F, 0x0F, 0x02}, // '#'
{0x70, 0xF8, 0x88, 0x8E, 0x8E, 0x98, 0x10, /*0x00,*/ 0x04, 0x0C, 0x08, 0x38, 0x38, 0x0F, 0x07}, // '$'
{0x30, 0x30, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x0C, 0x0C}, // '%'
{0x80, 0xD8, 0x7C, 0xE4, 0xBC, 0xD8, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x07, 0x0F, 0x08}, // '&'
{0x00, 0x10, 0x1F, 0x0F, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '''
{0x00, 0x00, 0xF0, 0xF8, 0x0C, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x03, 0x07, 0x0C, 0x08, 0x00}, // '('
{0x00, 0x00, 0x04, 0x0C, 0xF8, 0xF0, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0C, 0x07, 0x03, 0x00}, // ')'
{0x00, 0x80, 0xA0, 0xE0, 0xC0, 0xE0, 0xA0, /*0x80,*/ 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x02}, // '*'
{0x00, 0x80, 0x80, 0xE0, 0xE0, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00}, // '+'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x10, 0x1E, 0x0E, 0x00, 0x00}, // ','
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '-'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00}, // '.'
{0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, /*0x00,*/ 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00}, // '/'
{0xF8, 0xFC, 0x84, 0xC4, 0x64, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x09, 0x08, 0x08, 0x0F, 0x07}, // '0'
{0x00, 0x10, 0x18, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08}, // '1'
{0x18, 0x1C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // '2'
{0x18, 0x1C, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '3'
{0x80, 0xC0, 0x60, 0x30, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x01, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x0F}, // '4'
{0x7C, 0x7C, 0x44, 0x44, 0x44, 0xC4, 0x84, /*0x00,*/ 0x04, 0x0C, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '5'
{0xF0, 0xF8, 0x4C, 0x44, 0x44, 0xC4, 0x80, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '6'
{0x04, 0x04, 0x04, 0x84, 0xE4, 0x7C, 0x1C, /*0x00,*/ 0x00, 0x00, 0x0E, 0x0F, 0x01, 0x00, 0x00}, // '7'
{0xB8, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // '8'
{0x78, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x00, 0x08, 0x08, 0x08, 0x0C, 0x07, 0x03}, // '9'
{0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00}, // ':'
{0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0E, 0x06, 0x00, 0x00}, // ';'
{0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, /*0x00,*/ 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x08}, // '<'
{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /*0x00,*/ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}, // '='
{0x00, 0x08, 0x18, 0x30, 0x60, 0xC0, 0x80, /*0x00,*/ 0x00, 0x08, 0x0C, 0x06, 0x03, 0x01, 0x00}, // '>'
{0x38, 0x3C, 0x04, 0x84, 0xC4, 0x7C, 0x38, /*0x00,*/ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00}, // '?'
{0xF0, 0xF8, 0x08, 0xC8, 0xC8, 0xF8, 0xF0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0B, 0x0B, 0x0B, 0x01}, // '@'
{0xF8, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0xF8, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'A'
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0xFC, 0xB8, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'B'
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0x1C, 0x18, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0E, 0x06}, // 'C'
{0xFC, 0xFC, 0x04, 0x04, 0x0C, 0xF8, 0xF0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x0C, 0x07, 0x03}, // 'D'
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'E'
{0xFC, 0xFC, 0x44, 0x44, 0x44, 0x04, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'F'
{0xF8, 0xFC, 0x04, 0x84, 0x84, 0x9C, 0x98, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'G'
{0xFC, 0xFC, 0x40, 0x40, 0x40, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'H'
{0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'I'
{0x00, 0x00, 0x00, 0x04, 0xFC, 0xFC, 0x04, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x0F, 0x07, 0x00}, // 'J'
{0xFC, 0xFC, 0xE0, 0x30, 0x18, 0x0C, 0x04, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'K'
{0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x08}, // 'L'
{0xFC, 0xFC, 0x18, 0x70, 0x18, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'M'
{0xFC, 0xFC, 0x60, 0xC0, 0x80, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0F}, // 'N'
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'O'
{0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'P'
{0xF8, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0xF8, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0C, 0x0C, 0x1F, 0x17}, // 'Q'
{0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'R'
{0x38, 0x7C, 0x44, 0x44, 0x44, 0xCC, 0x88, /*0x00,*/ 0x06, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'S'
{0x00, 0x04, 0x04, 0xFC, 0xFC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'T'
{0xFC, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'U'
{0x7C, 0xFC, 0x80, 0x00, 0x80, 0xFC, 0x7C, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'V'
{0xFC, 0xFC, 0x00, 0x80, 0x00, 0xFC, 0xFC, /*0x00,*/ 0x0F, 0x0F, 0x06, 0x03, 0x06, 0x0F, 0x0F}, // 'W'
{0x0C, 0x3C, 0xF0, 0xC0, 0xF0, 0x3C, 0x0C, /*0x00,*/ 0x0C, 0x0F, 0x03, 0x00, 0x03, 0x0F, 0x0C}, // 'X'
{0x00, 0x3C, 0x7C, 0xC0, 0xC0, 0x7C, 0x3C, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // 'Y'
{0x04, 0x04, 0x84, 0xC4, 0x64, 0x3C, 0x1C, /*0x00,*/ 0x0E, 0x0F, 0x09, 0x08, 0x08, 0x08, 0x08}, // 'Z'
{0x00, 0x00, 0xFC, 0xFC, 0x04, 0x04, 0x00, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x00}, // '['
{0x38, 0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E}, // '"\'
{0x00, 0x00, 0x04, 0x04, 0xFC, 0xFC, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x08, 0x0F, 0x0F, 0x00}, // ']'
{0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '^'
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, // '_'
{0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // '`'
{0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'a'
{0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'b'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0x60, 0x40, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0C, 0x04}, // 'c'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xFC, 0xFC, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'd'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x09, 0x09, 0x09, 0x09, 0x01}, // 'e'
{0x20, 0x20, 0xF8, 0xFC, 0x24, 0x24, 0x04, /*0x00,*/ 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00}, // 'f'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'g'
{0xFC, 0xFC, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'h'
{0x00, 0x00, 0x20, 0xEC, 0xEC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'i'
{0x00, 0x00, 0x00, 0x00, 0x20, 0xEC, 0xEC, /*0x00,*/ 0x00, 0x30, 0x70, 0x40, 0x40, 0x7F, 0x3F}, // 'j'
{0xFC, 0xFC, 0x00, 0x80, 0xC0, 0x60, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x01, 0x03, 0x06, 0x0C, 0x08}, // 'k'
{0x00, 0x00, 0x04, 0xFC, 0xFC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x08, 0x0F, 0x0F, 0x08, 0x00}, // 'l'
{0xE0, 0xE0, 0x20, 0xE0, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x0F}, // 'm'
{0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F}, // 'n'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'o'
{0xE0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xC0, /*0x00,*/ 0x7F, 0x7F, 0x08, 0x08, 0x08, 0x0F, 0x07}, // 'p'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x7F, 0x7F}, // 'q'
{0xE0, 0xE0, 0x60, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, // 'r'
{0xC0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, /*0x00,*/ 0x08, 0x09, 0x09, 0x09, 0x09, 0x0F, 0x06}, // 's'
{0x20, 0x20, 0xFC, 0xFC, 0x20, 0x20, 0x00, /*0x00,*/ 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08}, // 't'
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x08, 0x08, 0x0F, 0x0F}, // 'u'
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x00, 0x03, 0x0F, 0x0C, 0x0F, 0x03, 0x00}, // 'v'
{0xE0, 0xE0, 0x00, 0x80, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x0F, 0x08, 0x0F, 0x08, 0x0F, 0x07}, // 'w'
{0x60, 0xE0, 0x80, 0x00, 0x80, 0xE0, 0x60, /*0x00,*/ 0x0C, 0x0E, 0x03, 0x01, 0x03, 0x0E, 0x0C}, // 'x'
{0xE0, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0xE0, /*0x00,*/ 0x07, 0x4F, 0x48, 0x48, 0x48, 0x7F, 0x3F}, // 'y'
{0x20, 0x20, 0x20, 0xA0, 0xE0, 0x60, 0x20, /*0x00,*/ 0x0C, 0x0E, 0x0B, 0x09, 0x08, 0x08, 0x08}, // 'z'
{0x00, 0x00, 0x40, 0xF8, 0xBC, 0x04, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x07, 0x0F, 0x08, 0x08}, // '{'
{0x00, 0x00, 0x00, 0xBC, 0xBC, 0x00, 0x00, /*0x00,*/ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, // '|'
{0x00, 0x04, 0x04, 0xBC, 0xF8, 0x40, 0x00, /*0x00,*/ 0x00, 0x08, 0x08, 0x0F, 0x07, 0x00, 0x00}, // '}'
{0x08, 0x0C, 0x04, 0x0C, 0x08, 0x0C, 0x04, /*0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // '->'
#endif
};
@@ -230,37 +231,40 @@ const uint8_t gFontBig[95][15] =
{0x00, 0xF0, 0xF8, 0xB8, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1C, 0xB8, 0xF0, 0xE0, 0x00, 0x11, 0x33, 0x77, 0x67, 0x66, 0x66, 0x66, 0x76, 0x33, 0x3F, 0x1F, 0x07},
{0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00}
};
// 6 Empty columns removed
#elif 0
// VCR font
const uint8_t gFontBigDigits[11][26] =
const uint8_t gFontBigDigits[11][26 - 6] =
{
{0x00, 0x00, 0xF8, 0xFC, 0x06, 0x86, 0xC6, 0xE6, 0xF6, 0x76, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x77, 0x67, 0x63, 0x61, 0x60, 0x70, 0x3F, 0x1F, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x60, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x1C, 0x86, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, 0x00, 0x00, 0x00, 0x7E, 0x7F, 0x63, 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x18, 0x1C, 0x06, 0x06, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, 0x00, 0x00, 0x00, 0x18, 0x38, 0x70, 0x60, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, 0x00},
{0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x7F, 0x7F, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x7E, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x66, 0xE6, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x18, 0x38, 0x70, 0x60, 0x60, 0x60, 0x60, 0x70, 0x3F, 0x1F, 0x00},
{0x00, 0x00, 0xF8, 0xFC, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x1C, 0x18, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x71, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x86, 0xC6, 0xE6, 0x7E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, 0x00, 0x00, 0x00, 0x1E, 0x3F, 0x73, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, 0x00},
{0x00, 0x00, 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0x86, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x18, 0x38, 0x71, 0x61, 0x61, 0x61, 0x61, 0x71, 0x3F, 0x1F, 0x00},
{0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}
{/*0x00, 0x00,*/ 0xF8, 0xFC, 0x06, 0x86, 0xC6, 0xE6, 0xF6, 0x76, 0xFC, 0xF8, /*0x00,*/ /*0x00, 0x00,*/ 0x1F, 0x3F, 0x77, 0x67, 0x63, 0x61, 0x60, 0x70, 0x3F, 0x1F, /*0x00*/},
{/*0x00, 0x00,*/ 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x60, 0x60, 0x00, 0x00, /*0x00*/},
{/*0x00, 0x00,*/ 0x18, 0x1C, 0x86, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x7E, 0x7F, 0x63, 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x60, /*0x00*/},
{/*0x00, 0x00,*/ 0x18, 0x1C, 0x06, 0x06, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x70, 0x60, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/},
{/*0x00, 0x00,*/ 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0xFE, 0xFE, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x7F, 0x7F, 0x06, 0x06, /*0x00*/},
{/*0x00, 0x00,*/ 0x7E, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x66, 0xE6, 0xC6, 0x86, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x70, 0x60, 0x60, 0x60, 0x60, 0x70, 0x3F, 0x1F, /*0x00*/},
{/*0x00, 0x00,*/ 0xF8, 0xFC, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x1C, 0x18, /*0x00,*/ /*0x00, 0x00,*/ 0x1F, 0x3F, 0x71, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/},
{/*0x00, 0x00,*/ 0x06, 0x06, 0x06, 0x06, 0x06, 0x86, 0xC6, 0xE6, 0x7E, 0x3E, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x01, 0x00, 0x00, 0x00, /*0x00*/},
{/*0x00, 0x00,*/ 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0xC6, 0xFC, 0x78, /*0x00,*/ /*0x00, 0x00,*/ 0x1E, 0x3F, 0x73, 0x61, 0x61, 0x61, 0x61, 0x73, 0x3F, 0x1E, /*0x00*/},
{/*0x00, 0x00,*/ 0x78, 0xFC, 0xC6, 0x86, 0x86, 0x86, 0x86, 0x86, 0xFC, 0xF8, /*0x00,*/ /*0x00, 0x00,*/ 0x18, 0x38, 0x71, 0x61, 0x61, 0x61, 0x61, 0x71, 0x3F, 0x1F, /*0x00*/},
{/*0x00, 0x00,*/ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, /*0x00*/}
};
#else
// Terminus font
const uint8_t gFontBigDigits[11][26] =
const uint8_t gFontBigDigits[11][26 - 6] =
{
{0x00, 0x00, 0xFC, 0xFE, 0xFE, 0x06, 0x86, 0xC6, 0xE6, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x7F, 0x67, 0x63, 0x61, 0x60, 0x7F, 0x7F, 0x3F, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x7F, 0x60, 0x60, 0x00, 0x00},
{0x00, 0x00, 0x1C, 0x1E, 0x1E, 0x06, 0x06, 0x06, 0x86, 0xFE, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x60, 0x70, 0x78, 0x7C, 0x6E, 0x67, 0x63, 0x61, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x0C, 0x0E, 0x0E, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x30, 0x70, 0x70, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3E, 0x00},
{0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x7F, 0x7F, 0x7F, 0x00},
{0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x30, 0x70, 0x70, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, 0x00},
{0x00, 0x00, 0xF8, 0xFC, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x80, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, 0x00},
{0x00, 0x00, 0x0E, 0x0E, 0x0E, 0x06, 0x06, 0x86, 0xE6, 0xFE, 0x7E, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7F, 0x7F, 0x03, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7C, 0xFE, 0xFE, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x7F, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3F, 0x00},
{0x00, 0x00, 0xFC, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x01, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7F, 0x3F, 0x1F, 0x00},
{0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}
{/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x86, 0xC6, 0xE6, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x67, 0x63, 0x61, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/},
{/*0x00, 0x00,*/ 0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x60, 0x60, 0x7F, 0x7F, 0x7F, 0x60, 0x60, 0x00, /*0x00*/},
{/*0x00, 0x00,*/ 0x1C, 0x1E, 0x1E, 0x06, 0x06, 0x06, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x60, 0x70, 0x78, 0x7C, 0x6E, 0x67, 0x63, 0x61, 0x60, 0x60, /*0x00*/},
{/*0x00, 0x00,*/ 0x0C, 0x0E, 0x0E, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3E, /*0x00*/},
{/*0x00, 0x00,*/ 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0xFE, 0xFE, 0xFE, /*0x00,*/ /*0x00, 0x00,*/ 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x7F, 0x7F, 0x7F, /*0x00*/},
{/*0x00, 0x00,*/ 0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x86, /*0x00,*/ /*0x00, 0x00,*/ 0x30, 0x70, 0x70, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/},
{/*0x00, 0x00,*/ 0xF8, 0xFC, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x80, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x7F, 0x3F, /*0x00*/},
{/*0x00, 0x00,*/ 0x0E, 0x0E, 0x0E, 0x06, 0x06, 0x86, 0xE6, 0xFE, 0x7E, 0x1E, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7F, 0x7F, 0x03, 0x00, 0x00, /*0x00*/},
{/*0x00, 0x00,*/ 0x7C, 0xFE, 0xFE, 0x86, 0x86, 0x86, 0x86, 0xFE, 0xFE, 0x7C, /*0x00,*/ /*0x00, 0x00,*/ 0x3F, 0x7F, 0x7F, 0x61, 0x61, 0x61, 0x61, 0x7F, 0x7F, 0x3F, /*0x00*/},
{/*0x00, 0x00,*/ 0xFC, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFC, /*0x00,*/ /*0x00, 0x00,*/ 0x01, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7F, 0x3F, 0x1F, /*0x00*/},
{/*0x00, 0x00,*/ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, /*0x00,*/ /*0x00, 0x00,*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, /*0x00*/}
};
#endif
/*
@@ -279,9 +283,9 @@ const uint8_t gFontSmallDigits[11][7] =
{0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00} // '-'
};
*/
const uint8_t gFontSmall[95][6] =
const uint8_t gFontSmall[95-1][6] =
{
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' '
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' '
{0x00, 0x00, 0x5E, 0x00, 0x00, 0x00}, // '!'
{0x00, 0x06, 0x00, 0x06, 0x00, 0x00}, // '"'
{0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00}, // '#'
@@ -379,9 +383,9 @@ const uint8_t gFontSmall[95][6] =
};
#ifdef ENABLE_SMALL_BOLD
const uint8_t gFontSmallBold[95][6] =
const uint8_t gFontSmallBold[95 - 1][6] =
{
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
// {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x5E, 0x5E, 0x00, 0x00},
{0x06, 0x06, 0x00, 0x06, 0x06, 0x00},
{0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00},
@@ -480,7 +484,7 @@ const uint8_t gFontSmall[95][6] =
#endif
#ifdef ENABLE_SPECTRUM
const uint8_t gFont3x5[160][3] =
const uint8_t gFont3x5[][3] =
{
{0x00, 0x00, 0x00}, // 32 - space
{0x00, 0x17, 0x00}, // 33 - exclam
@@ -577,70 +581,74 @@ const uint8_t gFontSmall[95][6] =
{0x00, 0x1b, 0x00}, // 124 - bar
{0x11, 0x1b, 0x04}, // 125 - braceright
{0x02, 0x03, 0x01}, // 126 - asciitilde
{0x00, 0x00, 0x00}, // 127 - empty
{0x00, 0x00, 0x00}, // 128 - empty
{0x00, 0x00, 0x00}, // 129 - empty
{0x00, 0x00, 0x00}, // 130 - empty
{0x00, 0x00, 0x00}, // 131 - empty
{0x00, 0x00, 0x00}, // 132 - empty
{0x00, 0x00, 0x00}, // 133 - empty
{0x00, 0x00, 0x00}, // 134 - empty
{0x00, 0x00, 0x00}, // 135 - empty
{0x00, 0x00, 0x00}, // 136 - empty
{0x00, 0x00, 0x00}, // 137 - empty
{0x00, 0x00, 0x00}, // 138 - empty
{0x00, 0x00, 0x00}, // 139 - empty
{0x00, 0x00, 0x00}, // 140 - empty
{0x00, 0x00, 0x00}, // 141 - empty
{0x00, 0x00, 0x00}, // 142 - empty
{0x00, 0x00, 0x00}, // 143 - empty
{0x00, 0x00, 0x00}, // 144 - empty
{0x00, 0x00, 0x00}, // 145 - empty
{0x00, 0x00, 0x00}, // 146 - empty
{0x00, 0x00, 0x00}, // 147 - empty
{0x00, 0x00, 0x00}, // 148 - empty
{0x00, 0x00, 0x00}, // 149 - empty
{0x00, 0x00, 0x00}, // 150 - empty
{0x00, 0x00, 0x00}, // 151 - empty
{0x00, 0x00, 0x00}, // 152 - empty
{0x00, 0x00, 0x00}, // 153 - empty
{0x00, 0x00, 0x00}, // 154 - empty
{0x00, 0x00, 0x00}, // 155 - empty
{0x00, 0x00, 0x00}, // 156 - empty
{0x00, 0x00, 0x00}, // 157 - empty
{0x00, 0x00, 0x00}, // 158 - empty
{0x00, 0x00, 0x00}, // 159 - empty
{0x00, 0x00, 0x00}, // 160 - empty
{0x00, 0x1d, 0x00}, // 161 - exclamdown
{0x0e, 0x1b, 0x0a}, // 162 - cent
{0x14, 0x1f, 0x15}, // 163 - sterling
{0x15, 0x0e, 0x15}, // 164 - currency
{0x0b, 0x1c, 0x0b}, // 165 - yen
{0x00, 0x1b, 0x00}, // 166 - brokenbar
{0x14, 0x1b, 0x05}, // 167 - section
{0x01, 0x00, 0x01}, // 168 - dieresis
{0x02, 0x05, 0x05}, // 169 - copyright
{0x16, 0x15, 0x17}, // 170 - ordfeminine
{0x02, 0x05, 0x00}, // 171 - guillemotleft
{0x02, 0x02, 0x06}, // 172 - logicalnot
{0x04, 0x04, 0x00}, // 173 - softhyphen
{0x07, 0x03, 0x04}, // 174 - registered
{0x01, 0x01, 0x01}, // 175 - macron
{0x02, 0x05, 0x02}, // 176 - degree
{0x12, 0x17, 0x12}, // 177 - plusminus
{0x01, 0x07, 0x04}, // 178 - twosuperior
{0x05, 0x07, 0x07}, // 179 - threesuperior
{0x00, 0x02, 0x01}, // 180 - acute
{0x1f, 0x08, 0x07}, // 181 - mu
{0x02, 0x1d, 0x1f}, // 182 - paragraph
{0x0e, 0x0e, 0x0e}, // 183 - periodcentered
{0x10, 0x14, 0x08}, // 184 - cedilla
{0x00, 0x07, 0x00}, // 185 - onesuperior
{0x12, 0x15, 0x12}, // 186 - ordmasculine
{0x00, 0x05, 0x02}, // 187 - guillemotright
{0x03, 0x08, 0x18}, // 188 - onequarter
{0x0b, 0x18, 0x10}, // 189 - onehalf
{0x03, 0x0b, 0x18}, // 190 - threequarters
{0x18, 0x15, 0x10}, // 191 - questiondown
{0x12, 0x17, 0x12}, // 127 - plusminus
// {0x00, 0x00, 0x00}, // 127 - empty
// {0x00, 0x00, 0x00}, // 128 - empty
// {0x00, 0x00, 0x00}, // 129 - empty
// {0x00, 0x00, 0x00}, // 130 - empty
// {0x00, 0x00, 0x00}, // 131 - empty
// {0x00, 0x00, 0x00}, // 132 - empty
// {0x00, 0x00, 0x00}, // 133 - empty
// {0x00, 0x00, 0x00}, // 134 - empty
// {0x00, 0x00, 0x00}, // 135 - empty
// {0x00, 0x00, 0x00}, // 136 - empty
// {0x00, 0x00, 0x00}, // 137 - empty
// {0x00, 0x00, 0x00}, // 138 - empty
// {0x00, 0x00, 0x00}, // 139 - empty
// {0x00, 0x00, 0x00}, // 140 - empty
// {0x00, 0x00, 0x00}, // 141 - empty
// {0x00, 0x00, 0x00}, // 142 - empty
// {0x00, 0x00, 0x00}, // 143 - empty
// {0x00, 0x00, 0x00}, // 144 - empty
// {0x00, 0x00, 0x00}, // 145 - empty
// {0x00, 0x00, 0x00}, // 146 - empty
// {0x00, 0x00, 0x00}, // 147 - empty
// {0x00, 0x00, 0x00}, // 148 - empty
// {0x00, 0x00, 0x00}, // 149 - empty
// {0x00, 0x00, 0x00}, // 150 - empty
// {0x00, 0x00, 0x00}, // 151 - empty
// {0x00, 0x00, 0x00}, // 152 - empty
// {0x00, 0x00, 0x00}, // 153 - empty
// {0x00, 0x00, 0x00}, // 154 - empty
// {0x00, 0x00, 0x00}, // 155 - empty
// {0x00, 0x00, 0x00}, // 156 - empty
// {0x00, 0x00, 0x00}, // 157 - empty
// {0x00, 0x00, 0x00}, // 158 - empty
// {0x00, 0x00, 0x00}, // 159 - empty
// {0x00, 0x00, 0x00}, // 160 - empty
// {0x00, 0x1d, 0x00}, // 161 - exclamdown
// {0x0e, 0x1b, 0x0a}, // 162 - cent
// {0x14, 0x1f, 0x15}, // 163 - sterling
// {0x15, 0x0e, 0x15}, // 164 - currency
// {0x0b, 0x1c, 0x0b}, // 165 - yen
// {0x00, 0x1b, 0x00}, // 166 - brokenbar
// {0x14, 0x1b, 0x05}, // 167 - section
// {0x01, 0x00, 0x01}, // 168 - dieresis
// {0x02, 0x05, 0x05}, // 169 - copyright
// {0x16, 0x15, 0x17}, // 170 - ordfeminine
// {0x02, 0x05, 0x00}, // 171 - guillemotleft
// {0x02, 0x02, 0x06}, // 172 - logicalnot
// {0x04, 0x04, 0x00}, // 173 - softhyphen
// {0x07, 0x03, 0x04}, // 174 - registered
// {0x01, 0x01, 0x01}, // 175 - macron
// {0x02, 0x05, 0x02}, // 176 - degree
// {0x12, 0x17, 0x12}, // 177 - plusminus
// {0x01, 0x07, 0x04}, // 178 - twosuperior
// {0x05, 0x07, 0x07}, // 179 - threesuperior
// {0x00, 0x02, 0x01}, // 180 - acute
// {0x1f, 0x08, 0x07}, // 181 - mu
// {0x02, 0x1d, 0x1f}, // 182 - paragraph
// {0x0e, 0x0e, 0x0e}, // 183 - periodcentered
// {0x10, 0x14, 0x08}, // 184 - cedilla
// {0x00, 0x07, 0x00}, // 185 - onesuperior
// {0x12, 0x15, 0x12}, // 186 - ordmasculine
// {0x00, 0x05, 0x02}, // 187 - guillemotright
// {0x03, 0x08, 0x18}, // 188 - onequarter
// {0x0b, 0x18, 0x10}, // 189 - onehalf
// {0x03, 0x0b, 0x18}, // 190 - threequarters
// {0x18, 0x15, 0x10}, // 191 - questiondown
};
#endif

13
font.h
View File

@@ -19,14 +19,13 @@
#include <stdint.h>
//extern const uint8_t gFontBig[95][16];
extern const uint8_t gFontBig[95][15];
extern const uint8_t gFontBigDigits[11][26];
//extern const uint8_t gFontSmallDigits[11][7];
extern const uint8_t gFont3x5[160][3];
extern const uint8_t gFontSmall[95][6];
extern const uint8_t gFontBig[95 - 1][16 - 2];
extern const uint8_t gFontBigDigits[11][26 - 6];
extern const uint8_t gFont3x5[96][3];
extern const uint8_t gFontSmall[95 - 1][6];
#ifdef ENABLE_SMALL_BOLD
extern const uint8_t gFontSmallBold[95][6];
extern const uint8_t gFontSmallBold[95 - 1][6];
#endif
#endif

View File

@@ -26,22 +26,22 @@ const freq_band_table_t frequencyBandTable[7] =
{
#ifndef ENABLE_WIDE_RX
// QS original
{ 5000000, 7600000},
{10800000, 13600000},
{13600000, 17400000},
{17400000, 35000000},
{35000000, 40000000},
{40000000, 47000000},
{47000000, 60000000}
{.lower = 5000000, .upper = 7600000},
{.lower = 10800000, .upper = 13700000},
{.lower = 13700000, .upper = 17400000},
{.lower = 17400000, .upper = 35000000},
{.lower = 35000000, .upper = 40000000},
{.lower = 40000000, .upper = 47000000},
{.lower = 47000000, .upper = 60000000}
#else
// extended range
{ 1800000, 10800000},
{10800000, 13600000},
{13600000, 17400000},
{17400000, 35000000},
{35000000, 40000000},
{40000000, 47000000},
{47000000, 130000000}
{.lower = BX4819_band1.lower, .upper = 10800000},
{.lower = 10800000, .upper = 13700000},
{.lower = 13700000, .upper = 17400000},
{.lower = 17400000, .upper = 35000000},
{.lower = 35000000, .upper = 40000000},
{.lower = 40000000, .upper = 47000000},
{.lower = 47000000, .upper = BX4819_band2.upper}
#endif
};
@@ -100,25 +100,21 @@ uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t T
return TxpMid;
}
uint32_t FREQUENCY_FloorToStep(uint32_t Upper, uint32_t Step, uint32_t Lower)
static int32_t rnd(int32_t freq, uint16_t step)
{
uint32_t Index;
return (freq + (step + 1) / 2) / step * step;
}
if (Step == 833)
{
const uint32_t Delta = Upper - Lower;
uint32_t Base = (Delta / 2500) * 2500;
const uint32_t Index = ((Delta - Base) % 2500) / 833;
if (Index == 2)
Base++;
return Lower + Base + (Index * 833);
uint32_t FREQUENCY_RoundToStep(uint32_t freq, uint16_t step)
{
if(step == 833) {
uint32_t base = freq/2500*2500;
int f = rnd(freq - base, step);
int x = f / step;
return base + f + (x == 3);
}
Index = (Upper - Lower) / Step;
return Lower + (Step * Index);
return rnd(freq, step);
}
int TX_freq_check(const uint32_t Frequency)
@@ -134,17 +130,17 @@ int TX_freq_check(const uint32_t Frequency)
switch (gSetting_F_LOCK)
{
case F_LOCK_OFF:
if (Frequency >= 13600000 && Frequency < 17400000)
if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < frequencyBandTable[BAND3_137MHz].upper)
return 0;
if (Frequency >= 17400000 && Frequency < 35000000)
if (Frequency >= frequencyBandTable[BAND4_174MHz].lower && Frequency < frequencyBandTable[BAND4_174MHz].upper)
if (gSetting_200TX)
return 0;
if (Frequency >= 35000000 && Frequency < 40000000)
if (Frequency >= frequencyBandTable[BAND5_350MHz].lower && Frequency < frequencyBandTable[BAND5_350MHz].upper)
if (gSetting_350TX && gSetting_350EN)
return 0;
if (Frequency >= 40000000 && Frequency < 47000000)
if (Frequency >= frequencyBandTable[BAND6_400MHz].lower && Frequency < frequencyBandTable[BAND6_400MHz].upper)
return 0;
if (Frequency >= 47000000 && Frequency <= 60000000)
if (Frequency >= frequencyBandTable[BAND7_470MHz].lower && Frequency <= 60000000)
if (gSetting_500TX)
return 0;
break;
@@ -171,14 +167,14 @@ int TX_freq_check(const uint32_t Frequency)
break;
case F_LOCK_430:
if (Frequency >= 13600000 && Frequency < 17400000)
if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000)
return 0;
if (Frequency >= 40000000 && Frequency < 43000000)
return 0;
break;
case F_LOCK_438:
if (Frequency >= 13600000 && Frequency < 17400000)
if (Frequency >= frequencyBandTable[BAND3_137MHz].lower && Frequency < 17400000)
return 0;
if (Frequency >= 40000000 && Frequency < 43800000)
return 0;

View File

@@ -35,7 +35,7 @@ enum FREQUENCY_Band_t {
BAND_NONE = -1,
BAND1_50MHz = 0,
BAND2_108MHz,
BAND3_136MHz,
BAND3_137MHz,
BAND4_174MHz,
BAND5_350MHz,
BAND6_400MHz,
@@ -76,7 +76,7 @@ extern const uint16_t StepFrequencyTable[7];
FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency);
uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, int32_t LowerLimit, int32_t Middle, int32_t UpperLimit, int32_t Frequency);
uint32_t FREQUENCY_FloorToStep(uint32_t Upper, uint32_t Step, uint32_t Lower);
uint32_t FREQUENCY_RoundToStep(uint32_t freq, uint16_t step);
int TX_freq_check(const uint32_t Frequency);
int RX_freq_check(const uint32_t Frequency);

View File

@@ -43,7 +43,7 @@ FUNCTION_Type_t gCurrentFunction;
void FUNCTION_Init(void)
{
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif
{
gCurrentCodeType = gSelectedCodeType;
@@ -93,7 +93,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
{
BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable();
gRxIdleMode = false;
UI_DisplayStatus(false);
UI_DisplayStatus();
}
switch (Function)
@@ -145,7 +145,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
BK4819_DisableVox();
BK4819_Sleep();
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, false);
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false);
gUpdateStatus = true;
@@ -179,13 +179,13 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
GUI_DisplayScreen();
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
SYSTEM_DelayMs(20);
BK4819_PlayTone(500, 0);
SYSTEM_DelayMs(2);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
gEnableSpeaker = true;
@@ -204,7 +204,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
RADIO_SetTxParameters();
// turn the RED LED on
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, true);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, true);
DTMF_Reply();
@@ -223,7 +223,7 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
BK4819_TransmitTone(true, 500);
#endif
SYSTEM_DelayMs(2);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
#ifdef ENABLE_ALARM
gAlarmToneCounter = 0;
#endif
@@ -237,7 +237,8 @@ void FUNCTION_Select(FUNCTION_Type_t Function)
else
BK4819_DisableScramble();
if (gSetting_backlight_on_tx_rx == 1 || gSetting_backlight_on_tx_rx == 3)
if (gSetting_backlight_on_tx_rx == BACKLIGHT_ON_TR_TX ||
gSetting_backlight_on_tx_rx == BACKLIGHT_ON_TR_TXRX)
BACKLIGHT_TurnOn();
break;

View File

@@ -17,6 +17,7 @@
#include "battery.h"
#include "driver/backlight.h"
#include "misc.h"
#include "settings.h"
#include "ui/battery.h"
#include "ui/menu.h"
#include "ui/ui.h"
@@ -34,48 +35,47 @@ uint16_t gBatteryCheckCounter;
volatile uint16_t gPowerSave_10ms;
/*
Based on real measurement
Volts Percent Volts Percent Volts Percent Volts Percent
8.28 100 7.95099 73 7.7184 46 7.48116 19
8.22 99 7.94188 72 7.71091 45 7.46364 18
8.17 98 7.9338 71 7.70911 44 7.44789 17
8.13632 97 7.92684 70 7.70098 43 7.43318 16
8.12308 96 7.9178 69 7.69619 42 7.41864 15
8.09688 95 7.90823 68 7.69018 41 7.40579 14
8.08124 94 7.89858 67 7.68473 40 7.39289 13
8.06912 93 7.88667 66 7.67911 39 7.37839 12
8.05826 92 7.87673 65 7.67087 38 7.36017 11
8.05008 91 7.86864 64 7.66601 37 7.33704 10
8.04192 90 7.85802 63 7.6599 36 7.3079 9
8.03866 89 7.84816 62 7.65418 35 7.26793 8
8.03089 88 7.83744 61 7.64775 34 7.21291 7
8.0284 87 7.82748 60 7.64065 33 7.13416 6
8.02044 86 7.81983 59 7.63136 32 7.02785 5
8.01832 85 7.80929 58 7.6244 31 6.89448 4
8.01072 84 7.79955 57 7.61636 30 6.72912 3
8.00965 83 7.79017 56 7.60738 29 6.5164 2
8.00333 82 7.78107 55 7.597 28 6.19272 1
7.99973 81 7.77167 54 7.5876 27 5.63138 0
7.99218 80 7.76509 53 7.57732 26
7.98999 79 7.75649 52 7.56563 25
7.98234 78 7.74939 51 7.55356 24
7.97892 77 7.7411 50 7.54088 23
7.97043 76 7.73648 49 7.52683 22
7.96478 75 7.72911 48 7.51285 21
7.95983 74 7.72097 47 7.49832 20
*/
unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV)
{
if (voltage_10mV > 814)
return 100;
if (voltage_10mV > 756)
return ((132ul * voltage_10mV) / 100) - 974u;
if (voltage_10mV > 729)
return ((63ul * voltage_10mV) / 100) - 452u;
if (voltage_10mV > 600)
return ((52ul * voltage_10mV) / 1000) - 31u;
const uint16_t crv1600[][2] = {
{814, 100},
{756, 24 },
{729, 7 },
{597, 0 },
{0, 0}
};
const uint16_t crv2200[][2] = {
{823, 100},
{740, 60},
{707, 21},
{680, 5},
{505, 0},
{0, 0}
};
const BATTERY_Type_t type = gEeprom.BATTERY_TYPE;
const uint16_t(*crv)[2];
uint8_t size;
if (type == BATTERY_TYPE_2200_MAH) {
crv = crv2200;
size = ARRAY_SIZE(crv2200);
}
else {
crv = crv1600;
size = ARRAY_SIZE(crv1600);
}
const int mulipl = 1000;
for (int i = 1; i < size; i++) {
if (voltage_10mV > crv[i][0]) {
int a = (crv[i - 1][1] - crv[i][1]) * mulipl / (crv[i - 1][0] - crv[i][0]);
int b = crv[i][1] - a * crv[i][0] / mulipl;
int p = a * voltage_10mV / mulipl + b;
return MIN(p, 100);
}
}
return 0;
}
@@ -86,27 +86,16 @@ void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
gBatteryDisplayLevel = 0;
if (gBatteryCalibration[5] < Voltage)
gBatteryDisplayLevel = 6;
else
if (gBatteryCalibration[4] < Voltage)
gBatteryDisplayLevel = 5;
else
if (gBatteryCalibration[3] < Voltage)
gBatteryDisplayLevel = 4;
else
if (gBatteryCalibration[2] < Voltage)
gBatteryDisplayLevel = 3;
else
if (gBatteryCalibration[1] < Voltage)
gBatteryDisplayLevel = 2;
else
if (gBatteryCalibration[0] < Voltage)
gBatteryDisplayLevel = 1;
for(uint8_t i = 6; i > 0; i--){
if (Voltage > gBatteryCalibration[i-1]) {
gBatteryDisplayLevel = i;
break;
}
}
gBatteryVoltageAverage = (Voltage * 760) / gBatteryCalibration[3];
if ((gScreenToDisplay == DISPLAY_MENU) && gMenuCursor == MENU_VOL)
if ((gScreenToDisplay == DISPLAY_MENU) && GetCurrentMenuId() == MENU_VOL)
gUpdateDisplay = true;
if (gBatteryCurrent < 501)

View File

@@ -33,6 +33,12 @@ extern uint16_t gBatteryCheckCounter;
extern volatile uint16_t gPowerSave_10ms;
typedef enum {
BATTERY_TYPE_1600_MAH,
BATTERY_TYPE_2200_MAH,
BATTERY_TYPE_UNKNOWN
} BATTERY_Type_t;
unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV);
void BATTERY_GetReadings(const bool bDisplayBatteryLevel);

View File

@@ -84,6 +84,7 @@ void BOOT_ProcessMode(BOOT_Mode_t Mode)
gEeprom.KEY_1_LONG_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_2_SHORT_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_2_LONG_PRESS_ACTION = ACTION_OPT_NONE;
gEeprom.KEY_M_LONG_PRESS_ACTION = ACTION_OPT_NONE;
RADIO_InitInfo(gRxVfo, FREQ_CHANNEL_LAST - 1, 41002500);

67
main.c
View File

@@ -61,7 +61,8 @@ void Main(void)
| SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE
| SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE
| SYSCON_DEV_CLK_GATE_CRC_BITS_ENABLE
| SYSCON_DEV_CLK_GATE_AES_BITS_ENABLE;
| SYSCON_DEV_CLK_GATE_AES_BITS_ENABLE
| SYSCON_DEV_CLK_GATE_PWM_PLUS0_BITS_ENABLE;
SYSTICK_Init();
BOARD_Init();
@@ -84,7 +85,7 @@ void Main(void)
BOARD_EEPROM_Init();
BOARD_EEPROM_LoadMoreSettings();
BOARD_EEPROM_LoadCalibration();
RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD);
RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD);
@@ -103,26 +104,21 @@ void Main(void)
#endif
BootMode = BOOT_GetMode();
// count the number of menu items
gMenuListCount = 0;
while (MenuList[gMenuListCount].name[0] != '\0')
gMenuListCount++;
if (BootMode == BOOT_MODE_F_LOCK)
{
gF_LOCK = true; // flag to say include the hidden menu items
}
else
{ // hide the hidden menu items
gMenuListCount -= 9;
// count the number of menu items
gMenuListCount = 0;
while (MenuList[gMenuListCount].name[0] != '\0') {
if(!gF_LOCK && MenuList[gMenuListCount].menu_id == FIRST_HIDDEN_MENU_ITEM)
break;
#ifndef ENABLE_F_CAL_MENU
gMenuListCount++;
#endif
gMenuListCount++;
}
// wait for user to release all butts before moving on
if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) ||
KEYBOARD_Poll() != KEY_INVALID ||
@@ -145,10 +141,10 @@ void Main(void)
{
FUNCTION_Select(FUNCTION_POWER_SAVE);
if (gEeprom.BACKLIGHT < (ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1))
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight OFF
if (gEeprom.BACKLIGHT_TIME < (ARRAY_SIZE(gSubMenu_BACKLIGHT) - 1)) // backlight is not set to be always on
BACKLIGHT_TurnOff(); // turn the backlight OFF
else
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); // turn the backlight ON
BACKLIGHT_TurnOn(); // turn the backlight ON
gReducedService = true;
}
@@ -167,21 +163,21 @@ void Main(void)
boot_counter_10ms = 0;
break;
}
#ifdef ENABLE_BOOT_BEEPS
if ((boot_counter_10ms % 25) == 0)
AUDIO_PlayBeep(BEEP_880HZ_40MS_OPTIONAL);
#endif
#ifdef ENABLE_BOOT_BEEPS
if ((boot_counter_10ms % 25) == 0)
AUDIO_PlayBeep(BEEP_880HZ_40MS_OPTIONAL);
#endif
}
}
#ifdef ENABLE_PWRON_PASSWORD
if (gEeprom.POWER_ON_PASSWORD < 1000000)
{
bIsInLockScreen = true;
UI_DisplayLock();
bIsInLockScreen = false;
}
#endif
#ifdef ENABLE_PWRON_PASSWORD
if (gEeprom.POWER_ON_PASSWORD < 1000000)
{
bIsInLockScreen = true;
UI_DisplayLock();
bIsInLockScreen = false;
}
#endif
BOOT_ProcessMode(BootMode);
@@ -189,7 +185,7 @@ void Main(void)
gUpdateStatus = true;
#ifdef ENABLE_VOICE
#ifdef ENABLE_VOICE
{
uint8_t Channel;
@@ -201,17 +197,16 @@ void Main(void)
AUDIO_SetVoiceID(1, VOICE_ID_CHANNEL_MODE);
AUDIO_SetDigitVoice(2, Channel + 1);
}
else
if (IS_FREQ_CHANNEL(Channel))
else if (IS_FREQ_CHANNEL(Channel))
AUDIO_SetVoiceID(1, VOICE_ID_FREQUENCY_MODE);
AUDIO_PlaySingleVoice(0);
}
#endif
#endif
#ifdef ENABLE_NOAA
RADIO_ConfigureNOAA();
#endif
#ifdef ENABLE_NOAA
RADIO_ConfigureNOAA();
#endif
// ******************
}

91
misc.c
View File

@@ -19,12 +19,13 @@
#include "misc.h"
#include "settings.h"
const uint8_t fm_resume_countdown_500ms = 2500 / 500; // 2.5 seconds
const uint8_t fm_radio_countdown_500ms = 2000 / 500; // 2 seconds
const uint16_t fm_play_countdown_scan_10ms = 100 / 10; // 100ms
const uint16_t fm_play_countdown_noscan_10ms = 1200 / 10; // 1.2 seconds
const uint16_t fm_restore_countdown_10ms = 5000 / 10; // 5 seconds
const uint8_t vfo_state_resume_countdown_500ms = 2500 / 500; // 2.5 seconds
const uint8_t menu_timeout_500ms = 20000 / 500; // 20 seconds
const uint16_t menu_timeout_long_500ms = 120000 / 500; // 2 minutes
@@ -72,9 +73,6 @@ const uint16_t NOAA_countdown_10ms = 5000 / 10; // 5 seconds
const uint16_t NOAA_countdown_2_10ms = 500 / 10; // 500ms
const uint16_t NOAA_countdown_3_10ms = 200 / 10; // 200ms
//const uint16_t gMax_bat_v = 840; // 8.4V
//const uint16_t gMin_bat_v = 660; // 6.6V
const uint32_t gDefaultAesKey[4] = {0x4AA5CC60, 0x0312CC5F, 0xFFD2DABB, 0x6BBA7F92};
const uint8_t gMicGain_dB2[5] = {3, 8, 16, 24, 31};
@@ -109,12 +107,7 @@ bool bHasCustomAesKey;
uint32_t gChallenge[4];
uint8_t gTryCount;
uint8_t gEEPROM_1EC0_0[8];
uint8_t gEEPROM_1EC0_1[8];
uint8_t gEEPROM_1EC0_2[8];
uint8_t gEEPROM_1EC0_3[8];
uint16_t gEEPROM_RSSI_CALIB[2][4];
uint16_t gEEPROM_RSSI_CALIB[7][4];
uint16_t gEEPROM_1F8A;
uint16_t gEEPROM_1F8C;
@@ -129,7 +122,6 @@ volatile bool gSchedulePowerSave;
volatile bool gScheduleDualWatch = true;
volatile uint16_t gDualWatchCountdown_10ms;
volatile bool gDualWatchCountdownExpired = true;
bool gDualWatchActive = false;
volatile uint8_t gSerialConfigCountDown_500ms;
@@ -141,6 +133,8 @@ volatile bool gTxTimeoutReached;
volatile uint16_t gTailNoteEliminationCountdown_10ms;
volatile uint8_t gVFOStateResumeCountdown_500ms;
#ifdef ENABLE_NOAA
volatile uint16_t gNOAA_Countdown_10ms;
#endif
@@ -207,10 +201,6 @@ uint16_t gLowBatteryCountdown;
uint8_t gNextMrChannel;
ReceptionMode_t gRxReceptionMode;
uint8_t gRestoreMrChannel;
enum scan_next_chan_t gCurrentScanList;
uint32_t gRestoreFrequency;
bool gRxVfoIsActive;
#ifdef ENABLE_ALARM
uint8_t gAlarmToneCounter;
@@ -260,66 +250,7 @@ int16_t gCurrentRSSI[2] = {0, 0}; // now one per VFO
uint8_t gIsLocked = 0xFF;
unsigned int get_rx_VFO(void)
{
unsigned int rx_vfo = gEeprom.TX_VFO;
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_B)
rx_vfo = 0;
else
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_A)
rx_vfo = 1;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B)
rx_vfo = 1;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A)
rx_vfo = 0;
return rx_vfo;
}
unsigned int get_tx_VFO(void)
{
unsigned int tx_vfo = gEeprom.TX_VFO;
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_B)
tx_vfo = 1;
else
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_A)
tx_vfo = 0;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B)
tx_vfo = 1;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A)
tx_vfo = 0;
return tx_vfo;
}
void NUMBER_Get(char *pDigits, uint32_t *pInteger)
{
unsigned int i;
uint32_t Multiplier = 10000000;
uint32_t Value = 0;
for (i = 0; i < 8; i++)
{
if (pDigits[i] > 9)
break;
Value += pDigits[i] * Multiplier;
Multiplier /= 10U;
}
*pInteger = Value;
}
void NUMBER_ToDigits(uint32_t Value, char *pDigits)
{
unsigned int i;
for (i = 0; i < 8; i++)
{
const uint32_t Result = Value / 10U;
pDigits[7 - i] = Value - (Result * 10U);
Value = Result;
}
pDigits[8] = 0;
}
int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit)
{
@@ -333,3 +264,15 @@ int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit,
return Base;
}
unsigned long StrToUL(const char * str)
{
unsigned long ul = 0;
for(uint8_t i = 0; i < strlen(str); i++){
char c = str[i];
if(c < '0' || c > '9')
break;
ul = ul * 10 + (uint8_t)(c-'0');
}
return ul;
}

48
misc.h
View File

@@ -32,12 +32,10 @@
#define MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
#endif
#define IS_MR_CHANNEL(x) ((x) >= MR_CHANNEL_FIRST && (x) <= MR_CHANNEL_LAST)
#define IS_MR_CHANNEL(x) ((x) <= MR_CHANNEL_LAST)
#define IS_FREQ_CHANNEL(x) ((x) >= FREQ_CHANNEL_FIRST && (x) <= FREQ_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)
enum {
MR_CHANNEL_FIRST = 0,
@@ -52,7 +50,8 @@ enum {
enum {
FLASHLIGHT_OFF = 0,
FLASHLIGHT_ON,
FLASHLIGHT_BLINK
FLASHLIGHT_BLINK,
FLASHLIGHT_SOS
};
enum {
@@ -84,21 +83,20 @@ enum CssScanMode_t
};
typedef enum CssScanMode_t CssScanMode_t;
enum scan_next_chan_t {
SCAN_NEXT_CHAN_SCANLIST1 = 0,
SCAN_NEXT_CHAN_SCANLIST2,
SCAN_NEXT_CHAN_DUAL_WATCH,
SCAN_NEXT_CHAN_MR,
SCAN_NEXT_NUM
enum BacklightOnRxTx_t {
BACKLIGHT_ON_TR_OFF,
BACKLIGHT_ON_TR_TX,
BACKLIGHT_ON_TR_RX,
BACKLIGHT_ON_TR_TXRX
};
typedef enum scan_next_chan_t scan_next_chan_t;
extern const uint8_t fm_resume_countdown_500ms;
extern const uint8_t fm_radio_countdown_500ms;
extern const uint16_t fm_play_countdown_scan_10ms;
extern const uint16_t fm_play_countdown_noscan_10ms;
extern const uint16_t fm_restore_countdown_10ms;
extern const uint8_t vfo_state_resume_countdown_500ms;
extern const uint8_t menu_timeout_500ms;
extern const uint16_t menu_timeout_long_500ms;
@@ -182,12 +180,7 @@ extern bool bHasCustomAesKey;
extern uint32_t gChallenge[4];
extern uint8_t gTryCount;
extern uint8_t gEEPROM_1EC0_0[8];
extern uint8_t gEEPROM_1EC0_1[8];
extern uint8_t gEEPROM_1EC0_2[8];
extern uint8_t gEEPROM_1EC0_3[8];
extern uint16_t gEEPROM_RSSI_CALIB[2][4];
extern uint16_t gEEPROM_RSSI_CALIB[7][4];
extern uint16_t gEEPROM_1F8A;
extern uint16_t gEEPROM_1F8C;
@@ -202,7 +195,6 @@ extern volatile bool gSchedulePowerSave;
extern volatile bool gScheduleDualWatch;
extern volatile uint16_t gDualWatchCountdown_10ms;
extern volatile bool gDualWatchCountdownExpired;
extern bool gDualWatchActive;
extern volatile uint8_t gSerialConfigCountDown_500ms;
@@ -233,8 +225,12 @@ extern bool gEndOfRxDetectedMaybe;
extern int16_t gVFO_RSSI[2];
extern uint8_t gVFO_RSSI_bar_level[2];
// battery critical, limit functionality to minimum
extern uint8_t gReducedService;
extern uint8_t gBatteryVoltageIndex;
// if not equal CSS_SCAN_MODE_OFF we are scanning CTCSS/DCS
// this is a scanning inside RX ctcss/dcs menu
extern CssScanMode_t gCssScanMode;
extern bool gUpdateRSSI;
extern AlarmState_t gAlarmState;
@@ -272,6 +268,8 @@ extern bool g_CxCSS_TAIL_Found;
extern uint16_t gVoxResumeCountdown;
extern uint16_t gVoxPauseCountdown;
#endif
// true means we are receiving signal
extern bool g_SquelchLost;
extern uint8_t gFlashLightState;
extern volatile uint16_t gFlashLightBlinkCounter;
@@ -280,10 +278,7 @@ extern uint16_t gLowBatteryCountdown;
extern uint8_t gNextMrChannel;
extern ReceptionMode_t gRxReceptionMode;
extern uint8_t gRestoreMrChannel;
extern scan_next_chan_t gCurrentScanList;
extern uint32_t gRestoreFrequency;
//TRUE when dual watch is momentarly suspended and RX_VFO is locked to either last TX or RX
extern bool gRxVfoIsActive;
extern uint8_t gAlarmToneCounter;
extern uint16_t gAlarmRunningCounter;
@@ -319,6 +314,7 @@ extern volatile bool gNextTimeslice40ms;
extern volatile bool gScheduleNOAA;
#endif
extern volatile bool gFlagTailNoteEliminationComplete;
extern volatile uint8_t gVFOStateResumeCountdown_500ms;
#ifdef ENABLE_FMRADIO
extern volatile bool gScheduleFM;
#endif
@@ -326,12 +322,8 @@ extern int16_t gCurrentRSSI[2]; // now one per VFO
extern uint8_t gIsLocked;
extern volatile uint8_t boot_counter_10ms;
unsigned int get_tx_VFO(void);
unsigned int get_rx_VFO(void);
void NUMBER_Get(char *pDigits, uint32_t *pInteger);
void NUMBER_ToDigits(uint32_t Value, char *pDigits);
int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit);
unsigned long StrToUL(const char * str);
#endif

162
radio.c
View File

@@ -51,7 +51,7 @@ bool RADIO_CheckValidChannel(uint16_t Channel, bool bCheckScanList, uint8_t VFO)
uint8_t PriorityCh1;
uint8_t PriorityCh2;
if (Channel > MR_CHANNEL_LAST)
if (!IS_MR_CHANNEL(Channel))
return false;
Attributes = gMR_ChannelAttributes[Channel];
@@ -97,12 +97,12 @@ uint8_t RADIO_FindNextChannel(uint8_t Channel, int8_t Direction, bool bCheckScan
{
unsigned int i;
for (i = 0; i <= MR_CHANNEL_LAST; i++)
for (i = 0; IS_MR_CHANNEL(i); i++)
{
if (Channel == 0xFF)
Channel = MR_CHANNEL_LAST;
else
if (Channel > MR_CHANNEL_LAST)
if (!IS_MR_CHANNEL(Channel))
Channel = MR_CHANNEL_FIRST;
if (RADIO_CheckValidChannel(Channel, bCheckScanList, VFO))
@@ -161,22 +161,22 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
if (IS_VALID_CHANNEL(Channel))
{
#ifdef ENABLE_NOAA
if (Channel >= NOAA_CHANNEL_FIRST)
{
RADIO_InitInfo(pRadio, gEeprom.ScreenChannel[VFO], NoaaFrequencyTable[Channel - NOAA_CHANNEL_FIRST]);
#ifdef ENABLE_NOAA
if (Channel >= NOAA_CHANNEL_FIRST)
{
RADIO_InitInfo(pRadio, gEeprom.ScreenChannel[VFO], NoaaFrequencyTable[Channel - NOAA_CHANNEL_FIRST]);
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF)
return;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gUpdateStatus = true;
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF)
return;
}
#endif
if (Channel <= MR_CHANNEL_LAST)
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gUpdateStatus = true;
return;
}
#endif
if (IS_MR_CHANNEL(Channel))
{
Channel = RADIO_FindNextChannel(Channel, RADIO_CHANNEL_UP, false, VFO);
if (Channel == 0xFF)
@@ -200,7 +200,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
uint8_t Index;
if (Channel <= MR_CHANNEL_LAST)
if (IS_MR_CHANNEL(Channel))
{
Channel = gEeprom.FreqChannel[VFO];
gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO];
@@ -218,7 +218,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
Band = BAND6_400MHz;
}
if (Channel <= MR_CHANNEL_LAST)
if (IS_MR_CHANNEL(Channel))
{
gEeprom.VfoInfo[VFO].Band = Band;
gEeprom.VfoInfo[VFO].SCANLIST1_PARTICIPATION = !!(Attributes & MR_CH_SCANLIST1);
@@ -235,7 +235,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
gEeprom.VfoInfo[VFO].SCANLIST2_PARTICIPATION = bParticipation2;
gEeprom.VfoInfo[VFO].CHANNEL_SAVE = Channel;
if (Channel <= MR_CHANNEL_LAST)
if (IS_MR_CHANNEL(Channel))
Base = Channel * 16;
else
Base = 0x0C80 + ((Channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16);
@@ -361,10 +361,8 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
Frequency = pRadio->freq_config_RX.Frequency;
#if 1
// fix previously set incorrect band
Band = FREQUENCY_GetBand(Frequency);
#endif
if (Frequency < frequencyBandTable[Band].lower)
Frequency = frequencyBandTable[Band].lower;
@@ -373,20 +371,19 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
Frequency = frequencyBandTable[Band].upper;
else
if (Channel >= FREQ_CHANNEL_FIRST)
Frequency = FREQUENCY_FloorToStep(Frequency, gEeprom.VfoInfo[VFO].StepFrequency, frequencyBandTable[Band].lower);
Frequency = FREQUENCY_RoundToStep(Frequency, gEeprom.VfoInfo[VFO].StepFrequency);
pRadio->freq_config_RX.Frequency = Frequency;
if (Frequency >= 10800000 && Frequency < 13600000)
if (Frequency >= frequencyBandTable[BAND2_108MHz].upper && Frequency < frequencyBandTable[BAND2_108MHz].upper)
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF;
else
if (Channel > MR_CHANNEL_LAST)
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY = FREQUENCY_FloorToStep(gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY, gEeprom.VfoInfo[VFO].StepFrequency, 0);
else if (!IS_MR_CHANNEL(Channel))
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY = FREQUENCY_RoundToStep(gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY, gEeprom.VfoInfo[VFO].StepFrequency);
RADIO_ApplyOffset(pRadio);
memset(gEeprom.VfoInfo[VFO].Name, 0, sizeof(gEeprom.VfoInfo[VFO].Name));
if (Channel < MR_CHANNEL_LAST)
if (IS_MR_CHANNEL(Channel))
{ // 16 bytes allocated to the channel name but only 10 used, the rest are 0's
EEPROM_ReadBuffer(0x0F50 + (Channel * 16), gEeprom.VfoInfo[VFO].Name + 0, 8);
EEPROM_ReadBuffer(0x0F58 + (Channel * 16), gEeprom.VfoInfo[VFO].Name + 8, 2);
@@ -516,6 +513,21 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
EEPROM_ReadBuffer(0x1ED0 + (Band * 16) + (pInfo->OUTPUT_POWER * 3), Txp, 3);
#ifdef ENABLE_REDUCE_LOW_MID_TX_POWER
// make low and mid even lower
if (pInfo->OUTPUT_POWER == OUTPUT_POWER_LOW) {
Txp[0] /= 5;
Txp[1] /= 5;
Txp[2] /= 5;
}
else if (pInfo->OUTPUT_POWER == OUTPUT_POWER_MID){
Txp[0] /= 3;
Txp[1] /= 3;
Txp[2] /= 3;
}
#endif
pInfo->TXP_CalculatedSetting = FREQUENCY_CalculateOutputPower(
Txp[0],
Txp[1],
@@ -555,13 +567,17 @@ void RADIO_ApplyOffset(VFO_Info_t *pInfo)
static void RADIO_SelectCurrentVfo(void)
{
gCurrentVfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gRxVfo : &gEeprom.VfoInfo[gEeprom.TX_VFO];
// if crossband is active and DW not the gCurrentVfo is gTxVfo (gTxVfo/TX_VFO is only ever changed by the user)
// otherwise it is set to gRxVfo which is set to gTxVfo in RADIO_SelectVfos
// so in the end gCurrentVfo is equal to gTxVfo unless dual watch changes it on incomming transmition (again, this can only happen when XB off)
// note: it is called only in certain situations so could be not up-to-date
gCurrentVfo = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF || gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) ? gRxVfo : gTxVfo;
}
void RADIO_SelectVfos(void)
{
gEeprom.TX_VFO = get_tx_VFO();
gEeprom.RX_VFO = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.TX_VFO : (gEeprom.TX_VFO + 1) & 1u;
// if crossband without DW is used then RX_VFO is the opposite to the TX_VFO
gEeprom.RX_VFO = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF || gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) ? gEeprom.TX_VFO : !gEeprom.TX_VFO;
gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_VFO];
gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_VFO];
@@ -569,25 +585,23 @@ void RADIO_SelectVfos(void)
RADIO_SelectCurrentVfo();
}
void RADIO_SetupRegisters(bool bSwitchToFunction0)
void RADIO_SetupRegisters(bool switchToForeground)
{
BK4819_FilterBandwidth_t Bandwidth = gRxVfo->CHANNEL_BANDWIDTH;
uint16_t InterruptMask;
uint32_t Frequency;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
gEnableSpeaker = false;
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, false);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2_GREEN, false);
switch (Bandwidth)
{
default:
Bandwidth = BK4819_FILTER_BW_WIDE;
[[fallthrough]];
case BK4819_FILTER_BW_WIDE:
case BK4819_FILTER_BW_NARROW:
#ifdef ENABLE_AM_FIX
@@ -599,13 +613,11 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
break;
}
#pragma GCC diagnostic pop
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, false);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false);
BK4819_SetupPowerAmplifier(0, 0);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, false);
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, false);
while (1)
{
@@ -622,7 +634,7 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
BK4819_WriteRegister(BK4819_REG_7D, 0xE940 | (gEeprom.MIC_SENSITIVITY_TUNING & 0x1f));
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) || !gIsNoaaMode)
if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) || !gIsNoaaMode)
Frequency = gRxVfo->pRX->Frequency;
else
Frequency = NoaaFrequencyTable[gNoaaChannel];
@@ -639,7 +651,7 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
BK4819_PickRXFilterPathBasedOnFrequency(Frequency);
// what does this in do ?
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, true);
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, true);
// AF RX Gain and DAC
BK4819_WriteRegister(BK4819_REG_48, 0xB3A8); // 1011 00 111010 1000
@@ -647,7 +659,7 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
InterruptMask = BK4819_REG_3F_SQUELCH_FOUND | BK4819_REG_3F_SQUELCH_LOST;
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif
{
if (gRxVfo->AM_mode == 0)
@@ -726,9 +738,9 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
#ifdef ENABLE_VOX
#ifdef ENABLE_NOAA
#ifdef ENABLE_FMRADIO
if (gEeprom.VOX_SWITCH && !gFmRadioMode && IS_NOT_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE) && gCurrentVfo->AM_mode == 0)
if (gEeprom.VOX_SWITCH && !gFmRadioMode && !IS_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE) && gCurrentVfo->AM_mode == 0)
#else
if (gEeprom.VOX_SWITCH && IS_NOT_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE) && gCurrentVfo->AM_mode == 0)
if (gEeprom.VOX_SWITCH && !IS_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE) && gCurrentVfo->AM_mode == 0)
#endif
#else
#ifdef ENABLE_FMRADIO
@@ -776,7 +788,7 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
FUNCTION_Init();
if (bSwitchToFunction0)
if (switchToForeground)
FUNCTION_Select(FUNCTION_FOREGROUND);
}
@@ -791,9 +803,9 @@ void RADIO_SetupRegisters(bool bSwitchToFunction0)
{
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF)
{
if (IS_NOT_NOAA_CHANNEL(gEeprom.ScreenChannel[0]))
if (!IS_NOAA_CHANNEL(gEeprom.ScreenChannel[0]))
{
if (IS_NOT_NOAA_CHANNEL(gEeprom.ScreenChannel[1]))
if (!IS_NOAA_CHANNEL(gEeprom.ScreenChannel[1]))
{
gIsNoaaMode = false;
return;
@@ -829,19 +841,17 @@ void RADIO_SetTxParameters(void)
{
BK4819_FilterBandwidth_t Bandwidth = gCurrentVfo->CHANNEL_BANDWIDTH;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
gEnableSpeaker = false;
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, false);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false);
switch (Bandwidth)
{
default:
Bandwidth = BK4819_FILTER_BW_WIDE;
[[fallthrough]];
case BK4819_FILTER_BW_WIDE:
case BK4819_FILTER_BW_NARROW:
#ifdef ENABLE_AM_FIX
@@ -853,8 +863,6 @@ void RADIO_SetTxParameters(void)
break;
}
#pragma GCC diagnostic pop
BK4819_SetFrequency(gCurrentVfo->pTX->Frequency);
// TX compressor
@@ -866,7 +874,7 @@ void RADIO_SetTxParameters(void)
BK4819_PickRXFilterPathBasedOnFrequency(gCurrentVfo->pTX->Frequency);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, true);
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_PA_ENABLE, true);
SYSTEM_DelayMs(5);
@@ -898,10 +906,7 @@ void RADIO_SetVfoState(VfoState_t State)
{
VfoState[0] = VFO_STATE_NORMAL;
VfoState[1] = VFO_STATE_NORMAL;
#ifdef ENABLE_FMRADIO
gFM_ResumeCountdown_500ms = 0;
#endif
gVFOStateResumeCountdown_500ms = 0;
}
else
{
@@ -916,9 +921,7 @@ void RADIO_SetVfoState(VfoState_t State)
VfoState[vfo] = State;
}
#ifdef ENABLE_FMRADIO
gFM_ResumeCountdown_500ms = fm_resume_countdown_500ms;
#endif
gVFOStateResumeCountdown_500ms = vfo_state_resume_countdown_500ms;
}
gUpdateDisplay = true;
@@ -937,10 +940,9 @@ void RADIO_PrepareTX(void)
if (!gRxVfoIsActive)
{ // use the current RX vfo
gEeprom.RX_VFO = gEeprom.TX_VFO;
gRxVfo = &gEeprom.VfoInfo[gEeprom.TX_VFO];
gRxVfo = gTxVfo;
gRxVfoIsActive = true;
}
gCurrentVfo = gRxVfo;
// let the user see that DW is not active
gDualWatchActive = false;
@@ -1044,23 +1046,17 @@ void RADIO_PrepareTX(void)
void RADIO_EnableCxCSS(void)
{
switch (gCurrentVfo->pTX->CodeType)
{
default:
case CODE_TYPE_OFF:
break;
case CODE_TYPE_CONTINUOUS_TONE:
BK4819_EnableCTCSS();
SYSTEM_DelayMs(200);
break;
case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL:
BK4819_EnableCDCSS();
SYSTEM_DelayMs(200);
break;
switch (gCurrentVfo->pTX->CodeType) {
case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL:
BK4819_EnableCDCSS();
break;
default:
BK4819_EnableCTCSS();
break;
}
SYSTEM_DelayMs(200);
}
void RADIO_PrepareCssTX(void)
@@ -1090,7 +1086,7 @@ void RADIO_SendEndOfTransmission(void)
{ // end-of-tx
if (gEeprom.DTMF_SIDE_TONE)
{
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOn();
gEnableSpeaker = true;
SYSTEM_DelayMs(60);
}
@@ -1105,7 +1101,7 @@ void RADIO_SendEndOfTransmission(void)
gEeprom.DTMF_CODE_PERSIST_TIME,
gEeprom.DTMF_CODE_INTERVAL_TIME);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
AUDIO_AudioPathOff();
gEnableSpeaker = false;
}

15
radio.h
View File

@@ -73,7 +73,14 @@ typedef struct VFO_Info_t
{
FREQ_Config_t freq_config_RX;
FREQ_Config_t freq_config_TX;
// this is for a purpose of the FrequencyReverse function
// it points to freq_config_RX normally and to freq_config_TX if reverse function is active
//
FREQ_Config_t *pRX;
// this is for a purpose of the FrequencyReverse function
// it points to freq_config_TX normally and to freq_config_RX if reverse function is active
FREQ_Config_t *pTX;
uint32_t TX_OFFSET_FREQUENCY;
@@ -115,8 +122,16 @@ typedef struct VFO_Info_t
char Name[16];
} VFO_Info_t;
// Settings of the main VFO that is selected by the user
// The pointer follows gEeprom.RX_VFO index
extern VFO_Info_t *gTxVfo;
// Settings of the actual VFO that is now used for RX,
// It is being alternated by dual watch, and flipped by crossband
// The pointer follows gEeprom.RX_VFO
extern VFO_Info_t *gRxVfo;
// Equal to gTxVfo unless dual watch changes it on incomming transmition (this can only happen when XB off and DW on)
extern VFO_Info_t *gCurrentVfo;
extern DCS_CodeType_t gSelectedCodeType;

View File

@@ -96,17 +96,18 @@ void SETTINGS_SaveSettings(void)
State[7] = gEeprom.MIC_SENSITIVITY;
EEPROM_WriteBuffer(0x0E70, State);
State[0] = 0xFF;
State[0] = (gEeprom.BACKLIGHT_MIN << 4) + gEeprom.BACKLIGHT_MAX;
State[1] = gEeprom.CHANNEL_DISPLAY_MODE;
State[2] = gEeprom.CROSS_BAND_RX_TX;
State[3] = gEeprom.BATTERY_SAVE;
State[4] = gEeprom.DUAL_WATCH;
State[5] = gEeprom.BACKLIGHT;
State[6] = gEeprom.TAIL_NOTE_ELIMINATION;
State[5] = gEeprom.BACKLIGHT_TIME;
State[6] = gEeprom.TAIL_TONE_ELIMINATION;
State[7] = gEeprom.VFO_OPEN;
EEPROM_WriteBuffer(0x0E78, State);
State[0] = gEeprom.BEEP_CONTROL;
State[0] |= gEeprom.KEY_M_LONG_PRESS_ACTION << 1;
State[1] = gEeprom.KEY_1_SHORT_PRESS_ACTION;
State[2] = gEeprom.KEY_1_LONG_PRESS_ACTION;
State[3] = gEeprom.KEY_2_SHORT_PRESS_ACTION;
@@ -122,11 +123,11 @@ void SETTINGS_SaveSettings(void)
#endif
EEPROM_WriteBuffer(0x0E98, Password);
#ifdef ENABLE_VOICE
memset(State, 0xFF, sizeof(State));
State[0] = gEeprom.VOICE_PROMPT;
EEPROM_WriteBuffer(0x0EA0, State);
#endif
memset(State, 0xFF, sizeof(State));
#ifdef ENABLE_VOICE
State[0] = gEeprom.VOICE_PROMPT;
EEPROM_WriteBuffer(0x0EA0, State);
#endif
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
State[0] = gEeprom.ALARM_MODE;
@@ -136,6 +137,7 @@ void SETTINGS_SaveSettings(void)
State[1] = gEeprom.ROGER;
State[2] = gEeprom.REPEATER_TAIL_TONE_ELIMINATION;
State[3] = gEeprom.TX_VFO;
State[4] = gEeprom.BATTERY_TYPE;
EEPROM_WriteBuffer(0x0EA8, State);
State[0] = gEeprom.DTMF_SIDE_TONE;
@@ -189,19 +191,19 @@ void SETTINGS_SaveSettings(void)
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode)
{
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(Channel))
if (!IS_NOAA_CHANNEL(Channel))
#endif
{
const uint16_t OffsetMR = Channel * 16;
uint16_t OffsetVFO = OffsetMR;
if (Channel > MR_CHANNEL_LAST)
if (!IS_MR_CHANNEL(Channel))
{ // it's a VFO, not a channel
OffsetVFO = (VFO == 0) ? 0x0C80 : 0x0C90;
OffsetVFO += (Channel - FREQ_CHANNEL_FIRST) * 32;
}
if (Mode >= 2 || Channel > MR_CHANNEL_LAST)
if (Mode >= 2 || !IS_MR_CHANNEL(Channel))
{ // copy VFO to a channel
uint8_t State[8];
@@ -226,7 +228,7 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
SETTINGS_UpdateChannel(Channel, pVFO, true);
if (Channel <= MR_CHANNEL_LAST)
if (IS_MR_CHANNEL(Channel))
{ // it's a memory channel
#ifndef ENABLE_KEEP_MEM_NAME
@@ -251,10 +253,20 @@ void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO,
}
}
void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration)
{
uint16_t buf[4];
EEPROM_WriteBuffer(0x1F40, batteryCalibration);
EEPROM_ReadBuffer( 0x1F48, buf, sizeof(buf));
buf[0] = batteryCalibration[4];
buf[1] = batteryCalibration[5];
EEPROM_WriteBuffer(0x1F48, buf);
}
void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep)
{
#ifdef ENABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(Channel))
if (!IS_NOAA_CHANNEL(Channel))
#endif
{
uint8_t State[8];
@@ -279,7 +291,7 @@ void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep)
gMR_ChannelAttributes[Channel] = Attributes;
// #ifndef ENABLE_KEEP_MEM_NAME
if (Channel <= MR_CHANNEL_LAST)
if (IS_MR_CHANNEL(Channel))
{ // it's a memory channel
const uint16_t OffsetMR = Channel * 16;

View File

@@ -21,6 +21,7 @@
#include <stdint.h>
#include "frequencies.h"
#include <helper/battery.h>
#include "radio.h"
enum POWER_OnDisplayMode_t {
@@ -80,6 +81,9 @@ enum {
ACTION_OPT_ALARM,
ACTION_OPT_FM,
ACTION_OPT_1750,
ACTION_OPT_KEYLOCK,
ACTION_OPT_A_B,
ACTION_OPT_VFO_MR,
ACTION_OPT_LEN
};
@@ -121,7 +125,13 @@ typedef struct {
#ifdef ENABLE_NOAA
uint8_t NoaaChannel[2];
#endif
// The actual VFO index (0-upper/1-lower) that is now used for RX,
// It is being alternated by dual watch, and flipped by crossband
uint8_t RX_VFO;
// The main VFO index (0-upper/1-lower) selected by the user
//
uint8_t TX_VFO;
uint8_t field7_0xa;
@@ -146,12 +156,12 @@ typedef struct {
#endif
bool BEEP_CONTROL;
uint8_t CHANNEL_DISPLAY_MODE;
bool TAIL_NOTE_ELIMINATION;
bool TAIL_TONE_ELIMINATION;
bool VFO_OPEN;
uint8_t DUAL_WATCH;
uint8_t CROSS_BAND_RX_TX;
uint8_t BATTERY_SAVE;
uint8_t BACKLIGHT;
uint8_t BACKLIGHT_TIME;
uint8_t SCAN_RESUME_MODE;
uint8_t SCAN_LIST_DEFAULT;
bool SCAN_LIST_ENABLED[2];
@@ -218,8 +228,12 @@ typedef struct {
uint8_t field78_0x96;
uint8_t field79_0x97;
uint8_t _pad[1];
uint8_t KEY_M_LONG_PRESS_ACTION;
uint8_t BACKLIGHT_MIN;
uint8_t BACKLIGHT_MAX;
BATTERY_Type_t BATTERY_TYPE;
} EEPROM_Config_t;
extern EEPROM_Config_t gEeprom;
#ifdef ENABLE_FMRADIO
@@ -228,6 +242,7 @@ extern EEPROM_Config_t gEeprom;
void SETTINGS_SaveVfoIndices(void);
void SETTINGS_SaveSettings(void);
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode);
void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration);
void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep);
#endif

View File

@@ -44,12 +44,19 @@ void UI_DisplayAircopy(void)
if (gInputBoxIndex == 0)
{
NUMBER_ToDigits(gRxVfo->freq_config_RX.Frequency, String);
UI_DisplayFrequency(String, 16, 2, 0, 0);
UI_DisplaySmallDigits(2, String + 6, 97, 3, true);
uint32_t frequency = gRxVfo->freq_config_RX.Frequency;
sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000);
// show the remaining 2 small frequency digits
UI_PrintStringSmall(String + 7, 97, 0, 3);
String[7] = 0;
// show the main large frequency digits
UI_DisplayFrequency(String, 16, 2, false);
}
else {
const char * ascii = INPUTBOX_GetAscii();
sprintf(String, "%.3s.%.3s",ascii, ascii + 3);
UI_DisplayFrequency(String, 16, 2, false);
}
else
UI_DisplayFrequency(gInputBox, 16, 2, 1, 0);
memset(String, 0, sizeof(String));
if (gAirCopyIsSendMode == 0)

View File

@@ -90,11 +90,14 @@ void UI_DisplayFM(void)
{
if (gInputBoxIndex == 0)
{
NUMBER_ToDigits(gEeprom.FM_FrequencyPlaying * 10000, String);
UI_DisplayFrequency(String, 23, 4, false, true);
sprintf(String, "%3d.%d", gEeprom.FM_FrequencyPlaying / 10, gEeprom.FM_FrequencyPlaying % 10);
UI_DisplayFrequency(String, 32, 4, true);
}
else {
const char * ascii = INPUTBOX_GetAscii();
sprintf(String, "%.3s.%.1s",ascii, ascii + 3);
UI_DisplayFrequency(String, 32, 4, false);
}
else
UI_DisplayFrequency(gInputBox, 23, 4, true, false);
ST7565_BlitFullScreen();
return;

View File

@@ -72,12 +72,12 @@ void UI_PrintString(const char *pString, uint8_t Start, uint8_t End, uint8_t Lin
for (i = 0; i < Length; i++)
{
if (pString[i] >= ' ' && pString[i] < 127)
const unsigned int ofs = (unsigned int)Start + (i * Width);
if (pString[i] > ' ' && pString[i] < 127)
{
const unsigned int index = pString[i] - ' ';
const unsigned int ofs = (unsigned int)Start + (i * Width);
memmove(gFrameBuffer[Line + 0] + ofs, &gFontBig[index][0], 8);
memmove(gFrameBuffer[Line + 1] + ofs, &gFontBig[index][8], 7);
const unsigned int index = pString[i] - ' ' - 1;
memmove(gFrameBuffer[Line + 0] + ofs, &gFontBig[index][0], 7);
memmove(gFrameBuffer[Line + 1] + ofs, &gFontBig[index][7], 7);
}
}
}
@@ -95,9 +95,9 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_
uint8_t *pFb = gFrameBuffer[Line] + Start;
for (i = 0; i < Length; i++)
{
if (pString[i] >= 32)
if (pString[i] > ' ')
{
const unsigned int index = (unsigned int)pString[i] - 32;
const unsigned int index = (unsigned int)pString[i] - ' ' - 1;
if (index < ARRAY_SIZE(gFontSmall))
memmove(pFb + (i * char_spacing) + 1, &gFontSmall[index], char_width);
}
@@ -118,9 +118,9 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_
uint8_t *pFb = gFrameBuffer[Line] + Start;
for (i = 0; i < Length; i++)
{
if (pString[i] >= 32)
if (pString[i] > ' ')
{
const unsigned int index = (unsigned int)pString[i] - 32;
const unsigned int index = (unsigned int)pString[i] - ' ' - 1;
if (index < ARRAY_SIZE(gFontSmallBold))
memmove(pFb + (i * char_spacing) + 1, &gFontSmallBold[index], char_width);
}
@@ -135,126 +135,46 @@ void UI_PrintStringSmallBuffer(const char *pString, uint8_t *buffer)
const unsigned int char_spacing = char_width + 1;
for (i = 0; i < strlen(pString); i++)
{
if (pString[i] >= 32)
if (pString[i] > ' ')
{
const unsigned int index = (unsigned int)pString[i] - 32;
const unsigned int index = (unsigned int)pString[i] - ' ' - 1;
if (index < ARRAY_SIZE(gFontSmall))
memmove(buffer + (i * char_spacing) + 1, &gFontSmall[index], char_width);
}
}
}
void UI_DisplayFrequency(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero, bool bFlag)
void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center)
{
const unsigned int char_width = 13;
uint8_t *pFb0 = gFrameBuffer[Y] + X;
uint8_t *pFb1 = pFb0 + 128;
bool bCanDisplay = false;
unsigned int i = 0;
// MHz
while (i < 3)
{
const unsigned int Digit = pDigits[i++];
if (bDisplayLeadingZero || bCanDisplay || Digit > 0)
uint8_t len = strlen(string);
for(int i = 0; i < len; i++) {
char c = string[i];
if(c=='-') c = '9' + 1;
if (bCanDisplay || c != ' ')
{
bCanDisplay = true;
memmove(pFb0, gFontBigDigits[Digit], char_width);
memmove(pFb1, gFontBigDigits[Digit] + char_width, char_width);
if(c>='0' && c<='9' + 1) {
memcpy(pFb0 + 2, gFontBigDigits[c-'0'], char_width - 3);
memcpy(pFb1 + 2, gFontBigDigits[c-'0'] + char_width - 3, char_width - 3);
}
else if(c=='.') {
*pFb1 = 0x60; pFb0++; pFb1++;
*pFb1 = 0x60; pFb0++; pFb1++;
*pFb1 = 0x60; pFb0++; pFb1++;
continue;
}
}
else
if (bFlag)
{
else if (center) {
pFb0 -= 6;
pFb1 -= 6;
}
pFb0 += char_width;
pFb1 += char_width;
}
// decimal point
*pFb1 = 0x60; pFb0++; pFb1++;
*pFb1 = 0x60; pFb0++; pFb1++;
*pFb1 = 0x60; pFb0++; pFb1++;
// kHz
while (i < 6)
{
const unsigned int Digit = pDigits[i++];
memmove(pFb0, gFontBigDigits[Digit], char_width);
memmove(pFb1, gFontBigDigits[Digit] + char_width, char_width);
pFb0 += char_width;
pFb1 += char_width;
}
}
void UI_DisplayFrequencySmall(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero)
{
const unsigned int char_width = ARRAY_SIZE(gFontSmall[0]);
const unsigned int spacing = 1 + char_width;
uint8_t *pFb = gFrameBuffer[Y] + X;
bool bCanDisplay = false;
unsigned int i = 0;
// MHz
while (i < 3)
{
const unsigned int c = pDigits[i++];
if (bDisplayLeadingZero || bCanDisplay || c > 0)
{
#if 0
memmove(pFb + 1, gFontSmallDigits[c], char_width);
#else
const unsigned int index = (c < 10) ? '0' - 32 + c : '-' - 32;
memmove(pFb + 1, gFontSmall[index], char_width);
#endif
pFb += spacing;
bCanDisplay = true;
}
}
// decimal point
pFb++;
pFb++;
*pFb++ = 0x60;
*pFb++ = 0x60;
pFb++;
// kHz
while (i < 8)
{
const unsigned int c = pDigits[i++];
#if 0
memmove(pFb + 1, gFontSmallDigits[c], char_width);
#else
const unsigned int index = (c < 10) ? '0' - 32 + c : '-' - 32;
memmove(pFb + 1, gFontSmall[index], char_width);
#endif
pFb += spacing;
}
}
void UI_DisplaySmallDigits(const uint8_t size, const char *str, const uint8_t x, const uint8_t y, const bool display_leading_zeros)
{
const unsigned int char_width = ARRAY_SIZE(gFontSmall[0]);
const unsigned int spacing = 1 + char_width;
bool display = display_leading_zeros;
unsigned int xx;
unsigned int i;
for (i = 0, xx = x; i < size; i++)
{
const unsigned int c = (unsigned int)str[i];
if (c > 0)
display = true; // non '0'
if (display && c < 11)
{
#if 0
memmove(gFrameBuffer[y] + xx, gFontSmallDigits[c], char_width);
#else
const unsigned int index = (c < 10) ? '0' - 32 + c : '-' - 32;
memmove(gFrameBuffer[y] + xx + 1, gFontSmall[index], char_width);
#endif
xx += spacing;
}
}
}

View File

@@ -28,9 +28,7 @@ void UI_PrintStringSmall(const char *pString, uint8_t Start, uint8_t End, uint8_
void UI_PrintStringSmallBold(const char *pString, uint8_t Start, uint8_t End, uint8_t Line);
#endif
void UI_PrintStringSmallBuffer(const char *pString, uint8_t *buffer);
void UI_DisplayFrequency(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero, bool bFlag);
void UI_DisplayFrequencySmall(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero);
void UI_DisplaySmallDigits(const uint8_t size, const char *str, const uint8_t x, const uint8_t y, const bool display_leading_zeros);
void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center);
#endif

View File

@@ -19,6 +19,7 @@
#include "ui/inputbox.h"
char gInputBox[8];
char inputBoxAscii[9];
uint8_t gInputBoxIndex;
void INPUTBOX_Append(const KEY_Code_t Digit)
@@ -29,7 +30,15 @@ void INPUTBOX_Append(const KEY_Code_t Digit)
if (gInputBoxIndex == 0)
memset(gInputBox, 10, sizeof(gInputBox));
if (Digit >= KEY_0 && Digit != KEY_INVALID)
if (Digit != KEY_INVALID)
gInputBox[gInputBoxIndex++] = (char)(Digit - KEY_0);
}
const char* INPUTBOX_GetAscii()
{
for(int i = 0; i < 8; i++) {
char c = gInputBox[i];
inputBoxAscii[i] = (c==10)? '-' : '0' + c;
}
return inputBoxAscii;
}

View File

@@ -25,6 +25,7 @@ extern char gInputBox[8];
extern uint8_t gInputBoxIndex;
void INPUTBOX_Append(const KEY_Code_t Digit);
const char* INPUTBOX_GetAscii();
#endif

View File

@@ -102,10 +102,9 @@ void UI_DisplayLock(void)
uint32_t Password;
gInputBoxIndex = 0;
Password = StrToUL(INPUTBOX_GetAscii());
NUMBER_Get(gInputBox, &Password);
if ((gEeprom.POWER_ON_PASSWORD * 100) == Password)
if ((gEeprom.POWER_ON_PASSWORD) == Password)
{
AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL);
return;

672
ui/main.c
View File

@@ -14,10 +14,6 @@
* limitations under the License.
*/
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
#pragma GCC diagnostic pop
#include <string.h>
#include <stdlib.h> // abs()
@@ -44,246 +40,184 @@ center_line_t center_line = CENTER_LINE_NONE;
// ***************************************************************************
void UI_drawBars(uint8_t *p, const unsigned int level)
static void DrawSmallAntennaAndBars(uint8_t *p, unsigned int level)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
if(level>6)
level = 6;
switch (level)
{
default:
case 7: memmove(p + 20, BITMAP_AntennaLevel6, sizeof(BITMAP_AntennaLevel6));
case 6: memmove(p + 17, BITMAP_AntennaLevel5, sizeof(BITMAP_AntennaLevel5));
case 5: memmove(p + 14, BITMAP_AntennaLevel4, sizeof(BITMAP_AntennaLevel4));
case 4: memmove(p + 11, BITMAP_AntennaLevel3, sizeof(BITMAP_AntennaLevel3));
case 3: memmove(p + 8, BITMAP_AntennaLevel2, sizeof(BITMAP_AntennaLevel2));
case 2: memmove(p + 5, BITMAP_AntennaLevel1, sizeof(BITMAP_AntennaLevel1));
case 1: memmove(p + 0, BITMAP_Antenna, sizeof(BITMAP_Antenna));
case 0: break;
memcpy(p, BITMAP_Antenna, ARRAY_SIZE(BITMAP_Antenna));
for(uint8_t i = 1; i <= level; i++) {
char bar = (0xff << (6-i)) & 0x7F;
memset(p + 2 + i*3, bar, 2);
}
#pragma GCC diagnostic pop
}
#ifdef ENABLE_AUDIO_BAR
unsigned int sqrt16(unsigned int value)
{ // return square root of 'value'
unsigned int shift = 16; // number of bits supplied in 'value' .. 2 ~ 32
unsigned int bit = 1u << --shift;
unsigned int sqrti = 0;
while (bit)
{
const unsigned int temp = ((sqrti << 1) | bit) << shift--;
if (value >= temp)
{
value -= temp;
sqrti |= bit;
}
bit >>= 1;
}
return sqrti;
}
void UI_DisplayAudioBar(void)
unsigned int sqrt16(unsigned int value)
{ // return square root of 'value'
unsigned int shift = 16; // number of bits supplied in 'value' .. 2 ~ 32
unsigned int bit = 1u << --shift;
unsigned int sqrti = 0;
while (bit)
{
if (gSetting_mic_bar)
{
const unsigned int line = 3;
const unsigned int bar_x = 2;
const unsigned int bar_width = LCD_WIDTH - 2 - bar_x;
unsigned int i;
const unsigned int temp = ((sqrti << 1) | bit) << shift--;
if (value >= temp) {
value -= temp;
sqrti |= bit;
}
bit >>= 1;
}
return sqrti;
}
if (gCurrentFunction != FUNCTION_TRANSMIT ||
gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE)
{
return; // screen is in use
}
void UI_DisplayAudioBar(void)
{
if (gSetting_mic_bar)
{
const unsigned int line = 3;
const unsigned int bar_x = 2;
const unsigned int bar_width = LCD_WIDTH - 2 - bar_x;
unsigned int i;
if (gCurrentFunction != FUNCTION_TRANSMIT ||
gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE)
{
return; // screen is in use
}
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
if (gAlarmState != ALARM_STATE_OFF)
return;
if (gAlarmState != ALARM_STATE_OFF)
return;
#endif
const unsigned int voice_amp = BK4819_GetVoiceAmplitudeOut(); // 15:0
// make non-linear to make more sensitive at low values
const unsigned int level = voice_amp * 8;
const unsigned int sqrt_level = sqrt16((level < 65535) ? level : 65535);
const unsigned int len = (sqrt_level <= bar_width) ? sqrt_level : bar_width;
const unsigned int voice_amp = BK4819_GetVoiceAmplitudeOut(); // 15:0
uint8_t *p_line = gFrameBuffer[line];
memset(p_line, 0, LCD_WIDTH);
for (i = 0; i < bar_width; i++)
p_line[bar_x + i] = (i > len) ? ((i & 1) == 0) ? 0x41 : 0x00 : ((i & 1) == 0) ? 0x7f : 0x3e;
// make non-linear to make more sensitive at low values
const unsigned int level = voice_amp * 8;
const unsigned int sqrt_level = sqrt16((level < 65535) ? level : 65535);
const unsigned int len = (sqrt_level <= bar_width) ? sqrt_level : bar_width;
if (gCurrentFunction == FUNCTION_TRANSMIT)
ST7565_BlitFullScreen();
}
uint8_t *p_line = gFrameBuffer[line];
memset(p_line, 0, LCD_WIDTH);
for (i = 0; i < bar_width; i++)
p_line[bar_x + i] = (i > len) ? ((i & 1) == 0) ? 0x41 : 0x00 : ((i & 1) == 0) ? 0x7f : 0x3e;
if (gCurrentFunction == FUNCTION_TRANSMIT)
ST7565_BlitFullScreen();
}
}
#endif
static void DisplayRSSIBar(const int16_t rssi, const bool now)
{
#if defined(ENABLE_RSSI_BAR)
void UI_DisplayRSSIBar(const int16_t rssi, const bool now)
{
// const int16_t s0_dBm = -127; // S0 .. base level
const int16_t s0_dBm = -147; // S0 .. base level
const int16_t s9_dBm = s0_dBm + (6 * 9); // S9 .. 6dB/S-Point
const int16_t bar_max_dBm = s9_dBm + 30; // S9+30dB
// const int16_t bar_min_dBm = s0_dBm + (6 * 0); // S0
const int16_t bar_min_dBm = s0_dBm + (6 * 4); // S4
// ************
if (center_line == CENTER_LINE_RSSI) {
const unsigned int txt_width = 7 * 8; // 8 text chars
const unsigned int bar_x = 2 + txt_width + 4; // X coord of bar graph
const unsigned int bar_width = LCD_WIDTH - 1 - bar_x;
const int16_t rssi_dBm = (rssi / 2) - 160;
const int16_t clamped_dBm = (rssi_dBm <= bar_min_dBm) ? bar_min_dBm : (rssi_dBm >= bar_max_dBm) ? bar_max_dBm : rssi_dBm;
const unsigned int bar_range_dB = bar_max_dBm - bar_min_dBm;
const unsigned int len = ((clamped_dBm - bar_min_dBm) * bar_width) / bar_range_dB;
const unsigned int line = 3;
uint8_t *p_line = gFrameBuffer[line];
char str[16];
char s[16];
unsigned int i;
const char plus[] = {
0b00011000,
0b00011000,
0b01111110,
0b01111110,
0b01111110,
0b00011000,
0b00011000,
};
const char hollowBar[] = {
0b01111111,
0b01000001,
0b01000001,
0b01111111
};
if (gEeprom.KEY_LOCK && gKeypadLocked > 0)
return; // display is in use
if (gCurrentFunction == FUNCTION_TRANSMIT ||
gScreenToDisplay != DISPLAY_MAIN ||
gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE)
return; // display is in use
if (now)
memset(p_line, 0, LCD_WIDTH);
const int16_t s0_dBm = -147; // S0 .. base level
const int16_t rssi_dBm = (rssi / 2) - 160;
if (rssi_dBm >= (s9_dBm + 6))
{ // S9+XXdB, 1dB increment
const char *fmt[] = {"%3d 9+%u ", "%3d 9+%2u "};
const unsigned int s9_dB = ((rssi_dBm - s9_dBm) <= 99) ? rssi_dBm - s9_dBm : 99;
sprintf(s, (s9_dB < 10) ? fmt[0] : fmt[1], rssi_dBm, s9_dB);
const uint8_t s_level = MIN(MAX((rssi_dBm - s0_dBm) / 6, 0), 9); // S0 - S9
uint8_t overS9dBm = MIN(MAX(73 + rssi_dBm, 0), 99);
uint8_t overS9Bars = MIN(overS9dBm/10, 4);
if(overS9Bars == 0) {
sprintf(str, "% 4d S%d", rssi_dBm, s_level);
}
else
{ // S0 ~ S9, 6dB per S-point
const unsigned int s_level = (rssi_dBm >= s0_dBm) ? (rssi_dBm - s0_dBm) / 6 : 0;
sprintf(s, "%4d S%u ", rssi_dBm, s_level);
else {
sprintf(str, "% 4d %2d", rssi_dBm, overS9dBm);
memcpy(p_line + 2 + 7*5, &plus, ARRAY_SIZE(plus));
}
UI_PrintStringSmall(s, 2, 0, line);
#if 1
// solid bar
for (i = 0; i < bar_width; i++)
p_line[bar_x + i] = (i > len) ? ((i & 1) == 0) ? 0x41 : 0x00 : ((i & 1) == 0) ? 0x7f : 0x3e;
#else
// knuled bar
for (i = 0; i < bar_width; i += 2)
p_line[bar_x + i] = (i <= len) ? 0x7f : 0x41;
#endif
UI_PrintStringSmall(str, 2, 0, line);
if (now)
ST7565_BlitFullScreen();
for(uint8_t i = 0; i < s_level; i++) { // S bars
for(uint8_t j = 0; j < 4; j++)
p_line[bar_x + i * 5 + j] = (~(0x7F >> (i+1))) & 0x7F;
}
for(uint8_t i = 0; i < overS9Bars; i++) { // +10 hollow bars
memcpy(p_line + (bar_x + (i + 9) * 5), &hollowBar, ARRAY_SIZE(hollowBar));
}
}
#else
uint8_t Level;
if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][3]) {
Level = 6;
} else if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][2]) {
Level = 4;
} else if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][1]) {
Level = 2;
} else if (rssi >= gEEPROM_RSSI_CALIB[gRxVfo->Band][0]) {
Level = 1;
} else {
Level = 0;
}
uint8_t *pLine = (gEeprom.RX_VFO == 0)? gFrameBuffer[2] : gFrameBuffer[6];
if (now)
memset(pLine, 0, 23);
DrawSmallAntennaAndBars(pLine, Level);
#endif
if (now)
ST7565_BlitFullScreen();
}
void UI_UpdateRSSI(const int16_t rssi, const int vfo)
{
#ifdef ENABLE_RSSI_BAR
(void)vfo; // unused
// optional larger RSSI dBm, S-point and bar level
(void)vfo; // unused
if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING)
{
// optional larger RSSI dBm, S-point and bar level
DisplayRSSIBar(rssi, true);
}
if (center_line != CENTER_LINE_RSSI)
return;
if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING)
{
UI_DisplayRSSIBar(rssi, true);
}
#else
// original little RS bars
// const int16_t dBm = (rssi / 2) - 160;
const uint8_t Line = (vfo == 0) ? 3 : 7;
uint8_t *p_line = gFrameBuffer[Line - 1];
// TODO: sort out all 8 values from the eeprom
#if 0
// dBm -105 -100 -95 -90 -70 -65 -60 -55
// RSSI 110 120 130 140 180 190 200 210
// 0000C0 6E 00 78 00 82 00 8C 00 B4 00 BE 00 C8 00 D2 00
//
const unsigned int band = 1;
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
p_line = gFrameBuffer[Line - 1];
memset(p_line, 0, 23);
// untested !!!
if (rssi_level == 0)
p_line = NULL;
else
UI_drawBars(p_line, rssi_level);
ST7565_DrawLine(0, Line, 23, p_line);
#endif
}
// ***************************************************************************
@@ -292,17 +226,11 @@ void UI_DisplayMain(void)
{
const unsigned int line0 = 0; // text screen line
const unsigned int line1 = 4;
char String[16];
char String[22];
unsigned int vfo_num;
center_line = CENTER_LINE_NONE;
// #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
const bool single_vfo = false;
// #endif
// clear the screen
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
@@ -313,31 +241,18 @@ void UI_DisplayMain(void)
ST7565_BlitFullScreen();
return;
}
unsigned int activeTxVFO = gRxVfoIsActive ? gEeprom.RX_VFO : gEeprom.TX_VFO;
for (vfo_num = 0; vfo_num < 2; vfo_num++)
{
const unsigned int line = (vfo_num == 0) ? line0 : line1;
unsigned int channel = gEeprom.TX_VFO;
// unsigned int tx_channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
const bool same_vfo = (channel == vfo_num) ? true : false;
const bool isMainVFO = (vfo_num == gEeprom.TX_VFO);
uint8_t *p_line0 = gFrameBuffer[line + 0];
uint8_t *p_line1 = gFrameBuffer[line + 1];
unsigned int mode = 0;
unsigned int state;
if (single_vfo)
{ // we're in single VFO mode - screen is dedicated to just one VFO
if (!same_vfo)
continue; // skip the unused vfo
}
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF && gRxVfoIsActive)
channel = gEeprom.RX_VFO; // we're currently monitoring the other VFO
if (channel != vfo_num)
if (activeTxVFO != vfo_num) // this is not active TX VFO
{
if (gDTMF_CallState != DTMF_CALL_STATE_NONE || gDTMF_IsTx || gDTMF_InputMode)
{ // show DTMF stuff
@@ -382,40 +297,34 @@ void UI_DisplayMain(void)
}
// highlight the selected/used VFO with a marker
if (!single_vfo && same_vfo)
if (isMainVFO)
memmove(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default));
else
if (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF)
memmove(p_line0 + 0, BITMAP_VFO_NotDefault, sizeof(BITMAP_VFO_NotDefault));
}
else
if (!single_vfo)
else // active TX VFO
{ // highlight the selected/used VFO with a marker
if (same_vfo)
if (isMainVFO)
memmove(p_line0 + 0, BITMAP_VFO_Default, sizeof(BITMAP_VFO_Default));
else
//if (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF)
memmove(p_line0 + 0, BITMAP_VFO_NotDefault, sizeof(BITMAP_VFO_NotDefault));
}
if (gCurrentFunction == FUNCTION_TRANSMIT)
{ // transmitting
#ifdef ENABLE_ALARM
if (gAlarmState == ALARM_STATE_ALARM)
mode = 2;
else
#endif
#ifdef ENABLE_ALARM
if (gAlarmState == ALARM_STATE_ALARM)
mode = 2;
else
#endif
{
channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
if (channel == vfo_num)
if (activeTxVFO == vfo_num)
{ // show the TX symbol
mode = 1;
#ifdef ENABLE_SMALL_BOLD
UI_PrintStringSmallBold("TX", 14, 0, line);
#else
UI_PrintStringSmall("TX", 14, 0, line);
#endif
#ifdef ENABLE_SMALL_BOLD
UI_PrintStringSmallBold("TX", 14, 0, line);
#else
UI_PrintStringSmall("TX", 14, 0, line);
#endif
}
}
}
@@ -427,61 +336,59 @@ void UI_DisplayMain(void)
gCurrentFunction == FUNCTION_INCOMING) &&
gEeprom.RX_VFO == vfo_num)
{
#ifdef ENABLE_SMALL_BOLD
UI_PrintStringSmallBold("RX", 14, 0, line);
#else
UI_PrintStringSmall("RX", 14, 0, line);
#endif
#ifdef ENABLE_SMALL_BOLD
UI_PrintStringSmallBold("RX", 14, 0, line);
#else
UI_PrintStringSmall("RX", 14, 0, line);
#endif
}
}
if (gEeprom.ScreenChannel[vfo_num] <= MR_CHANNEL_LAST)
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num]))
{ // channel mode
const unsigned int x = 2;
const bool inputting = (gInputBoxIndex == 0 || gEeprom.TX_VFO != vfo_num) ? false : true;
if (!inputting)
NUMBER_ToDigits(gEeprom.ScreenChannel[vfo_num] + 1, String); // show the memory channel number
sprintf(String, "M%u", gEeprom.ScreenChannel[vfo_num] + 1);
else
memmove(String + 5, gInputBox, 3); // show the input text
UI_PrintStringSmall("M", x, 0, line + 1);
UI_DisplaySmallDigits(3, String + 5, x + 7, line + 1, inputting);
}
else
if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]))
{ // frequency mode
// show the frequency band number
const unsigned int x = 2; // was 14
// sprintf(String, "FB%u", 1 + gEeprom.ScreenChannel[vfo_num] - FREQ_CHANNEL_FIRST);
sprintf(String, "VFO%u", 1 + gEeprom.ScreenChannel[vfo_num] - FREQ_CHANNEL_FIRST);
sprintf(String, "M%.3s", INPUTBOX_GetAscii()); // show the input text
UI_PrintStringSmall(String, x, 0, line + 1);
}
#ifdef ENABLE_NOAA
else
{
if (gInputBoxIndex == 0 || gEeprom.TX_VFO != vfo_num)
{ // channel number
sprintf(String, "N%u", 1 + gEeprom.ScreenChannel[vfo_num] - NOAA_CHANNEL_FIRST);
}
else
{ // user entering channel number
sprintf(String, "N%u%u", '0' + gInputBox[0], '0' + gInputBox[1]);
}
UI_PrintStringSmall(String, 7, 0, line + 1);
else if (IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]))
{ // frequency mode
// show the frequency band number
const unsigned int x = 2;
char * buf = gEeprom.VfoInfo[vfo_num].pRX->Frequency < 100000000 ? "" : "+";
sprintf(String, "F%u%s", 1 + gEeprom.ScreenChannel[vfo_num] - FREQ_CHANNEL_FIRST, buf);
UI_PrintStringSmall(String, x, 0, line + 1);
}
#ifdef ENABLE_NOAA
else
{
if (gInputBoxIndex == 0 || gEeprom.TX_VFO != vfo_num)
{ // channel number
sprintf(String, "N%u", 1 + gEeprom.ScreenChannel[vfo_num] - NOAA_CHANNEL_FIRST);
}
#endif
else
{ // user entering channel number
sprintf(String, "N%u%u", '0' + gInputBox[0], '0' + gInputBox[1]);
}
UI_PrintStringSmall(String, 7, 0, line + 1);
}
#endif
// ************
state = VfoState[vfo_num];
unsigned int state = VfoState[vfo_num];
#ifdef ENABLE_ALARM
if (gCurrentFunction == FUNCTION_TRANSMIT && gAlarmState == ALARM_STATE_ALARM)
{
channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
if (channel == vfo_num)
state = VFO_STATE_ALARM;
}
#endif
#ifdef ENABLE_ALARM
if (gCurrentFunction == FUNCTION_TRANSMIT && gAlarmState == ALARM_STATE_ALARM) {
if (activeTxVFO == vfo_num)
state = VFO_STATE_ALARM;
}
#endif
uint32_t frequency = gEeprom.VfoInfo[vfo_num].pRX->Frequency;
if (state != VFO_STATE_NORMAL)
{
@@ -489,58 +396,73 @@ void UI_DisplayMain(void)
if (state < ARRAY_SIZE(state_list))
UI_PrintString(state_list[state], 31, 0, line, 8);
}
else
if (gInputBoxIndex > 0 && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]) && gEeprom.TX_VFO == vfo_num)
else if (gInputBoxIndex > 0 && IS_FREQ_CHANNEL(gEeprom.ScreenChannel[vfo_num]) && gEeprom.TX_VFO == vfo_num)
{ // user entering a frequency
UI_DisplayFrequency(gInputBox, 32, line, true, false);
const char * ascii = INPUTBOX_GetAscii();
bool isGigaF = frequency>=100000000;
sprintf(String, "%.*s.%.3s", 3 + isGigaF, ascii, ascii + 3 + isGigaF);
#ifdef ENABLE_BIG_FREQ
if(!isGigaF) {
// show the remaining 2 small frequency digits
UI_PrintStringSmall(String + 7, 113, 0, line + 1);
String[7] = 0;
// show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false);
}
else
#endif
{
// show the frequency in the main font
UI_PrintString(String, 32, 0, line, 8);
}
// center_line = CENTER_LINE_IN_USE;
break;
}
else
{
uint32_t frequency = gEeprom.VfoInfo[vfo_num].pRX->Frequency;
if (gCurrentFunction == FUNCTION_TRANSMIT)
{ // transmitting
channel = (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) ? gEeprom.RX_VFO : gEeprom.TX_VFO;
if (channel == vfo_num)
if (activeTxVFO == vfo_num)
frequency = gEeprom.VfoInfo[vfo_num].pTX->Frequency;
}
if (gEeprom.ScreenChannel[vfo_num] <= MR_CHANNEL_LAST)
if (IS_MR_CHANNEL(gEeprom.ScreenChannel[vfo_num]))
{ // it's a channel
// show the channel symbols
// show the scan list assigment symbols
const uint8_t attributes = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
if (attributes & MR_CH_SCANLIST1)
memmove(p_line0 + 113, BITMAP_ScanList1, sizeof(BITMAP_ScanList1));
if (attributes & MR_CH_SCANLIST2)
memmove(p_line0 + 120, BITMAP_ScanList2, sizeof(BITMAP_ScanList2));
#ifndef ENABLE_BIG_FREQ
if ((attributes & MR_CH_COMPAND) > 0)
memmove(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
#else
// TODO: // find somewhere else to put the symbol
#endif
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
// compander symbol
#ifndef ENABLE_BIG_FREQ
if ((attributes & MR_CH_COMPAND) > 0)
memmove(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
#else
// TODO: // find somewhere else to put the symbol
#endif
switch (gEeprom.CHANNEL_DISPLAY_MODE)
{
case MDF_FREQUENCY: // show the channel frequency
#ifdef ENABLE_BIG_FREQ
NUMBER_ToDigits(frequency, String);
// show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false, false);
sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000);
#ifdef ENABLE_BIG_FREQ
if(frequency < 100000000) {
// show the remaining 2 small frequency digits
UI_DisplaySmallDigits(2, String + 6, 113, line + 1, true);
#else
UI_PrintStringSmall(String + 7, 113, 0, line + 1);
String[7] = 0;
// show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false);
}
else
#endif
{
// show the frequency in the main font
sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000);
UI_PrintString(String, 32, 0, line, 8);
#endif
}
break;
case MDF_CHANNEL: // show the channel number
@@ -557,18 +479,15 @@ void UI_DisplayMain(void)
sprintf(String, "CH-%03u", gEeprom.ScreenChannel[vfo_num] + 1);
}
if (gEeprom.CHANNEL_DISPLAY_MODE == MDF_NAME)
{
if (gEeprom.CHANNEL_DISPLAY_MODE == MDF_NAME) {
UI_PrintString(String, 32, 0, line, 8);
}
else
{
#ifdef ENABLE_SMALL_BOLD
UI_PrintStringSmallBold(String, 32 + 4, 0, line);
#else
UI_PrintStringSmall(String, 32 + 4, 0, line);
#endif
else {
#ifdef ENABLE_SMALL_BOLD
UI_PrintStringSmallBold(String, 32 + 4, 0, line);
#else
UI_PrintStringSmall(String, 32 + 4, 0, line);
#endif
// 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);
@@ -576,31 +495,34 @@ void UI_DisplayMain(void)
break;
}
#pragma GCC diagnostic pop
}
else
{ // frequency mode
#ifdef ENABLE_BIG_FREQ
NUMBER_ToDigits(frequency, String); // 8 digits
// show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false, false);
sprintf(String, "%3u.%05u", frequency / 100000, frequency % 100000);
#ifdef ENABLE_BIG_FREQ
if(frequency < 100000000) {
// show the remaining 2 small frequency digits
UI_DisplaySmallDigits(2, String + 6, 113, line + 1, true);
#else
UI_PrintStringSmall(String + 7, 113, 0, line + 1);
String[7] = 0;
// show the main large frequency digits
UI_DisplayFrequency(String, 32, line, false);
}
else
#endif
{
// show the frequency in the main font
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]];
if ((attributes & MR_CH_COMPAND) > 0)
#ifdef ENABLE_BIG_FREQ
memmove(p_line0 + 120, BITMAP_compand, sizeof(BITMAP_compand));
#else
memmove(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
#endif
#ifdef ENABLE_BIG_FREQ
memmove(p_line0 + 120, BITMAP_compand, sizeof(BITMAP_compand));
#else
memmove(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
#endif
}
}
@@ -627,8 +549,8 @@ void UI_DisplayMain(void)
Level = gVFO_RSSI_bar_level[vfo_num];
#endif
}
UI_drawBars(p_line1 + LCD_WIDTH, Level);
if(Level)
DrawSmallAntennaAndBars(p_line1 + LCD_WIDTH, Level);
}
// ************
@@ -696,38 +618,35 @@ void UI_DisplayMain(void)
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING);
#ifdef ENABLE_AUDIO_BAR
if (gSetting_mic_bar && gCurrentFunction == FUNCTION_TRANSMIT)
{
center_line = CENTER_LINE_AUDIO_BAR;
UI_DisplayAudioBar();
}
else
#endif
#ifdef ENABLE_AUDIO_BAR
if (gSetting_mic_bar && gCurrentFunction == FUNCTION_TRANSMIT) {
center_line = CENTER_LINE_AUDIO_BAR;
UI_DisplayAudioBar();
}
else
#endif
#if defined(ENABLE_AM_FIX) && defined(ENABLE_AM_FIX_SHOW_DATA)
if (rx && gEeprom.VfoInfo[gEeprom.RX_VFO].AM_mode && gSetting_AM_fix)
{
if (gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE)
return;
#if defined(ENABLE_AM_FIX) && defined(ENABLE_AM_FIX_SHOW_DATA)
if (rx && gEeprom.VfoInfo[gEeprom.RX_VFO].AM_mode && gSetting_AM_fix)
{
if (gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE)
return;
center_line = CENTER_LINE_AM_FIX_DATA;
AM_fix_print_data(gEeprom.RX_VFO, String);
UI_PrintStringSmall(String, 2, 0, 3);
}
else
#endif
#ifdef ENABLE_RSSI_BAR
if (rx)
{
center_line = CENTER_LINE_RSSI;
UI_DisplayRSSIBar(gCurrentRSSI[gEeprom.RX_VFO], false);
}
else
#endif
center_line = CENTER_LINE_AM_FIX_DATA;
AM_fix_print_data(gEeprom.RX_VFO, String);
UI_PrintStringSmall(String, 2, 0, 3);
}
else
#endif
#ifdef ENABLE_RSSI_BAR
if (rx) {
center_line = CENTER_LINE_RSSI;
DisplayRSSIBar(gCurrentRSSI[gEeprom.RX_VFO], false);
}
else
#endif
if (rx || gCurrentFunction == FUNCTION_FOREGROUND || gCurrentFunction == FUNCTION_POWER_SAVE)
{
#if 1
@@ -764,22 +683,21 @@ void UI_DisplayMain(void)
}
#endif
#ifdef ENABLE_SHOW_CHARGE_LEVEL
else
if (gChargingWithTypeC)
{ // charging .. show the battery state
if (gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE)
return;
#ifdef ENABLE_SHOW_CHARGE_LEVEL
else if (gChargingWithTypeC)
{ // charging .. show the battery state
if (gScreenToDisplay != DISPLAY_MAIN ||
gDTMF_CallState != DTMF_CALL_STATE_NONE)
return;
center_line = CENTER_LINE_CHARGE_DATA;
center_line = CENTER_LINE_CHARGE_DATA;
sprintf(String, "Charge %u.%02uV %u%%",
gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100,
BATTERY_VoltsToPercent(gBatteryVoltageAverage));
UI_PrintStringSmall(String, 2, 0, 3);
}
#endif
sprintf(String, "Charge %u.%02uV %u%%",
gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100,
BATTERY_VoltsToPercent(gBatteryVoltageAverage));
UI_PrintStringSmall(String, 2, 0, 3);
}
#endif
}
}

309
ui/menu.c
View File

@@ -36,106 +36,112 @@
#include "ui/menu.h"
#include "ui/ui.h"
// NOTE. this menu list is half way through a change, what might seem
// pointless at this time is for there for a reason.
//
const t_menu_item MenuList[] =
{
// text, voice ID, menu ID
{"SQL", VOICE_ID_SQUELCH, MENU_SQL },
{"STEP", VOICE_ID_FREQUENCY_STEP, MENU_STEP },
{"T PWR", VOICE_ID_POWER, MENU_TXP }, // was "TXP"
{"R DCS", VOICE_ID_DCS, MENU_R_DCS }, // was "R_DCS"
{"R CTCS", VOICE_ID_CTCSS, MENU_R_CTCS }, // was "R_CTCS"
{"T DCS", VOICE_ID_DCS, MENU_T_DCS }, // was "T_DCS"
{"T CTCS", VOICE_ID_CTCSS, MENU_T_CTCS }, // was "T_CTCS"
{"T DIR", VOICE_ID_TX_OFFSET_FREQUENCY_DIRECTION, MENU_SFT_D }, // was "SFT_D"
{"T OFFS", VOICE_ID_TX_OFFSET_FREQUENCY, MENU_OFFSET }, // was "OFFSET"
{"T VFO", VOICE_ID_INVALID, MENU_XB }, // was "WX"
{"T TOUT", VOICE_ID_TRANSMIT_OVER_TIME, MENU_TOT }, // was "TOT"
{"Step", VOICE_ID_FREQUENCY_STEP, MENU_STEP },
{"TxPwr", VOICE_ID_POWER, MENU_TXP }, // was "TXP"
{"RxDCS", VOICE_ID_DCS, MENU_R_DCS }, // was "R_DCS"
{"RxCTCS", VOICE_ID_CTCSS, MENU_R_CTCS }, // was "R_CTCS"
{"TxDCS", VOICE_ID_DCS, MENU_T_DCS }, // was "T_DCS"
{"TxCTCS", VOICE_ID_CTCSS, MENU_T_CTCS }, // was "T_CTCS"
{"TxODir", VOICE_ID_TX_OFFSET_FREQUENCY_DIRECTION, MENU_SFT_D }, // was "SFT_D"
{"TxOffs", VOICE_ID_TX_OFFSET_FREQUENCY, MENU_OFFSET }, // was "OFFSET"
{"W/N", VOICE_ID_CHANNEL_BANDWIDTH, MENU_W_N },
{"SCRAM", VOICE_ID_SCRAMBLER_ON, MENU_SCR }, // was "SCR"
{"BUSYCL", VOICE_ID_BUSY_LOCKOUT, MENU_BCL }, // was "BCL"
{"CH SAV", VOICE_ID_MEMORY_CHANNEL, MENU_MEM_CH }, // was "MEM-CH"
{"CH DEL", VOICE_ID_DELETE_CHANNEL, MENU_DEL_CH }, // was "DEL-CH"
{"CH NAM", VOICE_ID_INVALID, MENU_MEM_NAME },
{"CH DIS", VOICE_ID_INVALID, MENU_MDF }, // was "MDF"
{"BATSAV", VOICE_ID_SAVE_MODE, MENU_SAVE }, // was "SAVE"
#ifdef ENABLE_VOX
{"VOX", VOICE_ID_VOX, MENU_VOX },
{"Scramb", VOICE_ID_SCRAMBLER_ON, MENU_SCR }, // was "SCR"
{"BusyCL", VOICE_ID_BUSY_LOCKOUT, MENU_BCL }, // was "BCL"
{"Compnd", VOICE_ID_INVALID, MENU_COMPAND },
{"Demodu", VOICE_ID_INVALID, MENU_AM }, // was "AM"
{"ScAdd1", VOICE_ID_INVALID, MENU_S_ADD1 },
{"ScAdd2", VOICE_ID_INVALID, MENU_S_ADD2 },
{"ChSave", VOICE_ID_MEMORY_CHANNEL, MENU_MEM_CH }, // was "MEM-CH"
{"ChDele", VOICE_ID_DELETE_CHANNEL, MENU_DEL_CH }, // was "DEL-CH"
{"ChName", VOICE_ID_INVALID, MENU_MEM_NAME },
{"SList", VOICE_ID_INVALID, MENU_S_LIST },
{"SList1", VOICE_ID_INVALID, MENU_SLIST1 },
{"SList2", VOICE_ID_INVALID, MENU_SLIST2 },
{"ScnRev", VOICE_ID_INVALID, MENU_SC_REV },
#ifdef ENABLE_NOAA
{"NOAA-S", VOICE_ID_INVALID, MENU_NOAA_S },
#endif
{"BLT", VOICE_ID_INVALID, MENU_ABR }, // was "ABR"
{"BLTTRX", VOICE_ID_INVALID, MENU_ABR_ON_TX_RX },
{"DUALRX", VOICE_ID_DUAL_STANDBY, MENU_TDR }, // was "TDR"
{"BEEP", VOICE_ID_BEEP_PROMPT, MENU_BEEP },
{"F1Shrt", VOICE_ID_INVALID, MENU_F1SHRT },
{"F1Long", VOICE_ID_INVALID, MENU_F1LONG },
{"F2Shrt", VOICE_ID_INVALID, MENU_F2SHRT },
{"F2Long", VOICE_ID_INVALID, MENU_F2LONG },
{"M Long", VOICE_ID_INVALID, MENU_MLONG },
{"KeyLck", VOICE_ID_INVALID, MENU_AUTOLK }, // was "AUTOLk"
{"TxTOut", VOICE_ID_TRANSMIT_OVER_TIME, MENU_TOT }, // was "TOT"
{"BatSav", VOICE_ID_SAVE_MODE, MENU_SAVE }, // was "SAVE"
{"Mic", VOICE_ID_INVALID, MENU_MIC },
#ifdef ENABLE_AUDIO_BAR
{"MicBar", VOICE_ID_INVALID, MENU_MIC_BAR },
#endif
{"ChDisp", VOICE_ID_INVALID, MENU_MDF }, // was "MDF"
{"POnMsg", VOICE_ID_INVALID, MENU_PONMSG },
{"BatTxt", VOICE_ID_INVALID, MENU_BAT_TXT },
{"BackLt", VOICE_ID_INVALID, MENU_ABR }, // was "ABR"
{"BLMin", VOICE_ID_INVALID, MENU_ABR_MIN },
{"BLMax", VOICE_ID_INVALID, MENU_ABR_MAX },
{"BltTRX", VOICE_ID_INVALID, MENU_ABR_ON_TX_RX },
{"Beep", VOICE_ID_BEEP_PROMPT, MENU_BEEP },
#ifdef ENABLE_VOICE
{"VOICE", VOICE_ID_VOICE_PROMPT, MENU_VOICE },
{"Voice", VOICE_ID_VOICE_PROMPT, MENU_VOICE },
#endif
{"SC REV", VOICE_ID_INVALID, MENU_SC_REV },
{"KEYLOC", VOICE_ID_INVALID, MENU_AUTOLK }, // was "AUTOLk"
{"S ADD1", VOICE_ID_INVALID, MENU_S_ADD1 },
{"S ADD2", VOICE_ID_INVALID, MENU_S_ADD2 },
{"Roger", VOICE_ID_INVALID, MENU_ROGER },
{"STE", VOICE_ID_INVALID, MENU_STE },
{"RP STE", VOICE_ID_INVALID, MENU_RP_STE },
{"MIC", VOICE_ID_INVALID, MENU_MIC },
#ifdef ENABLE_AUDIO_BAR
{"MICBAR", VOICE_ID_INVALID, MENU_MIC_BAR },
#endif
{"COMPND", VOICE_ID_INVALID, MENU_COMPAND },
{"1 CALL", VOICE_ID_INVALID, MENU_1_CALL },
{"SLIST", VOICE_ID_INVALID, MENU_S_LIST },
{"SLIST1", VOICE_ID_INVALID, MENU_SLIST1 },
{"SLIST2", VOICE_ID_INVALID, MENU_SLIST2 },
{"1 Call", VOICE_ID_INVALID, MENU_1_CALL },
#ifdef ENABLE_ALARM
{"AL-MOD", VOICE_ID_INVALID, MENU_AL_MOD },
{"AlarmT", VOICE_ID_INVALID, MENU_AL_MOD },
#endif
{"ANI ID", VOICE_ID_ANI_CODE, MENU_ANI_ID },
{"UPCODE", VOICE_ID_INVALID, MENU_UPCODE },
{"DWCODE", VOICE_ID_INVALID, MENU_DWCODE },
{"UPCode", VOICE_ID_INVALID, MENU_UPCODE },
{"DWCode", VOICE_ID_INVALID, MENU_DWCODE },
{"PTT ID", VOICE_ID_INVALID, MENU_PTT_ID },
{"D ST", VOICE_ID_INVALID, MENU_D_ST },
{"D RSP", VOICE_ID_INVALID, MENU_D_RSP },
{"D HOLD", VOICE_ID_INVALID, MENU_D_HOLD },
{"D PRE", VOICE_ID_INVALID, MENU_D_PRE },
{"D DCD", VOICE_ID_INVALID, MENU_D_DCD },
{"D LIST", VOICE_ID_INVALID, MENU_D_LIST },
{"D LIVE", VOICE_ID_INVALID, MENU_D_LIVE_DEC }, // live DTMF decoder
{"PONMSG", VOICE_ID_INVALID, MENU_PONMSG },
{"ROGER", VOICE_ID_INVALID, MENU_ROGER },
{"BATVOL", VOICE_ID_INVALID, MENU_VOL }, // was "VOL"
{"BATTXT", VOICE_ID_INVALID, MENU_BAT_TXT },
{"MODE", VOICE_ID_INVALID, MENU_AM }, // was "AM"
{"D Resp", VOICE_ID_INVALID, MENU_D_RSP },
{"D Hold", VOICE_ID_INVALID, MENU_D_HOLD },
{"D Prel", VOICE_ID_INVALID, MENU_D_PRE },
{"D Decd", VOICE_ID_INVALID, MENU_D_DCD },
{"D List", VOICE_ID_INVALID, MENU_D_LIST },
{"D Live", VOICE_ID_INVALID, MENU_D_LIVE_DEC }, // live DTMF decoder
#ifdef ENABLE_AM_FIX
{"AM FIX", VOICE_ID_INVALID, MENU_AM_FIX },
{"AM Fix", VOICE_ID_INVALID, MENU_AM_FIX },
#endif
#ifdef ENABLE_AM_FIX_TEST1
{"AM FT1", VOICE_ID_INVALID, MENU_AM_FIX_TEST1 },
#endif
#ifdef ENABLE_NOAA
{"NOAA-S", VOICE_ID_INVALID, MENU_NOAA_S },
#ifdef ENABLE_VOX
{"VOX", VOICE_ID_VOX, MENU_VOX },
#endif
{"RESET", VOICE_ID_INITIALISATION, MENU_RESET }, // might be better to move this to the hidden menu items ?
{"BatVol", VOICE_ID_INVALID, MENU_VOL }, // was "VOL"
{"RxMode", VOICE_ID_DUAL_STANDBY, MENU_TDR },
{"Sql", VOICE_ID_SQUELCH, MENU_SQL },
// hidden menu items from here on
// enabled if pressing both the PTT and upper side button at power-on
{"F LOCK", VOICE_ID_INVALID, MENU_F_LOCK },
{"TX 200", VOICE_ID_INVALID, MENU_200TX }, // was "200TX"
{"TX 350", VOICE_ID_INVALID, MENU_350TX }, // was "350TX"
{"TX 500", VOICE_ID_INVALID, MENU_500TX }, // was "500TX"
{"350 EN", VOICE_ID_INVALID, MENU_350EN }, // was "350EN"
{"SCR EN", VOICE_ID_INVALID, MENU_SCREN }, // was "SCREN"
{"TX EN", VOICE_ID_INVALID, MENU_TX_EN }, // enable TX
{"F Lock", VOICE_ID_INVALID, MENU_F_LOCK },
{"Tx 200", VOICE_ID_INVALID, MENU_200TX }, // was "200TX"
{"Tx 350", VOICE_ID_INVALID, MENU_350TX }, // was "350TX"
{"Tx 500", VOICE_ID_INVALID, MENU_500TX }, // was "500TX"
{"350 En", VOICE_ID_INVALID, MENU_350EN }, // was "350EN"
{"ScraEn", VOICE_ID_INVALID, MENU_SCREN }, // was "SCREN"
{"TxEnab", VOICE_ID_INVALID, MENU_TX_EN }, // enable TX
#ifdef ENABLE_F_CAL_MENU
{"F CALI", VOICE_ID_INVALID, MENU_F_CALI }, // reference xtal calibration
{"FrCali", VOICE_ID_INVALID, MENU_F_CALI }, // reference xtal calibration
#endif
{"BATCAL", VOICE_ID_INVALID, MENU_BATCAL }, // battery voltage calibration
{"BatCal", VOICE_ID_INVALID, MENU_BATCAL }, // battery voltage calibration
{"BatTyp", VOICE_ID_INVALID, MENU_BATTYP }, // battery type 1600/2200mAh
{"Reset", VOICE_ID_INITIALISATION, MENU_RESET }, // might be better to move this to the hidden menu items ?
{"", VOICE_ID_INVALID, 0xff } // end of list - DO NOT delete or move this this
};
const uint8_t FIRST_HIDDEN_MENU_ITEM = MENU_F_LOCK;
const char gSubMenu_TXP[3][5] =
{
"LOW",
@@ -186,18 +192,12 @@ const char gSubMenu_TOT[11][7] =
"15 min"
};
const char gSubMenu_CHAN[3][10] =
const char* gSubMenu_RXMode[4] =
{
"OFF",
"UPPER\nVFO",
"LOWER\nVFO"
};
const char gSubMenu_XB[3][10] =
{
"RX\nVFO",
"UPPER\nVFO",
"LOWER\nVFO"
"MAIN\nONLY", // TX and RX on main only
"DUAL RX\nRESPOND", // Watch both and respond
"CROSS\nBAND", // TX on main, RX on secondary
"MAIN TX\nDUAL RX" // always TX on main, but RX on both
};
#ifdef ENABLE_VOICE
@@ -209,14 +209,14 @@ const char gSubMenu_XB[3][10] =
};
#endif
const char gSubMenu_SC_REV[3][13] =
const char gSubMenu_SC_REV[3][8] =
{
"TIME",
"TIMEOUT",
"CARRIER",
"SEARCH"
"STOP"
};
const char gSubMenu_MDF[4][15] =
const char* gSubMenu_MDF[4] =
{
"FREQ",
"CHANNEL\nNUMBER",
@@ -240,7 +240,7 @@ const char gSubMenu_D_RSP[4][11] =
"BOTH"
};
const char gSubMenu_PTT_ID[5][15] =
const char* gSubMenu_PTT_ID[5] =
{
"OFF",
"KEY\nUP",
@@ -257,7 +257,7 @@ const char gSubMenu_PONMSG[4][8] =
"NONE"
};
const char gSubMenu_ROGER[3][9] =
const char* gSubMenu_ROGER[3] =
{
"OFF",
"ROGER",
@@ -317,6 +317,12 @@ const char gSubMenu_BAT_TXT[3][8] =
"PERCENT"
};
const char gSubMenu_BATTYP[2][9] =
{
"1600mAh",
"2200mAh"
};
const char gSubMenu_SCRAMBLER[11][7] =
{
"OFF",
@@ -332,8 +338,41 @@ const char gSubMenu_SCRAMBLER[11][7] =
"3500Hz"
};
const t_sidefunction SIDEFUNCTIONS[] =
{
{"NONE", ACTION_OPT_NONE},
{"FLASH\nLIGHT", ACTION_OPT_FLASHLIGHT},
{"POWER", ACTION_OPT_POWER},
{"MONITOR", ACTION_OPT_MONITOR},
{"SCAN", ACTION_OPT_SCAN},
#ifdef ENABLE_VOX
{"VOX", ACTION_OPT_VOX},
#endif
#ifdef ENABLE_ALARM
{"ALARM", ACTION_OPT_ALARM},
#endif
#ifdef ENABLE_FMRADIO
{"FM RADIO", ACTION_OPT_FM},
#endif
#ifdef ENABLE_TX1750
{"1750HZ", ACTION_OPT_1750},
#endif
{"LOCK\nKEYPAD", ACTION_OPT_KEYLOCK},
{"SWITCH\nVFO", ACTION_OPT_A_B},
{"VFO/MR", ACTION_OPT_VFO_MR},
};
const t_sidefunction* gSubMenu_SIDEFUNCTIONS = SIDEFUNCTIONS;
const uint8_t gSubMenu_SIDEFUNCTIONS_size = ARRAY_SIZE(SIDEFUNCTIONS);
bool gIsInSubMenu;
uint8_t gMenuCursor;
int GetCurrentMenuId() {
if(gMenuCursor < ARRAY_SIZE(MenuList))
return MenuList[gMenuCursor].menu_id;
else
return MenuList[ARRAY_SIZE(MenuList)-1].menu_id;
}
int8_t gMenuScrollDirection;
int32_t gSubMenuSelection;
@@ -437,10 +476,7 @@ void UI_DisplayMenu(void)
bool already_printed = false;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough="
switch (gMenuCursor)
switch (GetCurrentMenuId())
{
case MENU_SQL:
sprintf(String, "%d", gSubMenuSelection);
@@ -483,7 +519,7 @@ void UI_DisplayMenu(void)
{
#if 1
unsigned int Code;
FREQ_Config_t *pConfig = (gMenuCursor == MENU_R_CTCS) ? &gTxVfo->freq_config_RX : &gTxVfo->freq_config_TX;
FREQ_Config_t *pConfig = (GetCurrentMenuId() == MENU_R_CTCS) ? &gTxVfo->freq_config_RX : &gTxVfo->freq_config_TX;
if (gSubMenuSelection == 0)
{
strcpy(String, "OFF");
@@ -523,21 +559,13 @@ void UI_DisplayMenu(void)
case MENU_OFFSET:
if (!gIsInSubMenu || gInputBoxIndex == 0)
{
sprintf(String, "%d.%05u", gSubMenuSelection / 100000, abs(gSubMenuSelection) % 100000);
sprintf(String, "%3d.%05u", gSubMenuSelection / 100000, abs(gSubMenuSelection) % 100000);
UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8);
}
else
{
for (i = 0; i < 3; i++)
String[i ] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0';
String[3] = '.';
for (i = 3; i < 6; i++)
String[i + 1] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0';
String[ 7] = '-';
String[ 8] = '-';
String[ 9] = 0;
String[10] = 0;
String[11] = 0;
const char * ascii = INPUTBOX_GetAscii();
sprintf(String, "%.3s.%.3s ",ascii, ascii + 3);
UI_PrintString(String, menu_item_x1, menu_item_x2, 1, 8);
}
@@ -571,8 +599,18 @@ void UI_DisplayMenu(void)
case MENU_ABR:
strcpy(String, gSubMenu_BACKLIGHT[gSubMenuSelection]);
BACKLIGHT_SetBrightness(-1);
break;
case MENU_ABR_MIN:
case MENU_ABR_MAX:
sprintf(String, "%d", gSubMenuSelection);
if(gIsInSubMenu)
BACKLIGHT_SetBrightness(gSubMenuSelection);
else
BACKLIGHT_SetBrightness(-1);
break;
case MENU_AM:
strcpy(String, (gSubMenuSelection == 0) ? "FM" : "AM");
break;
@@ -680,11 +718,7 @@ void UI_DisplayMenu(void)
break;
case MENU_TDR:
strcpy(String, gSubMenu_CHAN[gSubMenuSelection]);
break;
case MENU_XB:
strcpy(String, gSubMenu_XB[gSubMenuSelection]);
strcpy(String, gSubMenu_RXMode[gSubMenuSelection]);
break;
case MENU_TOT:
@@ -808,9 +842,20 @@ void UI_DisplayMenu(void)
sprintf(String, "%u.%02uV\n%u", vol / 100, vol % 100, gSubMenuSelection);
break;
}
}
#pragma GCC diagnostic pop
case MENU_BATTYP:
strcpy(String, gSubMenu_BATTYP[gSubMenuSelection]);
break;
case MENU_F1SHRT:
case MENU_F1LONG:
case MENU_F2SHRT:
case MENU_F2LONG:
case MENU_MLONG:
strcpy(String, gSubMenu_SIDEFUNCTIONS[gSubMenuSelection].name);
break;
}
if (!already_printed)
{ // we now do multi-line text in a single string
@@ -866,9 +911,9 @@ void UI_DisplayMenu(void)
}
}
if (gMenuCursor == MENU_SLIST1 || gMenuCursor == MENU_SLIST2)
if (GetCurrentMenuId() == MENU_SLIST1 || GetCurrentMenuId() == MENU_SLIST2)
{
i = (gMenuCursor == MENU_SLIST1) ? 0 : 1;
i = (GetCurrentMenuId() == MENU_SLIST1) ? 0 : 1;
// if (gSubMenuSelection == 0xFF)
if (gSubMenuSelection < 0)
@@ -913,9 +958,9 @@ void UI_DisplayMenu(void)
}
}
if (gMenuCursor == MENU_MEM_CH ||
gMenuCursor == MENU_DEL_CH ||
gMenuCursor == MENU_1_CALL)
if (GetCurrentMenuId() == MENU_MEM_CH ||
GetCurrentMenuId() == MENU_DEL_CH ||
GetCurrentMenuId() == MENU_1_CALL)
{ // display the channel name
char s[11];
BOARD_fetchChannelName(s, gSubMenuSelection);
@@ -924,18 +969,18 @@ void UI_DisplayMenu(void)
UI_PrintString(s, menu_item_x1, menu_item_x2, 2, 8);
}
if ((gMenuCursor == MENU_R_CTCS || gMenuCursor == MENU_R_DCS) && gCssScanMode != CSS_SCAN_MODE_OFF)
if ((GetCurrentMenuId() == MENU_R_CTCS || GetCurrentMenuId() == MENU_R_DCS) && gCssScanMode != CSS_SCAN_MODE_OFF)
UI_PrintString("SCAN", menu_item_x1, menu_item_x2, 4, 8);
if (gMenuCursor == MENU_UPCODE)
if (GetCurrentMenuId() == MENU_UPCODE)
if (strlen(gEeprom.DTMF_UP_CODE) > 8)
UI_PrintString(gEeprom.DTMF_UP_CODE + 8, menu_item_x1, menu_item_x2, 4, 8);
if (gMenuCursor == MENU_DWCODE)
if (GetCurrentMenuId() == MENU_DWCODE)
if (strlen(gEeprom.DTMF_DOWN_CODE) > 8)
UI_PrintString(gEeprom.DTMF_DOWN_CODE + 8, menu_item_x1, menu_item_x2, 4, 8);
if (gMenuCursor == MENU_D_LIST && gIsDtmfContactValid)
if (GetCurrentMenuId() == MENU_D_LIST && gIsDtmfContactValid)
{
Contact[11] = 0;
memmove(&gDTMF_ID, Contact + 8, 4);
@@ -943,22 +988,20 @@ void UI_DisplayMenu(void)
UI_PrintString(String, menu_item_x1, menu_item_x2, 4, 8);
}
if (gMenuCursor == MENU_R_CTCS ||
gMenuCursor == MENU_T_CTCS ||
gMenuCursor == MENU_R_DCS ||
gMenuCursor == MENU_T_DCS ||
gMenuCursor == MENU_D_LIST)
if (GetCurrentMenuId() == MENU_R_CTCS ||
GetCurrentMenuId() == MENU_T_CTCS ||
GetCurrentMenuId() == MENU_R_DCS ||
GetCurrentMenuId() == MENU_T_DCS ||
GetCurrentMenuId() == MENU_D_LIST)
{
unsigned int Offset;
NUMBER_ToDigits(gSubMenuSelection, String);
Offset = (gMenuCursor == MENU_D_LIST) ? 2 : 3;
UI_DisplaySmallDigits(Offset, String + (8 - Offset), 105, 0, false);
sprintf(String, "%2d", gSubMenuSelection);
UI_PrintStringSmall(String, 105, 0, 0);
}
if ((gMenuCursor == MENU_RESET ||
gMenuCursor == MENU_MEM_CH ||
gMenuCursor == MENU_MEM_NAME ||
gMenuCursor == MENU_DEL_CH) && gAskForConfirmation)
if ((GetCurrentMenuId() == MENU_RESET ||
GetCurrentMenuId() == MENU_MEM_CH ||
GetCurrentMenuId() == MENU_MEM_NAME ||
GetCurrentMenuId() == MENU_DEL_CH) && gAskForConfirmation)
{ // display confirmation
strcpy(String, (gAskForConfirmation == 1) ? "SURE?" : "WAIT!");
UI_PrintString(String, menu_item_x1, menu_item_x2, 5, 8);

View File

@@ -39,7 +39,6 @@ enum
MENU_T_CTCS,
MENU_SFT_D,
MENU_OFFSET,
MENU_XB,
MENU_TOT,
MENU_W_N,
MENU_SCR,
@@ -54,6 +53,8 @@ enum
#endif
MENU_ABR,
MENU_ABR_ON_TX_RX,
MENU_ABR_MIN,
MENU_ABR_MAX,
MENU_TDR,
MENU_BEEP,
#ifdef ENABLE_VOICE
@@ -103,9 +104,6 @@ enum
MENU_NOAA_S,
#endif
MENU_RESET,
// items after here are normally hidden
MENU_F_LOCK,
MENU_200TX,
MENU_350TX,
@@ -117,9 +115,16 @@ enum
#ifdef ENABLE_F_CAL_MENU
MENU_F_CALI, // reference xtal calibration
#endif
MENU_BATCAL // battery voltage calibration
MENU_BATCAL, // battery voltage calibration
MENU_F1SHRT,
MENU_F1LONG,
MENU_F2SHRT,
MENU_F2LONG,
MENU_MLONG,
MENU_BATTYP
};
extern const uint8_t FIRST_HIDDEN_MENU_ITEM;
extern const t_menu_item MenuList[];
extern const char gSubMenu_TXP[3][5];
@@ -128,20 +133,20 @@ extern const char gSubMenu_W_N[2][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][10];
extern const char gSubMenu_XB[3][10];
extern const char* gSubMenu_RXMode[4];
#ifdef ENABLE_VOICE
extern const char gSubMenu_VOICE[3][4];
#endif
extern const char gSubMenu_SC_REV[3][13];
extern const char gSubMenu_MDF[4][15];
extern const char gSubMenu_SC_REV[3][8];
extern const char* gSubMenu_MDF[4];
#ifdef ENABLE_ALARM
extern const char gSubMenu_AL_MOD[2][5];
#endif
extern const char gSubMenu_D_RSP[4][11];
extern const char gSubMenu_PTT_ID[5][15];
extern const char* gSubMenu_PTT_ID[5];
extern const char gSubMenu_PONMSG[4][8];
extern const char gSubMenu_ROGER[3][9];
extern const char* gSubMenu_ROGER[3];
extern const char gSubMenu_RESET[2][4];
extern const char gSubMenu_F_LOCK[6][4];
extern const char gSubMenu_BACKLIGHT[8][7];
@@ -150,12 +155,17 @@ extern const char gSubMenu_RX_TX[4][6];
extern const char gSubMenu_AM_fix_test1[4][8];
#endif
extern const char gSubMenu_BAT_TXT[3][8];
extern const char gSubMenu_BATTYP[2][9];
extern const char gSubMenu_SCRAMBLER[11][7];
typedef struct {char* name; uint8_t id;} t_sidefunction;
extern const uint8_t gSubMenu_SIDEFUNCTIONS_size;
extern const t_sidefunction* gSubMenu_SIDEFUNCTIONS;
extern bool gIsInSubMenu;
extern uint8_t gMenuCursor;
int GetCurrentMenuId();
extern int8_t gMenuScrollDirection;
extern int32_t gSubMenuSelection;

View File

@@ -33,7 +33,7 @@
#include "ui/ui.h"
#include "ui/status.h"
void UI_DisplayStatus(const bool test_display)
void UI_DisplayStatus()
{
uint8_t *line = gStatusLine;
unsigned int x = 0;
@@ -60,7 +60,7 @@ void UI_DisplayStatus(const bool test_display)
x1 = x + sizeof(BITMAP_RX);
}
else
if (gCurrentFunction == FUNCTION_POWER_SAVE || test_display)
if (gCurrentFunction == FUNCTION_POWER_SAVE)
{
memmove(line + x, BITMAP_POWERSAVE, sizeof(BITMAP_POWERSAVE));
x1 = x + sizeof(BITMAP_POWERSAVE);
@@ -69,7 +69,7 @@ void UI_DisplayStatus(const bool test_display)
#ifdef ENABLE_NOAA
// NOASS SCAN indicator
if (gIsNoaaMode || test_display)
if (gIsNoaaMode)
{
memmove(line + x, BITMAP_NOAA, sizeof(BITMAP_NOAA));
x1 = x + sizeof(BITMAP_NOAA);
@@ -85,79 +85,69 @@ void UI_DisplayStatus(const bool test_display)
x1 = x + 10;
}
else
#ifdef ENABLE_FMRADIO
// FM indicator
if (gFmRadioMode || test_display)
{
memmove(line + x, BITMAP_FM, sizeof(BITMAP_FM));
x1 = x + sizeof(BITMAP_FM);
}
else
#endif
// SCAN indicator
if (gScanStateDir != SCAN_OFF || gScreenToDisplay == DISPLAY_SCANNER || test_display)
if (gScanStateDir != SCAN_OFF || gScreenToDisplay == DISPLAY_SCANNER)
{
if (gNextMrChannel <= MR_CHANNEL_LAST)
char * s = "";
if (IS_MR_CHANNEL(gNextMrChannel) && gScreenToDisplay != DISPLAY_SCANNER)
{ // channel mode
if (gEeprom.SCAN_LIST_DEFAULT == 0)
UI_PrintStringSmallBuffer("1", line + x);
else
if (gEeprom.SCAN_LIST_DEFAULT == 1)
UI_PrintStringSmallBuffer("2", line + x);
else
if (gEeprom.SCAN_LIST_DEFAULT == 2)
UI_PrintStringSmallBuffer("*", line + x);
switch(gEeprom.SCAN_LIST_DEFAULT) {
case 0: s = "1"; break;
case 1: s = "2"; break;
case 2: s = "*"; break;
}
}
else
{ // frequency mode
UI_PrintStringSmallBuffer("S", line + x);
s = "S";
}
UI_PrintStringSmallBuffer(s, line + x);
x1 = x + 7;
}
x += 7; // font character width
#ifdef ENABLE_VOICE
// VOICE indicator
if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF || test_display)
if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF)
{
memmove(line + x, BITMAP_VoicePrompt, sizeof(BITMAP_VoicePrompt));
x1 = x + sizeof(BITMAP_VoicePrompt);
}
x += sizeof(BITMAP_VoicePrompt);
x += sizeof(BITMAP_VoicePrompt) + 1;
#else
// hmmm, what to put in it's place
#endif
// DUAL-WATCH indicator
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF || test_display)
{
if (gDualWatchActive || test_display)
memmove(line + x, BITMAP_TDR1, sizeof(BITMAP_TDR1));
else
memmove(line + x, BITMAP_TDR2, sizeof(BITMAP_TDR2));
x++;
if(gScreenToDisplay != DISPLAY_SCANNER) {
uint8_t dw = (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) + (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) * 2;
if(dw == 1 || dw == 3) { // DWR - dual watch + respond
if(gDualWatchActive)
memmove(line + x, BITMAP_TDR1, sizeof(BITMAP_TDR1) - (dw==1?0:5));
else
memmove(line + x + 3, BITMAP_TDR2, sizeof(BITMAP_TDR2));
}
else if(dw == 2) { // XB - crossband
memmove(line + x, BITMAP_XB, sizeof(BITMAP_XB));
}
}
x += sizeof(BITMAP_TDR1);
// CROSS-VFO indicator
if (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF || test_display)
{
memmove(line + x, BITMAP_XB, sizeof(BITMAP_XB));
x1 = x + sizeof(BITMAP_XB);
}
x += sizeof(BITMAP_XB);
x += sizeof(BITMAP_TDR1) + 2;
#ifdef ENABLE_VOX
// VOX indicator
if (gEeprom.VOX_SWITCH || test_display)
if (gEeprom.VOX_SWITCH)
{
memmove(line + x, BITMAP_VOX, sizeof(BITMAP_VOX));
x1 = x + sizeof(BITMAP_VOX);
}
x += sizeof(BITMAP_VOX);
x += sizeof(BITMAP_VOX) + 2;
#endif
x = MAX(x, 61u);
x1 = x;
// KEY-LOCK indicator
if (gEeprom.KEY_LOCK || test_display)
if (gEeprom.KEY_LOCK)
{
memmove(line + x, BITMAP_KeyLock, sizeof(BITMAP_KeyLock));
x += sizeof(BITMAP_KeyLock);
@@ -213,7 +203,7 @@ void UI_DisplayStatus(const bool test_display)
x = LCD_WIDTH - sizeof(BITMAP_BatteryLevel1) - sizeof(BITMAP_USB_C);
// USB-C charge indicator
if (gChargingWithTypeC || test_display)
if (gChargingWithTypeC)
memmove(line + x, BITMAP_USB_C, sizeof(BITMAP_USB_C));
x += sizeof(BITMAP_USB_C);

View File

@@ -17,7 +17,7 @@
#ifndef UI_STATUS_H
#define UI_STATUS_H
void UI_DisplayStatus(const bool test_display);
void UI_DisplayStatus();
#endif

View File

@@ -43,7 +43,6 @@ void UI_DisplayWelcome(void)
{
char WelcomeString0[16];
char WelcomeString1[16];
char WelcomeString2[16];
memset(gStatusLine, 0, sizeof(gStatusLine));
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
@@ -61,7 +60,6 @@ void UI_DisplayWelcome(void)
{
memset(WelcomeString0, 0, sizeof(WelcomeString0));
memset(WelcomeString1, 0, sizeof(WelcomeString1));
memset(WelcomeString2, 0, sizeof(WelcomeString2));
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_VOLTAGE)
{
@@ -70,10 +68,6 @@ void UI_DisplayWelcome(void)
gBatteryVoltageAverage / 100,
gBatteryVoltageAverage % 100,
BATTERY_VoltsToPercent(gBatteryVoltageAverage));
#if 0
sprintf(WelcomeString2, "Current %u", gBatteryCurrent); // needs scaling into mA
#endif
}
else
{
@@ -83,17 +77,9 @@ void UI_DisplayWelcome(void)
UI_PrintString(WelcomeString0, 0, 127, 0, 10);
UI_PrintString(WelcomeString1, 0, 127, 2, 10);
#if 0
UI_PrintStringSmall(WelcomeString2, 0, 127, 4);
#endif
UI_PrintStringSmall(Version, 0, 0, 6);
UI_PrintStringSmall(Version, 0, 0, 6);
#if 1
ST7565_BlitStatusLine(); // blank status line
#else
UI_DisplayStatus(true); // show all status line symbols (test)
#endif
ST7565_BlitStatusLine(); // blank status line
ST7565_BlitFullScreen();
}
}