From 814fe6c733bc4579d8f34942a737cf018fd30249 Mon Sep 17 00:00:00 2001 From: Rob French Date: Thu, 11 Feb 2021 22:00:24 -0600 Subject: [PATCH] Did add some code for updating the RigState architecture. Not ready to swap it out yet, however. --- Raduino/Raduino.ino | 7 ++ Raduino/ubitx.h | 2 + Raduino/ubitx_lcd_nextion.ino | 19 +---- Raduino/ubitx_ui.ino | 38 +++++++++ TeensyDSP/RigState.h | 146 ++++++++++++++++++++++++++++++++++ 5 files changed, 196 insertions(+), 16 deletions(-) diff --git a/Raduino/Raduino.ino b/Raduino/Raduino.ino index bd1587e..9f9f6f0 100644 --- a/Raduino/Raduino.ino +++ b/Raduino/Raduino.ino @@ -1475,6 +1475,13 @@ void checkAutoSaveFreqMode() rigState.vfo[0] = vfoA; rigState.vfo[1] = vfoB; + rigState.rit = ritRxFrequency - frequency; + rigState.flags = 0; + rigState.flags |= (vfoActive == VFO_B ? UBITX_VFOB_FLAG : 0); + rigState.flags |= (cwMode != 0 ? UBITX_CW_FLAG : 0); + rigState.flags |= (isUSB != 0 ? UBITX_USB_FLAG : 0); + rigState.flags |= (splitOn != 0 ? UBITX_SPLIT_FLAG : 0); + rigState.flags |= (ritOn != 0 ? UBITX_RIT_FLAG : 0); } void loop(){ diff --git a/Raduino/ubitx.h b/Raduino/ubitx.h index 2dfed05..da3f1d8 100644 --- a/Raduino/ubitx.h +++ b/Raduino/ubitx.h @@ -341,6 +341,8 @@ extern void DisplayVersionInfo(const char* fwVersionInfo); extern int GetI2CSmeterValue(int valueType); //ubitx_ui.ino extern void doRaduinoToTeensy(UBitxRigState* r); +extern void updateStateFromRaduino(UBitxRigState& r); +extern void updateRaduinoFromState(UBitxRigState& r); extern UBitxRigState rigState; diff --git a/Raduino/ubitx_lcd_nextion.ino b/Raduino/ubitx_lcd_nextion.ino index 0936ae5..7aa39b8 100644 --- a/Raduino/ubitx_lcd_nextion.ino +++ b/Raduino/ubitx_lcd_nextion.ino @@ -997,23 +997,10 @@ UBitxRigState catState; void idle_process() { // KC4UPR 2021-02-05 added update process for Raduino-TeensyDSP coordination - // Note, need to not have to copy this every time... - if (vfoActive == VFO_A) { - rigState.vfo[0] = frequency; - rigState.flags &= ~UBITX_VFOB_FLAG; - } else if (vfoActive == VFO_B) { - rigState.vfo[1] = frequency; - rigState.flags |= UBITX_VFOB_FLAG; - } + updateStateFromRaduino(rigState); doRaduinoToTeensy(&rigState); - if (vfoActive == VFO_A) { - if (rigState.vfo[0] != frequency) { - setFrequency(rigState.vfo[0]); - } else if (vfoActive == VFO_B) { - setFrequency(rigState.vfo[1]); - } - } - + updateRaduinoFromState(rigState); + //S-Meter Display if (((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0)) && (++checkCountSMeter > SMeterLatency)) { diff --git a/Raduino/ubitx_ui.ino b/Raduino/ubitx_ui.ino index 67258b0..b2921e4 100644 --- a/Raduino/ubitx_ui.ino +++ b/Raduino/ubitx_ui.ino @@ -350,3 +350,41 @@ void doRaduinoToTeensy(UBitxRigState* r) { Serial.print(len); Serial.println(); } + +void updateStateFromRaduino(UBitxRigState& r) { + // Note, we really need to be checking a dirty flag for this. But, I don't have a dirty flag in this version of the data type... + if (vfoActive == VFO_A) { + rigState.vfo[0] = frequency; + rigState.flags &= ~UBITX_VFOB_FLAG; + } else if (vfoActive == VFO_B) { + rigState.vfo[1] = frequency; + rigState.flags |= UBITX_VFOB_FLAG; + } + rigState.rit = ritRxFrequency - frequency; + rigState.flags = 0; + rigState.flags |= (vfoActive == VFO_B ? UBITX_VFOB_FLAG : 0); + rigState.flags |= (cwMode != 0 ? UBITX_CW_FLAG : 0); + rigState.flags |= (isUSB != 0 ? UBITX_USB_FLAG : 0); + rigState.flags |= (splitOn != 0 ? UBITX_SPLIT_FLAG : 0); + rigState.flags |= (ritOn != 0 ? UBITX_RIT_FLAG : 0); +} + +void updateRaduinoFromState(UBitxRigState& r) { + vfoActive = rigState.flags & UBITX_VFOB_FLAG ? VFO_B : VFO_A; + if (vfoActive == VFO_A) { + if (rigState.vfo[0] != frequency) { + setFrequency(rigState.vfo[0]); + } else if (vfoActive == VFO_B) { + setFrequency(rigState.vfo[1]); + } + } + ritRxFrequency = frequency + rigState.rit; + splitOn = rigState.flags & UBITX_SPLIT_FLAG ? 1 : 0; + ritOn = rigState.flags & UBITX_RIT_FLAG ? 1 : 0; + isUSB = rigState.flags & UBITX_USB_FLAG ? 1 : 0; + if (rigState.flags & UBITX_CW_FLAG) { + cwMode = isUSB ? 2 : 1; // 2 = cwu / 1 = cwl + } else { + cwMode = 0; + } +} diff --git a/TeensyDSP/RigState.h b/TeensyDSP/RigState.h index 4b1b695..064a876 100644 --- a/TeensyDSP/RigState.h +++ b/TeensyDSP/RigState.h @@ -25,4 +25,150 @@ struct UBitxRigState { uint32_t flags = 0; }; +/**********************************************************************/ + +template +struct Field { + byte id = ID; + bool dirty; + T data; + + inline size_t sizeOfWrite() { return dirty ? sizeof(byte) + sizeof(T) : 0; } + + template void writeChanges() { + if (dirty) { + STREAM().write(id); + STREAM().write((byte*)&data, sizeof(T)); + } + } + + template int read() { + size_t len = 0; + byte* ptr = (byte*)&data; + while (STREAM().available() && len < sizeof(T)) { + ptr[len++] = STREAM().read(); + } + return len; + } + + inline void merge(Field& f) { + if (dirty) { + f.data = data; + f.dirty = true; + } else if (f.dirty) { + data = f.data; + dirty = true; + } + } + + inline void markClean() { dirty = false; } +}; + +struct RigState { + Field vfoA; + Field vfoB; + Field rit; + Field xit; + Field flags; + + inline size_t sizeOfWrite() { + size_t size = 0; + size += vfoA.sizeOfWrite(); + size += vfoB.sizeOfWrite(); + size += rit.sizeOfWrite(); + size += xit.sizeOfWrite(); + size += flags.sizeOfWrite(); + return size; + } + + template void writeChanges() { + vfoA.writeChanges(); + vfoB.writeChanges(); + rit.writeChanges(); + xit.writeChanges(); + flags.writeChanges(); + } + + template void readChanges(size_t size) { + size_t len = 0; + while (STREAM().available() && len < size) { + switch(STREAM().read()) { + case 0: + len += vfoA.read(); + break; + + case 1: + len += vfoB.read(); + break; + + case 2: + len += rit.read(); + break; + + case 3: + len += xit.read(); + break; + + case 4: + len += flags.read(); + break; + + default: + ; + } + } + } + + inline void merge(RigState& r) { + vfoA.merge(r.vfoA); + vfoB.merge(r.vfoB); + rit.merge(r.rit); + xit.merge(r.xit); + flags.merge(r.flags); + } + + inline void markClean(RigState& r) { + vfoA.markClean(); + vfoB.markClean(); + rit.markClean(); + xit.markClean(); + flags.markClean(); + } +}; + +/* +Protocol discussion: +- I2C master: Raduino +- I2C slave: TeensyDSP + +Raduino state: + - Baseline uBITX variables + - I2C buffer + - On I2C transmit: make updates based on current variables + - On I2C receive: + - Update based on received I2C responses + - Update associated variables + +TeensyDSP state: + - CAT buffer + - Used to receive command from CAT (when commands arrive via Serial) + - Used to transmit state to Raduino (when requested via Wire1) + - Raduino buffer + - Used to receive state from Raduino (when received via Wire1) + - Used to transmit responses to CAT (over Serial) + - Questions + - How can these be synchronized? + - At the tail end of an I2C request handler. Before sending the response to the Raduino via I2C: + - Copy updated CAT buffer items to the Raduino buffer. + - Copy updated Raduino buffer items to the CAT buffer. + - In the case of conflicts, CAT wins. + - Transmit the CAT buffer state to the Raduino. +- TeensyDSP updates 'outgoing' state based on CAT inputs. + - Make change to data. + - Mark data as dirty, if different than incoming state. +- When requested, Teensy DSP sends 'outgoing' state to Raduino. + - Send dirty data over I2C. + - Mark data as clean. + */ + #endif