From 6f04812d04208a895b456baa78390a11799daa6a Mon Sep 17 00:00:00 2001
From: c vw <dl1ycf@darc.de>
Date: Fri, 21 Jan 2022 09:30:22 +0100
Subject: [PATCH] Better support for external CW keyers, compatible with the
 "Teensy CW Keyer shield".

---
 actions.c | 39 +++++++++++++++++++++++++++++++++++++--
 actions.h |  7 ++++++-
 midi2.c   |  4 +++-
 3 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/actions.c b/actions.c
index 272b6f3..f7af4ee 100644
--- a/actions.c
+++ b/actions.c
@@ -78,7 +78,6 @@ ACTION_TABLE ActionTable[] = {
   {COMPRESSION,		"COMPRESSION",		NULL,		MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
   {CTUN,		"CTUN",			"CTUN",		MIDI_KEY | CONTROLLER_SWITCH},
   {CW_FREQUENCY,	"CW FREQUENCY",		NULL,		MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
-  {CW_KEYER,            "CW(keyer)",            NULL,           MIDI_KEY | CONTROLLER_SWITCH},
   {CW_LEFT,		"CW LEFT",		"CWL",		MIDI_KEY | CONTROLLER_SWITCH},
   {CW_RIGHT,		"CW RIGHT",		"CWR",		MIDI_KEY | CONTROLLER_SWITCH},
   {CW_SPEED,		"CW SPEED",		NULL,		MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
@@ -181,6 +180,17 @@ ACTION_TABLE ActionTable[] = {
   {ZOOM,		"ZOOM",			NULL,		MIDI_WHEEL | CONTROLLER_ENCODER},
   {ZOOM_MINUS,		"ZOOM -",		"ZOOM-",	MIDI_KEY | CONTROLLER_SWITCH},
   {ZOOM_PLUS,		"ZOOM +",		"ZOOM+",	MIDI_KEY | CONTROLLER_SWITCH},
+//
+// The following actions support external CW keyers generating
+// the following messages:
+//
+// CW Keydown (MIDI and GPIO)
+// CW speed   (only MIDI)
+// CW side tone frequency (only MIDI)
+//
+  {CW_KEYER_KEYDOWN,    "KeyDown\n(keyer)",     NULL,           MIDI_KEY | CONTROLLER_SWITCH},
+  {CW_KEYER_SPEED,      "Speed\n(keyer)",       NULL,           MIDI_KNOB},
+  {CW_KEYER_SIDETONE,   "ST freq\n(keyer)",     NULL,           MIDI_KNOB},
   {ACTIONS,		"",			NULL,		TYPE_NONE}
 };
 
@@ -242,7 +252,7 @@ void schedule_action(enum ACTION action, enum ACTION_MODE mode, gint val) {
       g_print("CW_Left/Right but compiled without LOCALCW\n");
 #endif
       break;
-    case CW_KEYER:
+    case CW_KEYER_KEYDOWN:
       //
       // hard "key-up/down" action WITHOUT break-in
       // intended for external keyers (MIDI or GPIO connected)
@@ -1210,6 +1220,31 @@ int process_action(void *data) {
       }
       break;
 
+    case CW_KEYER_SPEED:
+      if (a->mode==ABSOLUTE) {
+        //
+        // The MIDI keyer reports the speed as a value between 1 and 127,
+        // however the range 0-127 is internally converted to 0-100 upstream
+        //
+        cw_keyer_speed=(127*a->val + 50)/100;
+	if (cw_keyer_speed <  1) cw_keyer_speed=1;
+	if (cw_keyer_speed > 99) cw_keyer_speed=99;
+        g_idle_add(ext_vfo_update,NULL);
+      }
+      break;
+
+    case CW_KEYER_SIDETONE:
+      if (a->mode==ABSOLUTE) {
+        //
+        // The MIDI keyer encodes the frequency as a value between 0 and 127,
+	// freq = 250 + 8*val
+        // however the range 0-127 is internally converted to 0-100 upstream
+	//
+        cw_keyer_sidetone_frequency=250 + (254*a->val + 12)/25;
+        g_idle_add(ext_vfo_update,NULL);
+      }
+      break;
+
     default:
       if(a->action>=0 && a->action<ACTIONS) {
         g_print("%s: UNKNOWN PRESSED SWITCH ACTION %d (%s)\n",__FUNCTION__,a->action,ActionTable[a->action].str);
diff --git a/actions.h b/actions.h
index 00db006..2772f57 100644
--- a/actions.h
+++ b/actions.h
@@ -43,7 +43,6 @@ enum ACTION {
   COMPRESSION,
   CTUN,
   CW_FREQUENCY,
-  CW_KEYER,
   CW_LEFT,
   CW_RIGHT,
   CW_SPEED,
@@ -146,6 +145,12 @@ enum ACTION {
   ZOOM,
   ZOOM_MINUS,
   ZOOM_PLUS,
+//
+// Support for external CW keyers
+//
+  CW_KEYER_KEYDOWN,
+  CW_KEYER_SPEED,
+  CW_KEYER_SIDETONE,
   ACTIONS
 };
 
diff --git a/midi2.c b/midi2.c
index f436e17..0f06586 100644
--- a/midi2.c
+++ b/midi2.c
@@ -220,7 +220,6 @@ static OLD_MAPPING OLD_Mapping[] = {
 	{ CTUN,  		"CTUN"			},
 	{ VFO,			"CURRVFO"		},
 	{ CW_LEFT,		"CWL"			},
-	{ CW_KEYER,		"CW(Keyer)"		},
 	{ CW_RIGHT,		"CWR"			},
 	{ CW_SPEED,		"CWSPEED"		},
 	{ DIV_GAIN_COARSE,	"DIVCOARSEGAIN"		},
@@ -284,6 +283,9 @@ static OLD_MAPPING OLD_Mapping[] = {
 	{ ZOOM,			"ZOOM"			},
 	{ ZOOM_MINUS,		"ZOOMDOWN"		},
 	{ ZOOM_PLUS,		"ZOOMUP"		},
+        { CW_KEYER_KEYDOWN,     "KEYER-CW"              },
+        { CW_KEYER_SPEED,       "KEYER-SPEED"           },
+        { CW_KEYER_SIDETONE,    "KEYER-SIDETONE"        },
         { NO_ACTION,  		"NONE"			}
 };
 
-- 
2.45.2