custom-uv-k5-firmware/radio.c

820 lines
21 KiB
C
Raw Normal View History

/* 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 <string.h>
2023-08-29 07:15:44 +08:00
#include "app/fm.h"
#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"
2023-08-14 19:28:09 +08:00
#include "functions.h"
#include "helper/battery.h"
#include "misc.h"
#include "radio.h"
#include "settings.h"
2023-08-30 07:01:30 +08:00
VFO_Info_t *gTxInfo;
VFO_Info_t *gRxInfo;
2023-08-20 22:28:17 +08:00
VFO_Info_t *gCrossTxRadioInfo;
2023-08-15 00:30:30 +08:00
DCS_CodeType_t gCodeType;
DCS_CodeType_t gCopyOfCodeType;
uint8_t gCode;
2023-08-29 23:02:35 +08:00
STEP_Setting_t gStepSetting;
bool RADIO_CheckValidChannel(uint16_t Channel, bool bCheckScanList, uint8_t VFO)
{
2023-08-28 19:05:15 +08:00
uint8_t Attributes;
uint8_t PriorityCh1;
uint8_t PriorityCh2;
2023-08-29 10:35:21 +08:00
if (!IS_MR_CHANNEL(Channel)) {
return false;
}
// Check channel is valid
2023-08-28 19:05:15 +08:00
Attributes = gMR_ChannelAttributes[Channel];
if ((Attributes & MR_CH_BAND_MASK) > BAND7_470MHz) {
return false;
}
if (bCheckScanList) {
switch (VFO) {
case 0:
2023-08-28 19:05:15 +08:00
if ((Attributes & MR_CH_SCANLIST1) == 0) {
return false;
}
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[0];
PriorityCh2 = gEeprom.SCANLIST_PRIORITY_CH2[0];
break;
case 1:
2023-08-28 19:05:15 +08:00
if ((Attributes & MR_CH_SCANLIST2) == 0) {
return false;
}
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[1];
PriorityCh2 = gEeprom.SCANLIST_PRIORITY_CH2[1];
break;
default:
return true;
}
2023-08-21 03:39:47 +08:00
if (PriorityCh1 == Channel) {
return false;
}
2023-08-21 03:39:47 +08:00
if (PriorityCh2 == Channel) {
return false;
}
}
return true;
}
2023-08-28 20:37:16 +08:00
uint8_t RADIO_FindNextChannel(uint8_t Channel, int8_t Direction, bool bCheckScanList, uint8_t VFO)
{
uint8_t i;
for (i = 0; i < 200; i++) {
2023-08-21 03:39:47 +08:00
if (Channel == 0xFF) {
2023-08-29 10:35:21 +08:00
Channel = MR_CHANNEL_LAST;
} else if (Channel > MR_CHANNEL_LAST) {
Channel = MR_CHANNEL_FIRST;
}
2023-08-21 03:39:47 +08:00
if (RADIO_CheckValidChannel(Channel, bCheckScanList, VFO)) {
return Channel;
}
2023-08-21 03:39:47 +08:00
Channel += Direction;
}
return 0xFF;
}
2023-08-20 22:28:17 +08:00
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;
2023-08-29 23:02:35 +08:00
pInfo->STEP_SETTING = STEP_25_0kHz;
pInfo->StepFrequency = 2500;
pInfo->CHANNEL_SAVE = ChannelSave;
pInfo->FrequencyReverse = false;
2023-08-22 06:57:56 +08:00
pInfo->OUTPUT_POWER = OUTPUT_POWER_HIGH;
2023-08-30 17:35:41 +08:00
pInfo->ConfigRX.Frequency = Frequency;
pInfo->ConfigTX.Frequency = Frequency;
pInfo->pCurrent = &pInfo->ConfigRX;
pInfo->pReverse = &pInfo->ConfigTX;
2023-08-30 05:05:22 +08:00
pInfo->FREQUENCY_OF_DEVIATION = 1000000;
RADIO_ConfigureSquelchAndOutputPower(pInfo);
}
2023-08-20 22:28:17 +08:00
void RADIO_ConfigureChannel(uint8_t VFO, uint32_t Arg)
{
2023-08-20 22:28:17 +08:00
VFO_Info_t *pRadio;
2023-08-28 05:57:33 +08:00
uint8_t Channel;
2023-08-28 19:05:15 +08:00
uint8_t Attributes;
uint8_t Band;
bool bParticipation2;
uint16_t Base;
uint8_t Data[8];
uint8_t Tmp;
2023-08-12 05:37:00 +08:00
uint32_t Frequency;
2023-08-20 22:28:17 +08:00
pRadio = &gEeprom.VfoInfo[VFO];
if (!gSetting_350EN) {
2023-08-28 19:05:15 +08:00
if (gEeprom.FreqChannel[VFO] == 204) {
gEeprom.FreqChannel[VFO] = 205;
}
2023-08-28 19:05:15 +08:00
if (gEeprom.ScreenChannel[VFO] == 204) {
gEeprom.ScreenChannel[VFO] = 205;
}
}
2023-08-28 19:05:15 +08:00
Channel = gEeprom.ScreenChannel[VFO];
2023-08-29 10:24:03 +08:00
if (IS_VALID_CHANNEL(Channel)) {
if (Channel >= NOAA_CHANNEL_FIRST) {
RADIO_InitInfo(pRadio, gEeprom.ScreenChannel[VFO], 2, NoaaFrequencyTable[Channel - NOAA_CHANNEL_FIRST]);
2023-08-21 03:04:40 +08:00
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF) {
return;
}
2023-08-30 07:19:12 +08:00
gUpdateStatus = true;
2023-08-21 03:04:40 +08:00
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
return;
}
2023-08-29 10:24:03 +08:00
if (IS_MR_CHANNEL(Channel)) {
2023-08-28 05:57:33 +08:00
Channel = RADIO_FindNextChannel(Channel, RADIO_CHANNEL_UP, false, VFO);
if (Channel == 0xFF) {
2023-08-28 19:05:15 +08:00
Channel = gEeprom.FreqChannel[VFO];
gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO];
} else {
2023-08-28 19:05:15 +08:00
gEeprom.ScreenChannel[VFO] = Channel;
gEeprom.MrChannel[VFO] = Channel;
}
}
} else {
2023-08-28 05:57:33 +08:00
Channel = 205;
}
2023-08-28 19:05:15 +08:00
Attributes = gMR_ChannelAttributes[Channel];
if (Attributes == 0xFF) {
uint8_t Index;
2023-08-29 10:24:03 +08:00
if (IS_MR_CHANNEL(Channel)) {
2023-08-28 19:05:15 +08:00
Channel = gEeprom.FreqChannel[VFO];
gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO];
}
2023-08-29 10:24:03 +08:00
Index = Channel - FREQ_CHANNEL_FIRST;
2023-08-28 05:57:33 +08:00
RADIO_InitInfo(pRadio, Channel, Index, gLowerLimitFrequencyBandTable[Index]);
return;
}
2023-08-28 19:05:15 +08:00
Band = Attributes & MR_CH_BAND_MASK;
if (Band > BAND7_470MHz) {
Band = BAND6_400MHz;
}
2023-08-29 10:24:03 +08:00
if (IS_MR_CHANNEL(Channel)) {
2023-08-20 22:28:17 +08:00
gEeprom.VfoInfo[VFO].Band = Band;
2023-08-28 19:05:15 +08:00
gEeprom.VfoInfo[VFO].SCANLIST1_PARTICIPATION = !!(Attributes & MR_CH_SCANLIST1);
bParticipation2 = !!(Attributes & MR_CH_SCANLIST2);
} else {
2023-08-29 10:24:03 +08:00
Band = Channel - FREQ_CHANNEL_FIRST;
2023-08-20 22:28:17 +08:00
gEeprom.VfoInfo[VFO].Band = Band;
bParticipation2 = true;
2023-08-20 22:28:17 +08:00
gEeprom.VfoInfo[VFO].SCANLIST1_PARTICIPATION = true;
}
2023-08-20 22:28:17 +08:00
gEeprom.VfoInfo[VFO].SCANLIST2_PARTICIPATION = bParticipation2;
2023-08-28 05:57:33 +08:00
gEeprom.VfoInfo[VFO].CHANNEL_SAVE = Channel;
2023-08-29 10:24:03 +08:00
if (IS_MR_CHANNEL(Channel)) {
2023-08-28 05:57:33 +08:00
Base = Channel * 16;
} else {
2023-08-29 10:24:03 +08:00
Base = 0x0C80 + ((Channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16);
}
2023-08-29 10:24:03 +08:00
if (Arg == 2 || Channel >= FREQ_CHANNEL_FIRST) {
EEPROM_ReadBuffer(Base + 8, Data, 8);
Tmp = Data[3] & 0x0F;
if (Tmp > 2) {
Tmp = 0;
}
2023-08-20 22:28:17 +08:00
gEeprom.VfoInfo[VFO].FREQUENCY_DEVIATION_SETTING = Tmp;
gEeprom.VfoInfo[VFO].AM_CHANNEL_MODE = !!(Data[3] & 0x10);
2023-08-28 05:31:19 +08:00
Tmp = Data[6];
2023-08-29 23:02:35 +08:00
if (Tmp > STEP_8_33kHz) {
Tmp = STEP_25_0kHz;
}
2023-08-20 22:28:17 +08:00
gEeprom.VfoInfo[VFO].STEP_SETTING = Tmp;
gEeprom.VfoInfo[VFO].StepFrequency = StepFrequencyTable[Tmp];
Tmp = Data[7];
if (Tmp > 10) {
Tmp = 0;
}
2023-08-20 22:28:17 +08:00
gEeprom.VfoInfo[VFO].SCRAMBLING_TYPE = Tmp;
2023-08-30 17:35:41 +08:00
gEeprom.VfoInfo[VFO].ConfigRX.CodeType = (Data[2] >> 0) & 0x0F;
gEeprom.VfoInfo[VFO].ConfigTX.CodeType = (Data[2] >> 4) & 0x0F;
Tmp = Data[0];
2023-08-30 17:35:41 +08:00
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:
2023-08-30 17:35:41 +08:00
gEeprom.VfoInfo[VFO].ConfigRX.CodeType = CODE_TYPE_OFF;
break;
}
2023-08-30 17:35:41 +08:00
gEeprom.VfoInfo[VFO].ConfigRX.RX_TX_Code = Tmp;
Tmp = Data[1];
2023-08-30 17:35:41 +08:00
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:
2023-08-30 17:35:41 +08:00
gEeprom.VfoInfo[VFO].ConfigTX.CodeType = CODE_TYPE_OFF;
break;
}
2023-08-30 17:35:41 +08:00
gEeprom.VfoInfo[VFO].ConfigTX.RX_TX_Code = Tmp;
if (Data[4] == 0xFF) {
2023-08-20 22:28:17 +08:00
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 {
2023-08-20 22:28:17 +08:00
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) {
2023-08-20 22:28:17 +08:00
gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = false;
gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = 0;
} else {
2023-08-20 22:28:17 +08:00
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);
2023-08-30 17:35:41 +08:00
pRadio->ConfigRX.Frequency = Info.Frequency;
if (Info.Offset >= 100000000) {
Info.Offset = 1000000;
}
2023-08-20 22:28:17 +08:00
gEeprom.VfoInfo[VFO].FREQUENCY_OF_DEVIATION = Info.Offset;
}
2023-08-30 17:35:41 +08:00
Frequency = pRadio->ConfigRX.Frequency;
2023-08-12 05:37:00 +08:00
if (Frequency < gLowerLimitFrequencyBandTable[Band]) {
2023-08-30 17:35:41 +08:00
pRadio->ConfigRX.Frequency = gLowerLimitFrequencyBandTable[Band];
2023-08-12 05:37:00 +08:00
} else if (Frequency > gUpperLimitFrequencyBandTable[Band]) {
2023-08-30 17:35:41 +08:00
pRadio->ConfigRX.Frequency = gUpperLimitFrequencyBandTable[Band];
2023-08-29 10:24:03 +08:00
} else if (Channel >= FREQ_CHANNEL_FIRST) {
2023-08-30 17:35:41 +08:00
pRadio->ConfigRX.Frequency = FREQUENCY_FloorToStep(pRadio->ConfigRX.Frequency, gEeprom.VfoInfo[VFO].StepFrequency, gLowerLimitFrequencyBandTable[Band]);
}
2023-08-30 17:35:41 +08:00
pRadio->ConfigRX.Frequency = Frequency;
if (Frequency - 10800000 < 2799991) {
2023-08-22 06:57:56 +08:00
gEeprom.VfoInfo[VFO].FREQUENCY_DEVIATION_SETTING = FREQUENCY_DEVIATION_OFF;
2023-08-29 10:35:21 +08:00
} else if (!IS_MR_CHANNEL(Channel)) {
2023-08-20 22:28:17 +08:00
Frequency = FREQUENCY_FloorToStep(gEeprom.VfoInfo[VFO].FREQUENCY_OF_DEVIATION, gEeprom.VfoInfo[VFO].StepFrequency, 0);
gEeprom.VfoInfo[VFO].FREQUENCY_OF_DEVIATION = Frequency;
}
2023-08-13 00:17:29 +08:00
RADIO_ApplyOffset(pRadio);
2023-08-20 22:28:17 +08:00
memset(gEeprom.VfoInfo[VFO].Name, 0, sizeof(gEeprom.VfoInfo[VFO].Name));
2023-08-29 10:35:21 +08:00
if (IS_MR_CHANNEL(Channel)) {
// 16 bytes allocated but only 12 used
2023-08-28 05:57:33 +08:00
EEPROM_ReadBuffer(0x0F50 + (Channel * 0x10), gEeprom.VfoInfo[VFO].Name + 0, 8);
EEPROM_ReadBuffer(0x0F58 + (Channel * 0x10), gEeprom.VfoInfo[VFO].Name + 8, 2);
}
2023-08-30 05:05:22 +08:00
if (!gEeprom.VfoInfo[VFO].FrequencyReverse) {
2023-08-30 17:35:41 +08:00
gEeprom.VfoInfo[VFO].pCurrent = &gEeprom.VfoInfo[VFO].ConfigRX;
gEeprom.VfoInfo[VFO].pReverse = &gEeprom.VfoInfo[VFO].ConfigTX;
} else {
2023-08-30 17:35:41 +08:00
gEeprom.VfoInfo[VFO].pCurrent = &gEeprom.VfoInfo[VFO].ConfigTX;
gEeprom.VfoInfo[VFO].pReverse = &gEeprom.VfoInfo[VFO].ConfigRX;
}
2023-08-30 07:47:34 +08:00
if (!gSetting_350EN) {
2023-08-30 17:35:41 +08:00
FREQ_Config_t *pConfig = gEeprom.VfoInfo[VFO].pCurrent;
if (pConfig->Frequency - 35000000 < 4999991) {
pConfig->Frequency = 41001250;
}
}
2023-08-29 10:24:03 +08:00
if (gEeprom.VfoInfo[VFO].Band == BAND2_108MHz && gEeprom.VfoInfo[VFO].AM_CHANNEL_MODE) {
2023-08-22 06:37:36 +08:00
gEeprom.VfoInfo[VFO].IsAM = true;
2023-08-20 22:28:17 +08:00
gEeprom.VfoInfo[VFO].SCRAMBLING_TYPE = 0;
gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = false;
2023-08-30 17:35:41 +08:00
gEeprom.VfoInfo[VFO].ConfigRX.CodeType = CODE_TYPE_OFF;
gEeprom.VfoInfo[VFO].ConfigTX.CodeType = CODE_TYPE_OFF;
} else {
2023-08-22 06:37:36 +08:00
gEeprom.VfoInfo[VFO].IsAM = false;
}
RADIO_ConfigureSquelchAndOutputPower(pRadio);
}
2023-08-20 22:28:17 +08:00
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
{
uint8_t Txp[3];
uint16_t Base;
FREQUENCY_Band_t Band;
2023-08-30 17:35:41 +08:00
Band = FREQUENCY_GetBand(pInfo->pCurrent->Frequency);
if (Band < BAND4_174MHz) {
Base = 0x1E60;
} else {
Base = 0x1E00;
}
if (gEeprom.SQUELCH_LEVEL == 0) {
2023-08-13 01:26:38 +08:00
pInfo->SquelchOpenRSSIThresh = 0x00;
pInfo->SquelchOpenNoiseThresh = 0x7F;
pInfo->SquelchCloseGlitchThresh = 0xFF;
pInfo->SquelchCloseRSSIThresh = 0x00;
pInfo->SquelchCloseNoiseThresh = 0x7F;
pInfo->SquelchOpenGlitchThresh = 0xFF;
} else {
Base += gEeprom.SQUELCH_LEVEL;
2023-08-13 01:26:38 +08:00
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;
}
2023-08-13 01:26:38 +08:00
if (pInfo->SquelchCloseNoiseThresh >= 0x80) {
pInfo->SquelchCloseNoiseThresh = 0x7F;
}
}
2023-08-30 17:35:41 +08:00
Band = FREQUENCY_GetBand(pInfo->pReverse->Frequency);
EEPROM_ReadBuffer(0x1ED0 + (Band * 0x10) + (pInfo->OUTPUT_POWER * 3), Txp, 3);
pInfo->TXP_CalculatedSetting =
FREQUENCY_CalculateOutputPower(
Txp[0],
Txp[1],
Txp[2],
LowerLimitFrequencyBandTable[Band],
MiddleFrequencyBandTable[Band],
UpperLimitFrequencyBandTable[Band],
2023-08-30 17:35:41 +08:00
pInfo->pReverse->Frequency);
}
2023-08-20 22:28:17 +08:00
void RADIO_ApplyOffset(VFO_Info_t *pInfo)
{
uint32_t Frequency;
2023-08-30 17:35:41 +08:00
Frequency = pInfo->ConfigRX.Frequency;
switch (pInfo->FREQUENCY_DEVIATION_SETTING) {
2023-08-22 06:57:56 +08:00
case FREQUENCY_DEVIATION_OFF:
break;
2023-08-22 06:57:56 +08:00
case FREQUENCY_DEVIATION_ADD:
Frequency += pInfo->FREQUENCY_OF_DEVIATION;
break;
2023-08-22 06:57:56 +08:00
case FREQUENCY_DEVIATION_SUB:
Frequency -= pInfo->FREQUENCY_OF_DEVIATION;
break;
}
if (Frequency < 5000000) {
Frequency = 5000000;
} else if (Frequency > 60000000) {
Frequency = 60000000;
}
2023-08-30 17:35:41 +08:00
pInfo->ConfigTX.Frequency = Frequency;
}
void RADIO_ConfigureTX(void)
{
2023-08-21 03:04:40 +08:00
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_B) {
gEeprom.TX_CHANNEL = 1;
2023-08-21 03:04:40 +08:00
} else if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_A) {
gEeprom.TX_CHANNEL = 0;
2023-08-21 03:04:40 +08:00
} else if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B) {
gEeprom.TX_CHANNEL = 1;
2023-08-21 03:04:40 +08:00
} else if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A) {
2023-08-14 05:29:18 +08:00
gEeprom.TX_CHANNEL = 0;
}
2023-08-30 07:01:30 +08:00
gTxInfo = &gEeprom.VfoInfo[gEeprom.TX_CHANNEL];
gEeprom.RX_CHANNEL = gEeprom.TX_CHANNEL;
2023-08-21 03:04:40 +08:00
if (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) {
if (gEeprom.TX_CHANNEL == 0) {
gEeprom.RX_CHANNEL = 1;
} else {
gEeprom.RX_CHANNEL = 0;
}
}
2023-08-30 07:01:30 +08:00
gRxInfo = &gEeprom.VfoInfo[gEeprom.RX_CHANNEL];
RADIO_ConfigureCrossTX();
}
void RADIO_ConfigureCrossTX(void)
{
2023-08-30 07:01:30 +08:00
gCrossTxRadioInfo = gRxInfo;
2023-08-21 03:04:40 +08:00
if (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) {
2023-08-20 22:28:17 +08:00
gCrossTxRadioInfo = &gEeprom.VfoInfo[gEeprom.TX_CHANNEL];
}
}
void RADIO_SetupRegisters(bool bSwitchToFunction0)
{
2023-08-27 01:31:41 +08:00
BK4819_FilterBandwidth_t Bandwidth;
uint16_t Status;
uint16_t InterruptMask;
uint32_t Frequency;
2023-08-15 00:30:30 +08:00
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
g_2000036B = 0;
BK4819_ToggleGpioOut(BK4819_GPIO0_PIN28, false);
2023-08-30 07:01:30 +08:00
Bandwidth = gRxInfo->CHANNEL_BANDWIDTH;
2023-08-27 01:31:41 +08:00
if (Bandwidth != BK4819_FILTER_BW_WIDE) {
Bandwidth = BK4819_FILTER_BW_NARROW;
}
BK4819_SetFilterBandwidth(Bandwidth);
BK4819_ToggleGpioOut(BK4819_GPIO1_PIN29, false);
BK4819_SetupPowerAmplifier(0, 0);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, false);
while (1) {
Status = BK4819_GetRegister(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 | 0xE940);
2023-08-30 07:01:30 +08:00
if (IS_NOT_NOAA_CHANNEL(gRxInfo->CHANNEL_SAVE) || !gIsNoaaMode) {
2023-08-30 17:35:41 +08:00
Frequency = gRxInfo->pCurrent->Frequency;
} else {
Frequency = NoaaFrequencyTable[gNoaaChannel];
}
BK4819_SetFrequency(Frequency);
2023-08-13 01:26:38 +08:00
BK4819_SetupSquelch(
2023-08-30 07:01:30 +08:00
gRxInfo->SquelchOpenRSSIThresh, gRxInfo->SquelchCloseRSSIThresh,
gRxInfo->SquelchOpenNoiseThresh, gRxInfo->SquelchCloseNoiseThresh,
gRxInfo->SquelchCloseGlitchThresh, gRxInfo->SquelchOpenGlitchThresh);
2023-08-13 00:17:29 +08:00
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
;
2023-08-30 07:01:30 +08:00
if (IS_NOT_NOAA_CHANNEL(gRxInfo->CHANNEL_SAVE)) {
2023-08-30 07:47:34 +08:00
if (!gRxInfo->IsAM) {
uint8_t CodeType;
uint8_t CodeWord;
CodeType = gCodeType;
CodeWord = gCode;
if (g_20000381 == 0) {
2023-08-30 17:35:41 +08:00
CodeType = gRxInfo->pCurrent->CodeType;
CodeWord = gRxInfo->pCurrent->RX_TX_Code;
}
switch (CodeType) {
case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL:
BK4819_SetCDCSSCodeWord(DCS_GetGolayCodeWord(CodeType, CodeWord));
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_SetCTCSSBaudRate(CTCSS_Options[CodeWord]);
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_SetCTCSSBaudRate(670);
BK4819_Set55HzTailDetection();
InterruptMask = 0
| BK4819_REG_3F_CxCSS_TAIL
| BK4819_REG_3F_SQUELCH_FOUND
| BK4819_REG_3F_SQUELCH_LOST
;
break;
}
2023-08-30 07:47:34 +08:00
if (gRxInfo->SCRAMBLING_TYPE == 0 || !gSetting_ScrambleEnable) {
BK4819_DisableScramble();
} else {
2023-08-30 07:01:30 +08:00
BK4819_EnableScramble(gRxInfo->SCRAMBLING_TYPE - 1);
}
}
} else {
BK4819_SetCTCSSBaudRate(2625);
InterruptMask = 0
| BK4819_REG_3F_CTCSS_FOUND
| BK4819_REG_3F_CTCSS_LOST
| BK4819_REG_3F_SQUELCH_FOUND
| BK4819_REG_3F_SQUELCH_LOST
;
}
2023-08-29 10:24:03 +08:00
if (gEeprom.VOX_SWITCH && !gFmRadioMode && IS_NOT_NOAA_CHANNEL(gCrossTxRadioInfo->CHANNEL_SAVE) && !gCrossTxRadioInfo->IsAM) {
BK4819_EnableVox(gEeprom.VOX1_THRESHOLD, gEeprom.VOX0_THRESHOLD);
InterruptMask |= 0
| BK4819_REG_3F_VOX_FOUND
| BK4819_REG_3F_VOX_LOST
;
} else {
BK4819_DisableVox();
}
2023-08-30 07:01:30 +08:00
if (gRxInfo->IsAM || (!gRxInfo->DTMF_DECODING_ENABLE && !gSetting_KILLED)) {
2023-08-15 00:09:51 +08:00
BK4819_DisableDTMF();
} else {
2023-08-15 00:09:51 +08:00
BK4819_EnableDTMF();
InterruptMask |= BK4819_REG_3F_DTMF_5TONE_FOUND;
}
BK4819_WriteRegister(BK4819_REG_3F, InterruptMask);
2023-08-14 19:28:09 +08:00
FUNCTION_Init();
if (bSwitchToFunction0 == 1) {
2023-08-14 19:28:09 +08:00
FUNCTION_Select(FUNCTION_0);
}
}
2023-08-14 07:39:49 +08:00
void RADIO_ConfigureNOAA(void)
{
uint8_t ChanAB;
2023-08-30 07:19:12 +08:00
gUpdateStatus = true;
2023-08-14 07:39:49 +08:00
if (gEeprom.NOAA_AUTO_SCAN) {
2023-08-21 03:04:40 +08:00
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) {
2023-08-29 10:24:03 +08:00
if (IS_NOT_NOAA_CHANNEL(gEeprom.ScreenChannel[0])) {
if (IS_NOT_NOAA_CHANNEL(gEeprom.ScreenChannel[1])) {
2023-08-14 07:39:49 +08:00
gIsNoaaMode = false;
return;
}
ChanAB = 1;
} else {
ChanAB = 0;
}
2023-08-29 10:24:03 +08:00
if (!gIsNoaaMode) {
gNoaaChannel = gEeprom.VfoInfo[ChanAB].CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
2023-08-14 07:39:49 +08:00
}
gIsNoaaMode = true;
return;
}
2023-08-30 07:01:30 +08:00
if (gRxInfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST) {
2023-08-14 07:39:49 +08:00
gIsNoaaMode = true;
2023-08-30 07:01:30 +08:00
gNoaaChannel = gRxInfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
2023-08-29 10:24:03 +08:00
g_20000356 = 50;
2023-08-30 17:59:18 +08:00
gSystickFlag8 = false;
} else {
gIsNoaaMode = false;
2023-08-14 07:39:49 +08:00
}
2023-08-30 17:59:18 +08:00
} else {
gIsNoaaMode = false;
2023-08-14 07:39:49 +08:00
}
}
2023-08-15 00:30:30 +08:00
void RADIO_PrepareTransmit(void)
{
BK4819_FilterBandwidth_t Bandwidth;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
g_2000036B = 0;
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, false);
Bandwidth = gCrossTxRadioInfo->CHANNEL_BANDWIDTH;
if (Bandwidth != BK4819_FILTER_BW_WIDE) {
Bandwidth = BK4819_FILTER_BW_NARROW;
}
BK4819_SetFilterBandwidth(Bandwidth);
2023-08-30 17:35:41 +08:00
BK4819_SetFrequency(gCrossTxRadioInfo->pReverse->Frequency);
2023-08-15 00:30:30 +08:00
BK4819_PrepareTransmit();
SYSTEM_DelayMs(10);
2023-08-30 17:35:41 +08:00
BK4819_PickRXFilterPathBasedOnFrequency(gCrossTxRadioInfo->pReverse->Frequency);
2023-08-15 00:30:30 +08:00
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, true);
SYSTEM_DelayMs(5);
2023-08-30 17:35:41 +08:00
BK4819_SetupPowerAmplifier(gCrossTxRadioInfo->TXP_CalculatedSetting, gCrossTxRadioInfo->pReverse->Frequency);
2023-08-15 00:30:30 +08:00
SYSTEM_DelayMs(10);
2023-08-30 17:35:41 +08:00
if (gCrossTxRadioInfo->pReverse->CodeType != CODE_TYPE_CONTINUOUS_TONE) {
if ((gCrossTxRadioInfo->pReverse->CodeType != CODE_TYPE_DIGITAL) && (gCrossTxRadioInfo->pReverse->CodeType != CODE_TYPE_REVERSE_DIGITAL)) {
2023-08-15 00:30:30 +08:00
BK4819_ExitSubAu();
return;
}
BK4819_SetCDCSSCodeWord(
DCS_GetGolayCodeWord(
2023-08-30 17:35:41 +08:00
gCrossTxRadioInfo->pReverse->CodeType,
gCrossTxRadioInfo->pReverse->RX_TX_Code
2023-08-15 00:30:30 +08:00
)
);
return;
}
2023-08-30 17:35:41 +08:00
BK4819_SetCTCSSBaudRate(CTCSS_Options[gCrossTxRadioInfo->pReverse->RX_TX_Code]);
2023-08-15 00:30:30 +08:00
}
void RADIO_SomethingElse(uint8_t Arg)
{
if (Arg == 0) {
g_20000371[0] = 0;
g_20000371[1] = 0;
g_20000373 = 0;
} else {
if (Arg == 6) {
g_20000371[0] = 6;
g_20000371[1] = 3;
} else {
uint8_t Channel;
Channel = gEeprom.RX_CHANNEL;
2023-08-21 03:04:40 +08:00
if (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) {
Channel = gEeprom.TX_CHANNEL;
}
g_20000371[Channel] = Arg;
}
g_20000373 = 5;
}
gUpdateDisplay = true;
}
void RADIO_SomethingWithTransmit(void)
{
2023-08-21 03:04:40 +08:00
if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) {
g_2000033A = 360;
gSystickFlag7 = 0;
if (g_2000041F == 0) {
gEeprom.RX_CHANNEL = gEeprom.TX_CHANNEL;
2023-08-30 07:01:30 +08:00
gRxInfo = gEeprom.VfoInfo + gEeprom.TX_CHANNEL;
}
g_2000041F = 1;
}
RADIO_ConfigureCrossTX();
if (g_20000383 == 0 || g_20000383 == 3 || (g_20000383 == 1 && gEeprom.ALARM_MODE == 1)) {
uint8_t Value;
if (!FREQUENCY_Check(gCrossTxRadioInfo)) {
2023-08-29 10:24:03 +08:00
if (gCrossTxRadioInfo->BUSY_CHANNEL_LOCK && gCurrentFunction == FUNCTION_4) {
Value = 1;
} else if (gBatteryDisplayLevel == 0) {
Value = 2;
} else {
// TODO: Fix this goto, a bit painful to disentangle
if (gBatteryDisplayLevel != 6) {
goto LAB_00007c20;
}
Value = 6;
}
} else {
Value = 3;
}
RADIO_SomethingElse(Value);
g_20000383 = 0;
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL);
} else {
LAB_00007c20:
if (g_200003BE == 1) {
if (g_20000438 == 2) {
g_200003BD = 1;
g_200003BC = 0;
g_200003C3 = 6;
}
else {
g_200003BC = 1;
g_200003BD = 0;
}
}
FUNCTION_Select(FUNCTION_TRANSMIT);
if (g_20000383 == 0) {
2023-08-16 05:39:26 +08:00
gTxTimerCountdown = gEeprom.TX_TIMEOUT_TIMER * 120;
} else {
2023-08-16 05:39:26 +08:00
gTxTimerCountdown = 0;
}
2023-08-29 20:26:13 +08:00
gTxTimeoutReached = false;
g_200003FD = 0;
2023-08-27 22:01:47 +08:00
gRTTECountdown = 0;
}
g_200003BE = 0;
}
void RADIO_EnableCxCSS(void)
{
2023-08-30 17:35:41 +08:00
switch (gCrossTxRadioInfo->pReverse->CodeType) {
case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL:
BK4819_EnableCDCSS();
break;
default:
BK4819_EnableCTCSS();
break;
}
SYSTEM_DelayMs(200);
}
void RADIO_Something(void)
{
RADIO_SomethingWithTransmit();
SYSTEM_DelayMs(200);
RADIO_EnableCxCSS();
RADIO_SetupRegisters(true);
}
void RADIO_Whatever(void)
{
g_20000381 = 0;
RADIO_SetupRegisters(true);
}
2023-08-27 22:37:52 +08:00
void RADIO_SendEndOfTransmission(void)
{
if (gEeprom.ROGER == ROGER_MODE_ROGER) {
BK4819_PlayRoger();
} else if (gEeprom.ROGER == ROGER_MODE_MDC) {
BK4819_PlayRogerMDC();
}
if (g_200003BC == 0 && (gCrossTxRadioInfo->DTMF_PTT_ID_TX_MODE == PTT_ID_EOT || gCrossTxRadioInfo->DTMF_PTT_ID_TX_MODE == PTT_ID_BOTH)) {
if (gEeprom.DTMF_SIDE_TONE) {
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
g_2000036B = 1;
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);
g_2000036B = 0;
}
BK4819_ExitDTMF_TX(true);
}