]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
Added support for CW Keying via MIDI/GPIO while using "internal CW"
authorc vw <dl1ycf@darc.de>
Wed, 13 Jul 2022 08:20:30 +0000 (10:20 +0200)
committerc vw <dl1ycf@darc.de>
Wed, 13 Jul 2022 08:20:30 +0000 (10:20 +0200)
(paddle connected to radio).

actions.c
actions.h
gpio.c
iambic.c
new_discovery.c
new_protocol.c
old_protocol.c

index cc3bb55dd91adf1b79043aedd277a4f69ad4c46c..8dfe0136baddcc6bc10fe71926905f0eaf2b7fed 100644 (file)
--- a/actions.c
+++ b/actions.c
@@ -187,10 +187,12 @@ ACTION_TABLE ActionTable[] = {
 // CW Keydown (MIDI and GPIO)
 // CW speed   (only MIDI)
 // CW side tone frequency (only MIDI)
+// CW PTT (MIDI and GPIO)
 //
   {CW_KEYER_KEYDOWN,    "CW Key\n(keyer)",      NULL,           MIDI_KEY | CONTROLLER_SWITCH},
   {CW_KEYER_SPEED,      "CW Speed\n(keyer)",    NULL,           MIDI_KNOB},
   {CW_KEYER_SIDETONE,   "CW pitch\n(keyer)",    NULL,           MIDI_KNOB},
+  {CW_KEYER_PTT,        "PTT\n(CW keyer)",      NULL,           MIDI_KEY | CONTROLLER_SWITCH},
   {ACTIONS,            "",                     NULL,           TYPE_NONE}
 };
 
@@ -239,7 +241,7 @@ static inline double KnobOrWheel(PROCESS_ACTION *a, double oldval, double minval
 
 //
 // This interface puts an "action" into the GTK idle queue,
-// but CW actions are processed immediately
+// but "CW key" actions are processed immediately
 //
 void schedule_action(enum ACTION action, enum ACTION_MODE mode, gint val) {
   PROCESS_ACTION *a;
@@ -247,6 +249,7 @@ void schedule_action(enum ACTION action, enum ACTION_MODE mode, gint val) {
     case CW_LEFT:
     case CW_RIGHT:
 #ifdef LOCALCW
+      cw_key_hit=1;
       keyer_event(action==CW_LEFT,mode==PRESSED);
 #else
       g_print("CW_Left/Right but compiled without LOCALCW\n");
@@ -256,9 +259,9 @@ void schedule_action(enum ACTION action, enum ACTION_MODE mode, gint val) {
       //
       // hard "key-up/down" action WITHOUT break-in
       // intended for external keyers (MIDI or GPIO connected)
-      // which take care of PTT themselves
+      // which take care of PTT themselves.
       //
-      if (mode==PRESSED && cw_keyer_internal==0) {
+      if (mode==PRESSED && (cw_keyer_internal==0 || CAT_cw_is_active)) {
         cw_key_down=960000;  // max. 20 sec to protect hardware
         cw_key_up=0;
         cw_key_hit=1;
@@ -1243,7 +1246,38 @@ int process_action(void *data) {
         g_idle_add(ext_vfo_update,NULL);
       }
       break;
-
+    case CW_KEYER_PTT:
+      //
+      // If you do CW with the key attached to the radio, and use a foot-switch for
+      // PTT, then this should trigger the standard PTT event. However, if you have the
+      // the key attached to the radio and want to use an external keyer (e.g.
+      // controlled by a contest logger), then "internal CW" muste temporarily be
+      // disabled in the radio (while keying from piHPSDR) in the radio.
+      // This is exactly the same situation as when using CAT
+      // CW commands together with "internal" CW (status variable CAT_cw_is_active),
+      // so the mechanism is already there. Therefore, the present case is just
+      // the same as "PTT" except that we set/clear the "CAT CW" condition.
+      //
+      // If the "CAT CW" flag is already cleared when the PTT release arrives, this
+      // means that the CW message from the keyer has been aborted by hitting the
+      // CW key. In this case, the radio takes care of "going RX".
+      //
+      switch (a->mode) {
+        case PRESSED:
+          CAT_cw_is_active = 1;
+          mox_update(1);
+          break;
+        case RELEASED:
+          if (CAT_cw_is_active == 1) {
+            CAT_cw_is_active = 0;
+            mox_update(0);
+          }
+          break;
+        default:
+          // should not happen
+          break;
+      }
+      break;
     case CW_KEYER_SIDETONE:
       if (a->mode==ABSOLUTE) {
         //
index 2772f57988c68de0753ed68dce678345ec5e29ad..7ffbb4dd00fa3dab74267d53de756811d3c76fc1 100644 (file)
--- a/actions.h
+++ b/actions.h
@@ -151,6 +151,7 @@ enum ACTION {
   CW_KEYER_KEYDOWN,
   CW_KEYER_SPEED,
   CW_KEYER_SIDETONE,
+  CW_KEYER_PTT,
   ACTIONS
 };
 
diff --git a/gpio.c b/gpio.c
index 2c134e96ebaec96ac4bdd5d1e07482d1eeb4ebd0..7bbdb961a63adc8c4a6bcc8e1535e8cd2a43f37f 100644 (file)
--- a/gpio.c
+++ b/gpio.c
@@ -521,9 +521,11 @@ static void process_edge(int offset,int value) {
   if(ENABLE_CW_BUTTONS) {
     if(offset==CWL_BUTTON) {
       keyer_event(1, CW_ACTIVE_LOW ? (value==PRESSED) : value);
+      cw_key_hit=1;  // this is to stop CAT CW messages that may be running
       found=TRUE;
     } else if(offset==CWR_BUTTON) {
       keyer_event(1, CW_ACTIVE_LOW ? (value==PRESSED) : value);
+      cw_key_hit=1;  // this is to stop CAT CW messages that may be running
       found=TRUE;
     }
   }
index 98b24fc83ae3c4a1fe115f7a41fcfff00d9655e3..0b8b673ed68ffa6e252cdf8eeb6e7d464205053a 100644 (file)
--- a/iambic.c
+++ b/iambic.c
@@ -284,8 +284,6 @@ void keyer_event(int left, int state) {
         // This is to remember whether the key stroke interrupts a running CAT CW 
        // Since in this case we return to RX after vox delay.
        if (CAT_cw_is_active) enforce_cw_vox=1;
-        // This is for aborting CAT CW messages if a key is hit.
-       cw_key_hit = 1;
     }
     if (left) {
       // left paddle hit or released
@@ -422,7 +420,6 @@ static void* keyer_thread(void *arg) {
                     if (*kdash) {                  // send manual dashes
                       cw_key_down=960000;  // max. 20 sec to protect hardware
                       cw_key_up=0;
-                      cw_key_hit=1;
                       gpio_cw_sidetone_set(1);
                       key_state=STRAIGHT;
                     }
index 7661377a7e0ab2bb82e7278fafe2b44c6882fc5a..37d50d1f096924b201d123001180a296fb1e63fb 100644 (file)
@@ -332,11 +332,26 @@ gpointer new_discover_receive_thread(gpointer data) {
                     discovered[devices].info.network.interface_length=sizeof(interface_addr);
                     strcpy(discovered[devices].info.network.interface_name,interface_name);
                     discovered[devices].supported_receivers=2;
-                    fprintf(stderr,"new_discover: found %d protocol=%d device=%d software_version=%d status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n", 
-                            devices,
-                            discovered[devices].protocol,
+                    //
+                    // Info not yet made use of:
+                    //
+                    // buffer[12]: P2 version supported (e.g. 39 for 3.9)
+                    // buffer[20]: number of DDCs
+                    // buffer[23]: beta version number (if nonzero)
+                    //             E.g. if buffer[13] is 21 and buffer[23] is 18 this
+                    //             means firmware Version 2.1.18
+                    //
+                    // We put the additional info to stderr at least since it might be
+                    // useful for debugging/development but do not store it in the
+                    // "discovered" data structure.
+                    //
+
+                    fprintf(stderr,"new_discover: P2(%d)  device=%d (%dRX) software_version=%d(.%d) status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n", 
+                            buffer[12] & 0xFF,
                             discovered[devices].device,
+                            buffer[20] & 0xFF,
                             discovered[devices].software_version,
+                            buffer[23] & 0xFF,
                             discovered[devices].status,
                             inet_ntoa(discovered[devices].info.network.address.sin_addr),
                             discovered[devices].info.network.mac_address[0],
index 5717d34f7dd0029f7cc977315e98fe9f41a2125b..aeaf5fadf656f929b668cae7ebfbe81c09571277 100644 (file)
@@ -1947,18 +1947,17 @@ static void process_high_priority() {
     alex_reverse_power_average = (alex_reverse_power + 3*alex_reverse_power_average) >> 2;
     supply_volts=((buffer[49]&0xFF)<<8)|(buffer[50]&0xFF);
 
-    if (cw_keyer_internal) {
-      // Stops CAT cw transmission if paddle hit in "internal" CW
-      if (dash || dot) cw_key_hit=1;
-    } else {
+    // Stops CAT cw transmission if paddle hit
+    if (dash || dot) {
+      CAT_cw_is_active=0;
+      cw_key_hit=1;
+    }
 #ifdef LOCALCW
-      //
-      // report "key hit" event to the local keyer
-      // (local keyer will stop CAT cw if necessary)
+    if (!cw_keyer_internal) {
       if (dash != previous_dash) keyer_event(0, dash);
       if (dot  != previous_dot ) keyer_event(1, dot );
-#endif
     }
+#endif
 
     if(previous_ptt!=local_ptt) {
       g_idle_add(ext_mox_update,GINT_TO_POINTER(local_ptt));
index 3bff3fa8ec5dcc41c768f279266d7ff0f531dd57..728e81c90c4cb26cd8f86ed1d8456c6c5431e5e9 100644 (file)
@@ -907,18 +907,17 @@ static void process_control_bytes() {
   dash=(control_in[0]&0x02)==0x02;
   dot=(control_in[0]&0x04)==0x04;
 
-  if (cw_keyer_internal) {
-    // Stops CAT cw transmission if paddle hit in "internal" CW
-    if (dash || dot) cw_key_hit=1;
-  } else {
+  // Stops CAT cw transmission if paddle hit in "internal" CW
+  if (dash || dot) {
+    cw_key_hit=1;
+    CAT_cw_is_active=0;
+  }
 #ifdef LOCALCW
-    //
-    // report "key hit" event to the local keyer
-    // (local keyer will stop CAT cw if necessary)
+  if (!cw_keyer_internal) {
     if (dash != previous_dash) keyer_event(0, dash);
     if (dot  != previous_dot ) keyer_event(1, dot );
-#endif
   }
+#endif
 
   if(previous_ptt!=local_ptt) {
     g_idle_add(ext_mox_update,(gpointer)(long)(local_ptt));