Added channel interlock functionality

New INTERLOCK parameter for config file interlocks all channels with the same interlock number configured to share DCD and PTT signaling.
Useful with several setup types where 2 or more channels shouldn't interfere with eachother. For example when radios and/or antennas are shared.
This commit is contained in:
Dave van der Locht 2022-05-27 11:31:27 +02:00
parent c9ffbd71c3
commit 29b82e2724
6 changed files with 85 additions and 3 deletions

View File

@ -86,6 +86,7 @@
#include "hdlc_rec.h" #include "hdlc_rec.h"
#if 0 /* Typical but not flexible enough. */ #if 0 /* Typical but not flexible enough. */
struct wav_header { /* .WAV file header. */ struct wav_header { /* .WAV file header. */
@ -900,6 +901,13 @@ void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alev
} /* end fake dlq_append */ } /* end fake dlq_append */
/* Fake is_channel_busy */
int is_channel_busy(int chan)
{
return 0;
}
void ptt_set (int ot, int chan, int ptt_signal) void ptt_set (int ot, int chan, int ptt_signal)
{ {
// Should only get here for DCD output control. // Should only get here for DCD output control.

View File

@ -245,6 +245,8 @@ struct audio_s {
int passall; /* Allow thru even with bad CRC. */ int passall; /* Allow thru even with bad CRC. */
/* Interlock channels */
int interlock; /* Interlock number */
/* Additional properties for transmit. */ /* Additional properties for transmit. */
@ -451,6 +453,14 @@ struct audio_s {
#define DEFAULT_TXTAIL 10 #define DEFAULT_TXTAIL 10
#define DEFAULT_FULLDUP 0 #define DEFAULT_FULLDUP 0
/*
* Interlocks are used to 'bind' channels together to share DCD and PTT signaling.
* Useful with several setup types where 2 or more channels shouldn't interfere with eachother.
* For example when radios and/or antennas are shared.
*/
#define MAX_INTERLOCKS 8
/* /*
* Note that we have two versions of these in audio.c and audio_win.c. * Note that we have two versions of these in audio.c and audio_win.c.
* Use one or the other depending on the platform. * Use one or the other depending on the platform.

View File

@ -1998,6 +1998,25 @@ void lm_channel_busy (dlq_item_t *E)
} /* end lm_channel_busy */ } /* end lm_channel_busy */
/*------------------------------------------------------------------------------
*
* Name: is_channel_busy
*
* Purpose: Returns DCD or PTT status for channel
*
* Inputs: Channel
*
* Outputs: True when busy, false when free
*
*------------------------------------------------------------------------------*/
int is_channel_busy(int chan)
{
if (ptt_status[chan] || dcd_status[chan])
return 1;
return 0;
} /* end is_channel_busy */
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------

View File

@ -76,6 +76,7 @@ void lm_seize_confirm (dlq_item_t *E);
void lm_channel_busy (dlq_item_t *E); void lm_channel_busy (dlq_item_t *E);
int is_channel_busy(int chan);
void dl_timer_expiry (void); void dl_timer_expiry (void);

View File

@ -780,6 +780,8 @@ void config_init (char *fname, struct audio_s *p_audio_config,
p_audio_config->achan[channel].sanity_test = SANITY_APRS; p_audio_config->achan[channel].sanity_test = SANITY_APRS;
p_audio_config->achan[channel].passall = 0; p_audio_config->achan[channel].passall = 0;
p_audio_config->achan[channel].interlock = 0;
for (ot = 0; ot < NUM_OCTYPES; ot++) { for (ot = 0; ot < NUM_OCTYPES; ot++) {
p_audio_config->achan[channel].octrl[ot].ptt_method = PTT_METHOD_NONE; p_audio_config->achan[channel].octrl[ot].ptt_method = PTT_METHOD_NONE;
strlcpy (p_audio_config->achan[channel].octrl[ot].ptt_device, "", sizeof(p_audio_config->achan[channel].octrl[ot].ptt_device)); strlcpy (p_audio_config->achan[channel].octrl[ot].ptt_device, "", sizeof(p_audio_config->achan[channel].octrl[ot].ptt_device));
@ -1729,6 +1731,31 @@ void config_init (char *fname, struct audio_s *p_audio_config,
} }
} }
/*
* INTERLOCK n
*
* Interlocks channels with the same interlock number (n) to share DCD and PTT signaling.
*/
else if (strcasecmp(t, "INTERLOCK") == 0) {
int n;
t = split(NULL,0);
if (t == NULL) {
text_color_set(DW_COLOR_ERROR);
dw_printf ("Line %d: Missing number for INTERLOCK command.\n", line);
continue;
}
n = atoi(t);
if (n >= 0 && n <= MAX_INTERLOCKS) {
p_audio_config->achan[channel].interlock = n;
}
else {
p_audio_config->achan[channel].interlock = 0;
text_color_set(DW_COLOR_ERROR);
dw_printf ("Line %d: Invalid number for INTERLOCK. Using %d.\n",
line, p_audio_config->achan[channel].interlock);
}
}
/* /*
* PTT - Push To Talk signal line. * PTT - Push To Talk signal line.

View File

@ -47,6 +47,7 @@
#include "ptt.h" #include "ptt.h"
#include "fx25.h" #include "fx25.h"
#include "il2p.h" #include "il2p.h"
#include "ax25_link.h"
//#define TEST 1 /* Define for unit testing. */ //#define TEST 1 /* Define for unit testing. */
@ -791,11 +792,27 @@ int hdlc_rec_data_detect_any (int chan)
{ {
int sc; int sc;
int ch;
int il;
assert (chan >= 0 && chan < MAX_CHANS); assert (chan >= 0 && chan < MAX_CHANS);
for (sc = 0; sc < num_subchan[chan]; sc++) { if (g_audio_p->achan[chan].interlock > 0) {
if (composite_dcd[chan][sc] != 0) // Channel has an interlock number configured, proceed checking interlocked channels
return (1); il = g_audio_p->achan[chan].interlock;
for (ch = 0; ch < MAX_CHANS; ch++) {
if (g_audio_p->achan[ch].interlock == il) {
// Check DCD and PTT state at data link state machine
if (is_channel_busy(ch))
return (1);
}
}
} else {
// No interlock
for (sc = 0; sc < num_subchan[chan]; sc++) {
if (composite_dcd[chan][sc] != 0)
return (1);
}
} }
if (get_input(ICTYPE_TXINH, chan) == 1) return (1); if (get_input(ICTYPE_TXINH, chan) == 1) return (1);