diff --git a/Raduino/Debug.h b/Raduino/Debug.h new file mode 120000 index 0000000..3978167 --- /dev/null +++ b/Raduino/Debug.h @@ -0,0 +1 @@ +../TeensyDSP/Debug.h \ No newline at end of file diff --git a/Raduino/Raduino.ino b/Raduino/Raduino.ino index 0e20fc4..111a812 100644 --- a/Raduino/Raduino.ino +++ b/Raduino/Raduino.ino @@ -337,7 +337,7 @@ byte delay_background(unsigned delayTime, byte fromType){ //fromType : 4 autoCWK return 1; //Check PTT while auto Sending - autoSendPTTCheck(); + //autoSendPTTCheck(); //Check_Cat(3); } @@ -1449,6 +1449,7 @@ void setup() factory_alignment(); #endif + rigState.begin(); } //Auto save Frequency and Mode with Protected eeprom life by KD8CEC @@ -1473,8 +1474,6 @@ void checkAutoSaveFreqMode() saveCheckTime = 0; //for reduce cpu use rate } } - - rigState.begin(); } void loop(){ diff --git a/Raduino/ubitx_keyer.ino b/Raduino/ubitx_keyer.ino index 691b1d0..f6bae39 100644 --- a/Raduino/ubitx_keyer.ino +++ b/Raduino/ubitx_keyer.ino @@ -296,7 +296,7 @@ void cwKeyer(void){ return; //Tx stop control by Main Loop } - Check_Cat(2); + //Check_Cat(2); } //end of while // } //end of elese } diff --git a/Raduino/ubitx_lcd_nextion.ino b/Raduino/ubitx_lcd_nextion.ino index 64c96ed..e260951 100644 --- a/Raduino/ubitx_lcd_nextion.ino +++ b/Raduino/ubitx_lcd_nextion.ino @@ -994,7 +994,9 @@ char checkCountSMeter = 0; void idle_process() { // KC4UPR 2021-02-05 added update process for Raduino-TeensyDSP coordination - rigState.update(); + rigState.send_RIGINF(); + delay(1); + rigState.receive_RIGINF(); //updateStateFromRaduino(rigState); //doRaduinoToTeensy(&rigState); //updateRaduinoFromState(rigState); diff --git a/Raduino/ubitx_menu.ino b/Raduino/ubitx_menu.ino index 502bd94..efeeda2 100644 --- a/Raduino/ubitx_menu.ino +++ b/Raduino/ubitx_menu.ino @@ -263,7 +263,7 @@ void menuCHMemory(int btn, byte isMemoryToVfo){ } } - Check_Cat(0); //To prevent disconnections + //Check_Cat(0); //To prevent disconnections } //end of while (knob) if (selectChannel < 20 && selectChannel >= 0) @@ -697,7 +697,7 @@ int getValueByKnob(int valueType, int targetValue, int minKnobValue, int maxKnob } } - Check_Cat(0); //To prevent disconnections + //Check_Cat(0); //To prevent disconnections } return targetValue; @@ -1290,7 +1290,7 @@ void doMenu(){ default : menuExit(btnState); break; } //end of switch - Check_Cat(0); //To prevent disconnections + //Check_Cat(0); //To prevent disconnections } //end of while //**************************************************************************** @@ -1690,7 +1690,7 @@ void menuSetupCarrier(int btn){ si5351bx_setfreq(0, usbCarrier); printCarrierFreq(usbCarrier); - Check_Cat(0); //To prevent disconnections + //Check_Cat(0); //To prevent disconnections delay(100); } diff --git a/Schematics/SW_Architecture.odg b/Schematics/SW_Architecture.odg new file mode 100644 index 0000000..1014f0e Binary files /dev/null and b/Schematics/SW_Architecture.odg differ diff --git a/TeensyDSP/DSP.cpp b/TeensyDSP/DSP.cpp index eecb5fa..f1689c9 100644 --- a/TeensyDSP/DSP.cpp +++ b/TeensyDSP/DSP.cpp @@ -28,18 +28,19 @@ UBitxDSP DSP; //static struct { // GUItool: begin automatically generated code -AudioInputUSB usbIn; //xy=227,290 -AudioInputI2S lineIn; //xy=235,182 -AudioAnalyzeRMS usbInRMS_R; //xy=350,380 -AudioAnalyzeRMS usbInRMS_L; //xy=409,341 -AudioAnalyzeRMS lineInRMS; //xy=461,222 -AudioMixer4 rxAudio; //xy=492,96 -AudioMixer4 txAudio; //xy=496,284 -AudioFilterFIR rxFilter; //xy=657,88 -AudioAmplifier usbOutAmp; //xy=822,84 -AudioAmplifier lineOutAmp; //xy=823,147 -AudioOutputI2S lineOut; //xy=1040,279 -AudioOutputUSB usbOut; //xy=1042,240 +AudioInputUSB usbIn; //xy=153,341 +AudioInputI2S lineIn; //xy=161,233 +AudioAnalyzeRMS usbInRMS_R; //xy=276,431 +AudioAnalyzeRMS usbInRMS_L; //xy=335,392 +AudioAnalyzeRMS lineInRMS; //xy=387,273 +AudioMixer4 rxAudio; //xy=418,147 +AudioMixer4 txAudio; //xy=422,335 +AudioFilterFIR rxFilter; //xy=583,139 +AudioAmplifier usbOutAmp; //xy=748,135 +AudioAmplifier lineOutAmp; //xy=749,198 +AudioAmplifier usbBypassAmp; //xy=756,261 +AudioOutputI2S lineOut; //xy=966,330 +AudioOutputUSB usbOut; //xy=968,291 AudioConnection patchCord1(usbIn, 0, txAudio, 1); AudioConnection patchCord2(usbIn, 0, usbInRMS_L, 0); AudioConnection patchCord3(usbIn, 1, usbInRMS_R, 0); @@ -47,13 +48,14 @@ AudioConnection patchCord4(lineIn, 0, rxAudio, 0); AudioConnection patchCord5(lineIn, 1, txAudio, 0); AudioConnection patchCord6(lineIn, 1, lineInRMS, 0); AudioConnection patchCord7(rxAudio, rxFilter); -AudioConnection patchCord8(rxAudio, 0, usbOut, 1); +AudioConnection patchCord8(rxAudio, usbBypassAmp); AudioConnection patchCord9(txAudio, 0, lineOut, 1); AudioConnection patchCord10(rxFilter, usbOutAmp); AudioConnection patchCord11(rxFilter, lineOutAmp); AudioConnection patchCord12(usbOutAmp, 0, usbOut, 0); AudioConnection patchCord13(lineOutAmp, 0, lineOut, 0); -AudioControlSGTL5000 audioCtrl; //xy=501,425 +AudioConnection patchCord14(usbBypassAmp, 0, usbOut, 1); +AudioControlSGTL5000 audioCtrl; //xy=427,476 // GUItool: end automatically generated code //} audio; @@ -99,10 +101,11 @@ void UBitxDSP::begin() { // SETUP THE AUDIO OUTPUTS // Line Output (RX) - lineOutAmp.gain(0.0); + lineOutAmp.gain(1.0); // USB Output (RX) - usbOutAmp.gain(0.0); + usbOutAmp.gain(1.0); + usbBypassAmp.gain(1.0); // Rig (Line) Output (TX) @@ -123,6 +126,9 @@ void UBitxDSP::begin() { state.voxDelay[TX_USB_IN_R_VOX] = TX_USB_IN_R_VOX_DELAY; state.voxTimeout[TX_USB_IN_R_VOX] = 0; + // Setup the RX Filter. + setRxFilter(300, 3000); + sinceLastUpdate = 0; } diff --git a/TeensyDSP/Debug.h b/TeensyDSP/Debug.h index aa18b3d..3b0da56 100644 --- a/TeensyDSP/Debug.h +++ b/TeensyDSP/Debug.h @@ -8,11 +8,13 @@ #define DBGPRINTLN(MSG) do { Serial.print("DBG: "); Serial.println(MSG); } while (0) #define DBGNEWLINE() do { Serial.println(); } while (0) #define DBGCMD(CMD) do { Serial.print("DBG: "); Serial.println(#CMD); CMD; } while (0) +#define IFDEBUG(CMD) do { CMD; } while (0) #else #define DBGPRINT(MSG) do {} while (0) #define DBGPRINTLN(MSG) do {} while (0) #define DBGNEWLINE() do {} while (0) #define DBGCMD(CMD) do { CMD; } while (0) +#define IFDEBUG(CMD) do {} while (0) #endif #endif diff --git a/TeensyDSP/Rig.h b/TeensyDSP/Rig.h index bbb67fe..65cf04c 100644 --- a/TeensyDSP/Rig.h +++ b/TeensyDSP/Rig.h @@ -15,31 +15,31 @@ class UBitxRig { inline bool isVFOA() const { return radState.isVFOA(); } inline bool isVFOB() const { return radState.isVFOB(); } inline bool isSplit() const { return radState.isSplit(); } - inline bool isRITOn() const { return radState.isRITOn(); } - inline bool isXITOn() const { return radState.isXITOn(); } - inline bool isModeCW() const { return radState.isCW() && radState.isUSB(); } - inline bool isModeCWR() const { return radState.isCW() && radState.isLSB(); } - inline bool isModeUSB() const { return radState.isUSB() && !radState.isCW(); } - inline bool isModeLSB() const { return radState.isLSB() && !radState.isCW(); } + inline bool isRIT() const { return radState.isRIT(); } + inline bool isXIT() const { return radState.isXIT(); } + inline bool isModeCWAny() const { return radState.isModeCWAny(); } + inline bool isModeCW() const { return radState.isModeCW(); } + inline bool isModeCWR() const { return radState.isModeCWR(); } + inline bool isModeUSB() const { return radState.isModeUSB(); } + inline bool isModeLSB() const { return radState.isModeLSB(); } inline bool isAI() const { return autoInfo; } inline void setFreqA(unsigned freq) { catState.setFreqA(freq); } inline void setFreqB(unsigned freq) { catState.setFreqB(freq); } inline void setRIT(int freq) { catState.setRIT(freq); } inline void setXIT(int freq) { catState.setXIT(freq); } - inline void selectVFOA() { catState.selectVFOA(); } - inline void selectVFOB() { catState.selectVFOA(); } - inline void toggleVFO() { catState.toggleVFO(); } + inline void setVFOA() { catState.setVFOA(); } + inline void setVFOB() { catState.setVFOB(); } inline void setSplitOn() { catState.setSplitOn(); } inline void setSplitOff() { catState.setSplitOff(); } inline void setRITOn() { catState.setRITOn(); } inline void setRITOff() { catState.setRITOff(); } inline void setXITOn() { catState.setXITOn(); } inline void setXITOff() { catState.setXITOff(); } - inline void setModeCW() { catState.setUSB(); catState.setCW(); } - inline void setModeCWR() { catState.setLSB(); catState.setCW(); } - inline void setModeUSB() { catState.setUSB(); catState.setCW(); } - inline void setModeLSB() { catState.setLSB(); catState.setCW(); } + inline void setCW() { catState.setCW(); } + inline void setCWR() { catState.setCWR(); } + inline void setUSB() { catState.setUSB(); } + inline void setLSB() { catState.setLSB(); } inline void aiOn() { autoInfo = true; } inline void aiOff() { autoInfo = false; } diff --git a/TeensyDSP/RigState.cpp b/TeensyDSP/RigState.cpp index 44e7bb8..da25d38 100644 --- a/TeensyDSP/RigState.cpp +++ b/TeensyDSP/RigState.cpp @@ -1,13 +1,62 @@ -#include "" +/*! + * @file RigState.cpp + * + * @mainpage uBITX V5X Software - RigState + * + * @section introsec Introduction + * + * TBD + * + * @section dependencies Dependencies + * + * TBD + * + * @section author Author + * + * Written by Rob "Scrape" French, KC4UPR + * + * @section license License + * + * TBD + */ -/**********************************************************************/ -// Raduino externs -- generally defined in Raduino.ino or ubitx.h +#include "Debug.h" +#include "RigState.h" + +/*********************************************************************** + * COMMON FUNCTIONS + * + * The following are all common to RigState objects, whether on the + * Raduino or on the TeensyDSP. + **********************************************************************/ + +static uint32_t zeroes[1] = {0}; // used to transmit zeroes + +/*! + * @brief Begin using the RigState object. In order to force an + * initial update (i.e. sending current state to the remote + * device), all fields are initially marked dirty. + */ +void UBitxRigState::begin() { + setDirty(); +} + +/*********************************************************************** + * RADUINO FUNCTIONS + * + * The following are specific to the Raduino implementation. Note that + * this depends on the use of the TEENSYDUINO #define, which may result + * in a fragile implementation for other development environments (e.g. + * if the normal Arduino IDE is not being used). + **********************************************************************/ #ifndef TEENSYDUINO +#include +#include "ubitx.h" #include "ubitx_eemap.h" -extern unsigned long frequency; +extern unsigned long frequency, ritRxFrequency, ritTxFrequency; extern unsigned long vfoA; extern unsigned long vfoB; extern char cwMode; @@ -15,48 +64,115 @@ extern char isUSB; extern char vfoActive; extern char ritOn; extern char splitOn; +extern char inTx; void setFrequency(unsigned long); /*! - * @brief Write dirty fields from the provided rig state, out to the - * Raduino variables. - * @param r - * Reference to a RigState object that will be used to update - * the Raduino variables. + * @brief Send the RigState from the Raduino to the TeensyDSP. The + * basic process is: (1) read in any updated (dirty) data + * from the Raduino's state variables; (2) transmit the dirty + * data to the TeensyDSP; (2a) for clean data, zeroes are + * transmitted; (3) mark all data as clean. */ -void writeDirty(const RigState& r) { - // VFO A frequency - if (r.isDirty(VFOA_WORD)) { - if (vfoActive == VFO_A) { - setFrequency(r.getFreqA()); +void UBitxRigState::send_RIGINF() { + readDirty(); + Wire.beginTransmission(I2CMETER_ADDR); + Wire.write(I2CMETER_RIGINF); + for (RigStateWord i = DIRTY_WORD; i < NUM_WORDS; i++) { + if (i == DIRTY_WORD || isDirty(i)) { + // always send the current dirty bits + // or, bytes for updated (dirty) fields + Wire.write((byte*)&data[i], sizeof(uint32_t)); } else { - vfoA = r.getFreqA(); + // otherwise, send out zeroes + Wire.write((byte*)&zeroes, sizeof(uint32_t)); + //---------------------------------------------------------------- + // NOTE: I am sending these zeroed out fields under a possibly + // mistaken assumption that in doing so, I will be sending a + // constant voltage on the SDA line most of the time, i.e. no + // bit changes, and so this will help reduce noise generated by + // I2C traffic (since most of the time there will be no updates.) + //---------------------------------------------------------------- + } + } + Wire.endTransmission(); + IFDEBUG( serialHexState("Sent") ); + //IFDEBUG( serialPrettyState("Sent") ); + setClean(); +} + +// delay(1); // 1ms - some delay required between ending transmission and requesting? + +/*! + * @brief Receive the RigState from the TeensyDSP. This generally + * reflects changes due to CAT transmission to the TeensyDSP. + * @param numBytes + * Number of bytes received from the TeensyDSP. + */ +void UBitxRigState::receive_RIGINF(int numBytes) { + // Retrieve all of the deltas. Mark any received fields as dirty. It + // is assumed that send_RIGINF() was called immedaitely before this, + // so the fields are already clean. + byte* ptr = (byte*)&data; + Wire.requestFrom(I2CMETER_ADDR, sizeof(data)); + for (RigStateWord i = DIRTY_WORD; i < NUM_WORDS && Wire.available(); i++) { + for (size_t j = 0; j < sizeof(uint32_t) && Wire.available(); j++) { + byte incomingByte = Wire.read(); + if (i == DIRTY_WORD || isDirty(i)) { + // always overwrite the dirty bits + // and, update bytes for fields marked dirty + *ptr = incomingByte; + } + ptr++; + } + } + writeDirty(); + IFDEBUG( serialHexState("Rcvd") ); + //IFDEBUG( serialPrettyState("Rcvd") ); + setClean(); // They get marked dirty as req'd during readDirty(). +} + +/*! + * @brief Write dirty fields from the RigState out to the Raduino + * variables. + */ +void UBitxRigState::writeDirty() { + // VFO A frequency + if (isDirty(VFOA_WORD)) { + if (vfoActive == VFO_A) { + setFrequency(getFreqA()); + } else { + vfoA = getFreqA(); } } // VFO B frequency - if (r.isDirty(VFOB_WORD)) { + if (isDirty(VFOB_WORD)) { if (vfoActive == VFO_B) { - setFrequency(r.getFreqB()); + setFrequency(getFreqB()); } else { - vfoB = r.getFreqB(); + vfoB = getFreqB(); } } // RIT and XIT frequencies - if (r.isDirty(OFFSETS_WORD)) { + if (isDirty(OFFSETS_WORD)) { // RIT - ritRxFrequency = r.getRIT() + ritTxFrequency; - if ((ritOn == 1) && (inTx == 0)) { - setFrequency(ritRxFrequency); + ritRxFrequency = getRIT() + ritTxFrequency; + if (ritOn == 1) { + if (inTx == 0) { + setFrequency(ritRxFrequency); + } else { + setFrequency(ritTxFrequency); + } } // XIT - TODO } // VFO A/B selection - if (r.isDirty(FLAGS_WORD)) { + if (isDirty(FLAGS_WORD)) { char prev = vfoActive; - vfoActive = r.isVFOA() ? VFO_A : VFO_B; + vfoActive = isVFOA() ? VFO_A : VFO_B; if (vfoActive != prev) { if (vfoActive == VFO_A) { if (vfoA != frequency) { @@ -70,11 +186,11 @@ void writeDirty(const RigState& r) { } // Split on/off - splitOn = r.isSplit() ? 1 : 0; + splitOn = isSplit() ? 1 : 0; // RIT on/off prev = ritOn; - ritOn = r.isRIT() ? 1 : 0; + ritOn = isRIT() ? 1 : 0; if (ritOn != prev) { if ((ritOn == 1) && (inTx == 0)) { setFrequency(ritRxFrequency); @@ -86,10 +202,10 @@ void writeDirty(const RigState& r) { // Mode prev = (cwMode << 1) | isUSB; - isUSB = r.isUSB() ? 1 : 0; - if (r.isCW()) { + isUSB = isModeUSB() ? 1 : 0; + if (isModeCW()) { cwMode = 2; // 2 = cwu - } else if (r.isCWR()) { + } else if (isModeCWR()) { cwMode = 1; // 1 = cwl } else { cwMode = 0; // 0 = no cw @@ -101,274 +217,200 @@ void writeDirty(const RigState& r) { } /*! - * @brief Read current Raduino variables into the provided RigState - * (if they are dirty) and set the appropriate dirty flags. + * @brief Read current Raduino variables into the RigState + * (if they are changed) and set the appropriate dirty flags. * @param r * RigState reference to put the values into. */ -void readDirty(RigState& r) { - unsigned freq; +void UBitxRigState::readDirty() { + unsigned long freq; short offset; // VFO A frequency freq = (vfoActive == VFO_A) ? frequency : vfoA; - if (r.getFreqA() != freq) { - r.setFreqA(freq); - r.setDirty(VFOA_WORD); + if (getFreqA() != freq) { + setFreqA(freq); } // VFO B frequency freq = (vfoActive == VFO_B) ? frequency : vfoB; - if (r.getFreqB() != freq) { - r.setFreqB(freq); - r.setDirty(VFOB_WORD); + if (getFreqB() != freq) { + setFreqB(freq); } // RIT frequency - offset = ritRxFrequency - frequency; - if (r.getRIT() != offset) { - r.setRIT(offset); - r.setDirty(OFFSETS_WORD); + if (inTx) { + offset = ritRxFrequency - ritTxFrequency; + } else { + offset = frequency - ritTxFrequency; + } + if (getRIT() != offset) { + setRIT(offset); } // XIT frequency offset = 0; // xitRxFrequency - frequency; - if (r.getXIT() != offset) { - r.setXIT(offset); - r.setDirty(OFFSETS_WORD); + if (getXIT() != offset) { + setXIT(offset); } - - bool dirty = false; - + // VFO A/B selection - if (r.isVFOA() && vfoActive == VFO_B) { - r.setVFOB(); - dirty = true; - } else if (r.isVFOB() && vfoActive == VFO_A) { - r.setVFOA(); - dirty = true; + if (isVFOA() && vfoActive == VFO_B) { + setVFOB(); + } else if (isVFOB() && vfoActive == VFO_A) { + setVFOA(); } // Split selection - if (r.isSplit() && splitOn == 0) { - r.setSplitOff(); - dirty = true; - } else if (!r.isSplit() && splitOn != 0) { - r.setSplitOn(); - dirty = true; + if (isSplit() && splitOn == 0) { + setSplitOff(); + } else if (!isSplit() && splitOn != 0) { + setSplitOn(); } // RIT selection - if (r.isRIT() && ritOn == 0) { - r.setRITOff(); - dirty = true; - } else if (!r.isRIT() && ritOn != 0) { - r.setRITOn(); - dirty = true; + if (isRIT() && ritOn == 0) { + setRITOff(); + } else if (!isRIT() && ritOn != 0) { + setRITOn(); } // XIT selection - r.setXITOff(); + //setXITOff(); // TODO // Mode - char prev = (r.isCW() ? 4 : 0) | (r.isCWR() ? 2 : 0) | (r.isUSB() ? 1 : 0); + char prev = (isModeCW() ? 4 : 0) | (isModeCWR() ? 2 : 0) | (isModeUSB() ? 1 : 0); char curr = (cwMode << 1) | isUSB; if (curr != prev) { if (cwMode == 2) { - r.setCW(); + setCW(); } else if (cwMode == 1) { - r.setCWR(); + setCWR(); } else { if (isUSB) { - r.setUSB(); + setUSB(); } else { - r.setLSB(); + setLSB(); } } - dirty = true; } - - if (dirty) r.setDirty(FLAGS_WORD); +} + +/*********************************************************************** + * TEENSYDSP FUNCTIONS + * + * The following are specific to the TeensyDSP implementation. Note + * that this depends on the use of the TEENSYDUINO #define, which may + * result in a fragile implementation for other development environments + * (e.g. if the normal Arduino IDE is not being used). + **********************************************************************/ + +#else + +#include + +/*! + * @brief Receive RIGINF data from the Raduino. This method should + * be called on the TeensyDSP 'radState' (Raduino state) + * instance, when a RIGINF signal is received via I2C. It + * receives the incoming data from the Raduino and updates the + * state. + */ +void UBitxRigState::receive_RIGINF(int numBytes) { + byte* ptr = (byte*)&data; + setClean(); // we'll get new dirty bits via the I2C message + for (RigStateWord i = DIRTY_WORD; i < NUM_WORDS && Wire1.available(); i++) { + for (size_t j = 0; j < sizeof(uint32_t) && Wire1.available(); j++) { + byte incomingByte = Wire1.read(); + if (i == DIRTY_WORD || isDirty(i)) { + // always overwrite the dirty bits + // and, update bytes for fields marked dirty + *ptr = incomingByte; + } + ptr++; + } + } + + IFDEBUG( serialHexState("Rcvd") ); + IFDEBUG( serialPrettyState("Rcvd") ); +} + +/**********************************************************************/ +/*! + * @brief Handle a RIGINF signal from the Raduino. This method should + * be called on the TeensyDSP 'catState' (CAT state) + * instance, when a RIGINF signal is received via I2C. It + * sends a response to the Raduino via I2C, using the Wire1 + * interface. + */ +void UBitxRigState::send_RIGINF() { + for (RigStateWord i = DIRTY_WORD; i < NUM_WORDS; i++) { + if (i == DIRTY_WORD || isDirty(i)) { + // always send the current dirty bits + // or, bytes for updated (dirty) fields + Wire1.write((byte*)&data[i], sizeof(uint32_t)); + } else { + // otherwise, send out zeroes + Wire1.write((byte*)&zeroes, sizeof(uint32_t)); + //---------------------------------------------------------------- + // NOTE: I am sending these zeroed out fields under a possibly + // mistaken assumption that in doing so, I will be sending a + // constant voltage on the SDA line most of the time, i.e. no + // bit changes, and so this will help reduce noise generated by + // I2C traffic (since most of the time there will be no updates.) + //---------------------------------------------------------------- + } + } + IFDEBUG( serialHexState("Sent") ); + IFDEBUG( serialPrettyState("Sent") ); + setClean(); // now that we've sent them, they're clean + //-------------------------------------------------------------------- + // TODO: Need to look at possibly merging the two states together at + // this point. The purpose would be to minimize the turnaround time + // for getting the most recent data to a CAT response. + //-------------------------------------------------------------------- } #endif -/**********************************************************************/ +#ifdef DEBUG -BaseField* raduinoFields[WIREBUS_NUM_FIELDS] = { - new Field(), - new Field(), - new Field(), - new Field(), - new Field(), - new Field(), -}; +char debugString[81] = {'\0'}; -/**********************************************************************/ - -RigState::RigState(): RigState(raduinoFields, WIREBUS_NUM_FIELDS) {} - -/*! - * @brief Begin using the RigState object. In order to force an - * update (e.g. sending current state to the remote device), - * all fields are marked dirty. - */ -void RigState::begin() { - for (byte i = 0; i < numFields; i++) { - if (read(i)) { - makeDirty(i); - } - } +void UBitxRigState::serialHexState(const char* label = "RigState") { + Serial.print(label); + sprintf(debugString, ": %#010lx, %#010lx, %#010lx, %#010lx, %#010lx", + data[DIRTY_WORD], data[VFOA_WORD], data[VFOB_WORD], data[OFFSETS_WORD], data[FLAGS_WORD]); + Serial.println(debugString); } -void updateRaduinoState(RigState& r) { - writeDirty(r); - Wire.beginTransmission(I2CMETER_ADDR); - Wire.write(I2CMETER_RIGINF); - for (RigStateWord i = 0; i < NUM_WORDS; i++) { - Wire.write((byte*)&r.data, sizeof(r.data)); // - write the field data - r.setClean(i); - } - Wire.endTransmission(); - - delay(1); // 1ms - some delay required between ending transmission and requesting? - - // Retrieve all of the deltas. Mark any received field as dirty. - Wire.requestFrom(I2CMETER_ADDR, numBytes); - bool doRead = true; - int index = -1; - byte* ptr; - while (Wire.available()) { - byte b = Wire.read(); - if (index == -1) { - if (numFields > b) { - ptr = data(b); - field[b].dirty = true; - numDirty++; - index = 0; - } else { - doRead = false; - } - } else { - if (doRead) { - ptr[index] = b; - } - if (++index == 4) { - index = -1; - doRead = true; - } - } - } - - // Perform the corresponding update for each dirty field. - for (byte i = 0; i < numFields; i++) { - if (field[i].dirty) { - write(i); - field[i].dirty = false; - numDirty--; - } - } +void UBitxRigState::serialPrettyState(const char* label = "RigState") { + Serial.println(label); + sprintf(debugString, "VFO A : %011ld %1c / VFO B : %011ld %1c", + getFreqA(), isDirty(VFOA_WORD) ? 'D' : ' ', getFreqB(), isDirty(VFOB_WORD) ? 'D' : ' '); + Serial.println(debugString); + sprintf(debugString, "RIT : %011ld %1c / XIT : %011ld %1c", + getRIT(), isDirty(OFFSETS_WORD) ? 'D' : ' ', getXIT(), isDirty(OFFSETS_WORD) ? 'D' : ' '); + Serial.println(debugString); + sprintf(debugString, "Split? %1c / VFO? %1c / RIT? %1c / XIT? %1c / Mode? %3s", + isSplit() ? 'Y' : 'N', isVFOA() ? 'A' : 'B', isRIT() ? 'Y' : 'N', isXIT() ? 'Y' : 'N', + isModeUSB() ? "USB" : (isModeLSB() ? "LSB" : (isModeCW() ? "CW " : (isModeCWR() ? "CWR" : " ")))); + Serial.println(debugString); } -/**********************************************************************/ -/*! - * @brief Handle a RIGINF signal from the Raduino. This method should - * be called on the TeensyDSP 'radState' (Raduino state) - * instance, when a RIGINF signal is received via I2C. It - * receives the incoming data from the Raduino. - */ -void RigState::receive_RIGINF() { - // 1st (-1) byte read should be a field index. - // 2nd (0) thru 5th (3) bytes are bytes of the field. - // We'll read as many fields as the Raduino sends. - bool doRead = true; - int index = -1; - byte* ptr; - while (Wire1.available()) { - byte b = Wire1.read(); - if (index == -1) { - if (numFields > b) { - ptr = data(b); - makeDirty(b); - index = 0; - } else { - doRead = false; - } - } else { - if (doRead) { - ptr[index] = b; - } - if (++index == 4) { - index = -1; - doRead = true; - } - } - } -} +#endif -/**********************************************************************/ -/*! - * @brief Handle a RIGINF signal from the Raduino. This method should - * be called on the TeensyDSP 'radState' (Raduino state) - * instance, when a RIGINF signal is received via I2C. It - * sends a response to the Raduino - */ -void RigState::send_RIGINF(byte numBytes, RigState& catState) { - // Now we need to determine the differences from the other state (i.e. - // from the catState) and send those differences. - byte rigRegBytes = 0; - for (byte i = 0; i < numFields; i++) { - if (isDirty(i) && !catState.isDirty(i)) { - catState.field[i]->data = field[i]->data; - makeClean(i); - } else if (catState.isDirty(i)) { - field[i]->data = catState.field[i]->data; - makeClean(i); - rigRegBytes += (sizeof(byte) + sizeof(uint32_t)); // size of field ID and data - } - } - - for (byte i = 0; i < numBytes; i++) { - Wire1.write(rigReqBytes); - } -} - -/**********************************************************************/ -/*! - * @brief Handle a RIGREQ signal from the Raduino. This method should - * be called on the TeensyDSP 'catState' (CAT state) instance, - * when a RIGREQ signal is received via I2C. It handles - * sending the changed fields. - */ -void RigState::respondRIGREQ(byte numBytes) { - byte bytesSent = 0; - - for (byte i = 0; i < numFields; i++) { - if (isDirty(i) && (dataSize(i) + sizeof(byte) <= numBytes - bytesSent)) { // Write each field that is dirty to the bus. - Wire1.write(i); // - write the field number/ID - Wire1.write(data(i), dataSize(i)); // - write the field data - makeClean(i); - bytesSent += dataSize(i) + sizeof(byte); - } - } - - // Don't know if this is necessary, but if we haven't written enough - // bytes yet, we'll write out some zeroes. - for (byte i = bytesSent; i < numBytes; i++) { - Wire1.write(0); - } -} /**********************************************************************/ #ifndef TEENSYDUINO -RigState rigState; +UBitxRigState _rigState; +UBitxRigState& rigState = _rigState; #endif -/********************************************************************** - * EOF * +/*********************************************************************** + * EOF **********************************************************************/ - diff --git a/TeensyDSP/RigState.h b/TeensyDSP/RigState.h index edb91d6..a50d5e5 100644 --- a/TeensyDSP/RigState.h +++ b/TeensyDSP/RigState.h @@ -1,3 +1,7 @@ +/*! + * @file RigState.h + */ + #ifndef __RigState_h__ #define __RigState_h__ @@ -11,6 +15,12 @@ #define UBITX_USB_FLAG 0x00000020 #define UBITX_TX_FLAG 0x00000040 +#ifdef TEENSYDUINO +#define DISABLEINTS(CMD) do { noInterrupts(); CMD; interrupts(); } while (0) +#else +#define DISABLEINTS(CMD) do { CMD; } while (0) +#endif + enum RigStateWord { DIRTY_WORD = 0, VFOA_WORD, @@ -20,174 +30,307 @@ enum RigStateWord { NUM_WORDS }; +inline RigStateWord& operator++(RigStateWord& orig) { + orig = static_cast(orig + 1); + // NOTE: Will overflow... + return orig; +} + +inline RigStateWord operator++(RigStateWord& orig, int) { + RigStateWord rVal = orig; + ++orig; + return rVal; +} + struct UBitxRigState { - uint32_t data[RigStateWord.NUM_WORDS] = {0}; + volatile uint32_t data[NUM_WORDS] = {0}; + + void begin(); + + void send_RIGINF(); + void receive_RIGINF(int numBytes = sizeof(data)); /*! - * @brief Set the dirty bit for for the specified word. + * @brief Set the dirty bit for the specified word. + * + * @param w + * The word to mark as dirty. */ inline void setDirty(RigStateWord w) { - data[i] |= w < NUM_WORDS ? 1 << w : 0; + data[DIRTY_WORD] |= w < NUM_WORDS ? 1 << w : 0; } + /*! + * @brief Set the dirty bits for all words. + */ + inline void setDirty() { DISABLEINTS( data[DIRTY_WORD] = 0xFFFFFFFF ); } + + /*! + * @brief Clear the dirty bit for the specified word. + * + * @param w + * The word to mark as clean. + */ inline void setClean(RigStateWord w) { - data[i] &= ~(w < NUM_WORDS ? 1 << w : 0); + data[DIRTY_WORD] &= ~(w < NUM_WORDS ? 1 << w : 0); } + /*! + * @brief Clear the dirty bits for all words. + */ + inline void setClean() { DISABLEINTS( data[DIRTY_WORD] = 0 ); } + + /*! + * @brief Check whether the specified word is clean. + * + * @param w + * The word to check for clean status. + * + * @return True if the word is clean. + */ + inline bool isClean(RigStateWord w) { + bool clean; + DISABLEINTS( clean = ((1 << w) & data[DIRTY_WORD]) > 0 ? false : true ); + return clean; + } + + /*! + * @brief Check whether the data is clean (as a whole). + * + * @return True if the data is clean (no dirty fields). + */ + inline bool isClean() { + bool clean; + DISABLEINTS( clean = data[DIRTY_WORD] == 0 ); + return clean; + } + + /*! + * @brief Check whether the specified word is dirty. + * + * @param w + * The word to check for dirty status. + * + * @return True if the word is dirty. + */ inline bool isDirty(RigStateWord w) { - return (1 << w) & data[DIRTY_WORD] > 0 ? true : false; + bool dirty; + DISABLEINTS( dirty = ((1 << w) & data[DIRTY_WORD]) > 0 ? true : false ); + return dirty; + } + + /*! + * @brief Check whether the data is dirty (as a whole). + * + * @return True if the data is dirty (at least one dirty field). + */ + inline bool isDirty() { + bool dirty; + DISABLEINTS( dirty = data[DIRTY_WORD] != 0 ); + return dirty; } - inline void setFreqA(uint32_t freq) { data[VFOA_WORD] = freq; } - inline uint32_t getFreqA() const { return data[VFOA_WORD]; } - inline void getFreqB(uint32_r freq) { data[VFOB_WORD] = freq; } - inline uint32_t getFreqB() const { return data[VFOB_WORD]; } - inline void setRIT(int16_t offset) { data[OFFSETS_WORD] = (offset << 16) | (0x0000FFFF & data[OFFSETS_WORD]); } - inline int16_t getRIT() const { return data[OFFSETS_WORD] >> 16; } - inline void setXIT(int16_t offset) { data[OFFSETS_WORD] = (0xFFFF0000 & data[OFFSETS_WORD]) | offset; - inline int16_t getXIT() const { return 0x0000FFFF & data[OFFSETS_WORD]; } - inline void setVFOA() { data[FLAGS_WORD] &= ~UBITX_VFOB_FLAG; } - inline void setVFOB() { data[FLAGS_WORD] |= UBITX_VFOB_FLAG; } - inline bool isVFOA() const { return data[FLAGS_WORD] & UBITX_VFOB_FLAG ? false : true; } - inline bool isVFOB() const { return data[FLAGS_WORD] & UBITX_VFOB_FLAG ? true : false; } - inline void setSplitOn() { data[FLAGS_WORD] |= UBITX_SPLIT_FLAG; } - inline void setSplitOff() { data[FLAGS_WORD] &= ~UBITX_SPLIT_FLAG; } - inline bool isSplit() const { data[FLAGS_WORD] & UBITX_SPLIT_FLAG ? true : false; } - inline void setRITOn() { data[FLAGS_WORD] |= UBITX_RIT_FLAG; } - inline void setRITOff() { data[FLAGS_WORD] &= ~UBITX_RIT_FLAG; } - inline bool isRIT() const { data[FLAGS_WORD] & UBITX_RIT_FLAG ? true : false; } - inline void setXITOn() { data[FLAGS_WORD] |= UBITX_XIT_FLAG; } - inline void setXITOff() { data[FLAGS_WORD] &= ~UBITX_XIT_FLAG; } - inline bool isXIT() const { data[FLAGS_WORD] & UBITX_XIT_FLAG ? true : false; } - inline void setUSB() { data[FLAGS_WORD] |= UBITX_USB_FLAG; data[FLAGS_WORD] &= ~UBITX_CW_FLAG; } - inline void setLSB() { data[FLAGS_WORD] &= ~UBITX_USB_FLAG; data[FLAGS_WORD] &= ~UBITX_CW_FLAG; } - inline void setCW() { data[FLAGS_WORD] |= UBITX_USB_FLAG; data[FLAGS_WORD] |= UBITX_CW_FLAG; } - inline void setCWR() { data[FLAGS_WORD] &= ~UBITX_USB_FLAG; data[FLAGS_WORD] |= UBITX_CW_FLAG; } - inline bool isUSB() { return (data[FLAGS_WORD] & UBITX_USB_FLAG > 0) && (data[FLAGS_WORD] & UBITX_CW_FLAG == 0); } - inline bool isLSB() { return (data[FLAGS_WORD] & UBITX_USB_FLAG == 0) && (data[FLAGS_WORD] & UBITX_CW_FLAG == 0); } - inline bool isCW() { return (data[FLAGS_WORD] & UBITX_USB_FLAG > 0) && (data[FLAGS_WORD] & UBITX_CW_FLAG > 0); } - inline bool isCWR() { return (data[FLAGS_WORD] & UBITX_USB_FLAG == 0) && (data[FLAGS_WORD] & UBITX_CW_FLAG > 0); } -}; + /*! + * @brief Set the VFO A frequency. + * + * @param freq + * The new frequency in Hz. + */ + inline void setFreqA(uint32_t freq, bool mark = true) { + DISABLEINTS( data[VFOA_WORD] = freq; + if (mark) setDirty(VFOA_WORD) ); + } + + inline uint32_t getFreqA() const { + uint32_t result; + DISABLEINTS( result = data[VFOA_WORD] ); + return result; + } -#ifndef TEENSYDUINO -void mergeDirty(const RigState& r); + /*! + * @brief Set the VFO B frequency. + * + * @param freq + * The new frequency in Hz. + */ + inline void setFreqB(uint32_t freq, bool mark = true) { + DISABLEINTS( data[VFOB_WORD] = freq ); + } + + inline uint32_t getFreqB() const { + uint32_t result; + DISABLEINTS( result = data[VFOB_WORD] ); + return result; + } + + inline void setRIT(int16_t offset, bool mark = true) { + DISABLEINTS( data[OFFSETS_WORD] = (int32_t(offset) << 16) | (0x0000FFFF & data[OFFSETS_WORD]); + if (mark) setDirty(OFFSETS_WORD) ); + } + + inline int16_t getRIT() const { + int16_t result; + DISABLEINTS( result = data[OFFSETS_WORD] >> 16 ); + return result; + } + + inline void setXIT(int16_t offset, bool mark = true) { + DISABLEINTS( data[OFFSETS_WORD] = (0xFFFF0000 & data[OFFSETS_WORD]) | offset; + if (mark) setDirty(OFFSETS_WORD) ); + } + + inline int16_t getXIT() const { + int16_t result; + DISABLEINTS( result = 0x0000FFFF & data[OFFSETS_WORD] ); + return result; + } + + inline void setVFOA(bool mark = true) { + DISABLEINTS( data[FLAGS_WORD] &= ~UBITX_VFOB_FLAG; + if (mark) setDirty(FLAGS_WORD) ); + } + + inline void setVFOB(bool mark = true) { + DISABLEINTS( data[FLAGS_WORD] |= UBITX_VFOB_FLAG; + if (mark) setDirty(FLAGS_WORD) ); + } + + inline bool isVFOA() const { + bool result; + DISABLEINTS( result = data[FLAGS_WORD] & UBITX_VFOB_FLAG ? false : true ); + return result; + } + + inline bool isVFOB() const { + bool result; + DISABLEINTS( result = data[FLAGS_WORD] & UBITX_VFOB_FLAG ? true : false ); + return result; + } + + inline void setSplitOn(bool mark = true) { + DISABLEINTS( data[FLAGS_WORD] |= UBITX_SPLIT_FLAG; + if (mark) setDirty(FLAGS_WORD) ); + } + + inline void setSplitOff(bool mark = true) { + DISABLEINTS( data[FLAGS_WORD] &= ~UBITX_SPLIT_FLAG; + if (mark) setDirty(FLAGS_WORD) ); + } + + inline bool isSplit() const { + bool result; + DISABLEINTS( result = data[FLAGS_WORD] & UBITX_SPLIT_FLAG ? true : false ); + return result; + } + + inline void setRITOn(bool mark = true) { + DISABLEINTS( data[FLAGS_WORD] |= UBITX_RIT_FLAG; + if (mark) setDirty(FLAGS_WORD) ); + } + + inline void setRITOff(bool mark = true) { + DISABLEINTS( data[FLAGS_WORD] &= ~UBITX_RIT_FLAG; + if (mark) setDirty(FLAGS_WORD) ); + } + + inline bool isRIT() const { + bool result; + DISABLEINTS( result = data[FLAGS_WORD] & UBITX_RIT_FLAG ? true : false ); + return result; + } + + inline void setXITOn(bool mark = true) { + DISABLEINTS( data[FLAGS_WORD] |= UBITX_XIT_FLAG; + if (mark) setDirty(FLAGS_WORD) ); + } + + inline void setXITOff(bool mark = true) { + DISABLEINTS( data[FLAGS_WORD] &= ~UBITX_XIT_FLAG; + if (mark) setDirty(FLAGS_WORD) ); + } + + inline bool isXIT() const { + bool result; + DISABLEINTS( result = data[FLAGS_WORD] & UBITX_XIT_FLAG ? true : false ); + return result; + } + + inline void setUSB(bool mark = true) { + DISABLEINTS( data[FLAGS_WORD] |= UBITX_USB_FLAG; + data[FLAGS_WORD] &= ~UBITX_CW_FLAG; + if (mark) setDirty(FLAGS_WORD) ); + } + + inline void setLSB(bool mark = true) { + DISABLEINTS( data[FLAGS_WORD] &= ~UBITX_USB_FLAG; + data[FLAGS_WORD] &= ~UBITX_CW_FLAG; + if (mark) setDirty(FLAGS_WORD) ); + } + + inline void setCW(bool mark = true) { + DISABLEINTS( data[FLAGS_WORD] |= UBITX_USB_FLAG; + data[FLAGS_WORD] |= UBITX_CW_FLAG; + if (mark) setDirty(FLAGS_WORD) ); + } + + inline void setCWR(bool mark = true) { + DISABLEINTS( data[FLAGS_WORD] &= ~UBITX_USB_FLAG; + data[FLAGS_WORD] |= UBITX_CW_FLAG; + if (mark) setDirty(FLAGS_WORD) ); + } + + inline bool isModeUSB() const { + bool result; + DISABLEINTS( result = ((data[FLAGS_WORD] & UBITX_USB_FLAG) > 0) && ((data[FLAGS_WORD] & UBITX_CW_FLAG) == 0) ); + return result; + } + + inline bool isModeLSB() const { + bool result; + DISABLEINTS( result = ((data[FLAGS_WORD] & UBITX_USB_FLAG) == 0) && ((data[FLAGS_WORD] & UBITX_CW_FLAG) == 0) ); + return result; + } + + inline bool isModeCWAny() const { + bool result; + DISABLEINTS( result = (data[FLAGS_WORD] & UBITX_CW_FLAG) > 0 ); + return result; + } + + inline bool isModeCW() const { + bool result; + DISABLEINTS( result = ((data[FLAGS_WORD] & UBITX_USB_FLAG) > 0) && ((data[FLAGS_WORD] & UBITX_CW_FLAG) > 0) ); + return result; + } + + inline bool isModeCWR() const { + bool result; + DISABLEINTS( result = ((data[FLAGS_WORD] & UBITX_USB_FLAG) == 0) && ((data[FLAGS_WORD] & UBITX_CW_FLAG) > 0) ); + return result; + } + +#ifdef DEBUG + void serialHexState(const char* label); + void serialPrettyState(const char* label); #endif -/**********************************************************************/ -// NEW IMPLEMENTATION - -struct BaseField { - BaseField(): dirty(false), data(0) {} - virtual ~BaseField() = 0; - - bool dirty; - uint32_t data; - - virtual bool read() = 0; - virtual void write() const = 0; -}; - -template -struct Field : public BaseField { - /*! - * @brief Using the supplied read function, which should take a - * pointer to data as its input, read from (some source) and - * update the value of data as appropriate. The read - * function should true if the new value is new and hence - * the dirty bit should be marked, false otherwise. - * @return True if data was updated (dirty), false otherwise. - */ - virtual bool read() { return R(&data); } - - /*! - * @brief Using the supplied write function, which should take - * data as its input, write data to some destination. - */ - virtual void write() const { W(data); } -}; - -#define WIREBUS_VFO_A 1 -#define WIREBUS_VFO_B 2 -#define WIREBUS_RIT_OFS 3 -#define WIREBUS_XIT_OFS 4 -#define WIREBUS_FLAGS 5 -#define WIREBUS_NUM_FIELDS 6 - -class RigState { - public: - RigState(BaseField** f = NULL, int numf = 0): field(f), numFields(numf), numDirty(0) {} - void begin(); - void update(); - - /*! - * @brief Read in the specified (by index) external value, and use - * it to update the rig state. - */ - inline bool read(byte i) { - return field[i]->read(); - } - - /*! - * @brief Use the specified (vy index) rig state field to update the - * external value. - */ - inline void write(byte i) { - field[i]->write(); - } - - inlie bool isDirty(byte i) { - return field[i]->dirty(); - } - - inline void makeDirty(byte i) { - if (!field[i]->dirty) { - field[i]->dirty = true; - numDirty++; - } - } - - inline void makeClean(byte i) { - if (field[i]->dirty) { - field[i]->dirty = false; - numDirty--; - } - } - - inline byte* data(byte i) { - return (byte*)(&(field[i]->data)); - } - - inline int dataSize(byte i) { - return sizeof(field[i]->data); - } - - inline unsigned getFreqA() const { return field[WIREBUS_VFO_A]->data; } - inline unsigned getFreqB() const { return field[WIREBUS_VFO_B]->data; } - inline int getRIT() const { return int(field[WIREBUS_VFO_A]->data); } - inline int getXIT() const { return int(field[WIREBUS_VFO_B]->data); } - inline bool isVFOA() const { return (field[WIREBUS_FLAGS]->data & UBITX_VFOB_FLAG) != UBITX_VFOB_FLAG; } - inline bool isVFOB() const { return (field[WIREBUS_FLAGS]->data & UBITX_VFOB_FLAG) == UBITX_VFOB_FLAG; } - inline bool isSplit() const { return (field[WIREBUS_FLAGS]->data & UBITX_SPLIT_FLAG) == UBITX_SPLIT_FLAG; } - inline bool isRITOn() const { return (field[WIREBUS_FLAGS]->data & UBITX_RIT_FLAG) == UBITX_RIT_FLAG; } - inline bool isXITOn() const { return (field[WIREBUS_FLAGS]->data & UBITX_XIT_FLAG) == UBITX_XIT_FLAG; } - inline bool isCW() const { return (field[WIREBUS_FLAGS]->data & UBITX_CW_FLAG) == UBITX_CW_FLAG; } - inline bool isLSB() const { return (field[WIREBUS_FLAGS]->data & UBITX_USB_FLAG) != UBITX_USB_FLAG; } - inline bool isUSB() const { return (field[WIREBUS_FLAGS]->data & UBITX_USB_FLAG) == UBITX_USB_FLAG; } - - static void merge(RigState& a, RigState& b); - - BaseField** field; - byte numFields; - byte numDirty; +#ifndef TEENSYDUINO + // These methods are only defined in the Raduino (Arduino) case of the + // RigState, not in the TeensyDSP (Teensy) case. + void writeDirty(); // write fields FROM RigState TO Raduino + void readDirty(); // read variables FROM Raduino TO RigState +#endif }; #ifndef TEENSYDUINO -extern RigState rigState; +extern UBitxRigState& rigState; #endif /* +NOTE: This is all currently OBE, leaving it here for reference/future cleanup. + Protocol discussion: - I2C master: Raduino - I2C slave: TeensyDSP @@ -221,5 +364,9 @@ TeensyDSP state: - Send dirty data over I2C. - Mark data as clean. */ - + #endif + +/*********************************************************************** + * EOF + **********************************************************************/ diff --git a/TeensyDSP/TS590.cpp b/TeensyDSP/TS590.cpp index d073c0f..3f51806 100644 --- a/TeensyDSP/TS590.cpp +++ b/TeensyDSP/TS590.cpp @@ -149,13 +149,13 @@ void TS590_FR::handleCommand(const char* cmd) { if (strlen(cmd) == 3) { switch (cmd[2]) { case '0': - rig()->selectVFOA(); - rig()->splitOff(); + rig()->setVFOA(); + rig()->setSplitOff(); break; case '1': - rig()->selectVFOB(); - rig()->splitOff(); + rig()->setVFOB(); + rig()->setSplitOff(); break; case '2': @@ -187,9 +187,9 @@ void TS590_FT::handleCommand(const char* cmd) { switch (cmd[2]) { case '0': if (rig()->isVFOA()) { - rig()->splitOff(); + rig()->setSplitOff(); } else if (rig()->isVFOB()) { - rig()->splitOn(); + rig()->setSplitOn(); } else { setSyntaxError(); } @@ -197,9 +197,9 @@ void TS590_FT::handleCommand(const char* cmd) { case '1': if (rig()->isVFOA()) { - rig()->splitOn(); + rig()->setSplitOn(); } else if (rig()->isVFOB()) { - rig()->splitOff(); + rig()->setSplitOff(); } else { setSyntaxError(); } @@ -238,19 +238,19 @@ void TS590_MD::handleCommand(const char* cmd) { break; case '1': // LSB - rig()->setModeLSB(); + rig()->setLSB(); break; case '2': // USB - rig()->setModeUSB(); + rig()->setUSB(); break; case '3': // CW - rig()->setModeCW(); + rig()->setCW(); break; case '7': // CW-R - rig()->setModeCWR(); + rig()->setCWR(); break; default: diff --git a/TeensyDSP/TeensyDSP.ino b/TeensyDSP/TeensyDSP.ino index bfeb3bd..d7ecda3 100644 --- a/TeensyDSP/TeensyDSP.ino +++ b/TeensyDSP/TeensyDSP.ino @@ -438,6 +438,7 @@ void i2cRequestEvent(void) // NEEDS TO GET UPDATED break; +/* case I2CMETER_REQCAT: // Provide latest CAT updates, if any. //Wire1.write(catState.header); // temporary - just writing a single, null byte @@ -457,7 +458,7 @@ void i2cRequestEvent(void) Wire1.write(0); } break; - +*/ default: break; } @@ -526,9 +527,9 @@ void loop() } // If CW mode, we need to update keying a lot... - if (Rig.isCW()) { - if (Rig.isCW()) Keyer.doPaddles(); - TR.update(Rig.isCW(), Keyer.isDown()); + if (Rig.isModeCWAny()) { + if (Rig.isModeCWAny()) Keyer.doPaddles(); + TR.update(Rig.isModeCWAny(), Keyer.isDown()); //if (TR.transmitting()) return; } @@ -543,11 +544,11 @@ void loop() // Update each of the subsystems, beginning with CAT control. TS590.update(); - TR.update(Rig.isCW(), Keyer.isDown()); + TR.update(Rig.isModeCWAny(), Keyer.isDown()); Rig.update(); DSP.update(); - //if (Rig.isCW()) return; + //if (Rig.isModeCWAny()) return; #ifdef DEBUG // For debugging, output some debug info every 1.0" (40 frames @ 40 Hz). @@ -670,7 +671,7 @@ void loop() forwardData(); } - if (Rig.isCW()) return; // In CW, the ADC measurement messes with the timing. So need to use interrupts on the Keyer, and/or continuous ADC. + if (Rig.isModeCWAny()) return; // In CW, the ADC measurement messes with the timing. So need to use interrupts on the Keyer, and/or continuous ADC. if (sinceADCMillis > adcIntervalMillis) { // Do stuff that we do once per ADC interval--ADC colllection. @@ -688,7 +689,7 @@ void loop() //forwardData(); } - //if (Rig.isCW()) return; + //if (Rig.isModeCWAny()) return; // Check Response Command if (responseCommand > 0 && sinceForward > LAST_TIME_INTERVAL) diff --git a/Raduino/cat_libs.ino b/raduino-tmp/cat_libs.ino similarity index 100% rename from Raduino/cat_libs.ino rename to raduino-tmp/cat_libs.ino diff --git a/Raduino/cw_autokey.ino b/raduino-tmp/cw_autokey.ino similarity index 100% rename from Raduino/cw_autokey.ino rename to raduino-tmp/cw_autokey.ino