ubitx-v5x/TeensyDSP/TS590.h
2021-03-19 15:30:30 -05:00

363 lines
9.4 KiB
C++

#ifndef __TS590_h__
#define __TS590_h__
#include <Arduino.h>
#include <Embedded_Template_Library.h>
#include <etl/delegate.h>
#include "DSP.h"
#include "Rig.h"
/**********************************************************************/
#define TS590_COMMAND_MAX_LENGTH 50 // including terminator (which will get converted to null)
const int ts590CommandMaxLength = TS590_COMMAND_MAX_LENGTH;
void ts590SendCommand(const char*, ...);
/*!
* @brief Send a syntax error response to the PC via CAT.
*/
inline void ts590SyntaxError() { ts590SendCommand("?"); }
/*!
* @brief Send a communications error response to the PC via CAT.
*/
inline void ts590CommError() { ts590SendCommand("E"); }
/*!
* @brief Send a processing error response to the PC via CAT.
*/
inline void ts590ProcessError() { ts590SendCommand("O"); }
enum TS590Error {
NoError,
SyntaxError,
CommError,
ProcessError
};
/**********************************************************************
**********************************************************************/
/*
class TS590BaseCommand {
public:
TS590BaseCommand(const char* prefix)
: myPrefix(prefix), prefixLength(strlen(prefix))
{}
virtual ~TS590BaseCommand() = 0;
inline const char* prefix() { return &myPrefix[0]; }
inline size_t length() { return prefixLength; }
virtual void handleCommand(const char* cmd) = 0;
virtual void sendResponse(const char* cmd) = 0;
virtual bool isReadCommand(const char* cmd) const;
inline void process(const char* cmd) {
theError = NoError;
if (isReadCommand(cmd)) {
DBGCMD( sendResponse(cmd) );
} else {
DBGCMD( handleCommand(cmd) );
switch(theError) {
case NoError:
if (theRig->isAI()) {
DBGCMD( sendResponse(cmd) );
}
break;
case SyntaxError:
DBGCMD( ts590SyntaxError() );
break;
case CommError:
DBGCMD( ts590CommError() );
break;
case ProcessError:
DBGCMD( ts590ProcessError() );
break;
}
}
}
private:
const char* myPrefix;
size_t prefixLength;
};
*/
typedef etl::delegate<bool(const char*)> ValidateFunc;
typedef etl::delegate<bool(const char*)> IsReadFunc;
typedef etl::delegate<void(bool)> ToggleFunc;
/*
class TS590ToggleCommand : public TS590BaseCommand {
TS590ToggleCommand(const char* prefix, ToggleFunc& setter, ToggleFunc& getter)
: TS590BaseCommand(prefix)
{}
private:
ToggleFunc& mySetter;
ToggleFunc& myGetter;
};
*/
/**********************************************************************/
/*!
* @brief A TS590S/SG "CAT" command. This is the base class for all
* CAT commands.
*/
class TS590Command {
public:
TS590Command(const char* pre);
virtual ~TS590Command();
/*!
* @brief Return the 2-character prefix for the command.
* @return The 2-character prefix for the command.
*/
inline const char* prefix() const { return &myPrefix[0]; }
inline size_t length() const { return prefixLength; }
/*!
* @brief Return the rig that this command will be used to control.
*/
inline UBitxRig* rig() const { return theRig; }
/*!
* @brief Return the DSP that this command will be used to control.
*/
inline UBitxDSP* dsp() const { return theDSP; }
/*!
* @brief Handle the provided Set command. If the Set command
* results in an error, then set the appropriate flag with
* setSyntaxError(), setCommError(), or setProcessError().
* @param cmd
* The current command string received from the PC via CAT.
* It should be null-terminated, and should no longer have
* the terminator (;).
*/
virtual void handleCommand(const char* cmd) = 0;
/*!
* @brief Send a response back to the PC. This assumes a
* successful command (no errors).
*/
virtual void sendResponse(const char* cmd) = 0;
virtual bool isReadCommand(const char* cmd) const;
void process(const char* cmd);
static void setSyntaxError();
static void setCommError();
static void setProcessError();
static void setRig(UBitxRig* r);
static void setDSP(UBitxDSP* d);
private:
const char* myPrefix;
size_t prefixLength;
static TS590Error theError;
static UBitxRig* theRig;
static UBitxDSP* theDSP;
};
/**********************************************************************/
typedef etl::delegate<void(bool)> SetBool;
typedef etl::delegate<bool(void)> GetBool;
class TS590Command_Bool : public TS590Command {
public:
TS590Command_Bool(const char* prefix, SetBool set, GetBool get)
: TS590Command(prefix), setter(set), getter(get) {}
virtual void handleCommand(const char* cmd);
virtual void sendResponse(const char* cmd);
private:
SetBool setter;
GetBool getter;
};
/**********************************************************************/
typedef etl::delegate<void(unsigned)> SetUL;
typedef etl::delegate<unsigned(void)> GetUL;
class TS590Command_UL : public TS590Command {
public:
TS590Command_UL(const char* prefix, size_t width, unsigned min, unsigned max, SetUL set, GetUL get)
: TS590Command(prefix), myWidth(width), myMin(min), myMax(max), mySlope(1), myIntercept(0), setter(set), getter(get) {}
TS590Command_UL(const char* prefix, size_t width, unsigned min, unsigned max, unsigned slope, unsigned intercept, SetUL set, GetUL get)
: TS590Command(prefix), myWidth(width), myMin(min), myMax(max), mySlope(slope), myIntercept(intercept), setter(set), getter(get) {}
virtual void handleCommand(const char* cmd);
virtual void sendResponse(const char* cmd);
private:
size_t myWidth;
unsigned myMin;
unsigned myMax;
unsigned mySlope;
unsigned myIntercept;
SetUL setter;
GetUL getter;
};
/**********************************************************************/
/*
typedef etl::delegate<void(bool)> SetULArray;
typedef etl::delegate<bool(void)> GetULArray;
class TS590Command_ULArray : public TS590Command {
public:
TS590Command_ULArray(const char* prefix, SetUL set, GetUL get)
: TS590Command(prefix), setter(set), getter(get) {}
virtual void handleCommand(const char* cmd);
virtual void sendResponse(const char* cmd);
private:
SetUL setter;
GetUL getter;
};
*/
/**********************************************************************/
/*!
* @brief CAT command for setting or reading the VFO A/B frequency.
*/
template<bool VFOA>
class TS590_FAB : public TS590Command {
public:
TS590_FAB(): TS590Command(VFOA ? "FA" : "FB") {}
virtual void handleCommand(const char* cmd) {
if (strlen(cmd) == 13) {
unsigned long freq = strtoul(&cmd[2], NULL, 10);
if (VFOA) {
rig()->setFreqA(freq);
} else {
rig()->setFreqB(freq);
}
} else {
setSyntaxError();
}
}
virtual void sendResponse(const char* cmd) {
ts590SendCommand(VFOA ? "FA%011u" : "FB%011u", VFOA ? rig()->getFreqA() : rig()->getFreqB());
}
};
typedef TS590_FAB<true> TS590_FA;
typedef TS590_FAB<false> TS590_FB;
/**********************************************************************/
/*!
* @brief CAT command for setting the receiver VFO. This will always
* disable split mode, if it was previously enabled.
*/
class TS590_FR : public TS590Command {
public:
TS590_FR(): TS590Command("FR") {}
virtual void handleCommand(const char* cmd);
virtual void sendResponse(const char* cmd);
};
/**********************************************************************/
/*!
* @brief CAT command for setting the transmitter VFO. If it is
* different than the receiver VFO, then split mode will be
* automatically enabled.
*/
class TS590_FT : public TS590Command {
public:
TS590_FT(): TS590Command("FT") {}
virtual void handleCommand(const char* cmd);
virtual void sendResponse(const char* cmd);
};
/**********************************************************************/
/*!
* @brief CAT command for setting the mode.
*/
class TS590_MD : public TS590Command {
public:
TS590_MD(): TS590Command("MD") {}
virtual void handleCommand(const char* cmd);
virtual void sendResponse(const char* cmd);
};
/**********************************************************************/
/*!
* @brief CAT command for setting the receiver high-cut frequency.
*/
class TS590_SH : public TS590Command {
public:
TS590_SH(): TS590Command("SH") {}
virtual void handleCommand(const char* cmd);
virtual void sendResponse(const char* cmd);
private:
unsigned index;
};
/*!
* @brief CAT command for setting the receiver low-cut frequency.
*/
class TS590_SL : public TS590Command {
public:
TS590_SL(): TS590Command("SL") {}
virtual void handleCommand(const char* cmd);
virtual void sendResponse(const char* cmd);
private:
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 {
public:
UBitxTS590(TS590Command** cmds, int len): commands(cmds), numCommands(len) {}
void begin();
void update();
private:
void processCommand();
char buf[ts590CommandMaxLength] = {0};
int bufLen = 0;
TS590Command** commands;
int numCommands;
};
extern UBitxTS590 TS590;
#endif
/**********************************************************************/