mirror of https://github.com/wb2osz/direwolf.git
Merge branch 'gpiod' of https://github.com/ew1abz/direwolf into ew1abz-gpiod
This commit is contained in:
commit
c87534fbc5
|
@ -109,5 +109,5 @@ $RECYCLE.BIN/
|
||||||
*.dSYM
|
*.dSYM
|
||||||
|
|
||||||
# cmake
|
# cmake
|
||||||
build/
|
build*/
|
||||||
tmp/
|
tmp/
|
|
@ -320,6 +320,14 @@ else()
|
||||||
set(HAMLIB_LIBRARIES "")
|
set(HAMLIB_LIBRARIES "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
find_package(gpiod)
|
||||||
|
if(GPIOD_FOUND)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_GPIOD")
|
||||||
|
else()
|
||||||
|
set(GPIOD_INCLUDE_DIRS "")
|
||||||
|
set(GPIOD_LIBRARIES "")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(LINUX)
|
if(LINUX)
|
||||||
find_package(ALSA REQUIRED)
|
find_package(ALSA REQUIRED)
|
||||||
if(ALSA_FOUND)
|
if(ALSA_FOUND)
|
||||||
|
|
|
@ -5,9 +5,9 @@ elseif(NOT DEFINED C_GCC AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||||
set(C_GCC 1)
|
set(C_GCC 1)
|
||||||
elseif(NOT DEFINED C_MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
elseif(NOT DEFINED C_MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
set(C_MSVC 1)
|
set(C_MSVC 1)
|
||||||
if(MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS_EQUAL 1929)
|
if(MSVC_VERSION GREATER 1919 AND MSVC_VERSION LESS 1926)
|
||||||
set(VS2019 ON)
|
set(VS2019 ON)
|
||||||
elseif(MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS_EQUAL 1919)
|
elseif(MSVC_VERSION GREATER 1910 AND MSVC_VERSION LESS 1919)
|
||||||
set(VS2017 ON)
|
set(VS2017 ON)
|
||||||
elseif(MSVC_VERSION GREATER 1899 AND MSVC_VERSION LESS 1910)
|
elseif(MSVC_VERSION GREATER 1899 AND MSVC_VERSION LESS 1910)
|
||||||
set(VS2015 ON)
|
set(VS2015 ON)
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# - Try to find libgpiod
|
||||||
|
# Once done this will define
|
||||||
|
# GPIOD_FOUND - System has libgpiod
|
||||||
|
# GPIOD_INCLUDE_DIRS - The libgpiod include directories
|
||||||
|
# GPIOD_LIBRARIES - The libraries needed to use libgpiod
|
||||||
|
# GPIOD_DEFINITIONS - Compiler switches required for using libgpiod
|
||||||
|
|
||||||
|
find_package(PkgConfig)
|
||||||
|
pkg_check_modules(PC_GPIOD QUIET gpiod)
|
||||||
|
|
||||||
|
find_path(GPIOD_INCLUDE_DIR gpiod.h)
|
||||||
|
find_library(GPIOD_LIBRARY NAMES gpiod)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
# handle the QUIETLY and REQUIRED arguments and set GPIOD_FOUND to TRUE
|
||||||
|
# if all listed variables are TRUE
|
||||||
|
find_package_handle_standard_args(gpiod DEFAULT_MSG
|
||||||
|
GPIOD_LIBRARY GPIOD_INCLUDE_DIR)
|
||||||
|
|
||||||
|
mark_as_advanced(GPIOD_INCLUDE_DIR GPIOD_LIBRARY)
|
||||||
|
|
||||||
|
set(GPIOD_LIBRARIES ${GPIOD_LIBRARY})
|
||||||
|
set(GPIOD_INCLUDE_DIRS ${GPIOD_INCLUDE_DIR})
|
|
@ -10,6 +10,7 @@ include_directories(
|
||||||
${PORTAUDIO_INCLUDE_DIRS}
|
${PORTAUDIO_INCLUDE_DIRS}
|
||||||
${SNDIO_INCLUDE_DIRS}
|
${SNDIO_INCLUDE_DIRS}
|
||||||
${CUSTOM_GEOTRANZ_DIR}
|
${CUSTOM_GEOTRANZ_DIR}
|
||||||
|
${GPIOD_INCLUDE_DIRS}
|
||||||
${CUSTOM_HIDAPI_DIR}
|
${CUSTOM_HIDAPI_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -155,6 +156,7 @@ target_link_libraries(direwolf
|
||||||
${ALSA_LIBRARIES}
|
${ALSA_LIBRARIES}
|
||||||
${UDEV_LIBRARIES}
|
${UDEV_LIBRARIES}
|
||||||
${PORTAUDIO_LIBRARIES}
|
${PORTAUDIO_LIBRARIES}
|
||||||
|
${GPIOD_LIBRARIES}
|
||||||
${SNDIO_LIBRARIES}
|
${SNDIO_LIBRARIES}
|
||||||
${AVAHI_LIBRARIES}
|
${AVAHI_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
|
@ -28,7 +28,8 @@
|
||||||
enum ptt_method_e {
|
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 using sysfs, deprecated after 2020, Linux only. */
|
||||||
|
PTT_METHOD_GPIOD, /* General purpose I/O, using libgpiod, Linux only. */
|
||||||
PTT_METHOD_LPT, /* Parallel printer port, Linux only. */
|
PTT_METHOD_LPT, /* Parallel printer port, Linux only. */
|
||||||
PTT_METHOD_HAMLIB, /* HAMLib, Linux only. */
|
PTT_METHOD_HAMLIB, /* HAMLib, Linux only. */
|
||||||
PTT_METHOD_CM108 }; /* GPIO pin of CM108/CM119/etc. Linux only. */
|
PTT_METHOD_CM108 }; /* GPIO pin of CM108/CM119/etc. Linux only. */
|
||||||
|
@ -311,6 +312,7 @@ struct audio_s {
|
||||||
/* the case for CubieBoard where it was longer. */
|
/* the case for CubieBoard where it was longer. */
|
||||||
/* This is filled in by ptt_init so we don't have to */
|
/* This is filled in by ptt_init so we don't have to */
|
||||||
/* recalculate it each time we access it. */
|
/* recalculate it each time we access it. */
|
||||||
|
/* Also GPIO chip name for GPIOD method. Looks like 'gpiochip4' */
|
||||||
|
|
||||||
/* This could probably be collapsed into ptt_device instead of being separate. */
|
/* This could probably be collapsed into ptt_device instead of being separate. */
|
||||||
|
|
||||||
|
|
37
src/config.c
37
src/config.c
|
@ -1842,6 +1842,43 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
}
|
}
|
||||||
p_audio_config->achan[channel].octrl[ot].ptt_method = PTT_METHOD_GPIO;
|
p_audio_config->achan[channel].octrl[ot].ptt_method = PTT_METHOD_GPIO;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
else if (strcasecmp(t, "GPIOD") == 0) {
|
||||||
|
#if __WIN32__
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Config file line %d: %s with GPIOD is only available on Linux.\n", line, otname);
|
||||||
|
#else
|
||||||
|
#if defined(USE_GPIOD)
|
||||||
|
t = split(NULL,0);
|
||||||
|
if (t == NULL) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Config file line %d: Missing GPIO chip for %s.\n", line, otname);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
strlcpy(p_audio_config->achan[channel].octrl[ot].out_gpio_name, t,
|
||||||
|
sizeof(p_audio_config->achan[channel].octrl[ot].out_gpio_name));
|
||||||
|
|
||||||
|
t = split(NULL,0);
|
||||||
|
if (t == NULL) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf("Config file line %d: Missing GPIO number for %s.\n", line, otname);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*t == '-') {
|
||||||
|
p_audio_config->achan[channel].octrl[ot].out_gpio_num = atoi(t+1);
|
||||||
|
p_audio_config->achan[channel].octrl[ot].ptt_invert = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p_audio_config->achan[channel].octrl[ot].out_gpio_num = atoi(t);
|
||||||
|
p_audio_config->achan[channel].octrl[ot].ptt_invert = 0;
|
||||||
|
}
|
||||||
|
p_audio_config->achan[channel].octrl[ot].ptt_method = PTT_METHOD_GPIOD;
|
||||||
|
#else
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("GPIOD is not supported.\n");
|
||||||
|
#endif /* USE_GPIOD*/
|
||||||
|
#endif /* __WIN32__ */
|
||||||
}
|
}
|
||||||
else if (strcasecmp(t, "LPT") == 0) {
|
else if (strcasecmp(t, "LPT") == 0) {
|
||||||
|
|
||||||
|
|
|
@ -306,7 +306,7 @@ int main (int argc, char *argv[])
|
||||||
//dw_printf ("Dire Wolf version %d.%d\n", MAJOR_VERSION, MINOR_VERSION);
|
//dw_printf ("Dire Wolf version %d.%d\n", MAJOR_VERSION, MINOR_VERSION);
|
||||||
|
|
||||||
|
|
||||||
#if defined(ENABLE_GPSD) || defined(USE_HAMLIB) || defined(USE_CM108) || USE_AVAHI_CLIENT || USE_MACOS_DNSSD
|
#if defined(ENABLE_GPSD) || defined(USE_HAMLIB) || defined(USE_CM108) || USE_AVAHI_CLIENT || USE_MACOS_DNSSD || USE_GPIOD
|
||||||
dw_printf ("Includes optional support for: ");
|
dw_printf ("Includes optional support for: ");
|
||||||
#if defined(ENABLE_GPSD)
|
#if defined(ENABLE_GPSD)
|
||||||
dw_printf (" gpsd");
|
dw_printf (" gpsd");
|
||||||
|
@ -317,6 +317,9 @@ int main (int argc, char *argv[])
|
||||||
#if defined(USE_CM108)
|
#if defined(USE_CM108)
|
||||||
dw_printf (" cm108-ptt");
|
dw_printf (" cm108-ptt");
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(USE_GPIOD)
|
||||||
|
dw_printf (" libgpiod");
|
||||||
|
#endif
|
||||||
#if (USE_AVAHI_CLIENT|USE_MACOS_DNSSD)
|
#if (USE_AVAHI_CLIENT|USE_MACOS_DNSSD)
|
||||||
dw_printf (" dns-sd");
|
dw_printf (" dns-sd");
|
||||||
#endif
|
#endif
|
||||||
|
|
70
src/ptt.c
70
src/ptt.c
|
@ -162,6 +162,10 @@
|
||||||
#include <hamlib/rig.h>
|
#include <hamlib/rig.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_GPIOD
|
||||||
|
#include <gpiod.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* So we can have more common code for fd. */
|
/* So we can have more common code for fd. */
|
||||||
typedef int HANDLE;
|
typedef int HANDLE;
|
||||||
#define INVALID_HANDLE_VALUE (-1)
|
#define INVALID_HANDLE_VALUE (-1)
|
||||||
|
@ -634,6 +638,31 @@ void export_gpio(int ch, int ot, int invert, int direction)
|
||||||
get_access_to_gpio (gpio_value_path);
|
get_access_to_gpio (gpio_value_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_GPIOD)
|
||||||
|
int gpiod_probe(const char *chip_name, int line_number)
|
||||||
|
{
|
||||||
|
struct gpiod_chip *chip;
|
||||||
|
chip = gpiod_chip_open_by_name(chip_name);
|
||||||
|
if (chip == NULL) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Can't open GPIOD chip %s.\n", chip_name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gpiod_line *line;
|
||||||
|
line = gpiod_chip_get_line(chip, line_number);
|
||||||
|
if (line == NULL) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Can't get GPIOD line %d.\n", line_number);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ptt_debug_level >= 2) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf("GPIOD probe OK. Chip: %s line: %d\n", chip_name, line_number);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* USE_GPIOD */
|
||||||
#endif /* not __WIN32__ */
|
#endif /* not __WIN32__ */
|
||||||
|
|
||||||
|
|
||||||
|
@ -650,7 +679,8 @@ void export_gpio(int ch, int ot, int invert, int direction)
|
||||||
* ptt_method Method for PTT signal.
|
* ptt_method Method for PTT signal.
|
||||||
* PTT_METHOD_NONE - not configured. Could be using VOX.
|
* PTT_METHOD_NONE - not configured. Could be using VOX.
|
||||||
* 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 (sysfs).
|
||||||
|
* PTT_METHOD_GPIOD - general purpose I/O (libgpiod).
|
||||||
* PTT_METHOD_LPT - Parallel printer port.
|
* PTT_METHOD_LPT - Parallel printer port.
|
||||||
* PTT_METHOD_HAMLIB - HAMLib rig control.
|
* PTT_METHOD_HAMLIB - HAMLib rig control.
|
||||||
* PTT_METHOD_CM108 - GPIO pins of CM108 etc. USB Audio.
|
* PTT_METHOD_CM108 - GPIO pins of CM108 etc. USB Audio.
|
||||||
|
@ -729,12 +759,13 @@ void ptt_init (struct audio_s *audio_config_p)
|
||||||
if (ptt_debug_level >= 2) {
|
if (ptt_debug_level >= 2) {
|
||||||
|
|
||||||
text_color_set(DW_COLOR_DEBUG);
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
dw_printf ("ch=%d, %s method=%d, device=%s, line=%d, gpio=%d, lpt_bit=%d, invert=%d\n",
|
dw_printf ("ch=%d, %s method=%d, device=%s, line=%d, name=%s, gpio=%d, lpt_bit=%d, invert=%d\n",
|
||||||
ch,
|
ch,
|
||||||
otnames[ot],
|
otnames[ot],
|
||||||
audio_config_p->achan[ch].octrl[ot].ptt_method,
|
audio_config_p->achan[ch].octrl[ot].ptt_method,
|
||||||
audio_config_p->achan[ch].octrl[ot].ptt_device,
|
audio_config_p->achan[ch].octrl[ot].ptt_device,
|
||||||
audio_config_p->achan[ch].octrl[ot].ptt_line,
|
audio_config_p->achan[ch].octrl[ot].ptt_line,
|
||||||
|
audio_config_p->achan[ch].octrl[ot].out_gpio_name,
|
||||||
audio_config_p->achan[ch].octrl[ot].out_gpio_num,
|
audio_config_p->achan[ch].octrl[ot].out_gpio_num,
|
||||||
audio_config_p->achan[ch].octrl[ot].ptt_lpt_bit,
|
audio_config_p->achan[ch].octrl[ot].ptt_lpt_bit,
|
||||||
audio_config_p->achan[ch].octrl[ot].ptt_invert);
|
audio_config_p->achan[ch].octrl[ot].ptt_invert);
|
||||||
|
@ -880,7 +911,28 @@ void ptt_init (struct audio_s *audio_config_p)
|
||||||
if (using_gpio) {
|
if (using_gpio) {
|
||||||
get_access_to_gpio ("/sys/class/gpio/export");
|
get_access_to_gpio ("/sys/class/gpio/export");
|
||||||
}
|
}
|
||||||
|
#if defined(USE_GPIOD)
|
||||||
|
// GPIOD
|
||||||
|
for (ch = 0; ch < MAX_CHANS; ch++) {
|
||||||
|
if (save_audio_config_p->achan[ch].medium == MEDIUM_RADIO) {
|
||||||
|
for (int ot = 0; ot < NUM_OCTYPES; ot++) {
|
||||||
|
if (audio_config_p->achan[ch].octrl[ot].ptt_method == PTT_METHOD_GPIOD) {
|
||||||
|
const char *chip_name = audio_config_p->achan[ch].octrl[ot].out_gpio_name;
|
||||||
|
int line_number = audio_config_p->achan[ch].octrl[ot].out_gpio_num;
|
||||||
|
int rc = gpiod_probe(chip_name, line_number);
|
||||||
|
if (rc < 0) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Disable PTT for channel %d\n", ch);
|
||||||
|
audio_config_p->achan[ch].octrl[ot].ptt_method = PTT_METHOD_NONE;
|
||||||
|
} else {
|
||||||
|
// Set initial state off ptt_set will invert output signal if appropriate.
|
||||||
|
ptt_set (ot, ch, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* USE_GPIOD */
|
||||||
/*
|
/*
|
||||||
* We should now be able to create the device nodes for
|
* We should now be able to create the device nodes for
|
||||||
* the pins we want to use.
|
* the pins we want to use.
|
||||||
|
@ -1298,6 +1350,18 @@ void ptt_set (int ot, int chan, int ptt_signal)
|
||||||
close (fd);
|
close (fd);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_GPIOD)
|
||||||
|
if (save_audio_config_p->achan[chan].octrl[ot].ptt_method == PTT_METHOD_GPIOD) {
|
||||||
|
const char *chip = save_audio_config_p->achan[chan].octrl[ot].out_gpio_name;
|
||||||
|
int line = save_audio_config_p->achan[chan].octrl[ot].out_gpio_num;
|
||||||
|
int rc = gpiod_ctxless_set_value(chip, line, ptt, false, "direwolf", NULL, NULL);
|
||||||
|
if (ptt_debug_level >= 1) {
|
||||||
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf("PTT_METHOD_GPIOD chip: %s line: %d ptt: %d rc: %d\n", chip, line, ptt, rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* USE_GPIOD */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue