From 9a343877e5431cb3544f3ec791579cba16060c34 Mon Sep 17 00:00:00 2001 From: Rob French Date: Mon, 9 Mar 2020 23:54:28 -0500 Subject: [PATCH] Updated the GPIO keyer to take a 5th (optional) argument, hangtime. Sets the number of milliseconds for a semi-QSK delay (i.e. stay in transmit for # of msecs after last CW symbol). --- gpiokeyer.c | 37 +++++++++++++++++++++++++++++++++---- quisk.c | 16 +++++++++++++++- quisk.h | 7 ++++++- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/gpiokeyer.c b/gpiokeyer.c index a48349d..8e3ebd8 100644 --- a/gpiokeyer.c +++ b/gpiokeyer.c @@ -111,6 +111,7 @@ Boston, MA 02110-1301, USA. **********************************************************************/ #define NSEC_PER_SEC (1000000000) +#define CW_HANGTIME_DEFAULT (250) /*********************************************************************** * Types @@ -184,7 +185,7 @@ static int cw_keyer_weight = 55; static int cw_keys_reversed = 0; static int cw_keyer_spacing = 0; static int cw_keyer_enabled = 1; -static int cw_hangtime_msec = 250; // not currently (re-)configurable +static int cw_hangtime_msec = CW_HANGTIME_DEFAULT; static int cw_active_state = 0; // not currently (re-)configurable /* Current Paddle State @@ -238,7 +239,7 @@ static void keyer_update() { * semi-QSK delay. ~250ms after the end of the last symbol, the * T/R switch will be disabled. */ - cw_hangtime_msec = (int)(0.25f * 1000.0f); +// cw_hangtime_msec = (int)(0.25f * 1000.0f); } /* KC4UPR: The "actual" event handler. Updates the value of the @@ -609,7 +610,20 @@ int open_key_gpiokeyer(const char * name) * two can be zero if that functionality is not desired, but they * must be present in the name string. */ - if (sscanf(name, "gpio:%d,%d,%d,%d", &left_paddle_gpio, &right_paddle_gpio, &keyer_out_gpio, &tr_switch_gpio) < 4) { + switch(sscanf(name, "gpio:%d,%d,%d,%d,%d", &left_paddle_gpio, &right_paddle_gpio, &keyer_out_gpio, &tr_switch_gpio, &cw_hangtime_msec)) { + case 5: + if (cw_hangtime_msec > 1000) cw_hangtime_msec = 1000; + if (cw_hangtime_msec < 0) cw_hangtime_msec = 0; + break; + + case 4: + /* KC4UPR: matched the first 4 inputs - original v0.1 interface. + * Need to fill-in-blanks for later version(s). + */ + cw_hangtime_msec = CW_HANGTIME_DEFAULT; + break; + + default: fprintf(stderr, "[GPIO Keyer] insufficient parameters: %s\n", name); return -1; } @@ -783,7 +797,7 @@ void quisk_set_gpio_keyer_strict(int flag) cw_keyer_spacing = (flag == 0 ? 0 : 1); } -/* KC4UPR: Enabled/disable the keyer. If true, then regardless of +/* KC4UPR: Enable/disable the keyer. If disabled, then regardless of * state, nothing will be output. */ void quisk_set_gpio_keyer_enabled(int flag) @@ -795,6 +809,21 @@ void quisk_set_gpio_keyer_enabled(int flag) cw_keyer_enabled = (flag == 0 ? 0 : 1); } +/* KC4UPR: Set the keyer "hangtime". This is the delay that the T/R + * switch remains set after the last symbol was transmitted (the default + * is 250 msec, if this is never called). Can be set from 0 to 1000 + * msec. + */ +void quisk_set_gpio_keyer_hangtime(int msec) +{ + #if defined(DEBUG) + fprintf(stdout, "[GPIO Keyer] hangtime: %d msec\n", msec) + #endif + if ((msec > -1) && (msec < 1001)) { + cw_hangtime_msec = msec; + } +} + /*********************************************************************** * EOF **********************************************************************/ diff --git a/quisk.c b/quisk.c index efaa260..4a3abdb 100755 --- a/quisk.c +++ b/quisk.c @@ -5215,7 +5215,6 @@ static PyObject * set_gpio_keyer_mode(PyObject * self, PyObject * args) static PyObject * set_gpio_keyer_speed(PyObject * self, PyObject * args) { int wpm; - fprintf(stderr, "Trying to set keyer speed\n"); if (!PyArg_ParseTuple (args, "i", &wpm)) return NULL; quisk_set_gpio_keyer_speed(wpm); @@ -5280,6 +5279,20 @@ static PyObject * set_gpio_keyer_enabled(PyObject * self, PyObject * args) Py_INCREF (Py_None); return Py_None; } + +/* KC4UPR: Set the GPIO keyer hangtime: the number of milliseconds to + * leave the T/R switch in "transmit" after the last CW symbol. + */ +static PyObject * set_gpio_keyer_hangtime(PyObject * self, PyObject * args) +{ + int hangtime; + + if (!PyArg_ParseTuple (args, "i", &hangtime)) + return NULL; + quisk_set_gpio_keyer_hangtime(hangtime); + Py_INCREF (Py_None); + return Py_None; +} #endif static PyMethodDef QuiskMethods[] = { @@ -5394,6 +5407,7 @@ static PyMethodDef QuiskMethods[] = { {"set_gpio_keyer_reversed", set_gpio_keyer_reversed, METH_VARARGS, "Enabled/disable reversed paddles."}, {"set_gpio_keyer_strict", set_gpio_keyer_strict, METH_VARARGS, "Enable/disable strict character spacing."}, {"set_gpio_keyer_enabled", set_gpio_keyer_enabled, METH_VARARGS, "Enable/disable the CW keyer"}, + {"set_gpio_keyer_hangtime", set_gpio_keyer_hangtime, METH_VARARGS, "Set number of msecs for semi-QSK delay"}, #endif {NULL, NULL, 0, NULL} /* Sentinel */ }; diff --git a/quisk.h b/quisk.h index cdc5b2a..7d46909 100755 --- a/quisk.h +++ b/quisk.h @@ -290,6 +290,7 @@ int QuiskDeltaMsec(int); * reverse - reverse left/right paddles (dot/dash by default) * strict - enforce strict character spacing * enabled - enable/disable the keyer + * hangtime - msecs to transmit after last CW symbol */ void quisk_set_gpio_keyer_mode(int); void quisk_set_gpio_keyer_speed(int); @@ -297,6 +298,7 @@ void quisk_set_gpio_keyer_weight(int); void quisk_set_gpio_keyer_reversed(int); void quisk_set_gpio_keyer_strict(int); void quisk_set_gpio_keyer_enabled(int); +void quisk_set_gpio_keyer_hangtime(int); #endif // Functions supporting digital voice codecs @@ -362,6 +364,7 @@ int import_quisk_api(void); // used to initialize Quisk_API //#define quisk_set_gpio_keyer_reversed (*( void (*) (int) )Quisk_API[14]) //#define quisk_set_gpio_keyer_strict (*( void (*) (int) )Quisk_API[15]) //#define quisk_set_gpio_keyer_enabled (*( void (*) (int) )Quisk_API[16]) +//#define quisk_set_gpio_keyer_hangtime (*( void (*) (int) )Quisk_API[17]) //#endif #else @@ -389,6 +392,7 @@ void quisk_sample_source4(ty_sample_start, ty_sample_stop, ty_sample_read, ty_sa //void quisk_set_gpio_keyer_reversed(int); //void quisk_set_gpio_keyer_strict(int); //void quisk_set_gpio_keyer_enabled(int); +//void quisk_set_gpio_keyer_hangtime(int); //#endif //#if defined(ENABLE_GPIO_KEYER) @@ -401,7 +405,8 @@ void quisk_sample_source4(ty_sample_start, ty_sample_stop, ty_sample_read, ty_sa // &quisk_sound_state, &QuiskGetConfigInt, &QuiskGetConfigDouble, &QuiskGetConfigString, &QuiskTimeSec, \ // &QuiskSleepMicrosec, &QuiskPrintTime, &quisk_sample_source, &quisk_dvoice_freedv, &quisk_is_key_down, \ // &quisk_sample_source4, &quisk_set_gpio_keyer_mode, &quisk_set_gpio_keyer_speed, \ -// &quisk_set_gpio_keyer_weight, &quisk_set_gpio_keyer_reversed, &quisk_set_gpio_keyer_strict, &quisk_set_gpio_keyer_enabled \ +// &quisk_set_gpio_keyer_weight, &quisk_set_gpio_keyer_reversed, &quisk_set_gpio_keyer_strict, \ +// &quisk_set_gpio_keyer_enabled, &quisk_set_gpio_keyer_hangtime \ // } //#else #define QUISK_API_INIT { \