Updates to RigState.
This commit is contained in:
		| @@ -18,7 +18,7 @@ const PROGMEM uint8_t meters_bitmap[] = { | |||||||
| }; | }; | ||||||
| */ | */ | ||||||
|  |  | ||||||
| #include "RigState.h" | //#include "RigState.h" | ||||||
|  |  | ||||||
| //SWR GRAPH,  DrawMeter and drawingMeter Logic function by VK2ETA  | //SWR GRAPH,  DrawMeter and drawingMeter Logic function by VK2ETA  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,6 +5,8 @@ | |||||||
|  |  | ||||||
| #ifndef TEENSYDUINO | #ifndef TEENSYDUINO | ||||||
|  |  | ||||||
|  | #include "ubitx_eemap.h" | ||||||
|  |  | ||||||
| extern unsigned long frequency; | extern unsigned long frequency; | ||||||
| extern unsigned long vfoA; | extern unsigned long vfoA; | ||||||
| extern unsigned long vfoB; | extern unsigned long vfoB; | ||||||
| @@ -15,123 +17,46 @@ extern char ritOn; | |||||||
| extern char splitOn; | extern char splitOn; | ||||||
| void setFrequency(unsigned long); | void setFrequency(unsigned long); | ||||||
|  |  | ||||||
| #endif | /*! | ||||||
|  |  *  @brief  Write dirty fields from the provided rig state, out to the | ||||||
| /**********************************************************************/ |  *          Raduino variables. | ||||||
| // Raduino functors - used to read/write from Raduino state |  *  @param  r | ||||||
|  |  *          Reference to a RigState object that will be used to update  | ||||||
| #ifndef TEENSYDUINO |  *          the Raduino variables. | ||||||
|  |  */ | ||||||
| struct readNone { | void writeDirty(const RigState& r) { | ||||||
|   bool operator()(uint32_t* d) { |   // VFO A frequency | ||||||
|     return false; |   if (r.isDirty(VFOA_WORD)) { | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| struct writeNone { |  | ||||||
|   void operator()(uint32_t d) { |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| struct readVFOA { |  | ||||||
|   bool operator()(uint32_t* d) { |  | ||||||
|     unsigned freq = (vfoActive == VFO_A) ? frequency : vfoA; |  | ||||||
|     if (*d == freq) { |  | ||||||
|       return false; |  | ||||||
|     } else { |  | ||||||
|       *d = freq; |  | ||||||
|       return true; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| struct writeVFOA { |  | ||||||
|   void operator()(uint32_t d) { |  | ||||||
|     if (vfoActive == VFO_A) { |     if (vfoActive == VFO_A) { | ||||||
|       setFrequency(d); |       setFrequency(r.getFreqA()); | ||||||
|     } else { |     } else { | ||||||
|       vfoA = frequency;     |       vfoA = r.getFreqA(); | ||||||
|     }     |     }     | ||||||
|   } |   } | ||||||
| }; |  | ||||||
|  |  | ||||||
| struct readVFOB { |   // VFO B frequency | ||||||
|   bool operator()(uint32_t* d) { |   if (r.isDirty(VFOB_WORD)) { | ||||||
|     unsigned freq = (vfoActive == VFO_B) ? frequency : vfoB; |  | ||||||
|     if (*d == freq) { |  | ||||||
|       return false |  | ||||||
|     } else { |  | ||||||
|       *d = freq; |  | ||||||
|       return true; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| struct writeVFOB { |  | ||||||
|   void operator()(uint32_t d) { |  | ||||||
|     if (vfoActive == VFO_B) { |     if (vfoActive == VFO_B) { | ||||||
|       setFrequency(d); |       setFrequency(r.getFreqB()); | ||||||
|     } else { |     } else { | ||||||
|       vfoB = frequency;     |       vfoB = r.getFreqB();  | ||||||
|     }     |     }     | ||||||
|   } |   } | ||||||
| }; |  | ||||||
|  |  | ||||||
| struct readRIT { |   // RIT and XIT frequencies | ||||||
|   bool operator()(uint32_t* d) { |   if (r.isDirty(OFFSETS_WORD)) { | ||||||
|     int freq = ritRxFrequency - frequency; |     // RIT | ||||||
|     if (*d == (uint32_t)freq) { |     ritRxFrequency = r.getRIT() + ritTxFrequency; | ||||||
|       return false; |  | ||||||
|     } else { |  | ||||||
|       *d = (uint32_t)freq; |  | ||||||
|       return true; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| struct writeRIT { |  | ||||||
|   void operator()(uint32_t d) { |  | ||||||
|     ritRxFrequency = (int)d + ritTxFrequency; |  | ||||||
|     if ((ritOn == 1) && (inTx == 0)) { |     if ((ritOn == 1) && (inTx == 0)) { | ||||||
|       setFrequency(ritRxFrequency); |       setFrequency(ritRxFrequency); | ||||||
|     } |     } | ||||||
|  |     // XIT - TODO | ||||||
|   } |   } | ||||||
| }; |  | ||||||
|  |  | ||||||
| struct readXIT { |   // VFO A/B selection | ||||||
|   bool operator()(uint32_t* d) { |   if (r.isDirty(FLAGS_WORD)) { | ||||||
|     return false; |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| struct writeXIT { |  | ||||||
|   void operator()(uint32_t d) { |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| struct readFlags { |  | ||||||
| bool operator()(uint32_t* d) { |  | ||||||
|     uint32_t flags = 0 |  | ||||||
|     flags = 0; |  | ||||||
|     flags |= (vfoActive == VFO_B ? UBITX_VFOB_FLAG : 0); |  | ||||||
|     flags |= (cwMode != 0 ? UBITX_CW_FLAG : 0); |  | ||||||
|     flags |= (isUSB != 0 ? UBITX_USB_FLAG : 0); |  | ||||||
|     flags |= (splitOn != 0 ? UBITX_SPLIT_FLAG : 0); |  | ||||||
|     flags |= (ritOn != 0 ? UBITX_RIT_FLAG : 0); |  | ||||||
|     //flags |= (xitOn != 0 ? UBITX_XIT_FLAG : 0); |  | ||||||
|     if (*d == flags) { |  | ||||||
|       return false; |  | ||||||
|     } else { |  | ||||||
|       *d = flags; |  | ||||||
|       return true; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| struct writeFlags { |  | ||||||
|   void operator()(uint32_t d) { |  | ||||||
|     char prev = vfoActive; |     char prev = vfoActive; | ||||||
|     vfoActive = (d & UBITX_VFOB_FLAG ? VFO_B : VFO_A); |     vfoActive = r.isVFOA() ? VFO_A : VFO_B; | ||||||
|     if (vfoActive != prev) { |     if (vfoActive != prev) { | ||||||
|       if (vfoActive == VFO_A) { |       if (vfoActive == VFO_A) { | ||||||
|         if (vfoA != frequency) { |         if (vfoA != frequency) { | ||||||
| @@ -144,28 +69,128 @@ struct writeFlags { | |||||||
|       } |       } | ||||||
|     }   |     }   | ||||||
|  |  | ||||||
|     splitOn = d & UBITX_SPLIT_FLAG ? 1 : 0; |     // Split on/off | ||||||
|  |     splitOn = r.isSplit() ? 1 : 0; | ||||||
|  |  | ||||||
|  |     // RIT on/off | ||||||
|     prev = ritOn; |     prev = ritOn; | ||||||
|     ritOn = d & UBITX_RIT_FLAG ? 1 : 0; |     ritOn = r.isRIT() ? 1 : 0; | ||||||
|     if (ritOn != prev) { |     if (ritOn != prev) { | ||||||
|       if ((ritOn == 1) && (inTx == 0)) { |       if ((ritOn == 1) && (inTx == 0)) { | ||||||
|         setFrequency(ritRxFrequency); |         setFrequency(ritRxFrequency); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     char prev = (cwMode << 1) | isUSB; |     // XIT on/off | ||||||
|     isUSB = d.flags & UBITX_USB_FLAG ? 1 : 0; |     // TODO | ||||||
|     if (d.flags & UBITX_CW_FLAG) {     |  | ||||||
|       cwMode = isUSB ? 2 : 1; // 2 = cwu / 1 = cwl |     // Mode | ||||||
|  |     prev = (cwMode << 1) | isUSB; | ||||||
|  |     isUSB = r.isUSB() ? 1 : 0; | ||||||
|  |     if (r.isCW()) { | ||||||
|  |       cwMode = 2; // 2 = cwu | ||||||
|  |     } else if (r.isCWR()) { | ||||||
|  |       cwMode = 1; // 1 = cwl | ||||||
|     } else { |     } else { | ||||||
|       cwMode = 0; |       cwMode = 0; // 0 = no cw | ||||||
|     } |     } | ||||||
|     if ((cwMode << 1) | isUSB != prev) { |     if ((cwMode << 1) | isUSB != prev) { | ||||||
|       setFrequency(frequency); |       setFrequency(frequency); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| }; | } | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  *  @brief  Read current Raduino variables into the provided RigState | ||||||
|  |  *          (if they are dirty) and set the appropriate dirty flags. | ||||||
|  |  *  @param  r | ||||||
|  |  *          RigState reference to put the values into. | ||||||
|  |  */ | ||||||
|  | void readDirty(RigState& r) { | ||||||
|  |   unsigned freq; | ||||||
|  |   short offset; | ||||||
|  |    | ||||||
|  |   // VFO A frequency | ||||||
|  |   freq = (vfoActive == VFO_A) ? frequency : vfoA; | ||||||
|  |   if (r.getFreqA() != freq) { | ||||||
|  |     r.setFreqA(freq); | ||||||
|  |     r.setDirty(VFOA_WORD); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // VFO B frequency | ||||||
|  |   freq = (vfoActive == VFO_B) ? frequency : vfoB; | ||||||
|  |   if (r.getFreqB() != freq) { | ||||||
|  |     r.setFreqB(freq); | ||||||
|  |     r.setDirty(VFOB_WORD); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // RIT frequency | ||||||
|  |   offset = ritRxFrequency - frequency; | ||||||
|  |   if (r.getRIT() != offset) { | ||||||
|  |     r.setRIT(offset); | ||||||
|  |     r.setDirty(OFFSETS_WORD); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // XIT frequency | ||||||
|  |   offset = 0; // xitRxFrequency - frequency; | ||||||
|  |   if (r.getXIT() != offset) { | ||||||
|  |     r.setXIT(offset); | ||||||
|  |     r.setDirty(OFFSETS_WORD); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   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; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Split selection | ||||||
|  |   if (r.isSplit() && splitOn == 0) { | ||||||
|  |     r.setSplitOff(); | ||||||
|  |     dirty = true; | ||||||
|  |   } else if (!r.isSplit() && splitOn != 0) { | ||||||
|  |     r.setSplitOn(); | ||||||
|  |     dirty = true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // RIT selection | ||||||
|  |   if (r.isRIT() && ritOn == 0) { | ||||||
|  |     r.setRITOff(); | ||||||
|  |     dirty = true; | ||||||
|  |   } else if (!r.isRIT() && ritOn != 0) { | ||||||
|  |     r.setRITOn(); | ||||||
|  |     dirty = true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // XIT selection | ||||||
|  |   r.setXITOff(); | ||||||
|  |   // TODO | ||||||
|  |  | ||||||
|  |   // Mode | ||||||
|  |   char prev = (r.isCW() ? 4 : 0) | (r.isCWR() ? 2 : 0) | (r.isUSB() ? 1 : 0); | ||||||
|  |   char curr = (cwMode << 1) | isUSB; | ||||||
|  |   if (curr != prev) { | ||||||
|  |     if (cwMode == 2) { | ||||||
|  |       r.setCW(); | ||||||
|  |     } else if (cwMode == 1) { | ||||||
|  |       r.setCWR(); | ||||||
|  |     } else { | ||||||
|  |       if (isUSB) { | ||||||
|  |         r.setUSB(); | ||||||
|  |       } else { | ||||||
|  |         r.setLSB(); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     dirty = true; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   if (dirty) r.setDirty(FLAGS_WORD);   | ||||||
|  | } | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -197,29 +222,17 @@ void RigState::begin() { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void RigState::update() { | void updateRaduinoState(RigState& r) { | ||||||
|   // First we need to determine which fields have changed (and are |   writeDirty(r); | ||||||
|   // thus dirty and need to be sent to the TeensyDSP). |  | ||||||
|   for (byte i = 0; i < numFields; i++) { |  | ||||||
|     if (read(i)) { |  | ||||||
|       makeDirty(i); |  | ||||||
|     } |  | ||||||
|   }     |  | ||||||
|  |  | ||||||
|   // Next we need to send the current (changed) Raduino information |  | ||||||
|   // to the TeensyDSP. |  | ||||||
|   Wire.beginTransmission(I2CMETER_ADDR); |   Wire.beginTransmission(I2CMETER_ADDR); | ||||||
|   Wire.write(I2CMETER_RIGINF); |   Wire.write(I2CMETER_RIGINF); | ||||||
|   for (byte i = 0; i < numFields; i++) { |   for (RigStateWord i = 0; i < NUM_WORDS; i++) { | ||||||
|     if (isDirty(i)) {                   // Write each field that is dirty to the bus. |     Wire.write((byte*)&r.data, sizeof(r.data)); // - write the field data | ||||||
|       Wire.write(i);                    // - write the field number/ID |     r.setClean(i); | ||||||
|       Wire.write(data(i), dataSize(i)); // - write the field data |  | ||||||
|       makeClean(i); |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|   Wire.endTransmission();   |   Wire.endTransmission();   | ||||||
|  |  | ||||||
|   delay(1);   // some delay required between ending transmission and requesting? |   delay(1);   // 1ms - some delay required between ending transmission and requesting? | ||||||
|  |  | ||||||
|   // Retrieve all of the deltas.  Mark any received field as dirty. |   // Retrieve all of the deltas.  Mark any received field as dirty. | ||||||
|   Wire.requestFrom(I2CMETER_ADDR, numBytes); |   Wire.requestFrom(I2CMETER_ADDR, numBytes); | ||||||
|   | |||||||
| @@ -3,12 +3,6 @@ | |||||||
|  |  | ||||||
| #include <Arduino.h> | #include <Arduino.h> | ||||||
|  |  | ||||||
| #define UBITX_VFOA_UPDATE  0x00000001 |  | ||||||
| #define UBITX_VFOB_UPDATE  0x00000002 |  | ||||||
| #define UBITX_RIT_UPDATE   0x00000004 |  | ||||||
| #define UBITX_XIT_UPDATE   0x00000008 |  | ||||||
| #define UBITX_FLAGS_UPDATE 0x00000010 |  | ||||||
|  |  | ||||||
| #define UBITX_VFOB_FLAG   0x00000001 | #define UBITX_VFOB_FLAG   0x00000001 | ||||||
| #define UBITX_SPLIT_FLAG  0x00000002 | #define UBITX_SPLIT_FLAG  0x00000002 | ||||||
| #define UBITX_RIT_FLAG    0x00000004 | #define UBITX_RIT_FLAG    0x00000004 | ||||||
| @@ -17,14 +11,68 @@ | |||||||
| #define UBITX_USB_FLAG    0x00000020 | #define UBITX_USB_FLAG    0x00000020 | ||||||
| #define UBITX_TX_FLAG     0x00000040 | #define UBITX_TX_FLAG     0x00000040 | ||||||
|  |  | ||||||
| struct UBitxRigState { | enum RigStateWord { | ||||||
|   uint32_t header = 0; |   DIRTY_WORD = 0, | ||||||
|   uint32_t vfo[2]; |   VFOA_WORD, | ||||||
|   int32_t rit; |   VFOB_WORD, | ||||||
|   int32_t xit; |   OFFSETS_WORD, | ||||||
|   uint32_t flags = 0; |   FLAGS_WORD, | ||||||
|  |   NUM_WORDS | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | struct UBitxRigState { | ||||||
|  |   uint32_t data[RigStateWord.NUM_WORDS] = {0}; | ||||||
|  |  | ||||||
|  |   /*! | ||||||
|  |    *  @brief  Set the dirty bit for for the specified word. | ||||||
|  |    */ | ||||||
|  |   inline void setDirty(RigStateWord w) { | ||||||
|  |     data[i] |= w < NUM_WORDS ? 1 << w : 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   inline void setClean(RigStateWord w) { | ||||||
|  |     data[i] &= ~(w < NUM_WORDS ? 1 << w : 0); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   inline bool isDirty(RigStateWord w) { | ||||||
|  |     return (1 << w) & data[DIRTY_WORD] > 0 ? true : false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   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); } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #ifndef TEENSYDUINO | ||||||
|  | void mergeDirty(const RigState& r); | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /**********************************************************************/ | /**********************************************************************/ | ||||||
| // NEW IMPLEMENTATION | // NEW IMPLEMENTATION | ||||||
|  |  | ||||||
| @@ -58,7 +106,6 @@ struct Field : public BaseField { | |||||||
|   virtual void write() const { W(data); } |   virtual void write() const { W(data); } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #define WIREBUS_NULL        0 // an empty field |  | ||||||
| #define WIREBUS_VFO_A       1 | #define WIREBUS_VFO_A       1 | ||||||
| #define WIREBUS_VFO_B       2 | #define WIREBUS_VFO_B       2 | ||||||
| #define WIREBUS_RIT_OFS     3 | #define WIREBUS_RIT_OFS     3 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user