Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0d052b68b | ||
|
|
9a3249a667 | ||
|
|
ffdc0e03b5 | ||
|
|
d8d4384b20 | ||
|
|
0ce7d7bdc3 | ||
|
|
fb30ec8c86 | ||
|
|
67307463e2 | ||
|
|
fdd7fc063e | ||
|
|
592810b7d7 | ||
|
|
6e5e7e7aef | ||
|
|
cd0dc71de6 |
@@ -21,7 +21,7 @@
|
||||
* battery voltage callibration from menu
|
||||
* better battery percentage calculation, selectable for 1600mAh or 2200mAh
|
||||
* more configurable button functions
|
||||
* longpress MENU as another cofigurable button
|
||||
* longpress MENU as another configurable button
|
||||
* better DCS/CTCSS scanning in the menu (`* SCAN` while in RX DCS/CTCSS menu item)
|
||||
* Piotr022 s-meter style
|
||||
* restore initial freq/channel when scanning stopped with EXIT, remember last found transmission with MENU button
|
||||
|
||||
51
app/action.c
51
app/action.c
@@ -63,24 +63,22 @@ void ACTION_Power(void)
|
||||
gTxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW;
|
||||
|
||||
gRequestSaveChannel = 1;
|
||||
//gRequestSaveChannel = 2; // auto save the channel
|
||||
|
||||
#ifdef ENABLE_VOICE
|
||||
gAnotherVoiceID = VOICE_ID_POWER;
|
||||
#endif
|
||||
#ifdef ENABLE_VOICE
|
||||
gAnotherVoiceID = VOICE_ID_POWER;
|
||||
#endif
|
||||
|
||||
gRequestDisplayScreen = gScreenToDisplay;
|
||||
}
|
||||
|
||||
void ACTION_Monitor(void)
|
||||
{
|
||||
if (gCurrentFunction != FUNCTION_MONITOR)
|
||||
{ // enable the monitor
|
||||
if (gCurrentFunction != FUNCTION_MONITOR) { // enable the monitor
|
||||
RADIO_SelectVfos();
|
||||
#ifdef ENABLE_NOAA
|
||||
if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST && gIsNoaaMode)
|
||||
gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
|
||||
#endif
|
||||
#ifdef ENABLE_NOAA
|
||||
if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST && gIsNoaaMode)
|
||||
gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
|
||||
#endif
|
||||
RADIO_SetupRegisters(true);
|
||||
APP_StartListening(FUNCTION_MONITOR, false);
|
||||
return;
|
||||
@@ -88,32 +86,29 @@ void ACTION_Monitor(void)
|
||||
|
||||
gMonitor = false;
|
||||
|
||||
if (gScanStateDir != SCAN_OFF)
|
||||
{
|
||||
if (gScanStateDir != SCAN_OFF) {
|
||||
gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms;
|
||||
gScheduleScanListen = false;
|
||||
gScanPauseMode = true;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NOAA
|
||||
if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode)
|
||||
{
|
||||
gNOAA_Countdown_10ms = NOAA_countdown_10ms;
|
||||
gScheduleNOAA = false;
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_NOAA
|
||||
if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode) {
|
||||
gNOAA_Countdown_10ms = NOAA_countdown_10ms;
|
||||
gScheduleNOAA = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
RADIO_SetupRegisters(true);
|
||||
|
||||
#ifdef ENABLE_FMRADIO
|
||||
if (gFmRadioMode)
|
||||
{
|
||||
FM_Start();
|
||||
gRequestDisplayScreen = DISPLAY_FM;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
gRequestDisplayScreen = gScreenToDisplay;
|
||||
#ifdef ENABLE_FMRADIO
|
||||
if (gFmRadioMode) {
|
||||
FM_Start();
|
||||
gRequestDisplayScreen = DISPLAY_FM;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
gRequestDisplayScreen = gScreenToDisplay;
|
||||
}
|
||||
|
||||
void ACTION_Scan(bool bRestart)
|
||||
|
||||
53
app/app.c
53
app/app.c
@@ -173,14 +173,11 @@ static void HandleIncoming(void)
|
||||
{
|
||||
bool bFlag;
|
||||
|
||||
if (!g_SquelchLost)
|
||||
{ // squelch is closed
|
||||
|
||||
if (!g_SquelchLost) { // squelch is closed
|
||||
if (gDTMF_RX_index > 0)
|
||||
DTMF_clear_RX();
|
||||
|
||||
if (gCurrentFunction != FUNCTION_FOREGROUND)
|
||||
{
|
||||
if (gCurrentFunction != FUNCTION_FOREGROUND) {
|
||||
FUNCTION_Select(FUNCTION_FOREGROUND);
|
||||
gUpdateDisplay = true;
|
||||
}
|
||||
@@ -189,39 +186,31 @@ static void HandleIncoming(void)
|
||||
|
||||
bFlag = (gScanStateDir == SCAN_OFF && gCurrentCodeType == CODE_TYPE_OFF);
|
||||
|
||||
#ifdef ENABLE_NOAA
|
||||
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gNOAACountdown_10ms > 0)
|
||||
{
|
||||
gNOAACountdown_10ms = 0;
|
||||
bFlag = true;
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_NOAA
|
||||
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gNOAACountdown_10ms > 0) {
|
||||
gNOAACountdown_10ms = 0;
|
||||
bFlag = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g_CTCSS_Lost && gCurrentCodeType == CODE_TYPE_CONTINUOUS_TONE)
|
||||
{
|
||||
if (g_CTCSS_Lost && gCurrentCodeType == CODE_TYPE_CONTINUOUS_TONE) {
|
||||
bFlag = true;
|
||||
gFoundCTCSS = false;
|
||||
}
|
||||
|
||||
if (g_CDCSS_Lost && gCDCSSCodeType == CDCSS_POSITIVE_CODE && (gCurrentCodeType == CODE_TYPE_DIGITAL || gCurrentCodeType == CODE_TYPE_REVERSE_DIGITAL))
|
||||
{
|
||||
if (g_CDCSS_Lost && gCDCSSCodeType == CDCSS_POSITIVE_CODE && (gCurrentCodeType == CODE_TYPE_DIGITAL || gCurrentCodeType == CODE_TYPE_REVERSE_DIGITAL)) {
|
||||
gFoundCDCSS = false;
|
||||
}
|
||||
else
|
||||
if (!bFlag)
|
||||
else if (!bFlag)
|
||||
return;
|
||||
|
||||
if (gScanStateDir == SCAN_OFF)
|
||||
{ // not scanning
|
||||
if (gRxVfo->DTMF_DECODING_ENABLE || gSetting_KILLED)
|
||||
{ // DTMF DCD is enabled
|
||||
if (gScanStateDir == SCAN_OFF) { // not scanning
|
||||
if (gRxVfo->DTMF_DECODING_ENABLE || gSetting_KILLED) { // DTMF DCD is enabled
|
||||
|
||||
DTMF_HandleRequest();
|
||||
|
||||
if (gDTMF_CallState == DTMF_CALL_STATE_NONE)
|
||||
{
|
||||
if (gRxReceptionMode == RX_MODE_DETECTED)
|
||||
{
|
||||
if (gDTMF_CallState == DTMF_CALL_STATE_NONE) {
|
||||
if (gRxReceptionMode == RX_MODE_DETECTED) {
|
||||
gDualWatchCountdown_10ms = dual_watch_count_after_1_10ms;
|
||||
gScheduleDualWatch = false;
|
||||
|
||||
@@ -766,6 +755,9 @@ void APP_EndTransmission(void)
|
||||
// send the CTCSS/DCS tail tone - allows the receivers to mute the usual FM squelch tail/crash
|
||||
RADIO_EnableCxCSS();
|
||||
RADIO_SetupRegisters(false);
|
||||
|
||||
if (gMonitor)
|
||||
gFlagReconfigureVfos = true; //turn the monitor back on
|
||||
}
|
||||
|
||||
#ifdef ENABLE_VOX
|
||||
@@ -1726,6 +1718,9 @@ static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
||||
|
||||
// cancel user input
|
||||
cancelUserInputModes();
|
||||
|
||||
if (gMonitor)
|
||||
ACTION_Monitor(); //turn off the monitor
|
||||
}
|
||||
|
||||
if (gScreenToDisplay == DISPLAY_MENU) // 1of11
|
||||
@@ -2049,9 +2044,9 @@ Skip:
|
||||
{
|
||||
RADIO_SelectVfos();
|
||||
|
||||
#ifdef ENABLE_NOAA
|
||||
RADIO_ConfigureNOAA();
|
||||
#endif
|
||||
#ifdef ENABLE_NOAA
|
||||
RADIO_ConfigureNOAA();
|
||||
#endif
|
||||
|
||||
RADIO_SetupRegisters(true);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "app/spectrum.h"
|
||||
#include "driver/backlight.h"
|
||||
#include "audio.h"
|
||||
#include "ui/helper.h"
|
||||
|
||||
struct FrequencyBandInfo {
|
||||
uint32_t lower;
|
||||
@@ -125,21 +126,13 @@ static void SetRegMenuValue(uint8_t st, bool add) {
|
||||
// GUI functions
|
||||
|
||||
static void PutPixel(uint8_t x, uint8_t y, bool fill) {
|
||||
if (fill) {
|
||||
gFrameBuffer[y >> 3][x] |= 1 << (y & 7);
|
||||
} else {
|
||||
gFrameBuffer[y >> 3][x] &= ~(1 << (y & 7));
|
||||
}
|
||||
UI_DrawPixelBuffer(gFrameBuffer, x, y, fill);
|
||||
}
|
||||
static void PutPixelStatus(uint8_t x, uint8_t y, bool fill) {
|
||||
if (fill) {
|
||||
gStatusLine[x] |= 1 << y;
|
||||
} else {
|
||||
gStatusLine[x] &= ~(1 << y);
|
||||
}
|
||||
UI_DrawPixelBuffer(&gStatusLine, x, y, fill);
|
||||
}
|
||||
|
||||
static void DrawHLine(int sy, int ey, int nx, bool fill) {
|
||||
static void DrawVLine(int sy, int ey, int nx, bool fill) {
|
||||
for (int i = sy; i <= ey; i++) {
|
||||
if (i < 56 && nx < 128) {
|
||||
PutPixel(nx, i, fill);
|
||||
@@ -606,7 +599,7 @@ static void DrawSpectrum() {
|
||||
for (uint8_t x = 0; x < 128; ++x) {
|
||||
uint16_t rssi = rssiHistory[x >> settings.stepsCount];
|
||||
if (rssi != RSSI_MAX_VALUE) {
|
||||
DrawHLine(Rssi2Y(rssi), DrawingEndY, x, true);
|
||||
DrawVLine(Rssi2Y(rssi), DrawingEndY, x, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -620,36 +613,28 @@ static void DrawStatus() {
|
||||
#endif
|
||||
GUI_DisplaySmallest(String, 0, 1, true, true);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[i], &gBatteryCurrent);
|
||||
}
|
||||
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryCheckCounter++ % 4], &gBatteryCurrent);
|
||||
|
||||
uint16_t Voltage;
|
||||
uint8_t v = 0;
|
||||
|
||||
Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] +
|
||||
uint16_t voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] +
|
||||
gBatteryVoltages[3]) /
|
||||
4;
|
||||
4 * 760 / gBatteryCalibration[3];
|
||||
|
||||
for(uint8_t i = 5; i > 0; i--) {
|
||||
if(Voltage > gBatteryCalibration[i - 1]) {
|
||||
v = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
unsigned perc = BATTERY_VoltsToPercent(voltage);
|
||||
|
||||
gStatusLine[127] = 0b01111110;
|
||||
for (int i = 126; i >= 116; i--) {
|
||||
gStatusLine[i] = 0b01000010;
|
||||
// sprintf(String, "%d %d", voltage, perc);
|
||||
// GUI_DisplaySmallest(String, 48, 1, true, true);
|
||||
|
||||
gStatusLine[116] = 0b00011100;
|
||||
gStatusLine[117] = 0b00111110;
|
||||
for (int i = 118; i <= 126; i++) {
|
||||
gStatusLine[i] = 0b00100010;
|
||||
}
|
||||
v <<= 1;
|
||||
for (int i = 125; i >= 116; i--) {
|
||||
if (126 - i <= v) {
|
||||
gStatusLine[i + 2] = 0b01111110;
|
||||
|
||||
for (unsigned i = 127; i >= 118; i--) {
|
||||
if (127 - i <= (perc+5)*9/100) {
|
||||
gStatusLine[i] = 0b00111110;
|
||||
}
|
||||
}
|
||||
gStatusLine[117] = 0b01111110;
|
||||
gStatusLine[116] = 0b00011000;
|
||||
}
|
||||
|
||||
static void DrawF(uint32_t f) {
|
||||
@@ -712,19 +697,13 @@ static void DrawTicks() {
|
||||
|
||||
// center
|
||||
if (IsCenterMode()) {
|
||||
gFrameBuffer[5][62] = 0x80;
|
||||
gFrameBuffer[5][63] = 0x80;
|
||||
memset(gFrameBuffer[5] + 62, 0x80, 5);
|
||||
gFrameBuffer[5][64] = 0xff;
|
||||
gFrameBuffer[5][65] = 0x80;
|
||||
gFrameBuffer[5][66] = 0x80;
|
||||
} else {
|
||||
memset(gFrameBuffer[5] + 1, 0x80, 3);
|
||||
memset(gFrameBuffer[5] + 124, 0x80, 3);
|
||||
|
||||
gFrameBuffer[5][0] = 0xff;
|
||||
gFrameBuffer[5][1] = 0x80;
|
||||
gFrameBuffer[5][2] = 0x80;
|
||||
gFrameBuffer[5][3] = 0x80;
|
||||
gFrameBuffer[5][124] = 0x80;
|
||||
gFrameBuffer[5][125] = 0x80;
|
||||
gFrameBuffer[5][126] = 0x80;
|
||||
gFrameBuffer[5][127] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
7
board.c
7
board.c
@@ -727,6 +727,13 @@ void BOARD_EEPROM_Init(void)
|
||||
|
||||
// 0D60..0E27
|
||||
EEPROM_ReadBuffer(0x0D60, gMR_ChannelAttributes, sizeof(gMR_ChannelAttributes));
|
||||
for(uint16_t i = 0; i < sizeof(gMR_ChannelAttributes); i++) {
|
||||
ChannelAttributes_t *att = &gMR_ChannelAttributes[i];
|
||||
if(att->__val == 0xff){
|
||||
att->__val = 0;
|
||||
att->band = 0xf;
|
||||
}
|
||||
}
|
||||
|
||||
// 0F30..0F3F
|
||||
EEPROM_ReadBuffer(0x0F30, gCustomAesKey, sizeof(gCustomAesKey));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@echo off
|
||||
docker build -t uvk5 .
|
||||
docker run -v %CD%\compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make clean && make && cp firmware* compiled-firmware/"
|
||||
docker run --rm -v %CD%\compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make clean && make && cp firmware* compiled-firmware/"
|
||||
pause
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
docker build -t uvk5 .
|
||||
docker run -v ${PWD}/compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make && cp firmware* compiled-firmware/"
|
||||
docker run --rm -v ${PWD}/compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make && cp firmware* compiled-firmware/"
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
|
||||
static const uint16_t FSK_RogerTable[7] = {0xF1A2, 0x7446, 0x61A4, 0x6544, 0x4E8A, 0xE044, 0xEA84};
|
||||
|
||||
static const uint8_t DTMF_TONE1_GAIN = 65;
|
||||
static const uint8_t DTMF_TONE2_GAIN = 93;
|
||||
|
||||
static uint16_t gBK4819_GpioOutState;
|
||||
|
||||
bool gRxIdleMode;
|
||||
@@ -984,15 +987,15 @@ void BK4819_EnableDTMF(void)
|
||||
|
||||
void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch)
|
||||
{
|
||||
uint16_t ToneConfig;
|
||||
uint16_t ToneConfig = BK4819_REG_70_ENABLE_TONE1;
|
||||
|
||||
BK4819_EnterTxMute();
|
||||
BK4819_SetAF(BK4819_AF_BEEP);
|
||||
|
||||
if (bTuningGainSwitch == 0)
|
||||
ToneConfig = BK4819_REG_70_ENABLE_TONE1 | (96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN);
|
||||
ToneConfig |= 96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN;
|
||||
else
|
||||
ToneConfig = BK4819_REG_70_ENABLE_TONE1 | (28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN);
|
||||
ToneConfig |= 28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN;
|
||||
BK4819_WriteRegister(BK4819_REG_70, ToneConfig);
|
||||
|
||||
BK4819_WriteRegister(BK4819_REG_30, 0);
|
||||
@@ -1001,6 +1004,7 @@ void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch)
|
||||
BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency));
|
||||
}
|
||||
|
||||
// level 0 ~ 127
|
||||
void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay, const unsigned int level, const bool play_speaker)
|
||||
{
|
||||
BK4819_EnterTxMute();
|
||||
@@ -1013,9 +1017,7 @@ void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay,
|
||||
else
|
||||
BK4819_SetAF(BK4819_AF_MUTE);
|
||||
|
||||
// level 0 ~ 127
|
||||
// BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
||||
// BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
||||
|
||||
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | ((level & 0x7f) << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
||||
|
||||
BK4819_EnableTXLink();
|
||||
@@ -1209,9 +1211,9 @@ void BK4819_EnterDTMF_TX(bool bLocalLoopback)
|
||||
|
||||
BK4819_WriteRegister(BK4819_REG_70,
|
||||
BK4819_REG_70_MASK_ENABLE_TONE1 |
|
||||
(83u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) |
|
||||
(DTMF_TONE1_GAIN << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) |
|
||||
BK4819_REG_70_MASK_ENABLE_TONE2 |
|
||||
(83u << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN));
|
||||
(DTMF_TONE2_GAIN << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN));
|
||||
|
||||
BK4819_EnableTXLink();
|
||||
}
|
||||
@@ -1250,16 +1252,16 @@ void BK4819_PlayDTMF(char Code)
|
||||
switch (Code)
|
||||
{
|
||||
case '0': tone1 = 941; tone2 = 1336; break;
|
||||
case '1': tone1 = 679; tone2 = 1209; break;
|
||||
case '1': tone1 = 697; tone2 = 1209; break;
|
||||
case '2': tone1 = 697; tone2 = 1336; break;
|
||||
case '3': tone1 = 679; tone2 = 1477; break;
|
||||
case '3': tone1 = 697; tone2 = 1477; break;
|
||||
case '4': tone1 = 770; tone2 = 1209; break;
|
||||
case '5': tone1 = 770; tone2 = 1336; break;
|
||||
case '6': tone1 = 770; tone2 = 1477; break;
|
||||
case '7': tone1 = 852; tone2 = 1209; break;
|
||||
case '8': tone1 = 852; tone2 = 1336; break;
|
||||
case '9': tone1 = 852; tone2 = 1477; break;
|
||||
case 'A': tone1 = 679; tone2 = 1633; break;
|
||||
case 'A': tone1 = 697; tone2 = 1633; break;
|
||||
case 'B': tone1 = 770; tone2 = 1633; break;
|
||||
case 'C': tone1 = 852; tone2 = 1633; break;
|
||||
case 'D': tone1 = 941; tone2 = 1633; break;
|
||||
@@ -1320,8 +1322,7 @@ void BK4819_TransmitTone(bool bLocalLoopback, uint32_t Frequency)
|
||||
//
|
||||
// set the tone amplitude
|
||||
//
|
||||
// BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_MASK_ENABLE_TONE1 | (96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
||||
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_MASK_ENABLE_TONE1 | (28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
||||
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_MASK_ENABLE_TONE1 | (66u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
||||
|
||||
BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency));
|
||||
|
||||
@@ -1700,8 +1701,7 @@ void BK4819_PlayRoger(void)
|
||||
BK4819_EnterTxMute();
|
||||
BK4819_SetAF(BK4819_AF_MUTE);
|
||||
|
||||
// BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (96u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
||||
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (28u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
||||
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (66u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
|
||||
|
||||
BK4819_EnableTXLink();
|
||||
SYSTEM_DelayMs(50);
|
||||
@@ -1782,7 +1782,12 @@ void BK4819_PlayDTMFEx(bool bLocalLoopback, char Code)
|
||||
BK4819_EnterTxMute();
|
||||
|
||||
BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE);
|
||||
BK4819_WriteRegister(BK4819_REG_70, 0xD3D3);
|
||||
|
||||
BK4819_WriteRegister(BK4819_REG_70,
|
||||
BK4819_REG_70_MASK_ENABLE_TONE1 |
|
||||
(DTMF_TONE1_GAIN << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN) |
|
||||
BK4819_REG_70_MASK_ENABLE_TONE2 |
|
||||
(DTMF_TONE2_GAIN << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN));
|
||||
|
||||
BK4819_EnableTXLink();
|
||||
|
||||
|
||||
2
misc.c
2
misc.c
@@ -111,7 +111,7 @@ uint16_t gEEPROM_RSSI_CALIB[7][4];
|
||||
uint16_t gEEPROM_1F8A;
|
||||
uint16_t gEEPROM_1F8C;
|
||||
|
||||
uint8_t gMR_ChannelAttributes[FREQ_CHANNEL_LAST + 1];
|
||||
ChannelAttributes_t gMR_ChannelAttributes[FREQ_CHANNEL_LAST + 1];
|
||||
|
||||
volatile uint16_t gBatterySaveCountdown_10ms = battery_save_count_10ms;
|
||||
|
||||
|
||||
13
misc.h
13
misc.h
@@ -176,7 +176,18 @@ extern uint16_t gEEPROM_RSSI_CALIB[7][4];
|
||||
extern uint16_t gEEPROM_1F8A;
|
||||
extern uint16_t gEEPROM_1F8C;
|
||||
|
||||
extern uint8_t gMR_ChannelAttributes[207];
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t
|
||||
band : 4,
|
||||
compander : 2,
|
||||
scanlist2 : 1,
|
||||
scanlist1 : 1;
|
||||
};
|
||||
uint8_t __val;
|
||||
} ChannelAttributes_t;
|
||||
|
||||
extern ChannelAttributes_t gMR_ChannelAttributes[207];
|
||||
|
||||
extern volatile uint16_t gBatterySaveCountdown_10ms;
|
||||
|
||||
|
||||
330
radio.c
330
radio.c
@@ -56,24 +56,22 @@ const char gModulationStr[][4] =
|
||||
bool RADIO_CheckValidChannel(uint16_t Channel, bool bCheckScanList, uint8_t VFO)
|
||||
{ // return true if the channel appears valid
|
||||
|
||||
uint8_t Attributes;
|
||||
ChannelAttributes_t att;
|
||||
uint8_t PriorityCh1;
|
||||
uint8_t PriorityCh2;
|
||||
|
||||
if (!IS_MR_CHANNEL(Channel))
|
||||
return false;
|
||||
|
||||
Attributes = gMR_ChannelAttributes[Channel];
|
||||
att = gMR_ChannelAttributes[Channel];
|
||||
|
||||
if ((Attributes & MR_CH_BAND_MASK) > BAND7_470MHz)
|
||||
if (att.band > BAND7_470MHz)
|
||||
return false;
|
||||
|
||||
if (bCheckScanList)
|
||||
{
|
||||
switch (VFO)
|
||||
{
|
||||
if (bCheckScanList) {
|
||||
switch (VFO) {
|
||||
case 0:
|
||||
if ((Attributes & MR_CH_SCANLIST1) == 0)
|
||||
if (!att.scanlist1)
|
||||
return false;
|
||||
|
||||
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[0];
|
||||
@@ -81,7 +79,7 @@ bool RADIO_CheckValidChannel(uint16_t Channel, bool bCheckScanList, uint8_t VFO)
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if ((Attributes & MR_CH_SCANLIST2) == 0)
|
||||
if (!att.scanlist2)
|
||||
return false;
|
||||
|
||||
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[1];
|
||||
@@ -128,8 +126,8 @@ void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t
|
||||
memset(pInfo, 0, sizeof(*pInfo));
|
||||
|
||||
pInfo->Band = FREQUENCY_GetBand(Frequency);
|
||||
pInfo->SCANLIST1_PARTICIPATION = true;
|
||||
pInfo->SCANLIST2_PARTICIPATION = true;
|
||||
pInfo->SCANLIST1_PARTICIPATION = false;
|
||||
pInfo->SCANLIST2_PARTICIPATION = false;
|
||||
pInfo->STEP_SETTING = STEP_12_5kHz;
|
||||
pInfo->StepFrequency = gStepFrequencyTable[pInfo->STEP_SETTING];
|
||||
pInfo->CHANNEL_SAVE = ChannelSave;
|
||||
@@ -143,37 +141,31 @@ void RADIO_InitInfo(VFO_Info_t *pInfo, const uint8_t ChannelSave, const uint32_t
|
||||
|
||||
if (ChannelSave == (FREQ_CHANNEL_FIRST + BAND2_108MHz))
|
||||
pInfo->Modulation = MODULATION_AM;
|
||||
else
|
||||
pInfo->Modulation = MODULATION_FM;
|
||||
|
||||
RADIO_ConfigureSquelchAndOutputPower(pInfo);
|
||||
}
|
||||
|
||||
void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure)
|
||||
{
|
||||
uint8_t Channel;
|
||||
uint8_t Attributes;
|
||||
uint8_t Band;
|
||||
bool bParticipation2;
|
||||
uint16_t Base;
|
||||
uint32_t Frequency;
|
||||
VFO_Info_t *pRadio = &gEeprom.VfoInfo[VFO];
|
||||
VFO_Info_t *pVfo = &gEeprom.VfoInfo[VFO];
|
||||
|
||||
if (!gSetting_350EN)
|
||||
{
|
||||
if (gEeprom.FreqChannel[VFO] == (FREQ_CHANNEL_LAST - 2))
|
||||
gEeprom.FreqChannel[VFO] = FREQ_CHANNEL_LAST - 1;
|
||||
if (!gSetting_350EN) {
|
||||
if (gEeprom.FreqChannel[VFO] == FREQ_CHANNEL_FIRST + BAND5_350MHz)
|
||||
gEeprom.FreqChannel[VFO] = FREQ_CHANNEL_FIRST + BAND6_400MHz;
|
||||
|
||||
if (gEeprom.ScreenChannel[VFO] == (FREQ_CHANNEL_LAST - 2))
|
||||
gEeprom.ScreenChannel[VFO] = FREQ_CHANNEL_LAST - 1;
|
||||
if (gEeprom.ScreenChannel[VFO] == FREQ_CHANNEL_FIRST + BAND5_350MHz)
|
||||
gEeprom.ScreenChannel[VFO] = FREQ_CHANNEL_FIRST + BAND6_400MHz;
|
||||
}
|
||||
|
||||
Channel = gEeprom.ScreenChannel[VFO];
|
||||
uint8_t channel = gEeprom.ScreenChannel[VFO];
|
||||
|
||||
if (IS_VALID_CHANNEL(Channel))
|
||||
{
|
||||
if (IS_VALID_CHANNEL(channel)) {
|
||||
#ifdef ENABLE_NOAA
|
||||
if (Channel >= NOAA_CHANNEL_FIRST)
|
||||
if (channel >= NOAA_CHANNEL_FIRST)
|
||||
{
|
||||
RADIO_InitInfo(pRadio, gEeprom.ScreenChannel[VFO], NoaaFrequencyTable[Channel - NOAA_CHANNEL_FIRST]);
|
||||
RADIO_InitInfo(pVfo, gEeprom.ScreenChannel[VFO], NoaaFrequencyTable[channel - NOAA_CHANNEL_FIRST]);
|
||||
|
||||
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF)
|
||||
return;
|
||||
@@ -185,248 +177,240 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IS_MR_CHANNEL(Channel))
|
||||
{
|
||||
Channel = RADIO_FindNextChannel(Channel, RADIO_CHANNEL_UP, false, VFO);
|
||||
if (Channel == 0xFF)
|
||||
{
|
||||
Channel = gEeprom.FreqChannel[VFO];
|
||||
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 {
|
||||
gEeprom.ScreenChannel[VFO] = channel;
|
||||
gEeprom.MrChannel[VFO] = channel;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
Channel = FREQ_CHANNEL_LAST - 1;
|
||||
channel = FREQ_CHANNEL_LAST - 1;
|
||||
|
||||
Attributes = gMR_ChannelAttributes[Channel];
|
||||
if (Attributes == 0xFF)
|
||||
{ // invalid/unused channel
|
||||
|
||||
uint8_t Index;
|
||||
|
||||
if (IS_MR_CHANNEL(Channel))
|
||||
{
|
||||
Channel = gEeprom.FreqChannel[VFO];
|
||||
gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO];
|
||||
ChannelAttributes_t att = gMR_ChannelAttributes[channel];
|
||||
if (att.__val == 0xFF) { // invalid/unused channel
|
||||
if (IS_MR_CHANNEL(channel)) {
|
||||
channel = gEeprom.FreqChannel[VFO];
|
||||
gEeprom.ScreenChannel[VFO] = channel;
|
||||
}
|
||||
|
||||
Index = Channel - FREQ_CHANNEL_FIRST;
|
||||
|
||||
RADIO_InitInfo(pRadio, Channel, frequencyBandTable[Index].lower);
|
||||
uint8_t bandIdx = channel - FREQ_CHANNEL_FIRST;
|
||||
RADIO_InitInfo(pVfo, channel, frequencyBandTable[bandIdx].lower);
|
||||
return;
|
||||
}
|
||||
|
||||
Band = Attributes & MR_CH_BAND_MASK;
|
||||
if (Band > BAND7_470MHz)
|
||||
{
|
||||
Band = BAND6_400MHz;
|
||||
uint8_t band = att.band;
|
||||
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);
|
||||
bool bParticipation1;
|
||||
bool bParticipation2;
|
||||
if (IS_MR_CHANNEL(channel)) {
|
||||
bParticipation1 = att.scanlist1;
|
||||
bParticipation2 = att.scanlist2;
|
||||
}
|
||||
else {
|
||||
band = channel - FREQ_CHANNEL_FIRST;
|
||||
bParticipation1 = true;
|
||||
bParticipation2 = true;
|
||||
}
|
||||
|
||||
pVfo->Band = band;
|
||||
pVfo->SCANLIST1_PARTICIPATION = bParticipation1;
|
||||
pVfo->SCANLIST2_PARTICIPATION = bParticipation2;
|
||||
pVfo->CHANNEL_SAVE = channel;
|
||||
|
||||
uint16_t base;
|
||||
if (IS_MR_CHANNEL(channel))
|
||||
base = channel * 16;
|
||||
else
|
||||
base = 0x0C80 + ((channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16);
|
||||
|
||||
if (configure == VFO_CONFIGURE_RELOAD || IS_FREQ_CHANNEL(channel))
|
||||
{
|
||||
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 (configure == VFO_CONFIGURE_RELOAD || Channel >= FREQ_CHANNEL_FIRST)
|
||||
{
|
||||
uint8_t Tmp;
|
||||
uint8_t Data[8];
|
||||
uint8_t tmp;
|
||||
uint8_t data[8];
|
||||
|
||||
// ***************
|
||||
|
||||
EEPROM_ReadBuffer(Base + 8, Data, sizeof(Data));
|
||||
EEPROM_ReadBuffer(base + 8, data, sizeof(data));
|
||||
|
||||
Tmp = Data[3] & 0x0F;
|
||||
if (Tmp > TX_OFFSET_FREQUENCY_DIRECTION_SUB)
|
||||
Tmp = 0;
|
||||
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY_DIRECTION = Tmp;
|
||||
gEeprom.VfoInfo[VFO].Modulation = (Data[3] >> 4);
|
||||
tmp = data[3] & 0x0F;
|
||||
if (tmp > TX_OFFSET_FREQUENCY_DIRECTION_SUB)
|
||||
tmp = 0;
|
||||
pVfo->TX_OFFSET_FREQUENCY_DIRECTION = tmp;
|
||||
tmp = data[3] >> 4;
|
||||
if (tmp >= MODULATION_UKNOWN)
|
||||
tmp = MODULATION_FM;
|
||||
pVfo->Modulation = tmp;
|
||||
|
||||
Tmp = Data[6];
|
||||
if (Tmp >= ARRAY_SIZE(gStepFrequencyTable))
|
||||
Tmp = STEP_12_5kHz;
|
||||
gEeprom.VfoInfo[VFO].STEP_SETTING = Tmp;
|
||||
gEeprom.VfoInfo[VFO].StepFrequency = gStepFrequencyTable[Tmp];
|
||||
tmp = data[6];
|
||||
if (tmp >= ARRAY_SIZE(gStepFrequencyTable))
|
||||
tmp = STEP_12_5kHz;
|
||||
pVfo->STEP_SETTING = tmp;
|
||||
pVfo->StepFrequency = gStepFrequencyTable[tmp];
|
||||
|
||||
Tmp = Data[7];
|
||||
if (Tmp > (ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1))
|
||||
Tmp = 0;
|
||||
gEeprom.VfoInfo[VFO].SCRAMBLING_TYPE = Tmp;
|
||||
tmp = data[7];
|
||||
if (tmp > (ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1))
|
||||
tmp = 0;
|
||||
pVfo->SCRAMBLING_TYPE = tmp;
|
||||
|
||||
gEeprom.VfoInfo[VFO].freq_config_RX.CodeType = (Data[2] >> 0) & 0x0F;
|
||||
gEeprom.VfoInfo[VFO].freq_config_TX.CodeType = (Data[2] >> 4) & 0x0F;
|
||||
pVfo->freq_config_RX.CodeType = (data[2] >> 0) & 0x0F;
|
||||
pVfo->freq_config_TX.CodeType = (data[2] >> 4) & 0x0F;
|
||||
|
||||
Tmp = Data[0];
|
||||
switch (gEeprom.VfoInfo[VFO].freq_config_RX.CodeType)
|
||||
tmp = data[0];
|
||||
switch (pVfo->freq_config_RX.CodeType)
|
||||
{
|
||||
default:
|
||||
case CODE_TYPE_OFF:
|
||||
gEeprom.VfoInfo[VFO].freq_config_RX.CodeType = CODE_TYPE_OFF;
|
||||
Tmp = 0;
|
||||
pVfo->freq_config_RX.CodeType = CODE_TYPE_OFF;
|
||||
tmp = 0;
|
||||
break;
|
||||
|
||||
case CODE_TYPE_CONTINUOUS_TONE:
|
||||
if (Tmp > (ARRAY_SIZE(CTCSS_Options) - 1))
|
||||
Tmp = 0;
|
||||
if (tmp > (ARRAY_SIZE(CTCSS_Options) - 1))
|
||||
tmp = 0;
|
||||
break;
|
||||
|
||||
case CODE_TYPE_DIGITAL:
|
||||
case CODE_TYPE_REVERSE_DIGITAL:
|
||||
if (Tmp > (ARRAY_SIZE(DCS_Options) - 1))
|
||||
Tmp = 0;
|
||||
if (tmp > (ARRAY_SIZE(DCS_Options) - 1))
|
||||
tmp = 0;
|
||||
break;
|
||||
}
|
||||
gEeprom.VfoInfo[VFO].freq_config_RX.Code = Tmp;
|
||||
pVfo->freq_config_RX.Code = tmp;
|
||||
|
||||
Tmp = Data[1];
|
||||
switch (gEeprom.VfoInfo[VFO].freq_config_TX.CodeType)
|
||||
tmp = data[1];
|
||||
switch (pVfo->freq_config_TX.CodeType)
|
||||
{
|
||||
default:
|
||||
case CODE_TYPE_OFF:
|
||||
gEeprom.VfoInfo[VFO].freq_config_TX.CodeType = CODE_TYPE_OFF;
|
||||
Tmp = 0;
|
||||
pVfo->freq_config_TX.CodeType = CODE_TYPE_OFF;
|
||||
tmp = 0;
|
||||
break;
|
||||
|
||||
case CODE_TYPE_CONTINUOUS_TONE:
|
||||
if (Tmp > (ARRAY_SIZE(CTCSS_Options) - 1))
|
||||
Tmp = 0;
|
||||
if (tmp > (ARRAY_SIZE(CTCSS_Options) - 1))
|
||||
tmp = 0;
|
||||
break;
|
||||
|
||||
case CODE_TYPE_DIGITAL:
|
||||
case CODE_TYPE_REVERSE_DIGITAL:
|
||||
if (Tmp > (ARRAY_SIZE(DCS_Options) - 1))
|
||||
Tmp = 0;
|
||||
if (tmp > (ARRAY_SIZE(DCS_Options) - 1))
|
||||
tmp = 0;
|
||||
break;
|
||||
}
|
||||
gEeprom.VfoInfo[VFO].freq_config_TX.Code = Tmp;
|
||||
pVfo->freq_config_TX.Code = tmp;
|
||||
|
||||
if (Data[4] == 0xFF)
|
||||
if (data[4] == 0xFF)
|
||||
{
|
||||
gEeprom.VfoInfo[VFO].FrequencyReverse = false;
|
||||
gEeprom.VfoInfo[VFO].CHANNEL_BANDWIDTH = BK4819_FILTER_BW_WIDE;
|
||||
gEeprom.VfoInfo[VFO].OUTPUT_POWER = OUTPUT_POWER_LOW;
|
||||
gEeprom.VfoInfo[VFO].BUSY_CHANNEL_LOCK = false;
|
||||
pVfo->FrequencyReverse = false;
|
||||
pVfo->CHANNEL_BANDWIDTH = BK4819_FILTER_BW_WIDE;
|
||||
pVfo->OUTPUT_POWER = OUTPUT_POWER_LOW;
|
||||
pVfo->BUSY_CHANNEL_LOCK = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint8_t d4 = Data[4];
|
||||
gEeprom.VfoInfo[VFO].FrequencyReverse = !!((d4 >> 0) & 1u);
|
||||
gEeprom.VfoInfo[VFO].CHANNEL_BANDWIDTH = !!((d4 >> 1) & 1u);
|
||||
gEeprom.VfoInfo[VFO].OUTPUT_POWER = ((d4 >> 2) & 3u);
|
||||
gEeprom.VfoInfo[VFO].BUSY_CHANNEL_LOCK = !!((d4 >> 4) & 1u);
|
||||
const uint8_t d4 = data[4];
|
||||
pVfo->FrequencyReverse = !!((d4 >> 0) & 1u);
|
||||
pVfo->CHANNEL_BANDWIDTH = !!((d4 >> 1) & 1u);
|
||||
pVfo->OUTPUT_POWER = ((d4 >> 2) & 3u);
|
||||
pVfo->BUSY_CHANNEL_LOCK = !!((d4 >> 4) & 1u);
|
||||
}
|
||||
|
||||
if (Data[5] == 0xFF)
|
||||
if (data[5] == 0xFF)
|
||||
{
|
||||
gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = false;
|
||||
gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = PTT_ID_OFF;
|
||||
pVfo->DTMF_DECODING_ENABLE = false;
|
||||
pVfo->DTMF_PTT_ID_TX_MODE = PTT_ID_OFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = ((Data[5] >> 0) & 1u) ? true : false;
|
||||
gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = ((Data[5] >> 1) & 7u);
|
||||
pVfo->DTMF_DECODING_ENABLE = ((data[5] >> 0) & 1u) ? true : false;
|
||||
pVfo->DTMF_PTT_ID_TX_MODE = ((data[5] >> 1) & 7u);
|
||||
}
|
||||
|
||||
// ***************
|
||||
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
uint32_t Frequency;
|
||||
uint32_t Offset;
|
||||
} __attribute__((packed)) Info;
|
||||
} __attribute__((packed)) info;
|
||||
EEPROM_ReadBuffer(base, &info, sizeof(info));
|
||||
if(info.Frequency==0xFFFFFFFF)
|
||||
pVfo->freq_config_RX.Frequency = frequencyBandTable[band].lower;
|
||||
else
|
||||
pVfo->freq_config_RX.Frequency = info.Frequency;
|
||||
|
||||
EEPROM_ReadBuffer(Base, &Info, sizeof(Info));
|
||||
|
||||
pRadio->freq_config_RX.Frequency = Info.Frequency;
|
||||
|
||||
if (Info.Offset >= 100000000)
|
||||
Info.Offset = 1000000;
|
||||
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY = Info.Offset;
|
||||
if (info.Offset >= 100000000)
|
||||
info.Offset = 1000000;
|
||||
pVfo->TX_OFFSET_FREQUENCY = info.Offset;
|
||||
|
||||
// ***************
|
||||
}
|
||||
|
||||
Frequency = pRadio->freq_config_RX.Frequency;
|
||||
uint32_t frequency = pVfo->freq_config_RX.Frequency;
|
||||
|
||||
// fix previously set incorrect band
|
||||
Band = FREQUENCY_GetBand(Frequency);
|
||||
band = FREQUENCY_GetBand(frequency);
|
||||
|
||||
if (Frequency < frequencyBandTable[Band].lower)
|
||||
Frequency = frequencyBandTable[Band].lower;
|
||||
else
|
||||
if (Frequency > frequencyBandTable[Band].upper)
|
||||
Frequency = frequencyBandTable[Band].upper;
|
||||
else
|
||||
if (Channel >= FREQ_CHANNEL_FIRST)
|
||||
Frequency = FREQUENCY_RoundToStep(Frequency, gEeprom.VfoInfo[VFO].StepFrequency);
|
||||
if (frequency < frequencyBandTable[band].lower)
|
||||
frequency = frequencyBandTable[band].lower;
|
||||
else if (frequency > frequencyBandTable[band].upper)
|
||||
frequency = frequencyBandTable[band].upper;
|
||||
else if (channel >= FREQ_CHANNEL_FIRST)
|
||||
frequency = FREQUENCY_RoundToStep(frequency, pVfo->StepFrequency);
|
||||
|
||||
pRadio->freq_config_RX.Frequency = Frequency;
|
||||
pVfo->freq_config_RX.Frequency = frequency;
|
||||
|
||||
if (Frequency >= frequencyBandTable[BAND2_108MHz].upper && Frequency < frequencyBandTable[BAND2_108MHz].upper)
|
||||
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF;
|
||||
else if (!IS_MR_CHANNEL(Channel))
|
||||
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY = FREQUENCY_RoundToStep(gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY, gEeprom.VfoInfo[VFO].StepFrequency);
|
||||
if (frequency >= frequencyBandTable[BAND2_108MHz].upper && frequency < frequencyBandTable[BAND2_108MHz].upper)
|
||||
pVfo->TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF;
|
||||
else if (!IS_MR_CHANNEL(channel))
|
||||
pVfo->TX_OFFSET_FREQUENCY = FREQUENCY_RoundToStep(pVfo->TX_OFFSET_FREQUENCY, pVfo->StepFrequency);
|
||||
|
||||
RADIO_ApplyOffset(pRadio);
|
||||
RADIO_ApplyOffset(pVfo);
|
||||
|
||||
memset(gEeprom.VfoInfo[VFO].Name, 0, sizeof(gEeprom.VfoInfo[VFO].Name));
|
||||
if (IS_MR_CHANNEL(Channel))
|
||||
memset(pVfo->Name, 0, sizeof(pVfo->Name));
|
||||
if (IS_MR_CHANNEL(channel))
|
||||
{ // 16 bytes allocated to the channel name but only 10 used, the rest are 0's
|
||||
EEPROM_ReadBuffer(0x0F50 + (Channel * 16), gEeprom.VfoInfo[VFO].Name + 0, 8);
|
||||
EEPROM_ReadBuffer(0x0F58 + (Channel * 16), gEeprom.VfoInfo[VFO].Name + 8, 2);
|
||||
EEPROM_ReadBuffer(0x0F50 + (channel * 16), pVfo->Name + 0, 8);
|
||||
EEPROM_ReadBuffer(0x0F58 + (channel * 16), pVfo->Name + 8, 2);
|
||||
}
|
||||
|
||||
if (!gEeprom.VfoInfo[VFO].FrequencyReverse)
|
||||
if (!pVfo->FrequencyReverse)
|
||||
{
|
||||
gEeprom.VfoInfo[VFO].pRX = &gEeprom.VfoInfo[VFO].freq_config_RX;
|
||||
gEeprom.VfoInfo[VFO].pTX = &gEeprom.VfoInfo[VFO].freq_config_TX;
|
||||
pVfo->pRX = &pVfo->freq_config_RX;
|
||||
pVfo->pTX = &pVfo->freq_config_TX;
|
||||
}
|
||||
else
|
||||
{
|
||||
gEeprom.VfoInfo[VFO].pRX = &gEeprom.VfoInfo[VFO].freq_config_TX;
|
||||
gEeprom.VfoInfo[VFO].pTX = &gEeprom.VfoInfo[VFO].freq_config_RX;
|
||||
pVfo->pRX = &pVfo->freq_config_TX;
|
||||
pVfo->pTX = &pVfo->freq_config_RX;
|
||||
}
|
||||
|
||||
if (!gSetting_350EN)
|
||||
{
|
||||
FREQ_Config_t *pConfig = gEeprom.VfoInfo[VFO].pRX;
|
||||
FREQ_Config_t *pConfig = pVfo->pRX;
|
||||
if (pConfig->Frequency >= 35000000 && pConfig->Frequency < 40000000)
|
||||
pConfig->Frequency = 43300000;
|
||||
}
|
||||
|
||||
if (gEeprom.VfoInfo[VFO].Modulation != MODULATION_FM)
|
||||
if (pVfo->Modulation != MODULATION_FM)
|
||||
{ // freq/chan is in AM mode
|
||||
gEeprom.VfoInfo[VFO].SCRAMBLING_TYPE = 0;
|
||||
// gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = false; // no reason to disable DTMF decoding, aircraft use it on SSB
|
||||
gEeprom.VfoInfo[VFO].freq_config_RX.CodeType = CODE_TYPE_OFF;
|
||||
gEeprom.VfoInfo[VFO].freq_config_TX.CodeType = CODE_TYPE_OFF;
|
||||
pVfo->SCRAMBLING_TYPE = 0;
|
||||
// pVfo->DTMF_DECODING_ENABLE = false; // no reason to disable DTMF decoding, aircraft use it on SSB
|
||||
pVfo->freq_config_RX.CodeType = CODE_TYPE_OFF;
|
||||
pVfo->freq_config_TX.CodeType = CODE_TYPE_OFF;
|
||||
}
|
||||
|
||||
gEeprom.VfoInfo[VFO].Compander = (Attributes & MR_CH_COMPAND) >> 4;
|
||||
pVfo->Compander = att.compander;
|
||||
|
||||
RADIO_ConfigureSquelchAndOutputPower(pRadio);
|
||||
RADIO_ConfigureSquelchAndOutputPower(pVfo);
|
||||
}
|
||||
|
||||
void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)
|
||||
|
||||
7
radio.h
7
radio.h
@@ -23,13 +23,6 @@
|
||||
#include "dcs.h"
|
||||
#include "frequencies.h"
|
||||
|
||||
enum {
|
||||
MR_CH_BAND_MASK = 0x0F << 0,
|
||||
MR_CH_COMPAND = 3u << 4, // new
|
||||
MR_CH_SCANLIST2 = 1u << 6,
|
||||
MR_CH_SCANLIST1 = 1u << 7
|
||||
};
|
||||
|
||||
enum {
|
||||
RADIO_CHANNEL_UP = 0x01u,
|
||||
RADIO_CHANNEL_DOWN = 0xFFu,
|
||||
|
||||
70
settings.c
70
settings.c
@@ -263,55 +263,45 @@ void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration)
|
||||
EEPROM_WriteBuffer(0x1F48, buf);
|
||||
}
|
||||
|
||||
void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep)
|
||||
void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep)
|
||||
{
|
||||
#ifdef ENABLE_NOAA
|
||||
if (!IS_NOAA_CHANNEL(Channel))
|
||||
#endif
|
||||
#ifdef ENABLE_NOAA
|
||||
if (!IS_NOAA_CHANNEL(channel))
|
||||
#endif
|
||||
{
|
||||
uint8_t State[8];
|
||||
uint8_t Attributes = 0xFF; // default attributes
|
||||
uint16_t Offset = 0x0D60 + (Channel & ~7u);
|
||||
uint8_t state[8];
|
||||
ChannelAttributes_t att = {
|
||||
.band = 0xf,
|
||||
.compander = 0,
|
||||
.scanlist1 = 0,
|
||||
.scanlist2 = 0,
|
||||
}; // default attributes
|
||||
|
||||
Attributes &= (uint8_t)(~MR_CH_COMPAND); // default to '0' = compander disabled
|
||||
uint16_t offset = 0x0D60 + (channel & ~7u);
|
||||
EEPROM_ReadBuffer(offset, state, sizeof(state));
|
||||
|
||||
EEPROM_ReadBuffer(Offset, State, sizeof(State));
|
||||
|
||||
if (keep)
|
||||
{
|
||||
Attributes = (pVFO->SCANLIST1_PARTICIPATION << 7) | (pVFO->SCANLIST2_PARTICIPATION << 6) | (pVFO->Compander << 4) | (pVFO->Band << 0);
|
||||
if (State[Channel & 7u] == Attributes)
|
||||
if (keep) {
|
||||
att.band = pVFO->Band;
|
||||
att.scanlist1 = pVFO->SCANLIST1_PARTICIPATION;
|
||||
att.scanlist2 = pVFO->SCANLIST2_PARTICIPATION;
|
||||
att.compander = pVFO->Compander;
|
||||
if (state[channel & 7u] == att.__val)
|
||||
return; // no change in the attributes
|
||||
}
|
||||
|
||||
State[Channel & 7u] = Attributes;
|
||||
state[channel & 7u] = att.__val;
|
||||
EEPROM_WriteBuffer(offset, state);
|
||||
|
||||
EEPROM_WriteBuffer(Offset, State);
|
||||
gMR_ChannelAttributes[channel] = att;
|
||||
|
||||
gMR_ChannelAttributes[Channel] = Attributes;
|
||||
|
||||
// #ifndef ENABLE_KEEP_MEM_NAME
|
||||
if (IS_MR_CHANNEL(Channel))
|
||||
{ // it's a memory channel
|
||||
|
||||
const uint16_t OffsetMR = Channel * 16;
|
||||
if (!keep)
|
||||
{ // clear/reset the channel name
|
||||
//memset(&State, 0xFF, sizeof(State));
|
||||
memset(&State, 0x00, sizeof(State)); // follow the QS way
|
||||
EEPROM_WriteBuffer(0x0F50 + OffsetMR, State);
|
||||
EEPROM_WriteBuffer(0x0F58 + OffsetMR, State);
|
||||
}
|
||||
// else
|
||||
// { // update the channel name
|
||||
// memmove(State, pVFO->Name + 0, 8);
|
||||
// EEPROM_WriteBuffer(0x0F50 + OffsetMR, State);
|
||||
// //memset(State, 0xFF, sizeof(State));
|
||||
// memset(State, 0x00, sizeof(State)); // follow the QS way
|
||||
// memmove(State, pVFO->Name + 8, 2);
|
||||
// EEPROM_WriteBuffer(0x0F58 + OffsetMR, State);
|
||||
// }
|
||||
if (IS_MR_CHANNEL(channel)) { // it's a memory channel
|
||||
const uint16_t OffsetMR = channel * 16;
|
||||
if (!keep) {
|
||||
// clear/reset the channel name
|
||||
memset(&state, 0x00, sizeof(state));
|
||||
EEPROM_WriteBuffer(0x0F50 + OffsetMR, state);
|
||||
EEPROM_WriteBuffer(0x0F58 + OffsetMR, state);
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,9 +127,9 @@ enum CHANNEL_DisplayMode_t {
|
||||
typedef enum CHANNEL_DisplayMode_t CHANNEL_DisplayMode_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t ScreenChannel[2];
|
||||
uint8_t FreqChannel[2];
|
||||
uint8_t MrChannel[2];
|
||||
uint8_t ScreenChannel[2]; // current channels set in the radio (memory or frequency channels)
|
||||
uint8_t FreqChannel[2]; // last frequency channels used
|
||||
uint8_t MrChannel[2]; // last memory channels used
|
||||
#ifdef ENABLE_NOAA
|
||||
uint8_t NoaaChannel[2];
|
||||
#endif
|
||||
@@ -254,6 +254,6 @@ void SETTINGS_SaveVfoIndices(void);
|
||||
void SETTINGS_SaveSettings(void);
|
||||
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode);
|
||||
void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration);
|
||||
void SETTINGS_UpdateChannel(uint8_t Channel, const VFO_Info_t *pVFO, bool keep);
|
||||
void SETTINGS_UpdateChannel(uint8_t channel, const VFO_Info_t *pVFO, bool keep);
|
||||
|
||||
#endif
|
||||
|
||||
32
ui/helper.c
32
ui/helper.c
@@ -180,10 +180,12 @@ void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center)
|
||||
}
|
||||
}
|
||||
|
||||
void UI_DrawPixel(uint8_t x, uint8_t y, bool black)
|
||||
void UI_DrawPixelBuffer(uint8_t (*buffer)[128], uint8_t x, uint8_t y, bool black)
|
||||
{
|
||||
gFrameBuffer[y/8][x] &= ~(1 << (y%8));
|
||||
gFrameBuffer[y/8][x] |= black << (y%8);
|
||||
if(black)
|
||||
buffer[y/8][x] |= 1 << (y%8);
|
||||
else
|
||||
buffer[y/8][x] &= ~(1 << (y%8));
|
||||
}
|
||||
|
||||
static void sort(int16_t *a, int16_t *b)
|
||||
@@ -195,12 +197,12 @@ static void sort(int16_t *a, int16_t *b)
|
||||
}
|
||||
}
|
||||
|
||||
void UI_DrawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black)
|
||||
void UI_DrawLineBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black)
|
||||
{
|
||||
if(x2==x1) {
|
||||
sort(&y1, &y2);
|
||||
for(int16_t i = y1; i <= y2; i++) {
|
||||
UI_DrawPixel(x1, i, black);
|
||||
UI_DrawPixelBuffer(buffer, x1, i, black);
|
||||
}
|
||||
} else {
|
||||
const int multipl = 1000;
|
||||
@@ -210,17 +212,17 @@ void UI_DrawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black)
|
||||
sort(&x1, &x2);
|
||||
for(int i = x1; i<= x2; i++)
|
||||
{
|
||||
UI_DrawPixel(i, i*a/multipl +b, black);
|
||||
UI_DrawPixelBuffer(buffer, i, i*a/multipl +b, black);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UI_DrawRectangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black)
|
||||
void UI_DrawRectangleBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black)
|
||||
{
|
||||
UI_DrawLine(x1,y1, x1,y2, black);
|
||||
UI_DrawLine(x1,y1, x2,y1, black);
|
||||
UI_DrawLine(x2,y1, x2,y2, black);
|
||||
UI_DrawLine(x1,y2, x2,y2, black);
|
||||
UI_DrawLineBuffer(buffer, x1,y1, x1,y2, black);
|
||||
UI_DrawLineBuffer(buffer, x1,y1, x2,y1, black);
|
||||
UI_DrawLineBuffer(buffer, x2,y1, x2,y2, black);
|
||||
UI_DrawLineBuffer(buffer, x1,y2, x2,y2, black);
|
||||
}
|
||||
|
||||
void UI_DisplayPopup(const char *string)
|
||||
@@ -234,13 +236,13 @@ void UI_DisplayPopup(const char *string)
|
||||
// }
|
||||
|
||||
// for(uint8_t x = 10; x < 118; x++) {
|
||||
// UI_DrawPixel(x, 10, true);
|
||||
// UI_DrawPixel(x, 46-9, true);
|
||||
// UI_DrawPixelBuffer(x, 10, true);
|
||||
// UI_DrawPixelBuffer(x, 46-9, true);
|
||||
// }
|
||||
|
||||
// for(uint8_t y = 11; y < 37; y++) {
|
||||
// UI_DrawPixel(10, y, true);
|
||||
// UI_DrawPixel(117, y, true);
|
||||
// UI_DrawPixelBuffer(10, y, true);
|
||||
// UI_DrawPixelBuffer(117, y, true);
|
||||
// }
|
||||
// DrawRectangle(9,9, 118,38, true);
|
||||
UI_PrintString(string, 9, 118, 2, 8);
|
||||
|
||||
@@ -33,7 +33,7 @@ void UI_DisplayFrequency(const char *string, uint8_t X, uint8_t Y, bool center);
|
||||
|
||||
void UI_DisplayPopup(const char *string);
|
||||
|
||||
void UI_DrawPixel(uint8_t x, uint8_t y, bool black);
|
||||
void UI_DrawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black);
|
||||
void UI_DrawRectangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black);
|
||||
void UI_DrawPixelBuffer(uint8_t (*buffer)[128], uint8_t x, uint8_t y, bool black);
|
||||
void UI_DrawLineBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black);
|
||||
void UI_DrawRectangleBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black);
|
||||
|
||||
|
||||
26
ui/main.c
26
ui/main.c
@@ -169,8 +169,18 @@ static void DisplayRSSIBar(const int16_t rssi, const bool now)
|
||||
if (now)
|
||||
memset(p_line, 0, LCD_WIDTH);
|
||||
|
||||
const int8_t dBmCorrTable[7] = {
|
||||
-15, // band 1
|
||||
-15, // band 2
|
||||
-25, // band 3
|
||||
-20, // band 4
|
||||
-20, // band 5
|
||||
-20, // band 6
|
||||
-7 // band 7
|
||||
};
|
||||
|
||||
const int16_t s0_dBm = -147; // S0 .. base level
|
||||
const int16_t rssi_dBm = (rssi / 2) - 160;
|
||||
const int16_t rssi_dBm = (rssi / 2) - 160 + dBmCorrTable[gRxVfo->Band];
|
||||
|
||||
const uint8_t s_level = MIN(MAX((rssi_dBm - s0_dBm) / 6, 0), 9); // S0 - S9
|
||||
uint8_t overS9dBm = MIN(MAX(rssi_dBm - (s0_dBm + 9*6), 0), 99);
|
||||
@@ -433,7 +443,7 @@ void UI_DisplayMain(void)
|
||||
UI_PrintString(String, 32, 0, line, 8);
|
||||
}
|
||||
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -447,15 +457,15 @@ void UI_DisplayMain(void)
|
||||
{ // it's a channel
|
||||
|
||||
// show the scan list assigment symbols
|
||||
const uint8_t attributes = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
|
||||
if (attributes & MR_CH_SCANLIST1)
|
||||
const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
|
||||
if (att.scanlist1)
|
||||
memmove(p_line0 + 113, BITMAP_ScanList1, sizeof(BITMAP_ScanList1));
|
||||
if (attributes & MR_CH_SCANLIST2)
|
||||
if (att.scanlist2)
|
||||
memmove(p_line0 + 120, BITMAP_ScanList2, sizeof(BITMAP_ScanList2));
|
||||
|
||||
// compander symbol
|
||||
#ifndef ENABLE_BIG_FREQ
|
||||
if ((attributes & MR_CH_COMPAND) > 0)
|
||||
if (att.compander)
|
||||
memmove(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
|
||||
#else
|
||||
// TODO: // find somewhere else to put the symbol
|
||||
@@ -533,8 +543,8 @@ void UI_DisplayMain(void)
|
||||
}
|
||||
|
||||
// show the channel symbols
|
||||
const uint8_t attributes = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
|
||||
if ((attributes & MR_CH_COMPAND) > 0)
|
||||
const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
|
||||
if (att.compander)
|
||||
#ifdef ENABLE_BIG_FREQ
|
||||
memmove(p_line0 + 120, BITMAP_compand, sizeof(BITMAP_compand));
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user