2020-05-17 00:48:39 -04:00
|
|
|
//======================================================================
|
|
|
|
// 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,
|
2020-06-07 16:27:27 -04:00
|
|
|
IOP_DEBUG_MSG,
|
2020-05-17 00:48:39 -04:00
|
|
|
|
|
|
|
// Requests
|
|
|
|
IOP_MODE_REQUEST,
|
2020-05-18 09:16:54 -04:00
|
|
|
IOP_SSB_STATUS_MSG,
|
2020-05-26 00:08:55 -04:00
|
|
|
IOP_DGT_STATUS_MSG,
|
2020-05-17 00:48:39 -04:00
|
|
|
IOP_CW_STATUS_MSG,
|
2020-05-18 09:16:54 -04:00
|
|
|
IOP_TEST_STATUS_MSG,
|
2020-06-06 01:06:45 -04:00
|
|
|
IOP_MENU_DISPLAY_MSG,
|
2020-06-07 16:27:27 -04:00
|
|
|
IOP_MENU_INACTIVE_MSG,
|
2020-05-17 00:48:39 -04:00
|
|
|
|
|
|
|
// 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 {
|
2020-05-26 00:08:55 -04:00
|
|
|
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
|
2020-05-17 00:48:39 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Keyer modes.
|
|
|
|
*/
|
|
|
|
|
2020-05-18 09:16:54 -04:00
|
|
|
enum KeyerMode {
|
|
|
|
KEYER_MODE_STRAIGHT = 0,
|
|
|
|
KEYER_MODE_IAMBIC_A,
|
|
|
|
KEYER_MODE_IAMBIC_B,
|
|
|
|
//KEYER_ULTIMATIC,
|
|
|
|
//KEYER_BUG,
|
2020-05-17 00:48:39 -04:00
|
|
|
// add any new elements here
|
2020-05-18 09:16:54 -04:00
|
|
|
NUM_KEYER_MODES
|
2020-05-17 00:48:39 -04:00
|
|
|
};
|
|
|
|
|
2020-05-18 09:16:54 -04:00
|
|
|
enum RxFilter {
|
2020-05-26 00:08:55 -04:00
|
|
|
RX_FILTER_WIDE = 0,
|
|
|
|
RX_FILTER_MEDIUM,
|
2020-05-18 09:16:54 -04:00
|
|
|
RX_FILTER_NARROW,
|
|
|
|
NUM_RX_FILTERS
|
|
|
|
};
|
|
|
|
|
2020-05-26 00:08:55 -04:00
|
|
|
const unsigned char RIG_MODE_LETTER[NUM_RIG_MODES] = {'s', 'S', 'c', 'C', 'd', 'D', 't', 'T'};
|
2020-05-18 09:16:54 -04:00
|
|
|
const unsigned char KEYER_MODE_LETTER[NUM_KEYER_MODES] = {'S', 'A', 'B'};
|
2020-05-26 00:08:55 -04:00
|
|
|
const unsigned char RX_FILTER_LETTER[NUM_RX_FILTERS] = {'W', 'M', 'N'};
|
2020-05-17 00:48:39 -04:00
|
|
|
|
|
|
|
const uint8_t NO_FLAGS = 0;
|
|
|
|
const uint8_t REVERSED = 1;
|
|
|
|
|
|
|
|
struct IOPMessage {
|
2020-06-07 16:27:27 -04:00
|
|
|
IOPMessage() { memset(data, 0, IOP_MESSAGE_MAX_LEN); }
|
|
|
|
uint8_t id;
|
|
|
|
uint8_t len;
|
|
|
|
uint8_t data[IOP_MESSAGE_MAX_LEN];
|
2020-05-17 00:48:39 -04:00
|
|
|
};
|
|
|
|
|
2020-05-26 00:08:55 -04:00
|
|
|
//======================================================================
|
|
|
|
// IConfig
|
|
|
|
//
|
|
|
|
// Interface to a configuration object.
|
|
|
|
//======================================================================
|
|
|
|
|
|
|
|
class IConfig {
|
|
|
|
public:
|
|
|
|
virtual ~IConfig() {}
|
|
|
|
};
|
|
|
|
|
2020-05-18 09:16:54 -04:00
|
|
|
//======================================================================
|
|
|
|
// SSB CONFIGURATION
|
|
|
|
//======================================================================
|
2020-05-17 00:48:39 -04:00
|
|
|
|
2020-05-26 00:08:55 -04:00
|
|
|
class SSBConfig : public IConfig {
|
|
|
|
public:
|
|
|
|
SSBConfig(RxFilter f): filter(f) {}
|
2020-05-18 09:16:54 -04:00
|
|
|
// parameters
|
2020-06-11 00:23:15 -04:00
|
|
|
RxFilter filter = RX_FILTER_MEDIUM;
|
|
|
|
// bool comp_enable = false;
|
|
|
|
// float comp_threshold = 0.1;
|
|
|
|
// float comp_ratio = 20.0;
|
|
|
|
// float comp_gain = 2.0;
|
2020-05-18 09:16:54 -04:00
|
|
|
};
|
2020-05-17 00:48:39 -04:00
|
|
|
|
2020-05-18 09:16:54 -04:00
|
|
|
//======================================================================
|
2020-05-26 00:08:55 -04:00
|
|
|
// DGT CONFIGURATION
|
2020-05-18 09:16:54 -04:00
|
|
|
//======================================================================
|
|
|
|
|
2020-05-26 00:08:55 -04:00
|
|
|
class DGTConfig : public IConfig {
|
|
|
|
public:
|
|
|
|
DGTConfig(RxFilter f): filter(f) {}
|
2020-05-18 09:16:54 -04:00
|
|
|
// parameters
|
2020-05-26 00:08:55 -04:00
|
|
|
RxFilter filter = RX_FILTER_MEDIUM;
|
2020-05-18 09:16:54 -04:00
|
|
|
};
|
2020-05-17 00:48:39 -04:00
|
|
|
|
|
|
|
//======================================================================
|
|
|
|
// CW CONFIGURATION
|
|
|
|
//======================================================================
|
|
|
|
|
2020-05-26 00:08:55 -04:00
|
|
|
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) {}
|
2020-05-18 09:16:54 -04:00
|
|
|
// mode
|
|
|
|
KeyerMode mode = KEYER_MODE_IAMBIC_A;
|
|
|
|
// flags
|
|
|
|
bool reversed = false;
|
|
|
|
// parameters
|
|
|
|
uint8_t wpm = 15;
|
|
|
|
float weight = 3.0;
|
|
|
|
uint16_t sidetone = 700;
|
2020-05-26 00:08:55 -04:00
|
|
|
RxFilter filter = RX_FILTER_MEDIUM;
|
|
|
|
};
|
|
|
|
|
|
|
|
//======================================================================
|
|
|
|
// TT CONFIGURATION
|
|
|
|
//======================================================================
|
|
|
|
|
|
|
|
class TTConfig : public IConfig {
|
|
|
|
public:
|
|
|
|
TTConfig(RxFilter f): filter(f) {}
|
|
|
|
// parameters
|
2020-06-11 00:23:15 -04:00
|
|
|
RxFilter filter = RX_FILTER_MEDIUM;
|
2020-05-17 00:48:39 -04:00
|
|
|
};
|
|
|
|
|
2020-05-18 09:16:54 -04:00
|
|
|
//======================================================================
|
|
|
|
// 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();
|
2020-06-07 16:27:27 -04:00
|
|
|
void sendIOPDebugMessage(const char*);
|
2020-05-18 09:16:54 -04:00
|
|
|
|
|
|
|
void sendIOPModeRequest();
|
|
|
|
void sendIOPSSBStatus(SSBConfig const&);
|
2020-05-26 00:08:55 -04:00
|
|
|
void sendIOPDGTStatus(DGTConfig const&);
|
2020-05-18 09:16:54 -04:00
|
|
|
void sendIOPCWStatus(CWConfig const&);
|
|
|
|
void sendIOPTestStatus();
|
2020-06-07 16:27:27 -04:00
|
|
|
void sendIOPMenuDisplay(const char*);
|
|
|
|
void sendIOPMenuInactive();
|
2020-05-18 09:16:54 -04:00
|
|
|
|
2020-05-17 00:48:39 -04:00
|
|
|
//======================================================================
|
|
|
|
// 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
|
|
|
|
//======================================================================
|