mirror of https://github.com/wb2osz/direwolf.git
Limited support for CM108/CM119 GPIO PTT on Windows.
This commit is contained in:
parent
667e9caaf2
commit
a1afcbbafe
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
### New Features: ###
|
### New Features: ###
|
||||||
|
|
||||||
|
- Limited support for CM109/CM119 GPIO PTT on Windows.
|
||||||
|
|
||||||
- Dire Wolf now advertises itself using DNS Service Discovery. This allows suitable APRS / Packet Radio applications to find a network KISS TNC without knowing the IP address or TCP port. Thanks to Hessu for providing this. Currently available only for Linux and Mac OSX. [Read all about it here.](https://github.com/hessu/aprs-specs/blob/master/TCP-KISS-DNS-SD.md)
|
- Dire Wolf now advertises itself using DNS Service Discovery. This allows suitable APRS / Packet Radio applications to find a network KISS TNC without knowing the IP address or TCP port. Thanks to Hessu for providing this. Currently available only for Linux and Mac OSX. [Read all about it here.](https://github.com/hessu/aprs-specs/blob/master/TCP-KISS-DNS-SD.md)
|
||||||
|
|
||||||
- The transmit calibration tone (-x) command line option now accepts a radio channel number and/or a single letter mode: a = alternate tones, m = mark tone, s = space tone, p = PTT only no sound.
|
- The transmit calibration tone (-x) command line option now accepts a radio channel number and/or a single letter mode: a = alternate tones, m = mark tone, s = space tone, p = PTT only no sound.
|
||||||
|
|
|
@ -72,6 +72,7 @@ set(CUSTOM_SRC_DIR "${CMAKE_SOURCE_DIR}/src")
|
||||||
set(CUSTOM_EXTERNAL_DIR "${CMAKE_SOURCE_DIR}/external")
|
set(CUSTOM_EXTERNAL_DIR "${CMAKE_SOURCE_DIR}/external")
|
||||||
set(CUSTOM_MISC_DIR "${CUSTOM_EXTERNAL_DIR}/misc")
|
set(CUSTOM_MISC_DIR "${CUSTOM_EXTERNAL_DIR}/misc")
|
||||||
set(CUSTOM_REGEX_DIR "${CUSTOM_EXTERNAL_DIR}/regex")
|
set(CUSTOM_REGEX_DIR "${CUSTOM_EXTERNAL_DIR}/regex")
|
||||||
|
set(CUSTOM_HIDAPI_DIR "${CUSTOM_EXTERNAL_DIR}/hidapi")
|
||||||
set(CUSTOM_GEOTRANZ_DIR "${CUSTOM_EXTERNAL_DIR}/geotranz")
|
set(CUSTOM_GEOTRANZ_DIR "${CUSTOM_EXTERNAL_DIR}/geotranz")
|
||||||
set(CUSTOM_DATA_DIR "${CMAKE_SOURCE_DIR}/data")
|
set(CUSTOM_DATA_DIR "${CMAKE_SOURCE_DIR}/data")
|
||||||
set(CUSTOM_SCRIPTS_DIR "${CMAKE_SOURCE_DIR}/scripts")
|
set(CUSTOM_SCRIPTS_DIR "${CMAKE_SOURCE_DIR}/scripts")
|
||||||
|
@ -321,6 +322,7 @@ add_subdirectory(data)
|
||||||
# external libraries
|
# external libraries
|
||||||
add_subdirectory(${CUSTOM_GEOTRANZ_DIR})
|
add_subdirectory(${CUSTOM_GEOTRANZ_DIR})
|
||||||
add_subdirectory(${CUSTOM_REGEX_DIR})
|
add_subdirectory(${CUSTOM_REGEX_DIR})
|
||||||
|
add_subdirectory(${CUSTOM_HIDAPI_DIR})
|
||||||
add_subdirectory(${CUSTOM_MISC_DIR})
|
add_subdirectory(${CUSTOM_MISC_DIR})
|
||||||
|
|
||||||
# direwolf source code and utilities
|
# direwolf source code and utilities
|
||||||
|
|
|
@ -78,7 +78,6 @@ endfunction()
|
||||||
# The default will be set for maximum portability so packagers won't need to
|
# The default will be set for maximum portability so packagers won't need to
|
||||||
# to anything special.
|
# to anything special.
|
||||||
#
|
#
|
||||||
set(FORCE_SSE 1)
|
|
||||||
#
|
#
|
||||||
# While ENABLE_GENERIC also had the desired result (for x86_64), I don't think
|
# While ENABLE_GENERIC also had the desired result (for x86_64), I don't think
|
||||||
# it is the right approach. It prevents the detection of the architecture,
|
# it is the right approach. It prevents the detection of the architecture,
|
||||||
|
|
|
@ -263,10 +263,22 @@
|
||||||
%C%
|
%C%
|
||||||
%C%#DTMF
|
%C%#DTMF
|
||||||
%C%
|
%C%
|
||||||
%C%#
|
%L%# If using a C-Media CM108/CM119 or similar USB Audio Adapter,
|
||||||
%C%# If not using a VOX circuit, the transmitter Push to Talk (PTT)
|
%L%# you can use a GPIO pin for PTT control. This is very convenient
|
||||||
%C%# control is usually wired to a serial port with a suitable interface circuit.
|
%L%# because a single USB connection is used for both audio and PTT.
|
||||||
%C%# DON'T connect it directly!
|
%L%# Example:
|
||||||
|
%L%
|
||||||
|
%L%#PTT CM108
|
||||||
|
%L%
|
||||||
|
%W%# If using a C-Media CM108/CM119 or similar USB Audio Adapter,
|
||||||
|
%W%# you can use a GPIO pin for PTT control. This is very convenient
|
||||||
|
%W%# because a single USB connection is used for both audio and PTT.
|
||||||
|
%W%# Example:
|
||||||
|
%W%
|
||||||
|
%W%#PTT CM108
|
||||||
|
%W%%C%#
|
||||||
|
%C%# The transmitter Push to Talk (PTT) control can be wired to a serial port
|
||||||
|
%C%# with a suitable interface circuit. DON'T connect it directly!
|
||||||
%C%#
|
%C%#
|
||||||
%C%# For the PTT command, specify the device and either RTS or DTR.
|
%C%# For the PTT command, specify the device and either RTS or DTR.
|
||||||
%C%# RTS or DTR may be preceded by "-" to invert the signal.
|
%C%# RTS or DTR may be preceded by "-" to invert the signal.
|
||||||
|
|
|
@ -9,6 +9,7 @@ include_directories(
|
||||||
${UDEV_INCLUDE_DIRS}
|
${UDEV_INCLUDE_DIRS}
|
||||||
${PORTAUDIO_INCLUDE_DIRS}
|
${PORTAUDIO_INCLUDE_DIRS}
|
||||||
${CUSTOM_GEOTRANZ_DIR}
|
${CUSTOM_GEOTRANZ_DIR}
|
||||||
|
${CUSTOM_HIDAPI_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WIN32 OR CYGWIN)
|
if(WIN32 OR CYGWIN)
|
||||||
|
@ -106,6 +107,7 @@ if(LINUX)
|
||||||
elseif(WIN32 OR CYGWIN) # windows
|
elseif(WIN32 OR CYGWIN) # windows
|
||||||
list(APPEND direwolf_SOURCES
|
list(APPEND direwolf_SOURCES
|
||||||
audio_win.c
|
audio_win.c
|
||||||
|
cm108.c
|
||||||
|
|
||||||
# icon
|
# icon
|
||||||
# require plain gcc binary or link
|
# require plain gcc binary or link
|
||||||
|
@ -134,6 +136,7 @@ target_link_libraries(direwolf
|
||||||
${GEOTRANZ_LIBRARIES}
|
${GEOTRANZ_LIBRARIES}
|
||||||
${MISC_LIBRARIES}
|
${MISC_LIBRARIES}
|
||||||
${REGEX_LIBRARIES}
|
${REGEX_LIBRARIES}
|
||||||
|
${HIDAPI_LIBRARIES}
|
||||||
Threads::Threads
|
Threads::Threads
|
||||||
${GPSD_LIBRARIES}
|
${GPSD_LIBRARIES}
|
||||||
${HAMLIB_LIBRARIES}
|
${HAMLIB_LIBRARIES}
|
||||||
|
@ -147,7 +150,7 @@ if(WIN32 OR CYGWIN)
|
||||||
set_target_properties(direwolf
|
set_target_properties(direwolf
|
||||||
PROPERTIES COMPILE_FLAGS "-DUSE_REGEX_STATIC"
|
PROPERTIES COMPILE_FLAGS "-DUSE_REGEX_STATIC"
|
||||||
)
|
)
|
||||||
target_link_libraries(direwolf winmm ws2_32)
|
target_link_libraries(direwolf winmm ws2_32 setupapi)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# decode_aprs
|
# decode_aprs
|
||||||
|
@ -413,8 +416,11 @@ endif()
|
||||||
|
|
||||||
|
|
||||||
# List USB audio adapters than can use GPIO for PTT.
|
# List USB audio adapters than can use GPIO for PTT.
|
||||||
|
# Originally for Linux only (using udev).
|
||||||
|
# Version 1.7 adds it for Windows. Needs hidapi library.
|
||||||
|
|
||||||
# cm108
|
# cm108
|
||||||
if(UDEV_FOUND)
|
if(UDEV_FOUND OR WIN32 OR CYGWIN)
|
||||||
list(APPEND cm108_SOURCES
|
list(APPEND cm108_SOURCES
|
||||||
cm108.c
|
cm108.c
|
||||||
textcolor.c
|
textcolor.c
|
||||||
|
@ -430,8 +436,21 @@ if(UDEV_FOUND)
|
||||||
|
|
||||||
target_link_libraries(cm108
|
target_link_libraries(cm108
|
||||||
${MISC_LIBRARIES}
|
${MISC_LIBRARIES}
|
||||||
${UDEV_LIBRARIES}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (LINUX)
|
||||||
|
target_link_libraries(cm108
|
||||||
|
${UDEV_LIBRARIES}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (WIN32 OR CYGWIN)
|
||||||
|
target_link_libraries(cm108
|
||||||
|
${HIDAPI_LIBRARIES}
|
||||||
|
ws2_32
|
||||||
|
setupapi
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
@ -496,6 +515,6 @@ install(TARGETS atest DESTINATION ${INSTALL_BIN_DIR})
|
||||||
install(TARGETS ttcalc DESTINATION ${INSTALL_BIN_DIR})
|
install(TARGETS ttcalc DESTINATION ${INSTALL_BIN_DIR})
|
||||||
install(TARGETS kissutil DESTINATION ${INSTALL_BIN_DIR})
|
install(TARGETS kissutil DESTINATION ${INSTALL_BIN_DIR})
|
||||||
install(TARGETS appserver DESTINATION ${INSTALL_BIN_DIR})
|
install(TARGETS appserver DESTINATION ${INSTALL_BIN_DIR})
|
||||||
if(UDEV_FOUND)
|
if(UDEV_FOUND OR WIN32 OR CYGWIN)
|
||||||
install(TARGETS cm108 DESTINATION ${INSTALL_BIN_DIR})
|
install(TARGETS cm108 DESTINATION ${INSTALL_BIN_DIR})
|
||||||
endif()
|
endif()
|
||||||
|
|
10
src/audio.h
10
src/audio.h
|
@ -240,15 +240,17 @@ struct audio_s {
|
||||||
|
|
||||||
ptt_method_t ptt_method; /* none, serial port, GPIO, LPT, HAMLIB, CM108. */
|
ptt_method_t ptt_method; /* none, serial port, GPIO, LPT, HAMLIB, CM108. */
|
||||||
|
|
||||||
char ptt_device[100]; /* Serial device name for PTT. e.g. COM1 or /dev/ttyS0 */
|
char ptt_device[128]; /* Serial device name for PTT. e.g. COM1 or /dev/ttyS0 */
|
||||||
/* Also used for HAMLIB. Could be host:port when model is 1. */
|
/* Also used for HAMLIB. Could be host:port when model is 1. */
|
||||||
/* For years, 20 characters was plenty then we start getting extreme names like this: */
|
/* For years, 20 characters was plenty then we start getting extreme names like this: */
|
||||||
/* /dev/serial/by-id/usb-FTDI_Navigator__CAT___2nd_PTT__00000000-if00-port0 */
|
/* /dev/serial/by-id/usb-FTDI_Navigator__CAT___2nd_PTT__00000000-if00-port0 */
|
||||||
/* /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0 */
|
/* /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0 */
|
||||||
/* Issue 104, changed to 100 bytes in version 1.5. */
|
/* Issue 104, changed to 100 bytes in version 1.5. */
|
||||||
|
|
||||||
/* This same field is also used for CM108 GPIO PTT which will */
|
/* This same field is also used for CM108/CM119 GPIO PTT which will */
|
||||||
/* have a name like /dev/hidraw1. */
|
/* have a name like /dev/hidraw1 for Linux or */
|
||||||
|
/* \\?\hid#vid_0d8c&pid_0008&mi_03#8&39d3555&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} */
|
||||||
|
/* for Windows. Largest observed was 95 but add some extra to be safe. */
|
||||||
|
|
||||||
ptt_line_t ptt_line; /* Control line when using serial port. PTT_LINE_RTS, PTT_LINE_DTR. */
|
ptt_line_t ptt_line; /* Control line when using serial port. PTT_LINE_RTS, PTT_LINE_DTR. */
|
||||||
ptt_line_t ptt_line2; /* Optional second one: PTT_LINE_NONE when not used. */
|
ptt_line_t ptt_line2; /* Optional second one: PTT_LINE_NONE when not used. */
|
||||||
|
@ -256,7 +258,7 @@ struct audio_s {
|
||||||
int out_gpio_num; /* GPIO number. Originally this was only for PTT. */
|
int out_gpio_num; /* GPIO number. Originally this was only for PTT. */
|
||||||
/* It is now more general. */
|
/* It is now more general. */
|
||||||
/* octrl array is indexed by PTT, DCD, or CONnected indicator. */
|
/* octrl array is indexed by PTT, DCD, or CONnected indicator. */
|
||||||
/* For CM108, this should be in range of 1-8. */
|
/* For CM108/CM119, this should be in range of 1-8. */
|
||||||
|
|
||||||
#define MAX_GPIO_NAME_LEN 20 // 12 would cover any case I've seen so this should be safe
|
#define MAX_GPIO_NAME_LEN 20 // 12 would cover any case I've seen so this should be safe
|
||||||
|
|
||||||
|
|
319
src/cm108.c
319
src/cm108.c
|
@ -1,7 +1,7 @@
|
||||||
//
|
//
|
||||||
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2017,2019 John Langner, WB2OSZ
|
// Copyright (C) 2017,2019,2021 John Langner, WB2OSZ
|
||||||
//
|
//
|
||||||
// Parts of this were adapted from "hamlib" which contains the notice:
|
// Parts of this were adapted from "hamlib" which contains the notice:
|
||||||
//
|
//
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
* There is an incresing demand for using the GPIO pins of USB audio devices for PTT.
|
* There is an incresing demand for using the GPIO pins of USB audio devices for PTT.
|
||||||
* We have a few commercial products:
|
* We have a few commercial products:
|
||||||
*
|
*
|
||||||
|
* DINAH https://hamprojects.info/dinah/
|
||||||
* DMK URI http://www.dmkeng.com/URI_Order_Page.htm
|
* DMK URI http://www.dmkeng.com/URI_Order_Page.htm
|
||||||
* RB-USB RIM http://www.repeater-builder.com/products/usb-rim-lite.html
|
* RB-USB RIM http://www.repeater-builder.com/products/usb-rim-lite.html
|
||||||
* RA-35 http://www.masterscommunications.com/products/radio-adapter/ra35.html
|
* RA-35 http://www.masterscommunications.com/products/radio-adapter/ra35.html
|
||||||
|
@ -44,7 +45,8 @@
|
||||||
* http://www.repeater-builder.com/projects/fob/USB-Fob-Construction.pdf
|
* http://www.repeater-builder.com/projects/fob/USB-Fob-Construction.pdf
|
||||||
* https://irongarment.wordpress.com/2011/03/29/cm108-compatible-chips-with-gpio/
|
* https://irongarment.wordpress.com/2011/03/29/cm108-compatible-chips-with-gpio/
|
||||||
*
|
*
|
||||||
* Usually GPIO 3 is used because it is easier to tack solder a wire to a pin on the end.
|
* Homebrew plans all use GPIO 3 because it is easier to tack solder a wire to a pin on the end.
|
||||||
|
* All of the products, that I have seen, also use the same pin so this is the default.
|
||||||
*
|
*
|
||||||
* Soundmodem and hamlib paved the way but didn't get too far.
|
* Soundmodem and hamlib paved the way but didn't get too far.
|
||||||
* Dire Wolf 1.3 added HAMLIB support (Linux only) which theoretically allows this in a
|
* Dire Wolf 1.3 added HAMLIB support (Linux only) which theoretically allows this in a
|
||||||
|
@ -87,23 +89,28 @@
|
||||||
* Dire Wolf version 1.5 makes this much more flexible and easier to use by supporting multiple
|
* Dire Wolf version 1.5 makes this much more flexible and easier to use by supporting multiple
|
||||||
* sound devices and automatically determining the corresponding HID for the PTT signal.
|
* sound devices and automatically determining the corresponding HID for the PTT signal.
|
||||||
*
|
*
|
||||||
|
* In version 1.7, we add a half-backed solution for Windows. It's fine for situations
|
||||||
|
* with a single USB Audio Adapter, but does not automatically handle the multiple device case.
|
||||||
|
* Manual configuration needs to be used in this case.
|
||||||
|
*
|
||||||
*---------------------------------------------------------------*/
|
*---------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "direwolf.h"
|
||||||
|
|
||||||
#ifndef USE_CM108
|
#ifndef USE_CM108
|
||||||
|
|
||||||
#ifdef CM108_MAIN
|
#ifdef CM108_MAIN
|
||||||
|
|
||||||
#include "direwolf.h"
|
|
||||||
#include "textcolor.h"
|
#include "textcolor.h"
|
||||||
|
|
||||||
int main (void)
|
int main (void)
|
||||||
{
|
{
|
||||||
text_color_init (0); // Turn off text color.
|
text_color_init (0); // Turn off text color.
|
||||||
#if defined(__OpenBSD__) || defined(__FreeBSD__)
|
#if defined(__OpenBSD__) || defined(__FreeBSD__)
|
||||||
dw_printf ("CM108 PTT support is not available for BSD.\n");
|
dw_printf ("CM108 PTT support is not available for this operating system.\n");
|
||||||
#else
|
#else
|
||||||
dw_printf ("CM108 PTT support was disabled in Makefile.linux.\n");
|
dw_printf ("CM108 PTT support was excluded because /usr/include/libudev.h was missing.\n");
|
||||||
dw_printf ("It was excluded because /usr/include/libudev.h was missing.\n");
|
|
||||||
dw_printf ("Install it with \"sudo apt-get install libudev-dev\" or\n");
|
dw_printf ("Install it with \"sudo apt-get install libudev-dev\" or\n");
|
||||||
dw_printf ("\"sudo yum install libudev-devel\" then rebuild.\n");
|
dw_printf ("\"sudo yum install libudev-devel\" then rebuild.\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -112,11 +119,8 @@ int main (void)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else // USE_CM108 is defined.
|
#else // USE_CM108 is defined
|
||||||
|
|
||||||
#include "direwolf.h"
|
|
||||||
|
|
||||||
#include <libudev.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
@ -124,12 +128,18 @@ int main (void)
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
|
||||||
|
#if __WIN32__
|
||||||
|
#include <wchar.h>
|
||||||
|
#include "hidapi.h"
|
||||||
|
#else
|
||||||
|
#include <libudev.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/ioctl.h> // ioctl, _IOR
|
#include <sys/ioctl.h> // ioctl, _IOR
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <linux/hidraw.h> // for HIDIOCGRAWINFO
|
#include <linux/hidraw.h> // for HIDIOCGRAWINFO
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "textcolor.h"
|
#include "textcolor.h"
|
||||||
#include "cm108.h"
|
#include "cm108.h"
|
||||||
|
@ -216,6 +226,8 @@ static int cm108_write (char *name, int iomask, int iodata);
|
||||||
|
|
||||||
// Used to process regular expression matching results.
|
// Used to process regular expression matching results.
|
||||||
|
|
||||||
|
#ifndef __WIN32__
|
||||||
|
|
||||||
static void substr_se (char *dest, const char *src, int start, int endp1)
|
static void substr_se (char *dest, const char *src, int start, int endp1)
|
||||||
{
|
{
|
||||||
int len = endp1 - start;
|
int len = endp1 - start;
|
||||||
|
@ -229,6 +241,7 @@ static void substr_se (char *dest, const char *src, int start, int endp1)
|
||||||
|
|
||||||
} /* end substr_se */
|
} /* end substr_se */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Result of taking inventory of USB soundcards and USB HIDs.
|
* Result of taking inventory of USB soundcards and USB HIDs.
|
||||||
|
@ -237,15 +250,17 @@ static void substr_se (char *dest, const char *src, int start, int endp1)
|
||||||
struct thing_s {
|
struct thing_s {
|
||||||
int vid; // vendor id, displayed as four hexadecimal digits.
|
int vid; // vendor id, displayed as four hexadecimal digits.
|
||||||
int pid; // product id, displayed as four hexadecimal digits.
|
int pid; // product id, displayed as four hexadecimal digits.
|
||||||
char card_number[8]; // Number. e.g. 2 for plughw:2,0
|
char card_number[8]; // "Card" Number. e.g. 2 for plughw:2,0
|
||||||
char card_name[32]; // Name, assigned by system (e.g. Device_1) or by udev rule.
|
char card_name[32]; // Audio Card Name, assigned by system (e.g. Device_1) or by udev rule.
|
||||||
char product[32]; // product name (e.g. manufacturer, model)
|
char product[32]; // product name (e.g. manufacturer, model)
|
||||||
char devnode_sound[22]; // e.g. /dev/snd/pcmC0D0p
|
char devnode_sound[22]; // e.g. /dev/snd/pcmC0D0p
|
||||||
char plughw[72]; // Above in more familiar format e.g. plughw:0,0
|
char plughw[72]; // Above in more familiar format e.g. plughw:0,0
|
||||||
// Oversized to silence a compiler warning.
|
// Oversized to silence a compiler warning.
|
||||||
char plughw2[72]; // With name rather than number.
|
char plughw2[72]; // With name rather than number.
|
||||||
char devpath[128]; // Kernel dev path. Does not include /sys mount point.
|
char devpath[128]; // Kernel dev path. Does not include /sys mount point.
|
||||||
char devnode_hidraw[17]; // e.g. /dev/hidraw3
|
char devnode_hidraw[128]; // e.g. /dev/hidraw3 - for Linux - was length 17
|
||||||
|
// The Windows path for a HID looks like this, lengths up to 95 seen.
|
||||||
|
// \\?\hid#vid_0d8c&pid_000c&mi_03#8&164d11c9&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
|
||||||
char devnode_usb[25]; // e.g. /dev/bus/usb/001/012
|
char devnode_usb[25]; // e.g. /dev/bus/usb/001/012
|
||||||
// This is what we use to match up audio and HID.
|
// This is what we use to match up audio and HID.
|
||||||
};
|
};
|
||||||
|
@ -259,6 +274,13 @@ int cm108_inventory (struct thing_s *things, int max_things);
|
||||||
*
|
*
|
||||||
* Purpose: Useful utility to list USB audio and HID devices.
|
* Purpose: Useful utility to list USB audio and HID devices.
|
||||||
*
|
*
|
||||||
|
* Optional command line arguments:
|
||||||
|
*
|
||||||
|
* HID path
|
||||||
|
* GPIO number (default 3)
|
||||||
|
*
|
||||||
|
* When specified the pin will be set high and low until interrupted.
|
||||||
|
*
|
||||||
*------------------------------------------------------------------*/
|
*------------------------------------------------------------------*/
|
||||||
|
|
||||||
//#define EXTRA 1
|
//#define EXTRA 1
|
||||||
|
@ -267,18 +289,111 @@ int cm108_inventory (struct thing_s *things, int max_things);
|
||||||
|
|
||||||
#ifdef CM108_MAIN
|
#ifdef CM108_MAIN
|
||||||
|
|
||||||
int main (void)
|
static void usage(void)
|
||||||
|
{
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("\n");
|
||||||
|
dw_printf ("Usage: cm108 [ device-path [ gpio-num ] ]\n");
|
||||||
|
dw_printf ("\n");
|
||||||
|
dw_printf ("With no command line arguments, this will produce a list of\n");
|
||||||
|
#if __WIN32__
|
||||||
|
dw_printf ("Human Interface Devices (HID) and indicate which ones can be\n");
|
||||||
|
dw_printf ("used for GPIO PTT.\n");
|
||||||
|
#else
|
||||||
|
dw_printf ("Audio devices and Human Interface Devices (HID) and indicate\n");
|
||||||
|
dw_printf ("which ones can be used for GPIO PTT.\n");
|
||||||
|
#endif
|
||||||
|
dw_printf ("\n");
|
||||||
|
dw_printf ("Specify the HID device path to test the PTT fuction.\n");
|
||||||
|
dw_printf ("Its state should change once per second.\n");
|
||||||
|
#if __WIN32__
|
||||||
|
dw_printf ("You might need to quote the path depending on the command processor.\n");
|
||||||
|
#endif
|
||||||
|
dw_printf ("GPIO 3 is the default. A different number can be optionally specified.\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct thing_s things[MAXX_THINGS];
|
struct thing_s things[MAXX_THINGS];
|
||||||
int num_things;
|
int num_things;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
text_color_init (0); // Turn off text color.
|
text_color_init (0); // Turn off text color.
|
||||||
|
text_color_set(DW_COLOR_INFO);
|
||||||
|
|
||||||
|
if (argc >=2) {
|
||||||
|
char path[128];
|
||||||
|
strlcpy(path, argv[1], sizeof(path));
|
||||||
|
int gpio = 3;
|
||||||
|
if (argc >= 3) {
|
||||||
|
gpio = atoi(argv[2]);
|
||||||
|
}
|
||||||
|
if (gpio < 1 || gpio > 8) {
|
||||||
|
dw_printf ("GPIO number must be in range of 1 - 8.\n");
|
||||||
|
usage();
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
int state = 0;
|
||||||
|
while (1) {
|
||||||
|
dw_printf ("%d", state);
|
||||||
|
fflush (stdout);
|
||||||
|
int err = cm108_set_gpio_pin (path, gpio, state);
|
||||||
|
if (err != 0) {
|
||||||
|
dw_printf ("\nWRITE ERROR for USB Audio Adapter GPIO!\n");
|
||||||
|
usage();
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
SLEEP_SEC(1);
|
||||||
|
state = ! state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Take inventory of USB Audio adapters and other HID devices.
|
// Take inventory of USB Audio adapters and other HID devices.
|
||||||
|
|
||||||
num_things = cm108_inventory (things, MAXX_THINGS);
|
num_things = cm108_inventory (things, MAXX_THINGS);
|
||||||
|
|
||||||
|
#if __WIN32__
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
// Windows - Remove the sound related columns for now.
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
dw_printf (" VID PID %-*s %-*s"
|
||||||
|
"\n", (int)sizeof(things[0].product), "Product",
|
||||||
|
17, "HID [ptt]"
|
||||||
|
);
|
||||||
|
|
||||||
|
dw_printf (" --- --- %-*s %-*s"
|
||||||
|
|
||||||
|
"\n", (int)sizeof(things[0].product), "-------",
|
||||||
|
17, "---------"
|
||||||
|
);
|
||||||
|
for (i = 0; i < num_things; i++) {
|
||||||
|
|
||||||
|
dw_printf ("%2s %04x %04x %-*s %s"
|
||||||
|
|
||||||
|
"\n",
|
||||||
|
GOOD_DEVICE(things[i].vid,things[i].pid) ? "**" : " ",
|
||||||
|
things[i].vid, things[i].pid,
|
||||||
|
(int)sizeof(things[i].product), things[i].product,
|
||||||
|
things[i].devnode_hidraw
|
||||||
|
);
|
||||||
|
}
|
||||||
|
dw_printf ("\n");
|
||||||
|
dw_printf ("** = Can use Audio Adapter GPIO for PTT.\n");
|
||||||
|
dw_printf ("\n");
|
||||||
|
|
||||||
|
// T.B.D. - additional text ???
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/////////////////////////////////////////////
|
||||||
|
// Linux
|
||||||
|
/////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
dw_printf (" VID PID %-*s %-*s %-*s %-*s %-*s"
|
dw_printf (" VID PID %-*s %-*s %-*s %-*s %-*s"
|
||||||
#if EXTRA
|
#if EXTRA
|
||||||
" %-*s"
|
" %-*s"
|
||||||
|
@ -287,7 +402,7 @@ int main (void)
|
||||||
(int)sizeof(things[0].devnode_sound), "Sound",
|
(int)sizeof(things[0].devnode_sound), "Sound",
|
||||||
(int)sizeof(things[0].plughw)/5, "ADEVICE",
|
(int)sizeof(things[0].plughw)/5, "ADEVICE",
|
||||||
(int)sizeof(things[0].plughw2)/4, "ADEVICE",
|
(int)sizeof(things[0].plughw2)/4, "ADEVICE",
|
||||||
(int)sizeof(things[0].devnode_hidraw), "HID [ptt]"
|
17, "HID [ptt]"
|
||||||
#if EXTRA
|
#if EXTRA
|
||||||
, (int)sizeof(things[0].devnode_usb), "USB"
|
, (int)sizeof(things[0].devnode_usb), "USB"
|
||||||
#endif
|
#endif
|
||||||
|
@ -301,14 +416,14 @@ int main (void)
|
||||||
(int)sizeof(things[0].devnode_sound), "-----",
|
(int)sizeof(things[0].devnode_sound), "-----",
|
||||||
(int)sizeof(things[0].plughw)/5, "-------",
|
(int)sizeof(things[0].plughw)/5, "-------",
|
||||||
(int)sizeof(things[0].plughw2)/4, "-------",
|
(int)sizeof(things[0].plughw2)/4, "-------",
|
||||||
(int)sizeof(things[0].devnode_hidraw), "---------"
|
17, "---------"
|
||||||
#if EXTRA
|
#if EXTRA
|
||||||
, (int)sizeof(things[0].devnode_usb), "---"
|
, (int)sizeof(things[0].devnode_usb), "---"
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
for (i = 0; i < num_things; i++) {
|
for (i = 0; i < num_things; i++) {
|
||||||
|
|
||||||
dw_printf ("%2s %04x %04x %-*s %-*s %-*s %-*s %-*s"
|
dw_printf ("%2s %04x %04x %-*s %-*s %-*s %-*s %s"
|
||||||
#if EXTRA
|
#if EXTRA
|
||||||
" %-*s"
|
" %-*s"
|
||||||
#endif
|
#endif
|
||||||
|
@ -319,22 +434,22 @@ int main (void)
|
||||||
(int)sizeof(things[i].devnode_sound), things[i].devnode_sound,
|
(int)sizeof(things[i].devnode_sound), things[i].devnode_sound,
|
||||||
(int)sizeof(things[0].plughw)/5, things[i].plughw,
|
(int)sizeof(things[0].plughw)/5, things[i].plughw,
|
||||||
(int)sizeof(things[0].plughw2)/4, things[i].plughw2,
|
(int)sizeof(things[0].plughw2)/4, things[i].plughw2,
|
||||||
(int)sizeof(things[i].devnode_hidraw), things[i].devnode_hidraw
|
things[i].devnode_hidraw
|
||||||
#if EXTRA
|
#if EXTRA
|
||||||
, (int)sizeof(things[i].devnode_usb), things[i].devnode_usb
|
, (int)sizeof(things[i].devnode_usb), things[i].devnode_usb
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
//dw_printf (" %-*s\n", (int)sizeof(things[i].devpath), things[i].devpath);
|
//dw_printf (" %-*s\n", (int)sizeof(things[i].devpath), things[i].devpath);
|
||||||
}
|
}
|
||||||
|
dw_printf ("\n");
|
||||||
|
dw_printf ("** = Can use Audio Adapter GPIO for PTT.\n");
|
||||||
|
dw_printf ("\n");
|
||||||
|
|
||||||
static const char *suggested_names[] = {"Fred", "Wilma", "Pebbles", "Dino", "Barney", "Betty", "Bamm_Bamm" };
|
static const char *suggested_names[] = {"Fred", "Wilma", "Pebbles", "Dino", "Barney", "Betty", "Bamm_Bamm", "Chip", "Roxy" };
|
||||||
int iname = 0;
|
int iname = 0;
|
||||||
|
|
||||||
// From example in https://alsa.opensrc.org/Udev
|
// From example in https://alsa.opensrc.org/Udev
|
||||||
|
|
||||||
dw_printf ("\n");
|
|
||||||
dw_printf ("** = Can use Audio Adapter GPIO for PTT.\n");
|
|
||||||
dw_printf ("\n");
|
|
||||||
dw_printf ("Notice that each USB Audio adapter is assigned a number and a name. These are not predictable so you could\n");
|
dw_printf ("Notice that each USB Audio adapter is assigned a number and a name. These are not predictable so you could\n");
|
||||||
dw_printf ("end up using the wrong adapter after adding or removing other USB devices or after rebooting. You can assign a\n");
|
dw_printf ("end up using the wrong adapter after adding or removing other USB devices or after rebooting. You can assign a\n");
|
||||||
dw_printf ("name to each USB adapter so you can refer to the same one each time. This can be based on any characteristics\n");
|
dw_printf ("name to each USB adapter so you can refer to the same one each time. This can be based on any characteristics\n");
|
||||||
|
@ -372,7 +487,7 @@ int main (void)
|
||||||
}
|
}
|
||||||
dw_printf ("LABEL=\"my_usb_audio_end\"\n");
|
dw_printf ("LABEL=\"my_usb_audio_end\"\n");
|
||||||
dw_printf ("\n");
|
dw_printf ("\n");
|
||||||
|
#endif
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,6 +515,47 @@ int main (void)
|
||||||
|
|
||||||
int cm108_inventory (struct thing_s *things, int max_things)
|
int cm108_inventory (struct thing_s *things, int max_things)
|
||||||
{
|
{
|
||||||
|
int num_things = 0;
|
||||||
|
memset (things, 0, sizeof(struct thing_s) * max_things);
|
||||||
|
|
||||||
|
#if __WIN32__
|
||||||
|
|
||||||
|
struct hid_device_info *devs, *cur_dev;
|
||||||
|
|
||||||
|
if (hid_init()) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf("cm108_inventory: hid_init() failed.\n");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
devs = hid_enumerate(0x0, 0x0);
|
||||||
|
cur_dev = devs;
|
||||||
|
while (cur_dev) {
|
||||||
|
#if 0
|
||||||
|
printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number);
|
||||||
|
printf("\n");
|
||||||
|
printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string);
|
||||||
|
printf(" Product: %ls\n", cur_dev->product_string);
|
||||||
|
printf(" Release: %hx\n", cur_dev->release_number);
|
||||||
|
printf(" Interface: %d\n", cur_dev->interface_number);
|
||||||
|
printf(" Usage (page): 0x%hx (0x%hx)\n", cur_dev->usage, cur_dev->usage_page);
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
if (num_things < max_things && cur_dev->vendor_id != 0x051d) { // FIXME - remove exception
|
||||||
|
things[num_things].vid = cur_dev->vendor_id;
|
||||||
|
things[num_things].pid = cur_dev->product_id;
|
||||||
|
wcstombs (things[num_things].product, cur_dev->product_string, sizeof(things[num_things].product));
|
||||||
|
things[num_things].product[sizeof(things[num_things].product) - 1] = '\0';
|
||||||
|
strlcpy (things[num_things].devnode_hidraw, cur_dev->path, sizeof(things[num_things].devnode_hidraw));
|
||||||
|
|
||||||
|
num_things++;
|
||||||
|
}
|
||||||
|
cur_dev = cur_dev->next;
|
||||||
|
}
|
||||||
|
hid_free_enumeration(devs);
|
||||||
|
|
||||||
|
#else // Linux, with udev
|
||||||
|
|
||||||
struct udev *udev;
|
struct udev *udev;
|
||||||
struct udev_enumerate *enumerate;
|
struct udev_enumerate *enumerate;
|
||||||
struct udev_list_entry *devices, *dev_list_entry;
|
struct udev_list_entry *devices, *dev_list_entry;
|
||||||
|
@ -410,8 +566,6 @@ int cm108_inventory (struct thing_s *things, int max_things)
|
||||||
char const *pattrs_number = NULL;
|
char const *pattrs_number = NULL;
|
||||||
char card_devpath[128] = "";
|
char card_devpath[128] = "";
|
||||||
|
|
||||||
int num_things = 0;
|
|
||||||
memset (things, 0, sizeof(struct thing_s) * max_things);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First get a list of the USB audio devices.
|
* First get a list of the USB audio devices.
|
||||||
|
@ -561,6 +715,8 @@ int cm108_inventory (struct thing_s *things, int max_things)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // end Linux
|
||||||
|
|
||||||
return (num_things);
|
return (num_things);
|
||||||
|
|
||||||
} /* end cm108_inventory */
|
} /* end cm108_inventory */
|
||||||
|
@ -594,13 +750,48 @@ void cm108_find_ptt (char *output_audio_device, char *ptt_device, int ptt_devic
|
||||||
{
|
{
|
||||||
struct thing_s things[MAXX_THINGS];
|
struct thing_s things[MAXX_THINGS];
|
||||||
int num_things;
|
int num_things;
|
||||||
int i;
|
|
||||||
|
|
||||||
//dw_printf ("DEBUG: cm108_find_ptt('%s')\n", output_audio_device);
|
//dw_printf ("DEBUG: cm108_find_ptt('%s')\n", output_audio_device);
|
||||||
|
|
||||||
strlcpy (ptt_device, "", ptt_device_size);
|
strlcpy (ptt_device, "", ptt_device_size);
|
||||||
|
|
||||||
|
// Possible improvement: Skip if inventory already taken.
|
||||||
num_things = cm108_inventory (things, MAXX_THINGS);
|
num_things = cm108_inventory (things, MAXX_THINGS);
|
||||||
|
|
||||||
|
#if __WIN32__
|
||||||
|
// FIXME - This is just a half baked implementation.
|
||||||
|
// I have not been able to figure out how to find the connection
|
||||||
|
// between the audio device and HID in the same package.
|
||||||
|
// This is fine for a single USB Audio Adapter, good enough for most people.
|
||||||
|
// Those with multiple devices will need to manually configure PTT device path.
|
||||||
|
|
||||||
|
// Count how many good devices we have.
|
||||||
|
|
||||||
|
int good_devices = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < num_things; i++) {
|
||||||
|
if (GOOD_DEVICE(things[i].vid,things[i].pid) ) {
|
||||||
|
good_devices++;
|
||||||
|
//dw_printf ("DEBUG: success! returning '%s'\n", things[i].devnode_hidraw);
|
||||||
|
strlcpy (ptt_device, things[i].devnode_hidraw, ptt_device_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (good_devices == 0) return; // None found - caller will print a message.
|
||||||
|
|
||||||
|
if (good_devices == 1) return; // Success - Only one candidate device.
|
||||||
|
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("There are multiple USB Audio Devices with GPIO capability.\n");
|
||||||
|
dw_printf ("Explicitly specify one of them for more predictable results:\n");
|
||||||
|
for (int i = 0; i < num_things; i++) {
|
||||||
|
if (GOOD_DEVICE(things[i].vid,things[i].pid) ) {
|
||||||
|
dw_printf (" \"%s\"\n", things[i].devnode_hidraw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dw_printf ("Run the \"cm108\" utility for more details.\n");
|
||||||
|
text_color_set(DW_COLOR_INFO);
|
||||||
|
#else
|
||||||
regex_t sound_re;
|
regex_t sound_re;
|
||||||
char emsg[100];
|
char emsg[100];
|
||||||
int e = regcomp (&sound_re, ".+:(CARD=)?([A-Za-z0-9_]+)(,.*)?", REG_EXTENDED);
|
int e = regcomp (&sound_re, ".+:(CARD=)?([A-Za-z0-9_]+)(,.*)?", REG_EXTENDED);
|
||||||
|
@ -625,7 +816,7 @@ void cm108_find_ptt (char *output_audio_device, char *ptt_device, int ptt_devic
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_things; i++) {
|
for (int i = 0; i < num_things; i++) {
|
||||||
//dw_printf ("DEBUG: i=%d, card_name='%s', card_number='%s'\n", i, things[i].card_name, things[i].card_number);
|
//dw_printf ("DEBUG: i=%d, card_name='%s', card_number='%s'\n", i, things[i].card_name, things[i].card_number);
|
||||||
if (strcmp(num_or_name,things[i].card_name) == 0 || strcmp(num_or_name,things[i].card_number) == 0) {
|
if (strcmp(num_or_name,things[i].card_name) == 0 || strcmp(num_or_name,things[i].card_number) == 0) {
|
||||||
//dw_printf ("DEBUG: success! returning '%s'\n", things[i].devnode_hidraw);
|
//dw_printf ("DEBUG: success! returning '%s'\n", things[i].devnode_hidraw);
|
||||||
|
@ -638,6 +829,7 @@ void cm108_find_ptt (char *output_audio_device, char *ptt_device, int ptt_devic
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} /* end cm108_find_ptt */
|
} /* end cm108_find_ptt */
|
||||||
|
|
||||||
|
@ -649,7 +841,8 @@ void cm108_find_ptt (char *output_audio_device, char *ptt_device, int ptt_devic
|
||||||
*
|
*
|
||||||
* Purpose: Set one GPIO pin of the CM108 or similar.
|
* Purpose: Set one GPIO pin of the CM108 or similar.
|
||||||
*
|
*
|
||||||
* Inputs: name - Name of device such as /dev/hidraw2.
|
* Inputs: name - Name of device such as /dev/hidraw2 or
|
||||||
|
* \\?\hid#vid_0d8c&pid_0008&mi_03#8&39d3555&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
|
||||||
*
|
*
|
||||||
* num - GPIO number, range 1 thru 8.
|
* num - GPIO number, range 1 thru 8.
|
||||||
*
|
*
|
||||||
|
@ -669,44 +862,6 @@ void cm108_find_ptt (char *output_audio_device, char *ptt_device, int ptt_devic
|
||||||
*
|
*
|
||||||
*------------------------------------------------------------------*/
|
*------------------------------------------------------------------*/
|
||||||
|
|
||||||
#if TESTCM
|
|
||||||
|
|
||||||
// Switch pin between input, output-low, and output-high.
|
|
||||||
|
|
||||||
// gcc -DTESTCM=1 -DUSE_CM108 cm108.c textcolor.c misc.a -ludev
|
|
||||||
|
|
||||||
int main (int argc, char *argv[])
|
|
||||||
{
|
|
||||||
#define MODE_IN 0
|
|
||||||
#define MODE_OUT 0x04 // GPIO 3 = bit 2
|
|
||||||
#define OUT_LOW 0
|
|
||||||
#define OUT_HIGH 0x04
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
text_color_set(DW_COLOR_ERROR);
|
|
||||||
dw_printf ("Specify HID path on command line.\n");
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
text_color_set(DW_COLOR_INFO);
|
|
||||||
dw_printf ("Input-L\n");
|
|
||||||
cm108_write (argv[1], MODE_IN, OUT_LOW);
|
|
||||||
sleep(5);
|
|
||||||
dw_printf ("Input-H\n");
|
|
||||||
cm108_write (argv[1], MODE_IN, OUT_HIGH);
|
|
||||||
sleep(5);
|
|
||||||
dw_printf ("Out-LOW\n");
|
|
||||||
cm108_write (argv[1], MODE_OUT, OUT_LOW);
|
|
||||||
sleep(5);
|
|
||||||
dw_printf ("out-HIGH\n");
|
|
||||||
cm108_write (argv[1], MODE_OUT, OUT_HIGH);
|
|
||||||
sleep(5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
int cm108_set_gpio_pin (char *name, int num, int state)
|
int cm108_set_gpio_pin (char *name, int num, int state)
|
||||||
{
|
{
|
||||||
|
@ -758,6 +913,36 @@ int cm108_set_gpio_pin (char *name, int num, int state)
|
||||||
|
|
||||||
static int cm108_write (char *name, int iomask, int iodata)
|
static int cm108_write (char *name, int iomask, int iodata)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if __WIN32__
|
||||||
|
|
||||||
|
//text_color_set(DW_COLOR_DEBUG);
|
||||||
|
//dw_printf ("TEMP DEBUG cm108_write: %s %d %d\n", name, iomask, iodata);
|
||||||
|
|
||||||
|
hid_device *handle = hid_open_path(name);
|
||||||
|
if (handle == NULL) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Could not open %s for write\n", name);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char io[5];
|
||||||
|
io[0] = 0;
|
||||||
|
io[1] = 0;
|
||||||
|
io[2] = iodata;
|
||||||
|
io[3] = iomask;
|
||||||
|
io[4] = 0;
|
||||||
|
|
||||||
|
int res = hid_write(handle, io, sizeof(io));
|
||||||
|
if (res < 0) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Write failed to %s\n", name);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
hid_close(handle);
|
||||||
|
|
||||||
|
#else
|
||||||
int fd;
|
int fd;
|
||||||
struct hidraw_devinfo info;
|
struct hidraw_devinfo info;
|
||||||
char io[5];
|
char io[5];
|
||||||
|
@ -862,6 +1047,8 @@ static int cm108_write (char *name, int iomask, int iodata)
|
||||||
}
|
}
|
||||||
|
|
||||||
close (fd);
|
close (fd);
|
||||||
|
|
||||||
|
#endif
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
} /* end cm108_write */
|
} /* end cm108_write */
|
||||||
|
|
21
src/config.c
21
src/config.c
|
@ -63,7 +63,7 @@
|
||||||
#include "tt_text.h"
|
#include "tt_text.h"
|
||||||
#include "ax25_link.h"
|
#include "ax25_link.h"
|
||||||
|
|
||||||
#ifdef USE_CM108 // Linux only
|
#if USE_CM108 // Current Linux or Windows only
|
||||||
#include "cm108.h"
|
#include "cm108.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1854,9 +1854,9 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
}
|
}
|
||||||
else if (strcasecmp(t, "CM108") == 0) {
|
else if (strcasecmp(t, "CM108") == 0) {
|
||||||
|
|
||||||
/* CM108 - GPIO of USB sound card. case, Linux only. */
|
/* CM108 - GPIO of USB sound card. case, Linux and Windows only. */
|
||||||
|
|
||||||
#ifdef USE_CM108
|
#if USE_CM108
|
||||||
|
|
||||||
if (ot != OCTYPE_PTT) {
|
if (ot != OCTYPE_PTT) {
|
||||||
// Future project: Allow DCD and CON via the same device.
|
// Future project: Allow DCD and CON via the same device.
|
||||||
|
@ -1912,22 +1912,23 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file line %d: Could not determine USB Audio GPIO PTT device for audio output %s.\n", line,
|
dw_printf ("Config file line %d: Could not determine USB Audio GPIO PTT device for audio output %s.\n", line,
|
||||||
p_audio_config->adev[ACHAN2ADEV(channel)].adevice_out);
|
p_audio_config->adev[ACHAN2ADEV(channel)].adevice_out);
|
||||||
|
#if __WIN32__
|
||||||
|
dw_printf ("You must explicitly mention a HID path.\n");
|
||||||
|
#else
|
||||||
dw_printf ("You must explicitly mention a device name such as /dev/hidraw1.\n");
|
dw_printf ("You must explicitly mention a device name such as /dev/hidraw1.\n");
|
||||||
dw_printf ("See User Guide for details.\n");
|
#endif
|
||||||
|
dw_printf ("Run \"cm108\" utility to get a list.\n");
|
||||||
|
dw_printf ("See Interface Guide for details.\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
p_audio_config->achan[channel].octrl[ot].ptt_method = PTT_METHOD_CM108;
|
p_audio_config->achan[channel].octrl[ot].ptt_method = PTT_METHOD_CM108;
|
||||||
|
|
||||||
#else
|
|
||||||
#if __WIN32__
|
|
||||||
text_color_set(DW_COLOR_ERROR);
|
|
||||||
dw_printf ("Config file line %d: CM108 USB Audio GPIO PTT is not available for Windows.\n", line);
|
|
||||||
#else
|
#else
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Config file line %d: %s with CM108 is only available when USB Audio GPIO support is enabled.\n", line, otname);
|
dw_printf ("Config file line %d: %s with CM108 is only available when USB Audio GPIO support is enabled.\n", line, otname);
|
||||||
dw_printf ("You must rebuild direwolf with CM108 Audio Adapter GPIO PTT support.\n");
|
dw_printf ("You must rebuild direwolf with CM108 Audio Adapter GPIO PTT support.\n");
|
||||||
dw_printf ("See User Guide for details.\n");
|
dw_printf ("See Interface Guide for details.\n");
|
||||||
#endif
|
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//
|
//
|
||||||
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, 2020 John Langner, WB2OSZ
|
// Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, 2020, 2021 John Langner, WB2OSZ
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
@ -1207,6 +1207,11 @@ void app_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alev
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Audio input level is too high. Reduce so most stations are around 50.\n");
|
dw_printf ("Audio input level is too high. Reduce so most stations are around 50.\n");
|
||||||
}
|
}
|
||||||
|
else if (alevel.rec < 5) {
|
||||||
|
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Audio input level is too low. Increase so most stations are around 50.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Display non-APRS packets in a different color.
|
// Display non-APRS packets in a different color.
|
||||||
|
|
|
@ -37,6 +37,12 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Version 1.7 supports CM108/CM119 GPIO PTT for Windows.
|
||||||
|
// Define it here so we don't need to have separate Windows
|
||||||
|
// check in all the places that test this.
|
||||||
|
#if __WIN32__
|
||||||
|
#define USE_CM108 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Previously, we could handle only a single audio device.
|
* Previously, we could handle only a single audio device.
|
||||||
|
|
Loading…
Reference in New Issue