ubitx-v5d-xcvr/iopcomm/iopcomm.h
Rob French 66d1924685 Added speech compressor. Works.
Added some menu code.  But this needs to be redesigned.  Commented out.
Work this on a branch.
2020-06-10 23:23:15 -05:00

279 lines
6.6 KiB
C++

//======================================================================
// iopcomm.h
//======================================================================
#ifndef __iopcomm_h__
#define __iopcomm_h__
#include <stdint.h>
/* Message prefixes, starting with the ACK message (0). Message format
* consists of 1 or more bytes, where:
* b[0] - leftmost 3 bits == prefix
* - rightmost 5 bits == length of data (0-31)
* b[1]...b[31] (if present) - data bits
*/
enum PrefixID {
ACK = 0,
CAT_PREFIX,
IOP_PREFIX,
RAD_EEPROM_READ_PREFIX,
RAD_EEPROM_WRITE_PREFIX,
IOP_EEPROM_READ_PREFIX,
IOP_EEPROM_WRITE_PREFIX,
NUM_PREFIX_IDS
};
/* Masks for the leftmost 3 bits (prefix) and rightmost 5 bits (length)
* of a message.
*/
#define PREFIX_MASK 0xE0
#define LENGTH_MASK 0x1F
/* Convert a prefix and length to a byte, by shifting the prefix left
* 5 bits and OR-ing with the 5 bits of length.
*/
inline uint8_t prefixAndLengthToByte(PrefixID id, uint8_t len)
{
return (uint8_t(id) << 5) | (len & LENGTH_MASK);
}
/* Extract the prefix (leftmost 3 bits) from a byte.
*/
inline PrefixID byteToPrefix(uint8_t b)
{
return PrefixID(b >> 5);
}
/* Extract the length (rightmost 5 bits) from a byte.
*/
inline uint8_t byteToLength(byte b)
{
return uint8_t(b & LENGTH_MASK);
}
/* Message IDs/types, for IOP messages (messages between the Raduino and
* the IOP, not including CAT messages to be passed through).
*/
enum MessageID {
// Commands
IOP_MODE_COMMAND = 0,
IOP_START_TX_COMMAND,
IOP_STOP_TX_COMMAND,
IOP_CW_CONFIG_MSG,
IOP_DEBUG_MSG,
// Requests
IOP_MODE_REQUEST,
IOP_SSB_STATUS_MSG,
IOP_DGT_STATUS_MSG,
IOP_CW_STATUS_MSG,
IOP_TEST_STATUS_MSG,
IOP_MENU_DISPLAY_MSG,
IOP_MENU_INACTIVE_MSG,
// add any new elements here
NUM_MESSAGE_IDS
};
/* Max length of an IOP message payload (data), based on the following
* message format:
*
* byte 0: prefix (3 bits) + length (5 bits)
* byte 1: message ID (type)
* bytes 2-31: data bytes
*/
#define IOP_MESSAGE_MAX_LEN 30
/* Rig modes. Currently just defined as what the IOP cares about, but
* maybe these need to be expanded to encompass all of the rig modes.
* (e.g. USB, LSB, etc.)
*/
enum RigMode {
RIG_MODE_LSB = 0,
RIG_MODE_USB,
RIG_MODE_CWL,
RIG_MODE_CWU,
RIG_MODE_DGL,
RIG_MODE_DGU,
RIG_MODE_TTL,
RIG_MODE_TTU,
// add new items here
NUM_RIG_MODES
};
/* Keyer modes.
*/
enum KeyerMode {
KEYER_MODE_STRAIGHT = 0,
KEYER_MODE_IAMBIC_A,
KEYER_MODE_IAMBIC_B,
//KEYER_ULTIMATIC,
//KEYER_BUG,
// add any new elements here
NUM_KEYER_MODES
};
enum RxFilter {
RX_FILTER_WIDE = 0,
RX_FILTER_MEDIUM,
RX_FILTER_NARROW,
NUM_RX_FILTERS
};
const unsigned char RIG_MODE_LETTER[NUM_RIG_MODES] = {'s', 'S', 'c', 'C', 'd', 'D', 't', 'T'};
const unsigned char KEYER_MODE_LETTER[NUM_KEYER_MODES] = {'S', 'A', 'B'};
const unsigned char RX_FILTER_LETTER[NUM_RX_FILTERS] = {'W', 'M', 'N'};
const uint8_t NO_FLAGS = 0;
const uint8_t REVERSED = 1;
struct IOPMessage {
IOPMessage() { memset(data, 0, IOP_MESSAGE_MAX_LEN); }
uint8_t id;
uint8_t len;
uint8_t data[IOP_MESSAGE_MAX_LEN];
};
//======================================================================
// IConfig
//
// Interface to a configuration object.
//======================================================================
class IConfig {
public:
virtual ~IConfig() {}
};
//======================================================================
// SSB CONFIGURATION
//======================================================================
class SSBConfig : public IConfig {
public:
SSBConfig(RxFilter f): filter(f) {}
// parameters
RxFilter filter = RX_FILTER_MEDIUM;
// bool comp_enable = false;
// float comp_threshold = 0.1;
// float comp_ratio = 20.0;
// float comp_gain = 2.0;
};
//======================================================================
// DGT CONFIGURATION
//======================================================================
class DGTConfig : public IConfig {
public:
DGTConfig(RxFilter f): filter(f) {}
// parameters
RxFilter filter = RX_FILTER_MEDIUM;
};
//======================================================================
// CW CONFIGURATION
//======================================================================
class CWConfig : public IConfig {
public:
CWConfig(KeyerMode m, bool rev, uint8_t w, float wt, uint16_t st, RxFilter f):
mode(m), reversed(rev), wpm(w), weight(wt), sidetone(st), filter(f) {}
// mode
KeyerMode mode = KEYER_MODE_IAMBIC_A;
// flags
bool reversed = false;
// parameters
uint8_t wpm = 15;
float weight = 3.0;
uint16_t sidetone = 700;
RxFilter filter = RX_FILTER_MEDIUM;
};
//======================================================================
// TT CONFIGURATION
//======================================================================
class TTConfig : public IConfig {
public:
TTConfig(RxFilter f): filter(f) {}
// parameters
RxFilter filter = RX_FILTER_MEDIUM;
};
//======================================================================
// FUNCTION PROTOTYPES
//======================================================================
void sendCATMessage(const uint8_t*);
void sendIOPMessage(IOPMessage const&);
void recvIOPMessage(IOPMessage&, const uint8_t*, int);
void sendIOPModeCommand(RigMode);
void sendIOPStartTxCommand();
void sendIOPStopTxCommand();
void sendIOPDebugMessage(const char*);
void sendIOPModeRequest();
void sendIOPSSBStatus(SSBConfig const&);
void sendIOPDGTStatus(DGTConfig const&);
void sendIOPCWStatus(CWConfig const&);
void sendIOPTestStatus();
void sendIOPMenuDisplay(const char*);
void sendIOPMenuInactive();
//======================================================================
// TRANSLATOR
//======================================================================
/*
class Translator
{
public:
Translator(RigMode&, CWConfig&, Stream&);
void registerPrefixCb(PrefixID id, void (*func)(void*));
void registerMessageCb(MessageID id, void (*func)(void*));
void sendACK();
void sendIOPMessage(IOPMessage const&);
void receive();
void pack_ModeCommand(IOPMessage&, RigMode);
void pack_CWConfig(IOPMessage&, CWConfig const&);
void pack_ModeRequest(IOPMessage&);
void unpack(IOPMessage const&);
protected:
void unpack_ModeCommand(IOPMessage const&);
void unpack_CWConfig(IOPMessage const&);
void unpack_ModeRequest(IOPMessage const&);
private:
RigMode& mode;
CWConfig& cwConfig;
Stream& serial;
void (*prefixCb[NUM_PREFIX_IDS])(void*);
void (*messageCb[NUM_MESSAGE_IDS])(void*);
};
*/
#endif
//======================================================================
// EOF
//======================================================================