diff --git a/Makefile b/Makefile index 8bad7b4..12d757e 100644 --- a/Makefile +++ b/Makefile @@ -51,8 +51,9 @@ ENABLE_TX_WHEN_AM := 0 # Freq calibration 188 B ENABLE_F_CAL_MENU := 0 ENABLE_TX_UNLOCK_MENU := 0 -ENABLE_TX_POWER_CAL_MENU := 0 -ENABLE_FIX_TX_POWER := 1 +#ENABLE_TX_POWER_CAL_MENU := 0 +ENABLE_TX_POWER_FIX := 1 +ENABLE_TX_POWER_LOW_USER := 0 ENABLE_CTCSS_TAIL_PHASE_SHIFT := 1 ENABLE_CONTRAST := 0 ENABLE_BOOT_BEEPS := 0 @@ -355,8 +356,11 @@ endif ifeq ($(ENABLE_VOX_MORE_SENSITIVE),1) CFLAGS += -DENABLE_VOX_MORE_SENSITIVE endif -ifeq ($(ENABLE_FIX_TX_POWER),1) - CFLAGS += -DENABLE_FIX_TX_POWER +ifeq ($(ENABLE_TX_POWER_FIX),1) + CFLAGS += -DENABLE_TX_POWER_FIX +endif +ifeq ($(ENABLE_TX_POWER_LOW_USER),1) + CFLAGS += -DENABLE_TX_POWER_LOW_USER endif ifeq ($(ENABLE_ALARM),1) CFLAGS += -DENABLE_ALARM diff --git a/README.md b/README.md index 2152a57..e61ac11 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,8 @@ ENABLE_TX_WHEN_AM := 0 allow TX (always FM) when RX is set ENABLE_F_CAL_MENU := 0 enable frequency calibration hidden menu ENABLE_TX_UNLOCK_MENU := 0 allow TX everywhere EXCEPT airband (108~137) .. TX harmonic content will cause interference to other services, do so entirely at your own risk ! ENABLE_TX_POWER_CAL_MENU := 0 used to compute the TX power register values .. leave at '0' -ENABLE_FIX_TX_POWER := 1 fix the TX output power, L ~ 10mW, M ~ 500mW, H ~ 4W +ENABLE_TX_POWER_FIX := 1 fix the TX output power, L ~ 10mW, M ~ 500mW, H ~ 4W +ENABLE_TX_POWER_LOW_USER := 1 make the low power setting user settable - adds "TxPUSR" menu option ENABLE_CTCSS_TAIL_PHASE_SHIFT := 0 standard CTCSS tail phase shift rather than QS's own 55Hz tone method ENABLE_CONTRAST := 0 add contrast menu ENABLE_BOOT_BEEPS := 0 gives user audio feedback on volume knob position at boot-up diff --git a/app/menu.c b/app/menu.c index a3681b6..00301d0 100644 --- a/app/menu.c +++ b/app/menu.c @@ -120,6 +120,13 @@ int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax) *pMax = ARRAY_SIZE(g_sub_menu_mem_disp) - 1; break; + #ifdef ENABLE_TX_POWER_LOW_USER + case MENU_TX_POWER_LOW_USER: + *pMin = 0; + *pMax = 15; + break; + #endif + case MENU_TX_POWER: *pMin = 0; *pMax = ARRAY_SIZE(g_sub_menu_tx_power) - 1; @@ -430,6 +437,13 @@ void MENU_AcceptSetting(void) g_request_save_channel = 1; return; + #ifdef ENABLE_TX_POWER_LOW_USER + case MENU_TX_POWER_LOW_USER: + g_tx_vfo->channel.tx_pwr_user = g_sub_menu_selection; + g_request_save_channel = 1; + break; + #endif + case MENU_TX_POWER: g_tx_vfo->channel.tx_power = g_sub_menu_selection; g_request_save_channel = 1; @@ -905,7 +919,7 @@ void MENU_AcceptSetting(void) RADIO_ConfigureTXPower(g_current_vfo); if (g_current_function == FUNCTION_TRANSMIT && g_current_display_screen != DISPLAY_AIRCOPY) - BK4819_SetupPowerAmplifier(g_current_vfo->txp_calculated_setting, g_current_vfo->p_tx->frequency); + BK4819_SetupPowerAmplifier(g_current_vfo->txp_reg_value, g_current_vfo->p_tx->frequency); } break; #endif @@ -1008,6 +1022,12 @@ void MENU_ShowCurrentSetting(void) g_sub_menu_selection = FREQUENCY_get_step_index(STEP_FREQ_TABLE[g_tx_vfo->channel.step_setting]); break; + #ifdef ENABLE_TX_POWER_LOW_USER + case MENU_TX_POWER_LOW_USER: + g_sub_menu_selection = g_tx_vfo->channel.tx_pwr_user; + break; + #endif + case MENU_TX_POWER: g_sub_menu_selection = g_tx_vfo->channel.tx_power; break; diff --git a/driver/bk4819.c b/driver/bk4819.c index 54c964e..7398f15 100644 --- a/driver/bk4819.c +++ b/driver/bk4819.c @@ -28,6 +28,7 @@ #ifdef ENABLE_MDC1200 #include "mdc1200.h" #endif +#include "settings.h" #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) @@ -735,9 +736,9 @@ void BK4819_SetCompander(const unsigned int mode) const uint16_t r31 = BK4819_read_reg(0x31); - if (mode == 0) + if (mode == COMPAND_OFF) { // disable - BK4819_write_reg(0x31, r31 & ~(1u << 3)); + BK4819_write_reg(0x31, r31 & ~(1ul << 3)); return; } @@ -753,7 +754,7 @@ void BK4819_SetCompander(const unsigned int mode) // // <6:0> 64 Compress (AF Tx) noise point (dB) // - const uint16_t compress_ratio = (mode == 1 || mode >= 3) ? 2 : 0; // 2:1 + const uint16_t compress_ratio = (mode == COMPAND_TX || mode == COMPAND_TX_RX) ? 2 : 0; // 2:1 BK4819_write_reg(0x29, // (BK4819_read_reg(0x29) & ~(3u << 14)) | (compress_ratio << 14)); (compress_ratio << 14) | (86u << 7) | // compress 0dB @@ -771,7 +772,7 @@ void BK4819_SetCompander(const unsigned int mode) // // <6:0> 56 Expander (AF Rx) noise point (dB) // - const uint16_t expand_ratio = (mode >= 2) ? 1 : 0; // 1:2 + const uint16_t expand_ratio = (mode == COMPAND_RX || mode == COMPAND_TX_RX) ? 1 : 0; // 1:2 BK4819_write_reg(0x28, // (BK4819_read_reg(0x28) & ~(3u << 14)) | (expand_ratio << 14)); (expand_ratio << 14) | (86u << 7) | // expander 0dB diff --git a/firmware.bin b/firmware.bin index 716ca43..504ef6c 100644 Binary files a/firmware.bin and b/firmware.bin differ diff --git a/firmware.packed.bin b/firmware.packed.bin index d3a72ed..07afd6c 100644 Binary files a/firmware.packed.bin and b/firmware.packed.bin differ diff --git a/frequencies.c b/frequencies.c index 1c97268..b1f9ea4 100644 --- a/frequencies.c +++ b/frequencies.c @@ -72,9 +72,9 @@ const freq_band_table_t FREQ_BAND_TABLE[7] = // the first 7 values MUST remain in those same positions // so as to remain compatible with the QS config software // -const uint16_t STEP_FREQ_TABLE[21] = { +const uint16_t STEP_FREQ_TABLE[16] = { 250, 500, 625, 1000, 1250, 2500, 833, - 1, 5, 10, 25, 50, 100, 125, 1500, 3000, 5000, 10000, 12500, 25000, 50000 + 10, 25, 50, 100, 125, 1500, 3000, 5000, 10000 }; // the above step sizes will be sorted to appear to be in order to the user diff --git a/frequencies.h b/frequencies.h index cf1411d..70893f5 100644 --- a/frequencies.h +++ b/frequencies.h @@ -81,7 +81,7 @@ enum step_setting_e { }; typedef enum step_setting_e step_setting_t; -extern const uint16_t STEP_FREQ_TABLE[21]; +extern const uint16_t STEP_FREQ_TABLE[16]; extern uint16_t step_freq_table_sorted[ARRAY_SIZE(STEP_FREQ_TABLE)]; #ifdef ENABLE_NOAA diff --git a/radio.c b/radio.c index be9f3dc..f48fef5 100644 --- a/radio.c +++ b/radio.c @@ -143,7 +143,7 @@ void RADIO_InitInfo(vfo_info_t *p_vfo, const uint8_t ChannelSave, const uint32_t p_vfo->freq_config_tx.frequency = Frequency; p_vfo->p_rx = &p_vfo->freq_config_rx; p_vfo->p_tx = &p_vfo->freq_config_tx; - p_vfo->channel.compand = 0; // off + p_vfo->channel.compand = COMPAND_OFF; p_vfo->channel.squelch_level = 0; // use main squelch p_vfo->freq_in_channel = 0xff; @@ -575,59 +575,67 @@ void RADIO_ConfigureTXPower(vfo_info_t *p_vfo) memcpy(tx_power, g_eeprom.calib.tx_band_power[band].level[p_vfo->channel.tx_power], 3); - #if defined(ENABLE_FIX_TX_POWER) && !defined(ENABLE_TX_POWER_CAL_MENU) - switch (p_vfo->channel.tx_power) - { - case OUTPUT_POWER_LOW: // ~ 10mW -// if (p_vfo->p_tx->frequency <= 26000000) -// { // 137 ~ 174 -// tx_power[0] = 0x13; -// tx_power[1] = 0x13; -// tx_power[2] = 0x13; -// } -// else -// { // 400 ~ 470 - tx_power[0] = 0x13; - tx_power[1] = 0x13; - tx_power[2] = 0x13; -// } - break; + #ifndef ENABLE_TX_POWER_CAL_MENU - default: - case OUTPUT_POWER_MID: // ~ 500mW - if (p_vfo->p_tx->frequency <= 26000000) - { // 137 ~ 174 - tx_power[0] = 0x29; - tx_power[1] = 0x29; - tx_power[2] = 0x29; - } - else - { // 400 ~ 470 - tx_power[0] = 0x37; - tx_power[1] = 0x37; - tx_power[2] = 0x37; - } - break; + #ifdef ENABLE_TX_POWER_FIX + switch (p_vfo->channel.tx_power) + { + case OUTPUT_POWER_LOW: // ~ 10mW +// if (p_vfo->p_tx->frequency <= 26000000) +// { // 137 ~ 174 +// tx_power[0] = 0x13; +// tx_power[1] = 0x13; +// tx_power[2] = 0x13; +// } +// else +// { // 400 ~ 470 + tx_power[0] = 0x13; + tx_power[1] = 0x13; + tx_power[2] = 0x13; +// } + break; + + default: + case OUTPUT_POWER_MID: // ~ 500mW + if (p_vfo->p_tx->frequency <= 26000000) + { // 137 ~ 174 + tx_power[0] = 0x29; + tx_power[1] = 0x29; + tx_power[2] = 0x29; + } + else + { // 400 ~ 470 + tx_power[0] = 0x37; + tx_power[1] = 0x37; + tx_power[2] = 0x37; + } + break; + + case OUTPUT_POWER_HIGH: // ~ 4W + if (p_vfo->p_tx->frequency <= 26000000) + { // 137 ~ 174 + tx_power[0] = 0x7F; + tx_power[1] = 0x84; + tx_power[2] = 0x8C; + } + else + { // 400 ~ 470 + tx_power[0] = 0x96; + tx_power[1] = 0x96; + tx_power[2] = 0x8C; + } + break; + } + #endif - case OUTPUT_POWER_HIGH: // ~ 4W - if (p_vfo->p_tx->frequency <= 26000000) - { // 137 ~ 174 - tx_power[0] = 0x7F; - tx_power[1] = 0x84; - tx_power[2] = 0x8C; - } - else - { // 400 ~ 470 - tx_power[0] = 0x96; - tx_power[1] = 0x96; - tx_power[2] = 0x8C; - } - break; - } #endif - // set the TX power registers - p_vfo->txp_calculated_setting = FREQUENCY_CalculateOutputPower(tx_power[0], tx_power[1], tx_power[2], p_vfo->p_tx->frequency); +#ifdef ENABLE_TX_POWER_LOW_USER + if (p_vfo->channel.tx_power == OUTPUT_POWER_LOW) + p_vfo->txp_reg_value = 8 + (p_vfo->channel.tx_pwr_user * 2); + else +#endif + p_vfo->txp_reg_value = FREQUENCY_CalculateOutputPower(tx_power[0], tx_power[1], tx_power[2], p_vfo->p_tx->frequency); } void RADIO_apply_offset(vfo_info_t *p_vfo, const bool set_pees) @@ -901,7 +909,7 @@ void RADIO_setup_registers(bool switch_to_function_foreground) BK4819_DisableVox(); // RX expander - BK4819_SetCompander((g_rx_vfo->channel.mod_mode == MOD_MODE_FM && g_rx_vfo->channel.compand >= 2) ? g_rx_vfo->channel.compand : 0); + BK4819_SetCompander((g_rx_vfo->channel.mod_mode == MOD_MODE_FM) ? g_rx_vfo->channel.compand : COMPAND_OFF); BK4819_EnableDTMF(); interrupt_mask |= BK4819_REG_3F_DTMF_5TONE_FOUND; @@ -982,7 +990,7 @@ void RADIO_enableTX(const bool fsk_tx) // so MAKE SURE that DTMF is disabled - until needed BK4819_DisableDTMF(); - BK4819_SetCompander((!fsk_tx && g_rx_vfo->channel.mod_mode == MOD_MODE_FM && (g_rx_vfo->channel.compand == 1 || g_rx_vfo->channel.compand >= 3)) ? g_rx_vfo->channel.compand : 0); + BK4819_SetCompander((!fsk_tx && g_current_vfo->channel.mod_mode == MOD_MODE_FM) ? g_current_vfo->channel.compand : COMPAND_OFF); // ****************** @@ -996,7 +1004,7 @@ void RADIO_enableTX(const bool fsk_tx) BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_PA_ENABLE, true); // PA on if (g_current_display_screen != DISPLAY_AIRCOPY) - BK4819_SetupPowerAmplifier(g_current_vfo->txp_calculated_setting, g_current_vfo->p_tx->frequency); + BK4819_SetupPowerAmplifier(g_current_vfo->txp_reg_value, g_current_vfo->p_tx->frequency); else BK4819_SetupPowerAmplifier(0, g_current_vfo->p_tx->frequency); // very low power when in AIRCOPY mode diff --git a/settings.h b/settings.h index 66486d7..276205e 100644 --- a/settings.h +++ b/settings.h @@ -141,6 +141,13 @@ enum { BANDWIDTH_NARROW }; +enum compand_e { + COMPAND_OFF = 0, + COMPAND_TX, + COMPAND_RX, + COMPAND_TX_RX +}; + enum ptt_id_e { PTT_ID_OFF = 0, // OFF PTT_ID_TX_UP, // BEGIN OF TX @@ -186,93 +193,55 @@ typedef struct { uint8_t rx_ctcss_cdcss_code; // // [9] uint8_t tx_ctcss_cdcss_code; // - // [10] struct { - uint8_t rx_ctcss_cdcss_type:2; // - uint8_t unused1:2; // - uint8_t tx_ctcss_cdcss_type:2; // - uint8_t unused2:2; // + uint8_t rx_ctcss_cdcss_type:2; // + uint8_t unused1:2; // + uint8_t tx_ctcss_cdcss_type:2; // + uint8_t unused2:2; // }; - // [11] struct { - uint8_t tx_offset_dir:2; // - - #ifdef ENABLE_MDC1200 - uint8_t mdc1200_mode:2; // - #else - uint8_t unused3:2; // - #endif - - #if 0 - uint8_t mod_mode:1; // FM/AM - uint8_t unused4:3; // - #else - uint8_t mod_mode:2; // FM/AM/DSB - uint8_t unused4:2; // - #endif + uint8_t tx_offset_dir:2; // 0=none 1=neg 2=pos + uint8_t mdc1200_mode:2; // 1of11 + uint8_t mod_mode:2; // 0=FM 1=AM 2=DSB + uint8_t unused4:2; // }; - // [12] struct { - uint8_t frequency_reverse:1; // reverse repeater - uint8_t channel_bandwidth:1; // wide/narrow - uint8_t tx_power:2; // 0, 1 or 2 .. L, M or H - uint8_t busy_channel_lock:1; // - - #if 0 - // QS - uint8_t unused5:3; // - #else - // 1of11 - uint8_t unused5:1; // - uint8_t compand:2; // 0 = off, 1 = TX, 2 = RX, 3 = TX/RX - #endif + uint8_t frequency_reverse:1; // reverse repeater + uint8_t channel_bandwidth:1; // wide/narrow + uint8_t tx_power:2; // 0=Low 1=Medium 2=High + uint8_t busy_channel_lock:1; // + uint8_t unused5:1; // + uint8_t compand:2; // 0=off 1=TX 2=RX 3=TX/RX }; - // [13] struct { - uint8_t dtmf_decoding_enable:1; // - uint8_t dtmf_ptt_id_tx_mode:3; // - - #if 0 - // QS - uint8_t unused6:4; // - #else - // 1of11 - uint8_t squelch_level:4; // 0 ~ 9 per channel squelch, 0 = use main squelch level - #endif + uint8_t dtmf_decoding_enable:1; // + uint8_t dtmf_ptt_id_tx_mode:3; // + uint8_t squelch_level:4; // 1of11 0 ~ 9 per channel squelch, 0 = use main squelch level }; - // [14] - uint8_t step_setting; // - + struct { + uint8_t step_setting:4; // step size index 0 ~ 15 + uint8_t tx_pwr_user:4; // 1of11 + }; // [15] - #if 0 - // QS - struct { - uint8_t scrambler:4; // - uint8_t unused7:4; // - }; - #else - // 1of11 - struct { - uint8_t scrambler:5; // more scrambler frequencies - uint8_t unused7:3; // - }; - #endif - -} __attribute__((packed)) t_channel; // + struct { + uint8_t scrambler:5; // voice inversion scrambler frequency index + uint8_t unused7:3; // + }; +} __attribute__((packed)) t_channel; typedef union { struct { - uint8_t band:4; // why do QS have these bits ? band can/is computed from the frequency + uint8_t band:4; // 0~6 otherwise channel unused uint8_t unused:2; // uint8_t scanlist2:1; // set if in scan list 2 uint8_t scanlist1:1; // set if in scan list 1 }; - uint8_t attributes; + uint8_t attributes; // } __attribute__((packed)) t_channel_attrib; typedef struct { @@ -613,7 +582,7 @@ typedef struct vfo_info_t uint8_t squelch_open_glitch_thresh; uint8_t squelch_close_glitch_thresh; - uint8_t txp_calculated_setting; + uint8_t txp_reg_value; } vfo_info_t; diff --git a/ui/main.c b/ui/main.c index 2091534..8e72e5f 100644 --- a/ui/main.c +++ b/ui/main.c @@ -895,7 +895,7 @@ void UI_DisplayMain(void) } x += smallest_char_spacing * 4; - if (g_vfo_info[vfo_num].channel.compand) + if (g_vfo_info[vfo_num].channel.compand != COMPAND_OFF) UI_PrintStringSmallest("C", x, (line + 0) * 8, false, true); //x += smallest_char_spacing * 1; } @@ -909,7 +909,7 @@ void UI_DisplayMain(void) str[0] = 'I'; // frequency is in the ignore list #endif - if (g_vfo_info[vfo_num].channel.compand) + if (g_vfo_info[vfo_num].channel.compand != COMPAND_OFF) str[1] = 'C'; // compander is enabled UI_PrintStringSmall(str, LCD_WIDTH - (7 * 2), 0, line + 1); @@ -928,7 +928,7 @@ void UI_DisplayMain(void) if (is_freq_chan && freq_in_channel <= USER_CHANNEL_LAST) str[1] = 'F'; // this VFO frequency is also found in a channel - if (g_vfo_info[vfo_num].channel.compand) + if (g_vfo_info[vfo_num].channel.compand != COMPAND_OFF) str[2] = 'C'; // compander is enabled UI_PrintStringSmall(str, LCD_WIDTH - (7 * 3), 0, line + 1); @@ -990,7 +990,11 @@ void UI_DisplayMain(void) if (FREQUENCY_tx_freq_check(g_vfo_info[vfo_num].p_tx->frequency) == 0) { // show the TX power - const char pwr_list[] = "LMH"; + #ifdef ENABLE_TX_POWER_LOW_USER + const char pwr_list[] = "UMH"; // user, midium, high + #else + const char pwr_list[] = "LMH"; // low, medium, high + #endif const unsigned int i = g_vfo_info[vfo_num].channel.tx_power; str[0] = (i < ARRAY_SIZE(pwr_list)) ? pwr_list[i] : '\0'; str[1] = '\0'; diff --git a/ui/menu.c b/ui/menu.c index e28e8f1..0f4a750 100644 --- a/ui/menu.c +++ b/ui/menu.c @@ -53,6 +53,9 @@ const t_menu_item g_menu_list[] = {"STEP", VOICE_ID_FREQUENCY_STEP, MENU_STEP }, {"W/N", VOICE_ID_CHANNEL_BANDWIDTH, MENU_BANDWIDTH }, {"Tx PWR", VOICE_ID_POWER, MENU_TX_POWER }, // was "TXP" +#ifdef ENABLE_TX_POWER_LOW_USER + {"TxPUSR", VOICE_ID_POWER, MENU_TX_POWER_LOW_USER }, +#endif {"Rx DCS", VOICE_ID_DCS, MENU_RX_CDCSS }, // was "R_DCS" {"Rx CTS", VOICE_ID_CTCSS, MENU_RX_CTCSS }, // was "R_CTCS" {"Tx DCS", VOICE_ID_DCS, MENU_TX_CDCSS }, // was "T_DCS" @@ -192,7 +195,11 @@ const char g_sub_menu_mod_mode[3][4] = const char g_sub_menu_tx_power[3][7] = { - "LOW", + #ifdef ENABLE_TX_POWER_LOW_USER + "USER", + #else + "LOW", + #endif "MEDIUM", "HIGH" }; @@ -610,6 +617,17 @@ void UI_DisplayMenu(void) channel_setting = true; break; + #ifdef ENABLE_TX_POWER_LOW_USER + case MENU_TX_POWER_LOW_USER: +// sprintf(str, "%u", 8 + (g_sub_menu_selection * 2)); + sprintf(str, "%u", g_sub_menu_selection); + +// if (g_current_function == FUNCTION_TRANSMIT && g_current_display_screen != DISPLAY_AIRCOPY) +// BK4819_SetupPowerAmplifier(8 + (g_sub_menu_selection * 2), g_current_vfo->p_tx->frequency); + + break; + #endif + case MENU_RX_CDCSS: case MENU_TX_CDCSS: strcpy(str, "CDCSS\n"); diff --git a/ui/menu.h b/ui/menu.h index 4fd2283..ab33175 100644 --- a/ui/menu.h +++ b/ui/menu.h @@ -45,6 +45,9 @@ enum MENU_STEP, MENU_BANDWIDTH, MENU_TX_POWER, +#ifdef ENABLE_TX_POWER_LOW_USER + MENU_TX_POWER_LOW_USER, +#endif MENU_RX_CDCSS, MENU_RX_CTCSS, MENU_TX_CDCSS,