ubitx-iop/iopcomm/iopcomm.h

264 lines
6.3 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 struct rig_mode {
ssb = 0,
cw,
digi,
// add new items here
count
};
/* Keyer modes.
*/
enum struct keyer_mode {
straight = 0,
iambic_a,
iambic_b,
//ultimatic,
//bug,
// add any new items here
count
};
enum struct rx_filter {
wide = 0,
medium,
narrow,
count
};
enum struct digi_submode {
rtty = 0,
psk31,
user_defined,
count
};
//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.
//======================================================================
struct bpf_config {
float lo_freq;
float hi_freq;
float gain;
};
struct mode_config {
mode_config(bool usb, rx_filter f, const bpf_config *fc) : is_usb(usb), filter(f) {
for (int i = 0; i < static_cast<int>(rx_filter::count); i++) {
filter_cfg[i] = fc[i];
}
}
bool is_usb;
rx_filter filter;
bpf_config filter_cfg[static_cast<size_t>(rx_filter::count)];
};
//======================================================================
// SSB CONFIGURATION
//======================================================================
const bpf_config ssb_filter_config[] =
{bpf_config{ 300.0, 3100.0, 1.0},
bpf_config{ 500.0, 2900.0, 1.0},
bpf_config{ 700.0, 2500.0, 1.0}};
struct comp_config {
bool enabled = false;
float threshold = 0.1;
float ratio = 20.0;
float gain = 2.0;
};
struct ssb_config : public mode_config {
ssb_config() : mode_config(true, rx_filter::wide, ssb_filter_config) {}
comp_config comp;
};
//======================================================================
// DIGI CONFIGURATION
//======================================================================
const bpf_config digi_filter_config[] =
{bpf_config{ 300.0, 3100.0, 1.0},
bpf_config{ 500.0, 2900.0, 1.0},
bpf_config{1250.0, 1750.0, 1.0}};
struct digi_config : public mode_config {
digi_config() : mode_config(true, rx_filter::wide, digi_filter_config) {}
digi_submode submode = digi_submode::user_defined;
};
//======================================================================
// CW CONFIGURATION
//======================================================================
const bpf_config cw_filter_config[] =
{bpf_config{ 300.0, 1300.0, 1.0},
bpf_config{ 450.0, 950.0, 1.0},
bpf_config{ 575.0, 825.0, 1.0}};
struct cw_config : public mode_config {
cw_config() : mode_config(true, rx_filter::wide, cw_filter_config) {}
keyer_mode mode = keyer_mode::iambic_a;
// flags
bool reversed = false;
// parameters
uint8_t wpm = 15;
float weight = 3.0;
uint16_t sidetone = 700;
};
//======================================================================
// TT CONFIGURATION
//======================================================================
/*
struct 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(rig_mode);
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();
#endif
//======================================================================
// EOF
//======================================================================