]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
LOCALCW: better integration in Config menu, First dit/dah after PTT switching a littl...
authorc vw <dl1ycf@darc.de>
Wed, 8 Aug 2018 16:50:16 +0000 (18:50 +0200)
committerc vw <dl1ycf@darc.de>
Wed, 8 Aug 2018 16:50:16 +0000 (18:50 +0200)
configure.c
gpio.c
gpio.h
iambic.c

index 688d7ea6d0f6eceb6b00da4713383dea2c66e48f..dc512c48b6049e1522c9b1de9c8ddec8a77c6547 100644 (file)
@@ -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 089f0faa8cd6cf13886489a7a3528cebc0bfa4f9..d66c0fa5f779d899d9c0055517c13140b9adf401 100644 (file)
--- 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 96d772ce91912180821cb12f5d77787350bb2eab..9563bb65a4dd23b79885bc51e936c6a4f4b01ef1 100644 (file)
--- 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();
index e01360583a9671b77bcfa73ac99046167d38c985..14ddc9992d7f6c29ace9fd54c04192396b17e005 100644 (file)
--- 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);