From c3cc9a7cf70434b4e515f7e97c0aae6f241d04e9 Mon Sep 17 00:00:00 2001 From: Rob French Date: Wed, 10 Feb 2021 00:10:24 -0600 Subject: [PATCH] Got basic 3-way comm (CAT-Teensy-Raduino) working. CAT commands are received via Serial by the Teensy. Data is passed on to the Raduino via I2C. Had to add an intermediate step in the protocol in order for the Raduino to request a byte as a flag for whether or not any changed data was coming, and then if so, request the changed data. There are certainly some optimizations that could be made on this number. Currently, the Raduino code is very clunky. In addition, the Rig and RigState classes have deteriorated somewhat. --- Raduino/ubitx_lcd_nextion.ino | 7 +++++++ Raduino/ubitx_ui.ino | 36 +++++++++++++++++++++++++---------- TeensyDSP/Rig.h | 13 +++++++++++++ TeensyDSP/TS590.cpp | 8 ++++---- TeensyDSP/TeensyDSP.ino | 24 ++++++++++++++++++----- 5 files changed, 69 insertions(+), 19 deletions(-) diff --git a/Raduino/ubitx_lcd_nextion.ino b/Raduino/ubitx_lcd_nextion.ino index 35cba91..0936ae5 100644 --- a/Raduino/ubitx_lcd_nextion.ino +++ b/Raduino/ubitx_lcd_nextion.ino @@ -1006,6 +1006,13 @@ void idle_process() rigState.flags |= UBITX_VFOB_FLAG; } doRaduinoToTeensy(&rigState); + if (vfoActive == VFO_A) { + if (rigState.vfo[0] != frequency) { + setFrequency(rigState.vfo[0]); + } else if (vfoActive == VFO_B) { + setFrequency(rigState.vfo[1]); + } + } //S-Meter Display if (((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0)) && (++checkCountSMeter > SMeterLatency)) diff --git a/Raduino/ubitx_ui.ino b/Raduino/ubitx_ui.ino index efdd0f0..67258b0 100644 --- a/Raduino/ubitx_ui.ino +++ b/Raduino/ubitx_ui.ino @@ -312,6 +312,7 @@ void doRaduinoToTeensy(UBitxRigState* r) { Wire.write(ptr, sizeof(UBitxRigState)); Wire.endTransmission(); + Serial.println("BEFORE:"); Serial.print("VFO A: "); Serial.print(r->vfo[0]); Serial.print(", VFO B: "); @@ -319,18 +320,33 @@ void doRaduinoToTeensy(UBitxRigState* r) { Serial.print(", Data Size: "); Serial.print(sizeof(UBitxRigState)); Serial.println(); - - Wire.requestFrom(I2CMETER_ADDR, sizeof(UBitxRigState)); - UBitxRigState tmp; - + // First we need to see if there's any updated state. + Wire.requestFrom(I2CMETER_ADDR, sizeof(uint8_t)); int len = 0; - ptr = (uint8_t*)&tmp; - - while (Wire.available() > 0) { - uint8_t b = Wire.read(); - if (len < sizeof(UBitxRigState)) { - ptr[len++] = b; + int readflag = Wire.read(); + if (readflag != 0) { + Wire.requestFrom(I2CMETER_ADDR, sizeof(UBitxRigState)); + + UBitxRigState tmp; + + //int len = 0; + //ptr = (uint8_t*)&tmp; + + while (Wire.available() > 0) { + uint8_t b = Wire.read(); + if (len < sizeof(UBitxRigState)) { + ptr[len++] = b; + } } } + + Serial.println("AFTER:"); + Serial.print("VFO A: "); + Serial.print(r->vfo[0]); + Serial.print(", VFO B: "); + Serial.print(r->vfo[1]); + Serial.print(", Data Size: "); + Serial.print(len); + Serial.println(); } diff --git a/TeensyDSP/Rig.h b/TeensyDSP/Rig.h index 2050518..fa45b0a 100644 --- a/TeensyDSP/Rig.h +++ b/TeensyDSP/Rig.h @@ -123,6 +123,19 @@ class UBitxRig { uint8_t* const stateAsBytes() const { return (uint8_t* const)&state; } + inline void updateState(UBitxRigState& r, bool isCAT = false) { + if ((r.vfo[0] == state.vfo[0]) && + (r.vfo[1] == state.vfo[1]) && + (r.rit == state.rit) && + (r.xit == state.xit) && + (r.flags == state.flags)) { + return; + } else { + state = r; + lastUpdatedBy = isCAT ? CATSource : RaduinoSource; + } + } + private: bool autoInfo = false; UpdateSource lastUpdatedBy = NoSource; diff --git a/TeensyDSP/TS590.cpp b/TeensyDSP/TS590.cpp index cf1c927..18224b3 100644 --- a/TeensyDSP/TS590.cpp +++ b/TeensyDSP/TS590.cpp @@ -177,9 +177,9 @@ void TS590_FT::handleCommand(const char* cmd) { switch (cmd[2]) { case 0: if (rig()->isVFOA()) { - rig()->splitOff(); + rig()->splitOff(true); } else if (rig()->isVFOB()) { - rig()->splitOn(); + rig()->splitOn(true); } else { setSyntaxError(); } @@ -187,9 +187,9 @@ void TS590_FT::handleCommand(const char* cmd) { case 1: if (rig()->isVFOA()) { - rig()->splitOn(); + rig()->splitOn(true); } else if (rig()->isVFOB()) { - rig()->splitOff(); + rig()->splitOff(true); } else { setSyntaxError(); } diff --git a/TeensyDSP/TeensyDSP.ino b/TeensyDSP/TeensyDSP.ino index 3836db3..945532f 100644 --- a/TeensyDSP/TeensyDSP.ino +++ b/TeensyDSP/TeensyDSP.ino @@ -363,6 +363,8 @@ void setup() //Serial1.println("Start..."); } +bool sentRigInfFlag = false; + /*! @brief Receive a command via I2C. The most recent command will be received, which will indicate which data the DSP should be preparing to return. @@ -373,16 +375,20 @@ void i2cReceiveEvent(size_t numBytes) { int readCommand = 0; bool exitLoop = false; + UBitxRigState tmpState; while (Wire1.available() > 0 && !exitLoop) { readCommand = Wire1.read(); if (readCommand == I2CMETER_RIGINF) { size_t len = 0; - uint8_t* const ptr = Rig.stateAsBytes(); + uint8_t* const ptr = (uint8_t* const)&tmpState; while ((Wire1.available() > 0) && (len < sizeof(UBitxRigState))) { ptr[len++] = Wire1.read(); } - Rig.setRaduinoUpdate(); + if (!Rig.updatedByCAT()) { + Rig.updateState(tmpState); + } + sentRigInfFlag = false; // so we know that we need to send the flag first exitLoop = true; } } @@ -456,10 +462,18 @@ void i2cRequestEvent(void) // Provide latest CAT updates, if any. //Wire1.write(catState.header); // temporary - just writing a single, null byte if (Rig.updatedByCAT()) { - Wire1.write(Rig.stateAsBytes(), sizeof(UBitxRigState)); - Rig.clearUpdate(); + if (sentRigInfFlag) { + DBGPRINTLN("I2CMETER_REQCAT -- updated by CAT"); + Wire1.write(Rig.stateAsBytes(), sizeof(UBitxRigState)); + Rig.clearUpdate(); + } else { + Wire1.write(1); + sentRigInfFlag = true; + } } else { - Wire1.write(Rig.stateAsBytes(), sizeof(uint8_t)); + DBGPRINTLN("I2CMETER_REQCAT -- NOT updated by CAT"); + //Wire1.write(Rig.stateAsBytes(), sizeof(uint8_t)); + Wire1.write(0); } #ifdef DEBUG i2cRespCounter[i2cCommand - 0x50]++;