1 Star 0 Fork 0

Jumbo/uv-k5-firmware-fagci-mod

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
radio.c 23.82 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app/dtmf.h"
#include <string.h>
#if defined(ENABLE_FMRADIO)
#include "app/fm.h"
#endif
#include "audio.h"
#include "bsp/dp32g030/gpio.h"
#include "dcs.h"
#include "driver/bk4819.h"
#include "driver/eeprom.h"
#include "driver/gpio.h"
#include "driver/system.h"
#include "frequencies.h"
#include "functions.h"
#include "helper/battery.h"
#include "misc.h"
#include "radio.h"
#include "settings.h"
VFO_Info_t *gTxVfo;
VFO_Info_t *gRxVfo;
VFO_Info_t *gCurrentVfo;
DCS_CodeType_t gCurrentCodeType;
DCS_CodeType_t gSelectedCodeType;
uint8_t gSelectedCode;
STEP_Setting_t gStepSetting;
VfoState_t VfoState[2];
bool RADIO_CheckValidChannel(uint16_t Channel, bool bCheckScanList,
uint8_t VFO) {
uint8_t Attributes;
uint8_t PriorityCh1;
uint8_t PriorityCh2;
if (!IS_MR_CHANNEL(Channel)) {
return false;
}
// Check channel is valid
Attributes = gMR_ChannelAttributes[Channel];
if ((Attributes & MR_CH_BAND_MASK) > BAND7_470MHz) {
return false;
}
if (bCheckScanList) {
switch (VFO) {
case 0:
if ((Attributes & MR_CH_SCANLIST1) == 0) {
return false;
}
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[0];
PriorityCh2 = gEeprom.SCANLIST_PRIORITY_CH2[0];
break;
case 1:
if ((Attributes & MR_CH_SCANLIST2) == 0) {
return false;
}
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[1];
PriorityCh2 = gEeprom.SCANLIST_PRIORITY_CH2[1];
break;
default:
return true;
}
if (PriorityCh1 == Channel) {
return false;
}
if (PriorityCh2 == Channel) {
return false;
}
}
return true;
}
uint8_t RADIO_FindNextChannel(uint8_t Channel, int8_t Direction,
bool bCheckScanList, uint8_t VFO) {
uint8_t i;
for (i = 0; i <= MR_CHANNEL_LAST; i++) {
if (Channel == 0xFF) {
Channel = MR_CHANNEL_LAST;
} else if (Channel > MR_CHANNEL_LAST) {
Channel = MR_CHANNEL_FIRST;
}
if (RADIO_CheckValidChannel(Channel, bCheckScanList, VFO)) {
return Channel;
}
Channel += Direction;
}
return 0xFF;
}
void RADIO_InitInfo(VFO_Info_t *pInfo, uint8_t ChannelSave, uint8_t Band,
uint32_t Frequency) {
memset(pInfo, 0, sizeof(*pInfo));
pInfo->Band = Band;
pInfo->SCANLIST1_PARTICIPATION = true;
pInfo->SCANLIST2_PARTICIPATION = true;
pInfo->STEP_SETTING = STEP_25_0kHz;
pInfo->StepFrequency = 2500;
pInfo->CHANNEL_SAVE = ChannelSave;
pInfo->FrequencyReverse = false;
pInfo->OUTPUT_POWER = OUTPUT_POWER_HIGH;
pInfo->ConfigRX.Frequency = Frequency;
pInfo->ConfigTX.Frequency = Frequency;
pInfo->pRX = &pInfo->ConfigRX;
pInfo->pTX = &pInfo->ConfigTX;
pInfo->FREQUENCY_OF_DEVIATION = 1000000;
RADIO_ConfigureSquelchAndOutputPower(pInfo);
}
void RADIO_ConfigureChannel(uint8_t VFO, uint32_t Arg) {
VFO_Info_t *pRadio;
uint8_t Channel;
uint8_t Attributes;
uint8_t Band;
bool bParticipation2;
uint16_t Base;
uint8_t Data[8];
uint8_t Tmp;
uint32_t Frequency;
pRadio = &gEeprom.VfoInfo[VFO];
Channel = gEeprom.ScreenChannel[VFO];
if (IS_VALID_CHANNEL(Channel)) {
#if defined(ENABLE_NOAA)
if (Channel >= NOAA_CHANNEL_FIRST) {
RADIO_InitInfo(pRadio, gEeprom.ScreenChannel[VFO], 2,
NoaaFrequencyTable[Channel - NOAA_CHANNEL_FIRST]);
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) {
return;
}
gUpdateStatus = true;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
return;
}
#endif
if (IS_MR_CHANNEL(Channel)) {
Channel = RADIO_FindNextChannel(Channel, RADIO_CHANNEL_UP, false, VFO);
if (Channel == 0xFF) {
Channel = gEeprom.FreqChannel[VFO];
gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO];
} else {
gEeprom.ScreenChannel[VFO] = Channel;
gEeprom.MrChannel[VFO] = Channel;
}
}
} else {
Channel = 205;
}
Attributes = gMR_ChannelAttributes[Channel];
if (Attributes == 0xFF) {
uint8_t Index;
if (IS_MR_CHANNEL(Channel)) {
Channel = gEeprom.FreqChannel[VFO];
gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO];
}
Index = Channel - FREQ_CHANNEL_FIRST;
RADIO_InitInfo(pRadio, Channel, Index, FrequencyBandTable[Index].lower);
return;
}
Band = Attributes & MR_CH_BAND_MASK;
if (Band > BAND7_470MHz) {
Band = BAND6_400MHz;
}
if (IS_MR_CHANNEL(Channel)) {
gEeprom.VfoInfo[VFO].Band = Band;
gEeprom.VfoInfo[VFO].SCANLIST1_PARTICIPATION =
!!(Attributes & MR_CH_SCANLIST1);
bParticipation2 = !!(Attributes & MR_CH_SCANLIST2);
} else {
Band = Channel - FREQ_CHANNEL_FIRST;
gEeprom.VfoInfo[VFO].Band = Band;
bParticipation2 = true;
gEeprom.VfoInfo[VFO].SCANLIST1_PARTICIPATION = true;
}
gEeprom.VfoInfo[VFO].SCANLIST2_PARTICIPATION = bParticipation2;
gEeprom.VfoInfo[VFO].CHANNEL_SAVE = Channel;
if (IS_MR_CHANNEL(Channel)) {
Base = Channel * 16;
} else {
Base = 0x0C80 + ((Channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16);
}
if (Arg == 2 || Channel >= FREQ_CHANNEL_FIRST) {
EEPROM_ReadBuffer(Base + 8, Data, 8);
Tmp = Data[3] & 0x0F;
if (Tmp > 2) {
Tmp = 0;
}
gEeprom.VfoInfo[VFO].FREQUENCY_DEVIATION_SETTING = Tmp;
gEeprom.VfoInfo[VFO].AM_CHANNEL_MODE = (Data[3] >> 4) & 0b11;
Tmp = Data[6];
if (Tmp > STEP_100_0kHz) {
Tmp = STEP_0_01kHz;
}
gEeprom.VfoInfo[VFO].STEP_SETTING = Tmp;
gEeprom.VfoInfo[VFO].StepFrequency = StepFrequencyTable[Tmp];
Tmp = Data[7];
if (Tmp > 10) {
Tmp = 0;
}
gEeprom.VfoInfo[VFO].SCRAMBLING_TYPE = Tmp;
gEeprom.VfoInfo[VFO].ConfigRX.CodeType = (Data[2] >> 0) & 0x0F;
gEeprom.VfoInfo[VFO].ConfigTX.CodeType = (Data[2] >> 4) & 0x0F;
Tmp = Data[0];
switch (gEeprom.VfoInfo[VFO].ConfigRX.CodeType) {
case CODE_TYPE_CONTINUOUS_TONE:
if (Tmp >= 50) {
Tmp = 0;
}
break;
case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL:
if (Tmp >= 104) {
Tmp = 0;
}
break;
default:
gEeprom.VfoInfo[VFO].ConfigRX.CodeType = CODE_TYPE_OFF;
Tmp = 0;
break;
}
gEeprom.VfoInfo[VFO].ConfigRX.Code = Tmp;
Tmp = Data[1];
switch (gEeprom.VfoInfo[VFO].ConfigTX.CodeType) {
case CODE_TYPE_CONTINUOUS_TONE:
if (Tmp >= 50) {
Tmp = 0;
}
break;
case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL:
if (Tmp >= 104) {
Tmp = 0;
}
break;
default:
gEeprom.VfoInfo[VFO].ConfigTX.CodeType = CODE_TYPE_OFF;
Tmp = 0;
break;
}
gEeprom.VfoInfo[VFO].ConfigTX.Code = Tmp;
if (Data[4] == 0xFF) {
gEeprom.VfoInfo[VFO].FrequencyReverse = false;
gEeprom.VfoInfo[VFO].CHANNEL_BANDWIDTH = 0;
gEeprom.VfoInfo[VFO].OUTPUT_POWER = 2;
gEeprom.VfoInfo[VFO].BUSY_CHANNEL_LOCK = false;
} else {
gEeprom.VfoInfo[VFO].FrequencyReverse = !!(Data[4] & 0x01);
gEeprom.VfoInfo[VFO].CHANNEL_BANDWIDTH = !!(Data[4] & 0x02);
gEeprom.VfoInfo[VFO].OUTPUT_POWER = (Data[4] >> 2) & 0x03;
gEeprom.VfoInfo[VFO].BUSY_CHANNEL_LOCK = !!(Data[4] & 0x10);
}
if (Data[5] == 0xFF) {
gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = false;
gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = 0;
} else {
gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = !!(Data[5] & 1);
gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = (Data[5] >> 0x01) & 0x03;
}
struct {
uint32_t Frequency;
uint32_t Offset;
} Info;
EEPROM_ReadBuffer(Base, &Info, 8);
pRadio->ConfigRX.Frequency = Info.Frequency;
if (Info.Offset >= 100000000) {
Info.Offset = 1000000;
}
gEeprom.VfoInfo[VFO].FREQUENCY_OF_DEVIATION = Info.Offset;
}
Frequency = pRadio->ConfigRX.Frequency;
Band = FREQUENCY_GetBand(Frequency);
if (Frequency < FrequencyBandTable[Band].lower) {
pRadio->ConfigRX.Frequency = FrequencyBandTable[Band].lower;
} else if (Frequency > FrequencyBandTable[Band].upper) {
pRadio->ConfigRX.Frequency = FrequencyBandTable[Band].upper;
} else if (Channel >= FREQ_CHANNEL_FIRST) {
pRadio->ConfigRX.Frequency = FREQUENCY_FloorToStep(
pRadio->ConfigRX.Frequency, gEeprom.VfoInfo[VFO].StepFrequency,
FrequencyBandTable[Band].lower);
}
if (Frequency >= 10800000 && Frequency <= 13599990) {
gEeprom.VfoInfo[VFO].FREQUENCY_DEVIATION_SETTING = FREQUENCY_DEVIATION_OFF;
} else if (!IS_MR_CHANNEL(Channel)) {
Frequency =
FREQUENCY_FloorToStep(gEeprom.VfoInfo[VFO].FREQUENCY_OF_DEVIATION,
gEeprom.VfoInfo[VFO].StepFrequency, 0);
gEeprom.VfoInfo[VFO].FREQUENCY_OF_DEVIATION = Frequency;
}
RADIO_ApplyOffset(pRadio);
memset(gEeprom.VfoInfo[VFO].Name, 0, sizeof(gEeprom.VfoInfo[VFO].Name));
if (IS_MR_CHANNEL(Channel)) {
// 16 bytes allocated but only 12 used
EEPROM_ReadBuffer(0x0F50 + (Channel * 0x10), gEeprom.VfoInfo[VFO].Name + 0,
8);
EEPROM_ReadBuffer(0x0F58 + (Channel * 0x10), gEeprom.VfoInfo[VFO].Name + 8,
2);
}
if (!gEeprom.VfoInfo[VFO].FrequencyReverse) {
gEeprom.VfoInfo[VFO].pRX = &gEeprom.VfoInfo[VFO].ConfigRX;
gEeprom.VfoInfo[VFO].pTX = &gEeprom.VfoInfo[VFO].ConfigTX;
} else {
gEeprom.VfoInfo[VFO].pRX = &gEeprom.VfoInfo[VFO].ConfigTX;
gEeprom.VfoInfo[VFO].pTX = &gEeprom.VfoInfo[VFO].ConfigRX;
}
if (gEeprom.VfoInfo[VFO].AM_CHANNEL_MODE) {
gEeprom.VfoInfo[VFO].ModulationType = gEeprom.VfoInfo[VFO].AM_CHANNEL_MODE;
gEeprom.VfoInfo[VFO].SCRAMBLING_TYPE = 0;
gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = false;
gEeprom.VfoInfo[VFO].ConfigRX.CodeType = CODE_TYPE_OFF;
gEeprom.VfoInfo[VFO].ConfigTX.CodeType = CODE_TYPE_OFF;
} else {
gEeprom.VfoInfo[VFO].ModulationType = false;
}
RADIO_ConfigureSquelchAndOutputPower(pRadio);
}
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo) {
uint8_t Txp[3];
uint16_t Base;
FREQUENCY_Band_t Band;
Band = FREQUENCY_GetBand(pInfo->pRX->Frequency);
if (Band < BAND4_174MHz) {
Base = 0x1E60;
} else {
Base = 0x1E00;
}
if (gEeprom.SQUELCH_LEVEL == 0) {
pInfo->SquelchOpenRSSIThresh = 0x00;
pInfo->SquelchOpenNoiseThresh = 0x7F;
pInfo->SquelchCloseGlitchThresh = 0xFF;
pInfo->SquelchCloseRSSIThresh = 0x00;
pInfo->SquelchCloseNoiseThresh = 0x7F;
pInfo->SquelchOpenGlitchThresh = 0xFF;
} else {
Base += gEeprom.SQUELCH_LEVEL;
EEPROM_ReadBuffer(Base + 0x00, &pInfo->SquelchOpenRSSIThresh, 1);
EEPROM_ReadBuffer(Base + 0x10, &pInfo->SquelchCloseRSSIThresh, 1);
EEPROM_ReadBuffer(Base + 0x20, &pInfo->SquelchOpenNoiseThresh, 1);
EEPROM_ReadBuffer(Base + 0x30, &pInfo->SquelchCloseNoiseThresh, 1);
EEPROM_ReadBuffer(Base + 0x40, &pInfo->SquelchCloseGlitchThresh, 1);
EEPROM_ReadBuffer(Base + 0x50, &pInfo->SquelchOpenGlitchThresh, 1);
if (pInfo->SquelchOpenNoiseThresh >= 0x80) {
pInfo->SquelchOpenNoiseThresh = 0x7F;
}
if (pInfo->SquelchCloseNoiseThresh >= 0x80) {
pInfo->SquelchCloseNoiseThresh = 0x7F;
}
}
Band = FREQUENCY_GetBand(pInfo->pTX->Frequency);
EEPROM_ReadBuffer(0x1ED0 + (Band * 0x10) + (pInfo->OUTPUT_POWER * 3), Txp, 3);
pInfo->TXP_CalculatedSetting = FREQUENCY_CalculateOutputPower(
Txp[0], Txp[1], Txp[2], FrequencyBandTable[Band].lower,
(FrequencyBandTable[Band].upper - FrequencyBandTable[Band].lower) / 2,
FrequencyBandTable[Band].upper, pInfo->pTX->Frequency);
}
void RADIO_ApplyOffset(VFO_Info_t *pInfo) {
uint32_t Frequency;
Frequency = pInfo->ConfigRX.Frequency;
switch (pInfo->FREQUENCY_DEVIATION_SETTING) {
case FREQUENCY_DEVIATION_OFF:
break;
case FREQUENCY_DEVIATION_ADD:
Frequency += pInfo->FREQUENCY_OF_DEVIATION;
break;
case FREQUENCY_DEVIATION_SUB:
Frequency -= pInfo->FREQUENCY_OF_DEVIATION;
break;
}
if (Frequency < FrequencyBandTable[0].lower) {
Frequency = FrequencyBandTable[0].lower;
/* Lowest is upper limit of FrequencyBandTable*/
} else if (Frequency >
FrequencyBandTable[ARRAY_SIZE(FrequencyBandTable) - 1].upper) {
Frequency = FrequencyBandTable[ARRAY_SIZE(FrequencyBandTable) - 1].upper;
}
pInfo->ConfigTX.Frequency = Frequency;
}
static void RADIO_SelectCurrentVfo(void) {
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) {
gCurrentVfo = gRxVfo;
} else {
gCurrentVfo = &gEeprom.VfoInfo[gEeprom.TX_CHANNEL];
}
}
void RADIO_SelectVfos(void) {
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_B) {
gEeprom.TX_CHANNEL = 1;
} else if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_A) {
gEeprom.TX_CHANNEL = 0;
} else if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B) {
gEeprom.TX_CHANNEL = 1;
} else if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A) {
gEeprom.TX_CHANNEL = 0;
}
gTxVfo = &gEeprom.VfoInfo[gEeprom.TX_CHANNEL];
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) {
gEeprom.RX_CHANNEL = gEeprom.TX_CHANNEL;
} else {
if (gEeprom.TX_CHANNEL == 0) {
gEeprom.RX_CHANNEL = 1;
} else {
gEeprom.RX_CHANNEL = 0;
}
}
gRxVfo = &gEeprom.VfoInfo[gEeprom.RX_CHANNEL];
RADIO_SelectCurrentVfo();
}
void RADIO_SetupRegisters(bool bSwitchToFunction0) {
BK4819_FilterBandwidth_t Bandwidth;
uint16_t Status;
uint16_t InterruptMask;
uint32_t Frequency;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gEnableSpeaker = false;
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28_GREEN, false);
Bandwidth = gRxVfo->CHANNEL_BANDWIDTH;
if (Bandwidth != BK4819_FILTER_BW_WIDE) {
Bandwidth = BK4819_FILTER_BW_NARROW;
}
BK4819_SetFilterBandwidth(Bandwidth);
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29_RED, false);
BK4819_SetupPowerAmplifier(0, 0);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, false);
while (1) {
Status = BK4819_ReadRegister(BK4819_REG_0C);
if ((Status & 1U) == 0) { // INTERRUPT REQUEST
break;
}
BK4819_WriteRegister(BK4819_REG_02, 0);
SYSTEM_DelayMs(1);
}
BK4819_WriteRegister(BK4819_REG_3F, 0);
BK4819_WriteRegister(BK4819_REG_7D, gEeprom.MIC_SENSITIVITY_TUNING | 0xE94F);
#if defined(ENABLE_NOAA)
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) || !gIsNoaaMode) {
Frequency = gRxVfo->pRX->Frequency;
} else {
Frequency = NoaaFrequencyTable[gNoaaChannel];
}
#else
Frequency = gRxVfo->pRX->Frequency;
#endif
BK4819_SetFrequency(Frequency);
BK4819_SetupSquelch(
gRxVfo->SquelchOpenRSSIThresh, gRxVfo->SquelchCloseRSSIThresh,
gRxVfo->SquelchOpenNoiseThresh, gRxVfo->SquelchCloseNoiseThresh,
gRxVfo->SquelchCloseGlitchThresh, gRxVfo->SquelchOpenGlitchThresh);
BK4819_PickRXFilterPathBasedOnFrequency(Frequency);
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, true);
BK4819_WriteRegister(BK4819_REG_48, 0xB3A8);
InterruptMask = 0 | BK4819_REG_3F_SQUELCH_FOUND | BK4819_REG_3F_SQUELCH_LOST;
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE)) {
if (!gRxVfo->ModulationType) {
uint8_t CodeType;
uint8_t Code;
CodeType = gSelectedCodeType;
Code = gSelectedCode;
if (gCssScanMode == CSS_SCAN_MODE_OFF) {
CodeType = gRxVfo->pRX->CodeType;
Code = gRxVfo->pRX->Code;
}
switch (CodeType) {
case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL:
BK4819_SetCDCSSCodeWord(DCS_GetGolayCodeWord(CodeType, Code));
InterruptMask = 0 | BK4819_REG_3F_CxCSS_TAIL |
BK4819_REG_3F_CDCSS_FOUND | BK4819_REG_3F_CDCSS_LOST |
BK4819_REG_3F_SQUELCH_FOUND |
BK4819_REG_3F_SQUELCH_LOST;
break;
case CODE_TYPE_CONTINUOUS_TONE:
BK4819_SetCTCSSFrequency(CTCSS_Options[Code]);
BK4819_Set55HzTailDetection();
InterruptMask = 0 | BK4819_REG_3F_CxCSS_TAIL |
BK4819_REG_3F_CTCSS_FOUND | BK4819_REG_3F_CTCSS_LOST |
BK4819_REG_3F_SQUELCH_FOUND |
BK4819_REG_3F_SQUELCH_LOST;
break;
default:
BK4819_SetCTCSSFrequency(670);
BK4819_Set55HzTailDetection();
InterruptMask = 0 | BK4819_REG_3F_CxCSS_TAIL |
BK4819_REG_3F_SQUELCH_FOUND |
BK4819_REG_3F_SQUELCH_LOST;
break;
}
if (gRxVfo->SCRAMBLING_TYPE == 0 || !gSetting_ScrambleEnable) {
BK4819_DisableScramble();
} else {
BK4819_EnableScramble(gRxVfo->SCRAMBLING_TYPE - 1);
}
}
} else {
BK4819_SetCTCSSFrequency(2625);
InterruptMask = 0 | BK4819_REG_3F_CTCSS_FOUND | BK4819_REG_3F_CTCSS_LOST |
BK4819_REG_3F_SQUELCH_FOUND | BK4819_REG_3F_SQUELCH_LOST;
}
if (gEeprom.VOX_SWITCH
#if defined(ENABLE_FMRADIO)
&& !gFmRadioMode
#endif
&& IS_NOT_NOAA_CHANNEL(gCurrentVfo->CHANNEL_SAVE) && !gCurrentVfo->ModulationType) {
BK4819_EnableVox(gEeprom.VOX1_THRESHOLD, gEeprom.VOX0_THRESHOLD);
InterruptMask |= 0 | BK4819_REG_3F_VOX_FOUND | BK4819_REG_3F_VOX_LOST;
} else {
BK4819_DisableVox();
}
if (gRxVfo->ModulationType || !gRxVfo->DTMF_DECODING_ENABLE) {
BK4819_DisableDTMF();
} else {
BK4819_EnableDTMF();
InterruptMask |= BK4819_REG_3F_DTMF_5TONE_FOUND;
}
BK4819_WriteRegister(BK4819_REG_3F, InterruptMask);
BK4819_WriteRegister(0x40, (BK4819_ReadRegister(0x40) & ~(0b11111111111)) |
0b10110101010);
FUNCTION_Init();
if (bSwitchToFunction0) {
FUNCTION_Select(FUNCTION_FOREGROUND);
}
}
#if defined(ENABLE_NOAA)
void RADIO_ConfigureNOAA(void) {
uint8_t ChanAB;
gUpdateStatus = true;
if (gEeprom.NOAA_AUTO_SCAN) {
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) {
if (IS_NOT_NOAA_CHANNEL(gEeprom.ScreenChannel[0])) {
if (IS_NOT_NOAA_CHANNEL(gEeprom.ScreenChannel[1])) {
gIsNoaaMode = false;
return;
}
ChanAB = 1;
} else {
ChanAB = 0;
}
if (!gIsNoaaMode) {
gNoaaChannel =
gEeprom.VfoInfo[ChanAB].CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
}
gIsNoaaMode = true;
return;
}
if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST) {
gIsNoaaMode = true;
gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
gNOAA_Countdown = 50;
gScheduleNOAA = false;
} else {
gIsNoaaMode = false;
}
} else {
gIsNoaaMode = false;
}
}
#endif
void RADIO_SetTxParameters(void) {
BK4819_FilterBandwidth_t Bandwidth;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gEnableSpeaker = false;
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, false);
Bandwidth = gCurrentVfo->CHANNEL_BANDWIDTH;
if (Bandwidth != BK4819_FILTER_BW_WIDE) {
Bandwidth = BK4819_FILTER_BW_NARROW;
}
BK4819_SetFilterBandwidth(Bandwidth);
BK4819_SetFrequency(gCurrentVfo->pTX->Frequency);
BK4819_PrepareTransmit();
SYSTEM_DelayMs(10);
BK4819_PickRXFilterPathBasedOnFrequency(gCurrentVfo->pTX->Frequency);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, true);
SYSTEM_DelayMs(5);
BK4819_SetupPowerAmplifier(gCurrentVfo->TXP_CalculatedSetting,
gCurrentVfo->pTX->Frequency);
SYSTEM_DelayMs(10);
switch (gCurrentVfo->pTX->CodeType) {
case CODE_TYPE_CONTINUOUS_TONE:
BK4819_SetCTCSSFrequency(CTCSS_Options[gCurrentVfo->pTX->Code]);
break;
case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL:
BK4819_SetCDCSSCodeWord(DCS_GetGolayCodeWord(gCurrentVfo->pTX->CodeType,
gCurrentVfo->pTX->Code));
break;
default:
BK4819_ExitSubAu();
break;
}
}
void RADIO_SetVfoState(VfoState_t State) {
if (State == VFO_STATE_NORMAL) {
VfoState[0] = VFO_STATE_NORMAL;
VfoState[1] = VFO_STATE_NORMAL;
#if defined(ENABLE_FMRADIO)
gFM_ResumeCountdown = 0;
#endif
} else {
if (State == VFO_STATE_VOL_HIGH) {
VfoState[0] = VFO_STATE_VOL_HIGH;
VfoState[1] = VFO_STATE_TX_DISABLE;
} else {
uint8_t Channel;
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) {
Channel = gEeprom.RX_CHANNEL;
} else {
Channel = gEeprom.TX_CHANNEL;
}
VfoState[Channel] = State;
}
#if defined(ENABLE_FMRADIO)
gFM_ResumeCountdown = 5;
#endif
}
gUpdateDisplay = true;
}
void RADIO_PrepareTX(void) {
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) {
gDualWatchCountdown = 360;
gScheduleDualWatch = false;
if (!gRxVfoIsActive) {
gEeprom.RX_CHANNEL = gEeprom.TX_CHANNEL;
gRxVfo = &gEeprom.VfoInfo[gEeprom.TX_CHANNEL];
}
gRxVfoIsActive = true;
}
RADIO_SelectCurrentVfo();
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
if (gAlarmState == ALARM_STATE_OFF
#if defined(ENABLE_TX1750)
|| gAlarmState == ALARM_STATE_TX1750
#endif
#if defined(ENABLE_ALARM)
|| (gAlarmState == ALARM_STATE_ALARM &&
gEeprom.ALARM_MODE == ALARM_MODE_TONE)
#endif
) {
#else
if (1) {
#endif
VfoState_t State;
if (FREQUENCY_Check(gCurrentVfo)) {
if (gCurrentVfo->BUSY_CHANNEL_LOCK &&
gCurrentFunction == FUNCTION_RECEIVE) {
State = VFO_STATE_BUSY;
} else if (gBatteryDisplayLevel == 0) {
State = VFO_STATE_BAT_LOW;
} else if (gBatteryDisplayLevel == 6) {
State = VFO_STATE_VOL_HIGH;
} else {
goto Skip;
}
} else {
State = VFO_STATE_TX_DISABLE;
}
RADIO_SetVfoState(State);
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
gAlarmState = ALARM_STATE_OFF;
#endif
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL);
gDTMF_ReplyState = DTMF_REPLY_NONE;
return;
}
Skip:
if (gDTMF_ReplyState == DTMF_REPLY_ANI) {
if (gDTMF_CallMode == DTMF_CALL_MODE_DTMF) {
gDTMF_IsTx = true;
gDTMF_CallState = DTMF_CALL_STATE_NONE;
gDTMF_TxStopCountdown = 6;
} else {
gDTMF_CallState = DTMF_CALL_STATE_CALL_OUT;
gDTMF_IsTx = false;
}
}
FUNCTION_Select(FUNCTION_TRANSMIT);
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
if (gAlarmState == ALARM_STATE_OFF) {
gTxTimerCountdown = gEeprom.TX_TIMEOUT_TIMER * 120;
} else {
gTxTimerCountdown = 0;
}
#else
gTxTimerCountdown = gEeprom.TX_TIMEOUT_TIMER * 120;
#endif
gTxTimeoutReached = false;
gFlagEndTransmission = false;
gRTTECountdown = 0;
gDTMF_ReplyState = DTMF_REPLY_NONE;
}
void RADIO_EnableCxCSS(void) {
switch (gCurrentVfo->pTX->CodeType) {
case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL:
BK4819_EnableCDCSS();
SYSTEM_DelayMs(200);
break;
case CODE_TYPE_CONTINUOUS_TONE:
BK4819_EnableCTCSS();
SYSTEM_DelayMs(200);
break;
default:
break;
}
}
void RADIO_PrepareCssTX(void) {
RADIO_PrepareTX();
SYSTEM_DelayMs(200);
RADIO_EnableCxCSS();
RADIO_SetupRegisters(true);
}
void RADIO_SendEndOfTransmission(void) {
if (gEeprom.ROGER == ROGER_MODE_ROGER) {
BK4819_PlayRoger();
} else if (gEeprom.ROGER == ROGER_MODE_MDC) {
BK4819_PlayRogerMDC();
}
if (gDTMF_CallState == DTMF_CALL_STATE_NONE &&
(gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_EOT ||
gCurrentVfo->DTMF_PTT_ID_TX_MODE == PTT_ID_BOTH)) {
if (gEeprom.DTMF_SIDE_TONE) {
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gEnableSpeaker = true;
SYSTEM_DelayMs(60);
}
BK4819_EnterDTMF_TX(gEeprom.DTMF_SIDE_TONE);
BK4819_PlayDTMFString(
gEeprom.DTMF_DOWN_CODE, 0, gEeprom.DTMF_FIRST_CODE_PERSIST_TIME,
gEeprom.DTMF_HASH_CODE_PERSIST_TIME, gEeprom.DTMF_CODE_PERSIST_TIME,
gEeprom.DTMF_CODE_INTERVAL_TIME);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gEnableSpeaker = false;
}
BK4819_ExitDTMF_TX(true);
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/jumbo5566/uv-k5-firmware-fagci-mod.git
[email protected]:jumbo5566/uv-k5-firmware-fagci-mod.git
jumbo5566
uv-k5-firmware-fagci-mod
uv-k5-firmware-fagci-mod
main

搜索帮助