From 1f18346fa68b2918f8703b6b75bed5ca6359b2e5 Mon Sep 17 00:00:00 2001
From: c vw <dl1ycf@darc.de>
Date: Tue, 3 Mar 2020 15:02:55 +0100
Subject: [PATCH] DIVERSITY controls via MIDI and GPIO

---
 diversity_menu.c | 10 +++++-----
 gpio.c           | 23 ++++++++++++++++++++---
 gpio.h           |  4 ++++
 midi.h           |  8 ++++++--
 midi2.c          |  4 ++++
 midi3.c          | 47 ++++++++++++++++++++++++++++++++++++++++-------
 6 files changed, 79 insertions(+), 17 deletions(-)

diff --git a/diversity_menu.c b/diversity_menu.c
index eba5b02..69aa604 100644
--- a/diversity_menu.c
+++ b/diversity_menu.c
@@ -137,9 +137,9 @@ void update_diversity_gain(double increment) {
   // if gain is 27, we can only use coarse=25 and fine=2,
   // but normally we want to keep "fine" small
   //
-  gain_coarse=round(div_gain);
-  if (gain_coarse >  25.0) gain_coarse= 25.0;
-  if (gain_coarse < -25.0) gain_coarse=-25.0;
+  gain_coarse=2.0*round(0.5*div_gain);
+  if (div_gain >  25.0) gain_coarse= 25.0;
+  if (div_gain < -25.0) gain_coarse=-25.0;
   gain_fine=div_gain - gain_coarse;
   if(gain_coarse_scale!=NULL && gain_fine_scale != NULL) {
     gtk_range_set_value(GTK_RANGE(gain_coarse_scale),gain_coarse);
@@ -186,11 +186,11 @@ void update_diversity_phase(double increment) {
   //
   // calculate coarse and fine
   //
-  phase_coarse=2.0*round(div_phase*0.5);
+  phase_coarse=4.0*round(div_phase*0.25);
   phase_fine=div_phase-phase_coarse;
   if(phase_coarse_scale!=NULL && phase_fine_scale != NULL) {
     gtk_range_set_value(GTK_RANGE(phase_coarse_scale),phase_coarse);
-    gtk_range_set_value(GTK_RANGE(phase_fine_scale),phase_coarse);
+    gtk_range_set_value(GTK_RANGE(phase_fine_scale),phase_fine);
   } else {
     show_diversity_phase();
   }
diff --git a/gpio.c b/gpio.c
index 4da17aa..690b36a 100644
--- a/gpio.c
+++ b/gpio.c
@@ -224,7 +224,12 @@ char *encoder_string[ENCODER_ACTIONS] = {
   "SQUELCH RX2",
   "COMP",
   "DIVERSITY GAIN",
-  "DIVERSITY PHASE"};
+  "DIVERSITY GAIN (coarse)",
+  "DIVERSITY GAIN (fine)",
+  "DIVERSITY PHASE",
+  "DIVERSITY PHASE (coarse)",
+  "DIVERSITY PHASE (fine)"
+};
 
 char *sw_string[SWITCH_ACTIONS] = {
   "",
@@ -2053,10 +2058,22 @@ static void encoder_changed(int action,int pos) {
       set_compression(transmitter);
       break;
     case ENCODER_DIVERSITY_GAIN:
-      update_diversity_gain((double)pos);
+      update_diversity_gain((double)pos * 0.5);
+      break;
+    case ENCODER_DIVERSITY_GAIN_COARSE:
+      update_diversity_gain((double)pos * 2.5);
+      break;
+    case ENCODER_DIVERSITY_GAIN_FINE:
+      update_diversity_gain((double)pos * 0.1);
       break;
     case ENCODER_DIVERSITY_PHASE:
-      update_diversity_phase((double)pos);
+      update_diversity_phase((double)pos* 0.5);
+      break;
+    case ENCODER_DIVERSITY_PHASE_COARSE:
+      update_diversity_phase((double)pos*2.5);
+      break;
+    case ENCODER_DIVERSITY_PHASE_FINE:
+      update_diversity_phase((double)pos*0.1);
       break;
   }
 }
diff --git a/gpio.h b/gpio.h
index f90f188..49a373f 100644
--- a/gpio.h
+++ b/gpio.h
@@ -67,7 +67,11 @@ enum {
   ENCODER_SQUELCH_RX2,
   ENCODER_COMP,
   ENCODER_DIVERSITY_GAIN,
+  ENCODER_DIVERSITY_GAIN_COARSE,
+  ENCODER_DIVERSITY_GAIN_FINE,
   ENCODER_DIVERSITY_PHASE,
+  ENCODER_DIVERSITY_PHASE_COARSE,
+  ENCODER_DIVERSITY_PHASE_FINE,
   ENCODER_ACTIONS
 };
 
diff --git a/midi.h b/midi.h
index 3090b23..cdc9bdb 100644
--- a/midi.h
+++ b/midi.h
@@ -62,8 +62,12 @@ enum MIDIaction {
   CWL,			// CWL:			Left paddle pressed (use with ONOFF)
   CWR,			// CWR:			Right paddle pressed (use with ONOFF)
   CWSPEED,		// CWSPEED:		Set speed of (iambic) CW keyer
-  DIV_GAIN,		// DIVGAIN:		change DIVERSITY gain
-  DIV_PHASE,		// DIVPHASE:		change DIVERSITY phase
+  DIV_COARSEGAIN,	// DIVCOARSEGAIN:	change DIVERSITY gain in large increments
+  DIV_COARSEPHASE,	// DIVPHASE:		change DIVERSITY phase in large increments
+  DIV_FINEGAIN,		// DIVFINEGAIN:		change DIVERSITY gain in small increments
+  DIV_FINEPHASE,	// DIVFINEPHASE:	change DIVERSITY phase in small increments
+  DIV_GAIN,		// DIVGAIN:		change DIVERSITY gain in medium increments
+  DIV_PHASE,		// DIVPHASE:		change DIVERSITY phase in medium increments
   DIV_TOGGLE,		// DIVTOGGLE:		DIVERSITY on/off
   MIDI_DUP,		// DUP:			toggle duplex on/off
   FILTER_DOWN,		// FILTERDOWN:		cycle through filters downwards
diff --git a/midi2.c b/midi2.c
index 6385e5d..c77e3e9 100644
--- a/midi2.c
+++ b/midi2.c
@@ -115,6 +115,10 @@ static struct {
 	{ CWL,			"CWL"},
 	{ CWR,			"CWR"},
 	{ CWSPEED,		"CWSPEED"},
+	{ DIV_COARSEGAIN,	"DIVCOARSEGAIN"},
+	{ DIV_COARSEPHASE,	"DIVCOARSEPHASE"},
+	{ DIV_FINEGAIN,		"DIVFINEGAIN"},
+	{ DIV_FINEPHASE,	"DIVFINEPHASE"},
 	{ DIV_GAIN,		"DIVGAIN"},
 	{ DIV_PHASE,		"DIVPHASE"},
 	{ DIV_TOGGLE,		"DIVTOGGLE"},
diff --git a/midi3.c b/midi3.c
index 6c6a08d..96c444e 100644
--- a/midi3.c
+++ b/midi3.c
@@ -246,14 +246,30 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
 #endif
             g_idle_add(ext_vfo_update, NULL);
 	    break;
-	/////////////////////////////////////////////////////////// "DIVGAIN"
-	case DIV_GAIN:  // knob or wheel supported
+	/////////////////////////////////////////////////////////// "DIVCOARSEGAIN"
+	case DIV_COARSEGAIN:  // knob or wheel supported
+	case DIV_FINEGAIN:    // knob or wheel supported
+	case DIV_GAIN:        // knob or wheel supported
             switch (type) {
               case MIDI_KNOB:
-		dnew = 10.0*(-25.0 + 0.5*val - div_gain);
+                if (action == DIV_COARSEGAIN || action == DIV_GAIN) {
+		  // -25 to +25 dB in steps of 0.5 dB
+		  dnew = 10.0*(-25.0 + 0.5*val - div_gain);
+		} else {
+		  // round gain to a multiple of 0.5 dB and apply a +/- 0.5 dB update
+                  new = (int) (2*div_gain + 1.0) / 2;
+		  dnew = 10.0*((double) new + 0.01*val - 0.5 - div_gain);
+		}
                 break;
               case MIDI_WHEEL:
-                dnew= val;
+                // coarse: increaments in steps of 0.25 dB, medium: steps of 0.1 dB fine: in steps of 0.01 dB
+                if (action == DIV_GAIN) {
+		  dnew = val*0.5;
+		} else if (action == DIV_COARSEGAIN) {
+		  dnew = val*2.5;
+		} else {
+		  dnew = val * 0.1;
+	 	}
                 break;
               default:
                 // do not change
@@ -267,13 +283,30 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
             g_idle_add(ext_diversity_change_gain, dp);
             break;
         /////////////////////////////////////////////////////////// "DIVPHASE"
-        case DIV_PHASE:  // knob or wheel supported
+        case DIV_COARSEPHASE:   // knob or wheel supported
+        case DIV_FINEPHASE:     // knob or wheel supported
+	case DIV_PHASE:		// knob or wheel supported
             switch (type) {
               case MIDI_KNOB:
-                dnew = (-180.0 + 3.6*val - div_phase);
+		// coarse: change phase from -180 to 180
+                // fine: change from -5 to 5
+                if (action == DIV_COARSEPHASE || action == DIV_PHASE) {
+		  // coarse: change phase from -180 to 180 in steps of 3.6 deg
+                  dnew = (-180.0 + 3.6*val - div_phase);
+                } else {
+		  // fine: round to multiple of 5 deg and apply a +/- 5 deg update
+                  new = 5 * ((int) (div_phase+0.5) / 5);
+                  dnew =  (double) new + 0.1*val -5.0 -div_phase;
+                }
                 break;
               case MIDI_WHEEL:
-                dnew= val;
+		if (action == DIV_PHASE) {
+		  dnew = val*0.5; 
+		} else if (action == DIV_COARSEPHASE) {
+		  dnew = val*2.5;
+		} else if (action == DIV_FINEPHASE) {
+		  dnew = 0.1*val;
+		}
                 break;
               default:
                 // do not change
-- 
2.45.2