//====================================================================== // iopcomm.h //====================================================================== #ifndef __iopcomm_h__ #define __iopcomm_h__ #include /* 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(rx_filter::count); i++) { filter_cfg[i] = fc[i]; } } bool is_usb; rx_filter filter; bpf_config filter_cfg[static_cast(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 //======================================================================