ubitx-v5d-xcvr/ubitx_iop/cat.ino

265 lines
6.1 KiB
C++

//======================================================================
// cat.ino
//======================================================================
#include "cat.h"
#define ACK 0
#define CAT_PREFIX 0xC0
#define IOP_PREFIX 0xD0
#define EEPROM_READ_PREFIX 0xE0
#define EEPROM_WRITE_PREFIX 0xF0
#define IOP_MODE_COMMAND 0x00
#define IOP_MODE_SSB 0x01
#define IOP_MODE_DIGI 0x02
#define IOP_MODE_CW 0x03
//======================================================================
// CAT from PC-to-IOP
//
// The general concept for IOP use of CAT is for the IOP to pass thru
// all incoming CAT data (from the PC) to the Raduino.
//
// This might change in the future, if we want to grab CAT data straight
// from the PC. That might apply to things like specific audio filter
// settings or something, but since the Raduino modes are an important
// part of the mix, I think the commands really need to come from the
// Raduino... and besides, what if a PC is not connected?
//
//
// For data coming from the Raduino, the IOP does have to do a minimal
// processing to extra any Raduino-to-IOP commands.
//======================================================================
void initCAT(long baud, int portConfig)
{
// CAT with PC via USB
USBSERIAL.begin(baud);
USBSERIAL.flush();
#if not defined(FACTORY_CALIBRATION)
// CAT with Raduino via UART
HWSERIAL.begin(baud, portConfig);
USBSERIAL.flush();
#endif
}
//======================================================================
void processIOPCommand(const byte* buf, int len)
{
if (len > 0) {
switch(buf[0]) {
case IOP_MODE_COMMAND:
if (len < 2) {
return;
} else {
rigMode = RigMode(buf[1]);
}
break;
}
}
}
//======================================================================
void processCalCommand(const char* buf)
{
int count;
char cmd;
char subcmd;
char parm;
float value;
count = sscanf(buf, "%1c %1c %1c %f", &cmd, &subcmd, &parm, &value);
if (count < 3) {
USBSERIAL.println("Calibration: invalid command");
} else {
switch(cmd) {
case 'r':
case 'R':
case 't':
case 'T':
audioCalibrate(&iopConfig, cmd, subcmd, parm, value, (count == 4));
break;
default:
USBSERIAL.println("Calibration: invalid command");
}
}
}
//======================================================================
enum serial_mode_t {
NORMAL = 0,
CAT_MODE,
IOP_MODE,
EEPROM_READ,
EEPROM_WRITE,
} serialMode = NORMAL;
int readLength = 0;
int cmdLength = 0;
byte cmdBuffer[16];
char cmdString[17]; // added a char for null termination when required
uint16_t eepromStartIndex;
uint16_t eepromReadLength;
int magicFlag = 0;
//----------------------------------------------------------------------
void serviceCAT()
{
int incomingByte;
// read from the USB serial, pass through to UART serial
for (int i = 0; i < USBSERIAL.available(); i++) {
incomingByte = USBSERIAL.read();
#if defined(FACTORY_CALIBRATION)
// unless we're in factory calibration mode, in which case we're going
// to process calibration commands...
switch(incomingByte) {
case ';':
cmdString[cmdLength] = '\0';
if (cmdLength > 0) {
processCalCommand(cmdString);
cmdLength = 0;
}
break;
case '\n':
case '\r':
cmdString[0] = '\0';
cmdLength = 0;
break;
default:
cmdString[cmdLength++] = char(incomingByte);
if (cmdLength == 16) {
cmdString[cmdLength] = '\0';
processCalCommand(cmdString);
cmdLength = 0;
}
}
#else
HWSERIAL.write(incomingByte);
}
// read from the UART serial, see what we need to do with it
for (int i = 0; i < HWSERIAL.available(); i++) {
incomingByte = HWSERIAL.read();
switch(serialMode) {
case NORMAL:
if (incomingByte == ACK) {
USBSERIAL.write(incomingByte);
} else {
readLength = incomingByte & 0x0F;
if (readLength > 0) {
switch(incomingByte & 0xF0) {
case CAT_PREFIX:
case EEPROM_WRITE_PREFIX:
serialMode = CAT_MODE;
break;
case IOP_PREFIX:
serialMode = IOP_MODE;
cmdLength = 0;
break;
case EEPROM_READ_PREFIX:
serialMode = EEPROM_READ;
readLength = 5;
magicFlag = 0;
break;
default:
// should never happen
break;
}
}
}
break;
case CAT_MODE:
// In CAT mode, we just pass thru the remaining bytes to the PC.
USBSERIAL.write(incomingByte);
readLength--;
if (readLength == 0) {
serialMode = NORMAL;
}
break;
case IOP_MODE:
cmdBuffer[cmdLength] = incomingByte;
cmdLength++;
readLength--;
if (readLength == 0) {
processIOPCommand(cmdBuffer, cmdLength);
serialMode = 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;
}
serialMode = CAT_MODE;
break;
default:
// should never happen
break;
}
break;
case EEPROM_WRITE:
// TODO
break;
default:
// should never happen...
break;
}
#endif
}
}
//======================================================================
// EOF
//======================================================================