]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
Now behaves correctly if user switches mode during CAT CW
authorc vw <dl1ycf@darc.de>
Mon, 9 Jul 2018 09:21:27 +0000 (11:21 +0200)
committerc vw <dl1ycf@darc.de>
Mon, 9 Jul 2018 09:21:27 +0000 (11:21 +0200)
transmission.

old_protocol.c
radio.c
radio.h
rigctl.c
transmitter.c

index 4b944f5e54b8e9ca9699836416ea7b61f331283b..3c26cae7b7028431c9832918fc663db9627aebbe 100644 (file)
@@ -507,7 +507,7 @@ static void process_ozy_input_buffer(unsigned char  *buffer) {
     dot=(control_in[0]&0x04)==0x04;
 
     local_ptt=ptt;
-    if (dot || dash) external_cw_key_hit=1;
+    if (dot || dash) cw_key_hit=1;
     if(vfo[tx_vfo].mode==modeCWL || vfo[tx_vfo].mode==modeCWU) {
       local_ptt=ptt|dot|dash;
     }
diff --git a/radio.c b/radio.c
index 0b0c17634be184e9e9c03590f64c2a1233594b68..854f0537f82fa32eeed57652b76d28d55ada8554 100644 (file)
--- a/radio.c
+++ b/radio.c
@@ -289,7 +289,7 @@ double vox_gain=10.0;
 double vox_hang=250.0;
 int vox=0;
 int local_cw_is_active=0;
-int external_cw_key_hit=0;
+int cw_key_hit=0;
 
 int diversity_enabled=0;
 double i_rotate[2]={1.0,1.0};
diff --git a/radio.h b/radio.h
index c48f1db0b65f29beec908176f355e19df0ada74c..b455aec66bf47525eed9a116600e6248f8ded562 100644 (file)
--- a/radio.h
+++ b/radio.h
@@ -245,7 +245,7 @@ extern double vox_gain;
 extern double vox_hang;
 extern int vox;
 extern int local_cw_is_active;
-extern int external_cw_key_hit;
+extern int cw_key_hit;
 
 extern int diversity_enabled;
 extern double i_rotate[2];
index 42a7668e90d7c582fad6b07703a86d7fde3c7041..ec44ba43eb3d687a1b1608afac2414ad7f00fe1a 100644 (file)
--- a/rigctl.c
+++ b/rigctl.c
@@ -303,7 +303,7 @@ static long dashlen;
 static int  dotsamples;
 static int  dashsamples;
 
-extern int cw_key_up, cw_key_down;
+extern int cw_key_up, cw_key_down, cw_not_ready;
 
 //
 // send_dash()         send a "key-down" of a dashlen, followed by a "key-up" of a dotlen
@@ -317,7 +317,7 @@ extern int cw_key_up, cw_key_down;
 //
 void send_dash() {
   int TimeToGo;
-  if (external_cw_key_hit) return;
+  if (cw_key_hit || cw_not_ready) return;
   for(;;) {
     TimeToGo=cw_key_up+cw_key_down;
     if (TimeToGo == 0) break;
@@ -332,7 +332,7 @@ void send_dash() {
 
 void send_dot() {
   int TimeToGo;
-  if (external_cw_key_hit) return;
+  if (cw_key_hit || cw_not_ready) return;
   for(;;) {
     TimeToGo=cw_key_up+cw_key_down;
     if (TimeToGo == 0) break;
@@ -347,7 +347,7 @@ void send_dot() {
 
 void send_space(int len) {
   int TimeToGo;
-  if (external_cw_key_hit) return;
+  if (cw_key_hit || cw_not_ready) return;
   for(;;) {
     TimeToGo=cw_key_up+cw_key_down;
     if (TimeToGo == 0) break;
@@ -483,7 +483,7 @@ static gpointer rigctl_cw_thread(gpointer data)
   while (server_running) {
     // wait for cw_buf become filled with data
     // (periodically look every 100 msec)
-    external_cw_key_hit=0;
+    cw_key_hit=0;
     if (!cw_busy) {
       usleep(100000L);
       continue;
@@ -506,37 +506,38 @@ static gpointer rigctl_cw_thread(gpointer data)
         usleep(100000L);
     }
     i=0;
-    while(((c=local_buf[i++]) != '\0') && !external_cw_key_hit && mox) {
+    while(((c=local_buf[i++]) != '\0') && !cw_key_hit && !cw_not_ready) {
         rigctl_send_cw_char(c);
     }
-    //
-    // Either an external CW key has been hit (one connected to the SDR board),
-    // or MOX has manually been switched. In this case swallow any pending
-    // or incoming KY messages for about 0.75 sec. We need this long time since
-    // hamlib waits 0.5 secs after receiving a "KY1" message before trying to
-    // send the next bunch (do PTT update immediately).
-    //
-    if (external_cw_key_hit || !mox) {
+    if (cw_key_hit || cw_not_ready) {
+       //
+       // CW transmission has been aborted, either due to manually
+       // removing MOX, changing the mode to non-CW, or because a CW key has been hit.
+       // Do not remove PTT if we abort CAT CW because a CW key has been hit.
        local_cw_is_active=0;
        g_idle_add(ext_cw_key     ,(gpointer)0);
        // If an external CW key has been hit, we continue in TX mode
        // doing CW manually. Otherwise, switch PTT off.
-       if (!external_cw_key_hit) {
+       if (!cw_key_hit) {
          g_idle_add(ext_ptt_update ,(gpointer)0);
        }
-       for (i=0; i< 75; i++) {
+       // Stay for 1 sec swallowing incoming
+       // CAT CW commands. We need this long time since
+       // hamlib waits 0.5 secs after receiving a "KY1" message before trying to
+       // send the next bunch
+       for (i=0; i< 50; i++) {
          cw_busy=0;      // mark buffer free
-         usleep(10000L);
+         usleep(20000L);
        }
-    }
-    // If the next message is pending, continue
-    if (cw_busy) continue;
-    local_cw_is_active=0;
-    // In case of an abort of local CW, this has already been done.
-    // It is not too harmful to do it again. In case of "normal termination"
-    // of sending a CAT CW message, we have to do it here.
-    g_idle_add(ext_cw_key     ,(gpointer)0);
-    if (!external_cw_key_hit) {
+    } else {
+      //
+      // CAT CW message has been sent.
+      // If the next message is pending, continue.
+      // Otherwise remove PTT and wait for next CAT
+      // CW command.
+      if (cw_busy) continue;
+      local_cw_is_active=0;
+      g_idle_add(ext_cw_key     ,(gpointer)0);
       g_idle_add(ext_ptt_update ,(gpointer)0);
     }
   }
@@ -2151,34 +2152,37 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) {
         else if((strcmp(cmd_str,"KY")==0) && (zzid_flag == 0))
                                    { 
                                        // DL1YCF:
-                                       // Hamlib produces errors if we keep begin busy here for
-                                       // seconds. Therefore we just copy the data to be handled
-                                       // by a separate thread.
-                                       // Note that this thread only makes a 0 --> 1 transition for cw_busy,
-                                       // and the CW thread only makes a 1 --> 0 transition
+                                       // Hamlib produces timeout errors if we are busy here for
+                                       // seconds. Therefore we just move the data into a buffer
+                                       // that is processed by a separate thread.
+                                       // Note that here we only makes a 0 --> 1 transition for cw_busy,
+                                       // and the CW thread only makes a 1 --> 0 transition, so we do not
+                                       // need a mutex and/or atomic updates here.
                                        //
-                                       // Note: for a "KY;" command, we have to return "KY0;" if we can
-                                       // accept new data (buffer space available) and "KY1;" if we cannot,
+                                       // Note: The "KY;" command is used to query if we are busy. We return:
+                                       //  - if we can accept new data (buffer space available) : "KY0;"
+                                       //  - if buffer is full: "KY1;"
                                        //
                                         if (len <= 2) {
                                            if (cw_busy) {
-                                               send_resp(client_sock,"KY1;");  // can store no more data
+                                               send_resp(client_sock,"KY1;");
                                            } else {
                                                send_resp(client_sock,"KY0;");
                                                }
                                        } else {
-                                           // So we have data. We have to init the CW setup because TUNE
-                                           // changes the WDSP side tone frequency.
-                                           g_idle_add(ext_cw_setup,NULL);    // Initialize for external transmit
-                                           // We silently ignore buffer overruns. This does not happen with
-                                           // hamlib since I fixed it. Note further that the space immediately
-                                           // following "KY" is *not* part of the message.
-                                           // while cleaning up after hitting external CW key, just skip message
-                                           if (!cw_busy && len > 3 && !external_cw_key_hit) {
+                                           // - We silently ignore buffer overruns. This does not happen  if
+                                           //   "busy" is correctly queried.
+                                           // - Note further that the space immediately following "KY" is *not*
+                                           //   part of the message.
+                                           if (!cw_busy && len > 3) {
+                                               // A CW text will be sent. We have to call cw_setup here because
+                                               // TUNE changes the WDSP side tone frequency, and in this case we have
+                                               // to re-adjust it.
+                                               g_idle_add(ext_cw_setup,NULL);    // Initialize for external transmit
                                                // Copy data to buffer
-                                               strncpy(cw_buf, cmd_input+3, 30);
-                                               // Kenwood protocol allows for at most 28 characters, so
-                                               // this is pure paranoia
+                                               strncpy(cw_buf, cmd_input+3, 29);
+                                               // Kenwood protocol allows for at most 24 characters, so
+                                               // this seems pure paranoia -- but who knows?
                                                cw_buf[29]=0;
                                                cw_busy=1;
                                            }
index 91f9eb07f9829fd0b555c277a8f786efee21d02d..3bd504fada8791046c925e7920ea77f78146fb37 100644 (file)
@@ -62,11 +62,21 @@ static int filterHigh;
 static int waterfall_samples=0;
 static int waterfall_resample=8;
 
+
+// These three variables are global. Their use is:
+// cw_key_up/cw_key_down: set number of samples for next key-down/key-up sequence
+//                        Any of these variable will only be set from outside if
+//                       both have value 0.
+// cw_not_ready:          set to 0 if transmitting in CW mode. This is used to
+//                        abort pending CAT CW messages if MOX or MODE is switched
+//                        manually.
 int cw_key_up = 0;
 int cw_key_down = 0;
+int cw_not_ready=1;
+
 // cw_shape_buffer will eventually be integrated into TRANSMITTER
 static int *cw_shape_buffer = NULL;
-int cw_shape = 0;
+static int cw_shape = 0;
 
 extern void cw_audio_write(double sample);
 
@@ -814,7 +824,7 @@ static void full_tx_buffer(TRANSMITTER *tx) {
            qsample=qs>=0.0?(long)floor(qs*gain+0.5):(long)ceil(qs*gain-0.5);
            switch(protocol) {
                case ORIGINAL_PROTOCOL:
-                   old_protocol_iq_samples_with_sidetone(isample,qsample,0);
+                   old_protocol_iq_samples(isample,qsample);
                    break;
                case NEW_PROTOCOL:
                    new_protocol_iq_samples(isample,qsample);
@@ -837,8 +847,11 @@ void add_mic_sample(TRANSMITTER *tx,short mic_sample) {
     mode=vfo[0].mode;
   }
 
-// silence TX audio not transmitting, if tuning, or
-// when doing CW
+//
+// silence TX audio if not transmitting, if tuning, or
+// when doing CW. Note: CW side tone added later on by a
+// separate mechanism.
+//
 
   if (tune || !isTransmitting() || mode==modeCWL || mode==modeCWU) {
     mic_sample_double=0.0;
@@ -846,13 +859,10 @@ void add_mic_sample(TRANSMITTER *tx,short mic_sample) {
     mic_sample_double=(double)mic_sample/32768.0;
   }
 
-//This statement takes care that the cw shape buffer is
-//automatically wiped if we are not doing local CW
-
-  cw_shape_buffer[tx->samples]=0;
-
-  if((mode==modeCWL || mode==modeCWU)) {
-    if (isTransmitting()) {
+//
+// shape CW pulses when doing CW and transmitting, else nullify them
+//
+  if((mode==modeCWL || mode==modeCWU) && isTransmitting()) {
 //
 //     RigCtl CW sets the variables cw_key_up and cw_key_down
 //     to the number of samples for the next down/up sequence.
@@ -862,6 +872,7 @@ void add_mic_sample(TRANSMITTER *tx,short mic_sample) {
 //     heard way beside our frequency. The envelope goes up
 //       and down linearly within 200 samples (4.16 msec)
 //
+       cw_not_ready=0;
        if (cw_key_down > 0 ) {
            if (cw_shape < 200) cw_shape++;
            cw_key_down--;
@@ -875,14 +886,18 @@ void add_mic_sample(TRANSMITTER *tx,short mic_sample) {
        }
        cw_audio_write(0.00003937 * getNextSideToneSample() * cw_keyer_sidetone_volume * cw_shape);
         cw_shape_buffer[tx->samples]=cw_shape;
-    } else {
+  } else {
 //
-//     Have to reset pulse shaper since RigCtl may wait forever
+//     If no longer transmitting, or no longer doing CW: reset pulse shaper.
+//     This will also swallow any pending CW in rigtl CAT CW and wipe out the
+//      cw_shape buffer very quickly. In order to tell rigctl etc. that CW should be
+//     aborted, we also use the cw_not_ready flag.
 //
+       cw_not_ready=1;
        cw_key_up=0;
        cw_key_down=0;
        cw_shape=0;
-    }
+       cw_shape_buffer[tx->samples]=0;
   }
   tx->mic_input_buffer[tx->samples*2]=mic_sample_double;
   tx->mic_input_buffer[(tx->samples*2)+1]=0.0; //mic_sample_double;