1 // ---------------------------------------------------------------------------- 2 // ICOMkeying.cxx serial string CW interface to Elecraft transceivers 3 // 4 // Copyright (C) 2020 5 // Dave Freese, W1HKJ 6 // 7 // This file is part of fldigi. 8 // 9 // Fldigi is free software: you can redistribute it and/or modify 10 // it under the terms of the GNU General Public License as published by 11 // the Free Software Foundation, either version 3 of the License, or 12 // (at your option) any later version. 13 // 14 // Fldigi is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with fldigi. If not, see <http://www.gnu.org/licenses/>. 21 // ---------------------------------------------------------------------------- 22 23 #include <iostream> 24 #include <string> 25 26 #include "ICOMkeying.h" 27 #include "configuration.h" 28 #include "rigio.h" 29 #include "threads.h" 30 #include "debug.h" 31 #include "rigsupport.h" 32 #include "morse.h" 33 #include "fl_digi.h" 34 #include "util.h" 35 36 int ICOMwpm = 0; 37 bool use_ICOMkeyer = false; 38 static std::string ICOMcmd; 39 static cMorse ICOMmorse; 40 char lastICOMchar = 0; 41 42 static std::string hexvals = "0123456789ABCDEF"; CIVaddr(std::string s)43int CIVaddr(std::string s) 44 { 45 int val = 0; 46 if (s.length() != 2) return 0; 47 if (hexvals.find(s[0]) == std::string::npos) return 0; 48 if (hexvals.find(s[1]) == std::string::npos) return 0; 49 val = hexvals.find(s[0]) * 16 + hexvals.find(s[1]); 50 return val; 51 } 52 ICOMheader()53std::string ICOMheader() 54 { 55 std::string s; 56 s.assign("\xFE\xFE"); 57 s += ((char)CIVaddr(progdefaults.ICOMcivaddr)); 58 s.append("\xE0"); 59 return s; 60 } 61 hexstr(std::string s)62std::string hexstr(std::string s) 63 { 64 std::string hex; 65 for (size_t i = 0; i < s.length(); i++) { 66 hex.append(" x"); 67 hex += hexvals[(s[i] & 0xFF) >> 4]; 68 hex += hexvals[s[i] & 0xF]; 69 } 70 return hex; 71 } 72 73 set_ICOMkeyer()74void set_ICOMkeyer() { 75 ICOMwpm = progdefaults.CWspeed; 76 if (ICOMwpm < 6) ICOMwpm = 6; 77 if (ICOMwpm > 48) ICOMwpm = 48; 78 progdefaults.CWspeed = ICOMwpm; 79 int hexwpm = (ICOMwpm - 6) * 6 + 2; 80 ICOMcmd.assign(ICOMheader()); 81 ICOMcmd.append("\x14\x0C"); 82 ICOMcmd += (char)(hexwpm / 100); 83 ICOMcmd += (char)(((hexwpm % 100) / 10) * 16 + (hexwpm % 10)); 84 ICOMcmd += '\xFD'; 85 if (progdefaults.fldigi_client_to_flrig) { 86 xmlrpc_priority(hexstr(ICOMcmd)); 87 } else { 88 guard_lock ser_guard( &rigCAT_mutex); 89 rigio.WriteBuffer((unsigned char *)ICOMcmd.c_str(), ICOMcmd.length()); 90 } 91 MilliSleep(100); 92 } 93 ICOMkeyer_send_char(int c)94void ICOMkeyer_send_char(int c) 95 { 96 if (ICOMwpm != progdefaults.CWspeed) { 97 set_ICOMkeyer(); 98 } 99 100 if (c == GET_TX_CHAR_NODATA || c == 0x0d) { 101 MilliSleep(50); 102 return; 103 } 104 105 int set_time = 0; 106 107 c = toupper(c); 108 if (c < ' ') c = ' '; 109 if (c > 'Z') c = ' '; 110 111 int tc = 1200 / progdefaults.CWspeed; 112 if (progdefaults.CWusefarnsworth && (progdefaults.CWspeed > progdefaults.CWfarnsworth)) 113 tc = 1200 / progdefaults.CWfarnsworth; 114 115 if (c == ' ') { 116 if (lastICOMchar == ' ') 117 tc *= 7; 118 else 119 tc *= 5; 120 } else { 121 tc *= (ICOMmorse.tx_length(c)); 122 123 ICOMcmd.assign(ICOMheader()); 124 ICOMcmd.append("\x17"); 125 ICOMcmd += (char)(c); 126 ICOMcmd += '\xFD'; 127 128 if (progdefaults.fldigi_client_to_flrig) { 129 xmlrpc_priority(ICOMcmd); 130 } else if (progdefaults.chkUSERIGCATis) { 131 guard_lock ser_guard( &rigCAT_mutex); 132 rigio.WriteBuffer((unsigned char *)ICOMcmd.c_str(), ICOMcmd.length()); 133 } 134 } 135 136 tc -= progdefaults.CATkeying_compensation / (progdefaults.CWspeed * 6); 137 tc = int(tc); 138 if (set_time < tc) 139 MilliSleep((int)(tc - set_time)); 140 141 lastICOMchar = c; 142 } 143