Added HAMLib support for PTT control

This commit is contained in:
Wijnand Modderman-Lenstra 2015-10-27 17:31:02 +01:00
parent b14f1d0ff2
commit 565fa4c082
5 changed files with 210 additions and 8 deletions

View File

@ -204,6 +204,11 @@ LDLIBS += -lasound
#LDLIBS += -lgps #LDLIBS += -lgps
# Uncomment following lines to enable hamlib support.
CFLAGS += -DUSE_HAMLIB
LDLIBS += -lhamlib
# Name of current directory. # Name of current directory.
# Used to generate zip file name for distribution. # Used to generate zip file name for distribution.

24
audio.h
View File

@ -12,6 +12,10 @@
#ifndef AUDIO_H #ifndef AUDIO_H
#define AUDIO_H 1 #define AUDIO_H 1
#ifdef USE_HAMLIB
#include <hamlib/rig.h>
#endif
#include "direwolf.h" /* for MAX_CHANS used throughout the application. */ #include "direwolf.h" /* for MAX_CHANS used throughout the application. */
#include "ax25_pad.h" /* for AX25_MAX_ADDR_LEN */ #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_NONE, /* VOX or no transmit. */
PTT_METHOD_SERIAL, /* Serial port RTS or DTR. */ PTT_METHOD_SERIAL, /* Serial port RTS or DTR. */
PTT_METHOD_GPIO, /* General purpose I/O, Linux only. */ 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; typedef enum ptt_method_e ptt_method_t;
@ -175,13 +180,14 @@ struct audio_s {
#define OCTYPE_PTT 0 #define OCTYPE_PTT 0
#define OCTYPE_DCD 1 #define OCTYPE_DCD 1
#define OCTYPE_FUTURE 2 #define OCTYPE_RIG 2
#define OCTYPE_FUTURE 3
#define NUM_OCTYPES 3 /* number of values above */ #define NUM_OCTYPES 4 /* number of values above */
struct { 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 */ char ptt_device[20]; /* Serial device name for PTT. e.g. COM1 or /dev/ttyS0 */
@ -196,6 +202,10 @@ struct audio_s {
int ptt_invert; /* Invert the output. */ int ptt_invert; /* Invert the output. */
int ptt_invert2; /* Invert the secondary output. */ int ptt_invert2; /* Invert the secondary output. */
#ifdef USE_HAMLIB
int ptt_rig; /* HAMLib rig. */
#endif
} octrl[NUM_OCTYPES]; } octrl[NUM_OCTYPES];
/* Transmit timing. */ /* Transmit timing. */
@ -224,6 +234,11 @@ struct audio_s {
} achan[MAX_CHANS]; } achan[MAX_CHANS];
#ifdef USE_HAMLIB
int rigs; /* Total number of configured rigs */
RIG *rig[MAX_RIGS]; /* HAMLib rig instances */
#endif
}; };
@ -299,7 +314,6 @@ struct audio_s {
* Use one or the other depending on the platform. * Use one or the other depending on the platform.
*/ */
int audio_open (struct audio_s *pa); int audio_open (struct audio_s *pa);
int audio_get (int a); /* a = audio device, 0 for first */ int audio_get (int a); /* a = audio device, 0 for first */

100
config.c
View File

@ -46,6 +46,10 @@
#include <pthread.h> #include <pthread.h>
#endif #endif
#ifdef USE_HAMLIB
#include <hamlib/rig.h>
#endif
#include "ax25_pad.h" #include "ax25_pad.h"
#include "textcolor.h" #include "textcolor.h"
#include "audio.h" #include "audio.h"
@ -489,6 +493,10 @@ void config_init (char *fname, struct audio_s *p_audio_config,
int line; int line;
int channel; int channel;
int adevice; int adevice;
#if USE_HAMLIB
RIG *rig;
int rigs = 0;
#endif
#if DEBUG #if DEBUG
text_color_set(DW_COLOR_DEBUG); text_color_set(DW_COLOR_DEBUG);
@ -1367,6 +1375,24 @@ void config_init (char *fname, struct audio_s *p_audio_config,
dw_printf ("Config file line %d: %s with LPT is only available on x86 Linux.\n", line, otname); dw_printf ("Config file line %d: %s with LPT is only available on x86 Linux.\n", line, otname);
#endif #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 { else {
/* serial port case. */ /* serial port case. */
@ -1451,6 +1477,80 @@ void config_init (char *fname, struct audio_s *p_audio_config,
} /* end of PTT */ } /* end of PTT */
/*
* 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. * DWAIT - Extra delay for receiver squelch.
*/ */

View File

@ -31,6 +31,14 @@
#define MAX_CHANS ((MAX_ADEVS) * 2) #define MAX_CHANS ((MAX_ADEVS) * 2)
/*
* Maximum number of rigs.
*/
#ifdef USE_HAMLIB
#define MAX_RIGS MAX_CHANS
#endif
/* /*
* Get audio device number for given channel. * Get audio device number for given channel.
* and first channel for given device. * and first channel for given device.

79
ptt.c
View File

@ -121,6 +121,7 @@ void ptt_set_debug(int debug)
* PTT_METHOD_SERIAL - serial (com) port. * PTT_METHOD_SERIAL - serial (com) port.
* PTT_METHOD_GPIO - general purpose I/O. * PTT_METHOD_GPIO - general purpose I/O.
* PTT_METHOD_LPT - Parallel printer port. * PTT_METHOD_LPT - Parallel printer port.
* PTT_METHOD_HAMLIB - HAMLib rig control.
* *
* ptt_device Name of serial port device. * ptt_device Name of serial port device.
* e.g. COM1 or /dev/ttyS0. * e.g. COM1 or /dev/ttyS0.
@ -173,6 +174,7 @@ void ptt_init (struct audio_s *audio_config_p)
strcpy (otnames[OCTYPE_PTT], "PTT"); strcpy (otnames[OCTYPE_PTT], "PTT");
strcpy (otnames[OCTYPE_DCD], "DCD"); strcpy (otnames[OCTYPE_DCD], "DCD");
strcpy (otnames[OCTYPE_RIG], "RIG");
strcpy (otnames[OCTYPE_FUTURE], "FUTURE"); strcpy (otnames[OCTYPE_FUTURE], "FUTURE");
@ -314,7 +316,7 @@ void ptt_init (struct audio_s *audio_config_p)
#else #else
/* /*
* Does any of them use GPIO? * Does any of them use GPIO or HAMLIB?
*/ */
using_gpio = 0; using_gpio = 0;
@ -561,6 +563,36 @@ void ptt_init (struct audio_s *audio_config_p)
#endif /* x86 Linux */ #endif /* x86 Linux */
#ifdef USE_HAMLIB
for (ch = 0; ch < MAX_CHANS; ch++) {
if (save_audio_config_p->achan[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. */ /* Why doesn't it transmit? Probably forgot to specify PTT option. */
@ -586,7 +618,7 @@ void ptt_init (struct audio_s *audio_config_p)
* probably be renamed something like octrl_set. * probably be renamed something like octrl_set.
* *
* Inputs: ot - Output control type: * 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 * chan - channel, 0 .. (number of channels)-1
* *
@ -758,6 +790,24 @@ void ptt_set (int ot, int chan, int ptt_signal)
#endif /* x86 Linux */ #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 */ } /* end ptt_set */
@ -803,6 +853,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
} }