diff --git a/Makefile b/Makefile index fae45a1..da0438c 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ ENABLE_FREQ_SEARCH_TIMEOUT := 0 ENABLE_CODE_SEARCH_TIMEOUT := 0 ENABLE_KILL_REVIVE := 0 ENABLE_AM_FIX := 1 -ENABLE_AM_FIX_SHOW_DATA := 0 +ENABLE_AM_FIX_SHOW_DATA := 1 ENABLE_SQUELCH_MORE_SENSITIVE := 1 ENABLE_SQ_OPEN_WITH_UP_DN_BUTTS := 1 ENABLE_FASTER_CHANNEL_SCAN := 1 @@ -55,11 +55,12 @@ ENABLE_COPY_CHAN_TO_VFO_TO_CHAN := 1 TARGET = firmware GIT_HASH_TMP := $(shell git rev-parse --short HEAD) -ifeq ($(GIT_HASH_TMP),) +ifeq ($(GIT_HASH_TMP), ) GIT_HASH := "NOGIT" else GIT_HASH := $(GIT_HASH_TMP) endif + $(info GIT_HASH = $(GIT_HASH)) ifeq ($(ENABLE_UART), 0) @@ -190,6 +191,8 @@ else TOP := $(shell pwd) endif +$(info TOP = $(TOP)) + AS = arm-none-eabi-gcc CC = @@ -410,10 +413,21 @@ LIBS = DEPS = $(OBJS:.o=.d) +ifeq ($(OS), Windows_NT) + PYTHON = $(shell where python 2>NUL || where python3 2>NUL) +else + PYTHON = $(shell which python || which python3) +endif + all: $(TARGET) $(OBJCOPY) -O binary $< $<.bin - -python fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin - -python3 fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin + + $(info PYTHON = $(PYTHON)) + +# -python fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin +# -python3 fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin + -$(PYTHON) fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin + $(SIZE) $< debug: diff --git a/app/aircopy.c b/app/aircopy.c index 3d7cfca..c51748e 100644 --- a/app/aircopy.c +++ b/app/aircopy.c @@ -549,7 +549,7 @@ void AIRCOPY_process_fsk_rx_10ms(void) data[2] = false; // remove it } - EEPROM_WriteBuffer(eeprom_addr, data); // 8 bytes at a time + EEPROM_WriteBuffer8(eeprom_addr, data); // 8 bytes at a time data += write_size / sizeof(data[0]); eeprom_addr += write_size; } diff --git a/app/fm.c b/app/fm.c index 1892e24..8023e8b 100644 --- a/app/fm.c +++ b/app/fm.c @@ -115,7 +115,7 @@ void FM_EraseChannels(void) memset(Template, 0xFF, sizeof(Template)); for (i = 0; i < 5; i++) - EEPROM_WriteBuffer(0x0E40 + (i * 8), Template); + EEPROM_WriteBuffer8(0x0E40 + (i * 8), Template); memset(g_fm_channels, 0xFF, sizeof(g_fm_channels)); } diff --git a/app/menu.c b/app/menu.c index 9da091e..b847043 100644 --- a/app/menu.c +++ b/app/menu.c @@ -71,7 +71,7 @@ // EEPROM_ReadBuffer(0x1F88, &misc, 8); misc.BK4819_XtalFreqLow = value; - EEPROM_WriteBuffer(0x1F88, &misc); + EEPROM_WriteBuffer8(0x1F88, &misc); } } #endif @@ -103,6 +103,7 @@ int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax) switch (Cursor) { case MENU_SQL: + case MENU_CHAN_SQL: *pMin = 0; *pMax = 9; break; @@ -389,7 +390,12 @@ void MENU_AcceptSetting(void) case MENU_SQL: g_eeprom.squelch_level = g_sub_menu_selection; - g_vfo_configure_mode = VFO_CONFIGURE; + g_vfo_configure_mode = VFO_CONFIGURE; + break; + + case MENU_CHAN_SQL: + g_tx_vfo->squelch_level = g_sub_menu_selection; + g_vfo_configure_mode = VFO_CONFIGURE; break; case MENU_STEP: @@ -855,12 +861,12 @@ void MENU_AcceptSetting(void) g_battery_calibration[3] = g_sub_menu_selection; // 7.6V, ~29%, 3 bars above this value g_battery_calibration[4] = (788ul * g_sub_menu_selection) / 760; // 7.88V, ~65%, 4 bars above this value g_battery_calibration[5] = 2300; - EEPROM_WriteBuffer(0x1F40, g_battery_calibration); + EEPROM_WriteBuffer8(0x1F40, g_battery_calibration); EEPROM_ReadBuffer( 0x1F48, buf, sizeof(buf)); buf[0] = g_battery_calibration[4]; buf[1] = g_battery_calibration[5]; - EEPROM_WriteBuffer(0x1F48, buf); + EEPROM_WriteBuffer8(0x1F48, buf); break; } @@ -934,6 +940,10 @@ void MENU_ShowCurrentSetting(void) g_sub_menu_selection = g_eeprom.squelch_level; break; + case MENU_CHAN_SQL: + g_sub_menu_selection = g_tx_vfo->squelch_level; + break; + case MENU_STEP: g_sub_menu_selection = FREQUENCY_get_step_index(STEP_FREQ_TABLE[g_tx_vfo->step_setting]); break; diff --git a/app/uart.c b/app/uart.c index e370a32..bb9ac1d 100644 --- a/app/uart.c +++ b/app/uart.c @@ -359,11 +359,11 @@ static void cmd_051D(const uint8_t *pBuffer) #ifdef ENABLE_PWRON_PASSWORD if ((Offset < 0x0E98 || Offset >= 0x0E9C) || !g_password_locked || pCmd->allow_password) - EEPROM_WriteBuffer(Offset, data); + EEPROM_WriteBuffer8(Offset, data); #else if (Offset == 0x0E98) memset(data, 0xff, 4); // wipe the password - EEPROM_WriteBuffer(Offset, data); + EEPROM_WriteBuffer8(Offset, data); #endif } diff --git a/board.c b/board.c index cad5503..3694c2c 100644 --- a/board.c +++ b/board.c @@ -782,7 +782,7 @@ void BOARD_EEPROM_load(void) uint8_t *p_aes = (uint8_t*)&g_custom_aes_key; memset(p_aes, 0xff, sizeof(g_custom_aes_key)); for (i = 0; i < sizeof(g_custom_aes_key); i += 8) - EEPROM_WriteBuffer(0x0F30 + i, &p_aes[i]); + EEPROM_WriteBuffer8(0x0F30 + i, &p_aes[i]); g_has_custom_aes_key = false; } #endif @@ -977,7 +977,7 @@ void BOARD_FactoryReset(bool bIsAll) )) ) { - EEPROM_WriteBuffer(i, Template); + EEPROM_WriteBuffer8(i, Template); } } diff --git a/driver/eeprom.c b/driver/eeprom.c index 3bff947..e90be8c 100644 --- a/driver/eeprom.c +++ b/driver/eeprom.c @@ -22,22 +22,23 @@ void EEPROM_ReadBuffer(const uint16_t address, void *p_buffer, const unsigned int size) { - if (p_buffer == NULL || address >= 0x2000 || size == 0) + if (p_buffer == NULL || (address + size) > 0x2000 || size == 0) return; I2C_Start(); I2C_Write(0xA0); I2C_Write((address >> 8) & 0xFF); I2C_Write((address >> 0) & 0xFF); + I2C_Start(); I2C_Write(0xA1); I2C_ReadBuffer(p_buffer, size); I2C_Stop(); } -void EEPROM_WriteBuffer(const uint16_t address, const void *p_buffer) +void EEPROM_WriteBuffer8(const uint16_t address, const void *p_buffer) { - if (p_buffer == NULL || address >= 0x2000) + if (p_buffer == NULL || (address + 8) > 0x2000) return; #if 0 @@ -50,9 +51,12 @@ void EEPROM_WriteBuffer(const uint16_t address, const void *p_buffer) I2C_WriteBuffer(p_buffer, 8); I2C_Stop(); + // give the EEPROM time to burn the data in (apparently takes 1.5ms ~ 5ms) + SYSTEM_DelayMs(6); + #else // eeprom wear reduction - // only write the data IF it's different to what's already in eeprom + // only write the data if it's different to what's already there uint8_t buffer[8]; EEPROM_ReadBuffer(address, buffer, 8); @@ -64,10 +68,10 @@ void EEPROM_WriteBuffer(const uint16_t address, const void *p_buffer) I2C_Write((address >> 0) & 0xFF); I2C_WriteBuffer(p_buffer, 8); I2C_Stop(); + + // give the EEPROM time to burn the data in (apparently takes 1.5ms ~ 5ms) + SYSTEM_DelayMs(6); } #endif - - // give the EEPROM time to burn the data in (apparently takes 5ms) - SYSTEM_DelayMs(8); } diff --git a/driver/eeprom.h b/driver/eeprom.h index 32c5656..0db917b 100644 --- a/driver/eeprom.h +++ b/driver/eeprom.h @@ -20,7 +20,7 @@ #include void EEPROM_ReadBuffer(const uint16_t address, void *p_buffer, const unsigned int size); -void EEPROM_WriteBuffer(const uint16_t address, const void *p_buffer); +void EEPROM_WriteBuffer8(const uint16_t address, const void *p_buffer); #endif diff --git a/firmware.bin b/firmware.bin index 5ddc618..7c4f6c0 100644 Binary files a/firmware.bin and b/firmware.bin differ diff --git a/firmware.packed.bin b/firmware.packed.bin index 867b58d..9a33ed3 100644 Binary files a/firmware.packed.bin and b/firmware.packed.bin differ diff --git a/radio.c b/radio.c index 81864d0..fa66ab2 100644 --- a/radio.c +++ b/radio.c @@ -148,6 +148,7 @@ void RADIO_configure_channel(const unsigned int VFO, const unsigned int configur uint8_t Band; uint16_t Base; uint32_t Frequency; + vfo_info_t *p_vfo = &g_eeprom.vfo_info[VFO]; if (!g_setting_350_enable) { @@ -160,14 +161,14 @@ void RADIO_configure_channel(const unsigned int VFO, const unsigned int configur Channel = g_eeprom.screen_channel[VFO]; - g_eeprom.vfo_info[VFO].frequency_channel = 0xff; + p_vfo->frequency_channel = 0xff; if (IS_VALID_CHANNEL(Channel)) { #ifdef ENABLE_NOAA if (Channel >= NOAA_CHANNEL_FIRST) { - RADIO_InitInfo(&g_eeprom.vfo_info[VFO], g_eeprom.screen_channel[VFO], NOAA_FREQUENCY_TABLE[Channel - NOAA_CHANNEL_FIRST]); + RADIO_InitInfo(p_vfo, g_eeprom.screen_channel[VFO], NOAA_FREQUENCY_TABLE[Channel - NOAA_CHANNEL_FIRST]); if (g_eeprom.cross_vfo_rx_tx == CROSS_BAND_OFF) return; g_eeprom.cross_vfo_rx_tx = CROSS_BAND_OFF; @@ -208,7 +209,7 @@ void RADIO_configure_channel(const unsigned int VFO, const unsigned int configur Index = Channel - FREQ_CHANNEL_FIRST; - RADIO_InitInfo(&g_eeprom.vfo_info[VFO], Channel, FREQ_BAND_TABLE[Index].lower); + RADIO_InitInfo(p_vfo, Channel, FREQ_BAND_TABLE[Index].lower); return; } @@ -217,165 +218,99 @@ void RADIO_configure_channel(const unsigned int VFO, const unsigned int configur Band = BAND6_400MHz; if (Channel <= USER_CHANNEL_LAST) - { // user channel - g_eeprom.vfo_info[VFO].band = Band; - g_eeprom.vfo_info[VFO].scanlist_2_participation = (Attributes & USER_CH_SCANLIST2) ? 1 : 0; - g_eeprom.vfo_info[VFO].scanlist_1_participation = (Attributes & USER_CH_SCANLIST1) ? 1 : 0; + { // USER channel + p_vfo->band = Band; + p_vfo->scanlist_2_participation = (Attributes & USER_CH_SCANLIST2) ? 1 : 0; + p_vfo->scanlist_1_participation = (Attributes & USER_CH_SCANLIST1) ? 1 : 0; } else if (IS_FREQ_CHANNEL(Channel)) { // VFO channel - Band = Channel - FREQ_CHANNEL_FIRST; - g_eeprom.vfo_info[VFO].band = Band; // shouldn't this be "Band / 2" ? .. two VFO's per band + Band = Channel - FREQ_CHANNEL_FIRST; + g_eeprom.vfo_info[VFO].band = Band; // shouldn't this be "Band / 2" ? .. two VFO's per band #if 0 - g_eeprom.vfo_info[VFO].scanlist_2_participation = 1; - g_eeprom.vfo_info[VFO].scanlist_1_participation = 1; + p_vfo->scanlist_2_participation = 1; + p_vfo->scanlist_1_participation = 1; #else // allowing the vfo's to be included in the scanning - g_eeprom.vfo_info[VFO].scanlist_2_participation = (Attributes & USER_CH_SCANLIST2) ? 1 : 0; - g_eeprom.vfo_info[VFO].scanlist_1_participation = (Attributes & USER_CH_SCANLIST1) ? 1 : 0; + p_vfo->scanlist_2_participation = (Attributes & USER_CH_SCANLIST2) ? 1 : 0; + p_vfo->scanlist_1_participation = (Attributes & USER_CH_SCANLIST1) ? 1 : 0; #endif } - g_eeprom.vfo_info[VFO].channel_save = Channel; + p_vfo->channel_save = Channel; if (Channel <= USER_CHANNEL_LAST) Base = Channel * 16; else - Base = 0x0C80 + ((Channel - FREQ_CHANNEL_FIRST) * 32) + (VFO * 16); + Base = 0x0C80 + ((Channel - FREQ_CHANNEL_FIRST) * 16 * 2) + (VFO * 16); // VFO channel - if (configure == VFO_CONFIGURE_RELOAD || Channel >= FREQ_CHANNEL_FIRST) + if (configure == VFO_CONFIGURE_RELOAD || IS_FREQ_CHANNEL(Channel)) { - uint8_t Tmp; - uint8_t Data[8]; -// t_channel channel; + t_channel m_channel; -// EEPROM_ReadBuffer(Base, channel, sizeof(channel)); + EEPROM_ReadBuffer(Base, &m_channel, sizeof(m_channel)); - // *************** + p_vfo->freq_config_rx.frequency = m_channel.frequency; + p_vfo->tx_offset_freq = (m_channel.offset <= 100000000) ? m_channel.offset : 1000000; + p_vfo->tx_offset_freq_dir = (m_channel.tx_offset_dir <= TX_OFFSET_FREQ_DIR_SUB) ? m_channel.tx_offset_dir : TX_OFFSET_FREQ_DIR_OFF; + p_vfo->am_mode = m_channel.am_mode; + p_vfo->step_setting = (m_channel.step_setting < ARRAY_SIZE(STEP_FREQ_TABLE)) ? m_channel.step_setting : STEP_12_5kHz; + p_vfo->step_freq = STEP_FREQ_TABLE[p_vfo->step_setting]; + p_vfo->scrambling_type = (m_channel.scrambler < ARRAY_SIZE(g_sub_MENU_SCRAMBLERAMBLER)) ? m_channel.scrambler : 0; - EEPROM_ReadBuffer(Base + 8, Data, sizeof(Data)); - - g_eeprom.vfo_info[VFO].freq_config_rx.code_type = (Data[2] >> 0) & 0x0F; - g_eeprom.vfo_info[VFO].freq_config_tx.code_type = (Data[2] >> 4) & 0x0F; - - Tmp = Data[3] & 0x0F; - if (Tmp > TX_OFFSET_FREQ_DIR_SUB) - Tmp = 0; - g_eeprom.vfo_info[VFO].tx_offset_freq_dir = Tmp; - g_eeprom.vfo_info[VFO].am_mode = (Data[3] >> 4) & 1u; - - Tmp = Data[6]; - if (Tmp >= ARRAY_SIZE(STEP_FREQ_TABLE)) - Tmp = STEP_12_5kHz; - g_eeprom.vfo_info[VFO].step_setting = Tmp; - g_eeprom.vfo_info[VFO].step_freq = STEP_FREQ_TABLE[Tmp]; - - Tmp = Data[7]; - if (Tmp > (ARRAY_SIZE(g_sub_MENU_SCRAMBLERAMBLER) - 1)) - Tmp = 0; - g_eeprom.vfo_info[VFO].scrambling_type = Tmp; - - Tmp = Data[0]; - switch (g_eeprom.vfo_info[VFO].freq_config_rx.code_type) + p_vfo->freq_config_rx.code_type = m_channel.rx_ctcss_cdcss_type; + switch (m_channel.rx_ctcss_cdcss_type) { default: case CODE_TYPE_NONE: - g_eeprom.vfo_info[VFO].freq_config_rx.code_type = CODE_TYPE_NONE; - Tmp = 0; + p_vfo->freq_config_rx.code_type = CODE_TYPE_NONE; + p_vfo->freq_config_rx.code = 0; break; - case CODE_TYPE_CONTINUOUS_TONE: - if (Tmp > (ARRAY_SIZE(CTCSS_OPTIONS) - 1)) - Tmp = 0; + p_vfo->freq_config_rx.code = (m_channel.rx_ctcss_cdcss_code < ARRAY_SIZE(CTCSS_OPTIONS)) ? m_channel.rx_ctcss_cdcss_code : 0; break; - case CODE_TYPE_DIGITAL: case CODE_TYPE_REVERSE_DIGITAL: - if (Tmp > (ARRAY_SIZE(DCS_OPTIONS) - 1)) - Tmp = 0; + p_vfo->freq_config_rx.code = (m_channel.rx_ctcss_cdcss_code < ARRAY_SIZE(DCS_OPTIONS)) ? m_channel.rx_ctcss_cdcss_code : 0; break; } - g_eeprom.vfo_info[VFO].freq_config_rx.code = Tmp; - Tmp = Data[1]; - switch (g_eeprom.vfo_info[VFO].freq_config_tx.code_type) + p_vfo->freq_config_tx.code_type = m_channel.tx_ctcss_cdcss_type; + switch (m_channel.tx_ctcss_cdcss_type) { default: case CODE_TYPE_NONE: - g_eeprom.vfo_info[VFO].freq_config_tx.code_type = CODE_TYPE_NONE; - Tmp = 0; + p_vfo->freq_config_tx.code_type = CODE_TYPE_NONE; + p_vfo->freq_config_tx.code = 0; break; - case CODE_TYPE_CONTINUOUS_TONE: - if (Tmp > (ARRAY_SIZE(CTCSS_OPTIONS) - 1)) - Tmp = 0; + p_vfo->freq_config_tx.code = (m_channel.tx_ctcss_cdcss_code < ARRAY_SIZE(CTCSS_OPTIONS)) ? m_channel.tx_ctcss_cdcss_code : 0; break; - case CODE_TYPE_DIGITAL: case CODE_TYPE_REVERSE_DIGITAL: - if (Tmp > (ARRAY_SIZE(DCS_OPTIONS) - 1)) - Tmp = 0; + p_vfo->freq_config_tx.code = (m_channel.tx_ctcss_cdcss_code < ARRAY_SIZE(DCS_OPTIONS)) ? m_channel.tx_ctcss_cdcss_code : 0; break; } - g_eeprom.vfo_info[VFO].freq_config_tx.code = Tmp; - if (Data[4] == 0xFF) - { - g_eeprom.vfo_info[VFO].frequency_reverse = false; - g_eeprom.vfo_info[VFO].channel_bandwidth = BK4819_FILTER_BW_WIDE; - g_eeprom.vfo_info[VFO].output_power = OUTPUT_POWER_LOW; - g_eeprom.vfo_info[VFO].busy_channel_lock = false; - g_eeprom.vfo_info[VFO].compand = 0; - } - else - { - const uint8_t d4 = Data[4]; - g_eeprom.vfo_info[VFO].frequency_reverse = ((d4 >> 0) & 1u) ? true : false; - g_eeprom.vfo_info[VFO].channel_bandwidth = ((d4 >> 1) & 1u) ? true : false; - g_eeprom.vfo_info[VFO].output_power = (d4 >> 2) & 3u; - g_eeprom.vfo_info[VFO].busy_channel_lock = ((d4 >> 4) & 1u) ? true : false; - g_eeprom.vfo_info[VFO].compand = (d4 >> 6) & 3u; - } + p_vfo->frequency_reverse = m_channel.frequency_reverse ? true : false; + p_vfo->channel_bandwidth = m_channel.channel_bandwidth ? true : false; + p_vfo->output_power = m_channel.tx_power; + p_vfo->busy_channel_lock = m_channel.busy_channel_lock ? true : false; + p_vfo->compand = m_channel.compand; - if (Data[5] == 0xFF) - { - g_eeprom.vfo_info[VFO].dtmf_decoding_enable = false; - g_eeprom.vfo_info[VFO].dtmf_ptt_id_tx_mode = PTT_ID_OFF; - } - else - { - g_eeprom.vfo_info[VFO].dtmf_decoding_enable = ((Data[5] >> 0) & 1u) ? true : false; - g_eeprom.vfo_info[VFO].dtmf_ptt_id_tx_mode = ((Data[5] >> 1) & 7u); - } + p_vfo->dtmf_decoding_enable = m_channel.dtmf_decoding_enable ? true : false; + p_vfo->dtmf_ptt_id_tx_mode = m_channel.dtmf_ptt_id_tx_mode; - // *************** - - struct - { - uint32_t frequency; - uint32_t offset; - } __attribute__((packed)) info; - - EEPROM_ReadBuffer(Base, &info, sizeof(info)); - - g_eeprom.vfo_info[VFO].freq_config_rx.frequency = info.frequency; - - if (info.offset >= 100000000) - info.offset = 1000000; - g_eeprom.vfo_info[VFO].tx_offset_freq = info.offset; - - // *************** + p_vfo->squelch_level = (m_channel.squelch_level < 10) ? m_channel.squelch_level : 0; } - Frequency = g_eeprom.vfo_info[VFO].freq_config_rx.frequency; + Frequency = p_vfo->freq_config_rx.frequency; #if 1 // fix previously maybe incorrect set band - Band = FREQUENCY_GetBand(Frequency); - g_eeprom.vfo_info[VFO].band = Band; - + p_vfo->band = Band; #endif if (Frequency < FREQ_BAND_TABLE[Band].lower) @@ -385,66 +320,79 @@ void RADIO_configure_channel(const unsigned int VFO, const unsigned int configur Frequency = FREQ_BAND_TABLE[Band].upper; else if (Channel >= FREQ_CHANNEL_FIRST) - Frequency = FREQUENCY_FloorToStep(Frequency, g_eeprom.vfo_info[VFO].step_freq, FREQ_BAND_TABLE[Band].lower); + Frequency = FREQUENCY_FloorToStep(Frequency, p_vfo->step_freq, FREQ_BAND_TABLE[Band].lower); - g_eeprom.vfo_info[VFO].freq_config_rx.frequency = Frequency; + if (!g_setting_350_enable && Frequency >= 35000000 && Frequency < 40000000) + { // 350~400Mhz not allowed + + // hop onto the euro ham band + Frequency = 43350000; + p_vfo->freq_config_rx.frequency = Frequency; + p_vfo->freq_config_tx.frequency = Frequency; + Band = FREQUENCY_GetBand(Frequency); + p_vfo->band = Band; + p_vfo->frequency_reverse = 0; + p_vfo->tx_offset_freq_dir = TX_OFFSET_FREQ_DIR_OFF; + p_vfo->tx_offset_freq = 0; + } + + p_vfo->freq_config_rx.frequency = Frequency; if (Frequency >= 10800000 && Frequency < 13600000) - g_eeprom.vfo_info[VFO].tx_offset_freq_dir = TX_OFFSET_FREQ_DIR_OFF; // air band + { // air band + p_vfo->tx_offset_freq_dir = TX_OFFSET_FREQ_DIR_OFF; + p_vfo->tx_offset_freq = 0; + } else if (Channel > USER_CHANNEL_LAST) - g_eeprom.vfo_info[VFO].tx_offset_freq = FREQUENCY_FloorToStep(g_eeprom.vfo_info[VFO].tx_offset_freq, g_eeprom.vfo_info[VFO].step_freq, 0); - - if (IS_FREQ_CHANNEL(Channel)) - g_eeprom.vfo_info[VFO].frequency_channel = BOARD_find_channel(Frequency); // remember if a channel has this frequency - - RADIO_ApplyOffset(&g_eeprom.vfo_info[VFO]); - - memset(g_eeprom.vfo_info[VFO].name, 0, sizeof(g_eeprom.vfo_info[VFO].name)); - if (Channel <= USER_CHANNEL_LAST) - { // only 10 bytes used - EEPROM_ReadBuffer(0x0F50 + (Channel * 16), g_eeprom.vfo_info[VFO].name, 10); + { + p_vfo->tx_offset_freq = FREQUENCY_FloorToStep(p_vfo->tx_offset_freq, p_vfo->step_freq, 0); } - if (!g_eeprom.vfo_info[VFO].frequency_reverse) + RADIO_ApplyOffset(p_vfo); + + // channel name + memset(p_vfo->name, 0, sizeof(p_vfo->name)); + if (Channel <= USER_CHANNEL_LAST) + EEPROM_ReadBuffer(0x0F50 + (Channel * 16), p_vfo->name, 10); // only 10 bytes used + + if (!p_vfo->frequency_reverse) { - g_eeprom.vfo_info[VFO].p_rx = &g_eeprom.vfo_info[VFO].freq_config_rx; - g_eeprom.vfo_info[VFO].p_tx = &g_eeprom.vfo_info[VFO].freq_config_tx; + p_vfo->p_rx = &p_vfo->freq_config_rx; + p_vfo->p_tx = &p_vfo->freq_config_tx; } else { - g_eeprom.vfo_info[VFO].p_rx = &g_eeprom.vfo_info[VFO].freq_config_tx; - g_eeprom.vfo_info[VFO].p_tx = &g_eeprom.vfo_info[VFO].freq_config_rx; + p_vfo->p_rx = &p_vfo->freq_config_tx; + p_vfo->p_tx = &p_vfo->freq_config_rx; } - if (!g_setting_350_enable) - { - freq_config_t *pConfig = g_eeprom.vfo_info[VFO].p_rx; - if (pConfig->frequency >= 35000000 && pConfig->frequency < 40000000) // not allowed in this range - pConfig->frequency = 43300000; // hop onto the ham band - } - - if (g_eeprom.vfo_info[VFO].am_mode) + if (p_vfo->am_mode) { // freq/chan is in AM mode - g_eeprom.vfo_info[VFO].scrambling_type = 0; -// g_eeprom.vfo_info[VFO].dtmf_decoding_enable = false; // no reason to disable DTMF decoding, aircraft use it on SSB - g_eeprom.vfo_info[VFO].freq_config_rx.code_type = CODE_TYPE_NONE; - g_eeprom.vfo_info[VFO].freq_config_tx.code_type = CODE_TYPE_NONE; + // disable stuff, even though it can all still be used with AM ??? + p_vfo->scrambling_type = 0; +// p_vfo->dtmf_decoding_enable = false; + p_vfo->freq_config_rx.code_type = CODE_TYPE_NONE; + p_vfo->freq_config_tx.code_type = CODE_TYPE_NONE; } - RADIO_ConfigureSquelchAndOutputPower(&g_eeprom.vfo_info[VFO]); + RADIO_ConfigureSquelchAndOutputPower(p_vfo); + + if (IS_FREQ_CHANNEL(Channel)) + p_vfo->frequency_channel = BOARD_find_channel(Frequency); // remember if a channel has this frequency } void RADIO_ConfigureSquelchAndOutputPower(vfo_info_t *pInfo) { uint8_t TX_power[3]; + uint16_t Base; frequency_band_t Band; // ******************************* // squelch Band = FREQUENCY_GetBand(pInfo->p_rx->frequency); - uint16_t Base = (Band < BAND4_174MHz) ? 0x1E60 : 0x1E00; + Base = (Band < BAND4_174MHz) ? 0x1E60 : 0x1E00; // note that 'noise' and 'glitch' values are inverted compared to 'rssi' values @@ -919,7 +867,7 @@ void RADIO_enableTX(const bool fsk_tx) // if DTMF is enabled when TX'ing, it changes the TX audio filtering ! .. 1of11 // so MAKE SURE that DTMF is disabled - until needed BK4819_DisableDTMF(); - + BK4819_SetCompander((!fsk_tx && g_rx_vfo->am_mode == 0 && (g_rx_vfo->compand == 1 || g_rx_vfo->compand >= 3)) ? g_rx_vfo->compand : 0); BK4819_set_rf_frequency(g_current_vfo->p_tx->frequency, false); @@ -1139,7 +1087,7 @@ void RADIO_tx_eot(void) { // don't send EOT if TX'ing tone/alarm BK4819_ExitDTMF_TX(true); return; - } + } #endif if (g_dtmf_call_state == DTMF_CALL_STATE_NONE && diff --git a/radio.h b/radio.h index ba751cc..7bc368b 100644 --- a/radio.h +++ b/radio.h @@ -84,6 +84,8 @@ typedef struct vfo_info_t uint8_t tx_offset_freq_dir; + uint8_t squelch_level; // per channel squelch level + uint8_t squelch_open_rssi_thresh; uint8_t squelch_open_noise_thresh; uint8_t squelch_close_glitch_thresh; diff --git a/settings.c b/settings.c index 2d40019..d482473 100644 --- a/settings.c +++ b/settings.c @@ -44,10 +44,10 @@ eeprom_config_t g_eeprom; state.frequency = g_eeprom.fm_selected_frequency; state.is_channel_selected = g_eeprom.fm_is_channel_mode; - EEPROM_WriteBuffer(0x0E88, &state); + EEPROM_WriteBuffer8(0x0E88, &state); for (i = 0; i < 5; i++) - EEPROM_WriteBuffer(0x0E40 + (i * 8), &g_fm_channels[i * 4]); + EEPROM_WriteBuffer8(0x0E40 + (i * 8), &g_fm_channels[i * 4]); } #endif @@ -70,7 +70,7 @@ void SETTINGS_save_vfo_indices(void) State[7] = g_eeprom.noaa_channel[1]; #endif - EEPROM_WriteBuffer(0x0E80, State); + EEPROM_WriteBuffer8(0x0E80, State); } // ************************************************* @@ -178,8 +178,8 @@ void SETTINGS_restore_calibration(void) while (index < sizeof(calib2)) { const unsigned int addr = 0x1E00 + index; - EEPROM_WriteBuffer(addr, &calib2[index]); -// EEPROM_WriteBuffer(addr, buf); + EEPROM_WriteBuffer8(addr, &calib2[index]); +// EEPROM_WriteBuffer8(addr, buf); index += 8; } } @@ -191,7 +191,7 @@ void SETTINGS_restore_calibration(void) void SETTINGS_save(void) { uint8_t State[8]; - + State[0] = g_eeprom.chan_1_call; State[1] = g_eeprom.squelch_level; State[2] = g_eeprom.tx_timeout_timer; @@ -209,7 +209,7 @@ void SETTINGS_save(void) State[6] = 0; #endif State[7] = g_eeprom.mic_sensitivity; - EEPROM_WriteBuffer(0x0E70, State); + EEPROM_WriteBuffer8(0x0E70, State); #ifdef ENABLE_CONTRAST State[0] = g_setting_contrast; @@ -223,7 +223,7 @@ void SETTINGS_save(void) State[5] = g_eeprom.backlight; State[6] = g_eeprom.tail_note_elimination; State[7] = g_eeprom.vfo_open; - EEPROM_WriteBuffer(0x0E78, State); + EEPROM_WriteBuffer8(0x0E78, State); State[0] = g_eeprom.beep_control; State[1] = g_eeprom.key1_short_press_action; @@ -233,7 +233,7 @@ void SETTINGS_save(void) State[5] = g_eeprom.scan_resume_mode; State[6] = g_eeprom.auto_keypad_lock; State[7] = g_eeprom.pwr_on_display_mode; - EEPROM_WriteBuffer(0x0E90, State); + EEPROM_WriteBuffer8(0x0E90, State); { struct { @@ -246,13 +246,13 @@ void SETTINGS_save(void) array.password = g_eeprom.power_on_password; #endif - EEPROM_WriteBuffer(0x0E98, &array); + EEPROM_WriteBuffer8(0x0E98, &array); } #ifdef ENABLE_VOICE memset(State, 0xFF, sizeof(State)); State[0] = g_eeprom.voice_prompt; - EEPROM_WriteBuffer(0x0EA0, State); + EEPROM_WriteBuffer8(0x0EA0, State); #endif // ***************************** @@ -281,7 +281,7 @@ void SETTINGS_save(void) array.air_copy_freq = g_aircopy_freq; #endif - EEPROM_WriteBuffer(0x0EA8, &array); + EEPROM_WriteBuffer8(0x0EA8, &array); } State[0] = g_eeprom.dtmf_side_tone; @@ -292,13 +292,13 @@ void SETTINGS_save(void) State[5] = g_eeprom.dtmf_preload_time / 10U; State[6] = g_eeprom.dtmf_first_code_persist_time / 10U; State[7] = g_eeprom.dtmf_hash_code_persist_time / 10U; - EEPROM_WriteBuffer(0x0ED0, State); + EEPROM_WriteBuffer8(0x0ED0, State); memset(State, 0xFF, sizeof(State)); State[0] = g_eeprom.dtmf_code_persist_time / 10U; State[1] = g_eeprom.dtmf_code_interval_time / 10U; State[2] = g_eeprom.permit_remote_kill; - EEPROM_WriteBuffer(0x0ED8, State); + EEPROM_WriteBuffer8(0x0ED8, State); State[0] = g_eeprom.scan_list_default; State[1] = g_eeprom.scan_list_enabled[0]; @@ -308,7 +308,7 @@ void SETTINGS_save(void) State[5] = g_eeprom.scan_list_priority_ch1[1]; State[6] = g_eeprom.scan_list_priority_ch2[1]; State[7] = 0xFF; - EEPROM_WriteBuffer(0x0F18, State); + EEPROM_WriteBuffer8(0x0F18, State); memset(State, 0xFF, sizeof(State)); State[0] = g_setting_freq_lock; @@ -335,79 +335,85 @@ void SETTINGS_save(void) if (!g_setting_am_fix) State[7] &= ~(1u << 5); #endif State[7] = (State[7] & ~(3u << 6)) | ((g_setting_backlight_on_tx_rx & 3u) << 6); - EEPROM_WriteBuffer(0x0F40, State); + EEPROM_WriteBuffer8(0x0F40, State); memset(State, 0xFF, sizeof(State)); State[0] = g_eeprom.scan_hold_time_500ms; - EEPROM_WriteBuffer(0x0F48, State); + EEPROM_WriteBuffer8(0x0F48, State); } -void SETTINGS_save_channel(const uint8_t channel, const uint8_t vfo, const vfo_info_t *p_vfo, const uint8_t mode) +void SETTINGS_save_channel(const unsigned int channel, const unsigned int vfo, const vfo_info_t *p_vfo, const unsigned int mode) { - const uint16_t offset_mem = channel * 16; - uint16_t offset_vfo = offset_mem; - uint8_t state[16]; -// t_channel channel_data; + unsigned int eeprom_addr = channel * 16; + t_channel m_channel; if (p_vfo == NULL || IS_NOAA_CHANNEL(channel)) return; - if (IS_FREQ_CHANNEL(channel)) - { // it's a VFO - offset_vfo = (vfo == 0) ? 0x0C80 : 0x0C90; - offset_vfo += (channel - FREQ_CHANNEL_FIRST) * 16 * 2; - } - if (mode < 2 && channel <= USER_CHANNEL_LAST) return; + if (IS_FREQ_CHANNEL(channel)) + eeprom_addr = 0x0C80 + (16 * vfo) + ((channel - FREQ_CHANNEL_FIRST) * 16 * 2); // a VFO + #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) -// UART_printf("sav_chan %u %u %u\r\n", channel, vfo, mode); +// UART_printf("sav_chan %04X %3u %u %u\r\n", eeprom_addr, channel, vfo, mode); #endif - ((uint32_t *)state)[0] = p_vfo->freq_config_rx.frequency; - ((uint32_t *)state)[1] = p_vfo->tx_offset_freq; - EEPROM_WriteBuffer(offset_vfo, state); + memset(&m_channel, 0, sizeof(m_channel)); + m_channel.frequency = p_vfo->freq_config_rx.frequency; + m_channel.offset = p_vfo->tx_offset_freq; + m_channel.rx_ctcss_cdcss_code = p_vfo->freq_config_rx.code; + m_channel.tx_ctcss_cdcss_code = p_vfo->freq_config_tx.code; + m_channel.rx_ctcss_cdcss_type = p_vfo->freq_config_rx.code_type; +// m_channel.unused1:2 + m_channel.tx_ctcss_cdcss_type = p_vfo->freq_config_tx.code_type; +// m_channel.unused2:2 + m_channel.tx_offset_dir = p_vfo->tx_offset_freq_dir; +// m_channel.unused3:2 + m_channel.am_mode = p_vfo->am_mode & 1u; +// m_channel.unused4:3 + m_channel.frequency_reverse = p_vfo->frequency_reverse; + m_channel.channel_bandwidth = p_vfo->channel_bandwidth; + m_channel.tx_power = p_vfo->output_power; + m_channel.busy_channel_lock = p_vfo->busy_channel_lock; +// m_channel.unused5:1 + m_channel.compand = p_vfo->compand; + m_channel.dtmf_decoding_enable = p_vfo->dtmf_decoding_enable; + m_channel.dtmf_ptt_id_tx_mode = p_vfo->dtmf_ptt_id_tx_mode; +// m_channel.unused6:4 + m_channel.step_setting = p_vfo->step_setting; + m_channel.scrambler = p_vfo->scrambling_type; + m_channel.squelch_level = 0; - state[0] = p_vfo->freq_config_rx.code; - state[1] = p_vfo->freq_config_tx.code; - state[2] = (p_vfo->freq_config_tx.code_type << 4) | p_vfo->freq_config_rx.code_type; - state[3] = ((p_vfo->am_mode & 1u) << 4) | p_vfo->tx_offset_freq_dir; - state[4] = - ((p_vfo->compand & 3u) << 6) | - ((p_vfo->busy_channel_lock & 3u) << 4) | - ((p_vfo->output_power & 1u) << 2) | - ((p_vfo->channel_bandwidth & 1u) << 1) | - ((p_vfo->frequency_reverse & 1u) << 0); - state[5] = ((p_vfo->dtmf_ptt_id_tx_mode & 7u) << 1) | ((p_vfo->dtmf_decoding_enable & 1u) << 0); - state[6] = p_vfo->step_setting; - state[7] = p_vfo->scrambling_type; - EEPROM_WriteBuffer(offset_vfo + 8, state); + EEPROM_WriteBuffer8(eeprom_addr + 0, (uint8_t *)(&m_channel) + 0); + EEPROM_WriteBuffer8(eeprom_addr + 8, (uint8_t *)(&m_channel) + 8); SETTINGS_save_chan_attribs_name(channel, p_vfo); - if (channel > USER_CHANNEL_LAST) - return; // it's not a user memory channel + if (channel <= USER_CHANNEL_LAST) + { // user channel, it has a channel name + const unsigned int eeprom_addr = 0x0F50 + (channel * 16); + uint8_t name[16]; - #ifndef ENABLE_KEEP_MEM_NAME - { // clear/reset the channel name - memset(&state, 0, sizeof(state)); - EEPROM_WriteBuffer(0x0F50 + 0 + offset_mem, state + 0); - EEPROM_WriteBuffer(0x0F50 + 8 + offset_mem, state + 8); + memset(name, 0, sizeof(name)); + + #ifndef ENABLE_KEEP_MEM_NAME + // clear/reset the channel name + EEPROM_WriteBuffer8(eeprom_addr + 0, name + 0); + EEPROM_WriteBuffer8(eeprom_addr + 8, name + 8); + #else + if (mode >= 3) + { // save the channel name + memmove(name, p_vfo->name, 10); + EEPROM_WriteBuffer8(eeprom_addr + 0, name + 0); + EEPROM_WriteBuffer8(eeprom_addr + 8, name + 8); + } + #endif } - #else - if (mode >= 3) - { // save the channel name - memset(state, 0, sizeof(state)); - memmove(state, p_vfo->name, 10); - - EEPROM_WriteBuffer(0x0F50 + 0 + offset_mem, state + 0); - EEPROM_WriteBuffer(0x0F50 + 8 + offset_mem, state + 8); - } - #endif } -void SETTINGS_save_chan_attribs_name(const uint8_t channel, const vfo_info_t *p_vfo) +void SETTINGS_save_chan_attribs_name(const unsigned int channel, const vfo_info_t *p_vfo) { if (p_vfo == NULL || channel >= ARRAY_SIZE(g_user_channel_attributes)) return; @@ -425,9 +431,9 @@ void SETTINGS_save_chan_attribs_name(const uint8_t channel, const vfo_info_t *p_ const unsigned int index = channel & ~7u; // eeprom writes are always 8 bytes in length g_user_channel_attributes[channel] = attribs; // remember new attributes - EEPROM_WriteBuffer(0x0D60 + index, g_user_channel_attributes + index); + EEPROM_WriteBuffer8(0x0D60 + index, g_user_channel_attributes + index); } - + if (channel <= USER_CHANNEL_LAST) { // user memory channel const unsigned int index = channel * 16; @@ -436,7 +442,7 @@ void SETTINGS_save_chan_attribs_name(const uint8_t channel, const vfo_info_t *p_ memset(name, 0, sizeof(name)); memmove(name, p_vfo->name, 10); - EEPROM_WriteBuffer(0x0F50 + 0 + index, name + 0); - EEPROM_WriteBuffer(0x0F50 + 8 + index, name + 8); + EEPROM_WriteBuffer8(0x0F50 + 0 + index, name + 0); + EEPROM_WriteBuffer8(0x0F50 + 8 + index, name + 8); } } diff --git a/settings.h b/settings.h index 25b39f3..b7a0f7b 100644 --- a/settings.h +++ b/settings.h @@ -158,8 +158,10 @@ typedef struct { 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 @@ -168,11 +170,16 @@ typedef struct { uint8_t dtmf_ptt_id_tx_mode:3; // uint8_t unused6:4; // // [14] - uint8_t step_setting:3; // - uint8_t unused7:5; // + uint8_t step_setting; // // [15] uint8_t scrambler:4; // - uint8_t unused8:4; // + #if 0 + // QS + uint8_t unused7:4; // + #else + // 1of11 + uint8_t squelch_level:4; // 0 ~ 9 per channel squelch, 0 = use main squelch level + #endif } __attribute__((packed)) t_channel; // // 512 bytes @@ -564,7 +571,7 @@ extern eeprom_config_t g_eeprom; void SETTINGS_save_vfo_indices(void); //void SETTINGS_restore_calibration(void); void SETTINGS_save(void); -void SETTINGS_save_channel(const uint8_t channel, const uint8_t vfo, const vfo_info_t *p_vfo, const uint8_t mode); -void SETTINGS_save_chan_attribs_name(const uint8_t channel, const vfo_info_t *p_vfo); +void SETTINGS_save_channel(const unsigned int channel, const unsigned int vfo, const vfo_info_t *p_vfo, const unsigned int mode); +void SETTINGS_save_chan_attribs_name(const unsigned int channel, const vfo_info_t *p_vfo); #endif diff --git a/ui/menu.c b/ui/menu.c index 686dfd5..f5e9b44 100644 --- a/ui/menu.c +++ b/ui/menu.c @@ -48,6 +48,7 @@ const t_menu_item g_menu_list[] = // text, voice ID, menu ID {"SQL", VOICE_ID_SQUELCH, MENU_SQL }, + {"CH SQL", VOICE_ID_SQUELCH, MENU_CHAN_SQL }, {"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" @@ -538,7 +539,15 @@ void UI_DisplayMenu(void) switch (g_menu_cursor) { case MENU_SQL: - sprintf(String, "%d", g_sub_menu_selection); + strcpy(String, "MAIN SQL\n"); + sprintf(String + strlen(String), "%d\n ", g_sub_menu_selection); + break; + + case MENU_CHAN_SQL: + if (g_sub_menu_selection == 0) + strcpy(String, "USE\nMAIN SQL"); + else + sprintf(String, "%d\n ", g_sub_menu_selection); break; case MENU_MIC_GAIN: diff --git a/ui/menu.h b/ui/menu.h index 2906ba3..9e89960 100644 --- a/ui/menu.h +++ b/ui/menu.h @@ -41,6 +41,7 @@ enum // ************************************ MENU_SQL = 0, + MENU_CHAN_SQL, MENU_STEP, MENU_BANDWIDTH, MENU_TX_POWER,