Skip to content

Added HAMLib support for PTT control #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Makefile.linux
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ LDLIBS += -lasound
#LDLIBS += -lgps


# Uncomment following lines to enable hamlib support.
CFLAGS += -DUSE_HAMLIB
LDLIBS += -lhamlib


# Name of current directory.
# Used to generate zip file name for distribution.

Expand Down
24 changes: 19 additions & 5 deletions audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
#ifndef AUDIO_H
#define AUDIO_H 1

#ifdef USE_HAMLIB
#include <hamlib/rig.h>
#endif

#include "direwolf.h" /* for MAX_CHANS used throughout the application. */
#include "ax25_pad.h" /* for AX25_MAX_ADDR_LEN */

Expand All @@ -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;

Expand Down Expand Up @@ -175,13 +180,14 @@ struct audio_s {

#define OCTYPE_PTT 0
#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 {

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 */

Expand All @@ -196,6 +202,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];

/* Transmit timing. */
Expand Down Expand Up @@ -224,6 +234,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

};


Expand Down Expand Up @@ -299,7 +314,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 */
Expand Down
100 changes: 100 additions & 0 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
#include <pthread.h>
#endif

#ifdef USE_HAMLIB
#include <hamlib/rig.h>
#endif

#include "ax25_pad.h"
#include "textcolor.h"
#include "audio.h"
Expand Down Expand Up @@ -489,6 +493,10 @@ void config_init (char *fname, struct audio_s *p_audio_config,
int line;
int channel;
int adevice;
#if USE_HAMLIB
RIG *rig;
int rigs = 0;
#endif

#if DEBUG
text_color_set(DW_COLOR_DEBUG);
Expand Down Expand Up @@ -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);
#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 {

/* serial port case. */
Expand Down Expand Up @@ -1451,6 +1477,80 @@ void config_init (char *fname, struct audio_s *p_audio_config,
} /* 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.
*/
Expand Down
10 changes: 9 additions & 1 deletion direwolf.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@

#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.
* and first channel for given device.
Expand Down Expand Up @@ -158,4 +166,4 @@ typedef pthread_mutex_t dw_mutex_t;



#endif /* ifndef DIREWOLF_H */
#endif /* ifndef DIREWOLF_H */
79 changes: 77 additions & 2 deletions ptt.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ void ptt_set_debug(int debug)
* PTT_METHOD_SERIAL - serial (com) port.
* PTT_METHOD_GPIO - general purpose I/O.
* PTT_METHOD_LPT - Parallel printer port.
* PTT_METHOD_HAMLIB - HAMLib rig control.
*
* ptt_device Name of serial port device.
* e.g. COM1 or /dev/ttyS0.
Expand Down Expand Up @@ -173,6 +174,7 @@ void ptt_init (struct audio_s *audio_config_p)

strcpy (otnames[OCTYPE_PTT], "PTT");
strcpy (otnames[OCTYPE_DCD], "DCD");
strcpy (otnames[OCTYPE_RIG], "RIG");
strcpy (otnames[OCTYPE_FUTURE], "FUTURE");


Expand Down Expand Up @@ -314,7 +316,7 @@ void ptt_init (struct audio_s *audio_config_p)
#else

/*
* Does any of them use GPIO?
* Does any of them use GPIO or HAMLIB?
*/

using_gpio = 0;
Expand Down Expand Up @@ -561,6 +563,36 @@ void ptt_init (struct audio_s *audio_config_p)

#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. */

Expand All @@ -586,7 +618,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
*
Expand Down Expand Up @@ -758,6 +790,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 */

Expand Down Expand Up @@ -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
}


Expand Down