//====================================================================== // 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 //======================================================================