11 Commits
v0.17 ... v0.18

Author SHA1 Message Date
Krzysiek Egzmont
a0d052b68b Spectrum refactor 2023-11-25 19:28:21 +01:00
Krzysiek Egzmont
9a3249a667 FIX #121: Rise tones volume 2023-11-23 21:20:24 +01:00
Krzysiek Egzmont
ffdc0e03b5 FIX #114, #120: Restart monitor mode on PTT release, long press EXIT exits monitor mode 2023-11-23 21:02:47 +01:00
Krzysiek Egzmont
d8d4384b20 Refactoring 2023-11-23 19:48:47 +01:00
Krzysiek Egzmont
0ce7d7bdc3 FIX #129: Bug in radio initialization after reset. 2023-11-22 23:40:39 +01:00
Krzysiek Egzmont
fb30ec8c86 Refactor 2023-11-22 23:40:20 +01:00
Krzysiek Egzmont
67307463e2 FIX #92: Adjust s-meter values 2023-11-22 14:52:16 +01:00
Krzysiek Egzmont
fdd7fc063e Cleanup docker container after build 2023-11-22 14:51:53 +01:00
Krzysiek Egzmont
592810b7d7 FIX #125: Frequency input on the first VFO blanks the display on the second 2023-11-20 22:32:39 +01:00
Krzysiek Egzmont
6e5e7e7aef FIX #85: Equalize tones volume in DTMF codes, fix wrong DTMF frequency values 2023-11-20 21:24:09 +01:00
ErikS-web
cd0dc71de6 Update README.md
Type error corrected
2023-11-18 21:26:37 +01:00
17 changed files with 346 additions and 375 deletions

View File

@@ -21,7 +21,7 @@
* battery voltage callibration from menu * battery voltage callibration from menu
* better battery percentage calculation, selectable for 1600mAh or 2200mAh * better battery percentage calculation, selectable for 1600mAh or 2200mAh
* more configurable button functions * 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) * better DCS/CTCSS scanning in the menu (`* SCAN` while in RX DCS/CTCSS menu item)
* Piotr022 s-meter style * Piotr022 s-meter style
* restore initial freq/channel when scanning stopped with EXIT, remember last found transmission with MENU button * restore initial freq/channel when scanning stopped with EXIT, remember last found transmission with MENU button

View File

@@ -63,7 +63,6 @@ void ACTION_Power(void)
gTxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW; gTxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW;
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
//gRequestSaveChannel = 2; // auto save the channel
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_POWER; gAnotherVoiceID = VOICE_ID_POWER;
@@ -74,8 +73,7 @@ void ACTION_Power(void)
void ACTION_Monitor(void) void ACTION_Monitor(void)
{ {
if (gCurrentFunction != FUNCTION_MONITOR) if (gCurrentFunction != FUNCTION_MONITOR) { // enable the monitor
{ // enable the monitor
RADIO_SelectVfos(); RADIO_SelectVfos();
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST && gIsNoaaMode) if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST && gIsNoaaMode)
@@ -88,16 +86,14 @@ void ACTION_Monitor(void)
gMonitor = false; gMonitor = false;
if (gScanStateDir != SCAN_OFF) if (gScanStateDir != SCAN_OFF) {
{
gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms; gScanPauseDelayIn_10ms = scan_pause_delay_in_1_10ms;
gScheduleScanListen = false; gScheduleScanListen = false;
gScanPauseMode = true; gScanPauseMode = true;
} }
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode) if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode) {
{
gNOAA_Countdown_10ms = NOAA_countdown_10ms; gNOAA_Countdown_10ms = NOAA_countdown_10ms;
gScheduleNOAA = false; gScheduleNOAA = false;
} }
@@ -106,8 +102,7 @@ void ACTION_Monitor(void)
RADIO_SetupRegisters(true); RADIO_SetupRegisters(true);
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (gFmRadioMode) if (gFmRadioMode) {
{
FM_Start(); FM_Start();
gRequestDisplayScreen = DISPLAY_FM; gRequestDisplayScreen = DISPLAY_FM;
} }

View File

@@ -173,14 +173,11 @@ static void HandleIncoming(void)
{ {
bool bFlag; bool bFlag;
if (!g_SquelchLost) if (!g_SquelchLost) { // squelch is closed
{ // squelch is closed
if (gDTMF_RX_index > 0) if (gDTMF_RX_index > 0)
DTMF_clear_RX(); DTMF_clear_RX();
if (gCurrentFunction != FUNCTION_FOREGROUND) if (gCurrentFunction != FUNCTION_FOREGROUND) {
{
FUNCTION_Select(FUNCTION_FOREGROUND); FUNCTION_Select(FUNCTION_FOREGROUND);
gUpdateDisplay = true; gUpdateDisplay = true;
} }
@@ -190,38 +187,30 @@ static void HandleIncoming(void)
bFlag = (gScanStateDir == SCAN_OFF && gCurrentCodeType == CODE_TYPE_OFF); bFlag = (gScanStateDir == SCAN_OFF && gCurrentCodeType == CODE_TYPE_OFF);
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gNOAACountdown_10ms > 0) if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE) && gNOAACountdown_10ms > 0) {
{
gNOAACountdown_10ms = 0; gNOAACountdown_10ms = 0;
bFlag = true; bFlag = true;
} }
#endif #endif
if (g_CTCSS_Lost && gCurrentCodeType == CODE_TYPE_CONTINUOUS_TONE) if (g_CTCSS_Lost && gCurrentCodeType == CODE_TYPE_CONTINUOUS_TONE) {
{
bFlag = true; bFlag = true;
gFoundCTCSS = false; 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; gFoundCDCSS = false;
} }
else else if (!bFlag)
if (!bFlag)
return; return;
if (gScanStateDir == SCAN_OFF) if (gScanStateDir == SCAN_OFF) { // not scanning
{ // not scanning if (gRxVfo->DTMF_DECODING_ENABLE || gSetting_KILLED) { // DTMF DCD is enabled
if (gRxVfo->DTMF_DECODING_ENABLE || gSetting_KILLED)
{ // DTMF DCD is enabled
DTMF_HandleRequest(); DTMF_HandleRequest();
if (gDTMF_CallState == DTMF_CALL_STATE_NONE) if (gDTMF_CallState == DTMF_CALL_STATE_NONE) {
{ if (gRxReceptionMode == RX_MODE_DETECTED) {
if (gRxReceptionMode == RX_MODE_DETECTED)
{
gDualWatchCountdown_10ms = dual_watch_count_after_1_10ms; gDualWatchCountdown_10ms = dual_watch_count_after_1_10ms;
gScheduleDualWatch = false; 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 // send the CTCSS/DCS tail tone - allows the receivers to mute the usual FM squelch tail/crash
RADIO_EnableCxCSS(); RADIO_EnableCxCSS();
RADIO_SetupRegisters(false); RADIO_SetupRegisters(false);
if (gMonitor)
gFlagReconfigureVfos = true; //turn the monitor back on
} }
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
@@ -1726,6 +1718,9 @@ static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
// cancel user input // cancel user input
cancelUserInputModes(); cancelUserInputModes();
if (gMonitor)
ACTION_Monitor(); //turn off the monitor
} }
if (gScreenToDisplay == DISPLAY_MENU) // 1of11 if (gScreenToDisplay == DISPLAY_MENU) // 1of11

View File

@@ -17,6 +17,7 @@
#include "app/spectrum.h" #include "app/spectrum.h"
#include "driver/backlight.h" #include "driver/backlight.h"
#include "audio.h" #include "audio.h"
#include "ui/helper.h"
struct FrequencyBandInfo { struct FrequencyBandInfo {
uint32_t lower; uint32_t lower;
@@ -125,21 +126,13 @@ static void SetRegMenuValue(uint8_t st, bool add) {
// GUI functions // GUI functions
static void PutPixel(uint8_t x, uint8_t y, bool fill) { static void PutPixel(uint8_t x, uint8_t y, bool fill) {
if (fill) { UI_DrawPixelBuffer(gFrameBuffer, x, y, fill);
gFrameBuffer[y >> 3][x] |= 1 << (y & 7);
} else {
gFrameBuffer[y >> 3][x] &= ~(1 << (y & 7));
}
} }
static void PutPixelStatus(uint8_t x, uint8_t y, bool fill) { static void PutPixelStatus(uint8_t x, uint8_t y, bool fill) {
if (fill) { UI_DrawPixelBuffer(&gStatusLine, x, y, fill);
gStatusLine[x] |= 1 << y;
} else {
gStatusLine[x] &= ~(1 << y);
}
} }
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++) { for (int i = sy; i <= ey; i++) {
if (i < 56 && nx < 128) { if (i < 56 && nx < 128) {
PutPixel(nx, i, fill); PutPixel(nx, i, fill);
@@ -606,7 +599,7 @@ static void DrawSpectrum() {
for (uint8_t x = 0; x < 128; ++x) { for (uint8_t x = 0; x < 128; ++x) {
uint16_t rssi = rssiHistory[x >> settings.stepsCount]; uint16_t rssi = rssiHistory[x >> settings.stepsCount];
if (rssi != RSSI_MAX_VALUE) { 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 #endif
GUI_DisplaySmallest(String, 0, 1, true, true); GUI_DisplaySmallest(String, 0, 1, true, true);
for (int i = 0; i < 4; i++) { BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryCheckCounter++ % 4], &gBatteryCurrent);
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[i], &gBatteryCurrent);
}
uint16_t Voltage; uint16_t voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] +
uint8_t v = 0;
Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] +
gBatteryVoltages[3]) / gBatteryVoltages[3]) /
4; 4 * 760 / gBatteryCalibration[3];
for(uint8_t i = 5; i > 0; i--) { unsigned perc = BATTERY_VoltsToPercent(voltage);
if(Voltage > gBatteryCalibration[i - 1]) {
v = i; // sprintf(String, "%d %d", voltage, perc);
break; // GUI_DisplaySmallest(String, 48, 1, true, true);
}
gStatusLine[116] = 0b00011100;
gStatusLine[117] = 0b00111110;
for (int i = 118; i <= 126; i++) {
gStatusLine[i] = 0b00100010;
} }
gStatusLine[127] = 0b01111110; for (unsigned i = 127; i >= 118; i--) {
for (int i = 126; i >= 116; i--) { if (127 - i <= (perc+5)*9/100) {
gStatusLine[i] = 0b01000010; gStatusLine[i] = 0b00111110;
}
v <<= 1;
for (int i = 125; i >= 116; i--) {
if (126 - i <= v) {
gStatusLine[i + 2] = 0b01111110;
} }
} }
gStatusLine[117] = 0b01111110;
gStatusLine[116] = 0b00011000;
} }
static void DrawF(uint32_t f) { static void DrawF(uint32_t f) {
@@ -712,19 +697,13 @@ static void DrawTicks() {
// center // center
if (IsCenterMode()) { if (IsCenterMode()) {
gFrameBuffer[5][62] = 0x80; memset(gFrameBuffer[5] + 62, 0x80, 5);
gFrameBuffer[5][63] = 0x80;
gFrameBuffer[5][64] = 0xff; gFrameBuffer[5][64] = 0xff;
gFrameBuffer[5][65] = 0x80;
gFrameBuffer[5][66] = 0x80;
} else { } else {
memset(gFrameBuffer[5] + 1, 0x80, 3);
memset(gFrameBuffer[5] + 124, 0x80, 3);
gFrameBuffer[5][0] = 0xff; 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; gFrameBuffer[5][127] = 0xff;
} }
} }

View File

@@ -727,6 +727,13 @@ void BOARD_EEPROM_Init(void)
// 0D60..0E27 // 0D60..0E27
EEPROM_ReadBuffer(0x0D60, gMR_ChannelAttributes, sizeof(gMR_ChannelAttributes)); 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 // 0F30..0F3F
EEPROM_ReadBuffer(0x0F30, gCustomAesKey, sizeof(gCustomAesKey)); EEPROM_ReadBuffer(0x0F30, gCustomAesKey, sizeof(gCustomAesKey));

View File

@@ -1,4 +1,4 @@
@echo off @echo off
docker build -t uvk5 . 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 pause

View File

@@ -1,3 +1,3 @@
#!/bin/sh #!/bin/sh
docker build -t uvk5 . 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/"

View File

@@ -30,6 +30,9 @@
static const uint16_t FSK_RogerTable[7] = {0xF1A2, 0x7446, 0x61A4, 0x6544, 0x4E8A, 0xE044, 0xEA84}; 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; static uint16_t gBK4819_GpioOutState;
bool gRxIdleMode; bool gRxIdleMode;
@@ -984,15 +987,15 @@ void BK4819_EnableDTMF(void)
void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch) void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch)
{ {
uint16_t ToneConfig; uint16_t ToneConfig = BK4819_REG_70_ENABLE_TONE1;
BK4819_EnterTxMute(); BK4819_EnterTxMute();
BK4819_SetAF(BK4819_AF_BEEP); BK4819_SetAF(BK4819_AF_BEEP);
if (bTuningGainSwitch == 0) 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 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_70, ToneConfig);
BK4819_WriteRegister(BK4819_REG_30, 0); 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)); 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) void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay, const unsigned int level, const bool play_speaker)
{ {
BK4819_EnterTxMute(); BK4819_EnterTxMute();
@@ -1013,9 +1017,7 @@ void BK4819_PlaySingleTone(const unsigned int tone_Hz, const unsigned int delay,
else else
BK4819_SetAF(BK4819_AF_MUTE); 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_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | ((level & 0x7f) << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
BK4819_EnableTXLink(); BK4819_EnableTXLink();
@@ -1209,9 +1211,9 @@ void BK4819_EnterDTMF_TX(bool bLocalLoopback)
BK4819_WriteRegister(BK4819_REG_70, BK4819_WriteRegister(BK4819_REG_70,
BK4819_REG_70_MASK_ENABLE_TONE1 | 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 | 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(); BK4819_EnableTXLink();
} }
@@ -1250,16 +1252,16 @@ void BK4819_PlayDTMF(char Code)
switch (Code) switch (Code)
{ {
case '0': tone1 = 941; tone2 = 1336; break; 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 '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 '4': tone1 = 770; tone2 = 1209; break;
case '5': tone1 = 770; tone2 = 1336; break; case '5': tone1 = 770; tone2 = 1336; break;
case '6': tone1 = 770; tone2 = 1477; break; case '6': tone1 = 770; tone2 = 1477; break;
case '7': tone1 = 852; tone2 = 1209; break; case '7': tone1 = 852; tone2 = 1209; break;
case '8': tone1 = 852; tone2 = 1336; break; case '8': tone1 = 852; tone2 = 1336; break;
case '9': tone1 = 852; tone2 = 1477; 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 'B': tone1 = 770; tone2 = 1633; break;
case 'C': tone1 = 852; tone2 = 1633; break; case 'C': tone1 = 852; tone2 = 1633; break;
case 'D': tone1 = 941; 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 // 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 | (66u << 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_71, scale_freq(Frequency)); BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency));
@@ -1700,8 +1701,7 @@ void BK4819_PlayRoger(void)
BK4819_EnterTxMute(); BK4819_EnterTxMute();
BK4819_SetAF(BK4819_AF_MUTE); 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 | (66u << 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_EnableTXLink(); BK4819_EnableTXLink();
SYSTEM_DelayMs(50); SYSTEM_DelayMs(50);
@@ -1782,7 +1782,12 @@ void BK4819_PlayDTMFEx(bool bLocalLoopback, char Code)
BK4819_EnterTxMute(); BK4819_EnterTxMute();
BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE); 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(); BK4819_EnableTXLink();

2
misc.c
View File

@@ -111,7 +111,7 @@ uint16_t gEEPROM_RSSI_CALIB[7][4];
uint16_t gEEPROM_1F8A; uint16_t gEEPROM_1F8A;
uint16_t gEEPROM_1F8C; 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; volatile uint16_t gBatterySaveCountdown_10ms = battery_save_count_10ms;

13
misc.h
View File

@@ -176,7 +176,18 @@ extern uint16_t gEEPROM_RSSI_CALIB[7][4];
extern uint16_t gEEPROM_1F8A; extern uint16_t gEEPROM_1F8A;
extern uint16_t gEEPROM_1F8C; 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; extern volatile uint16_t gBatterySaveCountdown_10ms;

320
radio.c
View File

@@ -56,24 +56,22 @@ const char gModulationStr[][4] =
bool RADIO_CheckValidChannel(uint16_t Channel, bool bCheckScanList, uint8_t VFO) bool RADIO_CheckValidChannel(uint16_t Channel, bool bCheckScanList, uint8_t VFO)
{ // return true if the channel appears valid { // return true if the channel appears valid
uint8_t Attributes; ChannelAttributes_t att;
uint8_t PriorityCh1; uint8_t PriorityCh1;
uint8_t PriorityCh2; uint8_t PriorityCh2;
if (!IS_MR_CHANNEL(Channel)) if (!IS_MR_CHANNEL(Channel))
return false; 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; return false;
if (bCheckScanList) if (bCheckScanList) {
{ switch (VFO) {
switch (VFO)
{
case 0: case 0:
if ((Attributes & MR_CH_SCANLIST1) == 0) if (!att.scanlist1)
return false; return false;
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[0]; PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[0];
@@ -81,7 +79,7 @@ bool RADIO_CheckValidChannel(uint16_t Channel, bool bCheckScanList, uint8_t VFO)
break; break;
case 1: case 1:
if ((Attributes & MR_CH_SCANLIST2) == 0) if (!att.scanlist2)
return false; return false;
PriorityCh1 = gEeprom.SCANLIST_PRIORITY_CH1[1]; 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)); memset(pInfo, 0, sizeof(*pInfo));
pInfo->Band = FREQUENCY_GetBand(Frequency); pInfo->Band = FREQUENCY_GetBand(Frequency);
pInfo->SCANLIST1_PARTICIPATION = true; pInfo->SCANLIST1_PARTICIPATION = false;
pInfo->SCANLIST2_PARTICIPATION = true; pInfo->SCANLIST2_PARTICIPATION = false;
pInfo->STEP_SETTING = STEP_12_5kHz; pInfo->STEP_SETTING = STEP_12_5kHz;
pInfo->StepFrequency = gStepFrequencyTable[pInfo->STEP_SETTING]; pInfo->StepFrequency = gStepFrequencyTable[pInfo->STEP_SETTING];
pInfo->CHANNEL_SAVE = ChannelSave; 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)) if (ChannelSave == (FREQ_CHANNEL_FIRST + BAND2_108MHz))
pInfo->Modulation = MODULATION_AM; pInfo->Modulation = MODULATION_AM;
else
pInfo->Modulation = MODULATION_FM;
RADIO_ConfigureSquelchAndOutputPower(pInfo); RADIO_ConfigureSquelchAndOutputPower(pInfo);
} }
void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure) void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure)
{ {
uint8_t Channel; VFO_Info_t *pVfo = &gEeprom.VfoInfo[VFO];
uint8_t Attributes;
uint8_t Band;
bool bParticipation2;
uint16_t Base;
uint32_t Frequency;
VFO_Info_t *pRadio = &gEeprom.VfoInfo[VFO];
if (!gSetting_350EN) if (!gSetting_350EN) {
{ if (gEeprom.FreqChannel[VFO] == FREQ_CHANNEL_FIRST + BAND5_350MHz)
if (gEeprom.FreqChannel[VFO] == (FREQ_CHANNEL_LAST - 2)) gEeprom.FreqChannel[VFO] = FREQ_CHANNEL_FIRST + BAND6_400MHz;
gEeprom.FreqChannel[VFO] = FREQ_CHANNEL_LAST - 1;
if (gEeprom.ScreenChannel[VFO] == (FREQ_CHANNEL_LAST - 2)) if (gEeprom.ScreenChannel[VFO] == FREQ_CHANNEL_FIRST + BAND5_350MHz)
gEeprom.ScreenChannel[VFO] = FREQ_CHANNEL_LAST - 1; 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 #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) if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_OFF)
return; return;
@@ -185,248 +177,240 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
} }
#endif #endif
if (IS_MR_CHANNEL(Channel)) if (IS_MR_CHANNEL(channel)) {
{ channel = RADIO_FindNextChannel(channel, RADIO_CHANNEL_UP, false, VFO);
Channel = RADIO_FindNextChannel(Channel, RADIO_CHANNEL_UP, false, VFO); if (channel == 0xFF) {
if (Channel == 0xFF) channel = gEeprom.FreqChannel[VFO];
{
Channel = gEeprom.FreqChannel[VFO];
gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO]; gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO];
} }
else else {
{ gEeprom.ScreenChannel[VFO] = channel;
gEeprom.ScreenChannel[VFO] = Channel; gEeprom.MrChannel[VFO] = channel;
gEeprom.MrChannel[VFO] = Channel;
} }
} }
} }
else else
Channel = FREQ_CHANNEL_LAST - 1; channel = FREQ_CHANNEL_LAST - 1;
Attributes = gMR_ChannelAttributes[Channel]; ChannelAttributes_t att = gMR_ChannelAttributes[channel];
if (Attributes == 0xFF) if (att.__val == 0xFF) { // invalid/unused channel
{ // invalid/unused channel if (IS_MR_CHANNEL(channel)) {
channel = gEeprom.FreqChannel[VFO];
uint8_t Index; gEeprom.ScreenChannel[VFO] = channel;
if (IS_MR_CHANNEL(Channel))
{
Channel = gEeprom.FreqChannel[VFO];
gEeprom.ScreenChannel[VFO] = gEeprom.FreqChannel[VFO];
} }
Index = Channel - FREQ_CHANNEL_FIRST; uint8_t bandIdx = channel - FREQ_CHANNEL_FIRST;
RADIO_InitInfo(pVfo, channel, frequencyBandTable[bandIdx].lower);
RADIO_InitInfo(pRadio, Channel, frequencyBandTable[Index].lower);
return; return;
} }
Band = Attributes & MR_CH_BAND_MASK; uint8_t band = att.band;
if (Band > BAND7_470MHz) if (band > BAND7_470MHz) {
{ band = BAND6_400MHz;
Band = BAND6_400MHz;
} }
if (IS_MR_CHANNEL(Channel)) bool bParticipation1;
{ bool bParticipation2;
gEeprom.VfoInfo[VFO].Band = Band; if (IS_MR_CHANNEL(channel)) {
gEeprom.VfoInfo[VFO].SCANLIST1_PARTICIPATION = !!(Attributes & MR_CH_SCANLIST1); bParticipation1 = att.scanlist1;
bParticipation2 = !!(Attributes & MR_CH_SCANLIST2); bParticipation2 = att.scanlist2;
} }
else else {
{ band = channel - FREQ_CHANNEL_FIRST;
Band = Channel - FREQ_CHANNEL_FIRST; bParticipation1 = true;
gEeprom.VfoInfo[VFO].Band = Band;
bParticipation2 = true; bParticipation2 = true;
gEeprom.VfoInfo[VFO].SCANLIST1_PARTICIPATION = true;
} }
gEeprom.VfoInfo[VFO].SCANLIST2_PARTICIPATION = bParticipation2; pVfo->Band = band;
gEeprom.VfoInfo[VFO].CHANNEL_SAVE = Channel; pVfo->SCANLIST1_PARTICIPATION = bParticipation1;
pVfo->SCANLIST2_PARTICIPATION = bParticipation2;
pVfo->CHANNEL_SAVE = channel;
if (IS_MR_CHANNEL(Channel)) uint16_t base;
Base = Channel * 16; if (IS_MR_CHANNEL(channel))
base = channel * 16;
else else
Base = 0x0C80 + ((Channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16); base = 0x0C80 + ((channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16);
if (configure == VFO_CONFIGURE_RELOAD || Channel >= FREQ_CHANNEL_FIRST) if (configure == VFO_CONFIGURE_RELOAD || IS_FREQ_CHANNEL(channel))
{ {
uint8_t Tmp; uint8_t tmp;
uint8_t Data[8]; uint8_t data[8];
// *************** // ***************
EEPROM_ReadBuffer(Base + 8, Data, sizeof(Data)); EEPROM_ReadBuffer(base + 8, data, sizeof(data));
Tmp = Data[3] & 0x0F; tmp = data[3] & 0x0F;
if (Tmp > TX_OFFSET_FREQUENCY_DIRECTION_SUB) if (tmp > TX_OFFSET_FREQUENCY_DIRECTION_SUB)
Tmp = 0; tmp = 0;
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY_DIRECTION = Tmp; pVfo->TX_OFFSET_FREQUENCY_DIRECTION = tmp;
gEeprom.VfoInfo[VFO].Modulation = (Data[3] >> 4); tmp = data[3] >> 4;
if (tmp >= MODULATION_UKNOWN)
tmp = MODULATION_FM;
pVfo->Modulation = tmp;
Tmp = Data[6]; tmp = data[6];
if (Tmp >= ARRAY_SIZE(gStepFrequencyTable)) if (tmp >= ARRAY_SIZE(gStepFrequencyTable))
Tmp = STEP_12_5kHz; tmp = STEP_12_5kHz;
gEeprom.VfoInfo[VFO].STEP_SETTING = Tmp; pVfo->STEP_SETTING = tmp;
gEeprom.VfoInfo[VFO].StepFrequency = gStepFrequencyTable[Tmp]; pVfo->StepFrequency = gStepFrequencyTable[tmp];
Tmp = Data[7]; tmp = data[7];
if (Tmp > (ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1)) if (tmp > (ARRAY_SIZE(gSubMenu_SCRAMBLER) - 1))
Tmp = 0; tmp = 0;
gEeprom.VfoInfo[VFO].SCRAMBLING_TYPE = Tmp; pVfo->SCRAMBLING_TYPE = tmp;
gEeprom.VfoInfo[VFO].freq_config_RX.CodeType = (Data[2] >> 0) & 0x0F; pVfo->freq_config_RX.CodeType = (data[2] >> 0) & 0x0F;
gEeprom.VfoInfo[VFO].freq_config_TX.CodeType = (Data[2] >> 4) & 0x0F; pVfo->freq_config_TX.CodeType = (data[2] >> 4) & 0x0F;
Tmp = Data[0]; tmp = data[0];
switch (gEeprom.VfoInfo[VFO].freq_config_RX.CodeType) switch (pVfo->freq_config_RX.CodeType)
{ {
default: default:
case CODE_TYPE_OFF: case CODE_TYPE_OFF:
gEeprom.VfoInfo[VFO].freq_config_RX.CodeType = CODE_TYPE_OFF; pVfo->freq_config_RX.CodeType = CODE_TYPE_OFF;
Tmp = 0; tmp = 0;
break; break;
case CODE_TYPE_CONTINUOUS_TONE: case CODE_TYPE_CONTINUOUS_TONE:
if (Tmp > (ARRAY_SIZE(CTCSS_Options) - 1)) if (tmp > (ARRAY_SIZE(CTCSS_Options) - 1))
Tmp = 0; tmp = 0;
break; break;
case CODE_TYPE_DIGITAL: case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL: case CODE_TYPE_REVERSE_DIGITAL:
if (Tmp > (ARRAY_SIZE(DCS_Options) - 1)) if (tmp > (ARRAY_SIZE(DCS_Options) - 1))
Tmp = 0; tmp = 0;
break; break;
} }
gEeprom.VfoInfo[VFO].freq_config_RX.Code = Tmp; pVfo->freq_config_RX.Code = tmp;
Tmp = Data[1]; tmp = data[1];
switch (gEeprom.VfoInfo[VFO].freq_config_TX.CodeType) switch (pVfo->freq_config_TX.CodeType)
{ {
default: default:
case CODE_TYPE_OFF: case CODE_TYPE_OFF:
gEeprom.VfoInfo[VFO].freq_config_TX.CodeType = CODE_TYPE_OFF; pVfo->freq_config_TX.CodeType = CODE_TYPE_OFF;
Tmp = 0; tmp = 0;
break; break;
case CODE_TYPE_CONTINUOUS_TONE: case CODE_TYPE_CONTINUOUS_TONE:
if (Tmp > (ARRAY_SIZE(CTCSS_Options) - 1)) if (tmp > (ARRAY_SIZE(CTCSS_Options) - 1))
Tmp = 0; tmp = 0;
break; break;
case CODE_TYPE_DIGITAL: case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL: case CODE_TYPE_REVERSE_DIGITAL:
if (Tmp > (ARRAY_SIZE(DCS_Options) - 1)) if (tmp > (ARRAY_SIZE(DCS_Options) - 1))
Tmp = 0; tmp = 0;
break; 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; pVfo->FrequencyReverse = false;
gEeprom.VfoInfo[VFO].CHANNEL_BANDWIDTH = BK4819_FILTER_BW_WIDE; pVfo->CHANNEL_BANDWIDTH = BK4819_FILTER_BW_WIDE;
gEeprom.VfoInfo[VFO].OUTPUT_POWER = OUTPUT_POWER_LOW; pVfo->OUTPUT_POWER = OUTPUT_POWER_LOW;
gEeprom.VfoInfo[VFO].BUSY_CHANNEL_LOCK = false; pVfo->BUSY_CHANNEL_LOCK = false;
} }
else else
{ {
const uint8_t d4 = Data[4]; const uint8_t d4 = data[4];
gEeprom.VfoInfo[VFO].FrequencyReverse = !!((d4 >> 0) & 1u); pVfo->FrequencyReverse = !!((d4 >> 0) & 1u);
gEeprom.VfoInfo[VFO].CHANNEL_BANDWIDTH = !!((d4 >> 1) & 1u); pVfo->CHANNEL_BANDWIDTH = !!((d4 >> 1) & 1u);
gEeprom.VfoInfo[VFO].OUTPUT_POWER = ((d4 >> 2) & 3u); pVfo->OUTPUT_POWER = ((d4 >> 2) & 3u);
gEeprom.VfoInfo[VFO].BUSY_CHANNEL_LOCK = !!((d4 >> 4) & 1u); pVfo->BUSY_CHANNEL_LOCK = !!((d4 >> 4) & 1u);
} }
if (Data[5] == 0xFF) if (data[5] == 0xFF)
{ {
gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = false; pVfo->DTMF_DECODING_ENABLE = false;
gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = PTT_ID_OFF; pVfo->DTMF_PTT_ID_TX_MODE = PTT_ID_OFF;
} }
else else
{ {
gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = ((Data[5] >> 0) & 1u) ? true : false; pVfo->DTMF_DECODING_ENABLE = ((data[5] >> 0) & 1u) ? true : false;
gEeprom.VfoInfo[VFO].DTMF_PTT_ID_TX_MODE = ((Data[5] >> 1) & 7u); pVfo->DTMF_PTT_ID_TX_MODE = ((data[5] >> 1) & 7u);
} }
// *************** // ***************
struct struct {
{
uint32_t Frequency; uint32_t Frequency;
uint32_t Offset; 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)); if (info.Offset >= 100000000)
info.Offset = 1000000;
pRadio->freq_config_RX.Frequency = Info.Frequency; pVfo->TX_OFFSET_FREQUENCY = info.Offset;
if (Info.Offset >= 100000000)
Info.Offset = 1000000;
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY = Info.Offset;
// *************** // ***************
} }
Frequency = pRadio->freq_config_RX.Frequency; uint32_t frequency = pVfo->freq_config_RX.Frequency;
// fix previously set incorrect band // fix previously set incorrect band
Band = FREQUENCY_GetBand(Frequency); band = FREQUENCY_GetBand(frequency);
if (Frequency < frequencyBandTable[Band].lower) if (frequency < frequencyBandTable[band].lower)
Frequency = frequencyBandTable[Band].lower; frequency = frequencyBandTable[band].lower;
else else if (frequency > frequencyBandTable[band].upper)
if (Frequency > frequencyBandTable[Band].upper) frequency = frequencyBandTable[band].upper;
Frequency = frequencyBandTable[Band].upper; else if (channel >= FREQ_CHANNEL_FIRST)
else frequency = FREQUENCY_RoundToStep(frequency, pVfo->StepFrequency);
if (Channel >= FREQ_CHANNEL_FIRST)
Frequency = FREQUENCY_RoundToStep(Frequency, gEeprom.VfoInfo[VFO].StepFrequency);
pRadio->freq_config_RX.Frequency = Frequency; pVfo->freq_config_RX.Frequency = frequency;
if (Frequency >= frequencyBandTable[BAND2_108MHz].upper && Frequency < frequencyBandTable[BAND2_108MHz].upper) if (frequency >= frequencyBandTable[BAND2_108MHz].upper && frequency < frequencyBandTable[BAND2_108MHz].upper)
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF; pVfo->TX_OFFSET_FREQUENCY_DIRECTION = TX_OFFSET_FREQUENCY_DIRECTION_OFF;
else if (!IS_MR_CHANNEL(Channel)) else if (!IS_MR_CHANNEL(channel))
gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY = FREQUENCY_RoundToStep(gEeprom.VfoInfo[VFO].TX_OFFSET_FREQUENCY, gEeprom.VfoInfo[VFO].StepFrequency); 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)); memset(pVfo->Name, 0, sizeof(pVfo->Name));
if (IS_MR_CHANNEL(Channel)) if (IS_MR_CHANNEL(channel))
{ // 16 bytes allocated to the channel name but only 10 used, the rest are 0's { // 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(0x0F50 + (channel * 16), pVfo->Name + 0, 8);
EEPROM_ReadBuffer(0x0F58 + (Channel * 16), gEeprom.VfoInfo[VFO].Name + 8, 2); 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; pVfo->pRX = &pVfo->freq_config_RX;
gEeprom.VfoInfo[VFO].pTX = &gEeprom.VfoInfo[VFO].freq_config_TX; pVfo->pTX = &pVfo->freq_config_TX;
} }
else else
{ {
gEeprom.VfoInfo[VFO].pRX = &gEeprom.VfoInfo[VFO].freq_config_TX; pVfo->pRX = &pVfo->freq_config_TX;
gEeprom.VfoInfo[VFO].pTX = &gEeprom.VfoInfo[VFO].freq_config_RX; pVfo->pTX = &pVfo->freq_config_RX;
} }
if (!gSetting_350EN) if (!gSetting_350EN)
{ {
FREQ_Config_t *pConfig = gEeprom.VfoInfo[VFO].pRX; FREQ_Config_t *pConfig = pVfo->pRX;
if (pConfig->Frequency >= 35000000 && pConfig->Frequency < 40000000) if (pConfig->Frequency >= 35000000 && pConfig->Frequency < 40000000)
pConfig->Frequency = 43300000; pConfig->Frequency = 43300000;
} }
if (gEeprom.VfoInfo[VFO].Modulation != MODULATION_FM) if (pVfo->Modulation != MODULATION_FM)
{ // freq/chan is in AM mode { // freq/chan is in AM mode
gEeprom.VfoInfo[VFO].SCRAMBLING_TYPE = 0; pVfo->SCRAMBLING_TYPE = 0;
// gEeprom.VfoInfo[VFO].DTMF_DECODING_ENABLE = false; // no reason to disable DTMF decoding, aircraft use it on SSB // pVfo->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; pVfo->freq_config_RX.CodeType = CODE_TYPE_OFF;
gEeprom.VfoInfo[VFO].freq_config_TX.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) void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo)

View File

@@ -23,13 +23,6 @@
#include "dcs.h" #include "dcs.h"
#include "frequencies.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 { enum {
RADIO_CHANNEL_UP = 0x01u, RADIO_CHANNEL_UP = 0x01u,
RADIO_CHANNEL_DOWN = 0xFFu, RADIO_CHANNEL_DOWN = 0xFFu,

View File

@@ -263,55 +263,45 @@ void SETTINGS_SaveBatteryCalibration(const uint16_t * batteryCalibration)
EEPROM_WriteBuffer(0x1F48, buf); 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 #ifdef ENABLE_NOAA
if (!IS_NOAA_CHANNEL(Channel)) if (!IS_NOAA_CHANNEL(channel))
#endif #endif
{ {
uint8_t State[8]; uint8_t state[8];
uint8_t Attributes = 0xFF; // default attributes ChannelAttributes_t att = {
uint16_t Offset = 0x0D60 + (Channel & ~7u); .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) {
att.band = pVFO->Band;
if (keep) att.scanlist1 = pVFO->SCANLIST1_PARTICIPATION;
{ att.scanlist2 = pVFO->SCANLIST2_PARTICIPATION;
Attributes = (pVFO->SCANLIST1_PARTICIPATION << 7) | (pVFO->SCANLIST2_PARTICIPATION << 6) | (pVFO->Compander << 4) | (pVFO->Band << 0); att.compander = pVFO->Compander;
if (State[Channel & 7u] == Attributes) if (state[channel & 7u] == att.__val)
return; // no change in the attributes 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; if (IS_MR_CHANNEL(channel)) { // it's a memory channel
const uint16_t OffsetMR = channel * 16;
// #ifndef ENABLE_KEEP_MEM_NAME if (!keep) {
if (IS_MR_CHANNEL(Channel)) // clear/reset the channel name
{ // it's a memory channel memset(&state, 0x00, sizeof(state));
EEPROM_WriteBuffer(0x0F50 + OffsetMR, state);
const uint16_t OffsetMR = Channel * 16; EEPROM_WriteBuffer(0x0F58 + OffsetMR, state);
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);
// }
}
// #endif
} }
} }

View File

@@ -127,9 +127,9 @@ enum CHANNEL_DisplayMode_t {
typedef enum CHANNEL_DisplayMode_t CHANNEL_DisplayMode_t; typedef enum CHANNEL_DisplayMode_t CHANNEL_DisplayMode_t;
typedef struct { typedef struct {
uint8_t ScreenChannel[2]; uint8_t ScreenChannel[2]; // current channels set in the radio (memory or frequency channels)
uint8_t FreqChannel[2]; uint8_t FreqChannel[2]; // last frequency channels used
uint8_t MrChannel[2]; uint8_t MrChannel[2]; // last memory channels used
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
uint8_t NoaaChannel[2]; uint8_t NoaaChannel[2];
#endif #endif
@@ -254,6 +254,6 @@ void SETTINGS_SaveVfoIndices(void);
void SETTINGS_SaveSettings(void); void SETTINGS_SaveSettings(void);
void SETTINGS_SaveChannel(uint8_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode); 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_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 #endif

View File

@@ -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)); if(black)
gFrameBuffer[y/8][x] |= black << (y%8); buffer[y/8][x] |= 1 << (y%8);
else
buffer[y/8][x] &= ~(1 << (y%8));
} }
static void sort(int16_t *a, int16_t *b) 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) { if(x2==x1) {
sort(&y1, &y2); sort(&y1, &y2);
for(int16_t i = y1; i <= y2; i++) { for(int16_t i = y1; i <= y2; i++) {
UI_DrawPixel(x1, i, black); UI_DrawPixelBuffer(buffer, x1, i, black);
} }
} else { } else {
const int multipl = 1000; 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); sort(&x1, &x2);
for(int i = x1; i<= x2; i++) 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_DrawLineBuffer(buffer, x1,y1, x1,y2, black);
UI_DrawLine(x1,y1, x2,y1, black); UI_DrawLineBuffer(buffer, x1,y1, x2,y1, black);
UI_DrawLine(x2,y1, x2,y2, black); UI_DrawLineBuffer(buffer, x2,y1, x2,y2, black);
UI_DrawLine(x1,y2, x2,y2, black); UI_DrawLineBuffer(buffer, x1,y2, x2,y2, black);
} }
void UI_DisplayPopup(const char *string) void UI_DisplayPopup(const char *string)
@@ -234,13 +236,13 @@ void UI_DisplayPopup(const char *string)
// } // }
// for(uint8_t x = 10; x < 118; x++) { // for(uint8_t x = 10; x < 118; x++) {
// UI_DrawPixel(x, 10, true); // UI_DrawPixelBuffer(x, 10, true);
// UI_DrawPixel(x, 46-9, true); // UI_DrawPixelBuffer(x, 46-9, true);
// } // }
// for(uint8_t y = 11; y < 37; y++) { // for(uint8_t y = 11; y < 37; y++) {
// UI_DrawPixel(10, y, true); // UI_DrawPixelBuffer(10, y, true);
// UI_DrawPixel(117, y, true); // UI_DrawPixelBuffer(117, y, true);
// } // }
// DrawRectangle(9,9, 118,38, true); // DrawRectangle(9,9, 118,38, true);
UI_PrintString(string, 9, 118, 2, 8); UI_PrintString(string, 9, 118, 2, 8);

View File

@@ -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_DisplayPopup(const char *string);
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);
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);
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);

View File

@@ -169,8 +169,18 @@ static void DisplayRSSIBar(const int16_t rssi, const bool now)
if (now) if (now)
memset(p_line, 0, LCD_WIDTH); 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 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 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); 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); UI_PrintString(String, 32, 0, line, 8);
} }
break; continue;
} }
else else
{ {
@@ -447,15 +457,15 @@ void UI_DisplayMain(void)
{ // it's a channel { // it's a channel
// show the scan list assigment symbols // show the scan list assigment symbols
const uint8_t attributes = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
if (attributes & MR_CH_SCANLIST1) if (att.scanlist1)
memmove(p_line0 + 113, BITMAP_ScanList1, sizeof(BITMAP_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)); memmove(p_line0 + 120, BITMAP_ScanList2, sizeof(BITMAP_ScanList2));
// compander symbol // compander symbol
#ifndef ENABLE_BIG_FREQ #ifndef ENABLE_BIG_FREQ
if ((attributes & MR_CH_COMPAND) > 0) if (att.compander)
memmove(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand)); memmove(p_line0 + 120 + LCD_WIDTH, BITMAP_compand, sizeof(BITMAP_compand));
#else #else
// TODO: // find somewhere else to put the symbol // TODO: // find somewhere else to put the symbol
@@ -533,8 +543,8 @@ void UI_DisplayMain(void)
} }
// show the channel symbols // show the channel symbols
const uint8_t attributes = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]]; const ChannelAttributes_t att = gMR_ChannelAttributes[gEeprom.ScreenChannel[vfo_num]];
if ((attributes & MR_CH_COMPAND) > 0) if (att.compander)
#ifdef ENABLE_BIG_FREQ #ifdef ENABLE_BIG_FREQ
memmove(p_line0 + 120, BITMAP_compand, sizeof(BITMAP_compand)); memmove(p_line0 + 120, BITMAP_compand, sizeof(BITMAP_compand));
#else #else