From: c vw <dl1ycf@darc.de>
Date: Wed, 8 Aug 2018 16:50:16 +0000 (+0200)
Subject: LOCALCW: better integration in Config menu, First dit/dah after PTT switching a littl... 
X-Git-Url: https://git.rkrishnan.org/pf/content/banana.xhtml?a=commitdiff_plain;h=d30bab7fced5bdf9a93fcb2801b9cffc20045290;p=pihpsdr.git

LOCALCW: better integration in Config menu, First dit/dah after PTT switching a little bit longer
---

diff --git a/configure.c b/configure.c
index 688d7ea..dc512c4 100644
--- a/configure.c
+++ b/configure.c
@@ -96,11 +96,13 @@ static   GtkWidget *function;
 
 #ifdef LOCALCW
 static GtkWidget *cwl_label;
-static GtkWidget *cwl_gpio_label;
 static GtkWidget *cwl;
 static GtkWidget *cwr_label;
-static GtkWidget *cwr_gpio_label;
 static GtkWidget *cwr;
+static GtkWidget *cws_label;
+static GtkWidget *cws;
+static GtkWidget *b_enable_cws;
+static GtkWidget *b_enable_cwlr;
 #endif
 
 static gboolean save_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
@@ -149,8 +151,11 @@ static gboolean save_cb (GtkWidget *widget, GdkEventButton *event, gpointer data
     ENABLE_FUNCTION_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_function))?1:0;
     FUNCTION_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(function));
 #ifdef LOCALCW
+    ENABLE_CW_BUTTONS=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_cwlr))?1:0;
     CWL_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(cwl));
     CWR_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(cwr));
+    ENABLE_GPIO_SIDETONE=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_cws))?1:0;
+    SIDETONE_GPIO=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(cws));
 #endif
 
     gpio_save_state();
@@ -331,6 +336,25 @@ void configure_gpio(GtkWidget *parent) {
   gtk_widget_show(S1);
   gtk_grid_attach(GTK_GRID(grid),S1,2,y,1,1);
 
+#ifdef LOCALCW
+  // With LOCALCW, the menu got too long (does not fit on the screen)
+  // Therefore it has been moved to the right of S1/S2/S3
+  // The GPIO side tone is also configured here. Note that
+  // these setting are only active when doing local CW
+  cwl_label=gtk_label_new("CWL GPIO:");
+  gtk_widget_show(cwl_label);
+  gtk_grid_attach(GTK_GRID(grid),cwl_label,3,y,1,1);
+
+  cwl=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON(cwl),CWL_BUTTON);
+  gtk_widget_show(cwl);
+  gtk_grid_attach(GTK_GRID(grid),cwl,4,y,1,1);
+
+  b_enable_cwlr=gtk_check_button_new_with_label("Enable CW buttons");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_cwlr), ENABLE_CW_BUTTONS);
+  gtk_widget_show(b_enable_cwlr);
+  gtk_grid_attach(GTK_GRID(grid),b_enable_cwlr,5,y,1,1);
+#endif
 
   y++;
 
@@ -348,6 +372,17 @@ void configure_gpio(GtkWidget *parent) {
   gtk_widget_show(S2);
   gtk_grid_attach(GTK_GRID(grid),S2,2,y,1,1);
 
+#ifdef LOCALCW
+  cwr_label=gtk_label_new("CWR GPIO:");
+  gtk_widget_show(cwr_label);
+  gtk_grid_attach(GTK_GRID(grid),cwr_label,3,y,1,1);
+
+  cwr=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON(cwr),CWR_BUTTON);
+  gtk_widget_show(cwr);
+  gtk_grid_attach(GTK_GRID(grid),cwr,4,y,1,1);
+#endif
+
   y++;
 
   b_enable_S3=gtk_check_button_new_with_label("Enable S3");
@@ -364,6 +399,21 @@ void configure_gpio(GtkWidget *parent) {
   gtk_widget_show(S3);
   gtk_grid_attach(GTK_GRID(grid),S3,2,y,1,1);
 
+#ifdef LOCALCW
+  cws_label=gtk_label_new("  SideTone GPIO:");
+  gtk_widget_show(cws_label);
+  gtk_grid_attach(GTK_GRID(grid),cws_label,3,y,1,1);
+
+  cws=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON(cws),SIDETONE_GPIO);
+  gtk_widget_show(cws);
+  gtk_grid_attach(GTK_GRID(grid),cws,4,y,1,1);
+
+  b_enable_cws=gtk_check_button_new_with_label("Enable");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_cws), ENABLE_GPIO_SIDETONE);
+  gtk_widget_show(b_enable_cws);
+  gtk_grid_attach(GTK_GRID(grid),b_enable_cws,5,y,1,1);
+#endif
   y++;
 
   b_enable_S4=gtk_check_button_new_with_label("Enable S4");
@@ -430,38 +480,6 @@ void configure_gpio(GtkWidget *parent) {
 
   y++;
 
-#ifdef LOCALCW
-  cwl_label=gtk_label_new("CWL");
-  gtk_widget_show(cwl_label);
-  gtk_grid_attach(GTK_GRID(grid),cwl_label,0,y,1,1);
-
-  cwl_gpio_label=gtk_label_new("GPIO:");
-  gtk_widget_show(cwl_gpio_label);
-  gtk_grid_attach(GTK_GRID(grid),cwl_gpio_label,1,y,1,1);
-
-  cwl=gtk_spin_button_new_with_range (0.0,100.0,1.0);
-  gtk_spin_button_set_value (GTK_SPIN_BUTTON(cwl),CWL_BUTTON);
-  gtk_widget_show(cwl);
-  gtk_grid_attach(GTK_GRID(grid),cwl,2,y,1,1);
-
-  y++;
-
-  cwr_label=gtk_label_new("CWR");
-  gtk_widget_show(cwr_label);
-  gtk_grid_attach(GTK_GRID(grid),cwr_label,0,y,1,1);
-
-  cwr_gpio_label=gtk_label_new("GPIO:");
-  gtk_widget_show(cwr_gpio_label);
-  gtk_grid_attach(GTK_GRID(grid),cwr_gpio_label,1,y,1,1);
-
-  cwr=gtk_spin_button_new_with_range (0.0,100.0,1.0);
-  gtk_spin_button_set_value (GTK_SPIN_BUTTON(cwr),CWR_BUTTON);
-  gtk_widget_show(cwr);
-  gtk_grid_attach(GTK_GRID(grid),cwr,2,y,1,1);
-
-  y++;
-#endif
-  
   GtkWidget *save_b=gtk_button_new_with_label("Save");
   g_signal_connect (save_b, "button_press_event", G_CALLBACK(save_cb), NULL);
   gtk_grid_attach(GTK_GRID(grid),save_b,4,y-1,1,1);
diff --git a/gpio.c b/gpio.c
index 089f0fa..d66c0fa 100644
--- a/gpio.c
+++ b/gpio.c
@@ -29,6 +29,9 @@
 #include <poll.h>
 #include <sched.h>
 #include <wiringPi.h>
+#ifdef LOCALCW
+#include <softTone.h>
+#endif
 #include <semaphore.h>
 
 #include "band.h"
@@ -144,11 +147,14 @@ int FUNCTION_BUTTON=3;
 int ENABLE_E1_BUTTON=1;
 int ENABLE_E2_BUTTON=1;
 int ENABLE_E3_BUTTON=1;
-int ENABLE_CW_BUTTONS=1;
 #endif
+
 #ifdef LOCALCW
-int CWL_BUTTON=18;
-int CWR_BUTTON=19;
+int CWL_BUTTON=14;
+int CWR_BUTTON=15;
+int SIDETONE_GPIO=8;
+int ENABLE_GPIO_SIDETONE=0;
+int ENABLE_CW_BUTTONS=1;
 #endif
 
 static volatile int vfoEncoderPos;
@@ -848,6 +854,10 @@ void gpio_restore_state() {
  if(value) CWL_BUTTON=atoi(value);		
  value=getProperty("CWR_BUTTON");		
  if(value) CWR_BUTTON=atoi(value);		
+ value=getProperty("SIDETONE_GPIO");		
+ if(value) SIDETONE_GPIO=atoi(value);		
+ value=getProperty("ENABLE_GPIO_SIDETONE");		
+ if(value) ENABLE_GPIO_SIDETONE=atoi(value);		
 #endif
 
 
@@ -950,6 +960,10 @@ void gpio_save_state() {
  setProperty("CWL_BUTTON",value);		
  sprintf(value,"%d",CWR_BUTTON);		
  setProperty("CWR_BUTTON",value);		
+ sprintf(value,"%d",SIDETONE_GPIO);		
+ setProperty("SIDETONE_GPIO",value);		
+ sprintf(value,"%d",ENABLE_GPIO_SIDETONE);		
+ setProperty("ENABLE_GPIO_SIDETONE",value);		
 #endif
 
   saveProperties("gpio.props");
@@ -975,8 +989,11 @@ fprintf(stderr,"setup_encoder_pin: pin=%d updown=%d\n",pin,up_down);
 #ifdef LOCALCW
 
 // Note we cannot use debouncing, as after the first interrupt,
-// we might read the wrong level. So we forward all CW interrupts
+// we might read the wrong level. So we process all interrupts
 // to the keyer.
+// The only way to do proper debouncing is to record the times
+// of the last state change of each of the two buttons, and
+// disable further state changes for a short time (5 msec)
 
 static void setup_cw_pin(int pin, void(*pAlert)(void)) {
    fprintf(stderr,"setup_cw_pin: pin=%d \n",pin);
@@ -1134,6 +1151,9 @@ int gpio_init() {
     setup_cw_pin(CWL_BUTTON, cwAlert_left);
     setup_cw_pin(CWR_BUTTON, cwAlert_right);
   }
+  if (ENABLE_GPIO_SIDETONE) {
+    softToneCreate(SIDETONE_GPIO);
+  }
 #endif
 
   return 0;
@@ -1143,6 +1163,14 @@ void gpio_close() {
     running=0;
 }
 
+#ifdef LOCALCW
+void gpio_sidetone(int freq) {
+  if (ENABLE_GPIO_SIDETONE) {
+    softToneWrite (SIDETONE_GPIO, freq);
+  }
+}
+#endif
+
 int vfo_encoder_get_pos() {
   int pos=vfoEncoderPos;
 
diff --git a/gpio.h b/gpio.h
index 96d772c..9563bb6 100644
--- a/gpio.h
+++ b/gpio.h
@@ -80,8 +80,14 @@ extern int ENABLE_MOX_BUTTON;
 extern int MOX_BUTTON;
 extern int ENABLE_FUNCTION_BUTTON;
 extern int FUNCTION_BUTTON;
+#ifdef LOCALCW
 extern int CWL_BUTTON;
 extern int CWR_BUTTON;
+extern int SIDETONE_GPIO;
+extern int ENABLE_GPIO_SIDETONE;
+extern int ENABLE_CW_BUTTONS;
+void gpio_sidetone(int freq);
+#endif
 
 void gpio_restore_state();
 void gpio_save_state();
diff --git a/iambic.c b/iambic.c
index e013605..14ddc99 100644
--- a/iambic.c
+++ b/iambic.c
@@ -71,7 +71,6 @@
 #include <sys/mman.h>
 
 #include <wiringPi.h>
-#include <softTone.h>
 
 #include "gpio.h"
 #include "radio.h"
@@ -83,9 +82,6 @@
 static void* keyer_thread(void *arg);
 static pthread_t keyer_thread_id;
 
-// set to 0 to use the PI's hw:0 audio out for sidetone
-#define SIDETONE_GPIO 0 // this is in wiringPi notation // tried 4 working great.
-
 #define MY_PRIORITY (90)
 #define MAX_SAFE_STACK (8*1024)
 #define NSEC_PER_SEC   (1000000000)
@@ -124,6 +120,7 @@ static sem_t cw_event;
 #endif
 
 static int cwvox = 0;
+static int first_dot = 0;
 
 int keyer_out = 0;
 
@@ -169,6 +166,7 @@ void keyer_event(int gpio, int level) {
         if (running && !cwvox && !mox) {
 	   g_idle_add(ext_mox_update, (gpointer)(long) 1);
            cwvox=(int) vox_hang;
+	   first_dot=1;
 	}
     }
     if (gpio == CWL_BUTTON) {
@@ -203,17 +201,10 @@ void set_keyer_out(int state) {
         if(protocol==NEW_PROTOCOL) schedule_high_priority(9);
 		//fprintf(stderr,"set_keyer_out keyer_out= %d\n", keyer_out);
         if (state) {
-	    // DL1YCF: we must call cw_hold_key in *any* case, else no
-	    //         CW signal will be produced. We certainly do not
-	    //         want to produce a side tone *only*.
-            if (SIDETONE_GPIO) {
-                softToneWrite (SIDETONE_GPIO, cw_keyer_sidetone_frequency);
-	    }
+	    gpio_sidetone(cw_keyer_sidetone_frequency);
 	    cw_hold_key(1); // this starts a CW pulse in transmitter.c
         } else {
-            if (SIDETONE_GPIO) {
-                softToneWrite (SIDETONE_GPIO, 0);
-	    }
+	    gpio_sidetone(0);
 	    cw_hold_key(0); // this stops a CW pulse in transmitter.c
         }
     }
@@ -275,10 +266,18 @@ fprintf(stderr,"keyer_thread  state running= %d\n", running);
             case PREDOT:                         // need to clear any pending dots or dashes
                 clear_memory();
                 key_state = SENDDOT;
+		if (first_dot) {		// make the first "dot" or "dash" after automatic
+		   kdelay = -15;		// PTT switching 15 msec longer
+		   first_dot = 0;
+		}
                 break;
             case PREDASH:
                 clear_memory();
                 key_state = SENDDASH;
+		if (first_dot) {		// make the first "dot" or "dash" after automatic
+		   kdelay = -15;		// PTT switching 15 msec longer
+		   first_dot = 0;
+		}
                 break;
 
             // dot paddle  pressed so set keyer_out high for time dependant on speed
@@ -431,10 +430,6 @@ int keyer_init() {
             running = 0;
     }
 
-    if (SIDETONE_GPIO){
-        softToneCreate(SIDETONE_GPIO);
-    }
-
 #ifdef __APPLE__
     cw_event=sem_open("CW", O_CREAT, 0700, 0);
     rc = (cw_event == SEM_FAILED);