diff --git a/app/app.c b/app/app.c index e453b04..4a10376 100644 --- a/app/app.c +++ b/app/app.c @@ -51,6 +51,9 @@ #include "frequencies.h" #include "functions.h" #include "helper/battery.h" +#ifdef ENABLE_MDC1200 + #include "mdc1200.h" +#endif #include "misc.h" #include "radio.h" #include "settings.h" @@ -244,7 +247,7 @@ static void APP_process_rx(void) goto Skip; } - if (g_scan_state_dir != SCAN_STATE_DIR_OFF) // && IS_FREQ_CHANNEL(g_scan_next_channel)) + if (g_scan_state_dir != SCAN_STATE_DIR_OFF) // && IS_FREQ_CHANNEL(g_scan_next_channel)) { if (g_squelch_open) { @@ -262,7 +265,7 @@ static void APP_process_rx(void) } return; } - + Mode = END_OF_RX_MODE_END; goto Skip; } @@ -363,7 +366,7 @@ static void APP_process_rx(void) { Mode = END_OF_RX_MODE_END; } - + if (!g_end_of_rx_detected_maybe && Mode == END_OF_RX_MODE_NONE && g_next_time_slice_40ms && @@ -397,7 +400,7 @@ Skip: break; case END_OF_RX_MODE_TTE: - + if (g_eeprom.tail_note_elimination) { GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER); @@ -407,7 +410,7 @@ Skip: g_end_of_rx_detected_maybe = true; g_speaker_enabled = false; } - + break; } @@ -487,6 +490,10 @@ bool APP_start_listening(function_type_t Function, const bool reset_am_fix) BK1080_Init(0, false); #endif + #ifdef ENABLE_MDC1200 + MDC1200_reset_rx(); + #endif + // clear the other vfo's rssi level (to hide the antenna symbol) g_vfo_rssi_bar_level[(chan + 1) & 1u] = 0; @@ -602,7 +609,7 @@ bool APP_start_listening(function_type_t Function, const bool reset_am_fix) g_update_display = true; g_update_status = true; - + return true; } @@ -1191,15 +1198,15 @@ void APP_process(void) g_rx_reception_mode = RX_MODE_NONE; if (g_scan_next_channel <= USER_CHANNEL_LAST) - APP_next_channel(); + APP_next_channel(); else if (IS_FREQ_CHANNEL(g_scan_next_channel)) - APP_next_freq(); + APP_next_freq(); } /* if (g_scan_next_channel <= USER_CHANNEL_LAST) { // channel mode - + if (g_current_code_type == CODE_TYPE_NONE && g_current_function == FUNCTION_NEW_RECEIVE && !g_scan_pause_time_mode) { APP_start_listening(g_monitor_enabled ? FUNCTION_MONITOR : FUNCTION_RECEIVE, true); @@ -1208,13 +1215,13 @@ void APP_process(void) { // switch to next channel g_scan_pause_time_mode = false; g_rx_reception_mode = RX_MODE_NONE; - APP_next_channel(); + APP_next_channel(); } } else if (IS_FREQ_CHANNEL(g_scan_next_channel)) { // frequency mode - + if (g_current_function == FUNCTION_NEW_RECEIVE && !g_scan_pause_time_mode) { APP_start_listening(g_monitor_enabled ? FUNCTION_MONITOR : FUNCTION_RECEIVE, true); @@ -1223,7 +1230,7 @@ void APP_process(void) { // switch to next frequency g_scan_pause_time_mode = false; g_rx_reception_mode = RX_MODE_NONE; - APP_next_freq(); + APP_next_freq(); } } */ @@ -1797,7 +1804,7 @@ void APP_time_slice_10ms(void) RADIO_enableTX(false); BK4819_TransmitTone(true, 500); SYSTEM_DelayMs(2); - + GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER); g_speaker_enabled = true; @@ -2435,7 +2442,7 @@ void APP_time_slice_500ms(void) RADIO_tx_eot(); RADIO_EnableCxCSS(); } - + #ifdef ENABLE_VOX g_vox_resume_count_down = 80; #endif @@ -2464,7 +2471,7 @@ void APP_channel_next(const bool remember_current, const scan_state_dir_t scan_d g_scan_restore_channel = 0xff; g_scan_restore_frequency = 0xffffffff; } - + #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) UART_printf("APP_channel_next %u\r\n", g_scan_next_channel); #endif @@ -2476,7 +2483,7 @@ void APP_channel_next(const bool remember_current, const scan_state_dir_t scan_d APP_next_channel(); } else - if (IS_FREQ_CHANNEL(g_scan_next_channel)) + if (IS_FREQ_CHANNEL(g_scan_next_channel)) { // frequency mode if (remember_current) g_scan_restore_frequency = g_rx_vfo->freq_config_rx.frequency; diff --git a/app/menu.c b/app/menu.c index b443187..a5518ff 100644 --- a/app/menu.c +++ b/app/menu.c @@ -145,8 +145,8 @@ int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax) break; case MENU_SCAN_HOLD: - *pMin = 2; - *pMax = 20; // 10 seconds + *pMin = 2; // 1 second + *pMax = 40; // 20 seconds break; case MENU_CROSS_VFO: @@ -330,6 +330,11 @@ int MENU_GetLimits(uint8_t Cursor, int32_t *pMin, int32_t *pMax) break; #ifdef ENABLE_MDC1200 + case MENU_MDC1200_MODE: + *pMin = 0; + *pMax = ARRAY_SIZE(g_sub_menu_mdc1200_mode) - 1; + break; + case MENU_MDC1200_ID: *pMin = 0; *pMax = 0xffff; @@ -711,6 +716,11 @@ void MENU_AcceptSetting(void) break; #ifdef ENABLE_MDC1200 + case MENU_MDC1200_MODE: + g_tx_vfo->mdc1200_mode = g_sub_menu_selection; + g_request_save_channel = 1; + break; + case MENU_MDC1200_ID: g_eeprom.mdc1200_id = g_sub_menu_selection; break; @@ -1213,6 +1223,10 @@ void MENU_ShowCurrentSetting(void) break; #ifdef ENABLE_MDC1200 + case MENU_MDC1200_MODE: + g_sub_menu_selection = g_tx_vfo->mdc1200_mode; + break; + case MENU_MDC1200_ID: g_sub_menu_selection = g_eeprom.mdc1200_id; break; diff --git a/board.c b/board.c index d22ab50..4c0eb4c 100644 --- a/board.c +++ b/board.c @@ -756,7 +756,7 @@ void BOARD_EEPROM_load(void) // 0F48..0F4F EEPROM_ReadBuffer(0x0F48, Data, 8); - g_eeprom.scan_hold_time_500ms = (Data[0] > 20) ? 6 : (Data[0] < 2) ? 6 : Data[0]; + g_eeprom.scan_hold_time_500ms = (Data[0] > 40) ? 6 : (Data[0] < 2) ? 6 : Data[0]; if (!g_eeprom.vfo_open) { diff --git a/driver/bk4819.c b/driver/bk4819.c index fc00bcb..99f7861 100644 --- a/driver/bk4819.c +++ b/driver/bk4819.c @@ -121,6 +121,7 @@ void BK4819_Init(void) // BK4819_WriteRegister(0x37, 0x1D0F); // DisableAGC(0); + BK4819_WriteRegister(0x13, 0x03BE); BK4819_WriteRegister(0x12, 0x037B); BK4819_WriteRegister(0x11, 0x027B); @@ -268,7 +269,7 @@ void BK4819_DisableAGC(void) // 000=Bypass DC filter; // BK4819_WriteRegister(0x7E, - (0u << 15) | // 0 AGC fix mode + (1u << 15) | // 0 AGC fix mode (3u << 12) | // 3 AGC fix index (5u << 3) | // 5 DC Filter band width for Tx (MIC In) (6u << 0)); // 6 DC Filter band width for Rx (I.F In) @@ -345,7 +346,7 @@ void BK4819_EnableAGC(void) //BK4819_WriteRegister(0x7E, (1u << 15) | (4u << 12) | (5u << 3) | (6u << 0)); BK4819_WriteRegister(0x7E, - (1u << 15) | // 0 AGC fix mode + (0u << 15) | // 0 AGC fix mode (3u << 12) | // 3 AGC fix index (5u << 3) | // 5 DC Filter band width for Tx (MIC In) (6u << 0)); // 6 DC Filter band width for Rx (I.F In) @@ -1980,9 +1981,11 @@ void BK4819_send_MDC1200(const uint8_t op, const uint8_t arg, const uint16_t id) // <15> 1 = Enable TxCTCSS/CDCSS // 0 = Disable // - if (BK4819_ReadRegister(0x51) & (1u << 15)) - { // need to turn oss the CRCSS/CDCSS - BK4819_ExitSubAu(); + const bool code_enabled = (BK4819_ReadRegister(0x51) & (1u << 15)) ? true : false; + if (code_enabled) + { // need to turn off CTCSS/CDCSS + BK4819_WriteRegister(0x51, BK4819_ReadRegister(0x51) & ~(1u << 15)); +// BK4819_ExitSubAu(); SYSTEM_DelayMs(10); } @@ -2203,6 +2206,9 @@ void BK4819_send_MDC1200(const uint8_t op, const uint8_t arg, const uint16_t id) BK4819_WriteRegister(0x3F, 0); // disable interrupts BK4819_WriteRegister(0x70, 0); BK4819_WriteRegister(0x58, 0); + + if (code_enabled) + BK4819_WriteRegister(0x51, BK4819_ReadRegister(0x51) | (1u << 15)); } #endif diff --git a/firmware.bin b/firmware.bin index 0182bd1..2f6ccb8 100644 Binary files a/firmware.bin and b/firmware.bin differ diff --git a/firmware.packed.bin b/firmware.packed.bin index 7acf33d..5ac360d 100644 Binary files a/firmware.packed.bin and b/firmware.packed.bin differ diff --git a/functions.c b/functions.c index c3da084..159d94b 100644 --- a/functions.c +++ b/functions.c @@ -33,6 +33,9 @@ #include "frequencies.h" #include "functions.h" #include "helper/battery.h" +#ifdef ENABLE_MDC1200 + #include "mdc1200.h" +#endif #include "misc.h" #include "radio.h" #include "settings.h" @@ -268,9 +271,14 @@ void FUNCTION_Select(function_type_t Function) #endif if (!DTMF_Reply()) + { + if (g_current_vfo->mdc1200_mode == MDC1200_MODE_BOT || g_current_vfo->mdc1200_mode == MDC1200_MODE_BOTH) + BK4819_send_MDC1200(MDC1200_OP_CODE_PTT_ID, 0x80, g_eeprom.mdc1200_id); + else if (g_current_vfo->dtmf_ptt_id_tx_mode == PTT_ID_APOLLO) BK4819_PlayTone(APOLLO_TONE1_HZ, APOLLO_TONE_MS, 0); - + } + if (g_current_vfo->scrambling_type > 0 && g_setting_scramble_enable) BK4819_EnableScramble(g_current_vfo->scrambling_type - 1); diff --git a/mdc1200.c b/mdc1200.c index 5473686..f684685 100644 --- a/mdc1200.c +++ b/mdc1200.c @@ -7,6 +7,8 @@ #include "mdc1200.h" #include "misc.h" +#define FEC_K 7 + // MDC1200 sync bit reversals and packet sync // // >= 24-bit pre-amble @@ -14,7 +16,7 @@ // static const uint8_t pre_amble[] = {0x00, 0x00, 0x00, 0x00, 0x00}; static const uint8_t sync[] = {0xCC, 0x07, 0x09, 0x2a, 0x44, 0x6f}; - +/* uint8_t bit_reverse_8(uint8_t n) { n = ((n >> 1) & 0x55u) | ((n << 1) & 0xAAu); @@ -31,7 +33,7 @@ uint16_t bit_reverse_16(uint16_t n) n = ((n >> 8) & 0x00FFu) | ((n << 8) & 0xFF00u); return n; } -/* + uint32_t bit_reverse_32(uint32_t n) { n = ((n >> 1) & 0x55555555u) | ((n << 1) & 0xAAAAAAAAu); @@ -42,7 +44,6 @@ uint32_t bit_reverse_32(uint32_t n) return n; } */ - // ************************************ #if 0 @@ -105,8 +106,6 @@ uint32_t bit_reverse_32(uint32_t n) // ************************************ -#define FEC_K 7 - void error_correction(uint8_t *data) { // can correct up to 3 or 4 corrupted bits (I think) @@ -149,7 +148,49 @@ void error_correction(uint8_t *data) } } -bool MDC1200_decode_data(uint8_t *data) +void xor_modulation(uint8_t *data, const unsigned int size) +{ // exclusive-or succesive bits - the entire packet + unsigned int i; + uint8_t prev_bit = 0; + for (i = 0; i < size; i++) + { + int bit_num; + uint8_t in = data[i]; + uint8_t out = 0; + for (bit_num = 7; bit_num >= 0; bit_num--) + { + const uint8_t new_bit = (in >> bit_num) & 1u; + if (new_bit != prev_bit) + out |= 1u << bit_num; // previous bit and new bit are different - send a '1' + prev_bit = new_bit; + } + data[i] = out ^ 0xff; + } +} +/* +void xor_demodulation(uint8_t *data, const unsigned int size, const bool sync_inverted) +{ + unsigned int i; + uint8_t prev_bit = 0; + for (i = 0; i < size; i++) + { + int bit_num; + uint8_t in = data[i]; + uint8_t out = 0; + for (bit_num = 7; bit_num >= 0; bit_num--) + { + const uint8_t new_bit = (in >> bit_num) & 1u; + uint8_t bit = prev_bit ^ new_bit; + if (sync_inverted) + bit ^= 1u; + prev_bit = new_bit; + out |= bit << bit_num; + } + data[i] = out; + } +} +*/ +bool decode_data(uint8_t *data) { uint16_t crc1; uint16_t crc2; @@ -212,25 +253,7 @@ bool MDC1200_decode_data(uint8_t *data) crc1 = compute_crc(data, 4); crc2 = ((uint16_t)data[5] << 8) | (data[4] << 0); - if (crc1 != crc2) - return false; // CRC error, even after using the FEC bits - - // valid packet - - // extract the info - //uint8_t op = data[0]; - //uint8_t arg = data[1]; - //uint16_t id = ((uint16_t)data[3] << 8) | (data[2] << 0); - - - - - // TODO: pass the above received radio details over to the display function - - - - - return true; + return (crc1 == crc2) ? true : false; } uint8_t * encode_data(uint8_t *data) @@ -263,8 +286,7 @@ uint8_t * encode_data(uint8_t *data) } // 01 00 00 23 DD F0 00 65 00 00 0F 45 1F 21 - // 01 00 00 23 DD F0 00 65 00 00 0F 45 1F 21 - +/* #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) { const unsigned int size = FEC_K * 2; @@ -275,7 +297,7 @@ uint8_t * encode_data(uint8_t *data) UART_SendText("\r\n"); } #endif - +*/ { // interleave the bits unsigned int i; @@ -329,26 +351,6 @@ uint8_t * encode_data(uint8_t *data) return data + (FEC_K * 2); } -void delta_modulation(uint8_t *data, const unsigned int size) -{ // exclusive-or succesive bits - unsigned int i; - uint8_t prev_bit = 0; - for (i = 0; i < size; i++) - { - int bit_num; - uint8_t in = data[i]; - uint8_t out = 0; - for (bit_num = 7; bit_num >= 0; bit_num--) - { - const uint8_t new_bit = (in >> bit_num) & 1u; - if (new_bit != prev_bit) - out |= 1u << bit_num; // previous bit and new bit are different - send a '1' - prev_bit = new_bit; - } - data[i] = out ^ 0xff; - } -} - unsigned int MDC1200_encode_single_packet(uint8_t *data, const uint8_t op, const uint8_t arg, const uint16_t unit_id) { unsigned int size; @@ -383,7 +385,7 @@ unsigned int MDC1200_encode_single_packet(uint8_t *data, const uint8_t op, const } #endif */ - delta_modulation(data, size); + xor_modulation(data, size); return size; } @@ -423,11 +425,198 @@ unsigned int MDC1200_encode_double_packet(uint8_t *data, const uint8_t op, const size = (unsigned int)(p - data); - delta_modulation(data, size); + xor_modulation(data, size); return size; } */ + +struct { + uint8_t bit; + uint8_t prev_bit; + uint8_t xor_bit; + uint64_t shift_reg; + unsigned int bit_count; + unsigned int stage; + bool inverted_sync; + unsigned int data_index; + uint8_t data[40]; +} rx; + +void MDC1200_reset_rx(void) +{ + memset(&rx, 0, sizeof(rx)); +} + +bool MDC1200_process_rx(const uint8_t rx_byte, uint8_t *op, uint8_t *arg, uint16_t *unit_id) +{ + unsigned int i; + int k; + + for (k = 7; k >= 0; k--) + { + rx.prev_bit = rx.bit; + + rx.bit = (rx_byte >> k) & 1u; + + if (rx.stage == 0) + { // scanning for the pre-amble + rx.xor_bit = rx.bit & 1u; + } + else + { + rx.xor_bit = (rx.xor_bit ^ rx.bit) & 1u; + if (rx.inverted_sync) + rx.xor_bit ^= 1u; + } + + rx.shift_reg = (rx.shift_reg << 1) | (rx.xor_bit & 1u); + rx.bit_count++; + + // ********* + + if (rx.stage == 0) + { // looking for pre-amble + if (rx.bit_count < 20 || (rx.shift_reg & 0xfffff) != 1u) + continue; + + rx.xor_bit = 1; + rx.stage = 1; + rx.bit_count = 1; + + //s.printf("%5u %2u %u pre-amble found", index, rx_bit_count, rx_packet_stage); + //Memo1->Lines->Add(s); + } + + if (rx.stage < 2) + { + //s.printf("%5u %3u %u ", index, rx_bit_count, rx_packet_stage); + //for (uint64_t mask = 1ull << ((sizeof(rx_shift_reg) * 8) - 1); mask != 0; mask >>= 1) + // s += (rx_shift_reg & mask) ? '#' : '.'; + //s += " "; + //for (int i = sizeof(rx_shift_reg) - 1; i >= 0; i--) + //{ + // String s2; + // s2.printf(" %02X", (uint8_t)(rx_shift_reg >> (i * 8))); + // s += s2; + //} + //Memo1->Lines->Add(s); + } + + if (rx.stage == 1) + { // looking for the 40-bit sync pattern, it follows the 24-bit pre-amble + + const unsigned int sync_bit_ok_threshold = 32; + + if (rx.bit_count >= sync_bit_ok_threshold) + { + // 40-bit sync pattern + uint64_t sync_nor = 0x07092a446fu; // normal + uint64_t sync_inv = 0xffffffffffu ^ sync_nor; // bit inverted + + sync_nor ^= rx.shift_reg; + sync_inv ^= rx.shift_reg; + + unsigned int nor_count = 0; + unsigned int inv_count = 0; + for (i = 40; i > 0; i--, sync_nor >>= 1, sync_inv >>= 1) + { + nor_count += sync_nor & 1u; + inv_count += sync_inv & 1u; + } + nor_count = 40 - nor_count; + inv_count = 40 - inv_count; + + if (nor_count >= sync_bit_ok_threshold || inv_count >= sync_bit_ok_threshold) + { // good enough + + rx.inverted_sync = (inv_count > nor_count) ? true : false; + + //String s; + //s.printf("%5u %2u %u sync found %s %u bits ", + // index, + // rx_bit_count, + // rx_packet_stage, + // rx_inverted_sync ? "inv" : "nor", + // rx_inverted_sync ? inv_count : nor_count); + + //for (int i = 4; i >= 0; i--) + //{ + // String s2; + // uint8_t b = rx_shift_reg >> (8 * i); + // if (rx_inverted_sync) + // b ^= 0xff; + // s2.printf(" %02X", b); + // s += s2; + //} + //Memo1->Lines->Add(s); + + rx.data_index = 0; + rx.bit_count = 0; + rx.stage++; + } + } + + continue; + } + + // ********* + + if (rx.stage < 2) + continue; + + if (rx.bit_count < 8) + continue; + + rx.bit_count = 0; + + // 55 55 55 55 55 55 55 07 09 2A 44 6F 94 9C 22 20 32 A4 1A 37 1E 3A 00 98 2C 84 + + rx.data[rx.data_index++] = rx.shift_reg & 0xff; // save the last 8 bits + + if (rx.data_index < (FEC_K * 2)) + continue; + + // s.printf("%5u %3u %u %2u ", index, rx_bit_count, rx_packet_stage, rx_buffer.size()); + // for (i = 0; i < rx_data_index; i++) + // { + // String s2; + // const uint8_t b = rx_buffer[i]; + // s2.printf(" %02X", b); + // s += s2; + // } + // Memo1->Lines->Add(s); + + if (!decode_data(rx.data)) + { + MDC1200_reset_rx(); + continue; + } + + // extract the info from the packet + *op = rx.data[0]; + *arg = rx.data[1]; + *unit_id = ((uint16_t)rx.data[3] << 8) | (rx.data[2] << 0); + + //s.printf("%5u %3u %u %2u decoded ", index, rx_bit_count, rx_packet_stage, rx_buffer.size()); + //for (i = 0; i < 14; i++) + //{ + // String s2; + // const uint8_t b = data[i]; + // s2.printf(" %02X", b); + // s += s2; + //} + //Memo1->Lines->Add(s); + + // reset the detector + MDC1200_reset_rx(); + + return true; + } + + return false; +} + /* void test(void) { diff --git a/mdc1200.h b/mdc1200.h index 321bfac..942077c 100644 --- a/mdc1200.h +++ b/mdc1200.h @@ -86,8 +86,10 @@ enum mdc1200_op_code_e { MDC1200_OP_CODE_RADIO_CHECK = 0x63 }; -bool MDC1200_decode_data(uint8_t *data); unsigned int MDC1200_encode_single_packet(uint8_t *data, const uint8_t op, const uint8_t arg, const uint16_t unit_id); -unsigned int MDC1200_encode_double_packet(uint8_t *data, const uint8_t op, const uint8_t arg, const uint16_t unit_id, const uint8_t b0, const uint8_t b1, const uint8_t b2, const uint8_t b3); +//unsigned int MDC1200_encode_double_packet(uint8_t *data, const uint8_t op, const uint8_t arg, const uint16_t unit_id, const uint8_t b0, const uint8_t b1, const uint8_t b2, const uint8_t b3); + +void MDC1200_reset_rx(void); +bool MDC1200_process_rx(const uint8_t rx_byte, uint8_t *op, uint8_t *arg, uint16_t *unit_id); #endif diff --git a/radio.c b/radio.c index 69d9eaa..d13b161 100644 --- a/radio.c +++ b/radio.c @@ -300,6 +300,10 @@ void RADIO_configure_channel(const unsigned int VFO, const unsigned int configur break; } + #ifdef ENABLE_MDC1200 + p_vfo->mdc1200_mode = m_channel.mdc1200_mode; + #endif + 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; @@ -1126,7 +1130,8 @@ void RADIO_tx_eot(void) } else #ifdef ENABLE_MDC1200 - if (g_eeprom.roger_mode == ROGER_MODE_MDC) +// if (g_eeprom.roger_mode == ROGER_MODE_MDC) + if (g_current_vfo->mdc1200_mode == MDC1200_MODE_EOT || g_current_vfo->mdc1200_mode == MDC1200_MODE_BOTH) { BK4819_send_MDC1200(MDC1200_OP_CODE_POST_ID, 0x00, g_eeprom.mdc1200_id); } diff --git a/radio.h b/radio.h index 3bdbad9..91191e4 100644 --- a/radio.h +++ b/radio.h @@ -50,6 +50,14 @@ enum ptt_id_e { }; typedef enum ptt_id_e ptt_id_t; +enum mdc1200_mode_e { + MDC1200_MODE_OFF = 0, // OFF + MDC1200_MODE_BOT, // BEGIN OF TX + MDC1200_MODE_EOT, // END OF TX + MDC1200_MODE_BOTH // BOTH +}; +typedef enum mdc1200_mode_e mdc1200_mode_t; + enum vfo_state_e { VFO_STATE_NORMAL = 0, @@ -109,6 +117,10 @@ typedef struct vfo_info_t uint8_t dtmf_decoding_enable; ptt_id_t dtmf_ptt_id_tx_mode; + #ifdef ENABLE_MDC1200 + mdc1200_mode_t mdc1200_mode; + #endif + uint8_t busy_channel_lock; uint8_t am_mode; diff --git a/settings.c b/settings.c index 30d5bbf..6e7bfaa 100644 --- a/settings.c +++ b/settings.c @@ -385,7 +385,9 @@ void SETTINGS_save_channel(const unsigned int channel, const unsigned int vfo, c 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 + #ifdef ENABLE_MDC1200 + m_channel.mdc1200_mode = p_vfo->mdc1200_mode; + #endif m_channel.tx_offset_dir = p_vfo->tx_offset_freq_dir; // m_channel.unused3:2 m_channel.am_mode = p_vfo->am_mode & 1u; diff --git a/settings.h b/settings.h index 882f037..2f078be 100644 --- a/settings.h +++ b/settings.h @@ -149,7 +149,11 @@ typedef struct { uint8_t unused2:2; // // [11] uint8_t tx_offset_dir:2; // - uint8_t unused3:2; // + #ifdef ENABLE_MDC1200 + uint8_t mdc1200_mode:2; // + #else + uint8_t unused3:2; // + #endif uint8_t am_mode:1; // uint8_t unused4:3; // // [12] diff --git a/ui/helper.c b/ui/helper.c index f0f705c..212a47b 100644 --- a/ui/helper.c +++ b/ui/helper.c @@ -76,7 +76,7 @@ void UI_PrintString(const char *pString, uint8_t Start, uint8_t End, uint8_t Lin size_t Length = strlen(pString); if (End > Start) - Start += ((End - Start) - (Length * Width)) / 2; + Start += ((End - Start) - (Length * Width) - 1) / 2; for (i = 0; i < Length; i++) { diff --git a/ui/menu.c b/ui/menu.c index f2083d8..e41b14b 100644 --- a/ui/menu.c +++ b/ui/menu.c @@ -108,6 +108,7 @@ const t_menu_item g_menu_list[] = {"UpCODE", VOICE_ID_INVALID, MENU_UP_CODE }, {"DnCODE", VOICE_ID_INVALID, MENU_DN_CODE }, // was "DWCODE" #ifdef ENABLE_MDC1200 + {"MDCPTT", VOICE_ID_INVALID, MENU_MDC1200_MODE }, {"MDC ID", VOICE_ID_INVALID, MENU_MDC1200_ID }, #endif {"PTT ID", VOICE_ID_INVALID, MENU_PTT_ID }, @@ -279,12 +280,22 @@ const char g_sub_menu_dtmf_rsp[4][9] = const char g_sub_menu_ptt_id[5][15] = { "OFF", - "BEGIN", - "END", - "BEGIN +\nEND", + "BOT", + "EOT", + "BOT+EOT", "APOLLO\nQUINDAR" }; +#ifdef ENABLE_MDC1200 + const char g_sub_menu_mdc1200_mode[4][8] = + { + "OFF", + "BOT", + "EOT", + "BOT+EOT" + }; +#endif + const char g_sub_menu_pwr_on_msg[4][14] = { "ALL\nPIXELS\nON", @@ -293,11 +304,11 @@ const char g_sub_menu_pwr_on_msg[4][14] = "NONE" }; -const char g_sub_menu_roger_mode[3][16] = +const char g_sub_menu_roger_mode[2][16] = { "OFF", "TX END\nROGER", - "TX END\nMDC1200" +// "TX END\nMDC1200" }; const char g_sub_menu_reset[2][4] = @@ -996,6 +1007,11 @@ void UI_DisplayMenu(void) break; #ifdef ENABLE_MDC1200 + case MENU_MDC1200_MODE: + strcpy(str, "MDC1200\nMODE\n"); + strcat(str, g_sub_menu_mdc1200_mode[g_sub_menu_selection]); + break; + case MENU_MDC1200_ID: sprintf(str, "MDC1200\nID\n%04X", g_sub_menu_selection); break; diff --git a/ui/menu.h b/ui/menu.h index a8720c9..ac14b5f 100644 --- a/ui/menu.h +++ b/ui/menu.h @@ -101,6 +101,7 @@ enum MENU_DTMF_LIST, MENU_DTMF_LIVE_DEC, #ifdef ENABLE_MDC1200 + MENU_MDC1200_MODE, MENU_MDC1200_ID, #endif MENU_PTT_ID, @@ -169,37 +170,40 @@ extern const char g_sub_menu_bat_save[5][9]; extern const char g_sub_menu_tx_timeout[11][7]; extern const char g_sub_menu_dual_watch[3][10]; extern const char g_sub_menu_cross_vfo[3][10]; -#ifdef ENABLE_VOICE +#ifdef ENABLE_VOICE extern const char g_sub_menu_voice[3][4]; -#endif +#endif extern const char g_sub_menu_scan_car_resume[3][8]; extern const char g_sub_menu_mem_disp[4][15]; -#ifdef ENABLE_ALARM +#ifdef ENABLE_ALARM extern const char g_sub_menu_alarm_mode[2][5]; -#endif +#endif extern const char g_sub_menu_dtmf_rsp[4][9]; extern const char g_sub_menu_ptt_id[5][15]; +#ifdef ENABLE_MDC1200 + extern const char g_sub_menu_mdc1200_mode[4][8]; +#endif extern const char g_sub_menu_pwr_on_msg[4][14]; -extern const char g_sub_menu_roger_mode[3][16]; +extern const char g_sub_menu_roger_mode[2][16]; extern const char g_sub_menu_reset[2][4]; extern const char g_sub_menu_backlight[8][7]; extern const char g_sub_menu_rx_tx[4][6]; #ifdef ENABLE_AM_FIX_TEST1 extern const char g_sub_menu_AM_FIX_test1[4][8]; -#endif +#endif extern const char g_sub_menu_bat_text[3][8]; extern const char g_sub_menu_dis_en[2][9]; extern const char g_sub_menu_scrambler[11][7]; #ifdef ENABLE_SIDE_BUTT_MENU extern const char g_sub_menu_side_butt[9][16]; #endif - + extern bool g_in_sub_menu; - + extern uint8_t g_menu_cursor; extern int8_t g_menu_scroll_direction; extern int32_t g_sub_menu_selection; - + extern char g_edit_original[17]; extern char g_edit[17]; extern int g_edit_index;