Updated to include iopcomm.h/iopcomm.cpp, common to both the IOP and the
Raduino. It was intended to be more extensive, but I had to roll some of it back. Mostly just sharing of enums/types currently. Currently in "factory calibration" mode. Comms (CAT) in normal mode needs to be re-checked. Added two tone test mode, with two new modes available via Raduino menu: TTL and TTU. Using test mode, I'm thinking that the proper TX output calibration, assuming a full-scale 700/1900 test tone, is either: 0.061 (which I believe gives a 25 mV RMS output), or ~0.100 (which is just before the audio starts to distort, in terms of visible harmonics in the spectrum at the 45 MHz IF.
This commit is contained in:
parent
e9d021835a
commit
ccae79925b
351
iopcomm/iopcomm.cpp
Normal file
351
iopcomm/iopcomm.cpp
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
//======================================================================
|
||||||
|
// iopcomm.cpp
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#include "iopcomm.h"
|
||||||
|
|
||||||
|
#if defined(TEENSYDUINO)
|
||||||
|
// Compiling for the Teensy, so assuming this is IOP code.
|
||||||
|
#define MYSERIAL Serial1
|
||||||
|
#else
|
||||||
|
// Not compiling for the Teensy, so assuming this is Raduino code.
|
||||||
|
#define MYSERIAL Serial
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
void sendIOPMessage(IOPMessage const& msg)
|
||||||
|
{
|
||||||
|
MYSERIAL.write(prefixAndLengthToByte(IOP_PREFIX, msg.len + 1));
|
||||||
|
MYSERIAL.write(msg.id);
|
||||||
|
for (int i = 0; i < msg.len; i++) {
|
||||||
|
MYSERIAL.write(msg.data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
void recvIOPMessage(IOPMessage& msg, const uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
msg.id = buf[0];
|
||||||
|
msg.len = len - 1;
|
||||||
|
for (int i = 1; i < len; i++) {
|
||||||
|
msg.data[i-1] = buf[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
void sendIOPModeCommand(RigMode mode)
|
||||||
|
{
|
||||||
|
IOPMessage m;
|
||||||
|
m.id = IOP_MODE_COMMAND;
|
||||||
|
m.len = 1;
|
||||||
|
m.data[0] = uint8_t(mode);
|
||||||
|
sendIOPMessage(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
void sendIOPStartTxCommand()
|
||||||
|
{
|
||||||
|
IOPMessage m;
|
||||||
|
m.id = IOP_START_TX_COMMAND;
|
||||||
|
m.len = 0;
|
||||||
|
sendIOPMessage(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
void sendIOPStopTxCommand()
|
||||||
|
{
|
||||||
|
IOPMessage m;
|
||||||
|
m.id = IOP_STOP_TX_COMMAND;
|
||||||
|
m.len = 0;
|
||||||
|
sendIOPMessage(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
void sendIOPModeRequest()
|
||||||
|
{
|
||||||
|
IOPMessage m;
|
||||||
|
m.id = IOP_MODE_REQUEST;
|
||||||
|
m.len = 0;
|
||||||
|
sendIOPMessage(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
/*
|
||||||
|
enum SerialState {
|
||||||
|
NORMAL = 0,
|
||||||
|
CAT_MODE,
|
||||||
|
IOP_MODE,
|
||||||
|
EEPROM_READ,
|
||||||
|
EEPROM_WRITE,
|
||||||
|
};
|
||||||
|
|
||||||
|
Translator::Translator(RigMode& m, CWConfig& c, Stream& s = SERIAL):
|
||||||
|
mode(m), cwConfig(c), serial(s)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_PREFIX_IDS; i++) {
|
||||||
|
prefixCb[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_MESSAGE_IDS; i++) {
|
||||||
|
messageCb[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::sendACK()
|
||||||
|
{
|
||||||
|
serial.write(prefixAndLengthToByte(ACK, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::sendCATMessage(byte b, bool continued=false)
|
||||||
|
{
|
||||||
|
if (!continued) { // we're starting a CAT transmission sequence
|
||||||
|
|
||||||
|
} else { // we're continuing a CAT transmission sequence
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::sendIOPMessage(IOPMessage const& m)
|
||||||
|
{
|
||||||
|
serial.write(prefixAndLengthToByte(IOP_PREFIX, m.len+1));
|
||||||
|
serial.write(m.id);
|
||||||
|
for (int i = 0; i < m.len; i++) {
|
||||||
|
serial.write(m.data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Translator::receive()
|
||||||
|
{
|
||||||
|
static SerialState state;
|
||||||
|
|
||||||
|
static PrefixID readPrefix = 0;
|
||||||
|
static uint8_t readLength = 0;
|
||||||
|
|
||||||
|
static IOPMessage iopMsg;
|
||||||
|
|
||||||
|
static uint8_t cmdLength = 0;
|
||||||
|
static byte cmdBuffer[16];
|
||||||
|
static char cmdString[17]; // added a char for null termination when required
|
||||||
|
|
||||||
|
static uint16_t eepromStartIndex;
|
||||||
|
static uint16_t eepromReadLength;
|
||||||
|
static int eepromMagicFlag = 0;
|
||||||
|
|
||||||
|
int incomingByte;
|
||||||
|
|
||||||
|
for (int i = 0; i < serial.available(); i++) {
|
||||||
|
incomingByte = serial.read();
|
||||||
|
|
||||||
|
switch(state) {
|
||||||
|
case NORMAL:
|
||||||
|
if (incomingByte == ACK) {
|
||||||
|
prefixCb[ACK](NULL);
|
||||||
|
} else {
|
||||||
|
readPrefix = byteToPrefix(incomingbyte);
|
||||||
|
readLength = byteToLength(incomingbyte);
|
||||||
|
if (readLength > 0) {
|
||||||
|
switch(readPrefix) {
|
||||||
|
case CAT_PREFIX:
|
||||||
|
case RAD_EEPROM_WRITE_PREFIX:
|
||||||
|
state = CAT_MODE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOP_PREFIX:
|
||||||
|
state = IOP_MODE;
|
||||||
|
iopMsg.len = readLength - 1;
|
||||||
|
cmdLength = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RAD_EEPROM_READ_PREFIX:
|
||||||
|
state = EEPROM_READ;
|
||||||
|
readLength = 5;
|
||||||
|
eepromMagicFlag = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// should never happen
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CAT_MODE:
|
||||||
|
// In CAT mode, we just pass thru the remaining bytes to the PC.
|
||||||
|
if
|
||||||
|
USBSERIAL.write(incomingByte);
|
||||||
|
readLength--;
|
||||||
|
if (readLength == 0) {
|
||||||
|
state = NORMAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOP_MODE:
|
||||||
|
cmdBuffer[cmdLength] = incomingByte;
|
||||||
|
cmdLength++;
|
||||||
|
readLength--;
|
||||||
|
if (readLength == 0) {
|
||||||
|
processIOPCommand(cmdBuffer, cmdLength);
|
||||||
|
state = NORMAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EEPROM_READ:
|
||||||
|
readLength--;
|
||||||
|
switch(readLength) {
|
||||||
|
case 4:
|
||||||
|
eepromStartIndex = incomingByte;
|
||||||
|
if (incomingByte == 0x16) {
|
||||||
|
magicFlag++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
eepromStartIndex += (256 * incomingByte);
|
||||||
|
if (incomingByte == 0xe8) {
|
||||||
|
magicFlag++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
eepromReadLength = incomingByte;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
eepromReadLength += (256 * incomingByte);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
USBSERIAL.write(incomingByte);
|
||||||
|
if (magicFlag == 2) {
|
||||||
|
readLength = 126 + 2;
|
||||||
|
} else {
|
||||||
|
readLength = eepromReadLength + 2;
|
||||||
|
}
|
||||||
|
state = CAT_MODE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// should never happen
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EEPROM_WRITE:
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// should never happen...
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::registerPrefixCb(PrefixID id, void (*func)(void*))
|
||||||
|
{
|
||||||
|
if (id >= 0 && id < NUM_PREFIX_IDS) {
|
||||||
|
prefixCb[id] = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::registerMessageCb(MessageID id, void (*func)(void*))
|
||||||
|
{
|
||||||
|
if (id >= 0 && id < NUM_MESSAGE_IDS) {
|
||||||
|
messageCb[id] = func;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::pack_ModeCommand(IOPMessage& m, RigMode r)
|
||||||
|
{
|
||||||
|
m.id = IOP_MODE_COMMAND;
|
||||||
|
m.len = 1;
|
||||||
|
m.data[0] = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::unpack_ModeCommand(IOPMessage const& m)
|
||||||
|
{
|
||||||
|
*mode = RigMode(m.data[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::pack_CWConfig(IOPMessage &m, CWConfig const& c)
|
||||||
|
{
|
||||||
|
m.id = IOP_CW_CONFIG_MSG;
|
||||||
|
m.len = 6;
|
||||||
|
// mode
|
||||||
|
m.data[0] = byte(c.mode);
|
||||||
|
// flags
|
||||||
|
m.data[1] = NO_FLAGS;
|
||||||
|
m.data[1] |= (c.reversed ? REVERSED : 0);
|
||||||
|
// parameters
|
||||||
|
m.data[2] = byte(c.wpm);
|
||||||
|
m.data[3] = byte(c.weight * 10.0);
|
||||||
|
m.data[4] = byte(c.sidetone >> 8);
|
||||||
|
m.data[5] = byte(c.sidetone | 0x0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::unpack_CWConfig(IOPMessage const &m)
|
||||||
|
{
|
||||||
|
//if (m.id != IOP_CW_CONFIG_MSG || m.len != 6) {
|
||||||
|
// // do some error thing...
|
||||||
|
//}
|
||||||
|
//mode
|
||||||
|
cwConfig->mode = KeyMode(m.data[0]);
|
||||||
|
// flags
|
||||||
|
cwConfig->reversed = bool(m.data[1] & REVERSED);
|
||||||
|
// parameters
|
||||||
|
cwConfig->wpm = uint8_t(m.data[2]);
|
||||||
|
cwConfig->weight = float(m.data[3]) / 10.0;
|
||||||
|
cwConfig->sidetone = (m.data[4] << 8) | m.data[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::pack_ModeRequest(IOPMessage& m)
|
||||||
|
{
|
||||||
|
m.id = IOP_MODE_REQUEST;
|
||||||
|
m.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::unpack_ModeRequest(IOPMessage const& m)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::unpack(IOPMessage const& m)
|
||||||
|
{
|
||||||
|
switch (m.id) {
|
||||||
|
case IOP_MODE_COMMAND:
|
||||||
|
unpack_ModeCommand(m);
|
||||||
|
messageCb[m.id](mode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOP_START_TX_COMMAND:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOP_STOP_TX_COMMAND:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOP_CW_CONFIG_MSG:
|
||||||
|
unpack_CWConfig(m);
|
||||||
|
messageCb[m.id](cwConfig);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOP_MODE_REQUEST:
|
||||||
|
unpack_ModeRequest(m);
|
||||||
|
messageCb[m.id](NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOP_CW_STATUS_MSG:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//======================================================================
|
||||||
|
// EOF
|
||||||
|
//======================================================================
|
211
iopcomm/iopcomm.h
Normal file
211
iopcomm/iopcomm.h
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
//======================================================================
|
||||||
|
// 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,
|
||||||
|
|
||||||
|
// Requests
|
||||||
|
IOP_MODE_REQUEST,
|
||||||
|
IOP_CW_STATUS_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 {
|
||||||
|
MODE_SSB = 0,
|
||||||
|
MODE_DIGI,
|
||||||
|
MODE_CW,
|
||||||
|
MODE_TEST,
|
||||||
|
// add any new elements here
|
||||||
|
NUM_RIG_MODES
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Keyer modes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum KeyMode {
|
||||||
|
STRAIGHT = 0,
|
||||||
|
IAMBIC_A,
|
||||||
|
IAMBIC_B,
|
||||||
|
//ULTIMATIC,
|
||||||
|
//BUG,
|
||||||
|
// add any new elements here
|
||||||
|
NUM_KEY_MODES
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned char MODE_LETTER[3] = {'S', 'A', 'B'};
|
||||||
|
|
||||||
|
const uint8_t NO_FLAGS = 0;
|
||||||
|
const uint8_t REVERSED = 1;
|
||||||
|
|
||||||
|
struct IOPMessage {
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t len;
|
||||||
|
uint8_t data[IOP_MESSAGE_MAX_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void sendIOPMessage(IOPMessage const&);
|
||||||
|
void recvIOPMessage(IOPMessage&, const uint8_t*, int);
|
||||||
|
|
||||||
|
void sendIOPModeCommand(RigMode);
|
||||||
|
void sendIOPStartTxCommand();
|
||||||
|
void sendIOPStopTxCommand();
|
||||||
|
void sendIOPModeRequest();
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
// CW CONFIGURATION
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
struct CWConfig {
|
||||||
|
// mode
|
||||||
|
KeyMode mode = IAMBIC_A;
|
||||||
|
// flags
|
||||||
|
bool reversed = false;
|
||||||
|
// parameters
|
||||||
|
uint8_t wpm = 15;
|
||||||
|
float weight = 3.0;
|
||||||
|
uint16_t sidetone = 700;
|
||||||
|
};
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
// 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*);
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
// CW STATUS MESSAGE
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
//void packT_DisplayText(TMessage &m, CWConfig const &c)
|
||||||
|
//{
|
||||||
|
// m.id = IOP_CW_STATUS_MSG;
|
||||||
|
// m.len = 3;
|
||||||
|
// m.data[0] = ' '; // growth
|
||||||
|
// m.data[1] = MODE_LETTER[c.mode];
|
||||||
|
// m.data[2] = ' '; // TODO: RX filter width
|
||||||
|
//}
|
||||||
|
|
||||||
|
// No unpack required: this is a string to put on the display.
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
// EOF
|
||||||
|
//======================================================================
|
@ -22,6 +22,7 @@ enum TxInput {
|
|||||||
TX_MIC_IN = -1,
|
TX_MIC_IN = -1,
|
||||||
TX_LINE_IN = 0,
|
TX_LINE_IN = 0,
|
||||||
TX_USB_IN = 1,
|
TX_USB_IN = 1,
|
||||||
|
TX_TEST_IN = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TxOutput {
|
enum TxOutput {
|
||||||
|
@ -16,43 +16,49 @@ extern IOPConfig iopConfig;
|
|||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include <SD.h>
|
#include <SD.h>
|
||||||
#include <SerialFlash.h>
|
#include <SerialFlash.h>
|
||||||
|
|
||||||
// GUItool: begin automatically generated code
|
// GUItool: begin automatically generated code
|
||||||
AudioInputI2S inLine; //xy=224,194
|
AudioSynthWaveformSine sideTone; //xy=204,221
|
||||||
AudioInputUSB inUSB; //xy=224,303
|
AudioInputI2S inLine; //xy=208,170
|
||||||
AudioAnalyzeRMS rmsRX; //xy=399,71
|
AudioSynthWaveformSine sine2; //xy=207,423
|
||||||
AudioAnalyzePeak peakRX; //xy=403,122
|
AudioInputUSB inUSB; //xy=208,279
|
||||||
AudioMixer4 mixRX; //xy=460,187
|
AudioSynthWaveformSine sine1; //xy=208,382
|
||||||
AudioMixer4 mixTX; //xy=460,303
|
AudioAnalyzeRMS rmsRX; //xy=383,47
|
||||||
AudioAmplifier calRxUSB; //xy=650,189
|
AudioAnalyzePeak peakRX; //xy=387,98
|
||||||
AudioAmplifier calRxSpkr; //xy=654,79
|
AudioMixer4 mixRX; //xy=444,163
|
||||||
AudioAmplifier calRxLine; //xy=657,136
|
AudioMixer4 mixTX; //xy=444,279
|
||||||
AudioAmplifier calTxLine; //xy=669,272
|
AudioAmplifier calRxUSB; //xy=634,165
|
||||||
AudioAmplifier calTxUSB; //xy=670,329
|
AudioAmplifier calRxSpkr; //xy=638,55
|
||||||
AudioAnalyzePeak peakTX; //xy=685,402
|
AudioAmplifier calRxLine; //xy=641,112
|
||||||
AudioAnalyzeRMS rmsTX; //xy=699,457
|
AudioAmplifier calTxLine; //xy=653,248
|
||||||
AudioOutputAnalog outSpkr; //xy=830,79
|
AudioAmplifier calTxUSB; //xy=654,305
|
||||||
AudioOutputUSB outUSB; //xy=839,279
|
AudioAnalyzePeak peakTX; //xy=669,378
|
||||||
AudioOutputI2S outLine; //xy=842,228
|
AudioAnalyzeRMS rmsTX; //xy=683,433
|
||||||
AudioConnection patchCord1(inLine, 0, rmsRX, 0);
|
AudioOutputAnalog outSpkr; //xy=814,55
|
||||||
AudioConnection patchCord2(inLine, 0, peakRX, 0);
|
AudioOutputUSB outUSB; //xy=823,255
|
||||||
AudioConnection patchCord3(inLine, 0, mixRX, 0);
|
AudioOutputI2S outLine; //xy=826,204
|
||||||
AudioConnection patchCord4(inLine, 1, mixTX, 0);
|
AudioConnection patchCord1(sideTone, 0, mixRX, 2);
|
||||||
AudioConnection patchCord5(inUSB, 0, mixRX, 1);
|
AudioConnection patchCord2(inLine, 0, rmsRX, 0);
|
||||||
AudioConnection patchCord6(inUSB, 1, mixTX, 1);
|
AudioConnection patchCord3(inLine, 0, peakRX, 0);
|
||||||
AudioConnection patchCord7(mixRX, calRxSpkr);
|
AudioConnection patchCord4(inLine, 0, mixRX, 0);
|
||||||
AudioConnection patchCord8(mixRX, calRxLine);
|
AudioConnection patchCord5(inLine, 1, mixTX, 0);
|
||||||
AudioConnection patchCord9(mixRX, calRxUSB);
|
AudioConnection patchCord6(sine2, 0, mixTX, 3);
|
||||||
AudioConnection patchCord10(mixTX, calTxLine);
|
AudioConnection patchCord7(inUSB, 0, mixRX, 1);
|
||||||
AudioConnection patchCord11(mixTX, calTxUSB);
|
AudioConnection patchCord8(inUSB, 1, mixTX, 1);
|
||||||
AudioConnection patchCord12(mixTX, peakTX);
|
AudioConnection patchCord9(sine1, 0, mixTX, 2);
|
||||||
AudioConnection patchCord13(mixTX, rmsTX);
|
AudioConnection patchCord10(mixRX, calRxSpkr);
|
||||||
AudioConnection patchCord14(calRxUSB, 0, outUSB, 0);
|
AudioConnection patchCord11(mixRX, calRxLine);
|
||||||
AudioConnection patchCord15(calRxSpkr, outSpkr);
|
AudioConnection patchCord12(mixRX, calRxUSB);
|
||||||
AudioConnection patchCord16(calRxLine, 0, outLine, 0);
|
AudioConnection patchCord13(mixTX, calTxLine);
|
||||||
AudioConnection patchCord17(calTxLine, 0, outLine, 1);
|
AudioConnection patchCord14(mixTX, calTxUSB);
|
||||||
AudioConnection patchCord18(calTxUSB, 0, outUSB, 1);
|
AudioConnection patchCord15(mixTX, peakTX);
|
||||||
AudioControlSGTL5000 audioCtrl; //xy=407,467
|
AudioConnection patchCord16(mixTX, rmsTX);
|
||||||
|
AudioConnection patchCord17(calRxUSB, 0, outUSB, 0);
|
||||||
|
AudioConnection patchCord18(calRxSpkr, outSpkr);
|
||||||
|
AudioConnection patchCord19(calRxLine, 0, outLine, 0);
|
||||||
|
AudioConnection patchCord20(calTxLine, 0, outLine, 1);
|
||||||
|
AudioConnection patchCord21(calTxUSB, 0, outUSB, 1);
|
||||||
|
AudioControlSGTL5000 audioCtrl; //xy=391,443
|
||||||
// GUItool: end automatically generated code
|
// GUItool: end automatically generated code
|
||||||
|
|
||||||
RxInput audioRxInput;
|
RxInput audioRxInput;
|
||||||
@ -75,11 +81,30 @@ void audioInit()
|
|||||||
//audioCtrl.dacVolumeRamp(); // if this seems too slow, might try dacVolumeRampLinear().
|
//audioCtrl.dacVolumeRamp(); // if this seems too slow, might try dacVolumeRampLinear().
|
||||||
//audioCtrl.dacVolume(1.0, 0.0); // we're going to mute TX audio via the DAC unless we're transmitting
|
//audioCtrl.dacVolume(1.0, 0.0); // we're going to mute TX audio via the DAC unless we're transmitting
|
||||||
|
|
||||||
|
updateRxRigIn();
|
||||||
|
updateRxSpkrOut();
|
||||||
|
updateRxLineOut();
|
||||||
|
updateRxUSBOut();
|
||||||
|
|
||||||
|
// Note - these really just need to be init functions; keep things muted while setting them up.
|
||||||
|
updateTxMicIn();
|
||||||
|
updateTxLineIn();
|
||||||
|
updateTxUSBIn();
|
||||||
|
updateTxTwoToneIn();
|
||||||
|
|
||||||
|
updateTxRigOut();
|
||||||
|
|
||||||
audioSelectRxInput(RX_RIG_IN);
|
audioSelectRxInput(RX_RIG_IN);
|
||||||
audioSelectTxInput(TX_MIC_IN); // superfluous I think
|
audioSelectTxInput(TX_MIC_IN); // superfluous I think
|
||||||
|
|
||||||
//audioCtrl.adcHighPassFilterDisable();
|
//audioCtrl.adcHighPassFilterDisable();
|
||||||
audioCtrl.audioPreProcessorEnable();
|
audioCtrl.audioPreProcessorEnable();
|
||||||
|
|
||||||
|
// setup the two-tone generator
|
||||||
|
sine1.frequency(700);
|
||||||
|
sine2.frequency(1900);
|
||||||
|
sine1.amplitude(0);
|
||||||
|
sine2.amplitude(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void updateRxRigIn()
|
inline void updateRxRigIn()
|
||||||
@ -180,6 +205,30 @@ inline void restoreTxUSBIn()
|
|||||||
mixTX.gain(TX_USB_IN, iopConfig.txUSBInVol * iopConfig.txUSBInCal);
|
mixTX.gain(TX_USB_IN, iopConfig.txUSBInVol * iopConfig.txUSBInCal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void updateTxTwoToneIn()
|
||||||
|
{
|
||||||
|
sine1.amplitude(0.5);
|
||||||
|
sine2.amplitude(0.5);
|
||||||
|
mixTX.gain(TX_TEST_IN, iopConfig.txSine1Vol);
|
||||||
|
mixTX.gain(TX_TEST_IN + 1, iopConfig.txSine2Vol);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void muteTxTwoToneIn()
|
||||||
|
{
|
||||||
|
mixTX.gain(TX_TEST_IN, 0.0);
|
||||||
|
mixTX.gain(TX_TEST_IN + 1, 0.0);
|
||||||
|
sine1.amplitude(0);
|
||||||
|
sine2.amplitude(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void restoreTxTwoToneIn()
|
||||||
|
{
|
||||||
|
sine1.amplitude(0.5);
|
||||||
|
sine2.amplitude(0.5);
|
||||||
|
mixTX.gain(TX_TEST_IN, iopConfig.txSine1Vol);
|
||||||
|
mixTX.gain(TX_TEST_IN + 1, iopConfig.txSine2Vol);
|
||||||
|
}
|
||||||
|
|
||||||
inline void updateTxRigOut()
|
inline void updateTxRigOut()
|
||||||
{
|
{
|
||||||
calTxLine.gain(iopConfig.txRigOutCal);
|
calTxLine.gain(iopConfig.txRigOutCal);
|
||||||
@ -224,8 +273,7 @@ void audioSelectTxInput(TxInput input)
|
|||||||
//muteTxMicIn(); // redundant w/ Line-In
|
//muteTxMicIn(); // redundant w/ Line-In
|
||||||
muteTxLineIn();
|
muteTxLineIn();
|
||||||
muteTxUSBIn();
|
muteTxUSBIn();
|
||||||
mixTX.gain(2, 0);
|
muteTxTwoToneIn();
|
||||||
mixTX.gain(3, 0);
|
|
||||||
/* switch(input) {
|
/* switch(input) {
|
||||||
case TX_MIC_IN:
|
case TX_MIC_IN:
|
||||||
muteTxUSBIn();
|
muteTxUSBIn();
|
||||||
@ -293,6 +341,11 @@ void audioTransmit()
|
|||||||
muteRxRigIn();
|
muteRxRigIn();
|
||||||
updateTxUSBIn();
|
updateTxUSBIn();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MODE_TEST:
|
||||||
|
muteRxRigIn();
|
||||||
|
updateTxTwoToneIn();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,6 +376,11 @@ void audioReceive()
|
|||||||
muteTxUSBIn();
|
muteTxUSBIn();
|
||||||
restoreRxRigIn();
|
restoreRxRigIn();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MODE_TEST:
|
||||||
|
muteTxTwoToneIn();
|
||||||
|
restoreRxRigIn();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
128
ubitx_iop/cat.h
128
ubitx_iop/cat.h
@ -5,134 +5,18 @@
|
|||||||
#ifndef __iop_cat_h__
|
#ifndef __iop_cat_h__
|
||||||
#define __iop_cat_h__
|
#define __iop_cat_h__
|
||||||
|
|
||||||
#define ACK 0
|
//#define ACK 0
|
||||||
#define CAT_PREFIX 0xC0
|
//#define CAT_PREFIX 0xC0
|
||||||
#define IOP_PREFIX 0xD0
|
//#define IOP_PREFIX 0xD0
|
||||||
#define EEPROM_READ_PREFIX 0xE0
|
//#define EEPROM_READ_PREFIX 0xE0
|
||||||
#define EEPROM_WRITE_PREFIX 0xF0
|
//#define EEPROM_WRITE_PREFIX 0xF0
|
||||||
|
|
||||||
#define IOP_MODE_COMMAND 0x00
|
|
||||||
#define IOP_START_TX_COMMAND 0x01
|
|
||||||
#define IOP_STOP_TX_COMMAND 0x02
|
|
||||||
#define IOP_CW_CONFIG_MSG 0x03
|
|
||||||
|
|
||||||
#define IOP_MODE_REQUEST 0x00
|
|
||||||
#define IOP_CW_STATUS_MSG 0x03
|
|
||||||
|
|
||||||
#define IOP_MODE_SSB 0x00
|
|
||||||
#define IOP_MODE_DIGI 0x01
|
|
||||||
#define IOP_MODE_CW 0x02
|
|
||||||
|
|
||||||
|
#include <iopcomm.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#define USBSERIAL Serial
|
#define USBSERIAL Serial
|
||||||
#define HWSERIAL Serial1
|
#define HWSERIAL Serial1
|
||||||
|
|
||||||
/*struct IOPTMsg {
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum KeyMode {
|
|
||||||
STRAIGHT = 0,
|
|
||||||
IAMBIC_A,
|
|
||||||
IAMBIC_B,
|
|
||||||
//ULTIMATIC,
|
|
||||||
//BUG,
|
|
||||||
};
|
|
||||||
|
|
||||||
const byte MODE_LETTER[3] = {'S', 'A', 'B'};
|
|
||||||
|
|
||||||
const byte NO_FLAGS = 0;
|
|
||||||
const byte REVERSED = 1;
|
|
||||||
|
|
||||||
#define R_MESSAGE_MAX_LEN 32
|
|
||||||
#define T_MESSAGE_MAX_LEN 32
|
|
||||||
|
|
||||||
struct RMessage {
|
|
||||||
uint8_t id;
|
|
||||||
uint8_t len;
|
|
||||||
byte data[R_MESSAGE_MAX_LEN];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TMessage {
|
|
||||||
uint8_t id;
|
|
||||||
uint8_t len;
|
|
||||||
byte data[T_MESSAGE_MAX_LEN];
|
|
||||||
};
|
|
||||||
|
|
||||||
//======================================================================
|
|
||||||
// CW CONFIGURATION MESSAGE
|
|
||||||
//======================================================================
|
|
||||||
|
|
||||||
struct CWConfig {
|
|
||||||
// mode
|
|
||||||
KeyMode mode = IAMBIC_A;
|
|
||||||
// flags
|
|
||||||
bool reversed = false;
|
|
||||||
// parameters
|
|
||||||
uint8_t wpm = 15;
|
|
||||||
float weight = 3.0;
|
|
||||||
uint16_t sidetone = 700;
|
|
||||||
};
|
|
||||||
|
|
||||||
void packR_CWConfig(RMessage &m, CWConfig const &c)
|
|
||||||
{
|
|
||||||
m.id = IOP_CW_CONFIG_MSG;
|
|
||||||
m.len = 6;
|
|
||||||
// mode
|
|
||||||
m.data[0] = byte(c.mode);
|
|
||||||
// flags
|
|
||||||
m.data[1] = NO_FLAGS;
|
|
||||||
m.data[1] |= (c.reversed ? REVERSED : 0);
|
|
||||||
// parameters
|
|
||||||
m.data[2] = byte(c.wpm);
|
|
||||||
m.data[3] = byte(c.weight * 10.0);
|
|
||||||
m.data[4] = byte(c.sidetone >> 8);
|
|
||||||
m.data[5] = byte(c.sidetone | 0x0F);
|
|
||||||
}
|
|
||||||
|
|
||||||
void unpackR_CWConfig(CWConfig &c, RMessage const &m)
|
|
||||||
{
|
|
||||||
//if (m.id != IOP_CW_CONFIG_MSG || m.len != 6) {
|
|
||||||
// // do some error thing...
|
|
||||||
//}
|
|
||||||
//mode
|
|
||||||
c.mode = KeyMode(m.data[0]);
|
|
||||||
// flags
|
|
||||||
c.reversed = bool(m.data[1] & REVERSED);
|
|
||||||
// parameters
|
|
||||||
c.wpm = uint8_t(m.data[2]);
|
|
||||||
c.weight = float(m.data[3]) / 10.0;
|
|
||||||
c.sidetone = (m.data[4] << 8) | m.data[5];
|
|
||||||
}
|
|
||||||
|
|
||||||
//======================================================================
|
|
||||||
// MODE REQUEST MESSAGE
|
|
||||||
//======================================================================
|
|
||||||
|
|
||||||
void packT_ModeRequest(TMessage &m)
|
|
||||||
{
|
|
||||||
m.id = IOP_MODE_REQUEST;
|
|
||||||
m.len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//======================================================================
|
|
||||||
// CW STATUS MESSAGE
|
|
||||||
//======================================================================
|
|
||||||
|
|
||||||
//void packT_DisplayText(TMessage &m, CWConfig const &c)
|
|
||||||
//{
|
|
||||||
// m.id = IOP_CW_STATUS_MSG;
|
|
||||||
// m.len = 3;
|
|
||||||
// m.data[0] = ' '; // growth
|
|
||||||
// m.data[1] = MODE_LETTER[c.mode];
|
|
||||||
// m.data[2] = ' '; // TODO: RX filter width
|
|
||||||
//}
|
|
||||||
|
|
||||||
// No unpack required: this is a string to put on the display.
|
|
||||||
|
|
||||||
//======================================================================
|
|
||||||
|
|
||||||
void initCAT(long, int);
|
void initCAT(long, int);
|
||||||
void serviceCAT();
|
void serviceCAT();
|
||||||
|
|
||||||
|
@ -4,18 +4,9 @@
|
|||||||
|
|
||||||
#include "cat.h"
|
#include "cat.h"
|
||||||
|
|
||||||
//#define ACK 0
|
// make these messages static inside a function
|
||||||
//#define CAT_PREFIX 0xC0
|
IOPMessage inBuf; // input message buffer
|
||||||
//#define IOP_PREFIX 0xD0
|
IOPMessage outBuf; // output message buffer
|
||||||
//#define EEPROM_READ_PREFIX 0xE0
|
|
||||||
//#define EEPROM_WRITE_PREFIX 0xF0
|
|
||||||
//
|
|
||||||
//#define IOP_MODE_COMMAND 0x00
|
|
||||||
//#define IOP_START_TX_COMMAND 0x01
|
|
||||||
//#define IOP_STOP_TX_COMMAND 0x02
|
|
||||||
//#define IOP_MODE_SSB 0x00
|
|
||||||
//#define IOP_MODE_DIGI 0x01
|
|
||||||
//#define IOP_MODE_CW 0x02
|
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// CAT from PC-to-IOP
|
// CAT from PC-to-IOP
|
||||||
@ -39,50 +30,60 @@ void initCAT(long baud, int portConfig)
|
|||||||
// CAT with PC via USB
|
// CAT with PC via USB
|
||||||
USBSERIAL.begin(baud);
|
USBSERIAL.begin(baud);
|
||||||
USBSERIAL.flush();
|
USBSERIAL.flush();
|
||||||
|
#if defined(DEBUG)
|
||||||
#if not defined(FACTORY_CALIBRATION)
|
USBSERIAL.println("IOP: opened USB serial port (to PC)");
|
||||||
// CAT with Raduino via UART
|
|
||||||
HWSERIAL.begin(baud, portConfig);
|
|
||||||
USBSERIAL.flush();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Comm (including CAT passthru) with Raduino via UART
|
||||||
|
HWSERIAL.begin(baud, portConfig);
|
||||||
|
HWSERIAL.flush();
|
||||||
|
#if defined(DEBUG)
|
||||||
|
USBSERIAL.println("IOP: opened H/W serial port (to Raduino)");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//sendIOPModeRequest(); // Raduino doesn't support this yet
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
void processIOPCommand(const byte* buf, int len)
|
void processIOPCommand(IOPMessage const& m)
|
||||||
{
|
{
|
||||||
if (len > 0) {
|
switch(inBuf.id) {
|
||||||
switch(buf[0]) {
|
case IOP_MODE_COMMAND:
|
||||||
case IOP_MODE_COMMAND:
|
USBDEBUG("IOP_MODE_COMMAND received (from Raduino)");
|
||||||
if (len < 2) {
|
if (m.len < 1) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
setRigMode(RigMode(buf[1]));
|
setRigMode(m.data[0]);
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
USBSERIAL.print("DEBUG: mode ");
|
switch(rigMode) {
|
||||||
switch(rigMode) {
|
case MODE_CW:
|
||||||
case MODE_CW:
|
USBDEBUG("new mode - CW");
|
||||||
USBSERIAL.println("CW");
|
break;
|
||||||
break;
|
case MODE_SSB:
|
||||||
case MODE_SSB:
|
USBDEBUG("new mode - SSB");
|
||||||
USBSERIAL.println("SSB");
|
break;
|
||||||
break;
|
case MODE_DIGI:
|
||||||
case MODE_DIGI:
|
USBDEBUG("new mode - DIGI");
|
||||||
USBSERIAL.println("DIGI");
|
break;
|
||||||
break;
|
case MODE_TEST:
|
||||||
}
|
USBDEBUG("new mode - TEST");
|
||||||
#endif
|
break;
|
||||||
}
|
}
|
||||||
break;
|
#endif
|
||||||
|
|
||||||
case IOP_START_TX_COMMAND:
|
|
||||||
catPTTOn();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IOP_STOP_TX_COMMAND:
|
|
||||||
catPTTOff();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOP_START_TX_COMMAND:
|
||||||
|
catPTTOn();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOP_STOP_TX_COMMAND:
|
||||||
|
catPTTOff();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOP_CW_CONFIG_MSG:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,15 +118,16 @@ void processCalCommand(const char* buf)
|
|||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
enum serial_mode_t {
|
enum SerialState {
|
||||||
NORMAL = 0,
|
NORMAL = 0,
|
||||||
CAT_MODE,
|
CAT_MODE,
|
||||||
IOP_MODE,
|
IOP_MODE,
|
||||||
EEPROM_READ,
|
EEPROM_READ,
|
||||||
EEPROM_WRITE,
|
EEPROM_WRITE,
|
||||||
} serialMode = NORMAL;
|
} serialState = NORMAL;
|
||||||
|
|
||||||
int readLength = 0;
|
uint8_t readPrefix = 0;
|
||||||
|
uint8_t readLength = 0;
|
||||||
|
|
||||||
int cmdLength = 0;
|
int cmdLength = 0;
|
||||||
byte cmdBuffer[16];
|
byte cmdBuffer[16];
|
||||||
@ -139,7 +141,7 @@ int magicFlag = 0;
|
|||||||
|
|
||||||
void serviceCAT()
|
void serviceCAT()
|
||||||
{
|
{
|
||||||
int incomingByte;
|
uint8_t incomingByte;
|
||||||
|
|
||||||
// read from the USB serial, pass through to UART serial
|
// read from the USB serial, pass through to UART serial
|
||||||
for (int i = 0; i < USBSERIAL.available(); i++) {
|
for (int i = 0; i < USBSERIAL.available(); i++) {
|
||||||
@ -172,33 +174,56 @@ void serviceCAT()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
// Don't pass CAT commands through if in DEBUG mode.
|
||||||
|
#if not defined(DEBUG)
|
||||||
HWSERIAL.write(incomingByte);
|
HWSERIAL.write(incomingByte);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// read from the UART serial, see what we need to do with it
|
// read from the UART serial, see what we need to do with it
|
||||||
for (int i = 0; i < HWSERIAL.available(); i++) {
|
for (int i = 0; i < HWSERIAL.available(); i++) {
|
||||||
incomingByte = HWSERIAL.read();
|
incomingByte = HWSERIAL.read();
|
||||||
|
#if defined(DEBUG)
|
||||||
|
char ibBuff[20];
|
||||||
|
itoa(serialState, ibBuff, 10);
|
||||||
|
USBSERIAL.print("IOP: serialState = ");
|
||||||
|
USBSERIAL.print(ibBuff);
|
||||||
|
itoa(incomingByte, ibBuff, 10);
|
||||||
|
USBSERIAL.print("; incomingByte = ");
|
||||||
|
USBSERIAL.println(ibBuff);
|
||||||
|
#endif
|
||||||
|
|
||||||
switch(serialMode) {
|
switch(serialState) {
|
||||||
case NORMAL:
|
case NORMAL:
|
||||||
if (incomingByte == ACK) {
|
if (incomingByte == ACK) {
|
||||||
USBSERIAL.write(incomingByte);
|
USBSERIAL.write(incomingByte);
|
||||||
} else {
|
} else {
|
||||||
readLength = incomingByte & 0x0F;
|
readPrefix = byteToPrefix(incomingByte);
|
||||||
|
readLength = byteToLength(incomingByte);
|
||||||
|
#if defined(DEBUG)
|
||||||
|
itoa(readPrefix, ibBuff, 10);
|
||||||
|
USBSERIAL.print("IOP: readPrefix = ");
|
||||||
|
USBSERIAL.print(ibBuff);
|
||||||
|
itoa(readLength, ibBuff, 10);
|
||||||
|
USBSERIAL.print("; readLength = ");
|
||||||
|
USBSERIAL.println(ibBuff);
|
||||||
|
#endif
|
||||||
if (readLength > 0) {
|
if (readLength > 0) {
|
||||||
switch(incomingByte & 0xF0) {
|
USBDEBUG("readLength > 0");
|
||||||
|
switch(readPrefix) {
|
||||||
case CAT_PREFIX:
|
case CAT_PREFIX:
|
||||||
case EEPROM_WRITE_PREFIX:
|
case RAD_EEPROM_WRITE_PREFIX:
|
||||||
serialMode = CAT_MODE;
|
serialState = CAT_MODE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOP_PREFIX:
|
case IOP_PREFIX:
|
||||||
serialMode = IOP_MODE;
|
USBDEBUG("entering IOP_MODE");
|
||||||
cmdLength = 0;
|
serialState = IOP_MODE;
|
||||||
|
cmdLength = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EEPROM_READ_PREFIX:
|
case RAD_EEPROM_READ_PREFIX:
|
||||||
serialMode = EEPROM_READ;
|
serialState = EEPROM_READ;
|
||||||
readLength = 5;
|
readLength = 5;
|
||||||
magicFlag = 0;
|
magicFlag = 0;
|
||||||
break;
|
break;
|
||||||
@ -216,7 +241,7 @@ void serviceCAT()
|
|||||||
USBSERIAL.write(incomingByte);
|
USBSERIAL.write(incomingByte);
|
||||||
readLength--;
|
readLength--;
|
||||||
if (readLength == 0) {
|
if (readLength == 0) {
|
||||||
serialMode = NORMAL;
|
serialState = NORMAL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -225,8 +250,9 @@ void serviceCAT()
|
|||||||
cmdLength++;
|
cmdLength++;
|
||||||
readLength--;
|
readLength--;
|
||||||
if (readLength == 0) {
|
if (readLength == 0) {
|
||||||
processIOPCommand(cmdBuffer, cmdLength);
|
recvIOPMessage(inBuf, cmdBuffer, cmdLength);
|
||||||
serialMode = NORMAL;
|
processIOPCommand(inBuf);
|
||||||
|
serialState = NORMAL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -262,7 +288,7 @@ void serviceCAT()
|
|||||||
} else {
|
} else {
|
||||||
readLength = eepromReadLength + 2;
|
readLength = eepromReadLength + 2;
|
||||||
}
|
}
|
||||||
serialMode = CAT_MODE;
|
serialState = CAT_MODE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -5,13 +5,15 @@
|
|||||||
#ifndef __iop_config_h__
|
#ifndef __iop_config_h__
|
||||||
#define __iop_config_h__
|
#define __iop_config_h__
|
||||||
|
|
||||||
|
#include <iopcomm.h>
|
||||||
|
|
||||||
#define KEYER_LEFT_PADDLE_PIN 16
|
#define KEYER_LEFT_PADDLE_PIN 16
|
||||||
#define KEYER_RIGHT_PADDLE_PIN 17
|
#define KEYER_RIGHT_PADDLE_PIN 17
|
||||||
|
|
||||||
// Uncomment to use the "factory" calibration mode. This is intended to
|
// Uncomment to use the "factory" calibration mode. This is intended to
|
||||||
// allow calibration of IOP settings, separately from the uBITX/Raduino.
|
// allow calibration of IOP settings, separately from the uBITX/Raduino.
|
||||||
// There will be no pass-thru of any CAT.
|
// There will be no pass-thru of any CAT.
|
||||||
//#define FACTORY_CALIBRATION
|
#define FACTORY_CALIBRATION
|
||||||
|
|
||||||
// IOPConfig
|
// IOPConfig
|
||||||
// Used to store configuration parameters during runtime, as well as to
|
// Used to store configuration parameters during runtime, as well as to
|
||||||
@ -22,7 +24,7 @@ struct IOPConfig {
|
|||||||
|
|
||||||
// rig-in parameters (RX)
|
// rig-in parameters (RX)
|
||||||
uint8_t rxRigInLevel = 5;
|
uint8_t rxRigInLevel = 5;
|
||||||
float rxRigInVol = 0.7;
|
float rxRigInVol = 1.0; //0.7;
|
||||||
float rxRigInCal = 1.0;
|
float rxRigInCal = 1.0;
|
||||||
// USB-in parameters (RX) - debug/monitor use only
|
// USB-in parameters (RX) - debug/monitor use only
|
||||||
bool rxUSBInEnable = false;
|
bool rxUSBInEnable = false;
|
||||||
@ -68,21 +70,27 @@ struct IOPConfig {
|
|||||||
|
|
||||||
// microphone-in parameters (TX)
|
// microphone-in parameters (TX)
|
||||||
uint8_t txMicInGain = 12;
|
uint8_t txMicInGain = 12;
|
||||||
float txMicInVol = 0.7;
|
float txMicInVol = 1.0; //0.7;
|
||||||
float txMicInCal = 1.0;
|
float txMicInCal = 1.0;
|
||||||
// line-in parameters (TX)
|
// line-in parameters (TX)
|
||||||
uint8_t txLineInLevel = 5;
|
uint8_t txLineInLevel = 5;
|
||||||
float txLineInVol = 0.7;
|
float txLineInVol = 1.0; //0.7;
|
||||||
float txLineInCal = 1.30;
|
float txLineInCal = 1.30;
|
||||||
// USB-in parameters (TX)
|
// USB-in parameters (TX)
|
||||||
float txUSBInVol = 0.7;
|
float txUSBInVol = 1.0; //0.7;
|
||||||
float txUSBInCal = 1.0;
|
float txUSBInCal = 1.0;
|
||||||
|
// two-tone parameters (TX)
|
||||||
|
float txSine1Vol = 1.0;
|
||||||
|
float txSine2Vol = 1.0;
|
||||||
// rig-out parameters (TX) - default settings are based on hitting 70% of 25mVrms w/ mic
|
// rig-out parameters (TX) - default settings are based on hitting 70% of 25mVrms w/ mic
|
||||||
uint8_t txRigOutLevel = 31;
|
uint8_t txRigOutLevel = 31;
|
||||||
float txRigOutCal = 0.043;
|
float txRigOutCal = 0.043;
|
||||||
// USB-out parameters (TX)- debug/monitor use only
|
// USB-out parameters (TX)- debug/monitor use only
|
||||||
bool txUSBOutEnable = true;
|
bool txUSBOutEnable = true;
|
||||||
float txUSBOutCal = 1.0;
|
float txUSBOutCal = 1.0;
|
||||||
|
|
||||||
|
// CW configuration
|
||||||
|
CWConfig cw;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern IOPConfig iopConfig;
|
extern IOPConfig iopConfig;
|
||||||
|
@ -14,11 +14,17 @@
|
|||||||
// comment this out to disable debugging code
|
// comment this out to disable debugging code
|
||||||
//#define DEBUG
|
//#define DEBUG
|
||||||
|
|
||||||
enum RigMode {
|
#if defined(DEBUG)
|
||||||
MODE_SSB = 0,
|
#define USBDEBUG(x) USBSERIAL.print("IOP: "); USBSERIAL.println(x);
|
||||||
MODE_DIGI = 1,
|
#else
|
||||||
MODE_CW = 2,
|
#define USBDEBUG(x)
|
||||||
};
|
#endif
|
||||||
|
|
||||||
|
//enum RigMode {
|
||||||
|
// MODE_SSB = 0,
|
||||||
|
// MODE_DIGI = 1,
|
||||||
|
// MODE_CW = 2,
|
||||||
|
//};
|
||||||
|
|
||||||
enum TxState {
|
enum TxState {
|
||||||
TX_OFF = 0,
|
TX_OFF = 0,
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// ubitx_iop.ino
|
// ubitx_iop.ino
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
|
#include <iopcomm.h>
|
||||||
#include "ubitx_iop.h"
|
#include "ubitx_iop.h"
|
||||||
|
|
||||||
#include <Bounce2.h>
|
#include <Bounce2.h>
|
||||||
@ -145,6 +146,13 @@ void checkMicPTT()
|
|||||||
case MODE_DIGI:
|
case MODE_DIGI:
|
||||||
// Mic PTT actuation during Digital does nothing.
|
// Mic PTT actuation during Digital does nothing.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MODE_TEST:
|
||||||
|
txState = TX_MIC;
|
||||||
|
audioSelectTxInput(TX_TEST_IN);
|
||||||
|
audioTransmit();
|
||||||
|
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,6 +194,13 @@ void checkLinePTT()
|
|||||||
case MODE_DIGI:
|
case MODE_DIGI:
|
||||||
// Line PTT actuation during Digital does nothing.
|
// Line PTT actuation during Digital does nothing.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MODE_TEST:
|
||||||
|
txState = TX_LINE;
|
||||||
|
audioSelectTxInput(TX_TEST_IN);
|
||||||
|
audioTransmit();
|
||||||
|
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,6 +213,7 @@ void setRigMode(RigMode m)
|
|||||||
|
|
||||||
switch(rigMode) {
|
switch(rigMode) {
|
||||||
case MODE_SSB:
|
case MODE_SSB:
|
||||||
|
case MODE_TEST:
|
||||||
// SSB sets the TX audio input to line-in. Note that this will be
|
// SSB sets the TX audio input to line-in. Note that this will be
|
||||||
// automatically overridden by mic-in, if the mic PTT is pressed.
|
// automatically overridden by mic-in, if the mic PTT is pressed.
|
||||||
audioSelectTxInput(TX_LINE_IN);
|
audioSelectTxInput(TX_LINE_IN);
|
||||||
@ -244,7 +260,11 @@ void setup() {
|
|||||||
digitalWrite(PTT_KEY_OUT_PIN, HIGH);
|
digitalWrite(PTT_KEY_OUT_PIN, HIGH);
|
||||||
|
|
||||||
audioInit();
|
audioInit();
|
||||||
|
#if defined(FACTORY_CALIBRATION)
|
||||||
|
setRigMode(MODE_TEST);
|
||||||
|
#else
|
||||||
setRigMode(MODE_SSB);
|
setRigMode(MODE_SSB);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
Loading…
x
Reference in New Issue
Block a user