From bc5cc8234dfefbe62f7360a6aca3e11033835d5e Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 5 Oct 2025 16:37:12 -0700 Subject: [PATCH 1/5] xiegu-x6100 Initial PnP support for the Xiegu X6100. This radio is very unstable when it comes to CAT control. --- .../etc/udev/rules.d/89-et-xiegu-x6100.rules | 26 +++++++++++++++++++ overlay/opt/emcomm-tools/bin/et-audio | 14 +++++++++- .../conf/radios.d/xiegu-x6100.json | 18 +++++++++++++ overlay/opt/emcomm-tools/sbin/udev-tester.sh | 20 +++++++++++++- 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 overlay/etc/udev/rules.d/89-et-xiegu-x6100.rules create mode 100644 overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json diff --git a/overlay/etc/udev/rules.d/89-et-xiegu-x6100.rules b/overlay/etc/udev/rules.d/89-et-xiegu-x6100.rules new file mode 100644 index 0000000..319f137 --- /dev/null +++ b/overlay/etc/udev/rules.d/89-et-xiegu-x6100.rules @@ -0,0 +1,26 @@ +# Author : Gaston Gonzalez +# Date : 5 October 2025 +# Purpose : udev rules for the Xiegu X6100 +# +# Preconditions: +# 1. Xiegu X6100 connected via USB cable +# +# Postconditions: +# 1. /dev/et-cat created +# 2. rigctld is started +# 3. /dev/et-audio created + +SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d2", ENV{ET_DEVICE}=="", \ + PROGRAM="/opt/emcomm-tools/sbin/udev-tester.sh xiegu-x6100", \ + ACTION=="add", \ + ENV{ET_DEVICE}="X6100", ENV{ET_SUBDEVICE}="CAT", GROUP="dialout", MODE="0660", SYMLINK+="et-cat", \ + RUN+="/usr/bin/systemctl start rigctld" + +# This soundcard will collide with the DigiRig, so we need to ensure that this +# rule is ordered before it and that we guard the match with the PROGRAM check. +SUBSYSTEM=="sound", ATTRS{idVendor}=="0d8c", ATTRS{idProduct}=="0012", \ + PROGRAM="/opt/emcomm-tools/sbin/udev-tester.sh xiegu-x6100", \ + ACTION=="add", \ + ENV{ET_DEVICE}="X6100", \ + ATTR{id}="ET_AUDIO", \ + ENV{ET_SUBDEVICE}="AUDIO", GROUP="audio", MODE="0660", SYMLINK+="et-audio" diff --git a/overlay/opt/emcomm-tools/bin/et-audio b/overlay/opt/emcomm-tools/bin/et-audio index b7a4e05..4aa9062 100755 --- a/overlay/opt/emcomm-tools/bin/et-audio +++ b/overlay/opt/emcomm-tools/bin/et-audio @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 31 October 2024 -# Updated : 26 September 2025 +# Updated : 5 October 2025 # Purpose : Configures ET audio device with sane defaults # # Preconditions @@ -112,6 +112,18 @@ update-config () { et-log "Applied amixer settings for ${ET_DEVICE_NAME}" ;; + "X6100") + # Unmute Speaker a set volume. Adjust if remote station can't decode you. + amixer -q -c ${AUDIO_CARD} sset Speaker Playback Switch 42% unmute + # Unmute Mic + amixer -q -c ${AUDIO_CARD} sset Mic Playback Switch 52% unmute + # Set "L/R Capture" to 19. Adjust if you can't decode received audio. + amixer -q -c ${AUDIO_CARD} sset Mic Capture Switch 31% unmute + # Disable Auto Gain Control + amixer -q -c ${AUDIO_CARD} sset 'Auto Gain Control' mute + + et-log "Applied amixer settings for ${ET_DEVICE_NAME}" + ;; *) et-log "No ALSA configuration specified for this ET_DEVICE." ;; diff --git a/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json b/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json new file mode 100644 index 0000000..a90ee06 --- /dev/null +++ b/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json @@ -0,0 +1,18 @@ +{ + "id": "xiegu-x6100", + "vendor": "Xiegu", + "model": "X6100", + "rigctrl": { + "id": "3087", + "baud": "19200", + "conf": "data_bits=8,stop_bits=1", + "ptt": "RIG" + }, + "notes": [ + "Plug USB-C cable into the DEV port", + "Set mode to U-DIG" + ], + "fieldNotes": [ + "Tested with firmware version: 1.1.6 (2023/03/07)" + ] +} diff --git a/overlay/opt/emcomm-tools/sbin/udev-tester.sh b/overlay/opt/emcomm-tools/sbin/udev-tester.sh index 02fb7f9..5959aab 100755 --- a/overlay/opt/emcomm-tools/sbin/udev-tester.sh +++ b/overlay/opt/emcomm-tools/sbin/udev-tester.sh @@ -1,7 +1,7 @@ #!/bin/bash # Author : Gaston Gonzalez # Date : 11 October 2024 -# Updated : 13 September 2025 +# Updated : 5 October 2025 # Purpose : Perform tests that can be used by the udev subsystem to aid # in rule development. This is intended to by used with the PROGRAM # directive inside of a udev rule. @@ -13,6 +13,20 @@ ET_HOME=/opt/emcomm-tools ACTIVE_RADIO="${ET_HOME}/conf/radios.d/active-radio.json" +# Exit with a 0 exit status if, and only if, the currently selected radio is +# a Xiegu X6100 +test_xiegu_x6100() { + if [[ -L "${ET_HOME}/conf/radios.d/active-radio.json" ]]; then + ID=$(cat "${ET_HOME}/conf/radios.d/active-radio.json" | jq -r .id) + + if [[ "$ID" == "xiegu-x6100" ]]; then + exit 0 + fi + fi + + exit 1 +} + # Exit with a 0 exit status if, and only if, the currently selected radio is # a Yaesu FTX-1. test_yaesu_ftx1() { @@ -101,6 +115,9 @@ if [ $# -ne 1 ]; then fi case $1 in + xiegu-x6100) + test_xiegu_x6100 + ;; yaesu-ftx1) test_yaesu_ftx1 ;; @@ -112,6 +129,7 @@ case $1 in ;; digirig-mobile) test_digirig_mobile + ;; esac exit 1 From 7f862e306ce9aa4082ad30c4e5cb79d071b9d77a Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 6 Oct 2025 15:17:57 -0700 Subject: [PATCH 2/5] xiegu-x6100 Upgraded hamlib to the latest version (4.6.5) and upgraded the X6100 factory firmware to latest version (1.1.9 APP / 1.1.8 BASE) to resolve JS8Call timeout issue. It did not resolve the problem, but I am keeping the upgraded Hamlib version --- .../conf/radios.d/xiegu-x6100.json | 11 ++-- scripts/install-hamlib.sh | 52 ++++++++++--------- tests/test-hamlib.sh | 8 +++ 3 files changed, 42 insertions(+), 29 deletions(-) create mode 100755 tests/test-hamlib.sh diff --git a/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json b/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json index a90ee06..498ece8 100644 --- a/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json +++ b/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json @@ -5,14 +5,17 @@ "rigctrl": { "id": "3087", "baud": "19200", - "conf": "data_bits=8,stop_bits=1", - "ptt": "RIG" + "ptt": "RIG", + "conf": "stop_bits=1" }, "notes": [ + "Turn on radio", "Plug USB-C cable into the DEV port", - "Set mode to U-DIG" + "Set mode to U-DIG", + "Set filter to FILTER1", + "Set AGC to AGC--" ], "fieldNotes": [ - "Tested with firmware version: 1.1.6 (2023/03/07)" + "Tested with firmware version: 1.1.9 APP / 1.1.8 BASE" ] } diff --git a/scripts/install-hamlib.sh b/scripts/install-hamlib.sh index 423ba7d..174745f 100755 --- a/scripts/install-hamlib.sh +++ b/scripts/install-hamlib.sh @@ -2,46 +2,48 @@ # # Author : Gaston Gonzalez # Date : 25 November 2022 -# Updated : 19 May 2024 -# Purpose : Install hamlib for rig control +# Updated : 6 October 2025 +# Purpose : Install hamlib for rig control (rigctld) set -e +trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG +trap 'et-log "\"${last_command}\" command failed with exit code $?."' ERR -ET_DIST_DIR=/opt/dist -ET_SRC_DIR=/opt/src +. ./env.sh +. ../overlay/opt/emcomm-tools/bin/et-common -VERSION=4.5 -APP_AND_VERSION=hamlib-$VERSION -TARBALL=$APP_AND_VERSION.tar.gz -URL=https://github.com/Hamlib/Hamlib/releases/download/$VERSION/$TARBALL -INSTALL_DIR=/opt/$APP_AND_VERSION -LINK_PATH=/opt/hamlib +APP="hamlib" +VERSION=4.6.5 +APP_AND_VERSION="${APP}-${VERSION}" +INSTALL_DIR="/opt/${APP_AND_VERSION}" +LINK_PATH="/opt/${APP}" +TARBALL=${APP_AND_VERSION}.tar.gz +URL=https://github.com/Hamlib/Hamlib/releases/download/${VERSION}/${TARBALL} -if [ ! -e $ET_DIST_DIR/$TARBALL ]; then +if [[ ! -e $ET_DIST_DIR/$TARBALL ]]; then et-log "Downloading hamlib: $URL " - curl -s -L -O --fail $URL + download_with_retries ${URL} ${TARBALL} - [ ! -e $ET_DIST_DIR ] && mkdir -v $ET_DIST_DIR - [ ! -e $ET_SRC_DIR ] && mkdir -v $ET_SRC_DIR + [ ! -e ${ET_DIST_DIR} ] && mkdir -v ${ET_DIST_DIR} + [ ! -e ${ET_SRC_DIR} ] && mkdir -v ${ET_SRC_DIR} - mv $TARBALL $ET_DIST_DIR + mv ${TARBALL} ${ET_DIST_DIR} fi CWD_DIR=`pwd` -cd $ET_SRC_DIR -et-log "Unpacking $ET_DIST_DIR/$TARBALL" -tar -xzf $ET_DIST_DIR/$TARBALL && cd $APP_AND_VERSION +cd ${ET_SRC_DIR} +et-log "Unpacking ${ET_DIST_DIR}/${TARBALL}" +tar -xzf ${ET_DIST_DIR}/${TARBALL} && cd ${APP_AND_VERSION} -[ ! -e $INSTALL_DIR ] && mkdir -v $INSTALL_DIR +[ ! -e ${INSTALL_DIR} ] && mkdir -v ${INSTALL_DIR} -et-log "Building Hamlib $VERSION" -./configure --prefix=$INSTALL_DIR +et-log "Building Hamlib ${VERSION}" +./configure --prefix=${INSTALL_DIR} make && make check && make install -[ -e $LINK_PATH ] && rm $LINK_PATH -ln -v -s $INSTALL_DIR $LINK_PATH +[ -e ${LINK_PATH} ] && rm ${LINK_PATH} +ln -v -s ${INSTALL_DIR} ${LINK_PATH} -stow -v -d /opt hamlib -t /usr/local +stow -v -d /opt ${APP} -t /usr/local cd $CWD_DIR - diff --git a/tests/test-hamlib.sh b/tests/test-hamlib.sh new file mode 100755 index 0000000..acff967 --- /dev/null +++ b/tests/test-hamlib.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# Author : Gaston Gonzalez +# Date : 8 November 2024 +# Updated : 6 October 2025 +# Purpose : Test hamlib installation + +OUT=$(which rigctld) +exit $? From f255f8ecd8b9c326c3e9e648bdc951857ad425b9 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 7 Oct 2025 05:29:09 -0700 Subject: [PATCH 3/5] xiegu-x6100 - Found a workaround to handle the slow CAT control initialize. We need to prime the connection to rigctld by requesting a command such as asking for the frequency. This workaround will be refactored generically. --- overlay/opt/emcomm-tools/bin/et-js8call | 13 ++++++++++++- .../opt/emcomm-tools/conf/radios.d/xiegu-x6100.json | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-js8call b/overlay/opt/emcomm-tools/bin/et-js8call index 9f5783b..a031c1a 100755 --- a/overlay/opt/emcomm-tools/bin/et-js8call +++ b/overlay/opt/emcomm-tools/bin/et-js8call @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 24 October 2024 -# Updated : 20 November 2024 +# Updated : 6 October 2025 # Purpose : Wrapper script for starting JS8Call with PnP support # # Preconditions @@ -32,6 +32,17 @@ notify_user() { } start() { + + # Handle a special case with Xiegu X6100 to pre-initialize the hamlib + # client connection. It takes almost 6 seconds for rig control clients + # (including the rigctl client) to connect the first time with the X6100. + ACTIVE_RADIO=$(et-system-info active-radio) + if [[ "${ACTIVE_RADIO}" = "X6100" ]]; then + et-log "Priming rig control client connection for ${ACTIVE_RADIO}" + notify_user "JS8Call will be slow to start due to rig priming" + rigctl -m 2 f > /dev/null + fi + /opt/emcomm-tools/bin/et-kill-all && update-config && /usr/bin/js8call & if [ ! -e /dev/et-gps ]; then diff --git a/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json b/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json index 498ece8..9371fbe 100644 --- a/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json +++ b/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json @@ -6,7 +6,7 @@ "id": "3087", "baud": "19200", "ptt": "RIG", - "conf": "stop_bits=1" + "conf": "timeout=1000,retry=1,timeout_retry=1" }, "notes": [ "Turn on radio", From a233ff2e87a761cfc6e03dc82cb31115fdea976a Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 7 Oct 2025 06:04:06 -0700 Subject: [PATCH 4/5] xiegu-x6100 Refactored rigctld priming into et-common function --- overlay/opt/emcomm-tools/bin/et-common | 24 +++++++++++++++++++++++- overlay/opt/emcomm-tools/bin/et-js8call | 16 +++++----------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-common b/overlay/opt/emcomm-tools/bin/et-common index bc781dd..f4315a4 100755 --- a/overlay/opt/emcomm-tools/bin/et-common +++ b/overlay/opt/emcomm-tools/bin/et-common @@ -1,7 +1,7 @@ #!/bin/bash # Author : Gaston Gonzalez # Date : 1 February 2025 -# Updated : 20 August 2025 +# Updated : 7 October 2025 # Purpose : Common environment variables and functions # Standardized device paths for supported hardware @@ -141,3 +141,25 @@ download_with_retries() { echo "Download failed after $max_retries attempts." return 1 } + +# prime_rigctld_conn makes a connection to the rig control daemon (rigctld) +# and requests the radio's frequency in an effort to initialize CAT control. +# +# For example, it takes almost 6 seconds for rig control clients (including +# the rigctl client) to connect the first time with the Xiegu X6100 to rigctld. +# JS8Call will fail to handle this properly if this "priming" task is not +# executed before it starts up.. +prime_rigctld_conn() { + + ACTIVE_RADIO=$(et-system-info active-radio) + case "${ACTIVE_RADIO}" in + "X6100") + et-log "Priming rig control client connection for ${ACTIVE_RADIO}" + notify_user "Please be patient. Priming connection to radio." + rigctl -m 2 f > /dev/null + ;; + *) + et-log "No rigctld priming needed for ${ACTIVE_RADIO}" + ;; + esac +} diff --git a/overlay/opt/emcomm-tools/bin/et-js8call b/overlay/opt/emcomm-tools/bin/et-js8call index a031c1a..c746c8b 100755 --- a/overlay/opt/emcomm-tools/bin/et-js8call +++ b/overlay/opt/emcomm-tools/bin/et-js8call @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 24 October 2024 -# Updated : 6 October 2025 +# Updated : 7 October 2025 # Purpose : Wrapper script for starting JS8Call with PnP support # # Preconditions @@ -12,6 +12,7 @@ # 1. Stop all running EmComm Tools modes # 2. JS8Call audio settings updated # 3. JS8Call started +. /opt/emcomm-tools/bin/et-common usage() { echo "usage: $(basename $0) " @@ -33,15 +34,8 @@ notify_user() { start() { - # Handle a special case with Xiegu X6100 to pre-initialize the hamlib - # client connection. It takes almost 6 seconds for rig control clients - # (including the rigctl client) to connect the first time with the X6100. - ACTIVE_RADIO=$(et-system-info active-radio) - if [[ "${ACTIVE_RADIO}" = "X6100" ]]; then - et-log "Priming rig control client connection for ${ACTIVE_RADIO}" - notify_user "JS8Call will be slow to start due to rig priming" - rigctl -m 2 f > /dev/null - fi + # Ensure that we have a pre-initialized CAT control connection for select radios + prime_rigctld_conn /opt/emcomm-tools/bin/et-kill-all && update-config && /usr/bin/js8call & @@ -53,7 +47,7 @@ start() { } -update-config () { +update-config() { JS8CALL_CONF_FILE="${HOME}/.config/JS8Call.ini" From b70f3c05645d97adca207adf7f398302a2b4018e Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 7 Oct 2025 06:23:12 -0700 Subject: [PATCH 5/5] xiegu-x6100 - Refactored rig control priming approach to encapsulate it behind a radio configuration property called: primeRig. --- overlay/opt/emcomm-tools/bin/et-common | 21 +++++++++++-------- .../conf/radios.d/xiegu-x6100.json | 3 ++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-common b/overlay/opt/emcomm-tools/bin/et-common index f4315a4..b3e94aa 100755 --- a/overlay/opt/emcomm-tools/bin/et-common +++ b/overlay/opt/emcomm-tools/bin/et-common @@ -10,6 +10,10 @@ export ET_DEVICE_CAT="/dev/et-cat" export ET_DEVICE_GPS="/dev/et-gps" export ET_DEVICE_SDR="/dev/et-sdr" +# Standardized configuration locations and files +export ET_HOME="/opt/emcomm-tools" +export ET_ACTIVE_RADIO_CONF="${ET_HOME}/conf/radios.d/active-radio.json" + export ESC="\x1B" export RED="${ESC}[1;31m" export BLUE="${ESC}[1;34m" @@ -151,15 +155,14 @@ download_with_retries() { # executed before it starts up.. prime_rigctld_conn() { - ACTIVE_RADIO=$(et-system-info active-radio) - case "${ACTIVE_RADIO}" in - "X6100") - et-log "Priming rig control client connection for ${ACTIVE_RADIO}" + ACTIVE_RADIO=$(jq -r -e '.rigctrl.primeRig' ${ET_ACTIVE_RADIO_CONF}) + if [[ $? -eq 0 ]]; then + if [[ "${ACTIVE_RADIO}" = "true" ]]; then + et-log "Priming rig control client connection" notify_user "Please be patient. Priming connection to radio." rigctl -m 2 f > /dev/null - ;; - *) - et-log "No rigctld priming needed for ${ACTIVE_RADIO}" - ;; - esac + else + et-log "No rigctld priming needed" + fi + fi } diff --git a/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json b/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json index 9371fbe..2550b68 100644 --- a/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json +++ b/overlay/opt/emcomm-tools/conf/radios.d/xiegu-x6100.json @@ -6,7 +6,8 @@ "id": "3087", "baud": "19200", "ptt": "RIG", - "conf": "timeout=1000,retry=1,timeout_retry=1" + "conf": "timeout=1000,retry=1,timeout_retry=1", + "primeRig": true }, "notes": [ "Turn on radio",