175 lines
4.1 KiB
C++
175 lines
4.1 KiB
C++
#ifndef __RigState_h__
|
|
#define __RigState_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_SPLIT_FLAG 0x00000002
|
|
#define UBITX_RIT_FLAG 0x00000004
|
|
#define UBITX_XIT_FLAG 0x00000008
|
|
#define UBITX_CW_FLAG 0x00000010
|
|
#define UBITX_USB_FLAG 0x00000020
|
|
#define UBITX_TX_FLAG 0x00000040
|
|
|
|
struct UBitxRigState {
|
|
uint32_t header = 0;
|
|
uint32_t vfo[2];
|
|
int32_t rit;
|
|
int32_t xit;
|
|
uint32_t flags = 0;
|
|
};
|
|
|
|
/**********************************************************************/
|
|
|
|
template<typename T, int ID>
|
|
struct Field {
|
|
byte id = ID;
|
|
bool dirty;
|
|
T data;
|
|
|
|
inline size_t sizeOfWrite() { return dirty ? sizeof(byte) + sizeof(T) : 0; }
|
|
|
|
template<typename STREAM> void writeChanges() {
|
|
if (dirty) {
|
|
STREAM().write(id);
|
|
STREAM().write((byte*)&data, sizeof(T));
|
|
}
|
|
}
|
|
|
|
template<typename STREAM> 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<T,ID>& 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<uint32_t, 0> vfoA;
|
|
Field<uint32_t, 1> vfoB;
|
|
Field<int32_t, 2> rit;
|
|
Field<int32_t, 3> xit;
|
|
Field<uint32_t, 4> 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<typename STREAM> void writeChanges() {
|
|
vfoA.writeChanges<STREAM>();
|
|
vfoB.writeChanges<STREAM>();
|
|
rit.writeChanges<STREAM>();
|
|
xit.writeChanges<STREAM>();
|
|
flags.writeChanges<STREAM>();
|
|
}
|
|
|
|
template<typename STREAM> void readChanges(size_t size) {
|
|
size_t len = 0;
|
|
while (STREAM().available() && len < size) {
|
|
switch(STREAM().read()) {
|
|
case 0:
|
|
len += vfoA.read<STREAM>();
|
|
break;
|
|
|
|
case 1:
|
|
len += vfoB.read<STREAM>();
|
|
break;
|
|
|
|
case 2:
|
|
len += rit.read<STREAM>();
|
|
break;
|
|
|
|
case 3:
|
|
len += xit.read<STREAM>();
|
|
break;
|
|
|
|
case 4:
|
|
len += flags.read<STREAM>();
|
|
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
|