diff --git a/CHANGES.md b/CHANGES.md index 7f1a73f..d659caa 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,14 @@ ---------- +## Version 1.3 -- Development snapshot I -- December 2015 ## + +### New Feature: ### + +- Added support for hamlib. This will provide more flexible options for PTT control. + +---------- + ## Version 1.3 -- Development snapshot H -- December 2015 ## ### New Feature: ### diff --git a/Makefile.linux b/Makefile.linux index 8bd5244..21b3787 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -212,6 +212,11 @@ LDFLAGS += -lgps endif +# Uncomment following lines to enable hamlib support. +#CFLAGS += -DUSE_HAMLIB +#LDFLAGS += -lhamlib + + # Name of current directory. # Used to generate zip file name for distribution. diff --git a/README.md b/README.md index 9372c94..5e28b5c 100644 --- a/README.md +++ b/README.md @@ -51,9 +51,12 @@ Version 1.2 decodes more than 1000 error-free frames from [WA8LMF TNC Test CD](h Go to the [releases page](https://github.com/wb2osz/direwolf/releases). Download a zip file with "win" in its name, unzip it, and run direwolf.exe from a command window. -### Linux - short version for the impatient ### +For more details see the **User Guide** in the [doc directory](https://github.com/wb2osz/direwolf/tree/master/doc). -Download the source, unpack the files and run: + +### Linux - Download with web browser ### + +Go to the [releases page](https://github.com/wb2osz/direwolf/releases). Chose desired release and download the source as zip or compressed tar file. Unpack the files, with "unzip" or "tar xfz," and then: cd direwolf-* make @@ -62,7 +65,19 @@ Download the source, unpack the files and run: For more details see the **User Guide** in the [doc directory](https://github.com/wb2osz/direwolf/tree/master/doc). Special considerations for the Raspberry Pi are found in **Raspberry-Pi-APRS.pdf** -Use of "git clone" is not recommended at this time because there could be some inconsistencies during the transition from the old site. +### Linux - Using git clone ### + + cd ~ + git clone https://www.github.com/wb2osz/direwolf + cd direwolf + git checkout 1.2 + make + sudo make install + make install-conf + +The "git checkout 1.2" is necessary to get the most recent stable release. The tip of the master branch is temporarily in an inconsistent state during the transition from the old website. If you want the latest (unstable) development version, use "git checkout dev" instead. + +For more details see the **User Guide** in the [doc directory](https://github.com/wb2osz/direwolf/tree/master/doc). Special considerations for the Raspberry Pi are found in **Raspberry-Pi-APRS.pdf** ## Join the conversation ## @@ -72,6 +87,8 @@ Here are some good places to share information: - [Raspberry Pi 4 Ham Radio](https://groups.yahoo.com/neo/groups/Raspberry_Pi_4-Ham_RADIO/info) +- [linuxham](https://groups.yahoo.com/neo/groups/linuxham/info) + - [TAPR aprssig](http://www.tapr.org/pipermail/aprssig/) diff --git a/audio.h b/audio.h index e25d4a1..18c7365 100644 --- a/audio.h +++ b/audio.h @@ -12,6 +12,10 @@ #ifndef AUDIO_H #define AUDIO_H 1 +#ifdef USE_HAMLIB +#include +#endif + #include "direwolf.h" /* for MAX_CHANS used throughout the application. */ #include "ax25_pad.h" /* for AX25_MAX_ADDR_LEN */ @@ -25,7 +29,8 @@ enum ptt_method_e { PTT_METHOD_NONE, /* VOX or no transmit. */ PTT_METHOD_SERIAL, /* Serial port RTS or DTR. */ PTT_METHOD_GPIO, /* General purpose I/O, Linux only. */ - PTT_METHOD_LPT }; /* Parallel printer port, Linux only. */ + PTT_METHOD_LPT, /* Parallel printer port, Linux only. */ + PTT_METHOD_HAMLIB }; /* HAMLib, Linux only. */ typedef enum ptt_method_e ptt_method_t; @@ -168,13 +173,13 @@ struct audio_s { #define OCTYPE_PTT 0 #define OCTYPE_DCD 1 -#define OCTYPE_FUTURE 2 +#define OCTYPE_FUTURE 2 -#define NUM_OCTYPES 3 /* number of values above */ +#define NUM_OCTYPES 4 /* number of values above */ struct { - ptt_method_t ptt_method; /* none, serial port, GPIO, LPT. */ + ptt_method_t ptt_method; /* none, serial port, GPIO, LPT, HAMLIB. */ char ptt_device[20]; /* Serial device name for PTT. e.g. COM1 or /dev/ttyS0 */ @@ -189,6 +194,10 @@ struct audio_s { int ptt_invert; /* Invert the output. */ int ptt_invert2; /* Invert the secondary output. */ +#ifdef USE_HAMLIB + int ptt_rig; /* HAMLib rig. */ +#endif + } octrl[NUM_OCTYPES]; #define ICTYPE_TXINH 0 @@ -227,6 +236,11 @@ struct audio_s { } achan[MAX_CHANS]; +#ifdef USE_HAMLIB + int rigs; /* Total number of configured rigs */ + RIG *rig[MAX_RIGS]; /* HAMLib rig instances */ +#endif + }; @@ -302,7 +316,6 @@ struct audio_s { * Use one or the other depending on the platform. */ - int audio_open (struct audio_s *pa); int audio_get (int a); /* a = audio device, 0 for first */ diff --git a/config.c b/config.c index 799b0de..cb54011 100644 --- a/config.c +++ b/config.c @@ -46,6 +46,10 @@ #include /* for DEFAULT_GPSD_PORT (2947) */ #endif +#ifdef USE_HAMLIB +#include +#endif + #include "ax25_pad.h" #include "textcolor.h" #include "audio.h" @@ -608,6 +612,12 @@ void config_init (char *fname, struct audio_s *p_audio_config, int adevice; int m; +#if USE_HAMLIB + RIG *rig; + int rigs = 0; +#endif + + #if DEBUG text_color_set(DW_COLOR_DEBUG); dw_printf ("config_init ( %s )\n", fname); @@ -1531,6 +1541,24 @@ void config_init (char *fname, struct audio_s *p_audio_config, text_color_set(DW_COLOR_ERROR); dw_printf ("Config file line %d: %s with LPT is only available on x86 Linux.\n", line, otname); #endif + } + else if (strcasecmp(t, "RIG") == 0) { +#ifdef USE_HAMLIB + p_audio_config->achan[channel].octrl[ot].ptt_method = PTT_METHOD_HAMLIB; + + t = strtok (NULL, " ,\t\n\r"); + if (t == NULL) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Config file line %d: Missing RIG number.\n", line); + continue; + } + + p_audio_config->achan[channel].octrl[ot].ptt_rig = atoi(t); + +#else + text_color_set(DW_COLOR_ERROR); + dw_printf ("Config file line %d: %s with RIG is only available when hamlib support is enabled.\n", line, otname); +#endif } else { @@ -1663,6 +1691,80 @@ void config_init (char *fname, struct audio_s *p_audio_config, } } +/* + * RIG - HAMLib rig configuration. + * + * xxx port model + * + * For example a Yeasu FT-817 on /dev/ttyUSB0: + * RIG /dev/ttyUSB0 120 + * + * For example rigctld on localhost: + * RIG 127.0.0.1:4532 2 + */ + + else if (strcasecmp(t, "RIG") == 0) { +#ifdef USE_HAMLIB + int n; + hamlib_port_t port; + rig_model_t rig_model; + + if (rigs == MAX_RIGS) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Config file line %d: Maximum number of rigs reached.\n", line); + continue; + } + + t = strtok (NULL, " ,\t\n\r"); + if (t == NULL) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Config file line %d: Missing port, model[, key=value].\n", + line); + continue; + } + + strncpy (port.pathname, t, FILPATHLEN - 1); + + t = strtok (NULL, " ,\t\n\r"); + if (t == NULL) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Config file line %d: Missing model[, key=value]\n", line); + continue; + } + + if (strcasecmp(t, "AUTO") == 0) { + rig_load_all_backends(); + rig_model = rig_probe(&port); + } + else { + rig_model = atoi(t); + } + + rig = rig_init(rig_model); + if (!rig) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Config file line %d: Unknown rig %d, please check riglist.h.\n", line, rig_model); + continue; + } + + strncpy (rig->state.rigport.pathname, port.pathname, FILPATHLEN - 1); + n = rig_open(rig); + if (n != RIG_OK) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Config file line %d: Rig open error %d: %s\n", line, n, rigerror(n)); + continue; + } + + p_audio_config->rig[rigs++] = rig; + p_audio_config->rigs = rigs; + +#else + text_color_set(DW_COLOR_ERROR); + dw_printf ("Config file line %d: RIG is only available when hamlib support is enabled.\n", line); + continue; +#endif + } + /* * DWAIT - Extra delay for receiver squelch. */ diff --git a/demod_afsk.c b/demod_afsk.c index 7167f90..c5d248a 100644 --- a/demod_afsk.c +++ b/demod_afsk.c @@ -104,25 +104,12 @@ static inline float convolve (const float *__restrict__ data, const float *__res float sum = 0.0f; int j; -#if 0 - // As suggested here, http://locklessinc.com/articles/vectorize/ - // Unfortunately, older compilers don't recognize it. - // Get more information by using -ftree-vectorizer-verbose=5 - - float *d = __builtin_assume_aligned(data, 16); - float *f = __builtin_assume_aligned(filter, 16); - -#pragma GCC ivdep - for (j=0; jachan[ch].valid) { + int ot, retcode; + RIG *rig; + freq_t freq; + + for (ot = 0; ot < NUM_OCTYPES; ot++) { + if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_HAMLIB) { + if (audio_config_p->achan[ch].octrl[ot].ptt_rig - 1 >= audio_config_p->rigs) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Error: RIG %d not available.\n", audio_config_p->achan[ch].octrl[ot].ptt_rig); + audio_config_p->achan[ch].octrl[ot].ptt_method = PTT_METHOD_NONE; + } + + rig = audio_config_p->rig[audio_config_p->achan[ch].octrl[ot].ptt_rig]; + retcode = rig_get_freq(rig, RIG_VFO_CURR, &freq); + if (retcode == RIG_OK) { + text_color_set(DW_COLOR_INFO); + dw_printf ("RIG tuned on %"PRIfreq"\n", freq); + } else { + text_color_set(DW_COLOR_ERROR); + dw_printf ("RIG rig_get_freq error %s, PTT probably will not work\n", rigerror(retcode)); + } + } + } + } + } +#endif + /* Why doesn't it transmit? Probably forgot to specify PTT option. */ @@ -688,7 +719,7 @@ void ptt_init (struct audio_s *audio_config_p) * probably be renamed something like octrl_set. * * Inputs: ot - Output control type: - * OCTYPE_PTT, OCTYPE_DCD, OCTYPE_FUTURE + * OCTYPE_PTT, OCTYPE_DCD, OCTYPE_HAMLIB, OCTYPE_FUTURE * * chan - channel, 0 .. (number of channels)-1 * @@ -860,6 +891,24 @@ void ptt_set (int ot, int chan, int ptt_signal) #endif /* x86 Linux */ +#ifdef USE_HAMLIB +/* + * Using hamlib? + */ + + if (save_audio_config_p->achan[chan].octrl[ot].ptt_method == PTT_METHOD_HAMLIB) { + int retcode; + RIG *rig = save_audio_config_p->rig[save_audio_config_p->achan[chan].octrl[ot].ptt_rig]; + + if ((retcode = rig_set_ptt(rig, RIG_VFO_CURR, ptt ? RIG_PTT_ON : RIG_PTT_OFF)) != RIG_OK) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Error sending rig_set_ptt command for channel %d %s\n", chan, otnames[ot]); + dw_printf ("%s\n", rigerror(retcode)); + } + } + +#endif + } /* end ptt_set */ @@ -965,6 +1014,31 @@ void ptt_term (void) } } } + +#ifdef USE_HAMLIB + for (n = 0; n < save_audio_config_p->rigs; n++) { + RIG *rig = save_audio_config_p->rig[n]; + int retcode; + + if ((retcode = rig_set_ptt(rig, RIG_VFO_CURR, RIG_PTT_OFF)) != RIG_OK) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Error sending rig_set_ptt command for rig %d\n", n); + dw_printf ("%s\n", rigerror(retcode)); + } + + if ((retcode = rig_close(rig)) != RIG_OK) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Error sending rig_close command for rig %d\n", n); + dw_printf ("%s\n", rigerror(retcode)); + } + + if ((retcode = rig_cleanup(rig)) != RIG_OK) { + text_color_set(DW_COLOR_ERROR); + dw_printf ("Error sending rig_cleanup command for rig %d\n", n); + dw_printf ("%s\n", rigerror(retcode)); + } + } +#endif }