AM fix update

This commit is contained in:
OneOfEleven 2023-09-22 13:52:17 +01:00
parent c5ca07e7e9
commit 17158231fb
7 changed files with 127 additions and 100 deletions

View File

@ -79,7 +79,7 @@ static void ACTION_Monitor(void)
RADIO_SetupRegisters(true);
APP_StartListening(FUNCTION_MONITOR);
APP_StartListening(FUNCTION_MONITOR, false);
return;
}

181
app/app.c
View File

@ -63,32 +63,37 @@
#include "ui/ui.h"
// original QS front end gains
static uint16_t lna_short = 3; // 0dB
static uint16_t lna = 2; // -14dB
static uint16_t mixer = 3; // 0dB
static uint16_t pga = 6; // -3dB
const uint16_t orig_lna_short = 3; // 0dB
const uint16_t orig_lna = 2; // -14dB
const uint16_t orig_mixer = 3; // 0dB
const uint16_t orig_pga = 6; // -3dB
#ifdef ENABLE_AM_FIX
// stuff to overcome the AM demodulator saturation problem
static uint16_t am_lna_short = orig_lna_short;
static uint16_t am_lna = orig_lna;
static uint16_t am_mixer = orig_mixer;
static uint16_t am_pga = orig_pga;
// moving average RSSI buffer
struct {
unsigned int count;
unsigned int index;
uint16_t samples[10]; // 100ms long buffer (10ms RSSI sample rate)
uint16_t samples[4]; // 40ms long buffer (10ms RSSI sample rate)
uint16_t sum; // sum of all samples in the buffer
} moving_avg_rssi;
unsigned int rssi_peak_hold_val = 0;
unsigned int rssi_peak_hold_count = 0;
unsigned int am_fix_increase_counter = 0;
void APP_reset_AM_fix(void)
{
// reset the moving average filter
memset(&moving_avg_rssi, 0, sizeof(moving_avg_rssi));
// reset the peak hold
rssi_peak_hold_val = 0;
rssi_peak_hold_count = 0;
am_fix_increase_counter = 0;
}
#endif
static void APP_ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
@ -218,7 +223,7 @@ static void APP_HandleIncoming(void)
}
}
APP_StartListening(FUNCTION_RECEIVE);
APP_StartListening(FUNCTION_RECEIVE, false);
}
static void APP_HandleReceive(void)
@ -432,7 +437,7 @@ static void APP_HandleFunction(void)
}
}
void APP_StartListening(FUNCTION_Type_t Function)
void APP_StartListening(FUNCTION_Type_t Function, const bool reset_am_fix)
{
if (gSetting_KILLED)
return;
@ -443,7 +448,8 @@ void APP_StartListening(FUNCTION_Type_t Function)
#endif
#ifdef ENABLE_AM_FIX
APP_reset_AM_fix();
if (reset_am_fix)
APP_reset_AM_fix(); // TODO: only reset it when moving channel/frequency
#endif
gVFO_RSSI_Level[gEeprom.RX_CHANNEL == 0] = 0;
@ -505,20 +511,16 @@ void APP_StartListening(FUNCTION_Type_t Function)
gUpdateStatus = true;
}
// original setting
uint16_t lna_short = orig_lna_short;
uint16_t lna = orig_lna;
uint16_t mixer = orig_mixer;
uint16_t pga = orig_pga;
if (gRxVfo->IsAM)
{ // AM
#ifdef ENABLE_AM_FIX
if (gSetting_AM_fix)
{ // original
lna_short = 3;
lna = 2;
mixer = 3;
pga = 6;
}
else
#endif
{
#ifndef ENABLE_AM_FIX
const uint32_t rx_frequency = gRxVfo->pRX->Frequency;
// the RX gain abrutly reduces above this frequency
@ -537,7 +539,7 @@ void APP_StartListening(FUNCTION_Type_t Function)
mixer = 3; // 3 original
pga = 7; // 6 original, 7 increased
}
}
#endif
// what do these 4 other gain settings do ???
//BK4819_WriteRegister(BK4819_REG_12, 0x037B); // 000000 11 011 11 011
@ -547,15 +549,6 @@ void APP_StartListening(FUNCTION_Type_t Function)
gNeverUsed = 0;
}
else
{ // FM
// original
lna_short = 3; // whats 'LNA short' mean ?
lna = 2;
mixer = 3;
pga = 6;
}
// apply the front end gain settings
BK4819_WriteRegister(BK4819_REG_13, (lna_short << 8) | (lna << 5) | (mixer << 3) | (pga << 0));
@ -1004,14 +997,14 @@ void APP_Update(void)
if (IS_FREQ_CHANNEL(gNextMrChannel))
{
if (gCurrentFunction == FUNCTION_INCOMING)
APP_StartListening(FUNCTION_RECEIVE);
APP_StartListening(FUNCTION_RECEIVE, true);
else
FREQ_NextChannel();
}
else
{
if (gCurrentCodeType == CODE_TYPE_OFF && gCurrentFunction == FUNCTION_INCOMING)
APP_StartListening(FUNCTION_RECEIVE);
APP_StartListening(FUNCTION_RECEIVE, true);
else
MR_NextChannel();
}
@ -1407,14 +1400,33 @@ void APP_CheckKeys(void)
// 1 = -27dB
// 0 = -33dB
// start with current settings
register uint16_t new_lna_short = lna_short;
register uint16_t new_lna = lna;
register uint16_t new_mixer = mixer;
register uint16_t new_pga = pga;
// -90dBm, any higher and the AM demodulator starts to saturate/clip (distort)
const uint16_t desired_rssi = (-90 + 160) * 2; // dBm to ADC sample
// -87dBm, any higher and the AM demodulator starts to saturate/clip (distort)
const uint16_t desired_rssi = (-87 + 160) * 2; // dBm to ADC sample
// start with current settings
register uint16_t new_lna_short = am_lna_short;
register uint16_t new_lna = am_lna;
register uint16_t new_mixer = am_mixer;
register uint16_t new_pga = am_pga;
// max gains to use
// uint16_t max_lna_short = orig_lna_short;
uint16_t max_lna = orig_lna;
uint16_t max_mixer = orig_mixer;
uint16_t max_pga = orig_pga;
const uint32_t rx_frequency = gRxVfo->pRX->Frequency;
// the RX gain abrutly reduces above this frequency
if (rx_frequency <= 22640000)
{
max_pga = 7;
}
else
{
max_lna = 5;
max_pga = 7;
}
// sample the current RSSI level
uint16_t rssi = BK4819_GetRSSI(); // 9-bit value (0 .. 511)
@ -1429,30 +1441,19 @@ void APP_CheckKeys(void)
if (++moving_avg_rssi.index >= ARRAY_SIZE(moving_avg_rssi.samples)) // next buffer slot
moving_avg_rssi.index = 0; // wrap-a-round
rssi = moving_avg_rssi.sum / moving_avg_rssi.count; // compute the average of the past 'n' samples
#if 1
if (rssi > rssi_peak_hold_val)
{ // enter hold mode (pause any gain increases)
rssi_peak_hold_val = rssi;
rssi_peak_hold_count = 10; // 100ms
}
else
if (rssi_peak_hold_count > 0)
rssi_peak_hold_count--;
else
rssi_peak_hold_val = rssi;
#endif
// the register adjustments below to be a bit more inteligent in order to obtain a consitant fine step size
// the register adjustments below to be more inteligent in order to maintain a good stable setting
if (rssi > desired_rssi)
{ // decrease gain
if (new_pga > 6)
if (new_pga > orig_pga)
new_pga--;
else
if (new_mixer > 3)
if (new_mixer > orig_mixer)
new_mixer--;
else
if (new_lna > 2)
if (new_lna > orig_lna)
new_lna--;
else
if (new_pga > 0)
@ -1466,41 +1467,55 @@ void APP_CheckKeys(void)
// else
// if (new_lna_short > 0)
// new_lna_short--;
am_fix_increase_counter = 50; // 500ms
}
if (moving_avg_rssi.index > 0)
{ // increase gain once every 100ms
if (am_fix_increase_counter > 0)
am_fix_increase_counter--;
if (am_fix_increase_counter == 0)
{ // increase gain
if (rssi_peak_hold_count == 0)
{
if (rssi < (desired_rssi - 7))
{ // increase gain
if (new_pga < 7)
new_pga++;
else
if (new_mixer < 3)
new_mixer++;
else
if (new_lna < 7)
new_lna++;
// else
// if (new_lna_short < 3)
// new_lna_short++;
if (rssi < (desired_rssi - 7))
{ // increase gain
if (new_pga < max_pga)
{
new_pga++;
am_fix_increase_counter = 10; // 100ms
}
else
if (new_mixer < max_mixer)
{
new_mixer++;
am_fix_increase_counter = 10; // 100ms
}
else
if (new_lna < max_lna)
{
new_lna++;
am_fix_increase_counter = 10; // 100ms
}
// else
// if (new_lna_short < max_lna_short)
// {
// new_lna_short++;
// am_fix_increase_counter = 10; // 100ms
// }
}
}
if (lna_short == new_lna_short && lna == new_lna && mixer == new_mixer && pga == new_pga)
if (am_lna_short == new_lna_short && am_lna == new_lna && am_mixer == new_mixer && am_pga == new_pga)
return; // no gain changes
// apply the new gain settings to the front end
lna_short = new_lna_short;
lna = new_lna;
mixer = new_mixer;
pga = new_pga;
am_lna_short = new_lna_short;
am_lna = new_lna;
am_mixer = new_mixer;
am_pga = new_pga;
BK4819_WriteRegister(BK4819_REG_13, (lna_short << 8) | (lna << 5) | (mixer << 3) | (pga << 0));
BK4819_WriteRegister(BK4819_REG_13, (am_lna_short << 8) | (am_lna << 5) | (am_mixer << 3) | (am_pga << 0));

View File

@ -23,7 +23,7 @@
void APP_EndTransmission(void);
void CHANNEL_Next(bool bFlag, int8_t Direction);
void APP_StartListening(FUNCTION_Type_t Function);
void APP_StartListening(FUNCTION_Type_t Function, const bool reset_am_fix);
void APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t Step);
void APP_Update(void);

BIN
firmware

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -46,6 +46,11 @@
#if 1
// TX audio level
// TODO: logify this to make the bar visible with the mostly small value
const uint16_t voice_amp = BK4819_GetVoiceAmplitudeOut(); // 15:0
const unsigned int max = 32767;
const unsigned int level = (((uint32_t)voice_amp * lcd_width) + (max / 2)) / max; // with rounding
@ -318,11 +323,13 @@ void UI_DisplayMain(void)
case MDF_NAME: // show the channel name
case MDF_NAME_FREQ: // show the channel name and frequency
BOARD_fetchChannelName(String, gEeprom.ScreenChannel[vfo_num]);
if (String[0] == 0)
{ // no channel name, show the channel number instead
sprintf(String, "CH-%03u", gEeprom.ScreenChannel[vfo_num] + 1);
}
if (gEeprom.CHANNEL_DISPLAY_MODE == MDF_NAME)
{
UI_PrintString(String, 32, 0, Line, 8);
@ -334,6 +341,7 @@ void UI_DisplayMain(void)
sprintf(String, "%03u.%05u", frequency / 100000, frequency % 100000);
UI_PrintStringSmall(String, 32 + 4, 0, Line + 1);
}
break;
}
}
@ -477,24 +485,28 @@ void UI_DisplayMain(void)
}
if (center_line_is_free)
{
{ // we're free to use the middle empty line for something
#ifdef ENABLE_AUDIO_BAR
UI_DisplayAudioBar();
#endif
if (gSetting_live_DTMF_decoder && gDTMF_ReceivedSaved[0] >= 32)
{ // show live DTMF decode
UI_PrintStringSmall(gDTMF_ReceivedSaved, 8, 0, 3);
}
else
if (gChargingWithTypeC)
{ // charging .. show the battery state
#ifdef ENABLE_SHOW_CHARGE_LEVEL
const uint16_t volts = (gBatteryVoltageAverage < gMin_bat_v) ? gMin_bat_v : gBatteryVoltageAverage;
const uint16_t percent = (100 * (volts - gMin_bat_v)) / (gMax_bat_v - gMin_bat_v);
sprintf(String, "Charge %u.%02uV %u%%", gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100, percent);
UI_PrintStringSmall(String, 2, 0, 3);
#endif
if (!gSetting_mic_bar)
#endif
{
if (gSetting_live_DTMF_decoder && gDTMF_ReceivedSaved[0] >= 32)
{ // show live DTMF decode
UI_PrintStringSmall(gDTMF_ReceivedSaved, 8, 0, 3);
}
else
if (gChargingWithTypeC)
{ // charging .. show the battery state
#ifdef ENABLE_SHOW_CHARGE_LEVEL
const uint16_t volts = (gBatteryVoltageAverage < gMin_bat_v) ? gMin_bat_v : gBatteryVoltageAverage;
const uint16_t percent = (100 * (volts - gMin_bat_v)) / (gMax_bat_v - gMin_bat_v);
sprintf(String, "Charge %u.%02uV %u%%", gBatteryVoltageAverage / 100, gBatteryVoltageAverage % 100, percent);
UI_PrintStringSmall(String, 2, 0, 3);
#endif
}
}
}