forked from mirror/uv-k5-firmware
Added radio configuration. Needs a few fixes.
This commit is contained in:
parent
acbf814fb4
commit
bce35ec297
1
Makefile
1
Makefile
@ -37,6 +37,7 @@ OBJS += dtmf.o
|
||||
OBJS += fm.o
|
||||
OBJS += frequencies.o
|
||||
OBJS += misc.o
|
||||
OBJS += radio.o
|
||||
OBJS += settings.o
|
||||
OBJS += main.o
|
||||
|
||||
|
@ -26,16 +26,6 @@ const uint32_t LowerLimitFrequencyBandTable[7] = {
|
||||
47000000,
|
||||
};
|
||||
|
||||
const uint32_t UpperLimitFrequencyBandTable[7] = {
|
||||
7600000,
|
||||
13599990,
|
||||
17399990,
|
||||
34999990,
|
||||
39999990,
|
||||
46999990,
|
||||
60000000,
|
||||
};
|
||||
|
||||
const uint32_t MiddleFrequencyBandTable[7] = {
|
||||
6500000,
|
||||
12200000,
|
||||
@ -46,3 +36,86 @@ const uint32_t MiddleFrequencyBandTable[7] = {
|
||||
55000000,
|
||||
};
|
||||
|
||||
const uint32_t UpperLimitFrequencyBandTable[7] = {
|
||||
7600000,
|
||||
13599990,
|
||||
17399990,
|
||||
34999990,
|
||||
39999990,
|
||||
46999990,
|
||||
60000000,
|
||||
};
|
||||
|
||||
const uint32_t NoaaFrequencyTable[10] = {
|
||||
16255000,
|
||||
16240000,
|
||||
16247500,
|
||||
16242500,
|
||||
16245000,
|
||||
16250000,
|
||||
16252500,
|
||||
16152500,
|
||||
16177500,
|
||||
16327500,
|
||||
};
|
||||
|
||||
const uint16_t StepFrequencyTable[6] = {
|
||||
250,
|
||||
500,
|
||||
625,
|
||||
1000,
|
||||
1250,
|
||||
2500
|
||||
};
|
||||
|
||||
FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency)
|
||||
{
|
||||
if ((Frequency - 5000000) < 2600001) {
|
||||
return BAND1_50MHz;
|
||||
}
|
||||
if ((Frequency - 10800000) < 2799991) {
|
||||
return BAND2_108MHz;
|
||||
}
|
||||
if ((Frequency - 13600000) < 3799991) {
|
||||
return BAND3_136MHz;
|
||||
}
|
||||
if ((Frequency - 17400000) < 17599991) {
|
||||
return BAND4_174MHz;
|
||||
}
|
||||
if ((Frequency - 35000000) < 4999991) {
|
||||
return BAND5_350MHz;
|
||||
}
|
||||
if ((Frequency - 40000000) < 6999991) {
|
||||
return BAND6_400MHz;
|
||||
}
|
||||
if ((Frequency - 47000000) < 13000001) {
|
||||
return BAND7_470MHz;
|
||||
}
|
||||
|
||||
// TODO: Double check the assembly
|
||||
return BAND6_400MHz;
|
||||
}
|
||||
|
||||
uint32_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, uint32_t LowerLimit, uint32_t Middle, uint32_t UpperLimit, uint32_t Frequency)
|
||||
{
|
||||
if (Frequency <= LowerLimit) {
|
||||
return TxpLow;
|
||||
}
|
||||
if (UpperLimit <= Frequency) {
|
||||
return TxpHigh;
|
||||
}
|
||||
if (Frequency <= Middle) {
|
||||
return TxpMid + ((TxpMid - TxpLow) * (Frequency - LowerLimit)) / (Middle - LowerLimit);
|
||||
}
|
||||
|
||||
return TxpMid + ((TxpHigh - TxpMid) * (Frequency - Middle)) / (UpperLimit - Middle);
|
||||
}
|
||||
|
||||
uint32_t FREQUENCY_FloorToStep(uint32_t Frequency, uint32_t Step, uint32_t Base)
|
||||
{
|
||||
uint32_t Index;
|
||||
|
||||
Index = (Frequency - Base) / Step;
|
||||
return Base + (Step * Index);
|
||||
}
|
||||
|
||||
|
@ -19,9 +19,27 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum FREQUENCY_Band_t {
|
||||
BAND1_50MHz = 0,
|
||||
BAND2_108MHz,
|
||||
BAND3_136MHz,
|
||||
BAND4_174MHz,
|
||||
BAND5_350MHz,
|
||||
BAND6_400MHz,
|
||||
BAND7_470MHz,
|
||||
};
|
||||
|
||||
typedef enum FREQUENCY_Band_t FREQUENCY_Band_t;
|
||||
|
||||
extern const uint32_t LowerLimitFrequencyBandTable[7];
|
||||
extern const uint32_t UpperLimitFrequencyBandTable[7];
|
||||
extern const uint32_t MiddleFrequencyBandTable[7];
|
||||
extern const uint32_t UpperLimitFrequencyBandTable[7];
|
||||
extern const uint32_t NoaaFrequencyTable[10];
|
||||
extern const uint16_t StepFrequencyTable[6];
|
||||
|
||||
FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency);
|
||||
uint32_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, uint32_t LowerLimit, uint32_t Middle, uint32_t UpperLimit, uint32_t Frequency);
|
||||
uint32_t FREQUENCY_FloorToStep(uint32_t Frequency, uint32_t Step, uint32_t Base);
|
||||
|
||||
#endif
|
||||
|
||||
|
6
main.c
6
main.c
@ -32,6 +32,7 @@
|
||||
#include "driver/systick.h"
|
||||
#include "driver/uart.h"
|
||||
#include "misc.h"
|
||||
#include "radio.h"
|
||||
|
||||
static const char Version[] = "UV-K5 Firmware, v0.01 Open Edition\r\n";
|
||||
|
||||
@ -134,6 +135,11 @@ void Main(void)
|
||||
BOARD_EEPROM_Init();
|
||||
BOARD_EEPROM_LoadMoreSettings();
|
||||
|
||||
RADIO_ConfigureChannel(0, 2);
|
||||
RADIO_ConfigureChannel(1, 2);
|
||||
|
||||
RADIO_ConfigureTX();
|
||||
|
||||
// Below this line is development/test area not conforming to the original firmware
|
||||
|
||||
// Show some signs of life
|
||||
|
2
misc.c
2
misc.c
@ -51,3 +51,5 @@ uint8_t gEEPROM_1F8E;
|
||||
|
||||
uint8_t gMR_ChannelParameters[207];
|
||||
|
||||
uint8_t g_2000036F;
|
||||
|
||||
|
2
misc.h
2
misc.h
@ -55,5 +55,7 @@ extern uint8_t gEEPROM_1F8E;
|
||||
|
||||
extern uint8_t gMR_ChannelParameters[207];
|
||||
|
||||
extern uint8_t g_2000036F;
|
||||
|
||||
#endif
|
||||
|
||||
|
454
radio.c
Executable file
454
radio.c
Executable file
@ -0,0 +1,454 @@
|
||||
/* 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>
|
||||
#include "driver/eeprom.h"
|
||||
#include "frequencies.h"
|
||||
#include "misc.h"
|
||||
#include "radio.h"
|
||||
#include "settings.h"
|
||||
|
||||
RADIO_Info_t *gTxRadioInfo;
|
||||
RADIO_Info_t *gRxRadioInfo;
|
||||
RADIO_Info_t *gCrossTxRadioInfo;
|
||||
|
||||
bool RADIO_CheckValidChannel(uint8_t ChNum, bool bCheckScanList, uint8_t RadioNum)
|
||||
{
|
||||
uint8_t ChParam;
|
||||
uint8_t PriorityCh1;
|
||||
uint8_t PriorityCh2;
|
||||
|
||||
if (ChNum >= 200) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check channel is valid
|
||||
ChParam = gMR_ChannelParameters[ChNum];
|
||||
if ((ChParam & MR_CH_BAND_MASK) > BAND7_470MHz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bCheckScanList) {
|
||||
if (RadioNum == 0) {
|
||||
if ((ChParam & MR_CH_SCANLIST1) == 0) {
|
||||
return false;
|
||||
}
|
||||
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[0];
|
||||
PriorityCh2 = gEeprom.SCANLIST_PRIORITY_CH2[0];
|
||||
} else if (RadioNum == 1) {
|
||||
if ((ChParam & MR_CH_SCANLIST2) == 0) {
|
||||
return false;
|
||||
}
|
||||
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[1];
|
||||
PriorityCh2 = gEeprom.SCANLIST_PRIORITY_CH2[1];
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
if (PriorityCh1 == ChNum) {
|
||||
return false;
|
||||
}
|
||||
if (PriorityCh2 == ChNum) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t RADIO_FindNextChannel(uint8_t ChNum, uint8_t Direction, bool bCheckScanList, uint8_t RadioNum)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < 200; i++) {
|
||||
if (ChNum == 0xFF) {
|
||||
ChNum = 199;
|
||||
} else if (ChNum >= 200) {
|
||||
ChNum = 0;
|
||||
}
|
||||
if (RADIO_CheckValidChannel(ChNum, bCheckScanList, RadioNum)) {
|
||||
return ChNum;
|
||||
}
|
||||
ChNum += Direction;
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void RADIO_InitInfo(RADIO_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 = 5;
|
||||
pInfo->StepFrequency = 2500;
|
||||
pInfo->CHANNEL_SAVE = ChannelSave;
|
||||
pInfo->FrequencyReverse = false;
|
||||
pInfo->OUTPUT_POWER = 2;
|
||||
pInfo->DCS[0].Frequency = Frequency;
|
||||
pInfo->DCS[1].Frequency = Frequency;
|
||||
pInfo->pNext = pInfo;
|
||||
pInfo->FREQUENCY_OF_DEVIATION = 1000000;
|
||||
pInfo->pDCS = &pInfo->DCS[1];
|
||||
RADIO_ConfigureSquelchAndOutputPower(pInfo);
|
||||
}
|
||||
|
||||
void RADIO_ConfigureChannel(uint8_t RadioNum, uint32_t Arg)
|
||||
{
|
||||
RADIO_Info_t *pRadio;
|
||||
uint8_t ChNum;
|
||||
uint8_t Params;
|
||||
uint8_t Band;
|
||||
bool bParticipation2;
|
||||
uint16_t Base;
|
||||
uint8_t Data[8];
|
||||
uint8_t Tmp;
|
||||
|
||||
pRadio = &gEeprom.RadioInfo[RadioNum];
|
||||
|
||||
if (!gSetting_350EN) {
|
||||
if (gEeprom.EEPROM_0E82_0E85[RadioNum] == 204) {
|
||||
gEeprom.EEPROM_0E82_0E85[RadioNum] = 205;
|
||||
}
|
||||
if (gEeprom.EEPROM_0E80_0E83[RadioNum] == 204) {
|
||||
gEeprom.EEPROM_0E80_0E83[RadioNum] = 205;
|
||||
}
|
||||
}
|
||||
|
||||
ChNum = gEeprom.EEPROM_0E80_0E83[RadioNum];
|
||||
if (ChNum < 217) {
|
||||
if (ChNum >= 207) {
|
||||
RADIO_InitInfo(pRadio, gEeprom.EEPROM_0E80_0E83[RadioNum], 2, NoaaFrequencyTable[ChNum - 207]);
|
||||
if (gEeprom.CROSS_BAND_RX_TX == 0) {
|
||||
return;
|
||||
}
|
||||
g_2000036F = 1;
|
||||
gEeprom.CROSS_BAND_RX_TX = 0;
|
||||
return;
|
||||
}
|
||||
if (ChNum < 200) {
|
||||
ChNum = RADIO_FindNextChannel(ChNum, RADIO_CHANNEL_UP, false, RadioNum);
|
||||
if (ChNum == 0xFF) {
|
||||
ChNum = gEeprom.EEPROM_0E82_0E85[RadioNum];
|
||||
gEeprom.EEPROM_0E80_0E83[RadioNum] = gEeprom.EEPROM_0E82_0E85[RadioNum];
|
||||
} else {
|
||||
gEeprom.EEPROM_0E80_0E83[RadioNum] = ChNum;
|
||||
gEeprom.EEPROM_0E81_0E84[RadioNum] = ChNum;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ChNum = 205;
|
||||
}
|
||||
|
||||
Params = gMR_ChannelParameters[ChNum];
|
||||
if (Params == 0xFF) {
|
||||
uint8_t Index;
|
||||
|
||||
if (ChNum < 200) {
|
||||
ChNum = gEeprom.EEPROM_0E82_0E85[RadioNum];
|
||||
gEeprom.EEPROM_0E80_0E83[RadioNum] = gEeprom.EEPROM_0E82_0E85[RadioNum];
|
||||
}
|
||||
Index = ChNum - 200;
|
||||
RADIO_InitInfo(pRadio, ChNum, Index, gLowerLimitFrequencyBandTable[Index]);
|
||||
return;
|
||||
}
|
||||
|
||||
Band = Params & MR_CH_BAND_MASK;
|
||||
if (Band > BAND7_470MHz) {
|
||||
Band = BAND6_400MHz;
|
||||
}
|
||||
|
||||
if (ChNum < 200) {
|
||||
gEeprom.RadioInfo[RadioNum].Band = Band;
|
||||
gEeprom.RadioInfo[RadioNum].SCANLIST1_PARTICIPATION = !!(Params & MR_CH_SCANLIST1);
|
||||
bParticipation2 = !!(Params & MR_CH_SCANLIST2);
|
||||
} else {
|
||||
Band = ChNum - 200;
|
||||
gEeprom.RadioInfo[RadioNum].Band = Band;
|
||||
bParticipation2 = true;
|
||||
gEeprom.RadioInfo[RadioNum].SCANLIST1_PARTICIPATION = true;
|
||||
}
|
||||
gEeprom.RadioInfo[RadioNum].SCANLIST2_PARTICIPATION = bParticipation2;
|
||||
gEeprom.RadioInfo[RadioNum].CHANNEL_SAVE = ChNum;
|
||||
|
||||
if (ChNum < 200) {
|
||||
Base = ChNum << 4;
|
||||
} else {
|
||||
Base = 0x0C80 + (ChNum * 32) + (RadioNum * 16);
|
||||
}
|
||||
|
||||
if (Arg == 2 || ChNum >= 200) {
|
||||
EEPROM_ReadBuffer(Base + 8, Data, 8);
|
||||
|
||||
Tmp = Data[3] & 0x0F;
|
||||
if (Tmp > 2) {
|
||||
Tmp = 0;
|
||||
}
|
||||
gEeprom.RadioInfo[RadioNum].FREQUENCY_DEVIATION_SETTING = Tmp;
|
||||
gEeprom.RadioInfo[RadioNum].AM_CHANNEL_MODE = !!(Data[3] & 0x10);
|
||||
|
||||
Tmp = Data[4];
|
||||
if (Tmp > 6) {
|
||||
Params = 5;
|
||||
}
|
||||
gEeprom.RadioInfo[RadioNum].STEP_SETTING = Tmp;
|
||||
gEeprom.RadioInfo[RadioNum].StepFrequency = StepFrequencyTable[Tmp];
|
||||
|
||||
Tmp = Data[7];
|
||||
if (Tmp > 10) {
|
||||
Tmp = 0;
|
||||
}
|
||||
gEeprom.RadioInfo[RadioNum].SCRAMBLING_TYPE = Tmp;
|
||||
gEeprom.RadioInfo[RadioNum].DCS[0].CodeType = (Data[2] >> 0) & 0x0F;
|
||||
gEeprom.RadioInfo[RadioNum].DCS[1].CodeType = (Data[2] >> 4) & 0x0F;
|
||||
|
||||
Tmp = Data[0];
|
||||
switch (gEeprom.RadioInfo[RadioNum].DCS[0].CodeType) {
|
||||
case 1: // CONTINUOUS TONE
|
||||
if (Tmp >= 50) {
|
||||
Tmp = 0;
|
||||
}
|
||||
break;
|
||||
case 2: // DIGITAL
|
||||
case 3: // REVERSE_DIGITAL
|
||||
if (Tmp >= 104) {
|
||||
Tmp = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gEeprom.RadioInfo[RadioNum].DCS[0].CodeType = 0;
|
||||
break;
|
||||
}
|
||||
gEeprom.RadioInfo[RadioNum].DCS[0].RX_TX_Code = Tmp;
|
||||
|
||||
Tmp = Data[1];
|
||||
switch (gEeprom.RadioInfo[RadioNum].DCS[1].CodeType) {
|
||||
case 1: // CONTINUOUS TONE
|
||||
if (Tmp >= 50) {
|
||||
Tmp = 0;
|
||||
}
|
||||
break;
|
||||
case 2: // DIGITAL
|
||||
case 3: // REVERSE_DIGITAL
|
||||
if (Tmp >= 104) {
|
||||
Tmp = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gEeprom.RadioInfo[RadioNum].DCS[1].CodeType = 0;
|
||||
break;
|
||||
}
|
||||
gEeprom.RadioInfo[RadioNum].DCS[1].RX_TX_Code = Tmp;
|
||||
|
||||
if (Data[4] == 0xFF) {
|
||||
gEeprom.RadioInfo[RadioNum].FrequencyReverse = false;
|
||||
gEeprom.RadioInfo[RadioNum].CHANNEL_BANDWIDTH = 0;
|
||||
gEeprom.RadioInfo[RadioNum].OUTPUT_POWER = 2;
|
||||
gEeprom.RadioInfo[RadioNum].BUSY_CHANNEL_LOCK = false;
|
||||
} else {
|
||||
gEeprom.RadioInfo[RadioNum].FrequencyReverse = !!(Data[4] & 0x01);
|
||||
gEeprom.RadioInfo[RadioNum].CHANNEL_BANDWIDTH = !!(Data[4] & 0x02);
|
||||
gEeprom.RadioInfo[RadioNum].OUTPUT_POWER = (Data[4] >> 2) & 0x03;
|
||||
gEeprom.RadioInfo[RadioNum].BUSY_CHANNEL_LOCK = !!(Data[4] & 0x10);
|
||||
}
|
||||
if (Data[5] == 0xFF) {
|
||||
gEeprom.RadioInfo[RadioNum].DTMF_DECODING_ENABLE = false;
|
||||
gEeprom.RadioInfo[RadioNum].DTMF_PTT_ID_TX_MODE = 0;
|
||||
} else {
|
||||
gEeprom.RadioInfo[RadioNum].DTMF_DECODING_ENABLE = !!(Data[5] & 1);
|
||||
gEeprom.RadioInfo[RadioNum].DTMF_PTT_ID_TX_MODE = (Data[5] >> 0x01) & 0x03;
|
||||
}
|
||||
|
||||
struct {
|
||||
uint32_t Frequency;
|
||||
uint32_t Offset;
|
||||
} Info;
|
||||
|
||||
EEPROM_ReadBuffer(Base, &Info, 8);
|
||||
|
||||
pRadio->DCS[0].Frequency = Info.Frequency;
|
||||
if (Info.Offset >= 100000000) {
|
||||
Info.Offset = 1000000;
|
||||
}
|
||||
gEeprom.RadioInfo[RadioNum].FREQUENCY_OF_DEVIATION = Info.Offset;
|
||||
}
|
||||
|
||||
uint32_t Frequency;
|
||||
|
||||
// TODO: Double check this block, Ghidra has some issues
|
||||
Frequency = gLowerLimitFrequencyBandTable[Band];
|
||||
if (Frequency <= pRadio->DCS[0].Frequency && (pRadio->DCS[0].Frequency <= gUpperLimitFrequencyBandTable[Band])) {
|
||||
Frequency = pRadio->DCS[0].Frequency;
|
||||
if (ChNum >= 200) {
|
||||
Frequency = FREQUENCY_FloorToStep(pRadio->DCS[0].Frequency, gEeprom.RadioInfo[RadioNum].StepFrequency, gLowerLimitFrequencyBandTable[Band]);
|
||||
}
|
||||
}
|
||||
pRadio->DCS[0].Frequency = Frequency;
|
||||
|
||||
if (Frequency - 10800000 < 2799991) {
|
||||
gEeprom.RadioInfo[RadioNum].FREQUENCY_DEVIATION_SETTING = 0;
|
||||
} else if (ChNum >= 200) {
|
||||
Frequency = FREQUENCY_FloorToStep(gEeprom.RadioInfo[RadioNum].FREQUENCY_OF_DEVIATION, gEeprom.RadioInfo[RadioNum].StepFrequency, 0);
|
||||
gEeprom.RadioInfo[RadioNum].FREQUENCY_OF_DEVIATION = Frequency;
|
||||
}
|
||||
RADIO_ApplyDeviation(pRadio);
|
||||
memset(gEeprom.RadioInfo[RadioNum].Name, 0, sizeof(gEeprom.RadioInfo[RadioNum].Name));
|
||||
if (ChNum < 200) {
|
||||
// 16 bytes allocated but only 12 used
|
||||
EEPROM_ReadBuffer(0x0F50 + (ChNum * 0x10), gEeprom.RadioInfo[RadioNum].Name + 0, 8);
|
||||
EEPROM_ReadBuffer(0x0F58 + (ChNum * 0x10), gEeprom.RadioInfo[RadioNum].Name + 8, 2);
|
||||
}
|
||||
|
||||
// TODO: Double check this block, Ghidra has some issues
|
||||
/*
|
||||
if (gEeprom.RadioInfo[RadioNum].FrequencyReverse == true) {
|
||||
gEeprom.RadioInfo[RadioNum].pDCS = &pRadio->DCS[0];
|
||||
gEeprom.RadioInfo[RadioNum].pNext = &gEeprom.RadioInfo[RadioNum];
|
||||
} else {
|
||||
gEeprom.RadioInfo[RadioNum].pNext = pRadio;
|
||||
gEeprom.RadioInfo[RadioNum].pDCS = gEeprom.RadioInfo[RadioNum].;
|
||||
}
|
||||
*/
|
||||
|
||||
if (gSetting_350EN == false) {
|
||||
RADIO_Info_t *pTmp = gEeprom.RadioInfo[RadioNum].pNext;
|
||||
if (pTmp->DCS[0].Frequency - 35000000 < 4999991) {
|
||||
pTmp->DCS[0].Frequency = 41001250;
|
||||
}
|
||||
}
|
||||
|
||||
if (gEeprom.RadioInfo[RadioNum].Band == BAND2_108MHz && gEeprom.RadioInfo[RadioNum].AM_CHANNEL_MODE == true) {
|
||||
gEeprom.RadioInfo[RadioNum]._0x0033 = true;
|
||||
gEeprom.RadioInfo[RadioNum].SCRAMBLING_TYPE = 0;
|
||||
gEeprom.RadioInfo[RadioNum].DTMF_DECODING_ENABLE = false;
|
||||
gEeprom.RadioInfo[RadioNum].DCS[0].CodeType = 0;
|
||||
gEeprom.RadioInfo[RadioNum].DCS[1].CodeType = 0;
|
||||
} else {
|
||||
gEeprom.RadioInfo[RadioNum]._0x0033 = false;
|
||||
}
|
||||
|
||||
RADIO_ConfigureSquelchAndOutputPower(pRadio);
|
||||
}
|
||||
|
||||
void RADIO_ConfigureSquelchAndOutputPower(RADIO_Info_t *pInfo)
|
||||
{
|
||||
uint8_t Txp[3];
|
||||
uint16_t Base;
|
||||
FREQUENCY_Band_t Band;
|
||||
|
||||
Band = FREQUENCY_GetBand(pInfo->pNext->DCS[0].Frequency);
|
||||
if (Band < BAND4_174MHz) {
|
||||
Base = 0x1E60;
|
||||
} else {
|
||||
Base = 0x1E00;
|
||||
}
|
||||
|
||||
if (gEeprom.SQUELCH_LEVEL == 0) {
|
||||
pInfo->SQ0 = 0x00;
|
||||
pInfo->SQ2 = 0x7F;
|
||||
pInfo->SQ4 = 0xFF;
|
||||
pInfo->SQ1 = 0x00;
|
||||
pInfo->SQ3 = 0x7F;
|
||||
pInfo->SQ5 = 0xFF;
|
||||
} else {
|
||||
Base += gEeprom.SQUELCH_LEVEL;
|
||||
EEPROM_ReadBuffer(Base + 0x00, &pInfo->SQ0, 1);
|
||||
EEPROM_ReadBuffer(Base + 0x10, &pInfo->SQ1, 1);
|
||||
EEPROM_ReadBuffer(Base + 0x20, &pInfo->SQ2, 1);
|
||||
EEPROM_ReadBuffer(Base + 0x30, &pInfo->SQ3, 1);
|
||||
EEPROM_ReadBuffer(Base + 0x40, &pInfo->SQ4, 1);
|
||||
EEPROM_ReadBuffer(Base + 0x50, &pInfo->SQ5, 1);
|
||||
if (pInfo->SQ2 >= 0x80) {
|
||||
pInfo->SQ2 = 0x7F;
|
||||
}
|
||||
if (pInfo->SQ3 >= 0x80) {
|
||||
pInfo->SQ3 = 0x7F;
|
||||
}
|
||||
}
|
||||
|
||||
Band = FREQUENCY_GetBand(pInfo->pDCS->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],
|
||||
pInfo->pDCS->Frequency);
|
||||
}
|
||||
|
||||
void RADIO_ApplyDeviation(RADIO_Info_t *pInfo)
|
||||
{
|
||||
uint32_t Frequency;
|
||||
|
||||
Frequency = pInfo->DCS[0].Frequency;
|
||||
switch (pInfo->FREQUENCY_DEVIATION_SETTING) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
Frequency += pInfo->FREQUENCY_OF_DEVIATION;
|
||||
break;
|
||||
case 2:
|
||||
Frequency -= pInfo->FREQUENCY_OF_DEVIATION;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Frequency < 5000000) {
|
||||
Frequency = 5000000;
|
||||
} else if (Frequency > 60000000) {
|
||||
Frequency = 60000000;
|
||||
}
|
||||
|
||||
pInfo->DCS[1].Frequency = Frequency;
|
||||
}
|
||||
|
||||
|
||||
void RADIO_ConfigureTX(void)
|
||||
{
|
||||
if (gEeprom.CROSS_BAND_RX_TX == 2) { // == CHAN B
|
||||
gEeprom.TX_CHANNEL = 1;
|
||||
} else if (gEeprom.CROSS_BAND_RX_TX == 1) { // != CHAN A
|
||||
gEeprom.TX_CHANNEL = 0;
|
||||
} else if (gEeprom.DUAL_WATCH == 2) { // == CHAN B
|
||||
gEeprom.TX_CHANNEL = 0;
|
||||
} else if (gEeprom.DUAL_WATCH == 1) { // == CHAN A
|
||||
gEeprom.TX_CHANNEL = 1;
|
||||
}
|
||||
|
||||
gTxRadioInfo = &gEeprom.RadioInfo[gEeprom.TX_CHANNEL];
|
||||
gEeprom.RX_CHANNEL = gEeprom.TX_CHANNEL;
|
||||
if (gEeprom.CROSS_BAND_RX_TX != 0) { // != OFF
|
||||
if (gEeprom.TX_CHANNEL == 0) {
|
||||
gEeprom.RX_CHANNEL = 1;
|
||||
} else {
|
||||
gEeprom.RX_CHANNEL = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gRxRadioInfo = &gEeprom.RadioInfo[gEeprom.RX_CHANNEL];
|
||||
RADIO_ConfigureCrossTX();
|
||||
}
|
||||
|
||||
void RADIO_ConfigureCrossTX(void)
|
||||
{
|
||||
gCrossTxRadioInfo = gRxRadioInfo;
|
||||
if (gEeprom.CROSS_BAND_RX_TX != 0) { // != OFF
|
||||
gCrossTxRadioInfo = &gEeprom.RadioInfo[gEeprom.TX_CHANNEL];
|
||||
}
|
||||
}
|
||||
|
86
radio.h
Executable file
86
radio.h
Executable file
@ -0,0 +1,86 @@
|
||||
/* Copyright 2023 Dual Tachyon
|
||||
* https://github.com/DualTachyon
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef RADIO_H
|
||||
#define RADIO_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum {
|
||||
MR_CH_SCANLIST1 = (1U << 7),
|
||||
MR_CH_SCANLIST2 = (1U << 6),
|
||||
MR_CH_BAND_MASK = 0x0FU,
|
||||
};
|
||||
|
||||
enum {
|
||||
RADIO_CHANNEL_UP = 0x01,
|
||||
RADIO_CHANNEL_DOWN = 0xFF,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t Frequency;
|
||||
uint8_t CodeType;
|
||||
uint8_t RX_TX_Code;
|
||||
uint8_t Padding[2];
|
||||
} DCS_Info_t;
|
||||
|
||||
typedef struct RADIO_Info_t {
|
||||
DCS_Info_t DCS[2];
|
||||
struct RADIO_Info_t *pNext;
|
||||
DCS_Info_t *pDCS;
|
||||
uint32_t FREQUENCY_OF_DEVIATION;
|
||||
uint16_t StepFrequency;
|
||||
uint8_t CHANNEL_SAVE;
|
||||
uint8_t FREQUENCY_DEVIATION_SETTING;
|
||||
uint8_t SQ0;
|
||||
uint8_t SQ2;
|
||||
uint8_t SQ4;
|
||||
uint8_t SQ1;
|
||||
uint8_t SQ3;
|
||||
uint8_t SQ5;
|
||||
uint8_t STEP_SETTING;
|
||||
uint8_t OUTPUT_POWER;
|
||||
uint8_t TXP_CalculatedSetting;
|
||||
bool FrequencyReverse;
|
||||
uint8_t SCRAMBLING_TYPE;
|
||||
uint8_t CHANNEL_BANDWIDTH;
|
||||
uint8_t SCANLIST1_PARTICIPATION;
|
||||
uint8_t SCANLIST2_PARTICIPATION;
|
||||
uint8_t Band;
|
||||
uint8_t DTMF_DECODING_ENABLE;
|
||||
uint8_t DTMF_PTT_ID_TX_MODE;
|
||||
uint8_t BUSY_CHANNEL_LOCK;
|
||||
uint8_t AM_CHANNEL_MODE;
|
||||
bool _0x0033;
|
||||
char Name[16];
|
||||
} RADIO_Info_t;
|
||||
|
||||
extern RADIO_Info_t *gTxRadioInfo;
|
||||
extern RADIO_Info_t *gRxRadioInfo;
|
||||
extern RADIO_Info_t *gCrossTxRadioInfo;
|
||||
|
||||
bool RADIO_CheckValidChannel(uint8_t ChNum, bool bCheckScanList, uint8_t RadioNum);
|
||||
uint8_t RADIO_FindNextChannel(uint8_t ChNum, uint8_t Direction, bool bCheckScanList, uint8_t RadioNum);
|
||||
void RADIO_InitInfo(RADIO_Info_t *pInfo, uint8_t ChannelSave, uint8_t ChIndex, uint32_t Frequency);
|
||||
void RADIO_ConfigureChannel(uint8_t RadioNum, uint32_t Arg);
|
||||
void RADIO_ConfigureSquelchAndOutputPower(RADIO_Info_t *pInfo);
|
||||
void RADIO_ApplyDeviation(RADIO_Info_t *pInfo);
|
||||
void RADIO_ConfigureTX(void);
|
||||
void RADIO_ConfigureCrossTX(void);
|
||||
|
||||
#endif
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "radio.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t EEPROM_0E80_0E83[2];
|
||||
@ -26,7 +27,7 @@ typedef struct {
|
||||
uint8_t EEPROM_0E81_0E84[2];
|
||||
uint8_t EEPROM_0E86;
|
||||
uint8_t EEPROM_0E87;
|
||||
uint8_t copy_EEPROM_0EAB;
|
||||
uint8_t RX_CHANNEL;
|
||||
uint8_t TX_CHANNEL;
|
||||
uint8_t field7_0xa;
|
||||
uint8_t field8_0xb;
|
||||
@ -101,7 +102,7 @@ typedef struct {
|
||||
uint8_t field77_0x95;
|
||||
uint8_t field78_0x96;
|
||||
uint8_t field79_0x97;
|
||||
//struct channel_settings_t RadioInfo[2];
|
||||
RADIO_Info_t RadioInfo[2];
|
||||
} EEPROM_Config_t;
|
||||
|
||||
extern EEPROM_Config_t gEeprom;
|
||||
|
Loading…
Reference in New Issue
Block a user