diff --git a/Makefile b/Makefile index 68d04b8..bcb9b06 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ ENABLE_COMPANDER := 1 ENABLE_SHOW_CHARGE_LEVEL := 0 ENABLE_REVERSE_BAT_SYMBOL := 1 ENABLE_AM_FIX := 1 +ENABLE_AM_FIX_SHOW_DATA := 1 ENABLE_SQUELCH1_LOWER := 1 ENABLE_AUDIO_BAR := 0 #ENABLE_SINGLE_VFO_CHAN := 1 @@ -87,6 +88,9 @@ OBJS += app/scanner.o ifeq ($(ENABLE_UART),1) OBJS += app/uart.o endif +ifeq ($(ENABLE_AM_FIX),1) + OBJS += am_fix.o +endif OBJS += audio.o OBJS += bitmaps.o OBJS += board.o @@ -201,6 +205,9 @@ endif ifeq ($(ENABLE_AM_FIX),1) CFLAGS += -DENABLE_AM_FIX endif +ifeq ($(ENABLE_AM_FIX_SHOW_DATA),1) + CFLAGS += -DENABLE_AM_FIX_SHOW_DATA +endif ifeq ($(ENABLE_SQUELCH1_LOWER),1) CFLAGS += -DENABLE_SQUELCH1_LOWER endif diff --git a/README.md b/README.md index bd94fa5..6900a99 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ ENABLE_COMPANDER := 1 compander option (per channel) ENABLE_SHOW_CHARGE_LEVEL := 1 show the charge level when the radio is on charge ENABLE_REVERSE_BAT_SYMBOL := 1 mirror the battery symbol on the status bar (+ pole on the right) ENABLE_AM_FIX := 1 dynamically adjust the front end gains when in AM mode to helo prevent AM demodulator saturation - ignore the on-screen RSSI (for now) +ENABLE_AM_FIX_SHOW_DATA := 1 show debug data for the AM fix ENABLE_SQUELCH1_LOWER := 1 adjusts squelch setting '1' to be more sensitive - I plan to let user adjust it in the menu ENABLE_AUDIO_BAR := 0 experimental, display an audo bar level when TX'ing #ENABLE_SINGLE_VFO_CHAN := 1 not yet implemented - single VFO on display when possible diff --git a/am_fix.c b/am_fix.c new file mode 100644 index 0000000..60eb246 --- /dev/null +++ b/am_fix.c @@ -0,0 +1,306 @@ + +#include + +#include "app/generic.h" +#include "app/main.h" +#include "ARMCM0.h" +#include "am_fix.h" +#include "board.h" +#include "driver/bk4819.h" +#include "driver/system.h" +#ifdef ENABLE_AM_FIX_SHOW_DATA + #include "external/printf/printf.h" +#endif +#include "frequencies.h" +#include "functions.h" +#include "misc.h" +#include "ui/rssi.h" + +// original QS front end gain settings +const uint8_t orig_lna_short = 3; // 0dB +const uint8_t orig_lna = 2; // -14dB +const uint8_t orig_mixer = 3; // 0dB +const uint8_t orig_pga = 6; // -3dB + +#ifdef ENABLE_AM_FIX + // stuff to overcome the AM demodulator saturation problem + // + // that is until someone works out how to properly configure the BK chip !! + + // REG_10 AGC gain table + // + // <15:10> ??? + // + // <9:8> = LNA Gain Short + // 3 = 0dB < original value + // 2 = -11dB + // 1 = -16dB + // 0 = -19dB + // + // <7:5> = LNA Gain + // 7 = 0dB + // 6 = -2dB + // 5 = -4dB + // 4 = -6dB + // 3 = -9dB + // 2 = -14dB < original value + // 1 = -19dB + // 0 = -24dB + // + // <4:3> = MIXER Gain + // 3 = 0dB < original value + // 2 = -3dB + // 1 = -6dB + // 0 = -8dB + // + // <2:0> = PGA Gain + // 7 = 0dB + // 6 = -3dB < original value + // 5 = -6dB + // 4 = -9dB + // 3 = -15dB + // 2 = -21dB + // 1 = -27dB + // 0 = -33dB + + // front end register dB values + const int8_t lna_short_dB[4] = {-19, -16, -11, 0}; + const int8_t lna_dB[8] = {-24, -19, -14, -9, -6, -4, -2, 0}; + const int8_t mixer_dB[4] = { -8, -6, -3, 0}; + const int8_t pga_dB[8] = {-33, -27, -21, -15, -9, -6, -3, 0}; + + // lookup table is by far easier than writing code to do the same + static const t_am_fix_gain_table am_fix_gain_table[] = + { + {.lna_short = 3, .lna = 2, .mixer = 3, .pga = 6}, // 0 0dB -14dB 0dB -3dB .. -17dB original + + {3, 0, 0, 0}, // 1 0dB -24dB -8dB -33dB .. -65dB + {3, 0, 1, 0}, // 2 0dB -24dB -6dB -33dB .. -63dB + {3, 0, 2, 0}, // 3 0dB -24dB -3dB -33dB .. -60dB + {3, 0, 0, 1}, // 4 0dB -24dB -8dB -27dB .. -59dB + {3, 1, 1, 0}, // 5 0dB -19dB -6dB -33dB .. -58dB + {3, 0, 1, 1}, // 6 0dB -24dB -6dB -27dB .. -57dB + {3, 1, 2, 0}, // 7 0dB -19dB -3dB -33dB .. -55dB + {3, 1, 0, 1}, // 8 0dB -19dB -8dB -27dB .. -54dB + {3, 0, 0, 2}, // 9 0dB -24dB -8dB -21dB .. -53dB + {3, 1, 1, 1}, // 10 0dB -19dB -6dB -27dB .. -52dB + {3, 0, 1, 2}, // 11 0dB -24dB -6dB -21dB .. -51dB + {3, 2, 2, 0}, // 12 0dB -14dB -3dB -33dB .. -50dB + {3, 2, 0, 1}, // 13 0dB -14dB -8dB -27dB .. -49dB + {3, 0, 2, 2}, // 14 0dB -24dB -3dB -21dB .. -48dB + {3, 2, 3, 0}, // 15 0dB -14dB 0dB -33dB .. -47dB + {3, 1, 3, 1}, // 16 0dB -19dB 0dB -27dB .. -46dB + {3, 0, 3, 2}, // 17 0dB -24dB 0dB -21dB .. -45dB + {3, 3, 0, 1}, // 18 0dB -9dB -8dB -27dB .. -44dB + {3, 1, 2, 2}, // 19 0dB -19dB -3dB -21dB .. -43dB + {3, 0, 2, 3}, // 20 0dB -24dB -3dB -15dB .. -42dB + {3, 0, 0, 4}, // 21 0dB -24dB -8dB -9dB .. -41dB + {3, 1, 1, 3}, // 22 0dB -19dB -6dB -15dB .. -40dB + {3, 0, 1, 4}, // 23 0dB -24dB -6dB -9dB .. -39dB + {3, 0, 0, 5}, // 24 0dB -24dB -8dB -6dB .. -38dB + {3, 1, 2, 3}, // 25 0dB -19dB -3dB -15dB .. -37dB + {3, 0, 2, 4}, // 26 0dB -24dB -3dB -9dB .. -36dB + {3, 4, 0, 2}, // 27 0dB -6dB -8dB -21dB .. -35dB + {3, 1, 1, 4}, // 28 0dB -19dB -6dB -9dB .. -34dB + {3, 1, 0, 5}, // 29 0dB -19dB -8dB -6dB .. -33dB + {3, 3, 0, 3}, // 30 0dB -9dB -8dB -15dB .. -32dB + {3, 5, 1, 2}, // 31 0dB -4dB -6dB -21dB .. -31dB + {3, 1, 0, 6}, // 32 0dB -19dB -8dB -3dB .. -30dB + {3, 2, 3, 3}, // 33 0dB -14dB 0dB -15dB .. -29dB + {3, 1, 1, 6}, // 34 0dB -19dB -6dB -3dB .. -28dB + {3, 4, 1, 3}, // 35 0dB -6dB -6dB -15dB .. -27dB + {3, 2, 2, 4}, // 36 0dB -14dB -3dB -9dB .. -26dB + {3, 1, 2, 6}, // 37 0dB -19dB -3dB -3dB .. -25dB + {3, 3, 1, 4}, // 38 0dB -9dB -6dB -9dB .. -24dB + {3, 2, 1, 6}, // 39 0dB -14dB -6dB -3dB .. -23dB + {3, 5, 2, 3}, // 40 0dB -4dB -3dB -15dB .. -22dB + {3, 4, 1, 4}, // 41 0dB -6dB -6dB -9dB .. -21dB + {3, 4, 0, 5}, // 42 0dB -6dB -8dB -6dB .. -20dB + {3, 5, 1, 4}, // 43 0dB -4dB -6dB -9dB .. -19dB + {3, 3, 3, 4}, // 44 0dB -9dB 0dB -9dB .. -18dB + {3, 2, 3, 6}, // 45 0dB -14dB 0dB -3dB .. -17dB original + {3, 5, 1, 5}, // 46 0dB -4dB -6dB -6dB .. -16dB + {3, 3, 3, 5}, // 47 0dB -9dB 0dB -6dB .. -15dB + {3, 2, 3, 7}, // 48 0dB -14dB 0dB 0dB .. -14dB + {3, 5, 1, 6}, // 49 0dB -4dB -6dB -3dB .. -13dB + {3, 4, 2, 6}, // 50 0dB -6dB -3dB -3dB .. -12dB + {3, 5, 2, 6}, // 51 0dB -4dB -3dB -3dB .. -10dB + {3, 4, 3, 6}, // 52 0dB -6dB 0dB -3dB .. -9dB + {3, 5, 2, 7}, // 53 0dB -4dB -3dB 0dB .. -7dB + {3, 4, 3, 7}, // 54 0dB -6dB 0dB 0dB .. -6dB + {3, 5, 3, 7} // 55 0dB -4dB 0dB 0dB .. -4dB + }; + + // table index that holds the original QS front end setting + const unsigned int original_index = 45; + + // current table index we're using + unsigned int am_fix_gain_table_index = original_index; // start with original QS setting + unsigned int am_fix_gain_table_index_prev = 0; + + // moving average RSSI buffer + // helps smooth out any spikey RSSI readings + struct { + unsigned int count; // + unsigned int index; // read/write buffer index + uint16_t samples[4]; // 40ms long buffer (10ms RSSI sample rate) + uint16_t sum; // sum of all samples in the buffer + } moving_avg_rssi = {0}; + + // used to prevent gain hunting, provides a peak hold time delay + unsigned int am_gain_hold_counter = 0; + + // used to correct the RSSI readings after our front end gain adjustments + int16_t rssi_db_gain_diff = 0; + + void AM_fix_reset(void) + { + // reset the moving average filter + memset(&moving_avg_rssi, 0, sizeof(moving_avg_rssi)); + + am_gain_hold_counter = 0; + + rssi_db_gain_diff = 0; + + am_fix_gain_table_index = original_index; // re-start with original QS setting + am_fix_gain_table_index_prev = 0; + } + + void AM_fix_adjust_frontEnd_10ms(void) + { + // we don't play with the front end gains if in FM mode + if (!gRxVfo->IsAM) + return; + + // we're in AM mode + + switch (gCurrentFunction) + { + case FUNCTION_TRANSMIT: + case FUNCTION_BAND_SCOPE: + case FUNCTION_POWER_SAVE: + return; + + // only adjust the front end if in one of these modes + case FUNCTION_FOREGROUND: + case FUNCTION_RECEIVE: + case FUNCTION_MONITOR: + case FUNCTION_INCOMING: + break; + } + + // -87dBm, any higher and the AM demodulator starts to saturate/clip (distort) + const uint16_t desired_rssi = (-87 + 160) * 2; // dBm to ADC sample +/* + // current RX frequency + const uint32_t rx_frequency = gRxVfo->pRX->Frequency; + + // max gains to use +// uint8_t max_lna_short = orig_lna_short; // we're not altering this one + uint8_t max_lna = orig_lna; + uint8_t max_mixer = orig_mixer; + uint8_t max_pga = orig_pga; + + if (rx_frequency <= 22640000) // the RX sensitivity abrutly drops above this frequency + { + max_pga = 7; + } + else + { // allow a bit more adjustment gain +// max_lna = 4; + max_lna = 7; + max_pga = 7; + } +*/ + // sample the current RSSI level + uint16_t rssi = BK4819_GetRSSI(); // 9-bit value (0 .. 511) + //gCurrentRSSI = rssi - (rssi_db_gain_diff * 2); + + // compute the moving average RSSI + if (moving_avg_rssi.count < ARRAY_SIZE(moving_avg_rssi.samples)) + moving_avg_rssi.count++; + moving_avg_rssi.sum -= moving_avg_rssi.samples[moving_avg_rssi.index]; // subtract the oldest sample + moving_avg_rssi.sum += rssi; // add the newest sample + moving_avg_rssi.samples[moving_avg_rssi.index] = rssi; // save the newest sample + if (++moving_avg_rssi.index >= ARRAY_SIZE(moving_avg_rssi.samples)) // + moving_avg_rssi.index = 0; // + rssi = moving_avg_rssi.sum / moving_avg_rssi.count; // compute the average of the past 'n' samples + + if (rssi > desired_rssi) + { // decrease gain + + if (am_fix_gain_table_index > 1) + am_fix_gain_table_index--; + + am_gain_hold_counter = 50; // 500ms + } + + if (am_gain_hold_counter > 0) + am_gain_hold_counter--; + + if (am_gain_hold_counter == 0) + { // hold has been released, we're now free to increase gain + + if (rssi < (desired_rssi - 10)) // 5dB hysterisis (helps prevent gain hunting) + { // increase gain + + if (am_fix_gain_table_index < (ARRAY_SIZE(am_fix_gain_table) - 1)) + am_fix_gain_table_index++; + } + } + + if (am_fix_gain_table_index == am_fix_gain_table_index_prev) + return; // no gain changes + + // apply the new gain settings to the front end + + // remember the new gain settings - for the next time this function is called + const uint16_t lna_short = am_fix_gain_table[am_fix_gain_table_index].lna_short; + const uint16_t lna = am_fix_gain_table[am_fix_gain_table_index].lna; + const uint16_t mixer = am_fix_gain_table[am_fix_gain_table_index].mixer; + const uint16_t pga = am_fix_gain_table[am_fix_gain_table_index].pga; + + BK4819_WriteRegister(BK4819_REG_13, (lna_short << 8) | (lna << 5) | (mixer << 3) | (pga << 0)); + + { // offset the RSSI reading to the rest of the firmware to cancel out the gain adjustments we've made here + static const int16_t orig_dB_gain = lna_short_dB[orig_lna_short & 3u] + lna_dB[orig_lna & 7u] + mixer_dB[orig_mixer & 3u] + pga_dB[orig_pga & 7u]; + const int16_t am_dB_gain = lna_short_dB[lna_short & 3u] + lna_dB[lna & 7u] + mixer_dB[mixer & 3u] + pga_dB[pga & 7u]; + + rssi_db_gain_diff = am_dB_gain - orig_dB_gain; + } + + am_fix_gain_table_index_prev = am_fix_gain_table_index; + + #ifdef ENABLE_AM_FIX_SHOW_DATA + gUpdateDisplay = true; + #endif + } + + #ifdef ENABLE_AM_FIX_SHOW_DATA + void AM_fix_print_data(char *s) + { + if (s == NULL) + return; + + const uint16_t lna_short = am_fix_gain_table[am_fix_gain_table_index].lna_short; + const uint16_t lna = am_fix_gain_table[am_fix_gain_table_index].lna; + const uint16_t mixer = am_fix_gain_table[am_fix_gain_table_index].mixer; + const uint16_t pga = am_fix_gain_table[am_fix_gain_table_index].pga; + + const int16_t am_dB_gain = lna_short_dB[lna_short & 3u] + lna_dB[lna & 7u] + mixer_dB[mixer & 3u] + pga_dB[pga & 7u]; + + #if 0 + sprintf(s, "%2d %3d %2d %3d %3d", + //am_fix_gain_table_index, + lna_short_dB[lna_short & 3u], + lna_dB[lna & 7u], + mixer_dB[mixer & 3u], + pga_dB[pga & 7u], + am_dB_gain); + #else + sprintf(s, "idx %2d gain %3ddB", am_fix_gain_table_index, am_dB_gain); + #endif + } + #endif + +#endif diff --git a/am_fix.h b/am_fix.h new file mode 100644 index 0000000..fb82631 --- /dev/null +++ b/am_fix.h @@ -0,0 +1,45 @@ + +#ifndef AM_FIXH + +#include +#include + +extern const uint8_t orig_lna_short; +extern const uint8_t orig_lna; +extern const uint8_t orig_mixer; +extern const uint8_t orig_pga; + +#ifdef ENABLE_AM_FIX + extern const int8_t lna_short_dB[4]; + extern const int8_t lna_dB[8]; + extern const int8_t mixer_dB[4]; + extern const int8_t pga_dB[8]; + + typedef struct + { + #if 1 + // bitfields take less flash bytes + uint8_t lna_short:2; // 0 ~ 3 + uint8_t lna:3; // 0 ~ 7 + uint8_t mixer:2; // 0 ~ 3 + uint8_t pga:3; // 0 ~ 7 + #else + uint8_t lna_short; // 0 ~ 3 + uint8_t lna; // 0 ~ 7 + uint8_t mixer; // 0 ~ 3 + uint8_t pga; // 0 ~ 7 + #endif + } t_am_fix_gain_table; +// } __attribute__((packed)) t_am_fix_gain_table; + + extern int16_t rssi_db_gain_diff; + + void AM_fix_reset(void); + void AM_fix_adjust_frontEnd_10ms(void); + #ifdef ENABLE_AM_FIX_SHOW_DATA + void AM_fix_print_data(char *s); + #endif + +#endif + +#endif diff --git a/app/app.c b/app/app.c index f837b86..f1ce84f 100644 --- a/app/app.c +++ b/app/app.c @@ -43,6 +43,7 @@ #include "driver/keyboard.h" #include "driver/st7565.h" #include "driver/system.h" +#include "am_fix.h" #include "dtmf.h" #include "external/printf/printf.h" #include "frequencies.h" @@ -62,160 +63,6 @@ #include "ui/status.h" #include "ui/ui.h" -// original QS front end gain settings -static const uint8_t orig_lna_short = 3; // 0dB -static const uint8_t orig_lna = 2; // -14dB -static const uint8_t orig_mixer = 3; // 0dB -static const uint8_t orig_pga = 6; // -3dB - -#ifdef ENABLE_AM_FIX - // stuff to overcome the AM demodulator saturation problem - // - // that is until someone works out how to properly configure the BK chip !! - - // REG_10 AGC gain table - // - // <15:10> ??? - // - // <9:8> = LNA Gain Short - // 3 = 0dB < original value - // 2 = -11dB - // 1 = -16dB - // 0 = -19dB - // - // <7:5> = LNA Gain - // 7 = 0dB - // 6 = -2dB - // 5 = -4dB - // 4 = -6dB - // 3 = -9dB - // 2 = -14dB < original value - // 1 = -19dB - // 0 = -24dB - // - // <4:3> = MIXER Gain - // 3 = 0dB < original value - // 2 = -3dB - // 1 = -6dB - // 0 = -8dB - // - // <2:0> = PGA Gain - // 7 = 0dB - // 6 = -3dB < original value - // 5 = -6dB - // 4 = -9dB - // 3 = -15dB - // 2 = -21dB - // 1 = -27dB - // 0 = -33dB - - // front end register dB values - static const int8_t lna_short_dB[] = {-19, -16, -11, 0}; - static const int8_t lna_dB[] = {-24, -19, -14, -9, -6, -4, -2, 0}; - static const int8_t mixer_dB[] = { -8, -6, -3, 0}; - static const int8_t pga_dB[] = {-33, -27, -21, -15, -9, -6, -3, 0}; - - typedef struct - { - uint8_t lna_short:2; // 0 ~ 3 - uint8_t lna:3; // 0 ~ 7 - uint8_t mixer:2; // 0 ~ 3 - uint8_t pga:3; // 0 ~ 7 - } t_am_fix_gain_table; -// } __attribute__((packed)) t_am_fix_gain_table; - - static const t_am_fix_gain_table am_fix_gain_table[] = - { - {.lna_short = 3, .lna = 2, .mixer = 3, .pga = 6}, // 0 0dB -14dB 0dB -3dB .. -17dB original - - {3, 0, 0, 0}, // 1 0dB -24dB -8dB -33dB .. -65dB - {3, 0, 1, 0}, // 2 0dB -24dB -6dB -33dB .. -63dB - {3, 0, 2, 0}, // 3 0dB -24dB -3dB -33dB .. -60dB - {3, 0, 0, 1}, // 4 0dB -24dB -8dB -27dB .. -59dB - {3, 1, 1, 0}, // 5 0dB -19dB -6dB -33dB .. -58dB - {3, 0, 1, 1}, // 6 0dB -24dB -6dB -27dB .. -57dB - {3, 1, 2, 0}, // 7 0dB -19dB -3dB -33dB .. -55dB - {3, 1, 0, 1}, // 8 0dB -19dB -8dB -27dB .. -54dB - {3, 0, 0, 2}, // 9 0dB -24dB -8dB -21dB .. -53dB - {3, 1, 1, 1}, // 10 0dB -19dB -6dB -27dB .. -52dB - {3, 0, 1, 2}, // 11 0dB -24dB -6dB -21dB .. -51dB - {3, 2, 2, 0}, // 12 0dB -14dB -3dB -33dB .. -50dB - {3, 2, 0, 1}, // 13 0dB -14dB -8dB -27dB .. -49dB - {3, 0, 2, 2}, // 14 0dB -24dB -3dB -21dB .. -48dB - {3, 2, 3, 0}, // 15 0dB -14dB 0dB -33dB .. -47dB - {3, 1, 3, 1}, // 16 0dB -19dB 0dB -27dB .. -46dB - {3, 0, 3, 2}, // 17 0dB -24dB 0dB -21dB .. -45dB - {3, 3, 0, 1}, // 18 0dB -9dB -8dB -27dB .. -44dB - {3, 1, 2, 2}, // 19 0dB -19dB -3dB -21dB .. -43dB - {3, 0, 2, 3}, // 20 0dB -24dB -3dB -15dB .. -42dB - {3, 0, 0, 4}, // 21 0dB -24dB -8dB -9dB .. -41dB - {3, 1, 1, 3}, // 22 0dB -19dB -6dB -15dB .. -40dB - {3, 0, 1, 4}, // 23 0dB -24dB -6dB -9dB .. -39dB - {3, 0, 0, 5}, // 24 0dB -24dB -8dB -6dB .. -38dB - {3, 1, 2, 3}, // 25 0dB -19dB -3dB -15dB .. -37dB - {3, 0, 2, 4}, // 26 0dB -24dB -3dB -9dB .. -36dB - {3, 4, 0, 2}, // 27 0dB -6dB -8dB -21dB .. -35dB - {3, 1, 1, 4}, // 28 0dB -19dB -6dB -9dB .. -34dB - {3, 1, 0, 5}, // 29 0dB -19dB -8dB -6dB .. -33dB - {3, 3, 0, 3}, // 30 0dB -9dB -8dB -15dB .. -32dB - {3, 5, 1, 2}, // 31 0dB -4dB -6dB -21dB .. -31dB - {3, 1, 0, 6}, // 32 0dB -19dB -8dB -3dB .. -30dB - {3, 2, 3, 3}, // 33 0dB -14dB 0dB -15dB .. -29dB - {3, 1, 1, 6}, // 34 0dB -19dB -6dB -3dB .. -28dB - {3, 4, 1, 3}, // 35 0dB -6dB -6dB -15dB .. -27dB - {3, 2, 2, 4}, // 36 0dB -14dB -3dB -9dB .. -26dB - {3, 1, 2, 6}, // 37 0dB -19dB -3dB -3dB .. -25dB - {3, 3, 1, 4}, // 38 0dB -9dB -6dB -9dB .. -24dB - {3, 2, 1, 6}, // 39 0dB -14dB -6dB -3dB .. -23dB - {3, 5, 2, 3}, // 40 0dB -4dB -3dB -15dB .. -22dB - {3, 4, 1, 4}, // 41 0dB -6dB -6dB -9dB .. -21dB - {3, 4, 0, 5}, // 42 0dB -6dB -8dB -6dB .. -20dB - {3, 5, 1, 4}, // 43 0dB -4dB -6dB -9dB .. -19dB - {3, 3, 3, 4}, // 44 0dB -9dB 0dB -9dB .. -18dB - {3, 2, 3, 6}, // 45 0dB -14dB 0dB -3dB .. -17dB original - {3, 5, 1, 5}, // 46 0dB -4dB -6dB -6dB .. -16dB - {3, 3, 3, 5}, // 47 0dB -9dB 0dB -6dB .. -15dB - {3, 2, 3, 7}, // 48 0dB -14dB 0dB 0dB .. -14dB - {3, 5, 1, 6}, // 49 0dB -4dB -6dB -3dB .. -13dB - {3, 4, 2, 6}, // 50 0dB -6dB -3dB -3dB .. -12dB - {3, 5, 2, 6}, // 51 0dB -4dB -3dB -3dB .. -10dB - {3, 4, 3, 6}, // 52 0dB -6dB 0dB -3dB .. -9dB - {3, 5, 2, 7}, // 53 0dB -4dB -3dB 0dB .. -7dB - {3, 4, 3, 7}, // 54 0dB -6dB 0dB 0dB .. -6dB - {3, 5, 3, 7} // 55 0dB -4dB 0dB 0dB .. -4dB - }; - - const unsigned int original_index = 45; - - unsigned int am_fix_gain_table_index = original_index; - unsigned int am_fix_gain_table_index_prev = 0; - - int16_t rssi_db_gain_diff = 0; // holds the compensation value to correct the RSSI reading - - // moving average RSSI buffer - struct { - unsigned int count; - unsigned int index; - uint16_t samples[4]; // 40ms long buffer (10ms RSSI sample rate) - uint16_t sum; // sum of all samples in the buffer - } moving_avg_rssi = {0}; - - unsigned int am_gain_hold_counter = 0; - - void APP_reset_AM_fix(void) - { - // reset the moving average filter - memset(&moving_avg_rssi, 0, sizeof(moving_avg_rssi)); - - am_gain_hold_counter = 0; - - rssi_db_gain_diff = 0; - - am_fix_gain_table_index = original_index; - am_fix_gain_table_index_prev = 0; - } -#endif - static void APP_ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); static void APP_CheckForIncoming(void) @@ -569,7 +416,7 @@ void APP_StartListening(FUNCTION_Type_t Function, const bool reset_am_fix) #ifdef ENABLE_AM_FIX if (reset_am_fix) - APP_reset_AM_fix(); // TODO: only reset it when moving channel/frequency + AM_fix_reset(); // TODO: only reset it when moving channel/frequency #endif gVFO_RSSI_bar_level[gEeprom.RX_CHANNEL == 0] = 0; @@ -1468,115 +1315,6 @@ void APP_CheckKeys(void) } } -#ifdef ENABLE_AM_FIX - - void adjust_AM_frontEnd_10ms(void) - { - // we don't play with the front end gains if in FM mode - if (!gRxVfo->IsAM) - return; - - // we're in AM mode - - switch (gCurrentFunction) - { - case FUNCTION_TRANSMIT: - case FUNCTION_BAND_SCOPE: - case FUNCTION_POWER_SAVE: - return; - - // only adjust the front end if in one of these modes - case FUNCTION_FOREGROUND: - case FUNCTION_RECEIVE: - case FUNCTION_MONITOR: - case FUNCTION_INCOMING: - break; - } - - // -87dBm, any higher and the AM demodulator starts to saturate/clip (distort) - const uint16_t desired_rssi = (-87 + 160) * 2; // dBm to ADC sample -/* - // current RX frequency - const uint32_t rx_frequency = gRxVfo->pRX->Frequency; - - // max gains to use -// uint8_t max_lna_short = orig_lna_short; // we're not altering this one - uint8_t max_lna = orig_lna; - uint8_t max_mixer = orig_mixer; - uint8_t max_pga = orig_pga; - - if (rx_frequency <= 22640000) // the RX sensitivity abrutly drops above this frequency - { - max_pga = 7; - } - else - { // allow a bit more adjustment gain -// max_lna = 4; - max_lna = 7; - max_pga = 7; - } -*/ - // sample the current RSSI level - uint16_t rssi = BK4819_GetRSSI(); // 9-bit value (0 .. 511) - //gCurrentRSSI = rssi - (rssi_db_gain_diff * 2); - - // compute the moving average RSSI - if (moving_avg_rssi.count < ARRAY_SIZE(moving_avg_rssi.samples)) - moving_avg_rssi.count++; - moving_avg_rssi.sum -= moving_avg_rssi.samples[moving_avg_rssi.index]; // subtract the oldest sample - moving_avg_rssi.sum += rssi; // add the newest sample - moving_avg_rssi.samples[moving_avg_rssi.index] = rssi; // save the newest sample - if (++moving_avg_rssi.index >= ARRAY_SIZE(moving_avg_rssi.samples)) // - moving_avg_rssi.index = 0; // - rssi = moving_avg_rssi.sum / moving_avg_rssi.count; // compute the average of the past 'n' samples - - if (rssi > desired_rssi) - { // decrease gain - - if (am_fix_gain_table_index > 1) - am_fix_gain_table_index--; - - am_gain_hold_counter = 50; // 500ms - } - - if (am_gain_hold_counter > 0) - am_gain_hold_counter--; - - if (am_gain_hold_counter == 0) - { // hold has been released, we're now free to increase gain - - if (rssi < (desired_rssi - 10)) // 5dB hysterisis (helps prevent gain hunting) - { // increase gain - - if (am_fix_gain_table_index < (ARRAY_SIZE(am_fix_gain_table) - 1)) - am_fix_gain_table_index++; - } - } - - if (am_fix_gain_table_index == am_fix_gain_table_index_prev) - return; // no gain changes - - // apply the new gain settings to the front end - - // remember the new gain settings - for the next time this function is called - const uint16_t lna_short = am_fix_gain_table[am_fix_gain_table_index].lna_short; - const uint16_t lna = am_fix_gain_table[am_fix_gain_table_index].lna; - const uint16_t mixer = am_fix_gain_table[am_fix_gain_table_index].mixer; - const uint16_t pga = am_fix_gain_table[am_fix_gain_table_index].pga; - - BK4819_WriteRegister(BK4819_REG_13, (lna_short << 8) | (lna << 5) | (mixer << 3) | (pga << 0)); - - { // offset the RSSI reading to the rest of the firmware to cancel out the gain adjustments we've made here - static const int16_t orig_dB_gain = lna_short_dB[orig_lna_short & 3u] + lna_dB[orig_lna & 7u] + mixer_dB[orig_mixer & 3u] + pga_dB[orig_pga & 7u]; - const int16_t am_dB_gain = lna_short_dB[lna_short & 3u] + lna_dB[lna & 7u] + mixer_dB[mixer & 3u] + pga_dB[pga & 7u]; - - rssi_db_gain_diff = am_dB_gain - orig_dB_gain; - } - - am_fix_gain_table_index_prev = am_fix_gain_table_index; - } -#endif - void APP_TimeSlice10ms(void) { gFlashLightBlinkCounter++; @@ -1589,7 +1327,7 @@ void APP_TimeSlice10ms(void) #ifdef ENABLE_AM_FIX if (gSetting_AM_fix) - adjust_AM_frontEnd_10ms(); + AM_fix_adjust_frontEnd_10ms(); #endif if (UART_IsCommandAvailable()) diff --git a/firmware b/firmware index 93dc904..328bba6 100644 Binary files a/firmware and b/firmware differ diff --git a/firmware.bin b/firmware.bin index 0238e3a..2b72c8a 100644 Binary files a/firmware.bin and b/firmware.bin differ diff --git a/firmware.packed.bin b/firmware.packed.bin index aca8caf..694d9dd 100644 Binary files a/firmware.packed.bin and b/firmware.packed.bin differ diff --git a/ui/main.c b/ui/main.c index 0847a13..b1aab31 100644 --- a/ui/main.c +++ b/ui/main.c @@ -17,6 +17,9 @@ #include #include "app/dtmf.h" +#ifdef ENABLE_AM_FIX_SHOW_DATA + #include "am_fix.h" +#endif #include "bitmaps.h" #include "board.h" #include "driver/bk4819.h" @@ -487,27 +490,32 @@ 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(); - - if (!gSetting_mic_bar) + #ifdef ENABLE_AM_FIX_SHOW_DATA + AM_fix_print_data(String); + UI_PrintStringSmall(String, 2, 0, 3); + #else + #ifdef ENABLE_AUDIO_BAR + UI_DisplayAudioBar(); + + 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 + } + } #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 - } - } } ST7565_BlitFullScreen();