This commit is contained in:
wu58430 2023-12-09 11:25:53 +08:00
parent 6f6bf98b96
commit 967f96e9e2
26 changed files with 927 additions and 851 deletions

View file

@ -22,12 +22,30 @@
<component name="ChangeListManager">
<list default="true" id="cea36e80-e289-4d69-9030-7186d540ac0e" name="更改" comment="readme add">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Makefile" beforeDir="false" afterPath="$PROJECT_DIR$/Makefile" afterDir="false" />
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/action.c" beforeDir="false" afterPath="$PROJECT_DIR$/app/action.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/action.h" beforeDir="false" afterPath="$PROJECT_DIR$/app/action.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/aircopy.c" beforeDir="false" afterPath="$PROJECT_DIR$/app/aircopy.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/app.c" beforeDir="false" afterPath="$PROJECT_DIR$/app/app.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/fm.c" beforeDir="false" afterPath="$PROJECT_DIR$/app/fm.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/main.c" beforeDir="false" afterPath="$PROJECT_DIR$/app/main.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/menu.c" beforeDir="false" afterPath="$PROJECT_DIR$/app/menu.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/main.c" beforeDir="false" afterPath="$PROJECT_DIR$/main.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/payment/payment-codes.md" beforeDir="false" afterPath="$PROJECT_DIR$/payment/payment-codes.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/spectrum.c" beforeDir="false" afterPath="$PROJECT_DIR$/app/spectrum.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/spectrum.h" beforeDir="false" afterPath="$PROJECT_DIR$/app/spectrum.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/audio.c" beforeDir="false" afterPath="$PROJECT_DIR$/audio.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/chinese.h" beforeDir="false" afterPath="$PROJECT_DIR$/chinese.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frequencies.c" beforeDir="false" afterPath="$PROJECT_DIR$/frequencies.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frequencies.h" beforeDir="false" afterPath="$PROJECT_DIR$/frequencies.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/functions.c" beforeDir="false" afterPath="$PROJECT_DIR$/functions.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/functions.h" beforeDir="false" afterPath="$PROJECT_DIR$/functions.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/misc.c" beforeDir="false" afterPath="$PROJECT_DIR$/misc.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/misc.h" beforeDir="false" afterPath="$PROJECT_DIR$/misc.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/payment/sponsors.md" beforeDir="false" afterPath="$PROJECT_DIR$/payment/sponsors.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/radio.c" beforeDir="false" afterPath="$PROJECT_DIR$/radio.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/settings.h" beforeDir="false" afterPath="$PROJECT_DIR$/settings.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ui/main.c" beforeDir="false" afterPath="$PROJECT_DIR$/ui/main.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ui/menu.c" beforeDir="false" afterPath="$PROJECT_DIR$/ui/menu.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ui/scanner.c" beforeDir="false" afterPath="$PROJECT_DIR$/ui/scanner.c" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ui/status.c" beforeDir="false" afterPath="$PROJECT_DIR$/ui/status.c" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -72,37 +90,37 @@
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;ASKED_ADD_EXTERNAL_FILES&quot;: &quot;true&quot;,
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.cidr.known.project.marker&quot;: &quot;true&quot;,
&quot;SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;,
&quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
&quot;cf.first.check.clang-format&quot;: &quot;false&quot;,
&quot;cidr.known.project.marker&quot;: &quot;true&quot;,
&quot;last_opened_file_path&quot;: &quot;C:/Users/RUPC/Desktop/UV-K6/uv-k5-firmware-chinese/compile-with-docker.bat&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;File.Encoding&quot;,
&quot;structure.view.defaults.are.configured&quot;: &quot;true&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ASKED_ADD_EXTERNAL_FILES": "true",
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.cidr.known.project.marker": "true",
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
"WebServerToolWindowFactoryState": "false",
"cf.first.check.clang-format": "false",
"cidr.known.project.marker": "true",
"last_opened_file_path": "C:/Users/RUPC/Desktop/UV-K6/uv-k5-firmware-chinese/win_make.bat",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "File.Encoding",
"structure.view.defaults.are.configured": "true",
"vue.rearranger.settings.migration": "true"
}
}</component>
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="C:\Users\RUPC\Desktop\UV-K6\uv-k5-firmware-chinese\app" />
<recent name="C:\Users\RUPC\Desktop\UV-K6\uv-k5-firmware-chinese" />
</key>
</component>
<component name="RunManager" selected="Shell Script.linux docker">
<configuration default="true" type="CLionExternalRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true">
<component name="RunManager" selected="Shell Script.win docker">
<configuration default="true" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true">
<method v="2">
<option name="CLION.EXTERNAL.BUILD" enabled="true" />
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
<configuration name="clean" type="MAKEFILE_TARGET_RUN_CONFIGURATION" factoryName="Makefile" temporary="true">
@ -141,10 +159,26 @@
<envs />
<method v="2" />
</configuration>
<configuration name="win" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value="" />
<option name="INDEPENDENT_SCRIPT_PATH" value="false" />
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/win_make.bat" />
<option name="SCRIPT_OPTIONS" value="" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EXECUTE_IN_TERMINAL" value="true" />
<option name="EXECUTE_SCRIPT_FILE" value="true" />
<envs />
<method v="2" />
</configuration>
<list>
<item itemvalue="Makefile 目标.clean" />
<item itemvalue="Shell Script.win docker" />
<item itemvalue="Shell Script.linux docker" />
<item itemvalue="Shell Script.win" />
</list>
<recent_temporary>
<list>
@ -180,6 +214,7 @@
<workItem from="1701934352200" duration="14088000" />
<workItem from="1702006730071" duration="3144000" />
<workItem from="1702024305901" duration="2385000" />
<workItem from="1702049513969" duration="8552000" />
</task>
<task id="LOCAL-00029" summary="MDC RX">
<created>1701678580088</created>

View file

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
# include <assert.h>
#include <string.h>
#ifdef ENABLE_FLASHLIGHT
@ -40,20 +41,76 @@
#include "settings.h"
#include "ui/inputbox.h"
#include "ui/ui.h"
#if defined(ENABLE_FMRADIO)
static void ACTION_Scan_FM(bool bRestart);
#endif
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
static void ACTION_AlarmOr1750(bool b1750);
inline static void ACTION_Alarm() { ACTION_AlarmOr1750(false); }
inline static void ACTION_1750() { ACTION_AlarmOr1750(true); };
#endif
inline static void ACTION_ScanRestart() { ACTION_Scan(true); };
void (*action_opt_table[])(void) = {
[ACTION_OPT_NONE] = &FUNCTION_NOP,
[ACTION_OPT_FLASHLIGHT] = &ACTION_FlashLight,
[ACTION_OPT_POWER] = &ACTION_Power,
[ACTION_OPT_MONITOR] = &ACTION_Monitor,
[ACTION_OPT_SCAN] = &ACTION_ScanRestart,
[ACTION_OPT_KEYLOCK] = &COMMON_KeypadLockToggle,
[ACTION_OPT_A_B] = &COMMON_SwitchVFOs,
[ACTION_OPT_VFO_MR] = &COMMON_SwitchVFOMode,
[ACTION_OPT_SWITCH_DEMODUL] = &ACTION_SwitchDemodul,
#ifdef ENABLE_VOX
[ACTION_OPT_VOX] = &ACTION_Vox,
#else
[ACTION_OPT_VOX] = &FUNCTION_NOP,
#endif
#ifdef ENABLE_FMRADIO
[ACTION_OPT_FM] = &ACTION_FM,
#else
[ACTION_OPT_FM] = &FUNCTION_NOP,
#endif
#ifdef ENABLE_ALARM
[ACTION_OPT_ALARM] = &ACTION_Alarm,
#else
[ACTION_OPT_ALARM] = &FUNCTION_NOP,
#endif
#ifdef ENABLE_TX1750
[ACTION_OPT_1750] = &ACTION_1750,
#else
[ACTION_OPT_1750] = &FUNCTION_NOP,
#endif
#ifdef ENABLE_BLMIN_TMP_OFF
[ACTION_OPT_BLMIN_TMP_OFF] = &ACTION_BlminTmpOff,
#else
[ACTION_OPT_BLMIN_TMP_OFF] = &FUNCTION_NOP,
#endif
[ACTION_OPT_D_DCD] = &ACTION_D_DCD,
[ACTION_OPT_WIDTH] = &ACTION_WIDTH,
};
static_assert(ARRAY_SIZE(action_opt_table) == ACTION_OPT_LEN);
void ACTION_Power(void)
{
if (++gTxVfo->OUTPUT_POWER > OUTPUT_POWER_HIGH)
gTxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW;
gRequestSaveChannel = 1;
gRequestDisplayScreen = gScreenToDisplay;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_POWER;
#endif
gRequestDisplayScreen = gScreenToDisplay;
}
void ACTION_Monitor(void)
@ -101,250 +158,120 @@ void ACTION_Monitor(void)
void ACTION_Scan(bool bRestart)
{
(void)bRestart;
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
{
if (gCurrentFunction != FUNCTION_RECEIVE &&
gCurrentFunction != FUNCTION_MONITOR &&
gCurrentFunction != FUNCTION_TRANSMIT)
{
GUI_SelectNextDisplay(DISPLAY_FM);
gMonitor = false;
if (gFM_ScanState != FM_SCAN_OFF)
{
FM_PlayAndUpdate();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
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
}
}
if (gFmRadioMode) {
ACTION_Scan_FM(bRestart);
return;
}
#endif
if (!SCANNER_IsScanning())
{ // not scanning
if (SCANNER_IsScanning()) {
return;
}
gMonitor = false;
// not scanning
gMonitor = false;
#ifdef ENABLE_DTMF_CALLING
DTMF_clear_RX();
DTMF_clear_RX();
#endif
gDTMF_RX_live_timeout = 0;
memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live));
RADIO_SelectVfos();
gDTMF_RX_live_timeout = 0;
memset(gDTMF_RX_live, 0, sizeof(gDTMF_RX_live));
RADIO_SelectVfos();
#ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif
{
GUI_SelectNextDisplay(DISPLAY_MAIN);
if (gScanStateDir != SCAN_OFF)
{ // already scanning
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
CHFRSCANNER_Start(false, gScanStateDir);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;
gUpdateStatus = true;
}
else
{ // stop scanning
CHFRSCANNER_Stop();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
}
else
{ // start scanning
CHFRSCANNER_Start(true, SCAN_FWD);
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN);
AUDIO_PlaySingleVoice(true);
#endif
// clear the other vfo's rssi level (to hide the antenna symbol)
gVFO_RSSI_bar_level[(gEeprom.RX_VFO + 1) & 1u] = 0;
// let the user see DW is not active
gDualWatchActive = false;
gUpdateStatus = true;
}
}
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) {
return;
}
#endif
GUI_SelectNextDisplay(DISPLAY_MAIN);
if (gScanStateDir != SCAN_OFF) {
// already scanning
if (!IS_MR_CHANNEL(gNextMrChannel)) {
CHFRSCANNER_Stop();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
return;
}
// channel mode. Keep scanning but toggle between scan lists
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT + 1) % 3;
// jump to the next channel
CHFRSCANNER_Start(false, gScanStateDir);
gScanPauseDelayIn_10ms = 1;
gScheduleScanListen = false;
} else {
// start scanning
CHFRSCANNER_Start(true, SCAN_FWD);
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN);
AUDIO_PlaySingleVoice(true);
#endif
// clear the other vfo's rssi level (to hide the antenna symbol)
gVFO_RSSI_bar_level[(gEeprom.RX_VFO + 1) & 1U] = 0;
// let the user see DW is not active
gDualWatchActive = false;
}
gUpdateStatus = true;
}
#ifdef ENABLE_VOX
void ACTION_Vox(void)
{
gEeprom.VOX_SWITCH = !gEeprom.VOX_SWITCH;
gRequestSaveSettings = true;
gFlagReconfigureVfos = true;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_VOX;
#endif
gUpdateStatus = true;
}
#endif
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
static void ACTION_AlarmOr1750(const bool b1750)
{
#if defined(ENABLE_ALARM)
const AlarmState_t alarm_mode = (gEeprom.ALARM_MODE == ALARM_MODE_TONE) ? ALARM_STATE_TXALARM : ALARM_STATE_SITE_ALARM;
gAlarmRunningCounter = 0;
#endif
#if defined(ENABLE_ALARM) && defined(ENABLE_TX1750)
gAlarmState = b1750 ? ALARM_STATE_TX1750 : alarm_mode;
#elif defined(ENABLE_ALARM)
gAlarmState = alarm_mode;
#else
gAlarmState = ALARM_STATE_TX1750;
#endif
(void)b1750;
gInputBoxIndex = 0;
gFlagPrepareTX = gAlarmState != ALARM_STATE_OFF;
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
gRequestDisplayScreen = DISPLAY_MAIN;
}
#endif
#ifdef ENABLE_FMRADIO
void ACTION_FM(void)
{
if (gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_MONITOR)
{
if (gFmRadioMode)
{
FM_TurnOff();
gInputBoxIndex = 0;
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
#endif
gFlagReconfigureVfos = true;
gRequestDisplayScreen = DISPLAY_MAIN;
return;
}
gMonitor = false;
RADIO_SelectVfos();
RADIO_SetupRegisters(true);
FM_Start();
gInputBoxIndex = 0;
gRequestDisplayScreen = DISPLAY_FM;
}
}
#endif
void ACTION_SwitchDemodul(void)
{
gRequestSaveChannel = 1;
gTxVfo->Modulation++;
if(gTxVfo->Modulation == MODULATION_UKNOWN)
gTxVfo->Modulation = MODULATION_FM;
gRequestSaveChannel = 1;
}
#ifdef ENABLE_BLMIN_TMP_OFF
void ACTION_BlminTmpOff(void)
{
if(++gEeprom.BACKLIGHT_MIN_STAT == BLMIN_STAT_UNKNOWN)
{
gEeprom.BACKLIGHT_MIN_STAT = BLMIN_STAT_ON;
BACKLIGHT_SetBrightness(0);
} else
{
BACKLIGHT_SetBrightness(0);
}
}
#endif
void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
if (gScreenToDisplay == DISPLAY_MAIN && gDTMF_InputMode) // entering DTMF code
{
if (Key == KEY_SIDE1 && !bKeyHeld && bKeyPressed) // side1 btn pressed
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gScreenToDisplay == DISPLAY_MAIN && gDTMF_InputMode){
// entering DTMF code
if (gDTMF_InputBox_Index > 0) // DTMF codes are in the input box
{
gDTMF_InputBox[--gDTMF_InputBox_Index] = '-'; // delete one code
if (gDTMF_InputBox_Index > 0)
{
gPttWasReleased = true;
gRequestDisplayScreen = DISPLAY_MAIN;
return;
}
}
gPttWasReleased = true;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
if (Key != KEY_SIDE1 || bKeyHeld || !bKeyPressed){
return;
}
gRequestDisplayScreen = DISPLAY_MAIN;
gDTMF_InputMode = false; // turn off DTMF input box if no codes left
}
// side1 btn pressed
gPttWasReleased = true;
return;
}
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gRequestDisplayScreen = DISPLAY_MAIN;
uint8_t funcShort = ACTION_OPT_NONE;
uint8_t funcLong = ACTION_OPT_NONE;
if (gDTMF_InputBox_Index <= 0) {
// turn off DTMF input box if no codes left
gDTMF_InputMode = false;
return;
}
// DTMF codes are in the input box
gDTMF_InputBox[--gDTMF_InputBox_Index] = '-'; // delete one code
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
return;
}
enum ACTION_OPT_t funcShort = ACTION_OPT_NONE;
enum ACTION_OPT_t funcLong = ACTION_OPT_NONE;
switch(Key) {
case KEY_SIDE1:
funcShort = ACTION_OPT_MONITOR;//gEeprom.KEY_1_SHORT_PRESS_ACTION;
@ -380,76 +307,219 @@ void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
}
// held or released after short press beyond this point
action_opt_table[funcShort]();
// switch (funcShort)
// {
// default:
// case ACTION_OPT_WIDTH:
// gTxVfo->CHANNEL_BANDWIDTH=!gTxVfo->CHANNEL_BANDWIDTH;
// gRequestSaveChannel = 1;
// break;
// case ACTION_OPT_NONE:
// break;
//
// case ACTION_OPT_POWER:
// ACTION_Power();
// break;
// case ACTION_OPT_MONITOR:
// ACTION_Monitor();
// break;
// case ACTION_OPT_SCAN:
// ACTION_Scan(true);
// break;
//
// case ACTION_OPT_KEYLOCK:
// COMMON_KeypadLockToggle();
// break;
// case ACTION_OPT_A_B:
// COMMON_SwitchVFOs();
// break;
// case ACTION_OPT_VFO_MR:
// COMMON_SwitchVFOMode();
// break;
// case ACTION_OPT_SWITCH_DEMODUL:
// ACTION_SwitchDemodul();
// break;
//#ifdef ENABLE_FLASHLIGHT
// case ACTION_OPT_FLASHLIGHT:
// ACTION_FlashLight();
//#endif
// break;
//#ifdef ENABLE_VOX
// case ACTION_OPT_VOX:
// ACTION_Vox();
//#endif
// break;
//#ifdef ENABLE_FMRADIO
// case ACTION_OPT_FM:
// ACTION_FM();
//#endif
// break;
//#ifdef ENABLE_ALARM
// case ACTION_OPT_ALARM:
// ACTION_AlarmOr1750(false);
// break;
//#endif
// case ACTION_OPT_1750:
//#if defined(ENABLE_TX1750)
// ACTION_AlarmOr1750(true);
// break;
//#endif
//#ifdef ENABLE_DTMF_CALLING
// case ACTION_OPT_D_DCD:
// gTxVfo->DTMF_DECODING_ENABLE = !gTxVfo->DTMF_DECODING_ENABLE;
// DTMF_clear_RX();
// gRequestSaveChannel = 1;
// break;
//
//#endif
//#ifdef ENABLE_BLMIN_TMP_OFF
// case ACTION_OPT_BLMIN_TMP_OFF:
// ACTION_BlminTmpOff();
// break;
//#endif
// }
}
switch (funcShort)
{
default:
case ACTION_OPT_WIDTH:
gTxVfo->CHANNEL_BANDWIDTH=!gTxVfo->CHANNEL_BANDWIDTH;
gRequestSaveChannel = 1;
// gRequestSaveSettings = 1;
break;
case ACTION_OPT_NONE:
break;
case ACTION_OPT_FLASHLIGHT:
#ifdef ENABLE_FLASHLIGHT
ACTION_FlashLight();
#endif
break;
case ACTION_OPT_POWER:
ACTION_Power();
break;
case ACTION_OPT_MONITOR:
ACTION_Monitor();
break;
case ACTION_OPT_SCAN:
ACTION_Scan(true);
break;
case ACTION_OPT_VOX:
#ifdef ENABLE_VOX
ACTION_Vox();
#endif
break;
case ACTION_OPT_ALARM:
#ifdef ENABLE_ALARM
ACTION_AlarmOr1750(false);
#endif
break;
#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;
case ACTION_OPT_SWITCH_DEMODUL:
ACTION_SwitchDemodul();
break;
#ifdef ENABLE_DTMF_CALLING
case ACTION_OPT_D_DCD:
gTxVfo->DTMF_DECODING_ENABLE = !gTxVfo->DTMF_DECODING_ENABLE;
DTMF_clear_RX();
gRequestSaveChannel = 1;
break;
void ACTION_FM(void)
{
if (gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_MONITOR)
{
gInputBoxIndex = 0;
if (gFmRadioMode) {
FM_TurnOff();
gFlagReconfigureVfos = true;
gRequestDisplayScreen = DISPLAY_MAIN;
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
#endif
#ifdef ENABLE_BLMIN_TMP_OFF
case ACTION_OPT_BLMIN_TMP_OFF:
ACTION_BlminTmpOff();
break;
#endif
return;
}
gMonitor = false;
RADIO_SelectVfos();
RADIO_SetupRegisters(true);
FM_Start();
gRequestDisplayScreen = DISPLAY_FM;
}
}
static void ACTION_Scan_FM(bool bRestart)
{
if (FUNCTION_IsRx()) {
return;
}
GUI_SelectNextDisplay(DISPLAY_FM);
gMonitor = false;
if (gFM_ScanState != FM_SCAN_OFF) {
FM_PlayAndUpdate();
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
return;
}
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
}
#endif
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
static void ACTION_AlarmOr1750(const bool b1750)
{
#if defined(ENABLE_ALARM)
const AlarmState_t alarm_mode = (gEeprom.ALARM_MODE == ALARM_MODE_TONE) ? ALARM_STATE_TXALARM : ALARM_STATE_SITE_ALARM;
gAlarmRunningCounter = 0;
#endif
#if defined(ENABLE_ALARM) && defined(ENABLE_TX1750)
gAlarmState = b1750 ? ALARM_STATE_TX1750 : alarm_mode;
#elif defined(ENABLE_ALARM)
gAlarmState = alarm_mode;
#else
gAlarmState = ALARM_STATE_TX1750;
#endif
(void)b1750;
gInputBoxIndex = 0;
gFlagPrepareTX = gAlarmState != ALARM_STATE_OFF;
if (gScreenToDisplay != DISPLAY_MENU) // 1of11 .. don't close the menu
gRequestDisplayScreen = DISPLAY_MAIN;
}
#endif
#ifdef ENABLE_VOX
void ACTION_Vox(void)
{
gEeprom.VOX_SWITCH = !gEeprom.VOX_SWITCH;
gRequestSaveSettings = true;
gFlagReconfigureVfos = true;
gUpdateStatus = true;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_VOX;
#endif
}
#endif
#ifdef ENABLE_BLMIN_TMP_OFF
void ACTION_BlminTmpOff(void)
{
if(++gEeprom.BACKLIGHT_MIN_STAT == BLMIN_STAT_UNKNOWN) {
gEeprom.BACKLIGHT_MIN_STAT = BLMIN_STAT_ON;
BACKLIGHT_SetBrightness(gEeprom.BACKLIGHT_MIN);
} else {
BACKLIGHT_SetBrightness(0);
}
}
#endif
void ACTION_WIDTH(void)
{
gRequestSaveChannel = 1;
gTxVfo->CHANNEL_BANDWIDTH=!gTxVfo->CHANNEL_BANDWIDTH;
}
void ACTION_D_DCD(void)
{
gRequestSaveChannel = 1;
gTxVfo->DTMF_DECODING_ENABLE = !gTxVfo->DTMF_DECODING_ENABLE;
DTMF_clear_RX();
}

View file

@ -26,17 +26,20 @@ void ACTION_Scan(bool bRestart);
#ifdef ENABLE_VOX
void ACTION_Vox(void);
#endif
#ifdef ENABLE_ALARM
//static void ACTION_AlarmOr1750(bool b1750)
#endif
#ifdef ENABLE_FMRADIO
void ACTION_FM(void);
#endif
void ACTION_SwitchDemodul(void);
void ACTION_SwitchWidth(void);
void ACTION_SwitchDTMFDecode(void);
#ifdef ENABLE_BLMIN_TMP_OFF
void ACTION_BlminTmpOff(void);
#endif
void ACTION_D_DCD(void);
void ACTION_WIDTH(void);
void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);

View file

@ -135,7 +135,7 @@ static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gInputBoxIndex = 0;
Frequency = StrToUL(INPUTBOX_GetAscii()) * 100;
for (i = 0; i < ARRAY_SIZE(frequencyBandTable); i++)
for (i = 0; i < BAND_N_ELEM; i++)
{
if (Frequency >= frequencyBandTable[i].lower && Frequency < frequencyBandTable[i].upper)
{

View file

@ -807,7 +807,6 @@ static void HandleVox(void)
}
}
#endif
void APP_Update(void)
{
#ifdef ENABLE_VOICE
@ -902,12 +901,8 @@ void APP_Update(void)
}
#ifdef ENABLE_FMRADIO
if (gScheduleFM &&
gFM_ScanState != FM_SCAN_OFF &&
gCurrentFunction != FUNCTION_MONITOR &&
gCurrentFunction != FUNCTION_RECEIVE &&
gCurrentFunction != FUNCTION_TRANSMIT)
{ // switch to FM radio mode
if (gScheduleFM && gFM_ScanState != FM_SCAN_OFF && !FUNCTION_IsRx()) {
// switch to FM radio mode
FM_Play();
gScheduleFM = false;
}
@ -952,6 +947,7 @@ void APP_Update(void)
#endif
}
if (gPowerSaveCountdownExpired && gCurrentFunction == FUNCTION_POWER_SAVE
#ifdef ENABLE_VOICE
&& gVoiceWriteIndex == 0
@ -960,7 +956,6 @@ void APP_Update(void)
{
static bool goToSleep;
// wake up, enable RX then go back to sleep
if (gRxIdleMode)
{
BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable();
@ -985,13 +980,12 @@ void APP_Update(void)
}
else if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF || gScanStateDir != SCAN_OFF || gCssBackgroundScan || goToSleep)
{ // dual watch mode off or scanning or rssi update request
// go back to sleep
gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10;
gRxIdleMode = true;
goToSleep = false;
BK4819_DisableVox();
BK4819_Sleep();
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_RX_ENABLE, false);
@ -999,11 +993,9 @@ void APP_Update(void)
// Authentic device checked removed
}
else
{
else {
// toggle between the two VFO's
DualwatchAlternate();
gPowerSave_10ms = power_save1_10ms;
goToSleep = true;
}
@ -1492,11 +1484,7 @@ void APP_TimeSlice500ms(void)
GUI_DisplayType_t disp = DISPLAY_INVALID;
#ifdef ENABLE_FMRADIO
if (gFmRadioMode &&
gCurrentFunction != FUNCTION_RECEIVE &&
gCurrentFunction != FUNCTION_MONITOR &&
gCurrentFunction != FUNCTION_TRANSMIT)
{
if (gFmRadioMode && ! FUNCTION_IsRx()) {
disp = DISPLAY_FM;
}
#endif
@ -1524,11 +1512,8 @@ void APP_TimeSlice500ms(void)
{
RADIO_SetVfoState(VFO_STATE_NORMAL);
#ifdef ENABLE_FMRADIO
if (gCurrentFunction != FUNCTION_RECEIVE &&
gCurrentFunction != FUNCTION_TRANSMIT &&
gCurrentFunction != FUNCTION_MONITOR &&
gFmRadioMode)
{ // switch back to FM radio mode
if (gFmRadioMode && !FUNCTION_IsRx()) {
// switch back to FM radio mode
FM_Start();
GUI_SelectNextDisplay(DISPLAY_FM);
}

View file

@ -62,7 +62,7 @@ static void Key_FUNC(KEY_Code_t Key, uint8_t state);
bool FM_CheckValidChannel(uint8_t Channel)
{
return (Channel < ARRAY_SIZE(gFM_Channels) && (gFM_Channels[Channel] >= 760 && gFM_Channels[Channel] < 1080)) ? true : false;
return (Channel < ARRAY_SIZE(gFM_Channels) && (gFM_Channels[Channel] >= 760 && gFM_Channels[Channel] < 1080));
}
uint8_t FM_FindNextChannel(uint8_t Channel, uint8_t Direction)
@ -192,43 +192,35 @@ int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit)
// This is supposed to be a signed value, but above function is unsigned
const uint16_t Deviation = BK1080_REG_07_GET_FREQD(Test2);
if (BK1080_REG_07_GET_SNR(Test2) >= 2)
{
const uint16_t Status = BK1080_ReadRegister(BK1080_REG_10);
if ((Status & BK1080_REG_10_MASK_AFCRL) == BK1080_REG_10_AFCRL_NOT_RAILED && BK1080_REG_10_GET_RSSI(Status) >= 10)
{
//if (Deviation > -281 && Deviation < 280)
if (Deviation < 280 || Deviation > 3815)
{
// not BLE(less than or equal)
if (Frequency > LowerLimit && (Frequency - BK1080_BaseFrequency) == 1)
{
if (BK1080_FrequencyDeviation & 0x800)
goto Bail;
if (BK1080_FrequencyDeviation < 20)
goto Bail;
}
// not BLT(less than)
if (Frequency >= LowerLimit && (BK1080_BaseFrequency - Frequency) == 1)
{
if ((BK1080_FrequencyDeviation & 0x800) == 0)
goto Bail;
// if (BK1080_FrequencyDeviation > -21)
if (BK1080_FrequencyDeviation > 4075)
goto Bail;
}
ret = 0;
}
}
if (BK1080_REG_07_GET_SNR(Test2) <= 2){
goto Bail;
}
const uint16_t Status = BK1080_ReadRegister(BK1080_REG_10);
if ((Status & BK1080_REG_10_MASK_AFCRL) != BK1080_REG_10_AFCRL_NOT_RAILED || BK1080_REG_10_GET_RSSI(Status) < 10) {
goto Bail;
}
//if (Deviation > -281 && Deviation < 280)
if (Deviation >= 280 && Deviation <= 3815) {
goto Bail;
}
// not BLE(less than or equal)
if (Frequency > LowerLimit && (Frequency - BK1080_BaseFrequency) == 1) {
if (BK1080_FrequencyDeviation & 0x800 || (BK1080_FrequencyDeviation < 20))
goto Bail;
}
// not BLT(less than)
if (Frequency >= LowerLimit && (BK1080_BaseFrequency - Frequency) == 1) {
if ((BK1080_FrequencyDeviation & 0x800) == 0 || (BK1080_FrequencyDeviation > 4075))
goto Bail;
}
ret = 0;
Bail:
BK1080_FrequencyDeviation = Deviation;
BK1080_BaseFrequency = Frequency;
@ -336,8 +328,8 @@ static void Key_DIGITS(KEY_Code_t Key, uint8_t state)
static void Key_FUNC(KEY_Code_t Key, uint8_t state)
{
if (state == BUTTON_EVENT_SHORT || state == BUTTON_EVENT_HELD)
{
if (state == BUTTON_EVENT_SHORT || state == BUTTON_EVENT_HELD)
{
bool autoScan = gWasFKeyPressed || (state == BUTTON_EVENT_HELD);
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
@ -446,11 +438,10 @@ static void Key_MENU(uint8_t state)
if (gAskToSave)
{
gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying;
gAskToSave = false;
gRequestSaveFM = true;
gRequestSaveFM = true;
}
else
gAskToSave = true;
gAskToSave = !gAskToSave;
}
else
{
@ -462,10 +453,8 @@ static void Key_MENU(uint8_t state)
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
gRequestSaveFM = true;
gAskToDelete = false;
}
else
gAskToDelete = true;
gAskToDelete = !gAskToDelete;
}
}
else
@ -480,11 +469,9 @@ static void Key_MENU(uint8_t state)
if (gAskToSave)
{
gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying;
gAskToSave = false;
gRequestSaveFM = true;
}
else
gAskToSave = true;
gAskToSave = !gAskToSave;
}
}
@ -497,10 +484,8 @@ static void Key_UP_DOWN(uint8_t state, int8_t Step)
}
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
}
else {
if (gInputBoxIndex || state!=BUTTON_EVENT_HELD)
return;
} else if (gInputBoxIndex || state!=BUTTON_EVENT_HELD) {
return;
}
if (gAskToSave) {
@ -573,7 +558,7 @@ void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
break;
case KEY_MENU:
Key_MENU(state);
return;
break;
case KEY_UP:
Key_UP_DOWN(state, 1);
break;

View file

@ -34,7 +34,6 @@ extern bool gFmRadioMode;
extern uint8_t gFmRadioCountdown_500ms;
extern volatile uint16_t gFmPlayCountdown_10ms;
extern volatile int8_t gFM_ScanState;
extern bool gFM_AutoScan;
extern uint8_t gFM_ChannelPosition;
// Doubts about whether this should be signed or not
extern uint16_t gFM_FrequencyDeviation;

View file

@ -144,7 +144,7 @@ gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
if (gTxVfo->Band == BAND5_350MHz && gSetting_F_LOCK != F_LOCK_NONE) {
// skip if not enabled
gTxVfo->Band += 1;
} else if (gTxVfo->Band >= BAND_LAST_ELEMENT) {
} else if (gTxVfo->Band >= BAND_N_ELEM) {
// go arround if overflowed
gTxVfo->Band = BAND1_50MHz;
}
@ -354,8 +354,8 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) {
} else if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) {
const uint32_t center = (BX4819_band1.upper + BX4819_band2.lower) / 2;
Frequency = (Frequency < center) ? BX4819_band1.upper : BX4819_band2.lower;
} else if (Frequency > frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper) {
Frequency = frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper;
} else if (Frequency > frequencyBandTable[BAND_N_ELEM- 1].upper) {
Frequency = frequencyBandTable[BAND_N_ELEM- 1].upper;
}
const FREQUENCY_Band_t band = FREQUENCY_GetBand(Frequency);

View file

@ -124,7 +124,7 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax) {
case MENU_STEP:
*pMin = 0;
*pMax = ARRAY_SIZE(gStepFrequencyTable) - 1;
*pMax =STEP_N_ELEM - 1;
break;
case MENU_ABR:

View file

@ -20,7 +20,7 @@
#include "driver/backlight.h"
#include "ui/helper.h"
#include "ui/main.h"
#include "frequencies.h"
struct FrequencyBandInfo {
uint32_t lower;
uint32_t upper;
@ -28,7 +28,7 @@ struct FrequencyBandInfo {
};
#define F_MIN frequencyBandTable[0].lower
#define F_MAX frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper
#define F_MAX frequencyBandTable[BAND_N_ELEM - 1].upper
const uint16_t RSSI_MAX_VALUE = 65535;

View file

@ -16,7 +16,7 @@
#ifndef SPECTRUM_H
#define SPECTRUM_H
#include "../frequencies.h"
#include "../bitmaps.h"
#include "../board.h"
#include "../bsp/dp32g030/gpio.h"

758
audio.c
View file

@ -15,12 +15,12 @@
*/
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
#include "app/fm.h"
#endif
#include "audio.h"
#include "bsp/dp32g030/gpio.h"
#ifdef ENABLE_FMRADIO
#include "driver/bk1080.h"
#include "driver/bk1080.h"
#endif
#include "driver/bk4819.h"
#include "driver/gpio.h"
@ -31,424 +31,412 @@
#include "settings.h"
#include "ui/ui.h"
#ifdef ENABLE_VOICE
static const uint8_t VoiceClipLengthChinese[58] =
{
0x32, 0x32, 0x32, 0x37, 0x37, 0x32, 0x32, 0x32,
0x32, 0x37, 0x37, 0x32, 0x64, 0x64, 0x64, 0x64,
0x64, 0x69, 0x64, 0x69, 0x5A, 0x5F, 0x5F, 0x64,
0x64, 0x69, 0x64, 0x64, 0x69, 0x69, 0x69, 0x64,
0x64, 0x6E, 0x69, 0x5F, 0x64, 0x64, 0x64, 0x69,
0x69, 0x69, 0x64, 0x69, 0x64, 0x64, 0x55, 0x5F,
0x5A, 0x4B, 0x4B, 0x46, 0x46, 0x69, 0x64, 0x6E,
0x5A, 0x64,
};
static const uint8_t VoiceClipLengthEnglish[76] =
{
0x50, 0x32, 0x2D, 0x2D, 0x2D, 0x37, 0x37, 0x37,
0x32, 0x32, 0x3C, 0x37, 0x46, 0x46, 0x4B, 0x82,
0x82, 0x6E, 0x82, 0x46, 0x96, 0x64, 0x46, 0x6E,
0x78, 0x6E, 0x87, 0x64, 0x96, 0x96, 0x46, 0x9B,
0x91, 0x82, 0x82, 0x73, 0x78, 0x64, 0x82, 0x6E,
0x78, 0x82, 0x87, 0x6E, 0x55, 0x78, 0x64, 0x69,
0x9B, 0x5A, 0x50, 0x3C, 0x32, 0x55, 0x64, 0x64,
0x50, 0x46, 0x46, 0x46, 0x4B, 0x4B, 0x50, 0x50,
0x55, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x37,
0x41, 0x32, 0x3C, 0x37,
};
VOICE_ID_t gVoiceID[8];
uint8_t gVoiceReadIndex;
uint8_t gVoiceWriteIndex;
volatile uint16_t gCountdownToPlayNextVoice_10ms;
volatile bool gFlagPlayQueuedVoice;
VOICE_ID_t gAnotherVoiceID = VOICE_ID_INVALID;
#endif
BEEP_Type_t gBeepToPlay = BEEP_NONE;
void AUDIO_PlayBeep(BEEP_Type_t Beep)
{
uint16_t ToneConfig;
uint16_t ToneFrequency;
uint16_t Duration;
if (Beep != BEEP_880HZ_60MS_TRIPLE_BEEP &&
Beep != BEEP_500HZ_60MS_DOUBLE_BEEP &&
Beep != BEEP_440HZ_500MS &&
Beep != BEEP_880HZ_200MS &&
Beep != BEEP_880HZ_500MS &&
!gEeprom.BEEP_CONTROL)
if (Beep != BEEP_880HZ_60MS_TRIPLE_BEEP &&
Beep != BEEP_500HZ_60MS_DOUBLE_BEEP &&
Beep != BEEP_440HZ_500MS &&
Beep != BEEP_880HZ_200MS &&
Beep != BEEP_880HZ_500MS &&
!gEeprom.BEEP_CONTROL)
return;
#ifdef ENABLE_AIRCOPY
if (gScreenToDisplay == DISPLAY_AIRCOPY)
return;
#endif
#ifdef ENABLE_AIRCOPY
if (gScreenToDisplay == DISPLAY_AIRCOPY)
return;
#endif
if (gCurrentFunction == FUNCTION_RECEIVE)
return;
if (gCurrentFunction == FUNCTION_RECEIVE)
return;
if (gCurrentFunction == FUNCTION_MONITOR)
return;
if (gCurrentFunction == FUNCTION_MONITOR)
return;
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
BK1080_Mute(true);
#endif
ToneConfig = BK4819_ReadRegister(BK4819_REG_71);
AUDIO_AudioPathOff();
AUDIO_AudioPathOff();
if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode)
BK4819_RX_TurnOn();
if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode)
BK4819_RX_TurnOn();
SYSTEM_DelayMs(20);
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
BK1080_Mute(true);
#endif
uint16_t ToneConfig = BK4819_ReadRegister(BK4819_REG_71);
uint16_t ToneFrequency;
switch (Beep)
{
default:
case BEEP_NONE:
ToneFrequency = 220;
break;
case BEEP_1KHZ_60MS_OPTIONAL:
ToneFrequency = 1000;
break;
case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL:
case BEEP_500HZ_60MS_DOUBLE_BEEP:
ToneFrequency = 500;
break;
case BEEP_440HZ_40MS_OPTIONAL:
case BEEP_440HZ_500MS:
ToneFrequency = 440;
break;
case BEEP_880HZ_40MS_OPTIONAL:
case BEEP_880HZ_60MS_TRIPLE_BEEP:
case BEEP_880HZ_200MS:
case BEEP_880HZ_500MS:
ToneFrequency = 880;
break;
}
BK4819_PlayTone(ToneFrequency, true);
SYSTEM_DelayMs(2);
AUDIO_AudioPathOn();
SYSTEM_DelayMs(60);
uint16_t Duration;
switch (Beep)
{
case BEEP_880HZ_60MS_TRIPLE_BEEP:
BK4819_ExitTxMute();
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;
break;
case BEEP_880HZ_40MS_OPTIONAL:
case BEEP_440HZ_40MS_OPTIONAL:
BK4819_ExitTxMute();
Duration = 40;
break;
case BEEP_880HZ_200MS:
BK4819_ExitTxMute();
Duration = 200;
break;
case BEEP_440HZ_500MS:
case BEEP_880HZ_500MS:
default:
BK4819_ExitTxMute();
Duration = 500;
break;
}
SYSTEM_DelayMs(Duration);
BK4819_EnterTxMute();
SYSTEM_DelayMs(20);
AUDIO_AudioPathOff();
SYSTEM_DelayMs(5);
BK4819_TurnsOffTones_TurnsOnRX();
SYSTEM_DelayMs(5);
BK4819_WriteRegister(BK4819_REG_71, ToneConfig);
if (gEnableSpeaker)
AUDIO_AudioPathOn();
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
BK1080_Mute(false);
#endif
if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode)
BK4819_Sleep();
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
#endif
}
#ifdef ENABLE_VOICE
static const uint8_t VoiceClipLengthChinese[58] =
{
0x32, 0x32, 0x32, 0x37, 0x37, 0x32, 0x32, 0x32,
0x32, 0x37, 0x37, 0x32, 0x64, 0x64, 0x64, 0x64,
0x64, 0x69, 0x64, 0x69, 0x5A, 0x5F, 0x5F, 0x64,
0x64, 0x69, 0x64, 0x64, 0x69, 0x69, 0x69, 0x64,
0x64, 0x6E, 0x69, 0x5F, 0x64, 0x64, 0x64, 0x69,
0x69, 0x69, 0x64, 0x69, 0x64, 0x64, 0x55, 0x5F,
0x5A, 0x4B, 0x4B, 0x46, 0x46, 0x69, 0x64, 0x6E,
0x5A, 0x64,
};
static const uint8_t VoiceClipLengthEnglish[76] =
{
0x50, 0x32, 0x2D, 0x2D, 0x2D, 0x37, 0x37, 0x37,
0x32, 0x32, 0x3C, 0x37, 0x46, 0x46, 0x4B, 0x82,
0x82, 0x6E, 0x82, 0x46, 0x96, 0x64, 0x46, 0x6E,
0x78, 0x6E, 0x87, 0x64, 0x96, 0x96, 0x46, 0x9B,
0x91, 0x82, 0x82, 0x73, 0x78, 0x64, 0x82, 0x6E,
0x78, 0x82, 0x87, 0x6E, 0x55, 0x78, 0x64, 0x69,
0x9B, 0x5A, 0x50, 0x3C, 0x32, 0x55, 0x64, 0x64,
0x50, 0x46, 0x46, 0x46, 0x4B, 0x4B, 0x50, 0x50,
0x55, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x37,
0x41, 0x32, 0x3C, 0x37,
};
VOICE_ID_t gVoiceID[8];
uint8_t gVoiceReadIndex;
uint8_t gVoiceWriteIndex;
volatile uint16_t gCountdownToPlayNextVoice_10ms;
volatile bool gFlagPlayQueuedVoice;
VOICE_ID_t gAnotherVoiceID = VOICE_ID_INVALID;
void AUDIO_PlayVoice(uint8_t VoiceID)
{
unsigned int i;
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
SYSTEM_DelayMs(20);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
switch (Beep)
for (i = 0; i < 8; i++)
{
default:
case BEEP_NONE:
ToneFrequency = 220;
break;
case BEEP_1KHZ_60MS_OPTIONAL:
ToneFrequency = 1000;
break;
case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL:
case BEEP_500HZ_60MS_DOUBLE_BEEP:
ToneFrequency = 500;
break;
case BEEP_440HZ_40MS_OPTIONAL:
case BEEP_440HZ_500MS:
ToneFrequency = 440;
break;
case BEEP_880HZ_40MS_OPTIONAL:
case BEEP_880HZ_60MS_TRIPLE_BEEP:
case BEEP_880HZ_200MS:
case BEEP_880HZ_500MS:
ToneFrequency = 880;
break;
if ((VoiceID & 0x80U) == 0)
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
else
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
SYSTICK_DelayUs(1000);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
SYSTICK_DelayUs(1200);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
VoiceID <<= 1;
SYSTICK_DelayUs(200);
}
}
BK4819_PlayTone(ToneFrequency, true);
void AUDIO_PlaySingleVoice(bool bFlag)
{
uint8_t VoiceID;
uint8_t Delay;
SYSTEM_DelayMs(2);
VoiceID = gVoiceID[0];
AUDIO_AudioPathOn();
SYSTEM_DelayMs(60);
switch (Beep)
if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF && gVoiceWriteIndex > 0)
{
case BEEP_880HZ_60MS_TRIPLE_BEEP:
BK4819_ExitTxMute();
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;
break;
if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE)
{ // Chinese
if (VoiceID >= ARRAY_SIZE(VoiceClipLengthChinese))
goto Bailout;
case BEEP_880HZ_40MS_OPTIONAL:
case BEEP_440HZ_40MS_OPTIONAL:
BK4819_ExitTxMute();
Duration = 40;
break;
Delay = VoiceClipLengthChinese[VoiceID];
VoiceID += VOICE_ID_CHI_BASE;
}
else
{ // English
if (VoiceID >= ARRAY_SIZE(VoiceClipLengthEnglish))
goto Bailout;
case BEEP_880HZ_200MS:
BK4819_ExitTxMute();
Duration = 200;
break;
Delay = VoiceClipLengthEnglish[VoiceID];
VoiceID += VOICE_ID_ENG_BASE;
}
case BEEP_440HZ_500MS:
case BEEP_880HZ_500MS:
default:
BK4819_ExitTxMute();
Duration = 500;
break;
}
if (FUNCTION_IsRx()) // 1of11
BK4819_SetAF(BK4819_AF_MUTE);
SYSTEM_DelayMs(Duration);
BK4819_EnterTxMute();
SYSTEM_DelayMs(20);
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
BK1080_Mute(true);
#endif
AUDIO_AudioPathOff();
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
#endif
SYSTEM_DelayMs(5);
//stop tone
//BK4819_TurnsOffTones_TurnsOnRX();
BK4819_stop_tones(false);
SYSTEM_DelayMs(5);
BK4819_WriteRegister(BK4819_REG_71, ToneConfig);
if (gEnableSpeaker)
AUDIO_AudioPathOn();
#ifdef ENABLE_VOX
gVoxResumeCountdown = 2000;
#endif
SYSTEM_DelayMs(5);
AUDIO_PlayVoice(VoiceID);
if (gVoiceWriteIndex == 1)
Delay += 3;
if (bFlag)
{
SYSTEM_DelayMs(Delay * 10);
if (FUNCTION_IsRx()) // 1of11
RADIO_SetModulation(gRxVfo->Modulation);
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
BK1080_Mute(false);
#endif
if (!gEnableSpeaker)
AUDIO_AudioPathOff();
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
#endif
return;
}
gVoiceReadIndex = 1;
gCountdownToPlayNextVoice_10ms = Delay;
gFlagPlayQueuedVoice = false;
return;
}
Bailout:
gVoiceReadIndex = 0;
gVoiceWriteIndex = 0;
}
void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID)
{
if (Index >= ARRAY_SIZE(gVoiceID))
return;
if (Index == 0)
{
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
}
gVoiceID[Index] = VoiceID;
gVoiceWriteIndex++;
}
uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value)
{
uint16_t Remainder;
uint8_t Result;
uint8_t Count;
if (Index == 0)
{
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
}
Count = 0;
Result = Value / 1000U;
Remainder = Value % 1000U;
if (Remainder < 100U)
{
if (Remainder < 10U)
goto Skip;
}
else
{
Result = Remainder / 100U;
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result;
Count++;
Remainder -= Result * 100U;
}
Result = Remainder / 10U;
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result;
Count++;
Remainder -= Result * 10U;
Skip:
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Remainder;
return Count + 1U;
}
void AUDIO_PlayQueuedVoice(void)
{
uint8_t VoiceID;
uint8_t Delay;
bool Skip;
Skip = false;
if (gVoiceReadIndex != gVoiceWriteIndex && gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF)
{
VoiceID = gVoiceID[gVoiceReadIndex];
if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE)
{
if (VoiceID < ARRAY_SIZE(VoiceClipLengthChinese))
{
Delay = VoiceClipLengthChinese[VoiceID];
VoiceID += VOICE_ID_CHI_BASE;
}
else
Skip = true;
}
else
{
if (VoiceID < ARRAY_SIZE(VoiceClipLengthEnglish))
{
Delay = VoiceClipLengthEnglish[VoiceID];
VoiceID += VOICE_ID_ENG_BASE;
}
else
Skip = true;
}
gVoiceReadIndex++;
if (!Skip)
{
if (gVoiceReadIndex == gVoiceWriteIndex)
Delay += 3;
AUDIO_PlayVoice(VoiceID);
gCountdownToPlayNextVoice_10ms = Delay;
gFlagPlayQueuedVoice = false;
#ifdef ENABLE_VOX
gVoxResumeCountdown = 2000;
#endif
return;
}
}
if (FUNCTION_IsRx())
{
RADIO_SetModulation(gRxVfo->Modulation); // 1of11
}
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
BK1080_Mute(false);
#endif
if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode)
BK4819_Sleep();
if (!gEnableSpeaker)
AUDIO_AudioPathOff();
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
#endif
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
}
#ifdef ENABLE_VOICE
void AUDIO_PlayVoice(uint8_t VoiceID)
{
unsigned int i;
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
SYSTEM_DelayMs(20);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
for (i = 0; i < 8; i++)
{
if ((VoiceID & 0x80U) == 0)
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
else
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
SYSTICK_DelayUs(1000);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
SYSTICK_DelayUs(1200);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
VoiceID <<= 1;
SYSTICK_DelayUs(200);
}
}
void AUDIO_PlaySingleVoice(bool bFlag)
{
uint8_t VoiceID;
uint8_t Delay;
VoiceID = gVoiceID[0];
if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF && gVoiceWriteIndex > 0)
{
if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE)
{ // Chinese
if (VoiceID >= ARRAY_SIZE(VoiceClipLengthChinese))
goto Bailout;
Delay = VoiceClipLengthChinese[VoiceID];
VoiceID += VOICE_ID_CHI_BASE;
}
else
{ // English
if (VoiceID >= ARRAY_SIZE(VoiceClipLengthEnglish))
goto Bailout;
Delay = VoiceClipLengthEnglish[VoiceID];
VoiceID += VOICE_ID_ENG_BASE;
}
if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING) // 1of11
BK4819_SetAF(BK4819_AF_MUTE);
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
BK1080_Mute(true);
#endif
AUDIO_AudioPathOn();
#ifdef ENABLE_VOX
gVoxResumeCountdown = 2000;
#endif
SYSTEM_DelayMs(5);
AUDIO_PlayVoice(VoiceID);
if (gVoiceWriteIndex == 1)
Delay += 3;
if (bFlag)
{
SYSTEM_DelayMs(Delay * 10);
if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING) // 1of11
RADIO_SetModulation(gRxVfo->Modulation);
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
BK1080_Mute(false);
#endif
if (!gEnableSpeaker)
AUDIO_AudioPathOff();
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
#endif
return;
}
gVoiceReadIndex = 1;
gCountdownToPlayNextVoice_10ms = Delay;
gFlagPlayQueuedVoice = false;
return;
}
Bailout:
gVoiceReadIndex = 0;
gVoiceWriteIndex = 0;
}
void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID)
{
if (Index >= ARRAY_SIZE(gVoiceID))
return;
if (Index == 0)
{
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
}
gVoiceID[Index] = VoiceID;
gVoiceWriteIndex++;
}
uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value)
{
uint16_t Remainder;
uint8_t Result;
uint8_t Count;
if (Index == 0)
{
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
}
Count = 0;
Result = Value / 1000U;
Remainder = Value % 1000U;
if (Remainder < 100U)
{
if (Remainder < 10U)
goto Skip;
}
else
{
Result = Remainder / 100U;
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result;
Count++;
Remainder -= Result * 100U;
}
Result = Remainder / 10U;
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result;
Count++;
Remainder -= Result * 10U;
Skip:
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Remainder;
return Count + 1U;
}
void AUDIO_PlayQueuedVoice(void)
{
uint8_t VoiceID;
uint8_t Delay;
bool Skip;
Skip = false;
if (gVoiceReadIndex != gVoiceWriteIndex && gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF)
{
VoiceID = gVoiceID[gVoiceReadIndex];
if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE)
{
if (VoiceID < ARRAY_SIZE(VoiceClipLengthChinese))
{
Delay = VoiceClipLengthChinese[VoiceID];
VoiceID += VOICE_ID_CHI_BASE;
}
else
Skip = true;
}
else
{
if (VoiceID < ARRAY_SIZE(VoiceClipLengthEnglish))
{
Delay = VoiceClipLengthEnglish[VoiceID];
VoiceID += VOICE_ID_ENG_BASE;
}
else
Skip = true;
}
gVoiceReadIndex++;
if (!Skip)
{
if (gVoiceReadIndex == gVoiceWriteIndex)
Delay += 3;
AUDIO_PlayVoice(VoiceID);
gCountdownToPlayNextVoice_10ms = Delay;
gFlagPlayQueuedVoice = false;
#ifdef ENABLE_VOX
gVoxResumeCountdown = 2000;
#endif
return;
}
}
if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING) // 1of11
RADIO_SetModulation(gRxVfo->Modulation);
#ifdef ENABLE_FMRADIO
if (gFmRadioMode)
BK1080_Mute(false);
#endif
if (!gEnableSpeaker)
AUDIO_AudioPathOff();
#ifdef ENABLE_VOX
gVoxResumeCountdown = 80;
#endif
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
}
#endif

View file

@ -117,7 +117,8 @@
#define 发送接收时 "\x0E\x0F\x2F\x05\x06\x8B"
//ui/menu.c
//!!还有一个列表
#define 列表 "\x83\x84"
#define 全部 "\xD5\xD6"
#define 扫描 "\x81\x82"
@ -136,14 +137,13 @@
//ui/welcome
#define 解锁 "\xB8\xB9"
//ui/scanner.c
//!!两频率
//!!两模拟亚音
//!!一数字亚音
#define 模拟亚音 "\x0C\x0D\x09\x0B"
#define 数字亚音 "\x07\x08\x09\x0B"
#define 频率 "\x03\x04"
#define 存置问 "\x1A\x1B\x3F"
#define 存置了 "\x1A\x1B\x3A"
#define 扫描 "\x81\x82"
//!! 扫描ok
//!! 扫描fail
//ui/fmradio.c
#define 删除问 "\x1E\x1F?"

View file

@ -17,7 +17,7 @@
#include "frequencies.h"
#include "misc.h"
#include "settings.h"
#include <assert.h>
// the BK4819 has 2 bands it covers, 18MHz ~ 630MHz and 760MHz ~ 1300MHz
#define BX4819_band1_lower 1800000
@ -61,11 +61,33 @@ const uint32_t NoaaFrequencyTable[10] =
#endif
const uint16_t gStepFrequencyTable[] = {
250, 500, 625, 1000, 1250, 2500, 833,
1, 5, 10, 25, 50, 100, 125, 1500, 3000, 5000, 10000, 12500, 25000, 50000
};
// this order of steps has to be preserved for backwards compatibility with other/stock firmwares
const uint16_t gStepFrequencyTable[] = {
// standard steps
[STEP_2_5kHz] = 250,
[STEP_5kHz] = 500,
[STEP_6_25kHz] = 625,
[STEP_10kHz] = 1000,
[STEP_12_5kHz] = 1250,
[STEP_25kHz] = 2500,
[STEP_8_33kHz] = 833,
// custom steps
[STEP_0_01kHz] = 1,
[STEP_0_05kHz] = 5,
[STEP_0_1kHz] = 10,
[STEP_0_25kHz] = 25,
[STEP_0_5kHz] = 50,
[STEP_1kHz] = 100,
[STEP_1_25kHz] = 125,
[STEP_15kHz] = 1500,
[STEP_30kHz] = 3000,
[STEP_50kHz] = 5000,
[STEP_100kHz] = 10000,
[STEP_125kHz] = 12500,
[STEP_250kHz] = 25000,
[STEP_500kHz] = 50000
};
const STEP_Setting_t StepSortedIndexes[] = {
STEP_0_01kHz, STEP_0_05kHz, STEP_0_1kHz, STEP_0_25kHz, STEP_0_5kHz, STEP_1kHz, STEP_1_25kHz, STEP_2_5kHz, STEP_5kHz, STEP_6_25kHz,
@ -85,16 +107,14 @@ uint32_t FREQUENCY_GetSortedIdxFromStepIdx(uint8_t stepIdx)
return i;
return 0;
}
static_assert(ARRAY_SIZE(gStepFrequencyTable) == STEP_N_ELEM);
FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency)
{
for (int band = ARRAY_SIZE(frequencyBandTable) - 1; band >= 0; band--)
for (int32_t band = BAND_N_ELEM - 1; band >= 0; band--)
if (Frequency >= frequencyBandTable[band].lower)
// if (Frequency < frequencyBandTable[band].upper)
return (FREQUENCY_Band_t)band;
return BAND1_50MHz;
// return BAND_NONE;
}
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)
@ -135,9 +155,8 @@ int32_t TX_freq_check(const uint32_t Frequency)
{ // return '0' if TX frequency is allowed
// otherwise return '-1'
if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper)
return -1; // not allowed outside this range
if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper)
return 1; // not allowed outside this range
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
return -1; // BX chip does not work in this range
@ -212,7 +231,7 @@ int32_t RX_freq_check(const uint32_t Frequency)
{ // return '0' if RX frequency is allowed
// otherwise return '-1'
if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper)
if (Frequency < frequencyBandTable[0].lower || Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper)
return -1;
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)

View file

@ -29,21 +29,19 @@ typedef struct {
extern const freq_band_table_t BX4819_band1;
extern const freq_band_table_t BX4819_band2;
extern const freq_band_table_t frequencyBandTable[7];
typedef enum {
BAND_NONE = -1,
BAND1_50MHz = 0,
BAND_NONE = -1,
BAND1_50MHz = 0,
BAND2_108MHz,
BAND3_137MHz,
BAND4_174MHz,
BAND5_350MHz,
BAND6_400MHz,
BAND7_470MHz,
BAND_LAST_ELEMENT //keep this guard as last element
BAND_N_ELEM
} FREQUENCY_Band_t;
extern const freq_band_table_t frequencyBandTable[];
typedef enum {
STEP_2_5kHz,
STEP_5kHz,
@ -66,11 +64,11 @@ typedef enum {
STEP_125kHz,
STEP_250kHz,
STEP_500kHz,
STEP_N_ELEM
} STEP_Setting_t;
extern const uint16_t gStepFrequencyTable[21];
extern const uint16_t gStepFrequencyTable[];
#ifdef ENABLE_NOAA
extern const uint32_t NoaaFrequencyTable[10];
#endif

View file

@ -41,7 +41,12 @@
#include "ui/ui.h"
FUNCTION_Type_t gCurrentFunction;
inline bool FUNCTION_IsRx()
{
return gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING ||
gCurrentFunction == FUNCTION_RECEIVE;
}
void FUNCTION_Init(void)
{
#ifdef ENABLE_NOAA

View file

@ -36,6 +36,6 @@ extern FUNCTION_Type_t gCurrentFunction;
void FUNCTION_Init(void);
void FUNCTION_Select(FUNCTION_Type_t Function);
bool FUNCTION_IsRx();
#endif

2
misc.c
View file

@ -248,7 +248,7 @@ volatile uint8_t boot_counter_10ms;
uint8_t gIsLocked = 0xFF;
inline void FUNCTION_NOP() { ; }
int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit)
{

2
misc.h
View file

@ -326,5 +326,5 @@ extern volatile uint8_t boot_counter_10ms;
int32_t NUMBER_AddWithWraparound(int32_t Base, int32_t Add, int32_t LowerLimit, int32_t UpperLimit);
unsigned long StrToUL(const char * str);
void FUNCTION_NOP();
#endif

View file

@ -23,14 +23,14 @@
| 江璐璐 | 支付宝打赏 | ¥10.00 | 2023-11-21 |
| 济南黄河业余无线电 | 微信打赏 | ¥25.00 | 2023-11-22 |
| DE.BG9JAQ | 微信打赏 | ¥9.99 | 2023-11-22 |
| 井之水 | 微信打赏 | ¥9.90 | 2023-11-22 |
| 井之水 | 微信打赏 | ¥9.90 | 2023-11-22 |
| 姜先生 | 微信打赏 | ¥66.61 | 2023-11-28 |
| Hui-Shao | 支付宝打赏 | ¥10.00 | 2023-11-29 |
| BI1OWT | 支付宝打赏 | ¥10.00 | 2023-12-01 |
| 蛋 | 微信打赏 | ¥6.66 | 2023-12-01 |
| J*n | 微信打赏 | ¥10.00 | 2023-12-04 |
| BG2FYX | 支付宝打赏 | ¥20.00 | 2023-12-06 |
| 井之水 | 微信打赏 | ¥9.90 | 2023-12-08 |

14
radio.c
View file

@ -251,7 +251,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
pVfo->Modulation = tmp;
tmp = data[6];
if (tmp >= ARRAY_SIZE(gStepFrequencyTable))
if (tmp >= STEP_N_ELEM)
tmp = STEP_12_5kHz;
pVfo->STEP_SETTING = tmp;
pVfo->StepFrequency = gStepFrequencyTable[tmp];
@ -423,13 +423,12 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
{
uint8_t Txp[3];
FREQUENCY_Band_t Band;
// *******************************
// squelch
Band = FREQUENCY_GetBand(pInfo->pRX->Frequency);
FREQUENCY_Band_t Band = FREQUENCY_GetBand(pInfo->pRX->Frequency);
uint16_t Base = (Band < BAND4_174MHz) ? 0x1E60 : 0x1E00;
if (gEeprom.SQUELCH_LEVEL == 0)
@ -511,7 +510,7 @@ void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
// output power
Band = FREQUENCY_GetBand(pInfo->pTX->Frequency);
uint8_t Txp[3];
EEPROM_ReadBuffer(0x1ED0 + (Band * 16) + (pInfo->OUTPUT_POWER * 3), Txp, 3);
@ -559,9 +558,8 @@ void RADIO_ApplyOffset(VFO_Info_t *pInfo)
if (Frequency < frequencyBandTable[0].lower)
Frequency = frequencyBandTable[0].lower;
else
if (Frequency > frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper)
Frequency = frequencyBandTable[ARRAY_SIZE(frequencyBandTable) - 1].upper;
else if (Frequency > frequencyBandTable[BAND_N_ELEM - 1].upper)
Frequency = frequencyBandTable[BAND_N_ELEM - 1].upper;
pInfo->freq_config_TX.Frequency = Frequency;
}

View file

@ -32,7 +32,7 @@
//};
typedef enum POWER_OnDisplayMode_t POWER_OnDisplayMode_t;
enum {
enum TxLockModes_t {
F_LOCK_DEF, //all default frequencies + configurable
F_LOCK_FCC,
F_LOCK_CE,
@ -74,7 +74,8 @@ enum {
OUTPUT_POWER_HIGH
};
enum {
enum ACTION_OPT_t {
ACTION_OPT_NONE = 0,
ACTION_OPT_FLASHLIGHT,
ACTION_OPT_POWER,
@ -88,14 +89,11 @@ enum {
ACTION_OPT_A_B,
ACTION_OPT_VFO_MR,
ACTION_OPT_SWITCH_DEMODUL,
#ifdef ENABLE_BLMIN_TMP_OFF
ACTION_OPT_BLMIN_TMP_OFF, //BackLight Minimum Temporay OFF
#endif
ACTION_OPT_LEN,
ACTION_OPT_D_DCD,
ACTION_OPT_WIDTH
ACTION_OPT_WIDTH,
ACTION_OPT_LEN
};
#ifdef ENABLE_VOICE
enum VOICE_Prompt_t
{

View file

@ -444,10 +444,7 @@ void UI_DisplayMain(void) {
}
} else { // receiving .. show the RX symbol
mode = VFO_MODE_RX;
if ((gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING) &&
gEeprom.RX_VFO == vfo_num) {
if (FUNCTION_IsRx() && gEeprom.RX_VFO == vfo_num) {
#ifdef ENABLE_SMALL_BOLD
UI_PrintStringSmallBold("RX", 14, 0, line);
#else
@ -733,9 +730,7 @@ void UI_DisplayMain(void) {
#endif
if (center_line == CENTER_LINE_NONE) { // we're free to use the middle line
const bool rx = (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING);
const bool rx = FUNCTION_IsRx();
#ifdef ENABLE_MDC1200
if (mdc1200_rx_ready_tick_500ms > 0)
{

View file

@ -836,7 +836,7 @@ void UI_DisplayMenu(void) {
sprintf(String, "list %u", 1 + gSubMenuSelection);
#else //!!列表
sprintf(String, "\x83\x84 %u", 1 + gSubMenuSelection);
sprintf(String, " %u", 1 + gSubMenuSelection);
#endif

View file

@ -36,28 +36,28 @@ void UI_DisplayScanner(void)
if (gScanSingleFrequency || (gScanCssState != SCAN_CSS_STATE_OFF && gScanCssState != SCAN_CSS_STATE_FAILED))
//频率
sprintf(String, "\x03\x04:%u.%05u", gScanFrequency / 100000, gScanFrequency % 100000);
sprintf(String, ":%u.%05u", gScanFrequency / 100000, gScanFrequency % 100000);
else
strcpy(String, "\x03\x04:**.*****");
strcpy(String, ":**.*****");
UI_PrintStringSmall(String, 2, 0, 1);
memset(String, 0, sizeof(String));
if (gScanCssState < SCAN_CSS_STATE_FOUND || !gScanUseCssResult)
//模拟亚音
strcpy(String, "\x0C\x0D\x09\x0B:******");
strcpy(String, ":******");
else
if (gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE)
//模拟亚音
#ifdef TEST_UNDE_CTCSS
sprintf(String, "\x0C\x0D\x09\x0B:%u.%uHz", gScanCssResultCode_all/10, gScanCssResultCode_all% 10);
sprintf(String, ":%u.%uHz", gScanCssResultCode_all/10, gScanCssResultCode_all% 10);
#else
sprintf(String, "\x0C\x0D\x09\x0B:%u.%uHz", CTCSS_Options[gScanCssResultCode] / 10, CTCSS_Options[gScanCssResultCode] % 10);
sprintf(String, ":%u.%uHz", CTCSS_Options[gScanCssResultCode] / 10, CTCSS_Options[gScanCssResultCode] % 10);
#endif
else
//数字亚音
sprintf(String, "\x07\x08\x09\x0B:D%03oN", DCS_Options[gScanCssResultCode]);
sprintf(String, ":D%03oN", DCS_Options[gScanCssResultCode]);
UI_PrintStringSmall(String, 2, 0, 3);
memset(String, 0, sizeof(String));
@ -85,12 +85,12 @@ void UI_DisplayScanner(void)
}
else if (gScanCssState == SCAN_CSS_STATE_FOUND)
//扫描ok
strcpy(String, "\x81\x82 OK.");
strcpy(String, " OK.");
else
//扫描fail
strcpy(String, "\x81\x82 FAIL.");
strcpy(String, " FAIL.");
Start = 2;
bCentered = 0;
}

View file

@ -53,9 +53,7 @@ void UI_DisplayStatus()
x1 = x + sizeof(BITMAP_TX);
}
else
if (gCurrentFunction == FUNCTION_RECEIVE ||
gCurrentFunction == FUNCTION_MONITOR ||
gCurrentFunction == FUNCTION_INCOMING)
if (FUNCTION_IsRx())
{
memmove(line + x, BITMAP_RX, sizeof(BITMAP_RX));
x1 = x + sizeof(BITMAP_RX);