1 // ----------------------------------------------------------------------------
2 // KYkeying.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 "KYkeying.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 
35 int KYwpm = 0;
36 bool use_KYkeyer = false;
37 static std::string KYcmd = "KY  ;";
38 static std::string KNWDcmd = "KY                         ;";
39 static std::string cmd;
40 static cMorse KYmorse;
41 static char lastKYchar = 0;
42 
set_KYkeyer()43 void set_KYkeyer()
44 {
45 	KYwpm = progdefaults.CWspeed;
46 	if (KYwpm < 8) KYwpm = 8;
47 	if (KYwpm > 50) KYwpm = 50;
48 	progdefaults.CWspeed = KYwpm;
49 	char cmd[10];
50 	snprintf(cmd, sizeof(cmd), "KS%03d;", KYwpm);
51 	if (progdefaults.fldigi_client_to_flrig) {
52 		xmlrpc_priority(cmd);
53 	} else {
54 		guard_lock ser_guard( &rigCAT_mutex);
55 		rigio.WriteBuffer((unsigned char *)cmd, strlen(cmd));
56 	}
57 	MilliSleep(50);
58 }
59 
KYkeyer_send_char(int c)60 void KYkeyer_send_char(int c)
61 {
62 	if (KYwpm != progdefaults.CWspeed) {
63 		set_KYkeyer();
64 	}
65 
66 	if (c == GET_TX_CHAR_NODATA || c == 0x0d) {
67 		MilliSleep(50);
68 		return;
69 	}
70 
71 	c = toupper(c);
72 	if (c < ' ') c = ' ';
73 	if (c > 'Z') c = ' ';
74 
75 	float tc = 1200.0 / progdefaults.CWspeed;
76 	if (progdefaults.CWusefarnsworth && (progdefaults.CWspeed > progdefaults.CWfarnsworth))
77 		tc = 1200.0 / progdefaults.CWfarnsworth;
78 
79 	if (c == ' ') {
80 		if (lastKYchar == ' ')
81 			tc *= 7;
82 		else
83 			tc *= 5;
84 	} else {
85 		tc *= KYmorse.tx_length(c);
86 		if (progdefaults.use_KNWDkeying) {
87 			KNWDcmd[3] = (char)c;
88 			cmd = KNWDcmd;
89 		} else {
90 			KYcmd[3] = (char)c;
91 			cmd = KYcmd;
92 		}
93 		if (progdefaults.fldigi_client_to_flrig) {
94 			xmlrpc_priority(cmd);
95 		} else if (progdefaults.chkUSERIGCATis) {
96 			guard_lock ser_guard( &rigCAT_mutex);
97 			rigio.WriteBuffer((unsigned char *)cmd.c_str(), cmd.length());
98 		}
99 	}
100 	tc -= progdefaults.CATkeying_compensation / (progdefaults.CWspeed  * 6);
101 	tc = int(tc);
102 	MilliSleep(tc);
103 
104 	lastKYchar = c;
105 }
106