Updated DSP. Compiles, no warnings/errors. Going to do some work on CAT.

This commit is contained in:
Rob French 2021-03-16 18:37:14 -05:00
parent 869e47d430
commit f724142fca
4 changed files with 244 additions and 208 deletions

View File

@ -10,17 +10,6 @@
//#include <SD.h> //#include <SD.h>
//#include <SerialFlash.h> //#include <SerialFlash.h>
const int rxRigInChannel = RX_RIG_IN_CH;
const int txMicInChannel = TX_MIC_IN_CH;
const int txLineInChannel = TX_LINE_IN_CH;
const int txUSBInChannel = TX_USB_IN_CH;
const int txNumChannels = TX_NUM_CHANNELS;
UBitxDSP DSP;
//static struct {
// GUItool: begin automatically generated code // GUItool: begin automatically generated code
AudioInputUSB usbIn; //xy=161,313 AudioInputUSB usbIn; //xy=161,313
AudioInputI2S lineIn; //xy=169,205 AudioInputI2S lineIn; //xy=169,205
@ -56,10 +45,6 @@ AudioControlSGTL5000 audioCtrl; //xy=435,448
//} audio; //} audio;
UBitxDSP::UBitxDSP()
: txSrc(MIC_IN), txSrcLatched(MIC_IN) {
}
void UBitxDSP::begin() { void UBitxDSP::begin() {
// Basic audio setup // Basic audio setup
@ -98,33 +83,32 @@ void UBitxDSP::update() {
if (state.vox[txSrc].enable && txVoxLevel.available()) { if (state.vox[txSrc].enable && txVoxLevel.available()) {
if (txVoxLevel.read() > state.vox[txSrc].threshold) { if (txVoxLevel.read() > state.vox[txSrc].threshold) {
voxTimeout = millis() + state.voxDelay; isVoxActive = true;
state.voxActive = true; sinceVoxActive = 0;
} }
} }
if (millis() > voxTimeout) { if (isVoxActive && (sinceVoxActive > state.voxDelay)) {
state.voxActive = false; isVoxActive = false;
} }
} }
void UBitxDSP::end() { void UBitxDSP::end() {
} }
//====================================================================== /**********************************************************************
// Transmit/Receive (T/R) Switching * Transmit/Receive switching
//====================================================================== **********************************************************************/
/*! /*!
* @brief Revert to receive (RX) mode from transmit (TX) mode. First * Return to receive (RX) mode from transmit (TX) mode.
* the transmit audio output is muted, to ensure that no more * First the transmit audio output is muted, to ensure that no more
* audio goes to the rig. Then we check to see if the latched * audio goes to the rig. Then we check to see if the latched TX audio
* TX audio source was different than the selected TX audio * source was different than the selected TX audio source; this happens
* source; this happens if the radio is currently set for a * if the radio is currently set for a particular input (which
* particular input (which determines what is monitored by the * determines what is monitored by the VOX), but then is commanded to
* VOX), but then is commanded to transmit a different source * transmit a different source (e.g. based on a CAT command). The
* (e.g. based on a CAT command). The actual transmit audio * actual transmit audio source is latched during transmit, but upon
* source is latched during transmit, but upon returning to * returning to receive, we restore the selected transmit audio.
* receive, we restore the selected transmit audio.
*/ */
void UBitxDSP::rx() { void UBitxDSP::rx() {
if (isTx) { if (isTx) {
@ -140,6 +124,9 @@ void UBitxDSP::rx() {
} }
} }
/*!
* Enter transmit (TX) mode from receive (RX) mode.
*/
void UBitxDSP::tx(TxAudioIn src) { void UBitxDSP::tx(TxAudioIn src) {
if (!isTx) { if (!isTx) {
muteRxIn(RX_AUDIO); muteRxIn(RX_AUDIO);
@ -159,9 +146,9 @@ void UBitxDSP::tx(TxAudioIn src) {
} }
} }
//====================================================================== /**********************************************************************
// Receive (RX) Audio Chain * General audio setup -- called via begin()
//====================================================================== **********************************************************************/
void UBitxDSP::setupRxAudio() { void UBitxDSP::setupRxAudio() {
for (int i = 0; i < NUM_RX_AUDIO_CH; i++) { for (int i = 0; i < NUM_RX_AUDIO_CH; i++) {
@ -185,42 +172,6 @@ void UBitxDSP::setupRxAudio() {
usbBypassAmp.gain(1.0); usbBypassAmp.gain(1.0);
} }
void UBitxDSP::setRxInLevel(RxAudioCh ch, float level) {
if (ch < NUM_RX_AUDIO_CH) {
state.rxin[ch].level = level;
rxAudio.gain(ch, state.rxin[ch].mute ? 0.0 : state.rxin[ch].level);
}
}
void UBitxDSP::muteRxIn() {
for (int i = 0; i < NUM_RX_AUDIO_CH; i++) {
state.rxin[RxAudioCh(i)].mute = true;
rxAudio.gain(i, 0.0);
}
}
void UBitxDSP::muteRxIn(RxAudioCh ch) {
if (ch < NUM_RX_AUDIO_CH) {
if (!state.rxin[ch].mute) {
state.rxin[ch].mute = true;
rxAudio.gain(ch, 0.0);
}
}
}
void UBitxDSP::unmuteRxIn(RxAudioCh ch) {
if (ch < NUM_RX_AUDIO_CH) {
if (state.rxin[ch].mute) {
state.rxin[ch].mute = false;
rxAudio.gain(ch, state.rxin[ch].level);
}
}
}
//======================================================================
// Transmit (TX) Audio Chain
//======================================================================
void UBitxDSP::setupTxAudio() { void UBitxDSP::setupTxAudio() {
for (int i = 0; i < NUM_TX_AUDIO_CH; i++) { for (int i = 0; i < NUM_TX_AUDIO_CH; i++) {
txAudio.gain(i, 0.0); txAudio.gain(i, 0.0);
@ -244,24 +195,64 @@ void UBitxDSP::setupTxAudio() {
tone2.frequency(1900); tone2.frequency(1900);
} }
/**********************************************************************
* Receive audio chain
**********************************************************************/
void UBitxDSP::setRxInLevel(RxAudioCh ch, float level) {
if (ch < NUM_RX_AUDIO_CH) {
state.rxIn[ch].level = level;
rxAudio.gain(ch, state.rxIn[ch].mute ? 0.0 : state.rxIn[ch].level);
}
}
void UBitxDSP::muteRxIn() {
for (int i = 0; i < NUM_RX_AUDIO_CH; i++) {
state.rxIn[RxAudioCh(i)].mute = true;
rxAudio.gain(i, 0.0);
}
}
void UBitxDSP::muteRxIn(RxAudioCh ch) {
if (ch < NUM_RX_AUDIO_CH) {
if (!state.rxIn[ch].mute) {
state.rxIn[ch].mute = true;
rxAudio.gain(ch, 0.0);
}
}
}
void UBitxDSP::unmuteRxIn(RxAudioCh ch) {
if (ch < NUM_RX_AUDIO_CH) {
if (state.rxIn[ch].mute) {
state.rxIn[ch].mute = false;
rxAudio.gain(ch, state.rxIn[ch].level);
}
}
}
/**********************************************************************
* Transmit audio chain
**********************************************************************/
void UBitxDSP::setTxInLevel(TxAudioCh ch, float level) { void UBitxDSP::setTxInLevel(TxAudioCh ch, float level) {
if (ch < NUM_TX_AUDIO_CH) { if (ch < NUM_TX_AUDIO_CH) {
state.txin[ch].level = level; state.txIn[ch].level = level;
txAudio.gain(ch, state.txin[ch].mute ? 0.0 : state.txin[ch].level); txAudio.gain(ch, state.txIn[ch].mute ? 0.0 : state.txIn[ch].level);
} }
} }
void UBitxDSP::muteTxIn() { void UBitxDSP::muteTxIn() {
for (int i = 0; i < NUM_TX_AUDIO_CH; i++) { for (int i = 0; i < NUM_TX_AUDIO_CH; i++) {
state.txin[TxAudioCh(i)].mute = true; state.txIn[TxAudioCh(i)].mute = true;
txAudio.gain(i, 0.0); txAudio.gain(i, 0.0);
} }
} }
void UBitxDSP::muteTxIn(TxAudioCh ch) { void UBitxDSP::muteTxIn(TxAudioCh ch) {
if (ch < NUM_TX_AUDIO_CH) { if (ch < NUM_TX_AUDIO_CH) {
if (!state.txin[ch].mute) { if (!state.txIn[ch].mute) {
state.txin[ch].mute = true; state.txIn[ch].mute = true;
txAudio.gain(ch, 0.0); txAudio.gain(ch, 0.0);
} }
} }
@ -269,29 +260,29 @@ void UBitxDSP::muteTxIn(TxAudioCh ch) {
void UBitxDSP::unmuteTxIn(TxAudioCh ch) { void UBitxDSP::unmuteTxIn(TxAudioCh ch) {
if (ch < NUM_TX_AUDIO_CH) { if (ch < NUM_TX_AUDIO_CH) {
if (state.txin[ch].mute) { if (state.txIn[ch].mute) {
state.txin[ch].mute = false; state.txIn[ch].mute = false;
rxAudio.gain(ch, state.txin[ch].level); rxAudio.gain(ch, state.txIn[ch].level);
} }
} }
} }
void UBitxDSP::setTxOutLevel(float level) { void UBitxDSP::setTxOutLevel(float level) {
state.txout.level = level; state.txOut.level = level;
txOutAmp.gain(state.txout.mute ? 0.0 : state.txout.level); txOutAmp.gain(state.txOut.mute ? 0.0 : state.txOut.level);
} }
void UBitxDSP::muteTxOut() { void UBitxDSP::muteTxOut() {
if (!state.txout.mute) { if (!state.txOut.mute) {
state.txout.mute = true; state.txOut.mute = true;
txOutAmp.gain(0.0); txOutAmp.gain(0.0);
} }
} }
void UBitxDSP::unmuteTxOut() { void UBitxDSP::unmuteTxOut() {
if (state.txout.mute) { if (state.txOut.mute) {
state.txout.mute = false; state.txOut.mute = false;
txOutAmp.gain(state.txout.level); txOutAmp.gain(state.txOut.level);
} }
} }
@ -338,13 +329,14 @@ void UBitxDSP::setTxAudioIn(TxAudioIn src, bool isTemp) {
default: default:
// should never happen // should never happen
break;
} }
} }
} }
//====================================================================== /**********************************************************************
// RX Audio Filter Settings * Receive audio filter (band pass)
//====================================================================== **********************************************************************/
const int minRxFilterLo = MIN_RX_FILTER_LO; const int minRxFilterLo = MIN_RX_FILTER_LO;
const int maxRxFilterHi = MAX_RX_FILTER_HI; const int maxRxFilterHi = MAX_RX_FILTER_HI;
@ -434,6 +426,17 @@ void UBitxDSP::setRxFilterCenter(int center) {
setRxFilter(lo, hi); setRxFilter(lo, hi);
} }
/**********************************************************************
* Singleton - the DSP instance
**********************************************************************/
#ifndef UBITXDSP_CLASS
#define UBITXDSP_CLASS UBitxDSP
#endif
UBITXDSP_CLASS theDSP;
UBitxDSP& DSP = theDSP;
/* /*
NOTES NOTES

View File

@ -9,113 +9,105 @@
#include <dynamicFilters.h> #include <dynamicFilters.h>
#include "Debug.h" #include "Debug.h"
#define MIN_RX_FILTER_LO 0 /**********************************************************************
#define MAX_RX_FILTER_HI 5000 * Macros
#define MIN_RX_FILTER_WIDTH 0 **********************************************************************/
#define MAX_RX_FILTER_WIDTH 5000
#define MIN_RX_FILTER_CENTER 0
#define MAX_RX_FILTER_CENTER 5000
#define DSP_MILLIS_PER_UPDATE 100 #define MIN_RX_FILTER_LO (0) //! Min allowable value of the RX filter low-cut frequency
#define MAX_RX_FILTER_HI (5000) //! Max allowable value of the RX filter hi-cut frequency
#define MIN_RX_FILTER_WIDTH (0) //! Min allowable value of the RX filter bandwidth
#define MAX_RX_FILTER_WIDTH (5000) //! Max allowable value of the RX filter bandwidth
#define MIN_RX_FILTER_CENTER (0) //! Min allowable value of the RX filter center frequency
#define MAX_RX_FILTER_CENTER (5000) //! Max allowable value of the RX filter center frequency
#define RX_RIG_IN_CH 0 #define DSP_MILLIS_PER_UPDATE (100) //! Number of milliseconds between update of the DSP object
#define TX_MIC_IN_CH 0 #define TX_VOX_MIC_THRESH (0.0) //! Threshold for mic VOX (not implemented, since mic requires special handling)
#define TX_LINE_IN_CH 0 #define TX_VOX_LINE_THRESH (0.25) //! Threshold for line in VOX
#define TX_USB_IN_CH 1 #define TX_VOX_USB_THRESH (0.25) //! Threshold for USB VOX
#define TX_NUM_CHANNELS 2 #define TX_VOX_TUNE_THRESH (0.0) //! Threshold for tune (single tone) VOX (not expected to be used)
#define TX_VOX_TT_THRESH (0.0) //! Threshold for two-tone VOX (not expected to be used)
#define TX_VOX_DELAY (500) //! VOX delay in milliseconds
#define TX_VOX_MIC_THRESH 0.0 /**********************************************************************
#define TX_VOX_LINE_THRESH 0.25 * Enumerations
#define TX_VOX_USB_THRESH 0.25 **********************************************************************/
#define TX_VOX_TUNE_THRESH 0.0
#define TX_VOX_TT_THRESH 0.0
#define TX_VOX_DELAY 500
/**********************************************************************/ //! Defines the four separate RX audio input channels available.
/*!
* @brief Defines the four separate RX audio input channels available.
* Not all are currently used by the implementation.
*/
enum RxAudioCh { enum RxAudioCh {
RX_AUDIO = 0, RX_AUDIO = 0, // Normal receiver audio input channel
RX_SPARE1, RX_SPARE1, // Not used
RX_SPARE2, RX_SPARE2, // Not used
RX_SPARE3, RX_SPARE3, // Not used
NUM_RX_AUDIO_CH NUM_RX_AUDIO_CH // Total number of channels
}; };
/*! //! Defines the different RX audio inputs (not channels).
* @brief Defines the different RX audio inputs. This is not really
* different than the channels, but in theory could be. See
* the corresponding TX enums for an example of this.
*/
enum RxAudioIn { enum RxAudioIn {
RIG_IN = 0, RIG_IN = 0, // Normal rig input (receiver audio)
NUM_RX_AUDIO_IN NUM_RX_AUDIO_IN // Total number of inputs
}; };
/*! //! Defines the four separate TX audio input channels available.
* @brief Defines the four separate TX audio input channels available.
* They do not directly correlate to TX audio input sources.
* Specifically. both mic and line inputs use TX_LINE, and
* the two-tone input uses both TX_TONE1 and TX_TONE2 at the
* same time.
*/
enum TxAudioCh { enum TxAudioCh {
TX_LINE = 0, TX_LINE = 0, // Line and/or mic audio input channel
TX_USB, TX_USB, // USB audio input channel
TX_TONE1, TX_TONE1, // Audio tone #1 input channel
TX_TONE2, TX_TONE2, // Audio tone #2 input channel
NUM_TX_AUDIO_CH NUM_TX_AUDIO_CH // Toal number of channels
}; };
/*! //! Defines the different TX audio input sources (not channels!).
* @brief Defines the different TX audio input sources (not channels!)
* As noted above, MIC_IN and LINE_IN share channels, and
* TWO_TONE_IN uses multiple channels.
*/
enum TxAudioIn { enum TxAudioIn {
MIC_IN = 0, MIC_IN = 0, // Microphone transmit audio input
LINE_IN, LINE_IN, // Line ("AUX") transmit audio input
USB_IN, USB_IN, // USB transmit audio input
TUNE_IN, TUNE_IN, // Tune input (transmits a single tone)
TWO_TONE_IN, TWO_TONE_IN, // Two tone audio input (transmits two tones)
NUM_TX_AUDIO_IN NUM_TX_AUDIO_IN // Total number of inputs
}; };
/*! /**********************************************************************
* @brief Describes a simple audio channel that can be muted. * Classes
*/ **********************************************************************/
//! Defines parameters for a simple audio channel that can be muted.
struct AudioChannel { struct AudioChannel {
bool mute = false; bool mute = false;
float level = 0.0; float level = 0.0;
}; };
/**********************************************************************/ /*!
* Contains the current 'persistent' state of the DSP.
* This includes all audio-specific state that can be saved to, or
* restored from, EEPROM. It does not include 'transient' state (such
* as whether we're currently transmitting or receiving).
*/
struct DSPState { struct DSPState {
// RX audio I/O settings - default to muted //! Receiver audio inputs; all default to muted.
AudioChannel rxin[NUM_RX_AUDIO_CH] = { AudioChannel rxIn[NUM_RX_AUDIO_CH] = {
{true, 1.0}, // audio {true, 1.0}, // audio
{true, 0.0}, // spare 1 {true, 0.0}, // spare 1
{true, 0.0}, // spare 2 {true, 0.0}, // spare 2
{true, 0.0} // spare 3 {true, 0.0} // spare 3
}; };
AudioChannel rxout = {true, 1.0};
// TX audio I/O settings - default to muted //! Receiver audio output; defaults to muted.
AudioChannel txin[NUM_TX_AUDIO_CH] = { AudioChannel rxOut = {true, 1.0};
//! Transmitter audio inputs; all default to muted.
AudioChannel txIn[NUM_TX_AUDIO_CH] = {
{true, 0.1}, // line {true, 0.1}, // line
{true, 0.1}, // USB {true, 0.1}, // USB
{true, 0.1}, // tone 1 {true, 0.1}, // tone 1
{true, 0.1} // tone 2 {true, 0.1} // tone 2
}; };
AudioChannel txout = {true, 1.0};
// TX VOX settings, per audio input (not channel!) //! Tranmitter audio output; defaults to muted.
AudioChannel txOut = {true, 1.0};
//! Transmitter VOX settings, per audio input (not channel).
struct { struct {
bool enable = false; bool enable = false;
float threshold = 1.0; float threshold = 1.0;
@ -126,44 +118,62 @@ struct DSPState {
{false, TX_VOX_TUNE_THRESH}, {false, TX_VOX_TUNE_THRESH},
{false, TX_VOX_TT_THRESH} {false, TX_VOX_TT_THRESH}
}; };
unsigned voxDelay = TX_VOX_DELAY;
bool voxActive = false;
// RX filter settings //! VOX delay (regardless of input).
unsigned voxDelay = TX_VOX_DELAY;
//! Current RX filter settings
int rxFilterLo = 300; int rxFilterLo = 300;
int rxFilterHi = 3000; int rxFilterHi = 3000;
}; };
/*!
* Defines the DSP subsystem of the UBitx V5X.
* The DSP subsystem, which relies on the Teensy Audio Library, is
* responsible for setting up the audio inputs and outputs for both
* receive (RX) and transmit (TX) audio, maintaining the correct path
* between inputs and outputs based on current TX/RX state, and setting
* up audio filters and other audio-based modules for the RX and TX
* audio paths.
*/
class UBitxDSP { class UBitxDSP {
// Object construction. /********************************************************************
public: * Object creation/deletion
UBitxDSP(); ********************************************************************/
public:
UBitxDSP() {}
/********************************************************************
* Basic administration
********************************************************************/
// Basic administrative functions.
public: public:
void begin(); void begin();
void update(); void update();
void end(); void end();
//==================================================================== /********************************************************************
// Transmit/Receive (T/R) Switching * Transmit/Receive switching
//==================================================================== ********************************************************************/
public: public:
void rx(); void rx();
inline void tx() { tx(txSrc); } inline void tx() { tx(txSrc); }
void tx(TxAudioIn src); void tx(TxAudioIn src);
//==================================================================== /********************************************************************
// Receive (RX) Audio Chain * General audio setup -- called via begin()
//==================================================================== ********************************************************************/
// General administrative function to setup the initial RX audio protected:
// chain. This should only be called once, via begin(). virtual void setupRxAudio();
private: virtual void setupTxAudio();
void setupRxAudio();
/********************************************************************
* Receive audio chain
********************************************************************/
// Basic control of RX audio inputs and outputs. // Basic control of RX audio inputs and outputs.
public: public:
@ -172,14 +182,9 @@ class UBitxDSP {
void muteRxIn(RxAudioCh ch); // Mute a specific RX audio input channel. void muteRxIn(RxAudioCh ch); // Mute a specific RX audio input channel.
void unmuteRxIn(RxAudioCh ch); // Un-mute a specific RX audio input channel. void unmuteRxIn(RxAudioCh ch); // Un-mute a specific RX audio input channel.
//==================================================================== /********************************************************************
// Transmit (TX) Audio Chain * Transmit audio chain
//==================================================================== ********************************************************************/
// General administrative function to setup the initial TX audio
// chain. This should only be called once, via begin().
private:
void setupTxAudio();
// Basic control of TX audio inputs and outputs. // Basic control of TX audio inputs and outputs.
public: public:
@ -196,12 +201,14 @@ class UBitxDSP {
void setTxAudioIn(TxAudioIn src, bool isTemp = false); // Select a specific TX audio input path, and identify it as permanent or temporary. void setTxAudioIn(TxAudioIn src, bool isTemp = false); // Select a specific TX audio input path, and identify it as permanent or temporary.
inline TxAudioIn getTxAudioIn() const { return txSrc; } // Return the current TX audio input. inline TxAudioIn getTxAudioIn() const { return txSrc; } // Return the current TX audio input.
//==================================================================== /********************************************************************
// RX Audio Filter Settings * Receive audio filter (band pass)
//==================================================================== ********************************************************************/
public: public:
void bypassRxFilter(); void bypassRxFilter();
void updateRxFilter();
void setRxFilter(int lo, int hi); void setRxFilter(int lo, int hi);
void setRxFilterLo(int lo); void setRxFilterLo(int lo);
void setRxFilterHi(int hi); void setRxFilterHi(int hi);
@ -209,53 +216,57 @@ class UBitxDSP {
void setRxFilterCenter(int center); void setRxFilterCenter(int center);
/*! /*!
* @brief Get the current low frequency bound of the RX band pass filter. * Get the current low frequency bound of the RX band pass filter.
* @return The low frequency bound. * @return The low frequency bound.
*/ */
inline int getRxFilterLo() { return state.rxFilterLo; } inline int getRxFilterLo() { return state.rxFilterLo; }
/*! /*!
* @brief Get the current high frequency bound of the RX band pass filter. * Get the current high frequency bound of the RX band pass filter.
* @return The high frequency bound. * @return The high frequency bound.
*/ */
inline int getRxFilterHi() { return state.rxFilterHi; } inline int getRxFilterHi() { return state.rxFilterHi; }
/*! /*!
* @brief Get the current width of the RX band pass filter. * Get the current width of the RX band pass filter.
* @return The filter width. * @return The filter width.
*/ */
inline int getRxFilterWidth() { return state.rxFilterHi - state.rxFilterLo; } inline int getRxFilterWidth() { return state.rxFilterHi - state.rxFilterLo; }
/*! /*!
* @brief Get the current center frequency of the RX band pass filter. * Get the current center frequency of the RX band pass filter.
* @return The center frequency. * @return The center frequency.
*/ */
inline int getRxFilterCenter() { return (state.rxFilterHi + state.rxFilterLo) / 2; } inline int getRxFilterCenter() { return (state.rxFilterHi + state.rxFilterLo) / 2; }
// TX audio input settings /********************************************************************
void setTxInputLevel(int ch, float lvl); * Transmit Voice-Operated-Switch (VOX)
void enableTxInput(int ch); ********************************************************************/
void disableTxInput(int ch);
void startTxInput(int ch); inline bool voxActive() { return isVoxActive; }
void stopTxInput(int ch); inline bool voxInactive() { return !isVoxActive; }
/********************************************************************
* Private state
********************************************************************/
private: private:
DSPState state;
bool isTx = false; bool isTx = false;
TxAudioIn txSrc = MIC_IN;
TxAudioIn txSrcLatched = MIC_IN;
void updateRxFilter(); short coefficients[NUM_COEFFICIENTS] = {0};
DSPState state; elapsedMillis sinceLastUpdate = 0;
short coefficients[NUM_COEFFICIENTS];
elapsedMillis sinceLastUpdate;
TxAudioIn txSrc, txSrcLatched;
float usbVol = 0.0; float usbVol = 0.0;
unsigned voxTimeout; bool isVoxActive = false;
elapsedMillis sinceVoxActive = 0;
}; };
extern UBitxDSP DSP; extern UBitxDSP& DSP;
#endif #endif

View File

@ -319,6 +319,16 @@ void TS590_SL::sendResponse(const char* cmd) {
/**********************************************************************/ /**********************************************************************/
void TS590_VX::handleCommand(const char* cmd) {
}
void TS590_VX::sendResponse(const char* cmd) {
}
/**********************************************************************/
TS590_FA cmdFA; TS590_FA cmdFA;
TS590_FB cmdFB; TS590_FB cmdFB;
TS590_FR cmdFR; TS590_FR cmdFR;

View File

@ -192,6 +192,18 @@ class TS590_SL : public TS590Command {
unsigned index; unsigned index;
}; };
/*!
* CAT command for enabling or disabling the mic VOX.
*/
class TS590_VX : public TS590Command {
public:
TS590_VX(): TS590Command("VX") {}
virtual void handleCommand(const char* cmd);
virtual void sendResponse(const char* cmd);
private:
unsigned index;
};
/**********************************************************************/ /**********************************************************************/
class UBitxTS590 { class UBitxTS590 {