Updated with some of the changes I made on travel. Will probably break everything...

This commit is contained in:
Rob French 2021-03-03 10:44:25 -06:00
parent 119902b1e0
commit 86ae1ddb2f
11 changed files with 501 additions and 98 deletions

View File

@ -214,12 +214,12 @@ void UBitxDSP::txUSBIn() {
/**********************************************************************/ /**********************************************************************/
// RX filter settings // RX filter settings
const int minRxFilterLo = MIN_RX_FILTER_LO; const float minRxFilterLo = MIN_RX_FILTER_LO;
const int maxRxFilterHi = MAX_RX_FILTER_HI; const float maxRxFilterHi = MAX_RX_FILTER_HI;
const int minRxFilterWidth = MIN_RX_FILTER_WIDTH; const float minRxFilterWidth = MIN_RX_FILTER_WIDTH;
const int maxRxFilterWidth = MAX_RX_FILTER_WIDTH; const float maxRxFilterWidth = MAX_RX_FILTER_WIDTH;
const int minRxFilterCenter = MIN_RX_FILTER_CENTER; const float minRxFilterCenter = MIN_RX_FILTER_CENTER;
const int maxRxFilterCenter = MAX_RX_FILTER_CENTER; const float maxRxFilterCenter = MAX_RX_FILTER_CENTER;
/*! /*!
* @brief Bypass the RX audio filter. * @brief Bypass the RX audio filter.
@ -238,7 +238,7 @@ void UBitxDSP::updateRxFilter() {
rxFilter.begin(coefficients, NUM_COEFFICIENTS); rxFilter.begin(coefficients, NUM_COEFFICIENTS);
} }
void UBitxDSP::setRxFilter(int lo, int hi) { void UBitxDSP::setRxFilter(float lo, float hi) {
if (hi < lo + minRxFilterWidth) { if (hi < lo + minRxFilterWidth) {
hi = lo + minRxFilterWidth; hi = lo + minRxFilterWidth;
} }
@ -256,7 +256,7 @@ void UBitxDSP::setRxFilter(int lo, int hi) {
updateRxFilter(); updateRxFilter();
} }
void UBitxDSP::setRxFilterLo(int lo) { void UBitxDSP::setRxFilterLo(float lo) {
if (lo > state.rxFilterHi - minRxFilterWidth) { if (lo > state.rxFilterHi - minRxFilterWidth) {
lo = state.rxFilterHi - minRxFilterWidth; lo = state.rxFilterHi - minRxFilterWidth;
} }
@ -267,7 +267,7 @@ void UBitxDSP::setRxFilterLo(int lo) {
updateRxFilter(); updateRxFilter();
} }
void UBitxDSP::setRxFilterHi(int hi) { void UBitxDSP::setRxFilterHi(float hi) {
if (hi < state.rxFilterLo + minRxFilterWidth) { if (hi < state.rxFilterLo + minRxFilterWidth) {
hi = state.rxFilterLo + minRxFilterWidth; hi = state.rxFilterLo + minRxFilterWidth;
} }
@ -278,27 +278,27 @@ void UBitxDSP::setRxFilterHi(int hi) {
updateRxFilter(); updateRxFilter();
} }
void UBitxDSP::setRxFilterWidth(int width) { void UBitxDSP::setRxFilterWidth(float width) {
if (width < minRxFilterWidth) { if (width < minRxFilterWidth) {
width = minRxFilterWidth; width = minRxFilterWidth;
} else if (width > maxRxFilterWidth) { } else if (width > maxRxFilterWidth) {
width = maxRxFilterWidth; width = maxRxFilterWidth;
} }
int center = (state.rxFilterHi + state.rxFilterLo) / 2; float center = (state.rxFilterHi + state.rxFilterLo) / 2;
int lo = center - (width / 2); float lo = center - (width / 2);
int hi = center + (width / 2); float hi = center + (width / 2);
setRxFilter(lo, hi); setRxFilter(lo, hi);
} }
void UBitxDSP::setRxFilterCenter(int center) { void UBitxDSP::setRxFilterCenter(float center) {
if (center < minRxFilterCenter) { if (center < minRxFilterCenter) {
center = minRxFilterCenter; center = minRxFilterCenter;
} else if (center > maxRxFilterCenter) { } else if (center > maxRxFilterCenter) {
center = maxRxFilterCenter; center = maxRxFilterCenter;
} }
int width = state.rxFilterHi - state.rxFilterLo; float width = state.rxFilterHi - state.rxFilterLo;
int lo = center - (width / 2); float lo = center - (width / 2);
int hi = center + (width / 2); float hi = center + (width / 2);
setRxFilter(lo, hi); setRxFilter(lo, hi);
} }

View File

@ -9,12 +9,12 @@
#include <dynamicFilters.h> #include <dynamicFilters.h>
#include "Debug.h" #include "Debug.h"
#define MIN_RX_FILTER_LO 0 #define MIN_RX_FILTER_LO 0.0
#define MAX_RX_FILTER_HI 5000 #define MAX_RX_FILTER_HI 5000.0
#define MIN_RX_FILTER_WIDTH 0 #define MIN_RX_FILTER_WIDTH 0.0
#define MAX_RX_FILTER_WIDTH 5000 #define MAX_RX_FILTER_WIDTH 5000.0
#define MIN_RX_FILTER_CENTER 0 #define MIN_RX_FILTER_CENTER 0.0
#define MAX_RX_FILTER_CENTER 5000 #define MAX_RX_FILTER_CENTER 5000.0
#define DSP_MILLIS_PER_UPDATE 100 #define DSP_MILLIS_PER_UPDATE 100
@ -41,8 +41,8 @@ struct DSPState {
// RX audio output settings // RX audio output settings
// RX filter settings // RX filter settings
int rxFilterLo = 300; float rxFilterLo = 300.0;
int rxFilterHi = 3000; float rxFilterHi = 3000.0;
// TX audio input settings // TX audio input settings
float txInLvl[4] = {0.5, 0.5, 0.0, 0.0}; float txInLvl[4] = {0.5, 0.5, 0.0, 0.0};
@ -86,11 +86,11 @@ class UBitxDSP {
// RX filter settings // RX filter settings
void bypassRxFilter(); void bypassRxFilter();
void setRxFilter(int lo, int hi); void setRxFilter(float lo, float hi);
void setRxFilterLo(int lo); void setRxFilterLo(float lo);
void setRxFilterHi(int hi); void setRxFilterHi(float hi);
void setRxFilterWidth(int width); void setRxFilterWidth(float width);
void setRxFilterCenter(int center); void setRxFilterCenter(float center);
/*! /*!
* @brief Get the current low frequency bound of the RX band pass filter. * @brief Get the current low frequency bound of the RX band pass filter.

View File

@ -61,7 +61,7 @@ speed(wpm), symWeight(weight)
// Calculate the length of dot, dash and silence // Calculate the length of dot, dash and silence
void UBitxKeyer::calcRatio() void UBitxKeyer::calcRatio()
{ {
float w = (1 + symWeight) / (symWeight -1); float w = (1.0 + symWeight) / (symWeight - 1.0);
spaceLen = (1200 / speed); spaceLen = (1200 / speed);
dotLen = spaceLen * (w - 1); dotLen = spaceLen * (w - 1);
dashLen = (1 + w) * spaceLen; dashLen = (1 + w) * spaceLen;
@ -73,6 +73,12 @@ void UBitxKeyer::setWPM(int wpm)
calcRatio(); calcRatio();
} }
void UBitxKeyer::setWeight(float weight)
{
symWeight = weight;
calcRatio();
}
//====================================================================== //======================================================================
// Latch paddle press // Latch paddle press
//====================================================================== //======================================================================
@ -107,10 +113,9 @@ bool UBitxKeyer::doPaddles()
if ((digitalRead(LP_in) == LOW) || (digitalRead(RP_in) == LOW) || (keyerControl & 0x03)) { if ((digitalRead(LP_in) == LOW) || (digitalRead(RP_in) == LOW) || (keyerControl & 0x03)) {
updatePaddleLatch(); updatePaddleLatch();
keyerState = CHK_DIT; keyerState = CHK_DIT;
// letting this fall through // return true; return true;
} else {
return false;
} }
return false;
//break; //break;
case CHK_DIT: // See if the dit paddle was pressed case CHK_DIT: // See if the dit paddle was pressed
@ -119,15 +124,15 @@ bool UBitxKeyer::doPaddles()
ktimer = dotLen; ktimer = dotLen;
keyerState = KEYED_PREP; keyerState = KEYED_PREP;
return true; return true;
} else { // fall through
keyerState = CHK_DAH;
} }
// fall through
keyerState = CHK_DAH;
case CHK_DAH: // See if dah paddle was pressed case CHK_DAH: // See if dah paddle was pressed
if (keyerControl & DAH_L) { if (keyerControl & DAH_L) {
ktimer = dashLen; ktimer = dashLen;
keyerState = KEYED_PREP; keyerState = KEYED_PREP;
// letting this fall through // return true; return true;
} else { } else {
keyerState = IDLE; keyerState = IDLE;
return false; return false;
@ -140,7 +145,7 @@ bool UBitxKeyer::doPaddles()
ktimer += millis(); // set ktimer to interval end time ktimer += millis(); // set ktimer to interval end time
keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits
keyerState = KEYED; // next state keyerState = KEYED; // next state
// letting this fall through // return true; return true;
//break; //break;
case KEYED: // Wait for timer to expire case KEYED: // Wait for timer to expire
@ -148,12 +153,11 @@ bool UBitxKeyer::doPaddles()
keyDown = false; keyDown = false;
ktimer = millis() + spaceLen; // inter-element time ktimer = millis() + spaceLen; // inter-element time
keyerState = INTER_ELEMENT; // next state keyerState = INTER_ELEMENT; // next state
// letting this fall through // return true; return true;
} else if (keyMode == IAMBICB) { // Iambic B Mode ? } else if (keyMode == IAMBICB) { // Iambic B Mode ?
updatePaddleLatch(); // yes, early paddle latch in Iambic B mode updatePaddleLatch(); // yes, early paddle latch in Iambic B mode
} else {
return true;
} }
return true;
// break; // break;
case INTER_ELEMENT: // Insert time between dits/dahs case INTER_ELEMENT: // Insert time between dits/dahs
@ -168,9 +172,8 @@ bool UBitxKeyer::doPaddles()
keyerState = IDLE; // go idle keyerState = IDLE; // go idle
return false; return false;
} }
} else {
return true;
} }
return true;
//break; //break;
} }

View File

@ -44,10 +44,12 @@ public:
//void cw_pin(int pin); //void cw_pin(int pin);
//void ptt_pin(int pin); //void ptt_pin(int pin);
void setWPM(int wpm); void setWPM(int wpm);
inline int getWPM() { return speed; }
void setWeight(float weight);
inline float getWeight() { return symWeight; }
inline void setMode(int mode) { keyMode = mode; } inline void setMode(int mode) { keyMode = mode; }
inline int getMode() { return keyMode; } inline int getMode() { return keyMode; }
inline bool isDown() { return keyDown; } inline bool isDown() { return keyDown; }
// void setWeight();
bool doPaddles(); bool doPaddles();

View File

@ -3,15 +3,56 @@
#include "RigState.h" #include "RigState.h"
#define DEFAULT_SSB_LO_CUT 300.0
#define DEFAULT_SSB_HI_CUT 3000.0
#define DEFAULT_CW_WIDTH 500.0
#define DEFAULT_LOW_USB false
#define DEFAULT_LOW_CWU true
#define DEFAULT_HIGH_USB true
#define DEFAULT_HIGH_CWU true
enum HamBand {
BAND_80M = 0,
BAND_60M,
BAND_40M,
BAND_30M,
BAND_20M,
BAND_17M,
BAND_15M,
BAND_12M,
BAND_10M,
NUM_BANDS
};
struct ModeConfig {
bool isUpper;
float dspLo;
float dspHi;
};
struct BandConfig {
ModeConfig cw;
ModeConfig ssb;
};
struct RigConfig {
//bool isData = false;
bool useUSBInput = true; // whether or not to use the USB input for data
};
class UBitxRig { class UBitxRig {
public: public:
UBitxRig();
inline void begin() {} inline void begin() {}
inline void update() {} inline void update() {}
inline unsigned getFreqA() const { return radState.getFreqA(); } inline unsigned getFreqA() const { return radState.getFreqA(); }
inline unsigned getFreqB() const { return radState.getFreqB(); } inline unsigned getFreqB() const { return radState.getFreqB(); }
inline int getRIT() const { return radState.getRIT(); } inline int getRIT() const { return radState.getRIT(); }
inline int getXIT() const { return radState.getXIT(); } inline int getXIT() const { return radState.getXIT(); }
inline bool isVFOA() const { return radState.isVFOA(); } inline bool isVFOA() const { return radState.isVFOA(); }
inline bool isVFOB() const { return radState.isVFOB(); } inline bool isVFOB() const { return radState.isVFOB(); }
inline bool isSplit() const { return radState.isSplit(); } inline bool isSplit() const { return radState.isSplit(); }
@ -22,12 +63,20 @@ class UBitxRig {
inline bool isModeCWR() const { return radState.isModeCWR(); } inline bool isModeCWR() const { return radState.isModeCWR(); }
inline bool isModeUSB() const { return radState.isModeUSB(); } inline bool isModeUSB() const { return radState.isModeUSB(); }
inline bool isModeLSB() const { return radState.isModeLSB(); } inline bool isModeLSB() const { return radState.isModeLSB(); }
inline float getCWSidetone() const { return static_cast<float>(radState.getSidetone()); }
inline bool isUSBInput() const { return conf.useUSBInput; }
inline bool isLineInput() const { return !conf.useUSBInput; }
inline bool isAI() const { return autoInfo; } inline bool isAI() const { return autoInfo; }
inline void setFreqA(unsigned freq) { catState.setFreqA(freq); } inline void setFreqA(unsigned freq) { catState.setFreqA(freq); }
inline void setFreqB(unsigned freq) { catState.setFreqB(freq); } inline void setFreqB(unsigned freq) { catState.setFreqB(freq); }
inline void setRIT(int freq) { catState.setRIT(freq); } inline void setRIT(int freq) { catState.setRIT(freq); }
inline void setXIT(int freq) { catState.setXIT(freq); } inline void setXIT(int freq) { catState.setXIT(freq); }
inline void setVFOA() { catState.setVFOA(); } inline void setVFOA() { catState.setVFOA(); }
inline void setVFOB() { catState.setVFOB(); } inline void setVFOB() { catState.setVFOB(); }
inline void setSplitOn() { catState.setSplitOn(); } inline void setSplitOn() { catState.setSplitOn(); }
@ -36,10 +85,15 @@ class UBitxRig {
inline void setRITOff() { catState.setRITOff(); } inline void setRITOff() { catState.setRITOff(); }
inline void setXITOn() { catState.setXITOn(); } inline void setXITOn() { catState.setXITOn(); }
inline void setXITOff() { catState.setXITOff(); } inline void setXITOff() { catState.setXITOff(); }
inline void setCW() { catState.setCW(); } inline void setModeCW() { catState.setModeCW(); }
inline void setCWR() { catState.setCWR(); } inline void setModeCWR() { catState.setModeCWR(); }
inline void setUSB() { catState.setUSB(); } inline void setModeUSB() { catState.setModeUSB(); }
inline void setLSB() { catState.setLSB(); } inline void setModeLSB() { catState.setModeLSB(); }
inline void setCWSidetone(float f) { catState.setSidetone(static_cast<uint16_t>(f)); }
inline void setUSBInput() { conf.useUSBInput = true; }
inline void setLineInput() { conf.useUSBInput = false; }
inline void aiOn() { autoInfo = true; } inline void aiOn() { autoInfo = true; }
inline void aiOff() { autoInfo = false; } inline void aiOff() { autoInfo = false; }
@ -59,9 +113,12 @@ class UBitxRig {
//void getBand(); //void getBand();
private: private:
RigConfig conf;
UBitxRigState catState; UBitxRigState catState;
UBitxRigState radState; UBitxRigState radState;
bool autoInfo = false; bool autoInfo = false;
BandConfig band[NUM_BANDS];
}; };
extern UBitxRig Rig; extern UBitxRig Rig;

View File

@ -56,7 +56,7 @@ void UBitxRigState::begin() {
#include "ubitx.h" #include "ubitx.h"
#include "ubitx_eemap.h" #include "ubitx_eemap.h"
extern unsigned long frequency, ritRxFrequency, ritTxFrequency; extern unsigned long frequency, ritRxFrequency, ritTxFrequency, sideTone;
extern unsigned long vfoA; extern unsigned long vfoA;
extern unsigned long vfoB; extern unsigned long vfoB;
extern char cwMode; extern char cwMode;
@ -169,8 +169,10 @@ void UBitxRigState::writeDirty() {
// XIT - TODO // XIT - TODO
} }
// VFO A/B selection // Various flags
if (isDirty(FLAGS_WORD)) { if (isDirty(FLAGS_WORD)) {
// VFO A/B selection
char prev = vfoActive; char prev = vfoActive;
vfoActive = isVFOA() ? VFO_A : VFO_B; vfoActive = isVFOA() ? VFO_A : VFO_B;
if (vfoActive != prev) { if (vfoActive != prev) {
@ -214,6 +216,13 @@ void UBitxRigState::writeDirty() {
setFrequency(frequency); setFrequency(frequency);
} }
} }
// Keyer information
if (isDirty(KEYER_WORD)) {
// Sidetone frequency
sideTone = static_cast<unsigned long>(getSidetone());
}
} }
/*! /*!
@ -284,17 +293,22 @@ void UBitxRigState::readDirty() {
char curr = (cwMode << 1) | isUSB; char curr = (cwMode << 1) | isUSB;
if (curr != prev) { if (curr != prev) {
if (cwMode == 2) { if (cwMode == 2) {
setCW(); setModeCW();
} else if (cwMode == 1) { } else if (cwMode == 1) {
setCWR(); setModeCWR();
} else { } else {
if (isUSB) { if (isUSB) {
setUSB(); setModeUSB();
} else { } else {
setLSB(); setModeLSB();
} }
} }
} }
// Sidetone
if (getSidetone() != static_cast<uint16_t>(sideTone)) {
setSidetone(static_cast<uint16_t>(sideTone));
}
} }
/*********************************************************************** /***********************************************************************
@ -332,6 +346,16 @@ void UBitxRigState::receive_RIGINF(int numBytes) {
} }
} }
//--------------------------------------------------------------------
// Do anything that needs to happen when something is updated by the
// Raduino... this would be due to e.g. changes through the menu.
// Current (as of 2/19/2021) things that DON'T need to have any
// updates: frequency (those just get requested by CAT as needed).
// Current things that do need to get updated: sidetone (used to
// update CW filter values).
//--------------------------------------------------------------------
processDirty();
IFDEBUG( serialHexState("Rcvd") ); IFDEBUG( serialHexState("Rcvd") );
IFDEBUG( serialPrettyState("Rcvd") ); IFDEBUG( serialPrettyState("Rcvd") );
} }
@ -372,6 +396,13 @@ void UBitxRigState::send_RIGINF() {
//-------------------------------------------------------------------- //--------------------------------------------------------------------
} }
/*!
* @brief Perform required actions based on any dirty bits set.
*/
void UBitxRigState::processDirty() {
}
#endif #endif
#ifdef DEBUG #ifdef DEBUG

View File

@ -15,6 +15,9 @@
#define UBITX_USB_FLAG 0x00000020 #define UBITX_USB_FLAG 0x00000020
#define UBITX_TX_FLAG 0x00000040 #define UBITX_TX_FLAG 0x00000040
#define UBITX_SIDETONE_MASK 0x000007FF
#define UBITX_KEYER_MODE_MASK 0x00003800
#ifdef TEENSYDUINO #ifdef TEENSYDUINO
#define DISABLEINTS(CMD) do { noInterrupts(); CMD; interrupts(); } while (0) #define DISABLEINTS(CMD) do { noInterrupts(); CMD; interrupts(); } while (0)
#else #else
@ -27,6 +30,7 @@ enum RigStateWord {
VFOB_WORD, VFOB_WORD,
OFFSETS_WORD, OFFSETS_WORD,
FLAGS_WORD, FLAGS_WORD,
KEYER_WORD,
NUM_WORDS NUM_WORDS
}; };
@ -255,25 +259,25 @@ struct UBitxRigState {
return result; return result;
} }
inline void setUSB(bool mark = true) { inline void setModeUSB(bool mark = true) {
DISABLEINTS( data[FLAGS_WORD] |= UBITX_USB_FLAG; DISABLEINTS( data[FLAGS_WORD] |= UBITX_USB_FLAG;
data[FLAGS_WORD] &= ~UBITX_CW_FLAG; data[FLAGS_WORD] &= ~UBITX_CW_FLAG;
if (mark) setDirty(FLAGS_WORD) ); if (mark) setDirty(FLAGS_WORD) );
} }
inline void setLSB(bool mark = true) { inline void setModeLSB(bool mark = true) {
DISABLEINTS( data[FLAGS_WORD] &= ~UBITX_USB_FLAG; DISABLEINTS( data[FLAGS_WORD] &= ~UBITX_USB_FLAG;
data[FLAGS_WORD] &= ~UBITX_CW_FLAG; data[FLAGS_WORD] &= ~UBITX_CW_FLAG;
if (mark) setDirty(FLAGS_WORD) ); if (mark) setDirty(FLAGS_WORD) );
} }
inline void setCW(bool mark = true) { inline void setModeCW(bool mark = true) {
DISABLEINTS( data[FLAGS_WORD] |= UBITX_USB_FLAG; DISABLEINTS( data[FLAGS_WORD] |= UBITX_USB_FLAG;
data[FLAGS_WORD] |= UBITX_CW_FLAG; data[FLAGS_WORD] |= UBITX_CW_FLAG;
if (mark) setDirty(FLAGS_WORD) ); if (mark) setDirty(FLAGS_WORD) );
} }
inline void setCWR(bool mark = true) { inline void setModeCWR(bool mark = true) {
DISABLEINTS( data[FLAGS_WORD] &= ~UBITX_USB_FLAG; DISABLEINTS( data[FLAGS_WORD] &= ~UBITX_USB_FLAG;
data[FLAGS_WORD] |= UBITX_CW_FLAG; data[FLAGS_WORD] |= UBITX_CW_FLAG;
if (mark) setDirty(FLAGS_WORD) ); if (mark) setDirty(FLAGS_WORD) );
@ -309,6 +313,18 @@ struct UBitxRigState {
return result; return result;
} }
inline void setSidetone(uint16_t f, bool mark = true) {
DISABLEINTS( data[KEYER_WORD] &= ~UBITX_SIDETONE_MASK;
data[KEYER_WORD] |= (uint32_t(f) & UBITX_SIDETONE_MASK);
if (mark) setDirty(KEYER_WORD) );
}
inline uint16_t getSidetone() {
uint32_t result;
DISABLEINTS( result = data[KEYER_WORD] & UBITX_SIDETONE_MASK );
return uint16_t(result);
}
#ifdef DEBUG #ifdef DEBUG
void serialHexState(const char* label); void serialHexState(const char* label);
void serialPrettyState(const char* label); void serialPrettyState(const char* label);
@ -319,6 +335,9 @@ struct UBitxRigState {
// RigState, not in the TeensyDSP (Teensy) case. // RigState, not in the TeensyDSP (Teensy) case.
void writeDirty(); // write fields FROM RigState TO Raduino void writeDirty(); // write fields FROM RigState TO Raduino
void readDirty(); // read variables FROM Raduino TO RigState void readDirty(); // read variables FROM Raduino TO RigState
#else
// These methods are only defined (currently) in the TeensyDSP case.
void processDirty();
#endif #endif
}; };

View File

@ -5,7 +5,8 @@
#include <Arduino.h> #include <Arduino.h>
#include "TR.h" #include "TR.h"
UBitxTR TR(DSP); UBitxTR _tr(DSP);
UBitxTR& TR = _tr;
void UBitxTR::update(bool cw, bool extKey) { void UBitxTR::update(bool cw, bool extKey) {
updateKey(); updateKey();

View File

@ -19,6 +19,12 @@ const int uBitxTRPttPin = UBITX_TR_PTT_PIN;
const int uBitxTRVoxPin = UBITX_TR_VOX_PIN; const int uBitxTRVoxPin = UBITX_TR_VOX_PIN;
const int uBitxTRKeyPin = UBITX_TR_KEY_PIN; const int uBitxTRKeyPin = UBITX_TR_KEY_PIN;
struct TxSource {
MIC_SOURCE = 0,
LINE_SOURCE,
USB_SOURCE,
};
class UBitxTR { class UBitxTR {
public: public:
UBitxTR(UBitxDSP& d, int out = uBitxTROutPin, int p = uBitxTRPttPin, int v = uBitxTRVoxPin, int k = uBitxTRKeyPin): UBitxTR(UBitxDSP& d, int out = uBitxTROutPin, int p = uBitxTRPttPin, int v = uBitxTRVoxPin, int k = uBitxTRKeyPin):
@ -63,9 +69,10 @@ class UBitxTR {
inline bool catActivated() { return (L_catActive != catActive) && L_catActive; } inline bool catActivated() { return (L_catActive != catActive) && L_catActive; }
inline bool catDeactivated() { return (L_catActive != catActive) && catActive; } inline bool catDeactivated() { return (L_catActive != catActive) && catActive; }
inline void catTX() { inline void catTX(TxSource src) {
L_catActive = catActive; L_catActive = catActive;
catActive = true; catActive = true;
txSource = src;
} }
inline void catRX() { inline void catRX() {
@ -73,10 +80,11 @@ class UBitxTR {
catActive = false; catActive = false;
} }
//====================================================================== //====================================================================
inline bool transmitting() { return isTX; } inline bool transmitting() { return isTX; }
inline bool receiving() { return !isTX; } inline bool receiving() { return !isTX; }
inline TxSource source() const { return txSource; }
/*! /*!
* @brief Check if any of the PTT's have been pressed or released * @brief Check if any of the PTT's have been pressed or released
@ -145,6 +153,7 @@ class UBitxTR {
bool L_keyDown = false; bool L_keyDown = false;
bool catActive = false; bool catActive = false;
bool L_catActive = false; bool L_catActive = false;
TxSource txSource = MIC_SOURCE;
}; };
extern UBitxTR TR; extern UBitxTR TR;

View File

@ -41,8 +41,6 @@ TS590Command::TS590Command(const char* pre) {
} }
} }
TS590Command::~TS590Command() {}
/*! /*!
* @brief Determine whether this is a Read command or not. by * @brief Determine whether this is a Read command or not. by
* default, if it's a 2-letter command, it's a Read. * default, if it's a 2-letter command, it's a Read.
@ -139,8 +137,18 @@ void TS590Command::setDSP(UBitxDSP* d) {
theDSP = d; theDSP = d;
} }
/*!
* @brief Set the T/R that will be used to process commands.
* @param t
* Pointer to the UBitxTR object.
*/
void TS590Command::setDSP(UBitxTR* t) {
theTR = t;
}
UBitxRig* TS590Command::theRig = &Rig; UBitxRig* TS590Command::theRig = &Rig;
UBitxDSP* TS590Command::theDSP = &DSP; UBitxDSP* TS590Command::theDSP = &DSP;
UBitxTR* TR590Command::theTR = &TR;
TS590Error TS590Command::theError = NoError; TS590Error TS590Command::theError = NoError;
/**********************************************************************/ /**********************************************************************/
@ -238,19 +246,19 @@ void TS590_MD::handleCommand(const char* cmd) {
break; break;
case '1': // LSB case '1': // LSB
rig()->setLSB(); rig()->setModeLSB();
break; break;
case '2': // USB case '2': // USB
rig()->setUSB(); rig()->setModeUSB();
break; break;
case '3': // CW case '3': // CW
rig()->setCW(); rig()->setModeCW();
break; break;
case '7': // CW-R case '7': // CW-R
rig()->setCWR(); rig()->setModeCWR();
break; break;
default: default:
@ -319,6 +327,123 @@ void TS590_SL::sendResponse(const char* cmd) {
/**********************************************************************/ /**********************************************************************/
void TS590_TX::handleCommand(const char* cmd) {
if (strlen(cmd) == 3) {
switch (cmd[2]) {
case '0':
tr.catTX(MIC_SOURCE);
break;
case '1':
tr.catTX(rig.isUSBInput() ? USB_INPUT : LINE_INPUT);
break;
case '2':
// TODO: Need to implement w/ Teensy Audio Tool.
//tr.catTX();
break;
default:
setSyntaxError();
}
} else if (strlen(cmd) == 2) {
tr.catTX(MIC_SOURCE);
} else {
setSyntaxError();
}
}
void TS590_TX::sendResponse(const char* cmd) {
char src;
switch (tr.source()) {
case MIC_SOURCE:
src = '0';
break;
case LINE_SOURCE:
case USB_SOURCE:
src = '1';
break;
}
ts590SeondCommand("TX%1c", src);
}
/**********************************************************************/
/*!
* @brief Create a new CAT EX command. It should be initialized with
* a 3-character P1 parameter (command number).
* @param pre
* A 3-character command prefix. If more than 3 characters
* are supplied, only the first two will be used. If less
* than three are supplied, then the command will be
* initialized with a null prefix.
*/
TS590EXCommand::TS590EXCommand(const char* P1):
TS590Command("EX") {
if (strlen(P1) >= 3) {
strncpy(myMenu, P1, 3);
}
}
/*!
* @brief Determine whether this is a Read command or not. by
* default, if it's a 2-letter command, it's a Read.
* @return True if a Read command; false otherwise.
*/
bool TS590EXCommand::isReadCommand(const char* cmd) const {
if (strlen(cmd) == 9) {
return true;
} else {
return false;
}
}
void TS590EXCommand::sendResponse(const char* cmd) {
ts590sendCommand("%2c%3c0000%s", prefix(), menu(), getReturnValue());
}
/**********************************************************************/
void TS590_EX034::handleCommand(const char* cmd) {
if (strlen(cmd) == 10 || strlen(cmd) == 11) {
index = (uint8_t)atol(&cmd[9]);
if (index < 15) {
rig().setCWSidetone(300.0 + (float)(index * 50));
} else {
setSyntaxError();
}
} else {
setSyntaxError();
}
}
void TS590_EX034::sendResponse(const char* cmd) {
ts590SendCommand("EX0340000%02d", index % 15);
}
/**********************************************************************/
void TS590_EX063::handleCommand(const char* cmd) {
if (strlen(cmd) == 10) {
if (cmd[9] == '0') {
rig().setLineInput();
} else if (cmd[9] == '1') {
rig().setUSBInput();
} else {
setSyntaxError();
}
} else {
setSyntaxError();
}
}
void TS590_EX063::sendResponse(const char* cmd) {
ts590SendCommand("EX0630000%1c", rig().isUSBInput() ? '1' : '0');
}
/**********************************************************************/
TS590_FA cmdFA; TS590_FA cmdFA;
TS590_FB cmdFB; TS590_FB cmdFB;
TS590_FR cmdFR; TS590_FR cmdFR;
@ -393,8 +518,27 @@ int compareCATCommands(const void* a, const void* b) {
return cmp; return cmp;
} }
int compareCATEXCommands(const void* a, const void* b) {
TS590Command const *B = *(TS590Command const **)b;
int cmp = strncmp((char*)a, (char*)B->prefix(), 5);
#ifdef DEBUG
Serial.print("Comparison: ");
Serial.print((char*)a);
Serial.print(" ? ");
Serial.print((char*)B->prefix());
Serial.print(" --> ");
Serial.println(cmp);
#endif
return cmp;
}
void UBitxTS590::processCommand() { void UBitxTS590::processCommand() {
TS590Command** cmd = (TS590Command**)bsearch(buf, commands, numCommands, sizeof(TS590Command*), compareCATCommands); TS590Command** cmd;
if (strncmp(buf, "EX", 2) == 0) {
cmd = (TS590Command**)bsearch(buf, commands, numCommands, sizeof(TS590Command*), compareCATEXCommands);
} else {
cmd = (TS590Command**)bsearch(buf, commands, numCommands, sizeof(TS590Command*), compareCATCommands);
}
if (cmd == NULL) { if (cmd == NULL) {
ts590SyntaxError(); ts590SyntaxError();
} else { } else {

View File

@ -4,9 +4,13 @@
#include <Arduino.h> #include <Arduino.h>
#include "DSP.h" #include "DSP.h"
#include "Rig.h" #include "Rig.h"
#include "TR.h"
/**********************************************************************/ /**********************************************************************/
// uncomment to use TS-590SG / comment to use TS-590S
#define USE_TS590SG
#define TS590_COMMAND_MAX_LENGTH 50 // including terminator (which will get converted to null) #define TS590_COMMAND_MAX_LENGTH 50 // including terminator (which will get converted to null)
const int ts590CommandMaxLength = TS590_COMMAND_MAX_LENGTH; const int ts590CommandMaxLength = TS590_COMMAND_MAX_LENGTH;
@ -62,6 +66,11 @@ class TS590Command {
*/ */
inline UBitxDSP* dsp() const { return theDSP; } inline UBitxDSP* dsp() const { return theDSP; }
/*!
* @brief Return the T/R that this command will be used to control.
*/
inline UBitxDSP* tr() const { return theTR; }
/*! /*!
* @brief Handle the provided Set command. If the Set command * @brief Handle the provided Set command. If the Set command
* results in an error, then set the appropriate flag with * results in an error, then set the appropriate flag with
@ -88,6 +97,7 @@ class TS590Command {
static void setProcessError(); static void setProcessError();
static void setRig(UBitxRig* r); static void setRig(UBitxRig* r);
static void setDSP(UBitxDSP* d); static void setDSP(UBitxDSP* d);
static void setTR(UBitxTR* t);
private: private:
char myPrefix[3] = "\0\0"; char myPrefix[3] = "\0\0";
@ -192,6 +202,133 @@ class TS590_SL : public TS590Command {
unsigned index; unsigned index;
}; };
/*!
* @brief CAT command to start transmitting.
*/
class TS590_TX : public TS590Command {
public:
TS590_TX(): TS590Command("TX") {}
virtual void handleCommand(const char* cmd);
virtual void sendResponse(const char* cmd);
};
/**********************************************************************/
class TS590EXCommand : public TS590Command {
public:
TS590EXCommand(const char *P1);
virtual ~TS590EXCommand() = 0;
inline const char* menu() const { return &myMenu[0]; }
virtual const char* getReturnValue() const = 0;
virtual void sendResponse(const char* cmd);
private:
char myMenu[4] = "\0\0\0";
};
/**********************************************************************/
/*!
* @brief CAT command for setting the sidetone pitch/frequency.
*/
class TS590_EX034 : public TS590EXCommand {
public:
TS590_EX034(): TS590EXCommand("034") {}
virtual void handleCommand(const char* cmd);
virtual const char* getReturnValue();
private:
uint8_t index;
};
/*!
* @brief CAT command for selecting the data input line.
*/
class TS590_EX063 : public TS590EXCommand {
public:
TS590_EX063(): TS590EXCommand("063") {}
virtual void handleCommand(const char* cmd);
virtual const char* getReturnValue();
};
/**********************************************************************/
/*!
* @brief CAT command for setting USB/Line audio input levels.
*/
template<bool USB, bool SG>
class TS590_EXDataAudioInLevel : public TS590EXCommand {
public:
TS590_EXDataAudioInLevel(): TS590EXCommand(USB ? (SG ? "071" : "064") : (SG ? "073" : "066")) {}
virtual void handleCommand(const char* cmd) {
if (strlen(cmd) == 10) {
uint8_t val = (cmd[9] - 48) % 10;
if (USB) {
// set USB input level
} else {
// set Line input level
}
} else {
setSyntaxError();
}
}
virtual const char* getReturnValue() {
static char str[2] = "\0";
// get input level - decimal 0 to 9 ... str[1] = ...
return str;
}
};
#ifdef USE_TS590SG
typedef TS590_EXDataAudioInLevel<true, true> TS590_EX071;
typedef TS590_EXDataAudioInLevel<false, true> TS590_EX073;
#else
typedef TS590_EXDataAudioInLevel<true, false> TS590_EX064;
typedef TS590_EXDataAudioInLevel<true, false> TS590_EX066;
#endif
/**********************************************************************/
/*!
* @brief CAT command for setting USB/Line audio output levels.
*/
template<bool USB, bool SG>
class TS590_EXDataAudioOutLevel : public TS590EXCommand {
public:
TS590_EXDataAudioOutLevel(): TS590EXCommand(USB ? (SG ? "072" : "065") : (SG ? "074" : "067")) {}
virtual void handleCommand(const char* cmd) {
if (strlen(cmd) == 10) {
uint8_t val = (cmd[9] - 48) % 10;
if (USB) {
// set USB output level
} else {
// set Line output level
}
} else {
setSyntaxError();
}
}
virtual const char* getReturnValue() {
static char str[2] = "\0";
// get output level - decimal 0 to 9 ... str[1] = ...
return str;
}
};
#ifdef USE_TS590SG
typedef TS590_EXDataAudioOutLevel<true, true> TS590_EX072;
typedef TS590_EXDataAudioOutLevel<false, true> TS590_EX074;
#else
typedef TS590_EXDataAudioOutLevel<true, false> TS590_EX065;
typedef TS590_EXDataAudioOutLevel<true, false> TS590_EX067;
#endif
/**********************************************************************/ /**********************************************************************/
class UBitxTS590 { class UBitxTS590 {