// ---------------------------------------------------------------------------- // Copyright (C) 2014 // David Freese, W1HKJ // Modified: January 2017 // Andy Stewart, KB1OIQ // Updated: June 2018 // Cliff Scott, AE5ZA // // This file is part of flrig. // // flrig is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // flrig is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // ---------------------------------------------------------------------------- #include #include #include #include "icom/IC705.h" #include "status.h" #include "trace.h" #include "tod_clock.h" #include "support.h" //============================================================================= // IC-705 const char IC705name_[] = "IC-705"; // these are only defined in this file // undef'd at end of file #define NUM_FILTERS 3 #define NUM_MODES 13 static int mode_filterA[NUM_MODES] = {1,1,1,1,1,1,1,1,1,1,1,1}; static int mode_filterB[NUM_MODES] = {1,1,1,1,1,1,1,1,1,1,1,1}; static int mode_bwA[NUM_MODES] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; static int mode_bwB[NUM_MODES] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; static const char *szfilter[NUM_FILTERS] = {"1", "2", "3"}; enum { LSB705, USB705, AM705, FM705, CW705, CWR705, RTTY705, RTTYR705, LSBD705, USBD705, AMD705, FMD705, DV705 }; static std::vectorIC705modes_; static const char *vIC705modes_[] = { "LSB", "USB", "AM", "FM", "CW", "CW-R", "RTTY", "RTTY-R", "LSB-D", "USB-D", "AM-D", "FM-D", "DV"}; char IC705_mode_type[] = { 'L', 'U', 'U', 'U', 'L', 'U', 'L', 'U', 'L', 'U', 'U', 'U', 'U' }; const char IC705_mode_nbr[] = { 0x00, 0x01, 0x02, 0x05, 0x03, 0x07, 0x04, 0x08, 0x00, 0x01, 0x02, 0x05, 0x17 }; static std::vectorIC705_ssb_bws; static const char *vIC705_ssb_bws[] = { "50", "100", "150", "200", "250", "300", "350", "400", "450", "500", "600", "700", "800", "900", "1000", "1100", "1200", "1300", "1400", "1500", "1600", "1700", "1800", "1900", "2000", "2100", "2200", "2300", "2400", "2500", "2600", "2700", "2800", "2900", "3000", "3100", "3200", "3300", "3400", "3500", "3600" }; static int IC705_bw_vals_SSB[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19, 20,21,22,23,24,25,26,27,28,29, 30,31,32,33,34,35,36,37,38,39, 40, WVALS_LIMIT}; static std::vectorIC705_rtty_bws; static const char *vIC705_rtty_bws[] = { "50", "100", "150", "200", "250", "300", "350", "400", "450", "500", "600", "700", "800", "900", "1000", "1100", "1200", "1300", "1400", "1500", "1600", "1700", "1800", "1900", "2000", "2100", "2200", "2300", "2400", "2500", "2600", "2700" }; static int IC705_bw_vals_RTTY[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19, 20,21,22,23,24,25,26,27,28,29, 30,31, WVALS_LIMIT}; static std::vectorIC705_am_bws; static const char *vIC705_am_bws[] = { "200", "400", "600", "800", "1000", "1200", "1400", "1600", "1800", "2000", "2200", "2400", "2600", "2800", "3000", "3200", "3400", "3600", "3800", "4000", "4200", "4400", "4600", "4800", "5000", "5200", "5400", "5600", "5800", "6000", "6200", "6400", "6600", "6800", "7000", "705", "7400", "705", "7800", "8000", "8200", "8400", "8600", "8800", "9000", "9200", "9400", "9600", "9800", "10000" }; static int IC705_bw_vals_AM[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19, 20,21,22,23,24,25,26,27,28,29, 30,31,32,33,34,35,36,37,38,39, 40,41,42,43,44,45,46,47,48,49 WVALS_LIMIT}; static std::vectorIC705_fm_bws; static const char *vIC705_fm_bws[] = { "FIXED" }; static int IC705_bw_vals_FM[] = { 1, WVALS_LIMIT}; //---------------------------------------------------------------------- static std::vectorIC705_att_labels; static const char *vIC705_att_labels[] = { "ATT", "20 dB" }; static std::vectorIC705_pre_labels; static const char *vIC705_pre_labels[] = { "PRE", "Pre 1", "Pre 2"}; //---------------------------------------------------------------------- static GUI IC705_widgets[]= { { (Fl_Widget *)btnVol, 2, 125, 50 }, //0 { (Fl_Widget *)sldrVOLUME, 54, 125, 156 }, //1 { (Fl_Widget *)btnAGC, 2, 145, 50 }, //2 { (Fl_Widget *)sldrRFGAIN, 54, 145, 156 }, //3 { (Fl_Widget *)sldrSQUELCH, 54, 165, 156 }, //4 { (Fl_Widget *)btnNR, 2, 185, 50 }, //5 { (Fl_Widget *)sldrNR, 54, 185, 156 }, //6 { (Fl_Widget *)btnLOCK, 214, 105, 50 }, //7 { (Fl_Widget *)sldrINNER, 266, 105, 156 }, //8 { (Fl_Widget *)btnCLRPBT, 214, 125, 50 }, //9 { (Fl_Widget *)sldrOUTER, 266, 125, 156 }, //10 { (Fl_Widget *)btnNotch, 214, 145, 50 }, //11 { (Fl_Widget *)sldrNOTCH, 266, 145, 156 }, //12 { (Fl_Widget *)sldrMICGAIN, 266, 165, 156 }, //13 { (Fl_Widget *)sldrPOWER, 266, 185, 156 }, //14 { (Fl_Widget *)NULL, 0, 0, 0 } }; void RIG_IC705::initialize() { VECTOR (IC705modes_, vIC705modes_); VECTOR (IC705_ssb_bws, vIC705_ssb_bws); VECTOR (IC705_rtty_bws, vIC705_rtty_bws); VECTOR (IC705_am_bws, vIC705_am_bws); VECTOR (IC705_fm_bws, vIC705_fm_bws); modes_ = IC705modes_; bandwidths_ = IC705_ssb_bws; bw_vals_ = IC705_bw_vals_SSB; VECTOR (IC705_att_labels, vIC705_att_labels); VECTOR (IC705_pre_labels, vIC705_pre_labels); att_labels_ = IC705_att_labels; pre_labels_ = IC705_pre_labels; _mode_type = IC705_mode_type; IC705_widgets[0].W = btnVol; IC705_widgets[1].W = sldrVOLUME; IC705_widgets[2].W = btnAGC; IC705_widgets[3].W = sldrRFGAIN; IC705_widgets[4].W = sldrSQUELCH; IC705_widgets[5].W = btnNR; IC705_widgets[6].W = sldrNR; IC705_widgets[7].W = btnLOCK; IC705_widgets[8].W = sldrINNER; IC705_widgets[9].W = btnCLRPBT; IC705_widgets[10].W = sldrOUTER; IC705_widgets[11].W = btnNotch; IC705_widgets[12].W = sldrNOTCH; IC705_widgets[13].W = sldrMICGAIN; IC705_widgets[14].W = sldrPOWER; btn_icom_select_13->deactivate(); choice_rTONE->activate(); choice_tTONE->activate(); } RIG_IC705::RIG_IC705() { defaultCIV = 0xA4; adjustCIV(defaultCIV); name_ = IC705name_; modes_ = IC705modes_; bandwidths_ = IC705_ssb_bws; bw_vals_ = IC705_bw_vals_SSB; _mode_type = IC705_mode_type; serial_baudrate = BR19200; stopbits = 1; serial_retries = 2; // serial_write_delay = 0; // serial_post_write_delay = 0; serial_timeout = 50; serial_echo = true; serial_rtscts = false; serial_rtsplus = true; serial_dtrplus = true; serial_catptt = true; serial_rtsptt = false; serial_dtrptt = false; widgets = IC705_widgets; def_freq = A.freq = 14070000ULL; def_mode = A.imode = 9; def_bw = A.iBW = 34; B.freq = 7070000ULL; B.imode = 9; B.iBW = 34; has_extras = true; has_cw_wpm = true; has_cw_spot_tone = true; has_cw_qsk = true; has_cw_break_in = true; has_vox_onoff = true; has_vox_gain = true; has_vox_anti = true; has_vox_hang = true; has_compON = true; has_compression = true; has_split = true; has_split_AB = true; has_micgain_control = true; has_bandwidth_control = true; has_smeter = true; has_voltmeter = true; has_power_out = true; has_swr_control = true; has_alc_control = true; has_idd_control = true; has_sql_control = true; has_agc_control = true; has_power_control = true; has_volume_control = true; has_mode_control = true; has_attenuator_control = true; has_preamp_control = true; has_noise_control = true; has_nb_level = true; has_noise_reduction = true; has_noise_reduction_control = true; has_auto_notch = true; has_notch_control = true; has_pbt_controls = true; has_FILTER = true; has_rf_control = true; has_ptt_control = true; has_tune_control = true; has_band_selection = true; has_xcvr_auto_on_off = true; precision = 1; ndigits = 9; has_vfo_adj = true; can_change_alt_vfo = true; has_a2b = true; CW_sense = 0; // CW is LSB }; static inline void minmax(int min, int max, int &val) { if (val > max) val = max; if (val < min) val = min; } void RIG_IC705::selectA() { cmd.assign(pre_to).append("\x07"); cmd += '\x00'; cmd.append(post); waitFB("select A"); isett("selectA"); inuse = onA; } void RIG_IC705::selectB() { cmd.assign(pre_to).append("\x07"); cmd += '\x01'; cmd.append(post); waitFB("select B"); isett("selectB"); inuse = onB; } //====================================================================== // IC705 unique commands //====================================================================== void RIG_IC705::swapAB() { cmd = pre_to; cmd += 0x07; cmd += 0xB0; cmd.append(post); waitFB("Exchange vfos"); get_modeA(); // get mode to update the filter A / B usage get_modeB(); } void RIG_IC705::set_xcvr_auto_on() { cmd = pre_to; cmd += '\x19'; cmd += '\x00'; get_trace(1, "getID()"); cmd.append(post); RigSerial->failed(0); if (waitFOR(8, "get ID") == false) { cmd.clear(); int fes[] = { 2, 2, 2, 3, 7, 13, 25, 50, 75, 150, 150, 150 }; if (progStatus.serial_baudrate >= 0 && progStatus.serial_baudrate <= 11) { cmd.append( fes[progStatus.serial_baudrate], '\xFE'); } RigSerial->WriteBuffer(cmd.c_str(), cmd.length()); cmd.assign(pre_to); cmd += '\x18'; cmd += '\x01'; set_trace(1, "power_on()"); cmd.append(post); RigSerial->failed(0); if (waitFB("Power ON")) { isett("power_on()"); cmd = pre_to; cmd += '\x19'; cmd += '\x00'; get_trace(1, "getID()"); cmd.append(post); int i = 0; for (i = 0; i < 150; i++) { // 15 second total timeout if (waitFOR(8, "get ID", 100) == true) { RigSerial->failed(0); return; } update_progress(i / 2); Fl::awake(); } RigSerial->failed(0); return; } isett("power_on()"); RigSerial->failed(1); return; } } void RIG_IC705::set_xcvr_auto_off() { cmd.clear(); cmd.append(pre_to); cmd += '\x18'; cmd += '\x00'; cmd.append(post); waitFB("Power OFF", 200); } bool RIG_IC705::check () { std::string resp = pre_fm; resp += '\x03'; cmd = pre_to; cmd += '\x03'; cmd.append( post ); bool ok = waitFOR(11, "check vfo"); isett("check vfo"); return ok; } unsigned long long RIG_IC705::get_vfoA () { std::string resp; cmd.assign(pre_to).append("\x25"); resp.assign(pre_fm).append("\x25"); if (inuse == onB) { cmd += '\x01'; resp += '\x01'; } else { cmd += '\x00'; resp += '\x00'; } cmd.append(post); if (waitFOR(12, "get vfo A")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { if (replystr[p+6] == -1) A.freq = 0; else A.freq = fm_bcd_be(replystr.substr(p+6), 10); } } igett("get_vfoA"); return A.freq; } void RIG_IC705::set_vfoA (unsigned long long freq) { A.freq = freq; cmd.assign(pre_to).append("\x25"); if (inuse == onB) cmd += '\x01'; else cmd += '\x00'; cmd.append( to_bcd_be( freq, 10) ); cmd.append( post ); waitFB("set vfo A"); isett("set_vfoA"); } unsigned long long RIG_IC705::get_vfoB () { std::string resp; cmd.assign(pre_to).append("\x25"); resp.assign(pre_fm).append("\x25"); if (inuse == onB) { cmd += '\x00'; resp += '\x00'; } else { cmd += '\x01'; resp += '\x01'; } cmd.append(post); if (waitFOR(12, "get vfo B")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { if (replystr[p+6] == -1) A.freq = 0; else B.freq = fm_bcd_be(replystr.substr(p+6), 10); } } igett("get_vfoB"); return B.freq; } void RIG_IC705::set_vfoB (unsigned long long freq) { B.freq = freq; cmd.assign(pre_to).append("\x25"); if (inuse == onB) cmd += '\x00'; else cmd += '\x01'; cmd.append( to_bcd_be( freq, 10 ) ); cmd.append( post ); waitFB("set vfo B"); isett("set_vfoB"); } // expecting // 0 1 2 3 4 5 6 7 8 9 // FE FE E0 94 26 NN NN NN NN FD // | | | | // | | | |__filter setting, 01, 02, 03 // | | |_____data mode, 00 - off, 01 - on // | |________Mode 00 - LSB // | 01 - USB // | 02 - AM // | 03 - CW // | 04 - RTTY // | 05 - FM // | 07 - CW-R // | 08 - RTTY-R // | 17 - DV // |___________selected vfo, 00 - active, 01 - inactive int RIG_IC705::get_modeA() { int md = 0; size_t p; std::string resp; cmd.assign(pre_to).append("\x26"); resp.assign(pre_fm).append("\x26"); if (inuse == onB) cmd += '\x01'; else cmd += '\x00'; cmd.append(post); if (waitFOR(10, "get mode A")) { p = replystr.rfind(resp); if (p == std::string::npos) goto end_wait_modeA; if (replystr[p+6] == -1) { md = A.imode = 0; } else { for (md = 0; md <= DV705; md++) { if (replystr[p+6] == IC705_mode_nbr[md]) { A.imode = md; if (replystr[p+7] == 0x01 && A.imode < CW705) A.imode += 8; if (A.imode > DV705) A.imode = 1; break; } } A.filter = replystr[p+8]; if (A.filter > 0 && A.filter < 4) mode_filterA[A.imode] = A.filter; } } end_wait_modeA: get_trace(4, "get mode A[", IC705modes_[A.imode].c_str(), "] ", str2hex(replystr.c_str(), replystr.length())); if (A.imode == CW705 || A.imode == CWR705) { cmd.assign(pre_to).append("\x1A\x05"); cmd += '\x00'; cmd += '\x53'; cmd.append(post); resp.assign(pre_fm).append("\x1A\x05"); resp += '\x00'; resp += '\x53'; if (waitFOR(10, "get CW sideband")) { p = replystr.rfind(resp); CW_sense = replystr[p+8]; if (CW_sense) { IC705_mode_type[CW705] = 'U'; IC705_mode_type[CWR705] = 'L'; } else { IC705_mode_type[CW705] = 'L'; IC705_mode_type[CWR705] = 'U'; } } get_trace(2, "get CW sideband ", str2hex(replystr.c_str(), replystr.length())); } return A.imode; } // LSB USB AM CW RTTY FM CW-R RTTY-R LSB-D USB-D // 0 1 2 3 4 5 6 7 8 9 void RIG_IC705::set_modeA(int val) { A.imode = val; cmd.assign(pre_to); cmd += '\x26'; if (inuse == onB) cmd += '\x01'; // unselected vfo else cmd += '\x00'; // selected vfo cmd += IC705_mode_nbr[A.imode]; // operating mode if (A.imode >= LSBD705 && A.imode < DV705) cmd += '\x01'; // data mode else cmd += '\x00'; cmd += mode_filterA[A.imode]; // filter cmd.append( post ); waitFB("set mode A"); set_trace(4, "set mode A[", IC705modes_[A.imode].c_str(), "] ", str2hex(replystr.c_str(), replystr.length())); } int RIG_IC705::get_modeB() { int md = 0; size_t p; std::string resp; cmd.assign(pre_to).append("\x26"); resp.assign(pre_fm).append("\x26"); if (inuse == onB) cmd += '\x00'; // active vfo else cmd += '\x01'; // inactive vfo cmd.append(post); if (waitFOR(10, "get mode B")) { p = replystr.rfind(resp); if (p == std::string::npos) goto end_wait_modeB; if (replystr[p+6] == -1) { md = filA = 0; } else { for (md = 0; md < LSBD705; md++) { if (replystr[p+6] == IC705_mode_nbr[md]) { B.imode = md; if (replystr[p+7] == 0x01 && B.imode < CW705) B.imode += 8; if (B.imode > DV705) B.imode = 1; break; } } B.filter = replystr[p+8]; } } end_wait_modeB: get_trace(4, "get mode B[", IC705modes_[B.imode].c_str(), "] ", str2hex(replystr.c_str(), replystr.length())); if (B.filter > 0 && B.filter < 4) mode_filterB[B.imode] = B.filter; get_trace(4, "get mode A[", IC705modes_[B.imode].c_str(), "] ", str2hex(replystr.c_str(), replystr.length())); if (B.imode == CW705 || B.imode == CWR705) { cmd.assign(pre_to).append("\x1A\x05"); cmd += '\x00'; cmd += '\x53'; cmd.append(post); resp.assign(pre_fm).append("\x1A\x05"); resp += '\x00'; resp += '\x53'; if (waitFOR(10, "get CW sideband")) { p = replystr.rfind(resp); CW_sense = replystr[p+8]; if (CW_sense) { IC705_mode_type[CW705] = 'U'; IC705_mode_type[CWR705] = 'L'; } else { IC705_mode_type[CW705] = 'L'; IC705_mode_type[CWR705] = 'U'; } } get_trace(2, "get CW sideband ", str2hex(replystr.c_str(), replystr.length())); } return B.imode; } void RIG_IC705::set_modeB(int val) { B.imode = val; cmd.assign(pre_to); cmd += '\x26'; if (inuse == onB) cmd += '\x00'; // selected vfo else cmd += '\x01'; // unselected vfo cmd += IC705_mode_nbr[B.imode]; // operating mode if (B.imode >= LSBD705 && B.imode < DV705) cmd += '\x01'; // data mode else cmd += '\x00'; cmd += mode_filterB[B.imode]; // filter cmd.append( post ); waitFB("set mode B"); set_trace(4, "set mode B[", IC705modes_[B.imode].c_str(), "] ", str2hex(replystr.c_str(), replystr.length())); } int RIG_IC705::get_FILT(int mode) { if (inuse == onB) return mode_filterB[mode]; return mode_filterA[mode]; } void RIG_IC705::set_FILT(int filter) { if (filter < 1 || filter > 3) return; if (inuse == onB) { B.filter = filter; mode_filterB[B.imode] = filter; cmd.assign(pre_to); cmd += '\x26'; cmd += '\x00'; // selected vfo cmd += IC705_mode_nbr[B.imode]; // operating mode if (B.imode >= LSBD705) cmd += '\x01'; // data mode else cmd += '\x00'; cmd += filter; // filter cmd.append( post ); waitFB("set mode/filter B"); set_trace(4, "set mode/filter B[", IC705modes_[B.imode].c_str(), "] ", str2hex(replystr.c_str(), replystr.length())); } else { A.filter = filter; mode_filterA[A.imode] = filter; cmd.assign(pre_to); cmd += '\x26'; cmd += '\x00'; // selected vfo cmd += IC705_mode_nbr[A.imode]; // operating mode if (A.imode >= LSBD705) cmd += '\x01'; // data mode else cmd += '\x00'; cmd += filter; // filter cmd.append( post ); waitFB("set mode/filter A"); set_trace(4, "set mode/filter A[", IC705modes_[A.imode].c_str(), "] ", str2hex(replystr.c_str(), replystr.length())); } } const char *RIG_IC705::FILT(int val) { if (val < 1) val = 1; if (val > 3) val = 3; return(szfilter[val - 1]); } const char * RIG_IC705::nextFILT() { int val = A.filter; if (inuse == onB) val = B.filter; val++; if (val > 3) val = 1; set_FILT(val); return szfilter[val - 1]; } void RIG_IC705::set_FILTERS(std::string s) { std::stringstream strm; strm << s; for (int i = 0; i < NUM_MODES; i++) strm >> mode_filterA[i]; for (int i = 0; i < NUM_MODES; i++) strm >> mode_filterB[i]; for (int i = 0; i < NUM_MODES; i++) { if (mode_filterA[i] < 1) mode_filterA[i] = 1; if (mode_filterA[i] > 3) mode_filterA[i] = 3; if (mode_filterB[i] < 1) mode_filterB[i] = 1; if (mode_filterB[i] > 3) mode_filterB[i] = 3; } } std::string RIG_IC705::get_FILTERS() { std::stringstream s; for (int i = 0; i < NUM_MODES; i++) { if (mode_filterA[i] < 1) mode_filterA[i] = 1; if (mode_filterA[i] > 3) mode_filterA[i] = 3; if (mode_filterB[i] < 1) mode_filterB[i] = 1; if (mode_filterB[i] > 3) mode_filterB[i] = 3; } for (int i = 0; i < NUM_MODES; i++) s << mode_filterA[i] << " "; for (int i = 0; i < NUM_MODES; i++) s << mode_filterB[i] << " "; return s.str(); } std::string RIG_IC705::get_BANDWIDTHS() { std::stringstream s; for (int i = 0; i < NUM_MODES; i++) s << mode_bwA[i] << " "; for (int i = 0; i < NUM_MODES; i++) s << mode_bwB[i] << " "; return s.str(); } void RIG_IC705::set_BANDWIDTHS(std::string s) { std::stringstream strm; strm << s; for (int i = 0; i < NUM_MODES; i++) strm >> mode_bwA[i]; for (int i = 0; i < NUM_MODES; i++) strm >> mode_bwB[i]; } bool RIG_IC705::can_split() { return true; } void RIG_IC705::set_split(bool val) { split = val; cmd = pre_to; cmd += 0x0F; cmd += val ? 0x01 : 0x00; cmd.append(post); waitFB(val ? "set split ON" : "set split OFF"); isett("set_split"); } int RIG_IC705::get_split() { int read_split = 0; cmd.assign(pre_to); cmd.append("\x0F"); cmd.append( post ); if (waitFOR(7, "get split")) { std::string resp = pre_fm; resp.append("\x0F"); size_t p = replystr.find(resp); if (p != std::string::npos) read_split = replystr[p+5]; if (read_split != 0xFA) // fail byte split = read_split; } igett("get_split"); return split; } int RIG_IC705::get_bwA() { if (A.imode == 3 || A.imode == 11) return 0; // FM, FM-D int current_vfo = inuse; if (current_vfo == onB) selectA(); cmd = pre_to; cmd.append("\x1a\x03"); cmd.append(post); int bwval = A.iBW; if (waitFOR(8, "get_bwA")) { std::string resp = pre_fm; resp.append("\x1A\x03"); size_t p = replystr.find(resp); if (p != std::string::npos) bwval = fm_bcd(replystr.substr(p+6), 2); } if (bwval != A.iBW) { A.iBW = bwval; mode_bwA[A.imode] = bwval; } if (current_vfo == onB) selectB(); igett("get_bwA"); return A.iBW; } void RIG_IC705::set_bwA(int val) { if (A.imode == 3 || A.imode == 11) return; // FM, FM-D A.iBW = val; int current_vfo = inuse; if (current_vfo == onB) selectA(); cmd = pre_to; cmd.append("\x1a\x03"); cmd.append(to_bcd(A.iBW, 2)); cmd.append(post); waitFB("set bwA"); mode_bwA[A.imode] = val; isett("set_bwA"); if (current_vfo == onB) selectB(); } int RIG_IC705::get_bwB() { if (B.imode == 3 || B.imode == 11) return 0; // FM, FM-D int current_vfo = inuse; if (current_vfo == onA) selectB(); cmd = pre_to; cmd.append("\x1a\x03"); cmd.append(post); int bwval = B.iBW; if (waitFOR(8, "get_bwB")) { std::string resp = pre_fm; resp.append("\x1A\x03"); size_t p = replystr.find(resp); if (p != std::string::npos) bwval = fm_bcd(replystr.substr(p+6), 2); } if (bwval != B.iBW) { B.iBW = bwval; mode_bwB[B.imode] = bwval; } if (current_vfo == onA) selectA(); igett("get_bwB"); return B.iBW; } void RIG_IC705::set_bwB(int val) { if (B.imode == 3 || B.imode == 11) return; // FM, FM-D B.iBW = val; int current_vfo = inuse; if (current_vfo == onA) selectB(); cmd = pre_to; cmd.append("\x1a\x03"); cmd.append(to_bcd(B.iBW, 2)); cmd.append(post); waitFB("set bwB"); mode_bwB[B.imode] = val; isett("set_bwB"); if (current_vfo == onA) selectA(); } // LSB USB AM FM CW CW-R RTTY RTTY-R LSB-D USB-D AM-D FM-D // 0 1 2 3 4 5 6 7 8 9 10 11 int RIG_IC705::adjust_bandwidth(int m) { int bw = 0; switch (m) { case 2: case 10: // AM, AM-D bandwidths_ = IC705_am_bws; bw_vals_ = IC705_bw_vals_AM; bw = 19; break; case 3: case 11: case 12: // FM, FM-D, DV bandwidths_ = IC705_fm_bws; bw_vals_ = IC705_bw_vals_FM; bw = 0; break; case 6: case 7: // RTTY, RTTY-R bandwidths_ = IC705_rtty_bws; bw_vals_ = IC705_bw_vals_RTTY; bw = 12; break; case 4: case 5: // CW, CW -R bandwidths_ = IC705_ssb_bws; bw_vals_ = IC705_bw_vals_SSB; bw = 12; break; case 0: case 1: // LSB, USB case 8: case 9: // LSB-D, USB-D default: bandwidths_ = IC705_ssb_bws; bw_vals_ = IC705_bw_vals_SSB; bw = 34; } return bw; } std::vector& RIG_IC705::bwtable(int m) { switch (m) { case 2: case 10: // AM, AM-D return IC705_am_bws; break; case 3: case 11: case 12: // FM, FM-D, DV return IC705_fm_bws; break; case 6: case 7: // RTTY, RTTY-R return IC705_rtty_bws; break; case 4: case 5: // CW, CW -R case 0: case 1: // LSB, USB case 8: case 9: // LSB-D, USB-D default: return IC705_ssb_bws; } return IC705_ssb_bws; } int RIG_IC705::def_bandwidth(int m) { int bw = adjust_bandwidth(m); if (inuse == onB) { if (mode_bwB[m] == -1) mode_bwB[m] = bw; return mode_bwB[m]; } if (mode_bwA[m] == -1) mode_bwA[m] = bw; return mode_bwA[m]; } int RIG_IC705::get_mic_gain() { int val = 0; std::string cstr = "\x14\x0B"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append(post); if (waitFOR(9, "get mic")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) val = num100(replystr.substr(p + 6)); } return val; } void RIG_IC705::set_mic_gain(int val) { cmd = pre_to; cmd.append("\x14\x0B"); cmd.append(bcd255(val)); cmd.append( post ); waitFB("set mic gain"); } void RIG_IC705::get_mic_gain_min_max_step(int &min, int &max, int &step) { min = 0; max = 100; step = 1; } static int comp_level[] = {11,34,58,81,104,128,151,174,197,221,244}; void RIG_IC705::set_compression(int on, int val) { cmd = pre_to; cmd.append("\x16\x44"); if (on) cmd += '\x01'; else cmd += '\x00'; cmd.append(post); waitFB("set Comp ON/OFF"); if (val < 0) return; if (val > 10) return; cmd.assign(pre_to).append("\x14\x0E"); cmd.append(to_bcd(comp_level[val], 3)); cmd.append( post ); waitFB("set comp"); } void RIG_IC705::get_compression(int &on, int &val) { std::string resp; cmd.assign(pre_to).append("\x16\x44").append(post); resp.assign(pre_fm).append("\x16\x44"); if (waitFOR(8, "get comp on/off")) { size_t p = replystr.find(resp); if (p != std::string::npos) on = (replystr[p+6] == 0x01); } cmd.assign(pre_to).append("\x14\x0E").append(post); resp.assign(pre_fm).append("\x14\x0E"); if (waitFOR(9, "get comp level")) { size_t p = replystr.find(resp); int level = 0; if (p != std::string::npos) { level = fm_bcd(replystr.substr(p+6), 3); for (val = 0; val < 11; val++) if (level <= comp_level[val]) break; } } } void RIG_IC705::set_vox_onoff() { if (progStatus.vox_onoff) { cmd.assign(pre_to).append("\x16\x46\x01"); cmd.append( post ); waitFB("set vox ON"); } else { cmd.assign(pre_to).append("\x16\x46"); cmd += '\x00'; cmd.append( post ); waitFB("set vox OFF"); } } // Xcvr values range 0...255 step 1 void RIG_IC705::get_vox_gain_min_max_step(int &min, int &max, int &step) { min = 0; max = 100; step = 1; } void RIG_IC705::set_vox_gain() { int vox_gain = round((progStatus.vox_gain * 255 / 100 + 0.5)); minmax(0, 255, vox_gain); cmd.assign(pre_to).append("\x14\x16"); cmd.append(to_bcd(vox_gain, 3)); cmd.append( post ); waitFB("SET vox gain"); } // Xcvr values range 0...255 step 1 void RIG_IC705::get_vox_anti_min_max_step(int &min, int &max, int &step) { min = 0; max = 100; step = 1; } void RIG_IC705::set_vox_anti() { int vox_anti = round((progStatus.vox_anti * 255 / 100 + 0.5)); minmax(0, 255, vox_anti); cmd.assign(pre_to).append("\x14\x17"); cmd.append(to_bcd(vox_anti, 3)); cmd.append( post ); waitFB("SET anti-vox"); } // VOX hang 0.0 - 2.0, step 0.1 // Xcvr values 0..20 step 1 void RIG_IC705::get_vox_hang_min_max_step(int &min, int &max, int &step) { min = 0; max = 20; step = 1; } void RIG_IC705::set_vox_hang() { cmd.assign(pre_to).append("\x1A\x05\x01\x91"); cmd.append(to_bcd(progStatus.vox_hang, 2)); cmd.append( post ); waitFB("SET vox hang"); } //---------------------------------------------------------------------- // CW controls void RIG_IC705::get_cw_wpm_min_max(int &min, int &max) { min = 6; max = 48; } void RIG_IC705::set_cw_wpm() { int iwpm = round((progStatus.cw_wpm - 6) * 255 / 42 + 0.5); minmax(0, 255, iwpm); cmd.assign(pre_to).append("\x14\x0C"); cmd.append(to_bcd(iwpm, 3)); cmd.append( post ); waitFB("SET cw wpm"); } void RIG_IC705::set_break_in() { // 16 47 00 break-in off // 16 47 01 break-in semi // 16 47 02 break-in full cmd.assign(pre_to).append("\x16\x47"); switch (progStatus.break_in) { case 2: cmd += '\x02'; break_in_label("FULL"); break; case 1: cmd += '\x01'; break_in_label("SEMI"); break; case 0: default: cmd += '\x00'; break_in_label("BK-IN"); } cmd.append(post); waitFB("SET break-in"); } int RIG_IC705::get_break_in() { cmd.assign(pre_to).append("\x16\x47").append(post); std::string resp; resp.assign(pre_fm); if (waitFOR(8, "get break in")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { progStatus.break_in = replystr[p+6]; if (progStatus.break_in == 0) break_in_label("qsk"); else if (progStatus.break_in == 1) break_in_label("SEMI"); else break_in_label("FULL"); } } return progStatus.break_in; } void RIG_IC705::get_cw_qsk_min_max_step(double &min, double &max, double &step) { min = 2.0; max = 13.0; step = 0.1; } void RIG_IC705::set_cw_qsk() { int qsk = round ((progStatus.cw_qsk - 2.0) * 255.0 / 11.0 + 0.5); minmax(0, 255, qsk); cmd.assign(pre_to).append("\x14\x0F"); cmd.append(to_bcd(qsk, 3)); cmd.append(post); waitFB("Set cw qsk delay"); } void RIG_IC705::get_cw_spot_tone_min_max_step(int &min, int &max, int &step) { min = 300; max = 900; step = 5; } void RIG_IC705::set_cw_spot_tone() { cmd.assign(pre_to).append("\x14\x09"); // values 0=300Hz 255=900Hz int n = round((progStatus.cw_spot_tone - 300) * 255.0 / 600.0 + 0.5); minmax(0, 255, n); cmd.append(to_bcd(n, 3)); cmd.append( post ); waitFB("SET cw spot tone"); } void RIG_IC705::set_cw_vol() { cmd.assign(pre_to); cmd.append("\x1A\x05"); cmd += '\x00'; cmd += '\x24'; cmd.append(to_bcd((int)(progStatus.cw_vol * 2.55), 3)); cmd.append( post ); waitFB("SET cw sidetone volume"); } // Tranceiver PTT on/off void RIG_IC705::set_PTT_control(int val) { cmd = pre_to; cmd += '\x1c'; cmd += '\x00'; cmd += (unsigned char) val; cmd.append( post ); waitFB("set ptt"); ptt_ = val; } int RIG_IC705::get_PTT() { cmd = pre_to; cmd += '\x1c'; cmd += '\x00'; std::string resp = pre_fm; resp += '\x1c'; resp += '\x00'; cmd.append(post); if (waitFOR(8, "get PTT")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) ptt_ = replystr[p + 6]; } return ptt_; } // Volume control val 0 ... 100 void RIG_IC705::set_volume_control(int val) { cmd = pre_to; cmd.append("\x14\x01"); cmd.append(bcd255(val)); cmd.append( post ); waitFB("set vol"); } /* I:12:20:22: get vol ans in 0 ms, OK cmd FE FE 7A E0 14 01 FD ans FE FE 7A E0 14 01 FD FE FE E0 7A 14 01 00 65 FD 0 1 2 3 4 5 6 7 8 */ int RIG_IC705::get_volume_control() { int val = 0; std::string cstr = "\x14\x01"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append( post ); if (waitFOR(9, "get vol")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) val = num100(replystr.substr(p + 6)); } return (val); } void RIG_IC705::get_vol_min_max_step(int &min, int &max, int &step) { min = 0; max = 100; step = 1; } void RIG_IC705::set_power_control(double val) { cmd = pre_to; cmd.append("\x14\x0A"); cmd.append(bcd255(val * 10)); cmd.append( post ); set_trace(2, "set_power_control()", str2hex(cmd.c_str(), cmd.length())); waitFB("set power"); } double RIG_IC705::get_power_control() { int val = progStatus.power_level; std::string cstr = "\x14\x0A"; std::string resp = pre_fm; cmd = pre_to; cmd.append(cstr).append(post); resp.append(cstr); if (waitFOR(9, "get power")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) val = num100(replystr.substr(p+6)) / 10; } get_trace(2, "get_power_control()", str2hex(replystr.c_str(), replystr.length())); return val; } void RIG_IC705::get_pc_min_max_step(double &min, double &max, double &step) { min = 0; max = 10.0; step = 0.1; } int RIG_IC705::get_smeter() { std::string cstr = "\x15\x02"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append( post ); int mtr= -1; if (waitFOR(9, "get smeter")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { mtr = fm_bcd(replystr.substr(p+6), 3); mtr = (int)ceil(mtr /2.41); if (mtr > 100) mtr = 100; } } return mtr; } double RIG_IC705::get_voltmeter() { std::string cstr = "\x15\x15"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append( post ); int mtr = 0; double val = 0; get_trace(1, "get_voltmeter()"); int ret = waitFOR(9, "get voltmeter"); geth(); if (ret) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { mtr = fm_bcd(replystr.substr(p+6), 3); val = 16.0 * mtr / 241.0; return val; } } return -1; } static meterpair pwrtbl[] = { {0, 0.0}, {26, 0.5}, {52, 1.0}, {80, 2.0}, {104, 3.0}, {122, 4.0}, {143, 5.0}, {158, 6.0}, {174, 7.0}, {191, 8.0}, {210, 9.0}, {228, 10.0}, {245, 11.0}, {255, 11.6} }; int RIG_IC705::get_power_out(void) { std::string cstr = "\x15\x11"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append( post ); int mtr= 0; int ret = waitFOR(9, "get power out"); igett("get power out"); if (ret) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { mtr = fm_bcd(replystr.substr(p+6), 3); size_t i = 0; for (i = 0; i < sizeof(pwrtbl) / sizeof(*pwrtbl) - 1; i++) if (mtr >= pwrtbl[i].mtr && mtr < pwrtbl[i+1].mtr) break; if (mtr < 0) mtr = 0; if (mtr > 255) mtr = 255; mtr = (int)ceil(pwrtbl[i].val + (pwrtbl[i+1].val - pwrtbl[i].val)*(mtr - pwrtbl[i].mtr)/(pwrtbl[i+1].mtr - pwrtbl[i].mtr)); if (mtr > 100) mtr = 100; } } return mtr; } // Table entries below correspond to SWR readings of 1.1, 1.5, 2.0, 2.5, 3.0 and infinity. // Values are also tweaked to fit the display of the SWR meter. static meterpair swrtbl[] = { {0, 0.0}, {48, 10.5}, {80, 23.0}, {103, 35.0}, {120, 48.0}, {255, 100.0 } }; int RIG_IC705::get_swr(void) { std::string cstr = "\x15\x12"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append( post ); int mtr= -1; if (waitFOR(9, "get swr")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { mtr = fm_bcd(replystr.substr(p+6), 3); size_t i = 0; for (i = 0; i < sizeof(swrtbl) / sizeof(*swrtbl) - 1; i++) if (mtr >= swrtbl[i].mtr && mtr < swrtbl[i+1].mtr) break; if (mtr < 0) mtr = 0; if (mtr > 255) mtr = 255; mtr = (int)ceil(swrtbl[i].val + (swrtbl[i+1].val - swrtbl[i].val)*(mtr - swrtbl[i].mtr)/(swrtbl[i+1].mtr - swrtbl[i].mtr)); if (mtr > 100) mtr = 100; } } return mtr; } int RIG_IC705::get_alc(void) { std::string cstr = "\x15\x13"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append( post ); int mtr= -1; if (waitFOR(9, "get alc")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { mtr = fm_bcd(replystr.substr(p+6), 3); mtr = (int)ceil(mtr /1.2); if (mtr > 100) mtr = 100; } } return mtr; } double RIG_IC705::get_idd(void) { get_trace(1, "get_idd()"); std::string cstr = "\x15\x16"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append( post ); double mtr= 0; int ret = waitFOR(9, "get idd"); igett(""); if (ret) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { mtr = fm_bcd(replystr.substr(p+6), 3); mtr = 4.0 * mtr / 241.0; if (mtr > 4) mtr = 4; } } return mtr; } void RIG_IC705::set_rf_gain(int val) { cmd = pre_to; cmd.append("\x14\x02"); cmd.append(bcd255(val)); cmd.append( post ); waitFB("set RF"); } int RIG_IC705::get_rf_gain() { int val = progStatus.rfgain; std::string cstr = "\x14\x02"; std::string resp = pre_fm; cmd = pre_to; cmd.append(cstr).append(post); resp.append(cstr); if (waitFOR(9, "get RF")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) val = num100(replystr.substr(p + 6)); } return val; } void RIG_IC705::get_rf_min_max_step(double &min, double &max, double &step) { min = 0; max = 100; step = 1; } int RIG_IC705::next_preamp() { if (atten_state == 1) return preamp_state; switch (preamp_state) { case 0: return 1; case 1: return 2; case 2: return 0; } return 0; } void RIG_IC705::set_preamp(int val) { cmd = pre_to; cmd += '\x16'; cmd += '\x02'; preamp_state = val; cmd += (unsigned char)preamp_state; cmd.append( post ); waitFB( (preamp_state == 0) ? "set Preamp OFF" : (preamp_state == 1) ? "set Preamp Level 1" : "set Preamp Level 2"); } int RIG_IC705::get_preamp() { std::string cstr = "\x16\x02"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append( post ); if (waitFOR(8, "get Preamp Level")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { preamp_state = replystr[p+6]; } } return preamp_state; } void RIG_IC705::set_attenuator(int val) { if (val) { atten_state = 1; } else { atten_state = 0; } cmd = pre_to; cmd += '\x11'; cmd += atten_state ? '\x20' : '\x00'; cmd.append( post ); waitFB("set att"); } int RIG_IC705::next_attenuator() { if (atten_state) return 0; return 1; } int RIG_IC705::get_attenuator() { cmd = pre_to; cmd += '\x11'; cmd.append( post ); std::string resp = pre_fm; resp += '\x11'; if (waitFOR(7, "get ATT")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { if (replystr[p+5] == 0x20) { atten_state = 1; return 1; } else { atten_state = 0; return 0; } } } return 0; } void RIG_IC705::set_noise(bool val) { cmd = pre_to; cmd.append("\x16\x22"); cmd += val ? 1 : 0; cmd.append(post); waitFB("set noise"); } int RIG_IC705::get_noise() { int val = progStatus.noise; std::string cstr = "\x16\x22"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append(post); if (waitFOR(8, "get noise")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { val = replystr[p+6]; } } return val; } void RIG_IC705::set_nb_level(int val) { cmd = pre_to; cmd.append("\x14\x12"); cmd.append(bcd255(val)); cmd.append( post ); waitFB("set NB level"); } int RIG_IC705::get_nb_level() { int val = progStatus.nb_level; std::string cstr = "\x14\x12"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append(post); if (waitFOR(9, "get NB level")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) val = num100(replystr.substr(p+6)); } return val; } void RIG_IC705::set_noise_reduction(int val) { cmd = pre_to; cmd.append("\x16\x40"); cmd += val ? 1 : 0; cmd.append(post); waitFB("set NR"); } int RIG_IC705::get_noise_reduction() { std::string cstr = "\x16\x40"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append(post); if (waitFOR(8, "get NR")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) return (replystr[p+6] ? 1 : 0); } return progStatus.noise_reduction; } /* I:12:06:50: get NR ans in 0 ms, OK cmd FE FE 7A E0 16 40 FD ans FE FE 7A E0 16 40 FD FE FE E0 7A 16 40 01 FD 0 1 2 3 4 5 6 7 I:12:06:50: get NRval ans in 0 ms, OK cmd FE FE 7A E0 14 06 FD ans FE FE 7A E0 14 06 FD FE FE E0 7A 14 06 00 24 FD 0 1 2 3 4 5 6 7 8 */ void RIG_IC705::set_noise_reduction_val(int val) { cmd = pre_to; cmd.append("\x14\x06"); val *= 16; val += 8; cmd.append(to_bcd(val, 3)); cmd.append(post); waitFB("set NRval"); } int RIG_IC705::get_noise_reduction_val() { int val = progStatus.noise_reduction_val; std::string cstr = "\x14\x06"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append(post); if (waitFOR(9, "get NRval")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { val = fm_bcd(replystr.substr(p+6),3); val -= 8; val /= 16; } } return val; } void RIG_IC705::set_squelch(int val) { cmd = pre_to; cmd.append("\x14\x03"); cmd.append(bcd255(val)); cmd.append( post ); waitFB("set Sqlch"); } int RIG_IC705::get_squelch() { int val = progStatus.squelch; std::string cstr = "\x14\x03"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append(post); if (waitFOR(9, "get squelch")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) val = num100(replystr.substr(p+6)); } return val; } void RIG_IC705::set_auto_notch(int val) { progStatus.auto_notch = an_level = val; cmd = pre_to; cmd += '\x16'; cmd += '\x41'; cmd += (unsigned char)val; cmd.append( post ); waitFB("set AN"); auto_notch_label(an_label(), an_level ? true : false); } int RIG_IC705::get_auto_notch() { std::string cstr = "\x16\x41"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append( post ); if (waitFOR(8, "get AN")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { progStatus.auto_notch = an_level = replystr[p+6]; auto_notch_label(an_label(), an_level ? true : false); } } return progStatus.auto_notch; } void RIG_IC705::set_notch(bool on, int freq) { int hexval; switch (vfo->imode) { default: case USB705: case USBD705: case RTTYR705: case DV705: hexval = freq - 1500; break; case LSB705: case LSBD705: case RTTY705: hexval = 1500 - freq; break; case CW705: if (CW_sense) hexval = freq - progStatus.cw_spot_tone; else hexval = progStatus.cw_spot_tone - freq; break; case CWR705: if (CW_sense) hexval = progStatus.cw_spot_tone - freq; else hexval = freq - progStatus.cw_spot_tone; break; } hexval /= 20; hexval += 128; if (hexval < 0) hexval = 0; if (hexval > 255) hexval = 255; cmd = pre_to; cmd.append("\x16\x48"); cmd += on ? '\x01' : '\x00'; cmd.append(post); waitFB("set notch"); set_trace(2, "set_notch() ", str2hex(cmd.c_str(), cmd.length())); cmd = pre_to; cmd.append("\x14\x0D"); cmd.append(to_bcd(hexval,3)); cmd.append(post); waitFB("set notch val"); set_trace(2, "set_notch_val() ", str2hex(cmd.c_str(), cmd.length())); } bool RIG_IC705::get_notch(int &val) { bool on = false; val = 1500; std::string cstr = "\x16\x48"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append( post ); if (waitFOR(8, "get notch")) { get_trace(2, "get_notch()", str2hex(replystr.c_str(), replystr.length())); size_t p = replystr.rfind(resp); if (p != std::string::npos) on = replystr[p + 6]; cmd = pre_to; resp = pre_fm; cstr = "\x14\x0D"; cmd.append(cstr); resp.append(cstr); cmd.append(post); if (waitFOR(9, "notch val")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { val = (int)ceil(fm_bcd(replystr.substr(p+6),3)); val -= 128; val *= 20; switch (vfo->imode) { default: case USB705: case USBD705: case RTTYR705: case DV705: val = 1500 + val; break; case LSB: case LSBD705: case RTTY705: val = 1500 - val; break; case CW705: if (CW_sense) val = progStatus.cw_spot_tone + val; else val = progStatus.cw_spot_tone - val; break; case CWR705: if (CW_sense) val = progStatus.cw_spot_tone - val; else val = progStatus.cw_spot_tone + val; break; } } get_trace(2, "get_notch_val() ", str2hex(replystr.c_str(), replystr.length())); } } return on; } void RIG_IC705::get_notch_min_max_step(int &min, int &max, int &step) { switch (vfo->imode) { default: case USB705: case USBD705: case RTTYR705: case LSB705: case LSBD705: case RTTY705: case DV705: min = 0; max = 3000; step = 20; break; case CW705: case CWR705: min = progStatus.cw_spot_tone - 500; max = progStatus.cw_spot_tone + 500; step = 20; break; } } int RIG_IC705::get_agc() { cmd = pre_to; cmd.append("\x16\x12"); cmd.append(post); if (waitFOR(8, "get AGC")) { size_t p = replystr.find(pre_fm); if (p != std::string::npos) agcval = replystr[p+6]; // 1 == off, 2 = FAST, 3 = MED, 4 = SLOW } return agcval; } int RIG_IC705::incr_agc() { agcval++; if (agcval == 4) agcval = 1; cmd = pre_to; cmd.append("\x16\x12"); cmd += agcval; cmd.append(post); waitFB("set AGC"); return agcval; } static const char *agcstrs[] = {"AGC", "FST", "MED", "SLO"}; const char *RIG_IC705::agc_label() { return agcstrs[agcval]; } int RIG_IC705::agc_val() { return (agcval); } void RIG_IC705::set_if_shift(int val) { int shift; sh_ = val; if (val == 0) sh_on_ = false; else sh_on_ = true; shift = 128 + val * 128 / 50; if (shift < 0) shift = 0; if (shift > 255) shift = 255; cmd = pre_to; cmd.append("\x14\x07"); cmd.append(to_bcd(shift, 3)); cmd.append(post); waitFB("set IF on/off"); cmd = pre_to; cmd.append("\x14\x08"); cmd.append(to_bcd(shift, 3)); cmd.append(post); waitFB("set IF val"); } bool RIG_IC705::get_if_shift(int &val) { val = sh_; return sh_on_; } void RIG_IC705::get_if_min_max_step(int &min, int &max, int &step) { min = -50; max = +50; step = 1; } void RIG_IC705::set_pbt_inner(int val) { int shift = 128 + val * 128 / 50; if (shift < 0) shift = 0; if (shift > 255) shift = 255; cmd = pre_to; cmd.append("\x14\x07"); cmd.append(to_bcd(shift, 3)); cmd.append(post); isett("set_pbt_inner()"); waitFB("set PBT inner"); } void RIG_IC705::set_pbt_outer(int val) { int shift = 128 + val * 128 / 50; if (shift < 0) shift = 0; if (shift > 255) shift = 255; cmd = pre_to; cmd.append("\x14\x08"); cmd.append(to_bcd(shift, 3)); cmd.append(post); isett("set_pbt_outer()"); waitFB("set PBT outer"); } int RIG_IC705::get_pbt_inner() { int val = 0; std::string cstr = "\x14\x07"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append( post ); if (waitFOR(9, "get pbt inner")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { val = num100(replystr.substr(p+6)); val -= 50; } } igett("get_pbt_inner"); return val; } int RIG_IC705::get_pbt_outer() { int val = 0; std::string cstr = "\x14\x08"; std::string resp = pre_fm; resp.append(cstr); cmd = pre_to; cmd.append(cstr); cmd.append( post ); if (waitFOR(9, "get pbt outer")) { size_t p = replystr.rfind(resp); if (p != std::string::npos) { val = num100(replystr.substr(p+6)); val -= 50; } } igett("get_pbt_outer"); return val; } void RIG_IC705::setVfoAdj(double v) { vfo_ = v; cmd.assign(pre_to); cmd.append("\x1A\x05"); cmd += '\x00'; cmd += '\x89'; cmd.append(bcd255(int(v))); cmd.append(post); waitFB("SET vfo adjust"); } double RIG_IC705::getVfoAdj() { cmd.assign(pre_to); cmd.append("\x1A\x05"); cmd += '\x00'; cmd += '\x89'; cmd.append(post); if (waitFOR(11, "get vfo adj")) { size_t p = replystr.find(pre_fm); if (p != std::string::npos) { vfo_ = num100(replystr.substr(p+8)); } } return vfo_; } /* Received from transceiver: Rx 56 bytes 00 | FE FE E0 A4 04 | 1A 01 band stack register command 06 | 03 register # 3 07 | 01 left side of display 08 | 00 00 05 07 00 frequency 13 | 00 mode 14 | 02 filter # 15 | 00 data mode == 0x01 16 | 00 duplex tone 17 | 00 digital squelch 18 | 00 08 85 repeater tone freq 21 | 00 08 85 tone squelch freq 25 | 00 00 23 dtcs code 27 | 00 digital squelch code 28 | 00 50 00 duplex offset freq 31 | 43 51 43 51 43 51 20 20 destination call 8 chars 39 | 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 register description 16 chars 55 | FD */ // test std::string const char bstack[] = "\ \xFE\xFE\xE0\xA4\x1A\ \x01\x03\x01\ \x00\x00\x05\x07\x00\ \x02\ \x02\ \x01\ \x00\ \x00\ \x00\x08\x85\ \x00\x08\x85\ \x00\x00\x23\ \x00\ \x00\x50\x00\ \x43\x51\x43\x51\x43\x51\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\ \x20\x20\x20\x20\x20\x20\x20\x20\ \xFD\ "; const char reg_strings[] = "W1HKJ 1234567812345678"; const char *sfreq[12] = { "\x00\x00\x91\x01\x00", // 160 "\x00\x00\x57\x03\x00", // 80 "\x00\x00\x07\x07\x00", // 40 "\x00\x00\x14\x10\x00", // 30 "\x00\x00\x07\x14\x00", // 20 "\x00\x80\x06\x18\x00", // 18 "\x00\x00\x07\x21\x00", // 15 "\x00\x00\x07\x24\x00", "\x00\x00\x07\x28\x00", "\x00\x00\x07\x50\x00", "\x00\x00\x07\x44\x01", "\x00\x00\x07\x30\x04" }; void RIG_IC705::get_band_selection(int v) { int v2 = v; switch (v) { case 11: v2 = 13; break; case 12: v2 = 14; break; default: break; } cmd.assign(pre_to); cmd.append("\x1A\x01"); cmd += to_bcd_be( v2, 2 ); cmd += '\x01'; cmd.append( post ); if (waitFOR(56, "get band stack")) { set_trace(2, "get band stack", str2hex(replystr.c_str(), replystr.length())); size_t p = replystr.rfind(pre_fm); if (p != std::string::npos) { int bandfreq = fm_bcd_be(replystr.substr(p + 8, 5), 10); // int bandmode = fm_bcd(replystr.substr(p + 13, 1) ,2); int mode = 0; for (int md = LSB705; md <= DV705; md++) { if (replystr[p + 13] == IC705_mode_nbr[md]) { mode = md; if (replystr[p+15] == 0x01 && mode < CW705) mode += 8; break; } } if (mode > DV705) mode = USB705; int bandfilter = replystr[p+14]; int tone = fm_bcd(replystr.substr(p + 18, 3), 6); tTONE = 0; for (size_t n = 0; n < sizeof(PL_tones) / sizeof(*PL_tones); n++) { if (tone == PL_tones[n]) { tTONE = n; break; } } tone = fm_bcd(replystr.substr(p + 21, 3), 6); rTONE = 0; for (size_t n = 0; n < sizeof(PL_tones) / sizeof(*PL_tones); n++) { if (tone == PL_tones[n]) { rTONE = n; break; } } if (inuse == onB) { set_vfoB(bandfreq); set_modeB(mode); set_FILT(bandfilter); } else { set_vfoA(bandfreq); set_modeA(mode); set_FILT(bandfilter); } } return; } } void RIG_IC705::set_band_selection(int v) { switch (v) { case 11: v = 13; break; case 12: v = 14; break; default: break; } unsigned long long freq = (inuse == onB ? B.freq : A.freq); int fil = (inuse == onB ? B.filter : A.filter); int mode = (inuse == onB ? B.imode : A.imode); cmd.assign(pre_to); cmd += '\x1A'; cmd += '\x01'; cmd += to_bcd_be( v, 2 ); cmd += '\x01'; cmd.append( to_bcd_be( freq, 10 ) ); // freq cmd += IC705_mode_nbr[mode]; // mode cmd += fil; // filter # if (mode >= LSBD705 && mode < DV705) cmd += '\x01'; // data mode else cmd += '\x00'; cmd += '\x00'; cmd += '\x00'; // duplex tone, digital squelch cmd.append(to_bcd(PL_tones[tTONE], 6)); // transmit tone cmd.append(to_bcd(PL_tones[rTONE], 6)); // receive tone cmd += '\x00'; cmd += '\x00'; cmd += '\x23'; // dtcs tone cmd += '\x00'; //digital squelch code cmd += '\x00'; cmd += '\x60'; cmd += '\x00'; // duplex offset cmd.append(" "); cmd.append(" "); cmd.append(post); waitFB("set_band_selection"); isett("set_band_selection"); }